⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inp.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher$Id: inp.c,v 1.14 2005/06/09 01:38:47 sjborley Exp $**********//* * SJB 22 May 2001 * Fixed memory leaks accociated with freeing memory used by lines in the input deck * in inp_spsource(). New line_free() routine added to help with this. *//* * Stuff for dealing with spice input decks and command scripts, and * the listing routines. */#include "ngspice.h"#include "cpdefs.h"#include "inpdefs.h"#include "ftedefs.h"#include "dvec.h"#include "fteinp.h"#include "inp.h"#include "circuits.h"#include "completion.h"#include "variable.h"#include "breakp2.h"#ifdef XSPICE/* gtri - add - 12/12/90 - wbk - include new stuff */#include "ipctiein.h"#include "enh.h"/* gtri - end - 12/12/90 */#endif#define line_free(line,flag)	{ line_free_x(line,flag); line = NULL; }/* static declarations */static char * upper(register char *string);static bool doedit(char *filename);static void line_free_x(struct line * deck, bool recurse);/* Do a listing. Use is listing [expanded] [logical] [physical] [deck] */voidcom_listing(wordlist *wl){    int type = LS_LOGICAL;    bool expand = FALSE;    char *s;    if (ft_curckt) {  /* if there is a current circuit . . . .  */        while (wl) {            s = wl->wl_word;            switch (*s) {                case 'l':                case 'L':                    type = LS_LOGICAL;                    break;                case 'p':                case 'P':                    type = LS_PHYSICAL;                    break;                case 'd':                case 'D':                    type = LS_DECK;                    break;                case 'e':                case 'E':                    expand = TRUE;                    break;                default:                    fprintf(cp_err,                    "Error: bad listing type %s\n", s);                    return; /* SJB - don't go on after an error */            }            wl = wl->wl_next;        }        if (type != LS_DECK)            fprintf(cp_out, "\t%s\n\n", ft_curckt->ci_name);        inp_list(cp_out, expand ? ft_curckt->ci_deck :                ft_curckt->ci_origdeck, ft_curckt->ci_options,                type);    } else        fprintf(cp_err, "Error: no circuit loaded.\n");    return;}static char *upper(char *string){    static char buf[BSIZE_SP];    if (string) {	strncpy(buf, string, BSIZE_SP - 1);	buf[BSIZE_SP - 1] = 0;	inp_casefix(buf);    } else {	strcpy(buf, "<null>");    }    return buf;}/* Provide an input listing on the specified file of the given card * deck.  The listing should be of either LS_PHYSICAL or LS_LOGICAL or * LS_DECK lines as specified by the type parameter.  */voidinp_list(FILE *file, struct line *deck, struct line *extras, int type){    struct line *here;    struct line *there;    bool renumber;    bool useout = (file == cp_out);    int i = 1;/* gtri - wbk - 03/07/91 - Don't use 'more' type output if ipc enabled */#ifdef XSPICE    if(g_ipc.enabled) {        useout = FALSE;    }#endif/* gtri - end - 03/07/91 */    if (useout)        out_init();    cp_getvar("renumber", VT_BOOL, (char *) &renumber);    if (type == LS_LOGICAL) {top1:	for (here = deck; here; here = here->li_next) {            if (renumber)                here->li_linenum = i;            i++;            if (ciprefix(".end", here->li_line) &&                    !isalpha(here->li_line[4]))                continue;            if (*here->li_line != '*') {                if (useout) {                    sprintf(out_pbuf, "%6d : %s\n",                            here->li_linenum,                            upper(here->li_line));		    out_send(out_pbuf);                } else                    fprintf(file, "%6d : %s\n",                            here->li_linenum,                            upper(here->li_line));                if (here->li_error) {                    if (useout) {                        out_printf("%s\n", here->li_error);                    } else                        fprintf(file, "%s\n", here->li_error);                }            }        }        if (extras) {            deck = extras;            extras = NULL;            goto top1;        }        if (useout) {            sprintf(out_pbuf, "%6d : .end\n", i);        out_send(out_pbuf);        } else            fprintf(file, "%6d : .end\n", i);    } else if ((type == LS_PHYSICAL) || (type == LS_DECK)) {top2:	for (here = deck; here; here = here->li_next) {            if ((here->li_actual == NULL) || (here == deck)) {                if (renumber)                    here->li_linenum = i;                i++;                if (ciprefix(".end", here->li_line) &&                        !isalpha(here->li_line[4]))                    continue;                if (type == LS_PHYSICAL) {                    if (useout) {                        sprintf(out_pbuf, "%6d : %s\n",				here->li_linenum,				upper(here->li_line));			out_send(out_pbuf);                    } else                        fprintf(file, "%6d : %s\n",				here->li_linenum,				upper(here->li_line));                } else {                    if (useout)                        out_printf("%s\n",				   upper(here->li_line));                    else                        fprintf(file, "%s\n",				upper(here->li_line));                }                if (here->li_error && (type == LS_PHYSICAL)) {                    if (useout)                        out_printf("%s\n",				   here->li_error);                    else                        fprintf(file, "%s\n",				here->li_error);                }            } else {                for (there = here->li_actual; there;                        there = there->li_next) {                    there->li_linenum = i++;                    if (ciprefix(".end", here->li_line) &&                            isalpha(here->li_line[4]))                        continue;                    if (type == LS_PHYSICAL) {                        if (useout) {                            sprintf(out_pbuf, "%6d : %s\n",				    there->li_linenum,				    upper(there->li_line));			    out_send(out_pbuf);                        } else                            fprintf(file, "%6d : %s\n",				    there->li_linenum,				    upper(there->li_line));                    } else {                        if (useout)                            out_printf("%s\n",                                upper(there->li_line));                        else                            fprintf(file, "%s\n",                                upper(there->li_line));                    }                    if (there->li_error &&                             (type == LS_PHYSICAL)) {                        if (useout)                            out_printf("%s\n",                            there->li_error);                        else                            fprintf(file, "%s\n",                            there->li_error);                    }                }                here->li_linenum = i;            }        }        if (extras) {            deck = extras;            extras = NULL;            goto top2;        }        if (type == LS_PHYSICAL) {            if (useout) {                sprintf(out_pbuf, "%6d : .end\n", i);                out_send(out_pbuf);            } else                fprintf(file, "%6d : .end\n", i);        } else {            if (useout)                out_printf(".end\n");            else                fprintf(file, ".end\n");        }    } else        fprintf(cp_err, "inp_list: Internal Error: bad type %d\n",                 type);    return;}/* * Free memory used by a line. * If recure is TRUE then recursivly free all lines linked via the li_next field. * If recurse is FALSE free only this line. * All lines linked via the li_actual field are always recursivly freed. * SJB - 22nd May 2001 */static voidline_free_x(struct line * deck, bool recurse) {    if(!deck)	return;    tfree(deck->li_line);    tfree(deck->li_error);    if(recurse)	line_free(deck->li_next,TRUE);    line_free(deck->li_actual,TRUE);    tfree(deck);}/* The routine to source a spice input deck. We read the deck in, take * out the front-end commands, and create a CKT structure. Also we * filter out the following cards: .save, .width, .four, .print, and * .plot, to perform after the run is over.  * Then, we run dodeck, which parses up the deck.             */voidinp_spsource(FILE *fp, bool comfile, char *filename)     /* arguments:      *  *fp = pointer to the input file      *  comfile = whether it is a command file.  Values are TRUE/FALSE      *  *filename =       */{    struct line *deck, *dd, *ld;    struct line *realdeck, *options = NULL;    char *tt = NULL, name[BSIZE_SP], *s, *t;    bool nosubckts, commands = FALSE;    wordlist *wl = NULL, *end = NULL, *wl_first = NULL;    wordlist *controls = NULL;    FILE *lastin, *lastout, *lasterr;    /* read in the deck from a file */    inp_readall(fp, &deck);    /* if nothing came back from inp_readall, just close fp and return to caller */    if (!deck) {	/* MW. We must close fp always when returning */        fclose(fp);        return;    }        if (!comfile)        options = inp_getopts(deck);    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 input\n");    }    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 cards .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] == '*')                    cp_evloop(dd->li_line + 2);                else                    cp_evloop(dd->li_line);	    }	    line_free(dd,FALSE); /* SJB - free this line's memory */        }       } /* end if(comfile) */     else {    /* must be regular deck . . . . */	for (dd = deck->li_next; dd; dd = ld->li_next) {    /* loop through deck and handle control cards */	    /* Ignore comment lines, but not lines begining with '*#' */	    s = dd->li_line;	    while(isspace(*s)) s++;            if ( (*s == '*') && ( (s != dd->li_line) || (s[1] != '#'))) {                ld = dd;                continue;            }	                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;		line_free(dd,FALSE); /* SJB - free this line's memory */                if (commands)                    fprintf(cp_err, "Warning: redundant .control card\n");                else                    commands = TRUE;            } else if (ciprefix(".endc", dd->li_line)) {                ld->li_next = dd->li_next;		line_free(dd,FALSE); /* SJB - free this line's memory */                if (commands)                    commands = FALSE;                else                    fprintf(cp_err, "Warning: misplaced .endc card\n");            } else if (commands || prefix("*#", dd->li_line)) {                wl = alloc(struct wordlist);                if (controls) {                    wl->wl_next = controls;                    controls->wl_prev = wl;                    controls = wl;                } else                    controls = wl;		                if (prefix("*#", dd->li_line))                    wl->wl_word = copy(dd->li_line + 2);                else {                    wl->wl_word = dd->li_line;		    dd->li_line = 0; /* SJB - prevent line_free() freeing the string (now pointed at by wl->wl_word) */		}#ifdef NUMPARAMS		/* Look for set or unset numparams.		   If either are found then we evaluate these lines immediately		   so they take effect before netlist parsing */		s = wl->wl_word;		while(isspace(*s)) s++;	/* step past any white space */		if(ciprefix("set", s)) {		    s+=3;		} else if(ciprefix("unset", s)) {		    s+=5;		}		if(s!=dd->li_line) {	/* one of the above must have matched */		    while(isspace(*s)) s++;	/* step past white space */		    if(ciprefix("numparams", s)) {			cp_evloop(wl->wl_word);		    }		}#endif /* NUMPARAMS */                ld->li_next = dd->li_next;		line_free(dd,FALSE); /* SJB - free this line's memory */            } else if (!*dd->li_line) {                /* So blank lines in com files don't get considered as                 * circuits.  */                ld->li_next = dd->li_next;		line_free(dd,FALSE); /* SJB - free this line's memory */            } 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")

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -