| 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)
{