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

📄 cshpar.c

📁 支持数字元件仿真的SPICE插件
💻 C
字号:
/* RCS Info: $Revision: 1.1 $ on $Date: 91/04/02 12:04:11 $ *           $Source: //pepper/atesse_spice/spice3/CP/RCS/cshpar.c,v $ * Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * * The main entry point for cshpar. */#include "prefix.h"#include "CPdefs.h"#ifdef UNIX#include <pwd.h>#endif#ifdef BSD#include <signal.h>#include <sys/wait.h>#endif#include "suffix.h"/* Things go as follows: * (1) Read the line and do some initial quoting (by setting the 8th bit), *  and command ignoring. Also deal with command completion. * (2) Do history substitutions. (!, ^) * (3) Do alias substitution. *  * Now, in front.c these things get done: * (4) Do variable substitution. ($varname) * (5) Do backquote substitution. (``) * (6) Do globbing. (*, ?, [], {}, ~) * (7) Do io redirection. */static bool fileexists();static void fixdescriptors();static void pwlist();bool cp_debug = false;char cp_gt = '>';char cp_lt = '<';char cp_amp = '&';FILE *cp_in;FILE *cp_out;FILE *cp_err;/* These are the fps that cp_ioreset resets the cp_* to.  They are changed * by the source routines. */FILE *cp_curin = NULL;FILE *cp_curout = NULL;FILE *cp_curerr = NULL;wordlist *cp_parse(string)    char *string;{    wordlist *wlist;    wlist = cp_lexer(string);    if (!string)        cp_event++;    if (!wlist || !wlist->wl_word)        return (wlist);    pwlist(wlist, "Initial parse");    wlist = cp_histsubst(wlist);    if (!wlist || !wlist->wl_word)        return (wlist);    pwlist(wlist, "After history substitution");    if (cp_didhsubst) {        wl_print(wlist, stdout);        (void) putc('\n', stdout);    }    /* Add the word list to the history. */    if (*wlist->wl_word)        cp_addhistent(cp_event - 1, wlist);    wlist = cp_doalias(wlist);    pwlist(wlist, "After alias substitution");    if (string && cp_lastone) {        /* Don't put this one in... */        cp_lastone = cp_lastone->hi_prev;        if (cp_lastone)            cp_lastone->hi_next = NULL;    }    pwlist(wlist, "Returning ");    return (wlist);}static voidpwlist(wlist, name)    wordlist *wlist;    char *name;{    wordlist *wl;    if (!cp_debug)        return;    fprintf(cp_err, "%s : [ ", name);    for (wl = wlist; wl; wl = wl->wl_next)        fprintf(cp_err, "%s ", wl->wl_word);    fprintf(cp_err, "]\n");    return;}/* This has to go somewhere... */voidcom_echo(wlist)    wordlist *wlist;{    bool nl = true;    if (wlist && eq(wlist->wl_word, "-n")) {        wlist = wlist->wl_next;        nl = false;    }    while (wlist) {        fputs(cp_unquote(wlist->wl_word), cp_out);        if (wlist->wl_next)            fputs(" ", cp_out);        wlist = wlist->wl_next;    }    if (nl)        fputs("\n", cp_out);}/* This routine sets the cp_{in,out,err} pointers and takes the io * directions out of the command line. */wordlist *cp_redirect(wl)    wordlist *wl;{    bool gotinput = false, gotoutput = false, goterror = false;    bool app = false, erralso = false;    wordlist *w, *bt, *nw;    char *s;    FILE *tmpfp;    w = wl->wl_next;    /* Don't consider empty commands. */    while (w) {        if (*w->wl_word == cp_lt) {            bt = w;            if (gotinput) {                fprintf(cp_err,                 "Error: ambiguous input redirect.\n");                goto error;            }            gotinput = true;            w = w->wl_next;            if (w == NULL) {                fprintf(cp_err,                 "Error: missing name for input.\n");                return (NULL);            }            if (*w->wl_word == cp_lt) {                /* Do reasonable stuff here... */            } else {                tmpfp = fopen(cp_unquote(w->wl_word), "r");                if (!tmpfp) {                    perror(w->wl_word);                    goto error;                } else                    cp_in = tmpfp;            }#ifdef CPDEBUG            if (cp_debug)                fprintf(cp_err, "Input file is %s...\n",                    w->wl_word);#endif            bt->wl_prev->wl_next = w->wl_next;            if (w->wl_next)                w->wl_next->wl_prev = bt->wl_prev;            nw = w->wl_next;            w->wl_next = NULL;            w = nw;            wl_free(bt);        } else if (*w->wl_word == cp_gt) {            bt = w;            if (gotoutput) {                fprintf(cp_err,                 "Error: ambiguous output redirect.\n");                goto error;            }            gotoutput = true;            w = w->wl_next;            if (w == NULL) {                fprintf(cp_err,                 "Error: missing name for output.\n");                return (NULL);            }            if (*w->wl_word == cp_gt) {                app = true;                w = w->wl_next;                if (w == NULL) {                    fprintf(cp_err,                     "Error: missing name for output.\n");                    return (NULL);                }            }            if (*w->wl_word == cp_amp) {                erralso = true;                if (goterror) {                    fprintf(cp_err,                 "Error: ambiguous error redirect.\n");                    return (NULL);                }                goterror = true;                w = w->wl_next;                if (w == NULL) {                    fprintf(cp_err,                     "Error: missing name for output.\n");                    return (NULL);                }            }            s = cp_unquote(w->wl_word);            if (cp_noclobber && fileexists(s)) {                fprintf(stderr, "Error: %s: file exists\n", s);                goto error;            }            if (app)                tmpfp = fopen(s, "a");            else                tmpfp = fopen(s, "w+");            if (!tmpfp) {                perror(w->wl_word);                goto error;            } else {                cp_out = tmpfp;                out_isatty = false;            }#ifdef CPDEBUG            if (cp_debug)                fprintf(cp_err, "Output file is %s... %s\n",                    w->wl_word, app ? "(append)" : "");#endif            bt->wl_prev->wl_next = w->wl_next;            if (w->wl_next)                w->wl_next->wl_prev = bt->wl_prev;            w = w->wl_next;            if (w)                w->wl_prev->wl_next = NULL;            wl_free(bt);            if (erralso)                cp_err = cp_out;        } else            w = w->wl_next;    }    return (wl);error:  wl_free(wl);    return (NULL);}/* Reset the cp_* FILE pointers to the standard ones.  This is tricky, since * if we are sourcing a command file, and io has been redirected from inside * the file, we have to reset it back to what it was for the source, not for * the top level.  That way if you type "foo > bar" where foo is a script, * and it has redirections of its own inside of it, none of the output from * foo will get sent to stdout... */voidcp_ioreset(){    if (cp_in != cp_curin) {        if (cp_in)            (void) fclose(cp_in);        cp_in = cp_curin;    }    if (cp_out != cp_curout) {        if (cp_out)            (void) fclose(cp_out);        cp_out = cp_curout;    }    if (cp_err != cp_curerr) {        if (cp_err)            (void) fclose(cp_err);        cp_err = cp_curerr;    }    /*** Minor bug here... */    out_isatty = true;    return;}static boolfileexists(name)    char *name;{#ifdef BSD    if (access(name, 0) == 0)        return (true);#endif    return (false);}#ifdef UNIX/* Fork a shell. */voidcom_shell(wl)    wordlist *wl;{    char *com, *shell = NULL;    long pid, r;#ifdef BSD    struct sigvec svint, svquit, svtstp;    static struct sigvec svign = { NULL, 0, 0 } ;#endif#ifdef UNIX    shell = getenv("SHELL");    if (shell == NULL)        shell = "/bin/csh";#endif#ifdef BSD    if (wl == NULL) {        fprintf(cp_out, "Forking shell...\n");        cp_ccon(false);        if ((pid = vfork()) == 0) {            fixdescriptors();            (void) execl(shell, shell, 0);        } else {            (void) sigvec(SIGINT, &svign, &svint);            (void) sigvec(SIGQUIT, &svign, &svquit);            (void) sigvec(SIGTSTP, &svign, &svtstp);            do {                r = wait((union wait *) NULL);            } while ((r != pid) && pid != -1);            (void) sigvec(SIGINT, &svint, (struct sigvec *) NULL);            (void) sigvec(SIGQUIT, &svquit, (struct sigvec *) NULL);            (void) sigvec(SIGTSTP, &svtstp, (struct sigvec *) NULL);            fprintf(cp_out, "\nWelcome back...\n");        }    } else {        com = wl_flatten(wl);        if ((pid = vfork()) == 0) {            fixdescriptors();            (void) execl("/bin/sh", "sh", "-c", com, 0);        } else            (void) sigvec(SIGINT, &svign, &svint);            (void) sigvec(SIGQUIT, &svign, &svquit);            (void) sigvec(SIGTSTP, &svign, &svtstp);            do {                r = wait((union wait *) NULL);            } while ((r != pid) && pid != -1);            (void) sigvec(SIGINT, &svint, (struct sigvec *) NULL);            (void) sigvec(SIGQUIT, &svquit, (struct sigvec *) NULL);            (void) sigvec(SIGTSTP, &svtstp, (struct sigvec *) NULL);    }#else        /* Easier to forget about changing the io descriptors. */    if (wl) {        com = wl_flatten(wl);        (void) system(com);    } else        (void) system(shell);#endif    return;}#ifdef BSD/* Do this only right before an exec, since we lose the old std*'s. */static voidfixdescriptors(){    if (cp_in != stdin)        (void) dup2(fileno(cp_in), fileno(stdin));    if (cp_out != stdout)        (void) dup2(fileno(cp_out), fileno(stdout));    if (cp_err != stderr)        (void) dup2(fileno(cp_err), fileno(stderr));    return;}#endifvoidcom_chdir(wl)    wordlist *wl;{    char *s;    struct passwd *pw;    if (wl == NULL) {        pw = getpwuid(getuid());        if (pw == NULL) {            fprintf(cp_err, "Welcome to the twilight zone...\n");            return;        }                   s = pw->pw_dir;    } else        s = cp_unquote(wl->wl_word);    if (chdir(s) == -1)        perror(s);    return;}#else#ifdef VMSvoidcom_shell(wl)    wordlist *wl;{    if (wl) {        char *s = wl_flatten(wl);        (void) system(wl);    } else        (void) system((char *) NULL);    return;}#else/* ARGSUSED */voidcom_shell(wl)    wordlist *wl;{    fprintf(cp_err, "Error: command only available with UNIX or VMS.\n");    return;}#endifvoidcom_chdir(wl)    wordlist *wl;{    fprintf(cp_err, "Error: command only available with UNIX.\n");    return;}#endif/* ARGSUSED */voidcom_rehash(wl)    wordlist *wl;{    char *s;    if (!cp_dounixcom) {        fprintf(cp_err, "Error: unixcom not set.\n");        return;    }    s = getenv("PATH");    if (s)        cp_rehash(s, true);    else        fprintf(cp_err, "Error: no PATH in environment...\n");    return;}/* This is a truly evil thing... */voidcom_strcmp(wl)    wordlist *wl;{    char *var, *s1, *s2;    int i;    var = wl->wl_word;    s1 = cp_unquote(wl->wl_next->wl_word);    s2 = cp_unquote(wl->wl_next->wl_next->wl_word);        i = strcmp(s1, s2);    cp_vset(var, VT_NUM, (char *) &i);    return;}

⌨️ 快捷键说明

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