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