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

📄 variable.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* RCS Info: $Revision: 1.1 $ on $Date: 91/04/02 12:04:31 $ *           $Source: //pepper/atesse_spice/spice3/CP/RCS/variable.c,v $ * Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * * Do variable substitution. */#include "prefix.h"#include "CPdefs.h"#include "suffix.h"static wordlist *vareval();static int vcmp();/* A variable substitution is * indicated by a $, and the variable name is the following string of * non-special characters. All variable values are inserted as a single * word, except for lists, which are a list of words. * A routine cp_usrset must be supplied by the host program to deal  * with variables that aren't used by cshpar -- it should be  * cp_usrset(var, isset), where var is a variable *, and isset is  * true if the variable is being set, false if unset. * Also required is a routine cp_enqvar(name) which returns a struct * variable *, which allows the host program to provide values for * non-cshpar variables. */bool cp_noglob = true;      /* This is just a bad thing. */bool cp_nonomatch = false;bool cp_noclobber = false;bool cp_ignoreeof = false;char cp_dol = '$';static struct variable *variables = NULL;/* Non-alphanumeric characters that may appear in variable names. < is very * special... */#define VALIDCHARS "$-_<#?@.()[]&"wordlist *cp_variablesubst(wlist)    wordlist *wlist;{    wordlist *wl, *nwl;    char *s, *t, buf[BSIZE], wbuf[BSIZE];    int i;    for (wl = wlist; wl; wl = wl->wl_next) {        t = wl->wl_word;        i = 0;        while(s = index(t, cp_dol)) {            while (t < s)                wbuf[i++] = *t++;            wbuf[i] = '\0';            (void) strcpy(buf, ++s);            s = buf;            t++;            while (*s && (isalphanum(*s) ||                    index(VALIDCHARS, *s))) {                /* Get s and t past the end of the var name. */                t++;                s++;            }            *s = '\0';            nwl = vareval(buf);            if (i) {                (void) strcpy(buf, wbuf);                if (nwl) {                    (void) strcat(buf, nwl->wl_word);                    tfree(nwl->wl_word);                } else {                    nwl = alloc(wordlist);                }                nwl->wl_word = copy(buf);            }            if (!(wl = wl_splice(wl, nwl)))                return (NULL);            /* This is bad... */            for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)                ;            (void) strcpy(buf, wl->wl_word);            i = strlen(buf);            (void) strcat(buf, t);            tfree(wl->wl_word);            wl->wl_word = copy(buf);            t = &wl->wl_word[i];            s = wl->wl_word;            for (i = 0; s < t; s++)                wbuf[i++] = *s;        }    }    return (wlist);}/* Evaluate a variable. */static wordlist *vareval(string)    char *string;{    struct variable *v;    wordlist *wl;    char buf[BSIZE], *s;    char *oldstring = copy(string);    char *range = NULL;    int i, up, low;    cp_wstrip(string);    if (s = index(string, '[')) {        *s = '\0';        range = s + 1;    }    switch (*string) {        case '$':        wl = alloc(wordlist);#ifdef UNIX        (void) sprintf(buf, "%d", getpid());#else        (void) strcpy(buf, "Sorry, this isn't UNIX...\n");#endif        wl->wl_word = copy(buf);        return (wl);        case '<':        (void) fflush(cp_out);        if (!fgets(buf, BSIZE, cp_in)) {            clearerr(cp_in);            (void) strcpy(buf, "EOF");        }        for (s = buf; *s && (*s != '\n'); s++)            ;        *s = '\0';        wl = cp_lexer(buf);        /* This is a hack. */        if (!wl->wl_word)            wl->wl_word = copy("");        return (wl);            case '?':        wl = alloc(wordlist);        string++;        for (v = variables; v; v = v->va_next)            if (eq(v->va_name, string))                break;        if (!v)            v = cp_enqvar(string);        wl->wl_word = copy(v ? "1" : "0");        return (wl);                case '#':        wl = alloc(wordlist);        string++;        for (v = variables; v; v = v->va_next)            if (eq(v->va_name, string))                break;        if (!v)            v = cp_enqvar(string);        if (!v) {            fprintf(cp_err, "Error: %s: no such variable.\n",                    string);            return (NULL);        }        if (v->va_type == VT_LIST)            for (v = v->va_vlist, i = 0; v; v = v->va_next)                i++;        else            i = (v->va_type != VT_BOOL);        (void) sprintf(buf, "%d", i);        wl->wl_word = copy(buf);        return (wl);        case '\0':        wl = alloc(wordlist);        wl->wl_word = copy("$");        return (wl);    }    /* The notation var[stuff] has two meanings...  If this is a real     * variable, then the [] denotes range, but if this is a strange     * (e.g, device parameter) variable, it could be anything...     */    for (v = variables; v; v = v->va_next)        if (eq(v->va_name, string))            break;    if (!v && isdigit(*string)) {        for (v = variables; v; v = v->va_next)            if (eq(v->va_name, "argv"))                break;        range = string;    }    if (!v) {        range = NULL;        string = oldstring;        v = cp_enqvar(string);    }    if (!v && (s = getenv(string))) {        wl = alloc(wordlist);        wl->wl_word = copy(s);        return (wl);    }    if (!v) {        fprintf(cp_err, "Error: %s: no such variable.\n", string);        return (NULL);    }    wl = cp_varwl(v);    /* Now parse and deal with 'range' ... */    if (range) {        for (low = 0; isdigit(*range); range++)            low = low * 10 + *range - '0';        if ((*range == '-') && isdigit(range[1]))            for (up = 0, range++; isdigit(*range); range++)                up = up * 10 + *range - '0';        else if (*range == '-')            up = wl_length(wl);        else            up = low;        up--, low--;        wl = wl_range(wl, low, up);    }    return (wl);}/* Print the values of currently defined variables. */struct xxx {    struct variable *x_v;    char x_char;} ;voidcp_vprint(){    struct variable *v;    struct variable *uv1, *uv2;    wordlist *wl;    int i, j;    char *s;    struct xxx *vars;    cp_usrvars(&uv1, &uv2);    for (v = uv1, i = 0; v; v = v->va_next)        i++;    for (v = uv2; v; v = v->va_next)        i++;    for (v = variables; v; v = v->va_next)        i++;        vars = (struct xxx *) tmalloc(sizeof (struct xxx) * i);    out_init();    for (v = variables, i = 0; v; v = v->va_next, i++) {        vars[i].x_v = v;        vars[i].x_char = ' ';    }    for (v = uv1; v; v = v->va_next, i++) {        vars[i].x_v = v;        vars[i].x_char = '*';    }    for (v = uv2; v; v = v->va_next, i++) {        vars[i].x_v = v;        vars[i].x_char = '+';    }    qsort((char *) vars, i, sizeof (struct xxx), vcmp);    for (j = 0; j < i; j++) {        if (j && eq(vars[j].x_v->va_name, vars[j - 1].x_v->va_name))            continue;        v = vars[j].x_v;        if (v->va_type == VT_BOOL) {/*             out_printf("%c %s\n", vars[j].x_char, v->va_name); */             sprintf(out_pbuf, "%c %s\n", vars[j].x_char, v->va_name);         out_send(out_pbuf);        } else {            out_printf("%c %s\t", vars[j].x_char, v->va_name);            wl = vareval(v->va_name);            s = wl_flatten(wl);            if (v->va_type == VT_LIST) {                out_printf("( %s )\n", s);            } else                out_printf("%s\n", s);        }    }        return;}static intvcmp(v1, v2)    struct xxx *v1, *v2;{    int i;    if (i = strcmp(v1->x_v->va_name, v2->x_v->va_name))        return (i);    else        return (v1->x_char - v2->x_char);}wordlist *cp_varwl(var)    struct variable *var;{    wordlist *wl = NULL, *w, *wx = NULL;    char buf[BSIZE];    struct variable *vt;    switch(var->va_type) {        case VT_BOOL:            /* Can't ever be false. */            (void) sprintf(buf, "%s", var->va_bool ? "true" :                    "false");            break;        case VT_NUM:            (void) sprintf(buf, "%d", var->va_num);            break;        case VT_REAL:            /* This is a case where printnum isn't too good... */            (void) sprintf(buf, "%G", var->va_real);            break;        case VT_STRING:            (void) strcpy(buf, cp_unquote(var->va_string));            break;        case VT_LIST:   /* The tricky case. */            for (vt = var->va_vlist; vt; vt = vt->va_next) {                w = cp_varwl(vt);                if (wl == NULL)                    wl = wx = w;                else {                    wx->wl_next = w;                    w->wl_prev = wx;                    wx = w;                }            }            return (wl);        default:            fprintf(cp_err,             "cp_varwl: Internal Error: bad variable type %d\n",                 var->va_type);            return (NULL);    }    wl = alloc(wordlist);    wl->wl_next = wl->wl_prev = NULL;    wl->wl_word = copy(buf);    return (wl);}/* Set a variable. */voidcp_vset(varname, type, value)    char *varname;    char type;    char *value;{    struct variable *v;    int i;    bool alreadythere = false;/* for (v = variables; v; v = v->va_next) ; printf("ok while setting %s\n",         varname);*/    varname = cp_unquote(varname);    for (v = variables; v; v = v->va_next)        if (eq(varname, v->va_name)) {            alreadythere = true;            break;        }    if (!v) {        v = alloc(variable);        v->va_name = copy(varname);    }    switch (type) {        case VT_BOOL:        if (* ((bool *) value) == false) {            cp_remvar(varname);            return;        } else            v->va_bool = true;        break;        case VT_NUM:        v->va_num = * (int *) value;        break;        case VT_REAL:        v->va_real = * (double *) value;        break;        case VT_STRING:        v->va_string = copy(value);        break;        case VT_LIST:        v->va_vlist = (struct variable *) value;        break;        default:        fprintf(cp_err,             "cp_vset: Internal Error: bad variable type %d.\n",                 type);        return;    }    v->va_type = type;    /* Now, see if there is anything interesting going on. We recognise     * these special variables: noglob, nonomatch, history, echo,     * noclobber, prompt, and verbose. cp_remvar looks for these variables     * too. The host program will get any others.     */    if (eq(varname, "noglob"))        cp_noglob = true;    else if (eq(varname, "nonomatch"))        cp_nonomatch = true;    else if (eq(varname, "history") && (type == VT_NUM))        cp_maxhistlength = v->va_num;    else if (eq(varname, "history") && (type == VT_REAL))        cp_maxhistlength = v->va_real;    else if (eq(varname, "noclobber"))        cp_noclobber = true;

⌨️ 快捷键说明

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