char * pari_completion_word(pari_rl_interface *rl, long end) { char *line = *rl->line_buffer; char *s = line + end, *found_quote = NULL; long i; /* truncate at cursor position */ *s = 0; /* first look for unclosed string */ for (i=0; i < end; i++) { switch(line[i]) { case '"': found_quote = found_quote? NULL: line + i; break; case '\\': i++; break; } } if (found_quote) return found_quote + 1; /* return next char after quote */ /* else find beginning of word */ while (s > line) { s--; if (!is_keyword_char(*s)) { s++; break; } } return s; }
static void check_name(const char *name) { const char *s = name; if (isalpha((int)*s)) while (is_keyword_char(*++s)) /* empty */; if (*s) pari_err(e_SYNTAX,"not a valid identifier", s, name); }
static void cut_trailing_garbage(char *s) { char c; while ( (c = *s++) ) { if (c == '\\' && ! *s++) return; /* gobble next char, return if none. */ if (!is_keyword_char(c) && c != '@') { s[-1] = 0; return; } } }
static void init_prefix(const char *text, int *len, int *junk, char **TEXT) { long l = strlen(text), j = l-1; while (j >= 0 && is_keyword_char(text[j])) j--; if (text[j] == '-' && j >= 7 && !strncmp(text+(j-7),"refcard",7)) j -= 8; j++; *TEXT = (char*)text + j; *junk = j; *len = l - j; }
/* do we add () at the end of completed word? (is it a function?) */ static int add_paren(pari_rl_interface *rl, int end) { entree *ep; const char *s; if (end < 0 || (*rl->line_buffer)[end] == '(') return 0; /* not from command_generator or already there */ ep = do_alias(current_ep); /* current_ep set in command_generator */ if (EpVALENCE(ep) < EpNEW) { /* is it a constant masked as a function (e.g Pi)? */ s = ep->help; if (!s) return 1; while (is_keyword_char(*s)) s++; return (*s != '='); } switch(EpVALENCE(ep)) { case EpVAR: return typ((GEN)ep->value) == t_CLOSURE; case EpINSTALL: return 1; } return 0; }
int pari_lex(union token_value *yylval, struct node_loc *yylloc, char **lex) { (void) yylval; yylloc->start=*lex; if (!**lex) { yylloc->end=*lex; return 0; } if (isalpha((int)**lex)) { while (is_keyword_char(**lex)) ++*lex; yylloc->end=*lex; return KENTRY; } if (**lex=='"') { ++*lex; skipstring(lex); if (!**lex) compile_err("run-away string",*lex-1); ++*lex; yylloc->end=*lex; return KSTRING; } if (**lex == '.') { int token; if ((*lex)[1]== '.') { *lex+=2; yylloc->end = *lex; return KDOTDOT; } token=skipconstante(lex); if (token==KREAL) { yylloc->end = *lex; return token; } ++*lex; yylloc->end=*lex; return '.'; } if (isbin((const char**)lex)) { while (**lex=='0' || **lex=='1') ++*lex; return KINTEGER; } if (ishex((const char**)lex)) { while (isxdigit((int)**lex)) ++*lex; return KINTEGER; } if (isdigit((int)**lex)) { int token=skipconstante(lex); yylloc->end = *lex; return token; } if ((*lex)[1]=='=') switch (**lex) { case '=': if ((*lex)[2]=='=') { *lex+=3; yylloc->end = *lex; return KID; } else { *lex+=2; yylloc->end = *lex; return KEQ; } case '>': *lex+=2; yylloc->end = *lex; return KGE; case '<': *lex+=2; yylloc->end = *lex; return KLE; case '*': *lex+=2; yylloc->end = *lex; return KME; case '/': *lex+=2; yylloc->end = *lex; return KDE; case '%': if ((*lex)[2]=='=') break; *lex+=2; yylloc->end = *lex; return KMODE; case '!': if ((*lex)[2]=='=') break; *lex+=2; yylloc->end = *lex; return KNE; case '\\': *lex+=2; yylloc->end = *lex; return KEUCE; case '+': *lex+=2; yylloc->end = *lex; return KPE; case '-': *lex+=2; yylloc->end = *lex; return KSE; } if (**lex==')' && (*lex)[1]=='-' && (*lex)[2]=='>') { *lex+=3; yylloc->end = *lex; return KPARROW; } if (**lex=='-' && (*lex)[1]=='>') { *lex+=2; yylloc->end = *lex; return KARROW; } if (**lex=='<' && (*lex)[1]=='>') { *lex+=2; yylloc->end = *lex; return KNE; } if (**lex=='\\' && (*lex)[1]=='/') switch((*lex)[2]) { case '=': *lex+=3; yylloc->end = *lex; return KDRE; default: *lex+=2; yylloc->end = *lex; return KDR; } if ((*lex)[1]==**lex) switch (**lex) { case '&': *lex+=2; yylloc->end = *lex; return KAND; case '|': *lex+=2; yylloc->end = *lex; return KOR; case '+': *lex+=2; yylloc->end = *lex; return KPP; case '-': *lex+=2; yylloc->end = *lex; return KSS; case '>': if ((*lex)[2]=='=') { *lex+=3; yylloc->end = *lex; return KSRE;} *lex+=2; yylloc->end = *lex; return KSR; case '<': if ((*lex)[2]=='=') { *lex+=3; yylloc->end = *lex; return KSLE; } *lex+=2; yylloc->end = *lex; return KSL; } yylloc->end = *lex+1; return (unsigned char) *(*lex)++; }