double * readtics(char *string) { int k; char *words, *worde; double *tics, *ticsk; tics = TMALLOC(double, MAXTICS); ticsk = tics; words = string; for (k = 0; *words && k < MAXTICS; words = worde) { words = skip_ws(words); worde = words; while (isalpha_c(*worde) || isdigit_c(*worde)) worde++; if (*worde) *worde++ = '\0'; sscanf(words, "%lf", ticsk++); k++; } *ticsk = HUGE; return (tics); }
static int is_dns_compliant(const char *s0, const char *slim) { int has_nondigit = 0, len = 0; const char *s; for (s = s0; s < slim; len++, s++) if (islower_c(*s)) has_nondigit = 1; else if (*s == '-') { has_nondigit = 1; if (s == s0 || s+1 == slim) return 0; } else if (isdigit_c(*s)) ; else if (*s == '.') { if (s == s0 || ! isalnum_c(s[-1])) return 0; if (s+1 == slim || ! isalnum_c(s[1])) return 0; } else return 0; return has_nondigit && len >= 3 && len <= 63; }
/* 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); }
double INPevaluate(char **line, int *error, int gobble) /* gobble: non-zero to gobble rest of token, zero to leave it alone */ { char *token; char *here; double mantis; int expo1; int expo2; int sign; int expsgn; char *tmpline; /* setup */ tmpline = *line; if (gobble) { /* MW. INPgetUTok should be called with gobble=0 or it make * errors in v(1,2) exp */ *error = INPgetUTok(line, &token, 0); if (*error) return (0.0); } else { token = *line; *error = 0; } mantis = 0; expo1 = 0; expo2 = 0; sign = 1; expsgn = 1; /* loop through all of the input token */ here = token; if (*here == '+') here++; /* plus, so do nothing except skip it */ else if (*here == '-') { /* minus, so skip it, and change sign */ here++; sign = -1; } if ((*here == '\0') || ((!(isdigit_c(*here))) && (*here != '.'))) { /* number looks like just a sign! */ *error = 1; if (gobble) { FREE(token); /* back out the 'gettok' operation */ *line = tmpline; } return (0); } while (isdigit_c(*here)) { /* digit, so accumulate it. */ mantis = 10 * mantis + *here - '0'; here++; } if (*here == '\0') { /* reached the end of token - done. */ if (gobble) { FREE(token); } else { *line = here; } return ((double) mantis * sign); } if (*here == ':') { /* ':' is no longer used for subcircuit node numbering but is part of ternary function a?b:c FIXME : subcircuit models still use ':' for model numbering Will this hurt somewhere? */ if (gobble) { FREE(token); } else { *line = here; } return ((double) mantis * sign); } /* after decimal point! */ if (*here == '.') { /* found a decimal point! */ here++; /* skip to next character */ if (*here == '\0') { /* number ends in the decimal point */ if (gobble) { FREE(token); } else { *line = here; } return ((double) mantis * sign); } while (isdigit_c(*here)) { /* digit, so accumulate it. */ mantis = 10 * mantis + *here - '0'; expo1 = expo1 - 1; here++; } } /* now look for "E","e",etc to indicate an exponent */ if ((*here == 'E') || (*here == 'e') || (*here == 'D') || (*here == 'd')) { /* have an exponent, so skip the e */ here++; /* now look for exponent sign */ if (*here == '+') here++; /* just skip + */ else if (*here == '-') { here++; /* skip over minus sign */ expsgn = -1; /* and make a negative exponent */ /* now look for the digits of the exponent */ } while (isdigit_c(*here)) { expo2 = 10 * expo2 + *here - '0'; here++; } } /* now we have all of the numeric part of the number, time to * look for the scale factor (alphabetic) */ switch (*here) { case 't': case 'T': expo1 = expo1 + 12; break; case 'g': case 'G': expo1 = expo1 + 9; break; case 'k': case 'K': expo1 = expo1 + 3; break; case 'u': case 'U': expo1 = expo1 - 6; break; case 'n': case 'N': expo1 = expo1 - 9; break; case 'p': case 'P': expo1 = expo1 - 12; break; case 'f': case 'F': expo1 = expo1 - 15; break; case 'm': case 'M': if (((here[1] == 'E') || (here[1] == 'e')) && ((here[2] == 'G') || (here[2] == 'g'))) { expo1 = expo1 + 6; /* Meg */ } else if (((here[1] == 'I') || (here[1] == 'i')) && ((here[2] == 'L') || (here[2] == 'l'))) { expo1 = expo1 - 6; mantis *= 25.4; /* Mil */ } else { expo1 = expo1 - 3; /* m, milli */ } break; default: break; } if (gobble) { FREE(token); } else { *line = here; } return (sign * mantis * pow(10.0, (double) (expo1 + expsgn * expo2))); }