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

📄 complete.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD GroupModified: 1999 Paolo Nenzi**********//* * 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 <config.h>#include "ngspice.h"#include "cpdefs.h"#include "complete.h"#ifdef HAVE_SYS_DIR_H#include <sys/types.h>#include <sys/dir.h>#else#  ifdef HAVE_DIRENT_H#    include <sys/types.h>#    include <dirent.h>#    ifndef direct#      define direct dirent#    endif#  endif#endif#ifdef HAVE_PWD_H#include <pwd.h>#endif#ifndef __MINGW32__	/* MW. We also need ioctl.h here I think */#include <sys/ioctl.h>#endif/* Be sure the ioctls get included in the following */#ifdef HAVE_SGTTY_H#include <sgtty.h>#else#ifdef HAVE_TERMIO_H#include <termio.h>#else#ifdef HAVE_TERMIOS_H#include <termios.h>#endif#endif#endif#define	CNTRL_D	'\004'#define	ESCAPE	'\033'#define NCLASSES 32bool cp_nocc;               /* Don't do command completion. */static struct ccom *commands = NULL;    /* The available commands. */static struct ccom *keywords[NCLASSES]; /* Keywords. *//* static declarations */static struct ccom * getccom(char *first);static wordlist * ccfilec(char *buf);static wordlist * ccmatch(char *word, struct ccom **dbase);static void printem(wordlist *wl);static wordlist * cctowl(struct ccom *cc, bool sib);static struct ccom * clookup(register char *word, struct ccom **dd, bool pref, 			     bool create);/* MW. I need top node in cdelete */static void cdelete(struct ccom *node, struct ccom **top);#ifdef TIOCSTIvoidcp_ccom(wordlist *wlist, char *buf, bool esc){    struct ccom *cc;    wordlist *a, *pmatches = NULL;    char wbuf[BSIZE_SP], *s;    int i=0;     int 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 =strrchr(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);    }         tfree(buf); /*CDHW*/        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(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(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 =strrchr(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(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(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(wordlist *wlist, char *buf, bool esc){    return;}#endifstatic wordlist *cctowl(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;        wl->wl_next = cctowl(cc->cc_child, TRUE);        if (wl->wl_next)            wl->wl_next->wl_prev = wl;    } else        wl = cctowl(cc->cc_child, TRUE);    if (sib) {        if (wl) {            for (end = wl; end->wl_next; end = end->wl_next)                ;            end->wl_next = cctowl(cc->cc_sibling, TRUE);            if (end->wl_next)                end->wl_next->wl_prev = wl;        } else            wl = cctowl(cc->cc_sibling, TRUE);    }    return (wl);}/* We use this in com_device... */

⌨️ 快捷键说明

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