struct pnode * PP_mkfnode(const char *func, struct pnode *arg) { struct func *f; struct pnode *p, *q; struct dvec *d; char buf[BSIZE_SP]; (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)) break; if (f->fu_name == NULL) { /* Give the user-defined functions a try. */ q = ft_substdef(func, arg); if (q) return (q); } if ((f->fu_name == NULL) && arg->pn_value) { /* Kludge -- maybe it is really a variable name. */ (void) sprintf(buf, "%s(%s)", func, arg->pn_value->v_name); free_pnode(arg); d = vec_get(buf); if (d == NULL) { /* Well, too bad. */ fprintf(cp_err, "Error: no such function as %s.\n", func); return (NULL); } /* (void) strcpy(buf, d->v_name); XXX */ 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); } if (!f->fu_func && arg->pn_op && arg->pn_op->op_num == PT_OP_COMMA) { p = PP_mkbnode(PT_OP_MINUS, PP_mkfnode(func, arg->pn_left), PP_mkfnode(func, arg->pn_right)); free_pnode(arg); return p; } p = alloc_pnode(); p->pn_func = f; p->pn_left = arg; if (p->pn_left) p->pn_left->pn_use++; return (p); }
bool cp_istrue(wordlist *wl) { struct dvec *v; struct pnode *names; bool rv; /* First do all the csh-type stuff here... */ wl = wl_copy(wl); wl = cp_variablesubst(wl); wl = cp_bquote(wl); cp_striplist(wl); names = ft_getpnames(wl, TRUE); wl_free(wl); v = ft_evaluate(names); rv = !vec_iszero(v); /* va: garbage collection for v, if pnode names is no simple value */ if (names->pn_value == NULL && v != NULL) vec_free(v); free_pnode(names); /* free also v, if pnode names is simple value */ return rv; }
/* 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. 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) { if (!t) return; /* 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 { /* 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)) vec_free(t->pn_value); /* patch by Stefan Jones */ tfree(t); } }
bool cp_istrue(wordlist *wl) { int i; struct dvec *v; struct pnode *pn; /* fprintf(stderr, "isTRUE: "); wl_print(wl, stderr); fprintf(stderr, "\n"); */ /* First do all the csh-type stuff here... */ wl = wl_copy(wl); wl = cp_variablesubst(wl); wl = cp_bquote(wl); cp_striplist(wl); pn = ft_getpnames(wl, TRUE); wl_free(wl); v = ft_evaluate(pn); /* It makes no sense to say while (all), but what the heck... */ while (v) { if (isreal(v)) { for (i = 0; i < v->v_length; i++) if (v->v_realdata[i] != 0.0) { free_pnode(pn); return (TRUE); } } else { for (i = 0; i < v->v_length; i++) if ((realpart(&v->v_compdata[i]) != 0.0) || (imagpart(&v->v_compdata[i]) != 0.0)) { free_pnode(pn); return (TRUE); } } v = v->v_link2; } free_pnode(pn); return (FALSE); }
bool cp_istrue(wordlist *wl) { int i; struct dvec *v; struct pnode *names; /* First do all the csh-type stuff here... */ wl = wl_copy(wl); wl = cp_variablesubst(wl); wl = cp_bquote(wl); cp_striplist(wl); names = ft_getpnames(wl, TRUE); wl_free(wl); v = ft_evaluate(names); for (; v; v = v->v_link2) if (isreal(v)) { for (i = 0; i < v->v_length; i++) if (v->v_realdata[i] != 0.0) { free_pnode(names); return (TRUE); } } else { for (i = 0; i < v->v_length; i++) if ((realpart(v->v_compdata[i]) != 0.0) || (imagpart(v->v_compdata[i]) != 0.0)) { free_pnode(names); return (TRUE); } } free_pnode(names); return (FALSE); }