void cp_striplist(wordlist *wlist) { wordlist *wl; for (wl = wlist; wl; wl = wl->wl_next) cp_wstrip(wl->wl_word); return; }
/* Evaluate a variable. */ wordlist * vareval(char *string) { struct variable *v; wordlist *wl; char buf[BSIZE_SP], *s; char *oldstring = copy(string); char *range = NULL; int i, up, low; cp_wstrip(string); if ((s = strchr(string, '[')) != NULL) { *s = '\0'; range = s + 1; } switch (*string) { case '$': wl = wl_cons(tprintf("%d", getpid()), NULL); tfree(oldstring); return (wl); case '<': (void) fflush(cp_out); if (!fgets(buf, BSIZE_SP, cp_in)) { clearerr(cp_in); (void) strcpy(buf, "EOF"); } for (s = buf; *s && (*s != '\n'); s++) ; *s = '\0'; wl = cp_lexer(buf); /* This is a hack. */ if (!wl->wl_word) wl->wl_word = copy(""); tfree(oldstring); return (wl); case '?': string++; for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v) v = cp_enqvar(string); wl = wl_cons(copy(v ? "1" : "0"), NULL); tfree(oldstring); return (wl); case '#': string++; for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v) v = cp_enqvar(string); if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); return (NULL); } if (v->va_type == CP_LIST) for (v = v->va_vlist, i = 0; v; v = v->va_next) i++; else i = (v->va_type != CP_BOOL); wl = wl_cons(tprintf("%d", i), NULL); tfree(oldstring); return (wl); case '\0': wl = wl_cons(copy("$"), NULL); tfree(oldstring); return (wl); } /* The notation var[stuff] has two meanings... If this is a real * variable, then the [] denotes range, but if this is a strange * (e.g, device parameter) variable, it could be anything... */ for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v && isdigit_c(*string)) { for (v = variables; v; v = v->va_next) if (eq(v->va_name, "argv")) break; range = string; } if (!v) { range = NULL; string = oldstring; v = cp_enqvar(string); } if (!v && (s = getenv(string)) != NULL) { wl = wl_cons(copy(s), NULL); tfree(oldstring); return (wl); } if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); return (NULL); } wl = cp_varwl(v); /* Now parse and deal with 'range' ... */ if (range) { /* rather crude fix when range itself is a $expression */ wordlist *r = NULL; if (*range == '$') { char *t = ++range; if (*t == '&') t++; while (isalnum_c(*t)) t++; *t = '\0'; r = vareval(range); if (!r || r->wl_next) { fprintf(cp_err, "Error: %s: illegal index.\n", string); tfree(oldstring); wl_free(r); return NULL; } range = r->wl_word; } for (low = 0; isdigit_c(*range); range++) low = low * 10 + *range - '0'; if ((*range == '-') && isdigit_c(range[1])) for (up = 0, range++; isdigit_c(*range); range++) up = up * 10 + *range - '0'; else if (*range == '-') up = wl_length(wl); else up = low; up--, low--; wl = wl_range(wl, low, up); wl_free(r); } tfree(oldstring); return (wl); }
/* Determine the value of a variable. Fail if the variable is unset, * and if the type doesn't match, try and make it work... */ bool cp_getvar(char *name, enum cp_types type, void *retval) { struct variable *v; struct variable *uv1; uv1 = cp_usrvars(); #ifdef TRACE /* SDB debug statement */ fprintf(stderr, "in cp_getvar, trying to get value of variable %s.\n", name); #endif for (v = variables; v; v = v->va_next) if (eq(name, v->va_name)) break; if (!v) for (v = uv1; v; v = v->va_next) if (eq(name, v->va_name)) break; if (!v && plot_cur) for (v = plot_cur->pl_env; v; v = v->va_next) if (eq(name, v->va_name)) break; if (!v && ft_curckt) for (v = ft_curckt->ci_vars; v; v = v->va_next) if (eq(name, v->va_name)) break; if (!v) { if (type == CP_BOOL && retval) *(bool *) retval = FALSE; free_struct_variable(uv1); return (FALSE); } if (v->va_type == type) { if (retval) switch (type) { case CP_BOOL: *(bool *) retval = TRUE; break; case CP_NUM: *(int *) retval = v->va_num; break; case CP_REAL: *(double *) retval = v->va_real; break; case CP_STRING: { /* Gotta be careful to have room. */ char *s = cp_unquote(v->va_string); cp_wstrip(s); strcpy((char*) retval, s); tfree(s); break; } case CP_LIST: /* Funny case... */ *(struct variable **) retval = v->va_vlist; break; default: fprintf(cp_err, "cp_getvar: Internal Error: bad var type %d.\n", type); break; } free_struct_variable(uv1); return (TRUE); } /* Try to coerce it.. */ if ((type == CP_NUM) && (v->va_type == CP_REAL)) { *(int *) retval = (int) v->va_real; } else if ((type == CP_REAL) && (v->va_type == CP_NUM)) { *(double *) retval = (double) v->va_num; } else if ((type == CP_STRING) && (v->va_type == CP_NUM)) { sprintf((char*) retval, "%d", v->va_num); } else if ((type == CP_STRING) && (v->va_type == CP_REAL)) { sprintf((char*) retval, "%f", v->va_real); } else { free_struct_variable(uv1); return (FALSE); } free_struct_variable(uv1); return (TRUE); }