|
|
|
@ -29,8 +29,7 @@ extern int PPparse(char **, struct pnode **); |
|
|
|
void db_print_pnode_tree(struct pnode *p, char *print); |
|
|
|
|
|
|
|
|
|
|
|
struct pnode * |
|
|
|
ft_getpnames_from_string(const char *sz, bool check) |
|
|
|
struct pnode *ft_getpnames_from_string(const char *sz, bool check) |
|
|
|
{ |
|
|
|
struct pnode *pn; |
|
|
|
|
|
|
|
@ -62,7 +61,7 @@ ft_getpnames(const wordlist *wl, bool check) |
|
|
|
return (struct pnode *) NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* Convert the list to a string then parse the string */ |
|
|
|
/* Conver the list to a string then parse the string */ |
|
|
|
const char * const sz = wl_flatten(wl); |
|
|
|
struct pnode * const pn = ft_getpnames_from_string(sz, check); |
|
|
|
txfree((void *) sz); |
|
|
|
@ -213,63 +212,70 @@ struct func func_not = { "not", cx_not }; |
|
|
|
|
|
|
|
|
|
|
|
/* Binary operator node. */ |
|
|
|
|
|
|
|
struct pnode * |
|
|
|
PP_mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2) |
|
|
|
struct pnode *PP_mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2) |
|
|
|
{ |
|
|
|
struct op *o; |
|
|
|
struct pnode *p; |
|
|
|
|
|
|
|
for (o = &ops[0]; o->op_name; o++) |
|
|
|
if (o->op_num == opnum) |
|
|
|
for (o = &ops[0]; o->op_name; o++) { |
|
|
|
if (o->op_num == opnum) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!o->op_name) |
|
|
|
if (!o->op_name) { |
|
|
|
fprintf(cp_err, "PP_mkbnode: Internal Error: no such op num %d\n", |
|
|
|
opnum); |
|
|
|
} |
|
|
|
|
|
|
|
p = alloc_pnode(); |
|
|
|
|
|
|
|
p->pn_op = o; |
|
|
|
|
|
|
|
p->pn_left = arg1; |
|
|
|
if (p->pn_left) |
|
|
|
if (p->pn_left) { |
|
|
|
p->pn_left->pn_use++; |
|
|
|
} |
|
|
|
|
|
|
|
p->pn_right = arg2; |
|
|
|
if (p->pn_right) |
|
|
|
if (p->pn_right) { |
|
|
|
p->pn_right->pn_use++; |
|
|
|
} |
|
|
|
|
|
|
|
return (p); |
|
|
|
} |
|
|
|
return p; |
|
|
|
} /* end of function PP_mkbnode */ |
|
|
|
|
|
|
|
|
|
|
|
/* Unary operator node. */ |
|
|
|
|
|
|
|
struct pnode * |
|
|
|
PP_mkunode(int op, struct pnode *arg) |
|
|
|
/* Unary operator node. */ |
|
|
|
struct pnode *PP_mkunode(int op, struct pnode *arg) |
|
|
|
{ |
|
|
|
struct pnode *p; |
|
|
|
struct op *o; |
|
|
|
|
|
|
|
p = alloc_pnode(); |
|
|
|
|
|
|
|
for (o = uops; o->op_name; o++) |
|
|
|
if (o->op_num == op) |
|
|
|
for (o = uops; o->op_name; o++) { |
|
|
|
if (o->op_num == op) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!o->op_name) |
|
|
|
if (!o->op_name) { |
|
|
|
fprintf(cp_err, "PP_mkunode: Internal Error: no such op num %d\n", |
|
|
|
op); |
|
|
|
} |
|
|
|
|
|
|
|
p->pn_op = o; |
|
|
|
|
|
|
|
p->pn_left = arg; |
|
|
|
if (p->pn_left) |
|
|
|
if (p->pn_left) { |
|
|
|
p->pn_left->pn_use++; |
|
|
|
} |
|
|
|
|
|
|
|
return p; |
|
|
|
} /* end of function PP_mkunode */ |
|
|
|
|
|
|
|
return (p); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Function node. We have to worry about a lot of things here. Something |
|
|
|
@ -280,9 +286,7 @@ PP_mkunode(int op, struct pnode *arg) |
|
|
|
* the arguments, and then return a copy of the expression that it was |
|
|
|
* defined to be. |
|
|
|
*/ |
|
|
|
|
|
|
|
struct pnode * |
|
|
|
PP_mkfnode(const char *func, struct pnode *arg) |
|
|
|
struct pnode *PP_mkfnode(const char *func, struct pnode *arg) |
|
|
|
{ |
|
|
|
struct func *f; |
|
|
|
struct pnode *p, *q; |
|
|
|
@ -292,15 +296,18 @@ PP_mkfnode(const char *func, struct pnode *arg) |
|
|
|
(void) strcpy(buf, func); |
|
|
|
strtolower(buf); /* Make sure the case is ok. */ |
|
|
|
|
|
|
|
for (f = &ft_funcs[0]; f->fu_name; f++) |
|
|
|
if (eq(f->fu_name, buf)) |
|
|
|
for (f = &ft_funcs[0]; f->fu_name; f++) { |
|
|
|
if (eq(f->fu_name, buf)) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (f->fu_name == NULL) { |
|
|
|
if (f->fu_name == NULL) { /* not found yet */ |
|
|
|
/* Give the user-defined functions a try. */ |
|
|
|
q = ft_substdef(func, arg); |
|
|
|
if (q) |
|
|
|
return (q); |
|
|
|
if (q) { /* found */ |
|
|
|
return q; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ((f->fu_name == NULL) && arg->pn_value) { |
|
|
|
@ -312,15 +319,16 @@ PP_mkfnode(const char *func, struct pnode *arg) |
|
|
|
/* Well, too bad. */ |
|
|
|
fprintf(cp_err, "Error: no such function as %s.\n", |
|
|
|
func); |
|
|
|
return (NULL); |
|
|
|
return (struct pnode *) NULL; |
|
|
|
} |
|
|
|
/* (void) strcpy(buf, d->v_name); XXX */ |
|
|
|
return (PP_mksnode(buf)); |
|
|
|
} else if (f->fu_name == NULL) { |
|
|
|
return PP_mksnode(buf); |
|
|
|
} |
|
|
|
else if (f->fu_name == NULL) { |
|
|
|
fprintf(cp_err, "Error: no function as %s with that arity.\n", |
|
|
|
func); |
|
|
|
free_pnode(arg); |
|
|
|
return (NULL); |
|
|
|
return (struct pnode *) NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (!f->fu_func && arg->pn_op && arg->pn_op->op_num == PT_OP_COMMA) { |
|
|
|
@ -335,17 +343,17 @@ PP_mkfnode(const char *func, struct pnode *arg) |
|
|
|
p->pn_func = f; |
|
|
|
|
|
|
|
p->pn_left = arg; |
|
|
|
if (p->pn_left) |
|
|
|
if (p->pn_left) { |
|
|
|
p->pn_left->pn_use++; |
|
|
|
} |
|
|
|
|
|
|
|
return (p); |
|
|
|
} |
|
|
|
return p; |
|
|
|
} /* end of function PP_mkfnode */ |
|
|
|
|
|
|
|
|
|
|
|
/* Number node. */ |
|
|
|
|
|
|
|
struct pnode * |
|
|
|
PP_mknnode(double number) |
|
|
|
/* Number node. */ |
|
|
|
struct pnode *PP_mknnode(double number) |
|
|
|
{ |
|
|
|
struct pnode *p; |
|
|
|
struct dvec *v; |
|
|
|
@ -354,7 +362,7 @@ PP_mknnode(double number) |
|
|
|
* to be careful to deal properly with node numbers that are quite |
|
|
|
* large... |
|
|
|
*/ |
|
|
|
v = dvec_alloc(number < MAXPOSINT |
|
|
|
v = dvec_alloc(number <= INT_MAX |
|
|
|
? tprintf("%d", (int) number) |
|
|
|
: tprintf("%G", number), |
|
|
|
SV_NOTYPE, |
|
|
|
@ -368,13 +376,12 @@ PP_mknnode(double number) |
|
|
|
p = alloc_pnode(); |
|
|
|
p->pn_value = v; |
|
|
|
return (p); |
|
|
|
} |
|
|
|
} /* end of function PP_mknnode */ |
|
|
|
|
|
|
|
|
|
|
|
/* String node. */ |
|
|
|
|
|
|
|
struct pnode * |
|
|
|
PP_mksnode(const char *string) |
|
|
|
/* String node. */ |
|
|
|
struct pnode *PP_mksnode(const char *string) |
|
|
|
{ |
|
|
|
struct dvec *v, *nv, *vs, *newv = NULL, *end = NULL; |
|
|
|
struct pnode *p; |
|
|
|
@ -387,17 +394,19 @@ PP_mksnode(const char *string) |
|
|
|
0, |
|
|
|
0, NULL); |
|
|
|
p->pn_value = nv; |
|
|
|
return (p); |
|
|
|
return p; |
|
|
|
} |
|
|
|
|
|
|
|
/* It's not obvious that we should be doing this, but... */ |
|
|
|
for (vs = v; vs; vs = vs->v_link2) { |
|
|
|
nv = vec_copy(vs); |
|
|
|
vec_new(nv); |
|
|
|
if (end) |
|
|
|
if (end) { |
|
|
|
end->v_link2 = nv; |
|
|
|
else |
|
|
|
} |
|
|
|
else { |
|
|
|
newv = end = nv; |
|
|
|
} |
|
|
|
end = nv; |
|
|
|
} |
|
|
|
p->pn_value = newv; |
|
|
|
@ -410,12 +419,12 @@ PP_mksnode(const char *string) |
|
|
|
/* The two lines above have been commented out to prevent deletion of @xxx[par] |
|
|
|
after execution of only a single command like plot @xxx[par] or write. We need to |
|
|
|
monitor if this will lead to excessive memory usage. h_vogt 090221 */ |
|
|
|
return (p); |
|
|
|
} |
|
|
|
return p; |
|
|
|
} /* end of function PP_mksnode */ |
|
|
|
|
|
|
|
|
|
|
|
struct pnode * |
|
|
|
alloc_pnode(void) |
|
|
|
|
|
|
|
struct pnode *alloc_pnode(void) |
|
|
|
{ |
|
|
|
struct pnode *pn = TMALLOC(struct pnode, 1); |
|
|
|
|
|
|
|
@ -432,42 +441,45 @@ alloc_pnode(void) |
|
|
|
pn->pn_next = NULL; |
|
|
|
|
|
|
|
return pn; |
|
|
|
} |
|
|
|
} /* end of function alloc_pnode */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Don't call this directly, always use the free_pnode() macro. |
|
|
|
The linked pnodes do not necessarily form a perfect tree as some nodes get |
|
|
|
reused. Hence, in this recursive walk trough the 'tree' we only free node |
|
|
|
that have their pn_use value at zero. Nodes that have pn_use values above |
|
|
|
zero have the link severed and their pn_use value decremented. |
|
|
|
reused. Hence, in this recursive walk through the 'tree', we only free |
|
|
|
nodes that have their pn_use value at zero. Nodes that have pn_use values |
|
|
|
above zero have the link severed and their pn_use value decremented. |
|
|
|
In addition, we don't walk past nodes with pn_use values avoid zero, just |
|
|
|
in case we have a circular reference (this probable does not happen in |
|
|
|
practice, but it does no harm playing safe) */ |
|
|
|
void |
|
|
|
free_pnode_x(struct pnode *t) |
|
|
|
in case we have a circular reference (This probably does not happen in |
|
|
|
practice, but it does no harm playing safe.) */ |
|
|
|
void free_pnode_x(struct pnode *t) |
|
|
|
{ |
|
|
|
if (!t) |
|
|
|
if (!t) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* don't walk past nodes used elsewhere. We decrement the pn_use value here, |
|
|
|
/* Don't walk past nodes used elsewhere. We decrement the pn_use value here, |
|
|
|
but the link gets severed by the action of the free_pnode() macro */ |
|
|
|
if (t->pn_use > 1) { |
|
|
|
t->pn_use--; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
/* pn_use is now 1, so its safe to free the pnode */ |
|
|
|
free_pnode(t->pn_left); |
|
|
|
free_pnode(t->pn_right); |
|
|
|
free_pnode(t->pn_next); |
|
|
|
tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */ |
|
|
|
if (t->pn_value && !(t->pn_value->v_flags & VF_PERMANENT)) |
|
|
|
if (t->pn_value && !(t->pn_value->v_flags & VF_PERMANENT)) { |
|
|
|
vec_free(t->pn_value); /* patch by Stefan Jones */ |
|
|
|
tfree(t); |
|
|
|
} |
|
|
|
txfree(t); |
|
|
|
} |
|
|
|
} |
|
|
|
} /* end of function free_pnode_x */ |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
db_print_func(FILE *fdst, struct func *f) |
|
|
|
|
|
|
|
static void db_print_func(FILE *fdst, struct func *f) |
|
|
|
{ |
|
|
|
if (!f) { |
|
|
|
fprintf(fdst, "nil"); |
|
|
|
@ -475,11 +487,11 @@ db_print_func(FILE *fdst, struct func *f) |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(fdst, "(func :fu_name %s :fu_func %p)", f->fu_name, f->fu_func); |
|
|
|
} |
|
|
|
} /* end of function db_print_func */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
db_print_op(FILE *fdst, struct op *op) |
|
|
|
static void db_print_op(FILE *fdst, struct op *op) |
|
|
|
{ |
|
|
|
if (!op) { |
|
|
|
fprintf(fdst, "nil"); |
|
|
|
@ -488,11 +500,11 @@ db_print_op(FILE *fdst, struct op *op) |
|
|
|
|
|
|
|
fprintf(fdst, "(op :op_num %d :op_name %s :op_arity %d :op_func %p)", |
|
|
|
op->op_num, op->op_name, op->op_arity, op->op_func.anonymous); |
|
|
|
} |
|
|
|
} /* end of function db_print_op */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
db_print_dvec(FILE *fdst, struct dvec *d) |
|
|
|
static void db_print_dvec(FILE *fdst, struct dvec *d) |
|
|
|
{ |
|
|
|
if (!d) { |
|
|
|
fprintf(fdst, "nil"); |
|
|
|
@ -501,11 +513,11 @@ db_print_dvec(FILE *fdst, struct dvec *d) |
|
|
|
|
|
|
|
fprintf(fdst, "(dvec :v_name %s :v_type %d :v_flags %d :v_length %d ...)", |
|
|
|
d->v_name, d->v_type, d->v_flags, d->v_length); |
|
|
|
} |
|
|
|
} /* end of function db_print_dvec */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
db_print_pnode(FILE *fdst, struct pnode *p) |
|
|
|
static void db_print_pnode(FILE *fdst, struct pnode *p) |
|
|
|
{ |
|
|
|
if (!p) { |
|
|
|
fprintf(fdst, "nil\n"); |
|
|
|
@ -513,8 +525,7 @@ db_print_pnode(FILE *fdst, struct pnode *p) |
|
|
|
} |
|
|
|
|
|
|
|
if (!p->pn_name && p->pn_value && !p->pn_func && !p->pn_op && |
|
|
|
!p->pn_left && !p->pn_right && !p->pn_next) |
|
|
|
{ |
|
|
|
!p->pn_left && !p->pn_right && !p->pn_next) { |
|
|
|
fprintf(fdst, "(pnode-value :pn_use %d", p->pn_use); |
|
|
|
fprintf(fdst, " :pn_value "); db_print_dvec(fdst, p->pn_value); |
|
|
|
fprintf(fdst, ")\n"); |
|
|
|
@ -522,8 +533,7 @@ db_print_pnode(FILE *fdst, struct pnode *p) |
|
|
|
} |
|
|
|
|
|
|
|
if (!p->pn_name && !p->pn_value && p->pn_func && !p->pn_op && |
|
|
|
!p->pn_right && !p->pn_next) |
|
|
|
{ |
|
|
|
!p->pn_right && !p->pn_next) { |
|
|
|
fprintf(fdst, "(pnode-func :pn_use %d", p->pn_use); |
|
|
|
fprintf(fdst, "\n :pn_func "); db_print_func(fdst, p->pn_func); |
|
|
|
fprintf(fdst, "\n :pn_left "); db_print_pnode(fdst, p->pn_left); |
|
|
|
@ -532,8 +542,7 @@ db_print_pnode(FILE *fdst, struct pnode *p) |
|
|
|
} |
|
|
|
|
|
|
|
if (!p->pn_name && !p->pn_value && !p->pn_func && p->pn_op && |
|
|
|
!p->pn_next) |
|
|
|
{ |
|
|
|
!p->pn_next) { |
|
|
|
fprintf(fdst, "(pnode-op :pn_use %d", p->pn_use); |
|
|
|
fprintf(fdst, "\n :pn_op "); db_print_op(fdst, p->pn_op); |
|
|
|
fprintf(fdst, "\n :pn_left "); db_print_pnode(fdst, p->pn_left); |
|
|
|
@ -550,11 +559,11 @@ db_print_pnode(FILE *fdst, struct pnode *p) |
|
|
|
fprintf(fdst, "\n :pn_right "); db_print_pnode(fdst, p->pn_right); |
|
|
|
fprintf(fdst, "\n :pn_next "); db_print_pnode(fdst, p->pn_next); |
|
|
|
fprintf(fdst, "\n)\n"); |
|
|
|
} |
|
|
|
} /* end of function db_print_pnode */ |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
db_print_pnode_tree(struct pnode *p, char *print) |
|
|
|
|
|
|
|
void db_print_pnode_tree(struct pnode *p, char *print) |
|
|
|
{ |
|
|
|
#if 1 |
|
|
|
NG_IGNORE(print); |
|
|
|
@ -569,18 +578,19 @@ db_print_pnode_tree(struct pnode *p, char *print) |
|
|
|
printf("%s:%d: %s {%s}\n%s\n", __FILE__, __LINE__, __func__, print, buf); |
|
|
|
tfree(buf); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} /* end of function db_print_pnode_tree */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
int PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
{ |
|
|
|
static char *specials = " \t%()-^+*,/|&<>~="; |
|
|
|
char *sbuf = *line; |
|
|
|
int token; |
|
|
|
|
|
|
|
while ((*sbuf == ' ') || (*sbuf == '\t')) |
|
|
|
while ((*sbuf == ' ') || (*sbuf == '\t')) { |
|
|
|
sbuf++; |
|
|
|
} |
|
|
|
|
|
|
|
llocp->start = sbuf; |
|
|
|
|
|
|
|
@ -590,28 +600,36 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
if ((sbuf[0] == 'g') && (sbuf[1] == 't') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return('>', 2); |
|
|
|
} else if ((sbuf[0] == 'l') && (sbuf[1] == 't') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'l') && (sbuf[1] == 't') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return('<', 2); |
|
|
|
} else if ((sbuf[0] == 'g') && (sbuf[1] == 'e') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'g') && (sbuf[1] == 'e') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return(TOK_GE, 2); |
|
|
|
} else if ((sbuf[0] == 'l') && (sbuf[1] == 'e') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'l') && (sbuf[1] == 'e') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return(TOK_LE, 2); |
|
|
|
} else if ((sbuf[0] == 'n') && (sbuf[1] == 'e') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'n') && (sbuf[1] == 'e') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return(TOK_NE, 2); |
|
|
|
} else if ((sbuf[0] == 'e') && (sbuf[1] == 'q') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'e') && (sbuf[1] == 'q') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return('=', 2); |
|
|
|
} else if ((sbuf[0] == 'o') && (sbuf[1] == 'r') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'o') && (sbuf[1] == 'r') && |
|
|
|
strchr(specials, sbuf[2])) { |
|
|
|
lexer_return('|', 2); |
|
|
|
} else if ((sbuf[0] == 'a') && (sbuf[1] == 'n') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'a') && (sbuf[1] == 'n') && |
|
|
|
(sbuf[2] == 'd') && strchr(specials, sbuf[3])) { |
|
|
|
lexer_return('&', 3); |
|
|
|
} else if ((sbuf[0] == 'n') && (sbuf[1] == 'o') && |
|
|
|
} |
|
|
|
else if ((sbuf[0] == 'n') && (sbuf[1] == 'o') && |
|
|
|
(sbuf[2] == 't') && strchr(specials, sbuf[3])) { |
|
|
|
lexer_return('~', 3); |
|
|
|
} |
|
|
|
@ -623,18 +641,19 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
lexer_return(*sbuf, 1); |
|
|
|
|
|
|
|
case '>': |
|
|
|
case '<': |
|
|
|
{ |
|
|
|
case '<': { |
|
|
|
/* Workaround, The Frontend makes "<>" into "< >" */ |
|
|
|
int j = 1; |
|
|
|
size_t j = 1; |
|
|
|
while (isspace_c(sbuf[j])) |
|
|
|
j++; |
|
|
|
if (((sbuf[j] == '<') || (sbuf[j] == '>')) && (sbuf[0] != sbuf[j])) { |
|
|
|
/* Allow both <> and >< for NE. */ |
|
|
|
lexer_return(TOK_NE, j+1); |
|
|
|
} else if (sbuf[1] == '=') { |
|
|
|
lexer_return(TOK_NE, j + 1); |
|
|
|
} |
|
|
|
else if (sbuf[1] == '=') { |
|
|
|
lexer_return((sbuf[0] == '>') ? TOK_GE : TOK_LE, 2); |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
lexer_return(*sbuf, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -659,26 +678,28 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
case '\0': |
|
|
|
lexer_return(*sbuf, 0); |
|
|
|
|
|
|
|
case '"': |
|
|
|
{ |
|
|
|
case '"': { |
|
|
|
char *start = ++sbuf; |
|
|
|
while (*sbuf && (*sbuf != '"')) |
|
|
|
sbuf++; |
|
|
|
lvalp->str = copy_substring(start, sbuf); |
|
|
|
if (*sbuf) |
|
|
|
if (*sbuf) { |
|
|
|
sbuf++; |
|
|
|
} |
|
|
|
lexer_return(TOK_STR, 0); |
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
{ |
|
|
|
default: { |
|
|
|
char *s = sbuf; |
|
|
|
double *td = ft_numparse(&s, FALSE); |
|
|
|
if ((!s || *s != ':') && td) { |
|
|
|
double val; |
|
|
|
|
|
|
|
if (ft_numparse(&s, FALSE, &val) >= 0 && |
|
|
|
(!s || *s != ':')) { |
|
|
|
sbuf = s; |
|
|
|
lvalp->num = *td; |
|
|
|
lvalp->num = val; |
|
|
|
lexer_return(TOK_NUM, 0); |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
int atsign = 0; |
|
|
|
char *start = sbuf; |
|
|
|
/* It is bad how we have to recognise '[' -- sometimes |
|
|
|
@ -693,13 +714,16 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
* i(v5) --> v5#branch |
|
|
|
*/ |
|
|
|
for (; *sbuf && !strchr(specials, *sbuf); sbuf++) |
|
|
|
if (*sbuf == '@') |
|
|
|
if (*sbuf == '@') { |
|
|
|
atsign = 1; |
|
|
|
else if (!atsign && *sbuf == '[') |
|
|
|
} |
|
|
|
else if (!atsign && *sbuf == '[') { |
|
|
|
break; |
|
|
|
} |
|
|
|
else if (*sbuf == ']') { |
|
|
|
if (atsign) |
|
|
|
if (atsign) { |
|
|
|
sbuf++; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@ -707,19 +731,25 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line) |
|
|
|
lexer_return(TOK_STR, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} /* end of switch over characters */ |
|
|
|
|
|
|
|
done: |
|
|
|
if (ft_parsedb) { |
|
|
|
if (token == TOK_STR) |
|
|
|
if (token == TOK_STR) { |
|
|
|
fprintf(stderr, "lexer: TOK_STR, \"%s\"\n", lvalp->str); |
|
|
|
else if (token == TOK_NUM) |
|
|
|
} |
|
|
|
else if (token == TOK_NUM) { |
|
|
|
fprintf(stderr, "lexer: TOK_NUM, %G\n", lvalp->num); |
|
|
|
else |
|
|
|
} |
|
|
|
else { |
|
|
|
fprintf(stderr, "lexer: token %d\n", token); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
*line = sbuf; |
|
|
|
llocp->stop = sbuf; |
|
|
|
return (token); |
|
|
|
} |
|
|
|
return token; |
|
|
|
} /* end of function PPlex */ |
|
|
|
|
|
|
|
|
|
|
|
|