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

📄 mfbcaps.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: -C- 1982 Giles Billingsley**********//* * mfbcaps.c * * sccsid "@(#)mfbcaps.c    1.9  9/3/83" * *     MFB is a graphics package that was developed by the integrated * circuits group of the Electronics Research Laboratory and the * Department of Electrical Engineering and Computer Sciences at * the University of California, Berkeley, California.  The programs * in MFB are available free of charge to any interested party. * The sale, resale, or use of these program for profit without the * express written consent of the Department of Electrical Engineering * and Computer Sciences, University of California, Berkeley, California, * is forbidden. */#define MAXHOP      5    /* max number of MCE=indirections */#define BADNUM      0    /* illegal number for numeric capability */#include "spice.h"#include "mfb.h"#include <ctype.h>#include "suffix.h"/* * mfbcap - routines for dealing with the terminal capability data base *        mfbcap routines must be loaded * * Essentially all the work here is scanning and decoding escapes * in string capabilities.  We don't use stdio because the editor * doesn't, and because living w/o it is not hard. */static char *mfb_buf;static int hopcount;       /* detect infinite loops in mfbcap, init 0 */FILE   *POpen();char   *strcpy();char   *MFBSkip();char   *MFBGetStr();char   *MFBCapDecod();int    MFBGetNum();int    MFBGetFlag();int    MFBGetEnt();int    MFBCheckForMCE();/* * Get an entry for terminal name in buffer bp, * from the mfbcap file.  Parse is very rudimentary; * we just notice escaped newlines. */intMFBGetEnt(bp, name, mfbcapFile)    char *bp;    char *name;    char *mfbcapFile;    {    register char *cp;    register int c;    register int i = 0, cnt = 0;    register int NewLine;    char inputBuffer[BUFSIZE];    FILE *CapFile;    int mfbcapDesc;    hopcount = 0;   /* Fixes bug in in spice3a* -- could only plot 5 times. */    mfb_buf = bp;    if((CapFile = POpen(mfbcapFile, "r", (char *)NULL, (char **)NULL)) == NULL)        return(MFBBADMCF);    mfbcapDesc = fileno(CapFile);    /*     * It should be faster to read mfbcap by 4Kbytes at a time     */    for(;;){    NewLine = 0;        cp = bp;        for(;;){            if(i >= cnt){                cnt = read(mfbcapDesc, inputBuffer, BUFSIZE);                if(cnt <= 0 && !NewLine){                    if(close(mfbcapDesc) < 0)            return(MFBBADMCF);                    return(MFBBADENT);                    }                i = 0;                }            c = inputBuffer[i++];        /*         * Check for continuation from previous line         */        if(NewLine && c != ' ' && c != '\t'){        --i;        break;        }        /*         * Check for new line         */        NewLine = 0;        if(c == '\n'){        NewLine = 1;        continue;        }        /*         * Check for line too long         */            else if(cp >= bp + BUFSIZE){        return(MFBMCELNG);                }            else                *cp++ = c;            }        *cp = 0;        /*         * The real work for the match.         */        if(mfbnamatch(name)){            if(close(mfbcapDesc) < 0)        return(MFBBADMCF);            return( MFBCheckForMCE(mfbcapFile) );            }        }    }/* * check the last entry, see if it's MCE=xxxxx. If so, * recursively find xxxxx and append that entry (minus the names) * to take the place of the MCE=xxxxx entry. This allows mfbcap * entries to say "like an AED but with a graphics tablet". * Note that this works because of the left to right scan. */intMFBCheckForMCE(mfbcapFile)    char *mfbcapFile;    {    register char *p, *q;    char mfbname[16];                      /* name of similar terminal */    char mfbbuf[BUFSIZE];    char *holdgbuf = mfb_buf;    int l;    p = mfb_buf + strlen(mfb_buf);    for(l=0; l<2; ++l){        while(*--p != ','){            if(p < mfb_buf){                return(MFBBADMCE);                }        }    }    while(*p == ',' || *p == ' ' || *p == '\t')        p++;    /* p now points to beginning of last field */    if(p[0] != 'M' || p[1] != 'C' || p[2] != 'E') return(MFBOK);    (void) strcpy(mfbname,p+4);    q = mfbname;    while(q && *q != ',')        q++;    *q = 0;    if(++hopcount > MAXHOP){        return(MFBINFMCE);        }    if((l = MFBGetEnt(mfbbuf,mfbname,mfbcapFile)) != 1){        return(l);        }    for(q=mfbbuf; *q != ','; q++) ;    l = p - holdgbuf + strlen(q);    if(l > BUFSIZE){        q[BUFSIZE - (p-mfb_buf)] = 0;        return(MFBMCELNG);        }    (void) strcpy(p, q+1);    mfb_buf = holdgbuf;    return(MFBOK);    }/* * mfbnamatch deals with name matching.  The first field of the mfbcap * entry is a sequence of names separated by |'s, so we compare * against each such name.  The normal , terminator after the last * name (before the first field) stops us. */mfbnamatch(np)    char *np;    {    register char *Np, *Bp;    Bp = mfb_buf;    if(*Bp == '#') return(FALSE);    for(;;){        for(Np = np; *Np && *Bp == *Np; Bp++, Np++) continue;        if(*Np == 0 && (*Bp == '|' || *Bp == ',' || *Bp == 0))            return(TRUE);        while(*Bp && *Bp != ',' && *Bp != '|') Bp++;        if(*Bp == 0 || *Bp == ',') return(FALSE);        Bp++;        }    }/* * Skip to the next field. */static char *MFBSkip(bp)    char *bp;    {    while(*bp && !(*bp == ',' && *(bp - 1) != '\\'))    bp++;    /* Now clear the white space */    while(*bp == ',' || *bp == ' ' || *bp == '\t')    bp++;    return(bp);    }/* * Handle a flag option. * Flag options are given "naked", i.e. followed by a , or the end * of the buffer.  Return 1 if we find the option, or 0 if it is * not given. */MFBGetFlag(id)    char *id;    {    register char *bp = mfb_buf;    register char *cp;    register int i;    for(;;){        bp = MFBSkip(bp);        if(!*bp) return(0);    i = 0;    cp = id;    while(*cp != 0 && *bp != 0){        if(*cp++ != *bp++){        i = 1;        break;        }        }    if(!i){            if(!*bp || *bp == ',')                return(1);            else if(*bp == '@')                return(0);            }        }    }/* * Get a string valued option. * These are given as *    GIS=\E\E\027 * Much decoding is done on the strings, and the strings are * placed in area, which is a ref parameter which is updated. * For speed there is no checking on area overflow. */char *MFBGetStr(id, area)    char *id, **area;    {    register char *bp = mfb_buf;    register char *cp;    register int i;    for(;;){        bp = MFBSkip(bp);        if(!*bp) return(NULL);    i = 0;    cp = id;    while(*cp != 0 && *bp != 0){        if(*cp++ != *bp++){        i = 1;        break;        }        }        if(i || *bp != '=') continue;        bp++;        return(MFBCapDecod(bp, area));        }    }/* * MFBCapDecod decodes the string capability escapes. */static char *MFBCapDecod(str, area)    char *str;    char **area;    {    char *cp;    int c;    char *dp;    int i;    cp = *area;    while((c = *str++) && c != ','){        switch (c){        case '^':            c = *str++ & 037;            break;        case '\\':            dp = "E\033^^\\\\,,n\nr\rt\tb\bf\f";            c = *str++;    nextc:                if(*dp++ == c){                c = *dp++;                break;                }            dp++;            if(*dp)                goto nextc;            if(isdigit(c)){                c -= '0', i = 2;                do                    c <<= 3, c |= *str++ - '0';                while(--i && isdigit(*str));                }            break;            }        *cp++ = c;        }    *cp++ = 0;    str = *area;    *area = cp;    return(str);    }/* * Return the (numeric) option id. * Numeric options look like *    MCL#255 * i.e. the option string is separated from the numeric value by * a # character.  If the option is not found we return -1. * Note that we handle hex numbers beginning with "0x" or "0X", * and octal numbers beginning with 0. * */MFBGetNum(id)    char *id;    {    register int i, j;    register char *bp = mfb_buf;    register char negative = 0 ;    register char *cp;    for(;;){        bp = MFBSkip(bp);        if(*bp == 0) return(BADNUM);    i = 0;    cp = id;    while(*cp != 0 && *bp != 0){        if(*cp++ != *bp++){        i = 1;        break;        }        }        if(*bp == 0) return(BADNUM);        if(i || *bp != '#') continue;        bp++;        if((negative=(*bp == '-'))) bp++ ;        i = 0;        while( (j = ((int)(*bp) - 060)) >= 0 && (j < 10) ) {            bp++; i *= 10; i += j;        }        if(negative)               return(-i) ;        else               return(i);        }    }

⌨️ 快捷键说明

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