Ilya Zakharevich on Fri, 5 Oct 2001 13:03:42 -0400


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

Re: Space removal from the user input


On Mon, Sep 17, 2001 at 12:34:03PM -0400, Ilya Zakharevich wrote:
> > It was just easier that way.
> 
> Hmm, I think that most probably it was me who implemented this, and
> most probably I just missed the fact that addhistory() does not copy,
> but keeps the pointer, and the space-removal algorithm does it by
> modifying the string.

It turned out that I'm not to blame.  Below is the patch which

 a) preserves spaces if no line-merging was performed;

 b) keeps the current (broken) behaviour with continuation lines;

 c) Adds a new default(): prompt_cont (what to put on continuation
    lines); the default behaviour of prompt_cont is as it was before;

Cannot continue now, since there is a high risk of conflicting
patches.  One of the patches in the pipeline introduced a "readline"
default(); one could use some bits of this variable to fine tune the
behaviour in the questionable cases...

Ilya

Index: src/gp/gp.c
===================================================================
RCS file: /home/megrez/cvsroot/pari/src/gp/gp.c,v
retrieving revision 1.77
diff -p -u -r1.77 gp.c
--- src/gp/gp.c	2001/07/16 14:57:10	1.77
+++ src/gp/gp.c	2001/10/05 16:53:46
@@ -40,13 +40,16 @@ BEGINEXTERN
 #  else
 #   ifdef READLINE_LIBRARY
 #     include <readline.h>
+#     include <history.h>
 #   else
 #     include <readline/readline.h>
+#     include <readline/history.h>
 #   endif
 #  endif
   extern int isatty(int);
   extern void add_history(char*);
 ENDEXTERN
+static int history_is_dup(char *s);
 #endif
 
 char*  _analyseur(void);
@@ -77,10 +80,12 @@ int    whatnow(char *s, int flag);
 #define MAX_PROMPT_LEN 128
 #define DFT_PROMPT "? "
 #define COMMENTPROMPT "comment> "
+#define CONTPROMPT ""
 #define DFT_INPROMPT ""
 static GEN *hist;
 static char *help_prg,*path;
 static char prompt[MAX_PROMPT_LEN];
+static char prompt_cont[MAX_PROMPT_LEN];
 static char thestring[256];
 static char *prettyprinter;
 static char *prettyprinter_dft = "tex2mail -TeX -noindent -ragged -by_par";
@@ -141,6 +146,7 @@ gp_preinit(int force)
 #endif
   }
   strcpy(prompt, dflt);
+  strcpy(prompt_cont, CONTPROMPT);
 
 #if defined(UNIX) || defined(__EMX__)
 #  if defined(__EMX__) || defined(__CYGWIN32__)
@@ -871,28 +877,40 @@ sd_prettyprinter(char *v, int flag)
     if (old && old != prettyprinter_dft) free(old);
     if (flag == d_INITRC) return gnil;
   }
   if (flag == d_RETURN) return strtoGEN(prettyprinter);
   if (flag == d_ACKNOWLEDGE)
     pariputsf("   prettyprinter = \"%s\"\n",prettyprinter);
   return gnil;
 }
 
 static GEN
-sd_prompt(char *v, int flag)
+sd_prompt_set(char *v, int flag, char *how, char *p)
 {
   if (*v)
   {
-    strncpy(prompt,v,MAX_PROMPT_LEN);
+    strncpy(p,v,MAX_PROMPT_LEN);
 #ifdef macintosh
-    strcat(prompt,"\n");
+    strcat(p,"\n");
 #endif
   }
-  if (flag == d_RETURN) return strtoGENstr(prompt,0);
+  if (flag == d_RETURN) return strtoGENstr(p,0);
   if (flag == d_ACKNOWLEDGE)
-    pariputsf("   prompt = \"%s\"\n",prompt);
+    pariputsf("   prompt%s = \"%s\"\n", how, p);
   return gnil;
 }
 
+static GEN
+sd_prompt(char *v, int flag)
+{
+    return sd_prompt_set(v, flag, "", prompt);
+}
+
+static GEN
+sd_prompt_cont(char *v, int flag)
+{
+    return sd_prompt_set(v, flag, "_cont", prompt_cont);
+}
+
 default_type gp_default_list[] =
 {
   {"buffersize",(void*)sd_buffersize},
@@ -914,6 +932,7 @@ default_type gp_default_list[] =
   {"primelimit",(void*)sd_primelimit},
   {"prettyprinter",(void*)sd_prettyprinter},
   {"prompt",(void*)sd_prompt},
+  {"prompt_cont",(void*)sd_prompt_cont},
   {"psfile",(void*)sd_psfile},
   {"realprecision",(void*)sd_realprecision},
   {"secure",(void*)sd_secure},
@@ -2145,7 +2164,7 @@ brace_color(char *s, int c, int force)
 }
 
 static char *
-do_prompt()
+do_prompt(char *p)
 {
   static char buf[MAX_PROMPT_LEN + 24]; /* + room for color codes */
   char *s;
@@ -2158,7 +2177,7 @@ do_prompt()
   if (filtre(s,NULL, f_COMMENT)) 
     strcpy(s, COMMENTPROMPT);
   else
-    do_strftime(prompt,s);
+    do_strftime(p,s);
   s += strlen(s);
   brace_color(s, c_INPUT, 1); return buf;
 }
@@ -2203,43 +2222,53 @@ file_input(Buffer *b, char **s0, FILE *f
 }
 
 #ifdef READLINE
+/* Read line; returns a malloc()ed string of the user input or NULL on EOF.
+   Increments the buffer size appropriately if needed; fix *endp if so.
+ */
 static char *
-gprl_input(Buffer *b, char **s0, char *prompt)
+gprl_input(Buffer *b, char **endp, char *prompt)
 {
-  long used = *s0 - b->buf;
-  long left = b->len - used;
+  long used = *endp - b->buf;
+  long left = b->len - used, l;
   char *s;
   
-  if (! (s = readline(prompt)) ) return NULL; /* EOF */
-  if ((ulong)left < strlen(s))
-  {
-    fix_buffer(b, b->len << 1);
-    *s0 = b->buf + used;
+  if (! (s = readline(prompt)) )
+      return NULL;			/* EOF */
+  l = strlen(s);
+  if ((ulong)left < l)
+  {
+    long incr = b->len;
+
+    if (incr < l)
+	incr = l;
+    fix_buffer(b, b->len + incr);
+    *endp = b->buf + used;
   }
   return s;
 }
 #endif
 
-#define skip_space(s) while (isspace((int)*s)) s++
 #define ask_filtre(t) filtre("",NULL,t)
 
-static void
-input_loop(Buffer *b, char *buf0, FILE *file, char *prompt)
+static int				/* True if more than one line read */
+input_loop(Buffer *b, char *already_read, FILE *file, char *prompt)
 {
   const int TeXmacs = (under_texmacs && file == stdin);
   const int f_flag = prompt? f_REG: f_REG | f_KEEPCASE;
-  char *end, *s = b->buf, *buf = buf0;
+  char *end, *s = b->buf;
   int wait_for_brace = 0;
   int wait_for_input = 0;
+  int read = 0;
 
   /* buffer is not empty, init filter */
   (void)ask_filtre(f_INIT);
   for(;;)
   {
-    char *t = buf;
+    char *t = already_read;
     if (!ask_filtre(f_COMMENT))
     { /* not in comment */
-      skip_space(t);
+      while (isspace((int)*t))		/* Skip space */
+	  t++;
       if (*t == LBRACE) { t++; wait_for_input = wait_for_brace = 1; }
     }
     end = filtre(t,s, f_flag);
@@ -2266,13 +2295,19 @@ input_loop(Buffer *b, char *buf0, FILE *
     }
     /* read continuation line */
 #ifdef READLINE
-    if (!file) { free(buf); buf = gprl_input(b,&s,""); }
-    else
-#endif
-      buf = file_input(b,&s,file,TeXmacs);
-    if (!buf) break;
+    if (!file) {
+	free(already_read);
+	already_read = gprl_input(b, &s, do_prompt(prompt_cont));
+	if (!history_is_dup(already_read))
+	    add_history(already_read);	/* Makes a copy */
+    } else
+#endif
+      already_read = file_input(b,&s,file,TeXmacs);
+    if (!already_read) break;
+    read++;
   }
-  if (!file && buf) free(buf);
+  if (!file && already_read) free(already_read);
+  return read;
 }
 
 /* prompt = NULL --> from gprc. Return 1 if new input, and 0 if EOF */
@@ -2316,28 +2351,47 @@ get_line_from_user(char *prompt, Buffer 
   pariputs(prompt);
   return get_line_from_file(prompt,b,infile);
 }
-#else
+#else	/* READLINE */
+static int
+history_is_dup(char *s)
+{
+    if (!history_length)
+	return 0;
+    return !strcmp(s, history_get(history_length)->line);
+}
+
 static int
 get_line_from_user(char *prompt, Buffer *b)
 {
-  static char *previous_hist = NULL;
   char *buf, *s = b->buf;
+  int index, added;
 
   if (! (buf = gprl_input(b,&s, prompt)) )
   { /* EOF */
     pariputs("\n"); return 0;
   }
-  input_loop(b,buf,NULL,prompt);
+  /* Put the original read line into history */
+  index = history_length;
+  if (!history_is_dup(buf))
+      add_history(buf);			/* Copies the entry */
+
+  added = input_loop(b,buf,NULL,prompt); /* free()s buf */
   unblock_SIGINT(); /* bug in readline 2.0: need to unblock ^C */
 
-  if (*s)
-  {
-    /* update history (don't add the same entry twice) */
-    if (!previous_hist || strcmp(s,previous_hist))
-    {
-      if (previous_hist) free(previous_hist);
-      previous_hist = pari_strdup(s); add_history(s);
-    }
+  if (*s) {				/* XXXX Better use b->buf ?! */
+      if (added) {			/* Remove incomplete lines */
+	  int i = history_length;
+
+	  while (i > index) {
+	      HIST_ENTRY *e = remove_history(--i);
+
+	      free(e->line);
+	      free(e);
+	  }
+	  if (!history_is_dup(s))
+	      add_history(s);
+      }
+  
     /* update logfile */
     if (logfile) fprintf(logfile, "%s%s\n",prompt,s);
   }
@@ -2433,7 +2487,7 @@ gp_main_loop(int ismain)
     for(;;)
     {
       int r;
-      r = read_line(do_prompt(), b);
+      r = read_line(do_prompt(prompt), b);
       if (!disable_color) term_color(c_NONE);
       if (!r)
       {