=================================================================== RCS file: /home/cvs/OpenXM_contrib/pari-2.2/src/gp/Attic/gp_rl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- OpenXM_contrib/pari-2.2/src/gp/Attic/gp_rl.c 2001/10/02 11:17:07 1.1 +++ OpenXM_contrib/pari-2.2/src/gp/Attic/gp_rl.c 2002/09/11 07:26:56 1.2 @@ -1,4 +1,4 @@ -/* $Id: gp_rl.c,v 1.1 2001/10/02 11:17:07 noro Exp $ +/* $Id: gp_rl.c,v 1.2 2002/09/11 07:26:56 noro Exp $ Copyright (C) 2000 The PARI group. @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, #include "gp.h" #ifdef READLINE -typedef char** (*CF)(char*, char* (*)()); /* completion function */ +typedef char** (*CF)(char*, char* (*)(void)); /* completion function */ typedef char* (*GF)(char*, int); /* generator function */ typedef int (*RLCI)(int, int); /* rl_complete and rl_insert functions */ @@ -34,8 +34,10 @@ BEGINEXTERN #endif #ifdef READLINE_LIBRARY # include +# include #else # include +# include #endif #ifndef HAS_RL_MESSAGE extern int rl_message (const char *, ...); @@ -47,8 +49,6 @@ extern char *filename_completion_function(char *text,i extern char *username_completion_function(char *text,int state); #endif char **pari_completion(char *text, int start, int end); -extern int rl_completion_query_items; -extern int rl_bind_key_in_map(); ENDEXTERN void print_fun_list(char **matches, int nbli); @@ -103,7 +103,7 @@ change_state(char *msg, int *opt, int count) } *opt = c; SAVE_PROMPT(); - rl_message("%s: %s.", (long)msg, (long)(c? "on": "off")); + rl_message("%s: %s.", msg, c? "on": "off"); c = rl_read_key(); RESTORE_PROMPT(); rl_clear_message(); @@ -141,7 +141,7 @@ pari_rl_matched_insert(int count, int key) if (count <= 0) return change_state("electric parens", &do_matched_insert, count); while (paropen[i] && paropen[i] != key) i++; - if (!paropen[i] || !do_matched_insert || under_emacs) + if (!paropen[i] || !do_matched_insert || GP_DATA->flags & EMACS) return ((RLCI)rl_insert)(count,key); rl_begin_undo_group(); ((RLCI)rl_insert)(count,key); @@ -262,8 +262,7 @@ add_paren(int end) static void match_concat(char **matches, char *s) { - int i = strlen(matches[0]) + 1; - matches[0] = (char*) gprealloc(matches[0], i+strlen(s), i); + matches[0] = (char*) gprealloc(matches[0], strlen(matches[0])+strlen(s)+1); strcat(matches[0],s); } @@ -303,7 +302,7 @@ get_matches(int end, char *text, char* f(char*,int)) rl_completion_append_character = ' '; #endif current_ep = NULL; - matches = COMPLETION_MATCHES(text, (char *(*)())f); + matches = COMPLETION_MATCHES(text, (char *(*)(void))f); if (matches && !matches[1]) /* a single match */ { if (add_paren(end)) @@ -320,7 +319,7 @@ get_matches(int end, char *text, char* f(char*,int)) else if (add_comma(end)) match_concat(matches,","); } - if (under_emacs) matches = matches_for_emacs(text,matches); + if (GP_DATA->flags & EMACS) matches = matches_for_emacs(text,matches); return matches; } #undef add_comma @@ -461,7 +460,7 @@ rl_print_aide(char *s, int flag) rl_point = 0; rl_end = 0; pari_outfile = rl_outstream; SAVE_PROMPT(); - rl_message("",0,0); + rl_message("%s",""); /* rl_message("") ==> "zero length format" warning */ aide(s, flag); RESTORE_PROMPT(); rl_point = p; rl_end = e; pari_outfile = save; @@ -538,7 +537,7 @@ pari_completion(char *text, int START, int END) while (j <= END && isspace((int)rl_line_buffer[j])) j++; k = END; while (k > j && isspace((int)rl_line_buffer[k])) k--; - /* If we are in empty parens, insert arguments for the function: */ + /* If we are in empty parens, output function help */ if (do_args_complete && k == j && (rl_line_buffer[j] == ')' || !rl_line_buffer[j]) && (iend - i < MAX_KEYWORD) @@ -546,25 +545,6 @@ pari_completion(char *text, int START, int END) buf[iend - i] = 0, 1) && (ep = is_entry(buf)) && ep->help) { -#if 0 - char *s = ep->help; - - while (is_keyword_char(*s)) s++; - if (*s++ == '(') - { /* Function, print arguments! */ - char *endh = s; - while (*endh && *endh != ')' && *endh != '(') endh++; - if (*endh == ')') - { /* Well-formed help. */ - char *str = strncpy((char*) gpmalloc(endh-s + 1), s, endh-s); - char **ret = (char**)gpmalloc(sizeof(char*)*2); - str[endh-s] = 0; - ret[0] = str; ret[1] = NULL; - if (under_emacs) ret = matches_for_emacs("",ret); - return ret; - } - } -#endif rl_print_aide(buf,h_RL); rl_attempted_completion_over = 1; return NULL; @@ -621,7 +601,7 @@ rl_long_help(int count, int key) } void -init_readline() +init_readline(void) { /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "Pari-GP"; @@ -640,7 +620,7 @@ init_readline() rl_attempted_completion_function = (rl_completion_func_t*) pari_completion; /* we always want the whole list of completions under emacs */ - if (under_emacs) rl_completion_query_items = 0x8fff; + if (GP_DATA->flags & EMACS) rl_completion_query_items = 0x8fff; #define Bind(a,b,c) (((void(*)(int,Function*,Keymap)) rl_bind_key_in_map)\ ((a), (Function*)(b), (c))) @@ -677,5 +657,89 @@ init_readline() Bind(155, pari_rl_backward_sexp, emacs_dos_keymap); /* Alt-Left */ Bind(157, pari_rl_forward_sexp, emacs_dos_keymap); /* Alt-Right*/ #endif +} + +static int +history_is_new(char *s) +{ + return (*s && (!history_length || + strcmp(s, history_get(history_length)->line))); +} + +static void +gp_add_history(char *s) +{ + if (history_is_new(s)) add_history(s); +} + +extern void fix_buffer(Buffer *b, long newlbuf); +extern int input_loop(filtre_t *F, input_method *IM); + +/* 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 **endp, input_method *IM) +{ + long used = *endp - b->buf; + long left = b->len - used, l; + char *s; + + if (! (s = readline(IM->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; + } + gp_add_history(s); /* Makes a copy */ + return s; +} + +static void +unblock_SIGINT(void) +{ +#ifdef USE_SIGRELSE + sigrelse(SIGINT); +#elif USE_SIGSETMASK + sigsetmask(0); +#endif +} + +/* request one line interactively. + * Return 0: EOF + * 1: got one line from readline or infile */ +int +get_line_from_readline(char *prompt, filtre_t *F) +{ + const int index = history_length; + char *s; + input_method IM; + + IM.prompt = prompt; + IM.getline= &gprl_input; + IM.free = 1; + if (! input_loop(F,&IM)) { pariputs("\n"); return 0; } + + s = ((Buffer*)F->data)->buf; + if (*s) + { + if (history_length > index+1) + { /* Multi-line input. Remove incomplete lines */ + int i = history_length; + while (i > index) { + HIST_ENTRY *e = remove_history(--i); + free(e->line); free(e); + } + gp_add_history(s); + } + + /* update logfile */ + if (logfile) fprintf(logfile, "%s%s\n",prompt,s); + } + unblock_SIGINT(); /* bug in readline 2.0: need to unblock ^C */ + return 1; } #endif