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

📄 complete.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group**********//* * Command completion code. We keep a data structure with information on each * command, to make lookups fast.  We also keep NCLASSES (which is sort of * hardwired as 32) sets of keywords. Each command has an array of NARGS * bitmasks (also hardwired as 4), stating whether the command takes that * particular class of keywords in that position. Class 0 always means * filename completion. */#include "spice.h"#include "util.h"#include "cpdefs.h"#ifdef HAS_BSDDIRS#include <sys/types.h>#include <sys/dir.h>#else#ifdef HAS_SYSVDIRS#include <sys/types.h>#include <dirent.h>#ifndef direct#define direct dirent#endif#endif#endif#ifdef HAS_GETPW#include <pwd.h>#endif/* Be sure the ioctls get included in the following */#ifdef HAS_BSDTTY#include <sgtty.h>#else#ifdef HAS_SYSVTTY#include <termio.h>#else#ifdef HAS_POSIXTTY#include <termios.h>#endif#endif#endif#include "suffix.h"#define	CNTRL_D	'\004'#define	ESCAPE	'\033'#define NCLASSES 32#define NARGS 4static wordlist *ccfilec();static wordlist *ccmatch();static wordlist *cctowl();static void cdelete();static struct ccom *clookup();static struct ccom *getccom();static void printem();static void throwaway();bool cp_nocc;               /* Don't do command completion. *//* The data structure for the commands is as follows: every node has a pointer * to its leftmost child, where the children of a node are those of which * the node is a prefix. This means that for a word like "ducks", there * must be nodes "d", "du", "duc", etc (which are all marked "invalid", * of course).  This data structure is called a "trie". */struct ccom {    char *cc_name;          /* Command or keyword name. */    long cc_kwords[NARGS];  /* What this command takes. */    char cc_invalid;    /* This node has been deleted. */    struct ccom *cc_child;  /* Left-most child. */    struct ccom *cc_sibling;/* Right (alph. greater) sibling. */    struct ccom *cc_ysibling;/* Left (alph. less) sibling. */    struct ccom *cc_parent; /* Parent node. */} ;static struct ccom *commands = NULL;    /* The available commands. */static struct ccom *keywords[NCLASSES]; /* Keywords. */#ifdef TIOCSTIvoidcp_ccom(wlist, buf, esc)    wordlist *wlist;    char *buf;    bool esc;{    struct ccom *cc;    wordlist *a, *pmatches = NULL;    char wbuf[BSIZE_SP], *s;    int i, j, arg;    buf = cp_unquote(copy(buf));    cp_wstrip(buf);    if (wlist->wl_next) {   /* Not the first word. */        cc = getccom(wlist->wl_word);        if (cc && cc->cc_invalid)            cc = NULL;        arg = wl_length(wlist) - 2;        if (arg > 3)            arg = 3;        /* First filenames. */        if (cc && (cc->cc_kwords[arg] & 1)) {            pmatches = ccfilec(buf);            s = rindex(buf, '/');            i = strlen(s ? s + 1 : buf);            if ((*buf == '~') && !index(buf, '/'))                i--;        }        /* The keywords. */        for (j = 1; j < NCLASSES; j++) {            if (cc && (cc->cc_kwords[arg] & (1 << j))) {                /* Find all the matching keywords. */                a = ccmatch(buf, &keywords[j]);                i = strlen(buf);                if (pmatches)                    pmatches = wl_append(pmatches, a);                else                    pmatches = a;            }        }        wl_sort(pmatches);    } else {        pmatches = ccmatch(buf, &commands);        i = strlen(buf);    }    if (!esc) {        printem(pmatches);        wl_free(pmatches);        return;    }    if (pmatches == NULL) {        (void) putchar('\07');        (void) fflush(cp_out);        return;    }    if (pmatches->wl_next == NULL) {        (void) strcpy(wbuf, &pmatches->wl_word[i]);        goto found;    }    /* Now we know which words might work. Extend the command as much     * as possible, then TIOCSTI the characters out.     */    for (j = 0;; j++, i++) {        wbuf[j] = pmatches->wl_word[i];        for (a = pmatches->wl_next; a; a = a->wl_next)                if (a->wl_word[i] != wbuf[j]) {                    (void) putchar('\07');                    (void) fflush(cp_out);                    wbuf[j] = '\0';                    goto found;                }        if (wbuf[j] == '\0')            goto found;    }found:  for (i = 0; wbuf[i]; i++)        (void) ioctl(fileno(cp_in), TIOCSTI, &wbuf[i]);    wl_free(pmatches);    return;}/* Figure out what the command is, given the name. Returns NULL if there * is no such command in the command list. This is tricky, because we have * to do a preliminary history and alias parse. (Or at least we should.) */static struct ccom *getccom(first)    char *first;{    struct alias *al;    int ntries = 21;    /* First look for aliases. Just interested in the first word...      * Don't bother doing history yet -- that might get complicated.     */    while (ntries-- > 0) {        for (al = cp_aliases; al; al = al->al_next)            if (eq(first, al->al_name)) {                first = al->al_text->wl_word;                break;            }        if (al == NULL)            break;    }    if (ntries == 0) {        fprintf(cp_err, "\nError: alias loop.\n");        return (NULL);    }    return (clookup(first, &commands, false, false));}/* Figure out what files match the prefix. */static wordlist *ccfilec(buf)    char *buf;{    DIR *wdir;    char *lcomp, *dir;    struct direct *de;    wordlist *wl = NULL, *t;    struct passwd *pw;    buf = copy(buf);    /* Don't mangle anything... */    lcomp = rindex(buf, '/');    if (lcomp == NULL) {        dir = ".";        lcomp = buf;        if (*buf == cp_til) {   /* User name completion... */            buf++;            while (pw = getpwent()) {                if (prefix(buf, pw->pw_name)) {                    if (wl == NULL) {                        wl = alloc(struct wordlist);                        wl->wl_next = NULL;                        wl->wl_prev = NULL;                    } else {                        t = wl;                        wl = alloc(struct wordlist);                        wl->wl_prev = NULL;                        wl->wl_next = t;			t->wl_prev = wl;                    }                    wl->wl_word = copy(pw->pw_name);                }            }            (void) endpwent();            return (wl);        }    } else {        dir = buf;        *lcomp = '\0';        lcomp++;        if (*dir == cp_til) {            dir = cp_tildexpand(dir);            if (dir == NULL)                return (NULL);        }    }    if (!(wdir = opendir(dir)))        return (NULL);    while (de = readdir(wdir))        if ((prefix(lcomp, de->d_name)) && (*lcomp ||                (*de->d_name != '.'))) {            if (wl == NULL) {                wl = alloc(struct wordlist);                wl->wl_next = NULL;		wl->wl_prev = NULL;	    } else {                t = wl;                wl = alloc(struct wordlist);                wl->wl_next = t;		t->wl_prev = wl;		wl->wl_prev = NULL;            }            wl->wl_word = copy(de->d_name);        }    (void) closedir(wdir);    wl_sort(wl);    return (wl);}/* See what keywords or commands match the prefix. Check extra also for * matches, if it is non-NULL. Return a wordlist which is in alphabetical * order. Note that we have to call this once for each class. */static wordlist *ccmatch(word, dbase)    char *word;    struct ccom **dbase;{    wordlist *wl;    register struct ccom *cc;        cc = clookup(word, dbase, true, false);    if (cc) {        if (*word)  /* This is a big drag. */            wl = cctowl(cc, false);        else            wl = cctowl(cc, true);    } else        wl = NULL;    return (wl);}/* Print the words in the wordlist in columns. They are already sorted...  * This is a hard thing to do with wordlists... */static voidprintem(wl)    wordlist *wl;{    wordlist *ww;    int maxl = 0, num, i, j, k, width = 79, ncols, nlines;    (void) putchar('\n');    if (wl == NULL) {        return;    }    num = wl_length(wl);    for (ww = wl; ww; ww = ww->wl_next) {        j = strlen(ww->wl_word);        if (j > maxl)            maxl = j;    }    if (++maxl % 8)        maxl += 8 - (maxl % 8);    ncols = width / maxl;    if (ncols == 0)        ncols = 1;    nlines = num / ncols + (num % ncols ? 1 : 0);    for (k = 0; k < nlines; k++) {        for (i = 0; i < ncols; i++) {            j = i * nlines + k;            if (j < num) {                fprintf(cp_out, "%-*s", maxl,                        wl_nthelem(j, wl)->wl_word);            } else                break;        }        (void) putchar('\n');    }    return;}#else /* if not TIOCSTI */voidcp_ccom(wlist, buf, esc)    wordlist *wlist;    char *buf;    bool esc;{    return;}#endifstatic wordlist *cctowl(cc, sib)    struct ccom *cc;    bool sib;{    wordlist *wl, *end;        if (!cc)        return (NULL);    if (!cc->cc_invalid) {        wl = alloc(struct wordlist);        wl->wl_word = copy(cc->cc_name);        wl->wl_prev = NULL;

⌨️ 快捷键说明

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