📄 inp.c
字号:
|| eq(s, ".op") || eq(s, ".tf")) { if (end) { end->wl_next = alloc(struct wordlist); end->wl_next->wl_prev = end; end = end->wl_next; } 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; line_free(dd,FALSE); /* SJB - free this line's memory */ } else ld = dd; } else ld = dd; } } /* end for(dd=deck->li_next . . . . */ /* we are done handling the control stuff. Now process remainder of deck */ if (deck->li_next) { /* There is something left after the controls. */ fprintf(cp_out, "\nCircuit: %s\n\n", tt); /* Old location of ENHtranslate_poly. This didn't work, because it * didn't handle models in .SUBCKTs correctly. Moved to new location below * by SDB on 4.13.2003 */ /* 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)) if( (deck->li_next = inp_subcktexpand(deck->li_next)) == NULL ){ line_free(realdeck,TRUE); line_free(deck->li_actual, TRUE); return; } /* done expanding subcircuit macros */ /* Now handle translation of spice2c6 POLYs. *//* New location of ENHtranslate_poly. This should handle .SUBCKTs better . . . . * SDB 4.13.2003. Comments? mailto:sdb@cloud9.net */#ifdef XSPICE/* gtri - wbk - Translate all SPICE 2G6 polynomial type sources */ deck->li_next = ENHtranslate_poly(deck->li_next);/* gtri - end - Translate all SPICE 2G6 polynomial type sources */#endif line_free(deck->li_actual,FALSE); /* SJB - free memory used by old li_actual (if any) */ deck->li_actual = realdeck; /* now call inp_dodeck, which loads deck into ft_curckt -- the current circuit. */ inp_dodeck(deck, tt, wl_first, FALSE, options, filename); } /* if (deck->li_next) */#ifdef TRACE /* SDB debug statement */ printf("In inp_spsource, done with dodeck.\n");#endif /* Now that the deck is loaded, do the commands, if there are any */ if (controls) { for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next) cp_evloop(wl->wl_word); wl_free(end); } } /* Hitoshi Tanaka */ if(dbs) tfree(dbs); /* Added */ /*saj, to process save commands always, not just in batch mode *(breaks encapsulation of frountend and parsing commands slightly)*/ ft_dotsaves(); /* 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. *//*------------------------------------------------------------------ * It appears that inp_dodeck adds the circuit described by *deck * to the current circuit (ft_curckt). *-----------------------------------------------------------------*/voidinp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *options, char *filename) /*fcn arguments: * *deck = the spice deck * *tt = the title of the deck * *end = pointer to the wordlist * reuse * *options * *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); } cp_getvar("noparse", VT_BOOL, (char *) &noparse); /*---------------------------------------------------- * Now assuming that we wanna parse this deck, we call * if_inpdeck which takes the deck and returns a * a pointer to the circuit ckt. *---------------------------------------------------*/ if (!noparse) ckt = if_inpdeck(deck, &tab); else ckt = NULL; out_init(); /*---------------------------------------------------- * Now run throuh the deck and look to see if there are * errors on any line. *---------------------------------------------------*/ for (dd = deck; dd; dd = dd->li_next) { #ifdef TRACE /* SDB debug statement */ printf("In inp_dodeck, looking for errors and examining line %s . . . \n", dd->li_line); #endif if (dd->li_error) { char *p, *q; #ifdef XSPICE /* gtri - modify - 12/12/90 - wbk - add setting of ipc syntax error flag */ g_ipc.syntax_error = IPC_TRUE;#endif/* gtri - end - 12/12/90 */ p = dd->li_error; do { q =strchr(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); } /* end if (dd->li_error) */ } /* for (dd = deck; dd; dd = dd->li_next) */ /* Add this circuit to the circuit list. If reuse is TRUE then use * the ft_curckt structure. */ if (!reuse) { /* Be sure that ci_devices and ci_nodes are valid */ ft_curckt->ci_devices = cp_kwswitch(CT_DEVNAMES, (char *) NULL); cp_kwswitch(CT_DEVNAMES, ft_curckt->ci_devices); ft_curckt->ci_nodes = cp_kwswitch(CT_NODENAMES, (char *) NULL); cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes); ft_newcirc(ct); /* Assign current circuit */ 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; /* attach the input ckt to the list of circuits */ 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; } /* switch . . . */ } } /* if (!noparse) . . . */ 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(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"); fclose(fp); } else if (!ft_curckt) { if (!(fp = fopen(filename, "w"))) { perror(filename); cp_interactive = inter; return; } fprintf(fp, "SPICE 3 test deck\n"); 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); /* fclose(fp); */ /* MW. inp_spsource already closed fp */ if (ft_curckt && !ft_curckt->ci_filename) unlink(filename); } cp_interactive = inter; /* note: default is to run circuit after successful edit */ fprintf(cp_out, "run circuit? "); fflush(cp_out); fgets(buf, BSIZE_SP, stdin); if (buf[0] != 'n') { fprintf(cp_out, "running circuit\n"); com_run(NULL); } return;}static booldoedit(char *filename){ 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/bin/vi"; } } sprintf(buf, "%s %s", editor, filename); return (system(buf) ? FALSE : TRUE);}voidcom_source(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); fclose(fp); cp_interactive = TRUE; unlink(tempfile); return; } while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0) fwrite(buf, 1, i, fp); fclose(tp); wl = wl->wl_next; } 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 spice initialisation file. */ if (ft_nutmeg || substring(INITSTR, owl->wl_word) || substring(ALT_INITSTR, 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; if (tempfile) unlink(tempfile); return;}voidinp_source(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 + -