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

📄 control.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
                    else {                        *num = nn - 1;                        return (BROKEN_STR);                    }		case CONTINUED: /* Continue. */                    if (nn < 2) {                        cn = NULL;                        break;                    } else {                        *num = nn - 1;                        return (CONTINUED_STR);                    }		default:                    cn = findlabel(i, bl->co_children);                    if (!cn)                        return (i);                }            }        }        break;    case CO_BREAK:        if (bl->co_numtimes > 0) {            *num = bl->co_numtimes;            return (BROKEN_STR);        } else {            fprintf(cp_err, "Warning: break %d a no-op\n",                    bl->co_numtimes);            return (NORMAL_STR);        }    case CO_CONTINUE:        if (bl->co_numtimes > 0) {            *num = bl->co_numtimes;            return (CONTINUED_STR);        } else {            fprintf(cp_err, "Warning: continue %d a no-op\n",                    bl->co_numtimes);            return (NORMAL_STR);        }    case CO_GOTO:        wl = cp_variablesubst(cp_bquote(cp_doglob(	    wl_copy(bl->co_text)))); /*CDHW Leak ? CDHW*/        return (wl->wl_word);    case CO_LABEL:	/* Do nothing. */	cp_periodic();  /*CDHW needed to avoid lock-ups when loop contains only a label CDHW*/	break;    case CO_STATEMENT:        docommand(wl_copy(bl->co_text));        break;    case CO_UNFILLED:        /* There was probably an error here... */        fprintf(cp_err, "Warning: ignoring previous error\n");        break;    default:        fprintf(cp_err, 		"doblock: Internal Error: bad block type %d\n",		bl->co_type);        return (NORMAL_STR);    }    return (NORMAL_STR);}/* Maxiumum number of cheverons used for the alternative prompt */#define MAX_CHEVRONS	16/* Get the alternate prompt.   Number of chevrons indicates stack depth.   Returns NULL when there is no alternate prompt.   SJB 28th April 2005 */char * get_alt_prompt(void){    int i = 0, j;    static char buf[MAX_CHEVRONS + 2];	/* includes terminating space & null */    struct control *c;        /* if nothing on the command stack return NULL */    if (cend[stackp] <= 0)	return NULL;        /* measure stack depth */    for (c = cend[stackp]->co_parent; c; c = c->co_parent)	i++;        if (i <= 0)	return NULL;        /* Avoid overflow of buffer and       indicate when we've limited the chevrons by starting with a '+' */    if(i > MAX_CHEVRONS) {	i = MAX_CHEVRONS;	buf[0]='+';    } else {	buf[0]='>';    }         /* return one chevron per command stack depth */    for (j = 1; j < i; j++)	buf[j] = '>';        /* Add space and terminate */    buf[j] = ' ';    buf[j + 1] = '\0';        return buf;}/* Get a command. This does all the bookkeeping things like turning * command completion on and off...  */static wordlist *getcommand(char *string){    wordlist *wlist;    if (cp_debug)        fprintf(cp_err, "calling getcommand %s\n", string ? string : "");#if !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE)    /* set cp_altprompt for use by the lexer - see parser/lexical.c */    cp_altprompt = get_alt_prompt();#endif /* !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE) */        cp_cwait = TRUE;    wlist = cp_parse(string);    cp_cwait = FALSE;    if (cp_debug) {        printf("getcommand ");        wl_print(wlist, stdout);        putc('\n', stdout);    }    return (wlist);}/* va: TODO: free control structure(s) before overwriting (memory leakage) */intcp_evloop(char *string){    wordlist *wlist, *ww;    struct control *x;    char *i;    int nn;#define newblock    cend[stackp]->co_children = alloc(struct control);      \	    ZERO(cend[stackp]->co_children,struct control), \            cend[stackp]->co_children->co_parent = cend[stackp]; \            cend[stackp] = cend[stackp]->co_children;        \            cend[stackp]->co_type = CO_UNFILLED;    for (;;) {	wlist = getcommand(string);	if (wlist == NULL) {    /* End of file or end of user input. */	    if (cend[stackp]->co_parent && !string) {		cp_resetcontrol();		continue;	    } else		return (0);	}	if ((wlist->wl_word == NULL) || (*wlist->wl_word == '\0')) {	    /* User just typed return. */	    wl_free(wlist); /* va, avoid memory leak */	    if (string)		return (1);	    else {		cp_event--;		continue;	    }	}	/* Just a check... */	for (ww = wlist; ww; ww = ww->wl_next)	    if (!ww->wl_word) {		fprintf(cp_err, 			"cp_evloop: Internal Error: NULL word pointer\n");		continue;	    }	/* Add this to the control structure list. If cend->co_type is	 * CO_UNFILLED, the last line was the beginning of a block,	 * and this is the unfilled first statement.  	 */	/* va: TODO: free old structure and its content, before overwriting */ 	if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {	    cend[stackp]->co_next = alloc(struct control);	    ZERO(cend[stackp]->co_next, struct control);	    cend[stackp]->co_next->co_prev = cend[stackp];	    cend[stackp]->co_next->co_parent = 		cend[stackp]->co_parent;	    cend[stackp] = cend[stackp]->co_next;	} else if (!cend[stackp]) {	    control[stackp] = cend[stackp] = alloc(struct control);	    ZERO(cend[stackp], struct control);	}	if (eq(wlist->wl_word, "while")) {	    cend[stackp]->co_type = CO_WHILE;	    cend[stackp]->co_cond = wl_copy(wlist->wl_next); /* va, wl_copy */	    if (!cend[stackp]->co_cond) {		fprintf(stderr,			"Error: missing while condition, 'false' will be assumed.\n");	    }	    newblock;	} else if (eq(wlist->wl_word, "dowhile")) {	    cend[stackp]->co_type = CO_DOWHILE;	    cend[stackp]->co_cond = wl_copy(wlist->wl_next); /* va, wl_copy */	    if (!cend[stackp]->co_cond) {	    	/* va: prevent misinterpretation as trigraph sequence with \-sign */		fprintf(stderr,			"Error: missing dowhile condition, '?\?\?' will be assumed.\n");	    }	    newblock;	} else if (eq(wlist->wl_word, "repeat")) {	    cend[stackp]->co_type = CO_REPEAT;	    if (!wlist->wl_next) {		cend[stackp]->co_numtimes = -1;	    } else {		char *s;		double *dd;				struct wordlist *t;  /*CDHW*/        	/*CDHW wlist = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(wlist)))); Wrong order? Leak? CDHW*/        	t = cp_doglob(cp_bquote(cp_variablesubst(wl_copy(wlist)))); /*CDHW leak from cp_doglob? */        	s = t->wl_next->wl_word;				dd = ft_numparse(&s, FALSE);		if (dd) {		    if (*dd < 0) {			fprintf(cp_err, 				"Error: can't repeat a negative number of times\n");			*dd = 0.0;		    }		    cend[stackp]->co_numtimes = (int) *dd;		} else		    fprintf(cp_err, 			    "Error: bad repeat argument %s\n",			    t->wl_next->wl_word); /* CDHW */		    wl_free(t); t = NULL;  /* CDHW */	    }	    newblock;	    	} else if (eq(wlist->wl_word, "if")) {	    cend[stackp]->co_type = CO_IF;	    cend[stackp]->co_cond = wl_copy(wlist->wl_next); /* va, wl_copy */	    if (!cend[stackp]->co_cond) {		fprintf(stderr, 			"Error: missing if condition.\n");	    }	    newblock;	    	} else if (eq(wlist->wl_word, "foreach")) {	    cend[stackp]->co_type = CO_FOREACH;	    if (wlist->wl_next) {		wlist = wlist->wl_next;		cend[stackp]->co_foreachvar = 		    copy(wlist->wl_word);		wlist = wlist->wl_next;	    } else		fprintf(stderr, 			"Error: missing foreach variable.\n");	    wlist = cp_doglob(wlist);  /*CDHW Possible leak around here? */	    cend[stackp]->co_text = wl_copy(wlist);	    newblock;	} else if (eq(wlist->wl_word, "label")) {	    cend[stackp]->co_type = CO_LABEL;	    if (wlist->wl_next) {		cend[stackp]->co_text = wl_copy(wlist->wl_next);		/* I think of everything, don't I? */		cp_addkword(CT_LABEL, wlist->wl_next->wl_word);		if (wlist->wl_next->wl_next)		    fprintf(cp_err, 			    "Warning: ignored extra junk after label.\n");	    } else		fprintf(stderr, "Error: missing label.\n");			} else if (eq(wlist->wl_word, "goto")) {	    /* Incidentally, this won't work if the values 1 and 2 ever get	     * to be valid character pointers -- I think it's reasonably	     * safe to assume they aren't...  */	    cend[stackp]->co_type = CO_GOTO;	    if (wlist->wl_next) {		cend[stackp]->co_text = wl_copy(wlist->wl_next);		if (wlist->wl_next->wl_next)		    fprintf(cp_err, 			    "Warning: ignored extra junk after goto.\n");	    } else		fprintf(stderr, "Error: missing label.\n");	} else if (eq(wlist->wl_word, "continue")) {	    cend[stackp]->co_type = CO_CONTINUE;	    if (wlist->wl_next) {		cend[stackp]->co_numtimes = scannum(wlist->						    wl_next->wl_word);		if (wlist->wl_next->wl_next)		    fprintf(cp_err, 			    "Warning: ignored extra junk after continue %d.\n",			    cend[stackp]->co_numtimes);	    } else		cend[stackp]->co_numtimes = 1;	} else if (eq(wlist->wl_word, "break")) {	    cend[stackp]->co_type = CO_BREAK;	    if (wlist->wl_next) {		cend[stackp]->co_numtimes = scannum(wlist->						    wl_next->wl_word);		if (wlist->wl_next->wl_next)		    fprintf(cp_err, 			    "Warning: ignored extra junk after break %d.\n",			    cend[stackp]->co_numtimes);	    } else		cend[stackp]->co_numtimes = 1;	} else if (eq(wlist->wl_word, "end")) {	    /* Throw away this thing. */	    if (!cend[stackp]->co_parent) {		fprintf(stderr, "Error: no block to end.\n");		cend[stackp]->co_type = CO_UNFILLED;	    } else if (cend[stackp]->co_prev) {		cend[stackp]->co_prev->co_next = NULL;		x = cend[stackp];		cend[stackp] = cend[stackp]->co_parent;		tfree(x); x=NULL;	    } else {		x = cend[stackp];		cend[stackp] = cend[stackp]->co_parent;		cend[stackp]->co_children = NULL;		tfree(x); x=NULL;	    }	} else if (eq(wlist->wl_word, "else")) {	    if (!cend[stackp]->co_parent ||		(cend[stackp]->co_parent->co_type !=		 CO_IF)) {		fprintf(stderr, "Error: misplaced else.\n");		cend[stackp]->co_type = CO_UNFILLED;	    } else {		if (cend[stackp]->co_prev)		    cend[stackp]->co_prev->co_next = NULL;		else		    cend[stackp]->co_parent->co_children = NULL;		cend[stackp]->co_parent->co_elseblock = cend[stackp];		cend[stackp]->co_prev = NULL;	    }	} else {	    cend[stackp]->co_type = CO_STATEMENT;	    cend[stackp]->co_text = wl_copy(wlist);	}	if (!cend[stackp]->co_parent) {	    x = cend[stackp];	    /* We have to toss this do-while loop in here so	     * that gotos at the top level will work.	     */	    do { nn = 0; /* CDHW */		i = doblock(x, &nn);		switch (*i) {		case NORMAL:		    break;		case BROKEN:		    fprintf(cp_err, 			    "Error: break not in loop or too many break levels given\n");		    break;		case CONTINUED:		    fprintf(cp_err, 			    "Error: continue not in loop or too many continue levels given\n");		    break;		default:		    x = findlabel(i, control[stackp]);		    if (!x)			fprintf(cp_err, "Error: label %s not found\n", i);		}		if (x)		    x = x->co_next;	    } while (x);	}	wl_free(wlist); wlist = NULL;	if (string) {	    return (1); /* The return value is irrelevant. */	}    }    wl_free(wlist); wlist = NULL;    return (0); /* va: which value? */}/* This blows away the control structures... */void cp_free_control(void); /* needed by resetcontrol */void cp_resetcontrol(void){    fprintf(cp_err, "Warning: clearing control structures\n");    if (cend[stackp] && cend[stackp]->co_parent)        fprintf(cp_err, "Warning: EOF before block terminated\n");    /* We probably should free the control structures... */    cp_free_control(); /* va: free it */    control[0] = cend[0] = NULL;    stackp = 0;    cp_kwswitch(CT_LABEL, (char *) NULL);    return;}/* Push or pop a new control structure set... */voidcp_popcontrol(void){    if (cp_debug)        fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1);    if (stackp < 1)        fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n");    else {        /* va: free unused control structure */        ctl_free(control[stackp]);        stackp--;    }    return;}voidcp_pushcontrol(void){    if (cp_debug)        fprintf(cp_err, "push: stackp: %d -> %d\n", stackp, stackp + 1);    if (stackp > CONTROLSTACKSIZE - 2) {        fprintf(cp_err, "Error: stack overflow -- max depth = %d\n",                CONTROLSTACKSIZE);        stackp = 0;    } else {        stackp++;        control[stackp] = cend[stackp] = NULL;    }    return;}/* And this returns to the top level (for use in the interrupt handlers). */voidcp_toplevel(void){    stackp = 0;    if (cend[stackp])        while (cend[stackp]->co_parent)            cend[stackp] = cend[stackp]->co_parent;    return;}/* va: This totally frees the control structures */void cp_free_control(void) {    int i;        for (i=stackp; i>=0; i--) ctl_free(control[i]);        control[0] = cend[0] = NULL;    stackp = 0;}

⌨️ 快捷键说明

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