📄 inp.c
字号:
} else wl_first = end = alloc(struct wordlist); end->wl_word = copy(dd->li_line); if (!eq(s, ".op") && !eq(s, ".tf")) { ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); } else ld = dd; } else ld = dd; } } if (deck->li_next) { /* There is something left after the controls. */ fprintf(cp_out, "\nCircuit: %s\n\n", tt); /* Now expand subcircuit macros. Note that we have to * fix the case before we do this but after we * deal with the commands. */ if (!cp_getvar("nosubckt", VT_BOOL, (char *) &nosubckts)) deck->li_next = inp_subcktexpand(deck-> li_next); deck->li_actual = realdeck; inp_dodeck(deck, tt, wl_first, false, options, filename); } /* Now that the deck is loaded, do the commands */ if (controls) { for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next) (void) cp_evloop(wl->wl_word); /*wl_free(end);*/ } } /* Now reset everything. Pop the control stack, and fix up the IO * as it was before the source. */ cp_popcontrol(); cp_curin = lastin; cp_curout = lastout; cp_curerr = lasterr; return;}/* This routine is cut in half here because com_rset has to do what follows * also. End is the list of commands we execute when the job is finished: * we only bother with this if we might be running in batch mode, since * it isn't much use otherwise. */voidinp_dodeck(deck, tt, end, reuse, options, filename) struct line *deck; char *tt; wordlist *end; bool reuse; struct line *options; char *filename;{ struct circ *ct; struct line *dd; char *ckt, *s; INPtables *tab; struct variable *eev = NULL; wordlist *wl; bool noparse, ii; /* First throw away any old error messages there might be and fix * the case of the lines. */ for (dd = deck; dd; dd = dd->li_next) { if (dd->li_error) { tfree(dd->li_error); dd->li_error = NULL; } } if (reuse) { ct = ft_curckt; } else { if (ft_curckt) { ft_curckt->ci_devices = cp_kwswitch(CT_DEVNAMES, (char *) NULL); ft_curckt->ci_nodes = cp_kwswitch(CT_NODENAMES, (char *) NULL); } ft_curckt = ct = alloc(struct circ); } (void) cp_getvar("noparse", VT_BOOL, (char *) &noparse); if (!noparse) ckt = if_inpdeck(deck, &tab); else ckt = NULL; out_init(); for (dd = deck; dd; dd = dd->li_next) if (dd->li_error) { char *p, *q; p = dd->li_error; do { q = index(p, '\n'); if (q) *q = 0; if (p == dd->li_error) out_printf("Error on line %d : %s\n\t%s\n", dd->li_linenum, dd->li_line, dd->li_error); else out_printf("\t%s\n", p); if (q) *q++ = '\n'; p = q; } while (p && *p); } /* Add this circuit to the circuit list. If reuse is true then * use the ft_curckt structure. */ if (!reuse) {#ifdef notdef /* Unused time-waster. */ for (dd = deck->li_next; dd; dd = dd->li_next) if_setndnames(dd->li_line);#endif /* Be sure that ci_devices and ci_nodes are valid */ ft_curckt->ci_devices = cp_kwswitch(CT_DEVNAMES, (char *) NULL); (void) cp_kwswitch(CT_DEVNAMES, ft_curckt->ci_devices); ft_curckt->ci_nodes = cp_kwswitch(CT_NODENAMES, (char *) NULL); (void) cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes); ft_newcirc(ct); /* ft_setccirc(); */ ft_curckt = ct; } ct->ci_name = tt; ct->ci_deck = deck; ct->ci_options = options; if (deck->li_actual) ct->ci_origdeck = deck->li_actual; else ct->ci_origdeck = ct->ci_deck; ct->ci_ckt = ckt; ct->ci_symtab = tab; ct->ci_inprogress = false; ct->ci_runonce = false; ct->ci_commands = end; if (filename) ct->ci_filename = copy(filename); else ct->ci_filename = NULL; if (!noparse) { for (; options; options = options->li_next) { for (s = options->li_line; *s && !isspace(*s); s++) ; ii = cp_interactive; cp_interactive = false; wl = cp_lexer(s); cp_interactive = ii; if (!wl || !wl->wl_word || !*wl->wl_word) continue; if (eev) eev->va_next = cp_setparse(wl); else ct->ci_vars = eev = cp_setparse(wl); while (eev->va_next) eev = eev->va_next; } for (eev = ct->ci_vars; eev; eev = eev->va_next) { static int one = 1; switch (eev->va_type) { case VT_BOOL: if_option(ct->ci_ckt, eev->va_name, eev->va_type, &one); break; case VT_NUM: if_option(ct->ci_ckt, eev->va_name, eev->va_type, (char *) &eev->va_num); break; case VT_REAL: if_option(ct->ci_ckt, eev->va_name, eev->va_type, (char *) &eev->va_real); break; case VT_STRING: if_option(ct->ci_ckt, eev->va_name, eev->va_type, eev->va_string); break; } } } cp_addkword(CT_CKTNAMES, tt); return;}/* Edit and re-load the current input deck. Note that if these commands are * used on a non-unix machine, they will leave spice.tmp junk files lying * around. */voidcom_edit(wl) wordlist *wl;{ char *filename; FILE *fp; bool inter, permfile; char buf[BSIZE_SP]; inter = cp_interactive; cp_interactive = false; if (wl) { if (!doedit(wl->wl_word)) { cp_interactive = inter; return; } if (!(fp = inp_pathopen(wl->wl_word, "r"))) { perror(wl->wl_word); cp_interactive = inter; return; } inp_spsource(fp, false, wl->wl_word); } else { /* If there is no circuit yet, then create one */ if (ft_curckt && ft_curckt->ci_filename) { filename = ft_curckt->ci_filename; permfile = true; } else { filename = smktemp("sp"); permfile = false; } if (ft_curckt && !ft_curckt->ci_filename) { if (!(fp = fopen(filename, "w"))) { perror(filename); cp_interactive = inter; return; } inp_list(fp, ft_curckt->ci_deck, ft_curckt->ci_options, LS_DECK); fprintf(cp_err, "Warning: editing a temporary file -- circuit not saved\n"); (void) fclose(fp); } else if (!ft_curckt) { if (!(fp = fopen(filename, "w"))) { perror(filename); cp_interactive = inter; return; } fprintf(fp, "SPICE 3 test deck\n"); (void) fclose(fp); } if (!doedit(filename)) { cp_interactive = inter; return; } if (!(fp = fopen(filename, "r"))) { perror(filename); cp_interactive = inter; return; } inp_spsource(fp, false, permfile ? filename : (char *) NULL); (void) fclose(fp);#ifdef HAS_UNLINK if (ft_curckt && !ft_curckt->ci_filename) (void) unlink(filename);#endif } cp_interactive = inter; /* note: default is to run circuit after successful edit */ fprintf(cp_out, "run circuit? "); fflush(cp_out); (void) gets(buf); if (buf[0] != 'n') { fprintf(cp_out, "running circuit\n"); com_run(NULL); } return;}static booldoedit(filename) char *filename;{#ifdef HAS_SYSTEM char buf[BSIZE_SP], buf2[BSIZE_SP], *editor; if (cp_getvar("editor", VT_STRING, buf2)) { editor = buf2; } else { if (!(editor = getenv("EDITOR"))) { if (Def_Editor && *Def_Editor) editor = Def_Editor; else editor = "/usr/ucb/vi"; } } (void) sprintf(buf, "%s %s", editor, filename); return (system(buf) ? false : true);#else fprintf(stderr, "Editor not available\n"); return false;#endif}voidcom_source(wl) wordlist *wl;{ FILE *fp, *tp; char buf[BSIZE_SP]; bool inter; char *tempfile = NULL; wordlist *owl = wl; int i; inter = cp_interactive; cp_interactive = false; if (wl->wl_next) { /* There are several files -- put them into a temp file */ tempfile = smktemp("sp"); if (!(fp = inp_pathopen(tempfile, "w+"))) { perror(tempfile); cp_interactive = true; return; } while (wl) { if (!(tp = inp_pathopen(wl->wl_word, "r"))) { perror(wl->wl_word); (void) fclose(fp); cp_interactive = true;#ifdef HAS_UNLINK (void) unlink(tempfile);#endif return; } while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0) (void) fwrite(buf, 1, i, fp); (void) fclose(tp); wl = wl->wl_next; } (void) fseek(fp, (long) 0, 0); } else fp = inp_pathopen(wl->wl_word, "r"); if (fp == NULL) { perror(wl->wl_word); cp_interactive = true; return; } /* Don't print the title if this is a .spiceinit file. */ if (ft_nutmeg || substring(".spiceinit", owl->wl_word) || substring("spice.rc", owl->wl_word)) inp_spsource(fp, true, tempfile ? (char *) NULL : wl->wl_word); else inp_spsource(fp, false, tempfile ? (char *) NULL : wl->wl_word); cp_interactive = inter;#ifdef HAS_UNLINK if (tempfile) (void) unlink(tempfile);#endif return;}voidinp_source(file) char *file;{ static struct wordlist wl = { NULL, NULL, NULL } ; wl.wl_word = file; com_source(&wl); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -