mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Fixed reading from stdin with calc -p
This commit is contained in:
11
CHANGES
11
CHANGES
@@ -23,6 +23,17 @@ The following are the changes from calc version 2.12.6.0 to date:
|
|||||||
Renamed README to README.FIRST. Added README.md for the
|
Renamed README to README.FIRST. Added README.md for the
|
||||||
GitHub repository.
|
GitHub repository.
|
||||||
|
|
||||||
|
Fixed reading from standard input (stdin) when -p is given on
|
||||||
|
the comamnd line. This now prints hello:
|
||||||
|
|
||||||
|
echo hello | calc -p 'stdin = files(0); print fgetline(stdin);'
|
||||||
|
|
||||||
|
Added more debugging realted to stdin when bit 4 of calc_debug
|
||||||
|
is set (e.g., running calc with -D16).
|
||||||
|
|
||||||
|
Updated the calc(1) man page and 'help file' to explain about
|
||||||
|
reading from standard input (stdin).
|
||||||
|
|
||||||
|
|
||||||
The following are the changes from calc version 2.12.5.4 to 2.12.5.6:
|
The following are the changes from calc version 2.12.5.4 to 2.12.5.6:
|
||||||
|
|
||||||
|
@@ -2268,7 +2268,7 @@ calc.1: calc.man ${MAKE_FILE}
|
|||||||
-e 's,$${CUSTOMINCDIR},${CUSTOMINCDIR},g' \
|
-e 's,$${CUSTOMINCDIR},${CUSTOMINCDIR},g' \
|
||||||
-e 's,$${CUSTOMHELPDIR},${CUSTOMHELPDIR},g' \
|
-e 's,$${CUSTOMHELPDIR},${CUSTOMHELPDIR},g' \
|
||||||
-e 's,$${CALCRC},${CALCRC},g' < calc.man > calc.1
|
-e 's,$${CALCRC},${CALCRC},g' < calc.man > calc.1
|
||||||
${Q} echo calc.man formed
|
${Q} echo calc.1 formed
|
||||||
|
|
||||||
calc.usage: calc.1 ${MAKE_FILE}
|
calc.usage: calc.1 ${MAKE_FILE}
|
||||||
${RM} -f $@
|
${RM} -f $@
|
||||||
|
23
calc.c
23
calc.c
@@ -110,6 +110,7 @@ main(int argc, char **argv)
|
|||||||
BOOL done = FALSE;
|
BOOL done = FALSE;
|
||||||
BOOL havearg;
|
BOOL havearg;
|
||||||
BOOL haveendstr;
|
BOOL haveendstr;
|
||||||
|
BOOL stdin_closed = FALSE;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -483,8 +484,11 @@ main(int argc, char **argv)
|
|||||||
if (havecommands) {
|
if (havecommands) {
|
||||||
cmdbuf[cmdlen++] = '\n';
|
cmdbuf[cmdlen++] = '\n';
|
||||||
cmdbuf[cmdlen] = '\0';
|
cmdbuf[cmdlen] = '\0';
|
||||||
if (fclose(stdin)) {
|
if (p_flag != TRUE) {
|
||||||
perror("main(): fclose(stdin) failed:");
|
if (fclose(stdin)) {
|
||||||
|
perror("main(): fclose(stdin) failed:");
|
||||||
|
}
|
||||||
|
stdin_closed = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +499,9 @@ main(int argc, char **argv)
|
|||||||
* unbuffered mode
|
* unbuffered mode
|
||||||
*/
|
*/
|
||||||
if (u_flag) {
|
if (u_flag) {
|
||||||
setbuf(stdin, NULL);
|
if (stdin_closed == FALSE) {
|
||||||
|
setbuf(stdin, NULL);
|
||||||
|
}
|
||||||
setbuf(stdout, NULL);
|
setbuf(stdout, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,6 +510,17 @@ main(int argc, char **argv)
|
|||||||
* initialize
|
* initialize
|
||||||
*/
|
*/
|
||||||
libcalc_call_me_first();
|
libcalc_call_me_first();
|
||||||
|
if (u_flag) {
|
||||||
|
if (conf->calc_debug & CALCDBG_TTY) {
|
||||||
|
if (stdin_closed == FALSE) {
|
||||||
|
printf("main: stdin set to unbuffered before "
|
||||||
|
"calling libcalc_call_me_first()\n");
|
||||||
|
} else {
|
||||||
|
printf("main: stdin closed before "
|
||||||
|
"calling libcalc_call_me_first()\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
|
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
|
||||||
if (conf->calc_debug & CALCDBG_TTY)
|
if (conf->calc_debug & CALCDBG_TTY)
|
||||||
printf("main: stdin_tty is %d\n", stdin_tty);
|
printf("main: stdin_tty is %d\n", stdin_tty);
|
||||||
|
34
calc.man
34
calc.man
@@ -554,6 +554,40 @@ print 27! ^2 or print 27\!^2
|
|||||||
.fi
|
.fi
|
||||||
.in -5n
|
.in -5n
|
||||||
|
|
||||||
|
Reading from standard input when calc is part of a pipe works
|
||||||
|
as long as the \-p flag is given to calc. For example, this
|
||||||
|
will print chongo was here:
|
||||||
|
.sp 1
|
||||||
|
.in +5n
|
||||||
|
.nf
|
||||||
|
echo chongo was here | calc \-p 'print fgetline(files(0));'
|
||||||
|
.sp 1
|
||||||
|
.fi
|
||||||
|
.in -5n
|
||||||
|
.sp 1
|
||||||
|
while this does not:
|
||||||
|
.sp 1
|
||||||
|
.in +5n
|
||||||
|
.nf
|
||||||
|
echo chongo was here | calc 'print fgetline(files(0));'
|
||||||
|
.sp 1
|
||||||
|
.fi
|
||||||
|
.in -5n
|
||||||
|
.sp 1
|
||||||
|
nor will this print chongo was here:
|
||||||
|
.sp 1
|
||||||
|
.in +5n
|
||||||
|
.nf
|
||||||
|
echo chongo was here | calc \-i 'print fgetline(files(0));'
|
||||||
|
.sp 1
|
||||||
|
.fi
|
||||||
|
.in -5n
|
||||||
|
.sp 1
|
||||||
|
This is because without \-p, the interactive parser, in an effort
|
||||||
|
to parse interactive commands, flushes data on standard input.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
|
||||||
\&
|
\&
|
||||||
.br
|
.br
|
||||||
CALC STARTUP FILES
|
CALC STARTUP FILES
|
||||||
|
39
help/file
39
help/file
@@ -50,6 +50,15 @@ Using files
|
|||||||
|
|
||||||
stdout = files(1);
|
stdout = files(1);
|
||||||
|
|
||||||
|
Or for example, if you wanted to assign a file value which is
|
||||||
|
equivalent to stdin, you could use:
|
||||||
|
|
||||||
|
stdout = files(0);
|
||||||
|
|
||||||
|
And for stderr:
|
||||||
|
|
||||||
|
stderr = files(2);
|
||||||
|
|
||||||
The 'fclose' function is used to close a file which had been opened.
|
The 'fclose' function is used to close a file which had been opened.
|
||||||
When this is done, the file value associated with the file remains
|
When this is done, the file value associated with the file remains
|
||||||
a file value, but appears 'closed', and cannot be used in further
|
a file value, but appears 'closed', and cannot be used in further
|
||||||
@@ -100,6 +109,36 @@ Using files
|
|||||||
single character string. It returns the null value when end of file
|
single character string. It returns the null value when end of file
|
||||||
is reached.
|
is reached.
|
||||||
|
|
||||||
|
Reading from standard input when calc is part of a pipe works
|
||||||
|
as long as the -p flag is given to calc. For example, this
|
||||||
|
will print "chongo was here":
|
||||||
|
|
||||||
|
echo chongo was here | calc -p 'print fgetline(files(0));'
|
||||||
|
|
||||||
|
while this does not:
|
||||||
|
|
||||||
|
echo chongo was here | calc 'print fgetline(files(0));'
|
||||||
|
|
||||||
|
nor will this print "chongo was here":
|
||||||
|
|
||||||
|
echo chongo was here | calc -i 'print fgetline(files(0));'
|
||||||
|
|
||||||
|
This is because without -p, the interactive parser, in an effort
|
||||||
|
to parse interactive commands, flushes data on standard input.
|
||||||
|
|
||||||
|
On the other hand, once interactive mode is entered, reading
|
||||||
|
from standard input works as expected. For example, this works:
|
||||||
|
|
||||||
|
$ calc
|
||||||
|
C-style arbitrary precision calculator (version 2.12.6.0)
|
||||||
|
Calc is open software. For license details type: help copyright
|
||||||
|
[Type "exit" to exit, or "help" for help.]
|
||||||
|
|
||||||
|
; str = fgetline(files(0))
|
||||||
|
this text was typed into stdin
|
||||||
|
; print str
|
||||||
|
this text was typed into stdin
|
||||||
|
|
||||||
The 'printf' and 'fprintf' functions are used to print results to a
|
The 'printf' and 'fprintf' functions are used to print results to a
|
||||||
file (which could be stdout or stderr). The 'fprintf' function
|
file (which could be stdout or stderr). The 'fprintf' function
|
||||||
accepts a file variable, whereas the 'printf' function assumes the
|
accepts a file variable, whereas the 'printf' function assumes the
|
||||||
|
11
input.c
11
input.c
@@ -361,6 +361,10 @@ f_pathopen(char *name, char *mode, char *pathlist, char **openpath)
|
|||||||
}
|
}
|
||||||
if (*openpath == NULL) {
|
if (*openpath == NULL) {
|
||||||
free(path);
|
free(path);
|
||||||
|
if ((conf->calc_debug & CALCDBG_TTY) && ret == stdin) {
|
||||||
|
printf("f_pathopen: closing stdin "
|
||||||
|
"on malloc return error\n");
|
||||||
|
}
|
||||||
fclose(ret);
|
fclose(ret);
|
||||||
math_error("cannot malloc return openpath buffer");
|
math_error("cannot malloc return openpath buffer");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@@ -647,8 +651,13 @@ closeinput(void)
|
|||||||
return;
|
return;
|
||||||
if (cip->i_str)
|
if (cip->i_str)
|
||||||
free(cip->i_str);
|
free(cip->i_str);
|
||||||
if (cip->i_fp)
|
if (cip->i_fp) {
|
||||||
|
if ((conf->calc_debug & CALCDBG_TTY) && cip->i_fp == stdin) {
|
||||||
|
printf("closeinput: closing stdin "
|
||||||
|
"at depth: %d\n", depth);
|
||||||
|
}
|
||||||
fclose(cip->i_fp);
|
fclose(cip->i_fp);
|
||||||
|
}
|
||||||
if (cip->i_name)
|
if (cip->i_name)
|
||||||
free(cip->i_name);
|
free(cip->i_name);
|
||||||
depth--;
|
depth--;
|
||||||
|
Reference in New Issue
Block a user