bool cp_oddcomm(char *s, wordlist *wl) { FILE *fp; if ((fp = inp_pathopen(s, "r")) != NULL) { char buf[BSIZE_SP]; wordlist *setarg; (void) fclose(fp); (void) sprintf(buf, "argc = %d argv = ( ", wl_length(wl)); while (wl) { (void) strcat(buf, wl->wl_word); (void) strcat(buf, " "); wl = wl->wl_next; } (void) strcat(buf, ")"); setarg = cp_lexer(buf); com_set(setarg); wl_free(setarg); inp_source(s); cp_remvar("argc"); cp_remvar("argv"); return (TRUE); } if (wl && eq(wl->wl_word, "=")) { wordlist *ww = wl_cons(copy(s), wl); com_let(ww); wl_delete_slice(ww, ww->wl_next); return (TRUE); } return (FALSE); }
static wordlist * backeval(char *string) { #ifdef HAVE_POPEN FILE *proc, *old; wordlist *wl; bool intv; proc = popen(string, "r"); if (proc == NULL) { fprintf(cp_err, "Error: can't evaluate %s.\n", string); return (NULL); } old = cp_inp_cur; cp_inp_cur = proc; intv = cp_interactive; cp_interactive = FALSE; cp_bqflag = TRUE; wl = cp_lexer(NULL); cp_bqflag = FALSE; cp_inp_cur = old; cp_interactive = intv; (void) pclose(proc); return (wl); #else wordlist *wl = wl_cons(copy(string), NULL); return (wl); #endif }
bool cp_oddcomm(char *s, wordlist *wl) { FILE *fp; char buf[BSIZE_SP]; wordlist ww; if ((fp = inp_pathopen(s, "r"))) { (void) fclose(fp); (void) sprintf(buf, "argc = %d argv = ( ", wl_length(wl)); while (wl) { (void) strcat(buf, wl->wl_word); (void) strcat(buf, " "); wl = wl->wl_next; } (void) strcat(buf, ")"); com_set(cp_lexer(buf)); inp_source(s); cp_remvar("argc"); cp_remvar("argv"); return (TRUE); } else if (wl && eq(wl->wl_word, "=")) { ww.wl_next = wl; wl->wl_prev = &ww; ww.wl_prev = NULL; ww.wl_word = s; com_let(&ww); return (TRUE); } else return (FALSE); }
void ft_cpinit(void) { bool found = FALSE, t = TRUE; char buf[BSIZE_SP], **x, *s, *r, *copys; struct comm *c; int i; FILE *fp; static char *predefs[] = { "yes", "1", "TRUE", "1", "no", "0", "FALSE", "0", "pi", "3.14159265358979323846", "e", "2.71828182845904523536", "c", "2.997925e8", "i", "0,1", "kelvin", "-273.15", "echarge", "1.60219e-19", "boltz", "1.38062e-23", "planck", "6.62620e-34" }; static char *udfs[] = { "max(x,y)", "(x gt y) * x + (x le y) * y", "min(x,y)", "(x lt y) * x + (x ge y) * y", "vdb(x)", "db(v(x))", "vdb(x,y)", "db(v(x) - v(y))", "vi(x)", "im(v(x))", "vi(x,y)", "im(v(x) - v(y))", "vm(x)", "mag(v(x))", "vm(x,y)", "mag(v(x) - v(y))", "vg(x)", "group_delay(v(x))", //A.Rroldan 10/06/05 group delay new function "gd(x)", "group_delay(v(x))", //A.Rroldan 10/06/05 group delay new function "vp(x)", "ph(v(x))", "vp(x,y)", "ph(v(x) - v(y))", "vr(x)", "re(v(x))", "vr(x,y)", "re(v(x) - v(y))" }; /* if TIOCSTI is defined (not available in MS Windows: Make escape the break character. So the user can type ahead... fcn defined in complete.c. */ cp_ccon(TRUE); /* Initialize io, cp_chars[], variable "history" in init.c. */ cp_init(); /* If command completion is available (global variable cp_nocc set in main.c by command line option -q) */ if (!cp_nocc) { /* Add commands... */ for (c = cp_coms; c->co_func; c++) { if (c->co_spiceonly && ft_nutmeg) continue; cp_addcomm(c->co_comname, c->co_cctypes[0], c->co_cctypes[1], c->co_cctypes[2], c->co_cctypes[3]); cp_addkword(CT_COMMANDS, c->co_comname); } /* And keywords... These are the ones that are constant... */ if (!ft_nutmeg) { cp_addkword(CT_LISTINGARGS, "deck"); cp_addkword(CT_LISTINGARGS, "logical"); cp_addkword(CT_LISTINGARGS, "physical"); cp_addkword(CT_LISTINGARGS, "expand"); cp_addkword(CT_STOPARGS, "when"); cp_addkword(CT_STOPARGS, "after"); } cp_addkword(CT_PLOT, "new"); cp_addkword(CT_PLOTKEYWORDS, "xlimit"); cp_addkword(CT_PLOTKEYWORDS, "ylimit"); cp_addkword(CT_PLOTKEYWORDS, "vs"); cp_addkword(CT_PLOTKEYWORDS, "xindices"); cp_addkword(CT_PLOTKEYWORDS, "xcompress"); cp_addkword(CT_PLOTKEYWORDS, "xdelta"); cp_addkword(CT_PLOTKEYWORDS, "ydelta"); cp_addkword(CT_PLOTKEYWORDS, "lingrid"); cp_addkword(CT_PLOTKEYWORDS, "loglog"); cp_addkword(CT_PLOTKEYWORDS, "linear"); cp_addkword(CT_PLOTKEYWORDS, "xlog"); cp_addkword(CT_PLOTKEYWORDS, "ylog"); cp_addkword(CT_PLOTKEYWORDS, "polar"); cp_addkword(CT_PLOTKEYWORDS, "smith"); cp_addkword(CT_PLOTKEYWORDS, "smithgrid"); cp_addkword(CT_PLOTKEYWORDS, "nointerp"); cp_addkword(CT_PLOTKEYWORDS, "title"); cp_addkword(CT_PLOTKEYWORDS, "xlabel"); cp_addkword(CT_PLOTKEYWORDS, "ylabel"); cp_addkword(CT_PLOTKEYWORDS, "linplot"); cp_addkword(CT_PLOTKEYWORDS, "combplot"); cp_addkword(CT_PLOTKEYWORDS, "pointplot"); cp_addkword(CT_RUSEARGS, "time"); cp_addkword(CT_RUSEARGS, "space"); cp_addkword(CT_RUSEARGS, "faults"); cp_addkword(CT_RUSEARGS, "elapsed"); cp_addkword(CT_RUSEARGS, "totiter"); cp_addkword(CT_RUSEARGS, "traniter"); cp_addkword(CT_RUSEARGS, "tranpoints"); cp_addkword(CT_RUSEARGS, "accept"); cp_addkword(CT_RUSEARGS, "rejected"); cp_addkword(CT_RUSEARGS, "time"); cp_addkword(CT_RUSEARGS, "trantime"); cp_addkword(CT_RUSEARGS, "lutime"); cp_addkword(CT_RUSEARGS, "solvetime"); cp_addkword(CT_RUSEARGS, "transolvetime"); cp_addkword(CT_RUSEARGS, "loadtime"); cp_addkword(CT_RUSEARGS, "all"); cp_addkword(CT_VECTOR, "all"); for (x = ft_setkwords; *x; x++) cp_addkword(CT_VARIABLES, *x); for (i = 0; ; i++) { if ((s = ft_typenames(i)) == NULL) break; cp_addkword(CT_TYPENAMES, s); } } cp_vset("program", CP_STRING, cp_program); /* Make the prompt use only the last component of the path... */ if (DIR_TERM) { for (s = cp_program; s && *s; s++) ; s--; while ((s > cp_program) && (*s != DIR_TERM)) s--; if (*s == DIR_TERM) s++; (void) strcpy(buf, s); for (s = buf; *s && (*s != '.'); s++) ; *s = '\0'; (void) strcat(buf, " ! -> "); } else { (void) sprintf(buf, "%s ! -> ", cp_program); } cp_vset("prompt", CP_STRING, buf); cp_vset("noglob", CP_BOOL, &t); cp_vset("brief", CP_BOOL, &t); /* Make vectors from values in predefs[] for the current plot. Define functions from entries in udfs[] (like user defined functions). */ { wordlist wl1, wl2, wl3; wl1.wl_next = &wl2; wl1.wl_prev = NULL; wl2.wl_next = NULL; wl2.wl_prev = &wl1; wl1.wl_word = "if"; wl2.wl_word = "1"; cp_setalias("begin", &wl1); wl1.wl_next = NULL; wl1.wl_word = "end"; cp_setalias("endif", &wl1); cp_setalias("endwhile", &wl1); cp_setalias("endforeach", &wl1); cp_setalias("endrepeat", &wl1); cp_setalias("enddowhile", &wl1); wl1.wl_word = "help"; cp_setalias("?", &wl1); wl1.wl_next = &wl2; wl2.wl_next = &wl3; wl2.wl_prev = &wl1; wl3.wl_prev = &wl2; wl3.wl_next = NULL; wl2.wl_word = "="; for (i = 0; (size_t) i < NUMELEMS(predefs); i += 2) { wl1.wl_word = predefs[i]; wl3.wl_word = predefs[i + 1]; com_let(&wl1); } wl2.wl_next = NULL; for (i = 0; (size_t) i < NUMELEMS(udfs); i += 2) { wl1.wl_word = udfs[i]; wl2.wl_word = udfs[i + 1]; com_define(&wl1); } } /* Reset this for the front end. */ cp_hash = '*'; /* NGSPICEDATADIR has been set to path "$dprefix/share/ngspice" in configure.ac, Spice_Lib_Dir has been set to NGSPICEDATADIR in conf.c, may be overridden by environmental variable SPICE_LIB_DIR in ivars(). Lib_Path has been set to Spice_Lib_Dir adding /scripts in ivars() */ if (Lib_Path && *Lib_Path) { /* set variable 'sourcepath' */ if (Inp_Path && *Inp_Path) (void) sprintf(buf, "sourcepath = ( %s %s %s )", DIR_CWD, Lib_Path, Inp_Path); else (void) sprintf(buf, "sourcepath = ( %s %s )", DIR_CWD, Lib_Path); { wordlist *wl; wl = cp_doglob(cp_lexer(buf)); cp_striplist(wl); com_set(wl); wl_free(wl); } /* Now source the standard startup file spinit or tclspinit. */ /* jump over leading spaces */ for (copys = s = cp_tildexpand(Lib_Path); copys && *copys; ) { while (isspace(*s)) s++; /* copy s into buf until space is seen, r is the actual position */ for (r = buf; *s && !isspace(*s); r++, s++) *r = *s; tfree(copys); /* add a path separator to buf at actual position */ (void) strcpy(r, DIR_PATHSEP); #ifdef TCL_MODULE /* add "tclspinit" to buf after actual position */ (void) strcat(r, "tclspinit"); #else /* add "spinit" to buf after actual position */ (void) strcat(r, "spinit"); #endif if ((fp = fopen(buf, "r")) != NULL) { cp_interactive = FALSE; inp_spsource(fp, TRUE, buf, FALSE); cp_interactive = TRUE; found = TRUE; break; #if defined(HAS_WINGUI) || defined(__MINGW32__) || defined(_MSC_VER) /* search in local directory where ngspice.exe resides */ #if defined TCL_MODULE } else if ((fp = fopen("./tclspinit", "r")) != NULL) { #else } else if ((fp = fopen("./spinit", "r")) != NULL) { #endif cp_interactive = FALSE; inp_spsource(fp, TRUE, buf, FALSE); cp_interactive = TRUE; found = TRUE; break; #endif } else if (ft_controldb) { fprintf(cp_err, "Note: can't open \"%s\".\n", buf); } } if (!found) fprintf(cp_err, "Note: can't find init file.\n"); } tcap_init(); }
int ft_cktcoms(bool terse) { wordlist *coms, *command, all; char *plottype, *s; struct dvec *v; static wordlist twl = { "col", NULL, NULL }; struct plot *pl; int i, found; char numbuf[BSIZE_SP]; /* For printnum*/ all.wl_next = NULL; all.wl_word = "all"; if (!ft_curckt) return 1; plot_cur = setcplot("op"); if (!ft_curckt->ci_commands && !plot_cur) goto nocmds; coms = ft_curckt->ci_commands; cp_interactive = FALSE; /* Listing */ if (ft_listprint) { if (terse) fprintf(cp_err, ".options: no listing, rawfile was generated.\n"); else inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options, LS_DECK); } /* If there was a .op line, then we have to do the .op output. */ plot_cur = setcplot("op"); if (plot_cur != NULL) { assert(plot_cur->pl_dvecs != NULL); if (plot_cur->pl_dvecs->v_realdata != NULL) { if (terse) { fprintf(cp_out, "OP information in rawfile.\n"); } else { fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage"); fprintf(cp_out, "\t%-30s%15s\n", "----", "-------"); fprintf(cp_out, "\t----\t-------\n"); for (v = plot_cur->pl_dvecs; v; v = v->v_next) { if (!isreal(v)) { fprintf(cp_err, "Internal error: op vector %s not real\n", v->v_name); continue; } if ((v->v_type == SV_VOLTAGE) && (*(v->v_name) != '@')) { printnum(numbuf, v->v_realdata[0]); fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf); } } fprintf(cp_out, "\n\tSource\tCurrent\n"); fprintf(cp_out, "\t------\t-------\n\n"); for (v = plot_cur->pl_dvecs; v; v = v->v_next) if (v->v_type == SV_CURRENT) { printnum(numbuf, v->v_realdata[0]); fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf); } fprintf(cp_out, "\n"); if (!ft_nomod) com_showmod(&all); com_show(&all); } } } for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix("tf", pl->pl_typename)) { if (terse) { fprintf(cp_out, "TF information in rawfile.\n"); break; } plot_cur = pl; fprintf(cp_out, "Transfer function information:\n"); com_print(&all); fprintf(cp_out, "\n"); } /* Now all the '.' lines */ while (coms) { command = cp_lexer(coms->wl_word); if (!command) goto bad; if (eq(command->wl_word, ".width")) { do command = command->wl_next; while (command && !ciprefix("out", command->wl_word)); if (command) { s = strchr(command->wl_word, '='); if (!s || !s[1]) { fprintf(cp_err, "Error: bad line %s\n", coms->wl_word); coms = coms->wl_next; continue; } i = atoi(++s); cp_vset("width", CP_NUM, &i); } } else if (eq(command->wl_word, ".print")) { if (terse) { fprintf(cp_out, ".print line ignored since rawfile was produced.\n"); } else { command = command->wl_next; if (!command) { fprintf(cp_err, "Error: bad line %s\n", coms->wl_word); coms = coms->wl_next; continue; } plottype = command->wl_word; command = command->wl_next; fixdotprint(command); twl.wl_next = command; found = 0; for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix(plottype, pl->pl_typename)) { plot_cur = pl; com_print(&twl); fprintf(cp_out, "\n"); found = 1; } if (!found) fprintf(cp_err, "Error: .print: no %s analysis found.\n", plottype); } } else if (eq(command->wl_word, ".plot")) { if (terse) { fprintf(cp_out, ".plot line ignored since rawfile was produced.\n"); } else { command = command->wl_next; if (!command) { fprintf(cp_err, "Error: bad line %s\n", coms->wl_word); coms = coms->wl_next; continue; } plottype = command->wl_word; command = command->wl_next; fixdotplot(command); found = 0; for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix(plottype, pl->pl_typename)) { plot_cur = pl; com_asciiplot(command); fprintf(cp_out, "\n"); found = 1; } if (!found) fprintf(cp_err, "Error: .plot: no %s analysis found.\n", plottype); } } else if (ciprefix(".four", command->wl_word)) { if (terse) { fprintf(cp_out, ".fourier line ignored since rawfile was produced.\n"); } else { int err; plot_cur = setcplot("tran"); err = fourier(command->wl_next, plot_cur); if (!err) fprintf(cp_out, "\n\n"); else fprintf(cp_err, "No transient data available for " "fourier analysis"); } } else if (!eq(command->wl_word, ".save") && !eq(command->wl_word, ".op") && // !eq(command->wl_word, ".measure") && !ciprefix(".meas", command->wl_word) && !eq(command->wl_word, ".tf")) { goto bad; } coms = coms->wl_next; } nocmds: /* Now the node table if (ft_nodesprint) ; */ /* The options */ if (ft_optsprint) { fprintf(cp_out, "Options:\n\n"); cp_vprint(); (void) putc('\n', cp_out); } /* And finally the accounting info. */ if (ft_acctprint) { static wordlist ww = { "everything", NULL, NULL }; com_rusage(&ww); } else if ((!ft_noacctprint) && (!ft_acctprint)) { com_rusage(NULL); } /* absolutely no accounting if noacct is given */ putc('\n', cp_out); return 0; bad: fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n"); return 1; }
/* 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); }