struct line * inp_getopts(struct line *deck) { struct line *last = NULL, *opts = NULL, *dd, *next = NULL; for (dd = deck->li_next; dd; dd = next) { next = dd->li_next; if (ciprefix(".opt", dd->li_line)) { inp_casefix(dd->li_line); if (last) last->li_next = dd->li_next; else deck->li_next = dd->li_next; dd->li_next = opts; opts = dd; } else { last = dd; } } return (opts); }
//void //inp_nutsource(FILE *fp, bool comfile, char *filename) void inp_nutsource(FILE *fp, int comfile, char *filename) { struct line *deck, *dd, *ld; struct line *realdeck, *options = NULL; char *tt = NULL, name[BSIZE_SP], *s, *t; //bool commands = FALSE; int commands = FALSE; wordlist *wl = NULL, *end = NULL; wordlist *controls = NULL; FILE *lastin, *lastout, *lasterr; deck = inp_readall(fp, NULL, comfile, FALSE); /* still to check if . or filename instead of NULL */ if (!deck) return; realdeck = inp_deckcopy(deck); if (!comfile) { /* Save the title before INPgetTitle gets it. */ tt = copy(deck->li_line); if (!deck->li_next) fprintf(cp_err, "Warning: no lines in deck...\n"); } (void) fclose(fp); /* Now save the IO context and start a new control set... After * we are done with the source we'll put the old file descriptors * back. I guess we could use a FILE stack, but since this routine * is recursive anyway... */ lastin = cp_curin; lastout = cp_curout; lasterr = cp_curerr; cp_curin = cp_in; cp_curout = cp_out; cp_curerr = cp_err; cp_pushcontrol(); /* We should now go through the deck and execute front-end * commands and remove them. Front-end commands are enclosed by * the lines .control and .endc, unless comfile * is TRUE, in which case every line must be a front-end command. * There are too many problems with matching the first word on * the line. */ ld = deck; if (comfile) { /* This is easy. */ for (dd = deck; dd; dd = ld) { ld = dd->li_next; if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#')) continue; if (!ciprefix(".control", dd->li_line) && !ciprefix(".endc", dd->li_line)) { if (dd->li_line[0] == '*') (void) cp_evloop(dd->li_line + 2); else (void) cp_evloop(dd->li_line); } tfree(dd->li_line); tfree(dd); } } else { for (dd = deck->li_next; dd; dd = ld->li_next) { if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#')) { ld = dd; continue; } (void) strncpy(name, dd->li_line, BSIZE_SP); for (s = name; *s && isspace(*s); s++) ; for (t = s; *t && !isspace(*t); t++) ; *t = '\0'; if (ciprefix(".control", dd->li_line)) { ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); if (commands) fprintf(cp_err, "Warning: redundant .control line\n"); else commands = TRUE; } else if (ciprefix(".endc", dd->li_line)) { ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); if (commands) commands = FALSE; else fprintf(cp_err, "Warning: misplaced .endc line\n"); } else if (commands || prefix("*#", dd->li_line)) { controls = wl_cons(NULL, controls); wl = controls; if (prefix("*#", dd->li_line)) wl->wl_word = copy(dd->li_line + 2); else wl->wl_word = dd->li_line; ld->li_next = dd->li_next; tfree(dd); } else if (!*dd->li_line) { /* So blank lines in com files don't get * considered as circuits. */ ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); } else { inp_casefix(s); inp_casefix(dd->li_line); if (eq(s, ".width") || ciprefix(".four", s) || eq(s, ".plot") || eq(s, ".print") || eq(s, ".save")) { wl_append_word(&wl, &end, copy(dd->li_line)); ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); } else { ld = dd; } } } if (deck->li_next) { /* There is something left after the controls. */ fprintf(cp_out, "\nCircuit: %s\n\n", tt); fprintf(stderr, "\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", CP_BOOL, NULL)) deck->li_next = inp_subcktexpand(deck->li_next); deck->li_actual = realdeck; nutinp_dodeck(deck, tt, wl, FALSE, options, filename); } /* Now that the deck is loaded, do the commands... */ controls = wl_reverse(controls); for (wl = controls; wl; wl = wl->wl_next) (void) cp_evloop(wl->wl_word); wl_free(controls); } /* 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; tfree(tt); }