Jeroen Demeyer on Tue, 12 Jan 2016 18:12:33 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Support trailing semicolon in gp_read_str_multiline()


On 2016-01-12 16:38, Bill Allombert wrote:
The issue is that gp does not display '123' put still put 123 in the result
history:
? a=123;
? %
%2 = 123
But with your patch, gp_read_str_multiline() do not allow to do it.

Here is a new version which returns the last character of the filtered input.

commit 3a4f5815b3c65b131bf513aa089f0f5d8d83dc57
Author: Jeroen Demeyer <jdemeyer@cage.ugent.be>
Date:   Tue Jan 12 15:30:48 2016 +0100

    Return final character in gp_read_str_multiline()

diff --git a/doc/usersch4.tex b/doc/usersch4.tex
index 719e512..a2a1d4c 100644
--- a/doc/usersch4.tex
+++ b/doc/usersch4.tex
@@ -1702,7 +1702,7 @@ There are two similar functions available to parse a string:
 
 \fun{GEN}{gp_read_str}{const char *s}\label{se:gp_read_str}
 
-\fun{GEN}{gp_read_str_multiline}{const char *s}
+\fun{GEN}{gp_read_str_multiline}{const char *s, char *last}
 
 \noindent
 Both functions read the whole string \kbd{s}. The function
@@ -1714,6 +1714,12 @@ same way as the GP command \tet{read}: newlines are significant and can
 be used to separate expressions.
 The return value is that of the last non-empty expression evaluated.
 
+In \kbd{gp\_read\_str\_multiline}, if \kbd{last} is non-\kbd{NULL},
+then \kbd{*last} receives the last character from the \emph{filtered}
+input: this can be used to check if the last character was a semi-colon
+(to hide the output in interactive usage). If (and only if) the
+input contains no statements, then \kbd{*last} is set to \kbd{0}.
+
 For both functions, \kbd{gp}'s metacommands \emph{are} recognized.
 
 \misctitle{Note} The obsolete form
diff --git a/src/headers/paridecl.h b/src/headers/paridecl.h
index 070b1c5..4cfbe5b 100644
--- a/src/headers/paridecl.h
+++ b/src/headers/paridecl.h
@@ -2511,7 +2511,7 @@ void    err_flush(void);
 void    err_printf(const char* pat, ...);
 GEN     gp_getenv(const char *s);
 GEN     gp_read_file(const char *s);
-GEN     gp_read_str_multiline(const char *s);
+GEN     gp_read_str_multiline(const char *s, char *last);
 GEN     gp_read_stream(FILE *f);
 GEN     gp_readvec_file(char *s);
 GEN     gp_readvec_stream(FILE *f);
diff --git a/src/language/es.c b/src/language/es.c
index 3c7a5e9..871f50b 100644
--- a/src/language/es.c
+++ b/src/language/es.c
@@ -262,15 +262,22 @@ gp_read_stream(FILE *fi)
 }
 
 static GEN
-gp_read_from_input(input_method* IM, int loop)
+gp_read_from_input(input_method* IM, int loop, char *last)
 {
   Buffer *b = new_buffer();
   GEN x = gnil;
   filtre_t F;
+  if (last) *last = 0;
   do {
+    char *s;
     init_filtre(&F, b);
     if (!input_loop(&F, IM)) break;
-    if (*(b->buf)) x = readseq(b->buf);
+    s = b->buf;
+    if (s[0])
+    {
+      x = readseq(s);
+      if (last) *last = s[strlen(s) - 1];
+    }
   } while (loop);
   delete_buffer(b);
   return x;
@@ -320,7 +327,7 @@ string_gets(char *s, int size, const char **ptr)
 }
 
 GEN
-gp_read_str_multiline(const char *s)
+gp_read_str_multiline(const char *s, char *last)
 {
   input_method IM;
   const char *ptr = s;
@@ -330,7 +337,7 @@ gp_read_str_multiline(const char *s)
   IM.getline = &file_input;
   IM.free = 0;
 
-  return gp_read_from_input(&IM, 1);
+  return gp_read_from_input(&IM, 1, last);
 }
 
 GEN