[GiNaC-list] Making ginsh interactive when the input is not a TTY
Vitaly Magerya
vmagerya at gmail.com
Wed Jun 21 11:28:52 CEST 2023
On 20/06/2023, Richard B. Kreckel <kreckel at in.terlu.de> wrote:
> Could you, please, polish your patch a little? In particular, explain
> the role of the magic '*' char. Also how it works at boundaries of
> YY_READ_BUF_SIZE.
Hi, Richy. The '*' value is only there so that if max_size is 0
and no characters are read, the final newline check (c=='\n')
would not compare to an uninitialized variable. This should never
happen, as far as I understand, but if it does, we still do the
right thing. Related to that, the max_size value passed to the
function is YY_READ_BUF_SIZE minus the current buffer content;
this is ensured by Flex.
But in any case, I did not invent this code: I copy-pasted it
directly from the interactive mode with HAVE_LIBREADLINE disabled;
this way I can convince myself that it's correct, because it's
already used a few lines up :)
I'm attaching the patch.
-------------- next part --------------
From 1c0342d5f21c078ec39f9c13deb1de821a0c2b3c Mon Sep 17 00:00:00 2001
From: Vitaly Magerya <magv at tx97.net>
Date: Wed, 21 Jun 2023 10:38:41 +0200
Subject: [PATCH] Make ginsh evaluate line-by-line in non-interactive mode
When used interactively ginsh consumes the input line by line, so
if a complete expression is entered it is enough to end the line
to get an evaluated result. In the non-interative mode (i.e. if
the input is not a tty) the input is consumed in blocks, making
it impossible to use ginsh as a subprocess.
This patch makes the non-interactive mode reuse the same line
parsing logic as the interactive mode (without readline), but skips
printing the "> " prompt, preserving the backward compatibility.
---
ginsh/ginsh_lexer.lpp | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/ginsh/ginsh_lexer.lpp b/ginsh/ginsh_lexer.lpp
index 8692b1ac..5169ecef 100644
--- a/ginsh/ginsh_lexer.lpp
+++ b/ginsh/ginsh_lexer.lpp
@@ -203,8 +203,16 @@ static int ginsh_input(char *buf, int max_size)
YY_FATAL_ERROR("input in flex scanner failed");
result = n;
#endif
- } else if (((result = fread(buf, 1, max_size, yyin)) == 0) && ferror(yyin))
- YY_FATAL_ERROR("input in flex scanner failed");
+ } else {
+ int c = '*', n;
+ for (n = 0; n < max_size && (c = getc(yyin)) != EOF && c != '\n'; ++n)
+ buf[n] = (char)c;
+ if (c == '\n')
+ buf[n++] = (char)c;
+ if (c == EOF && ferror(yyin))
+ YY_FATAL_ERROR("input in flex scanner failed");
+ result = n;
+ }
return result;
}
--
2.35.3
More information about the GiNaC-list
mailing list