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

📄 cshpar.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group**********//* * The main entry point for cshpar. */#include "spice.h"#include "misc.h"#include "cpdefs.h"#ifdef HAS_BSDTTY#include <sgtty.h>#else#ifdef HAS_SYSVTTY#include <termio.h>#else#ifdef HAS_POSIXTTY#include <termios.h>#endif#endif#endif#ifdef HAS_GETPW#include <pwd.h>#endif#ifdef HAS_UNIX_SIGS#include <signal.h>#endif#ifdef HAS_WAIT2#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. *  * 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();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 HAS_ACCESS    if (access(name, 0) == 0)        return (true);#endif    return (false);}#ifdef HAS_SYSTEM/* Fork a shell. */voidcom_shell(wl)    wordlist *wl;{    char *com, *shell = NULL;    long pid, r;#ifdef HAS_UNIX_SIGS    static SIGNAL_TYPE (*svint)( ), (*svquit)( ), (*svtstp)( );#endif#ifdef HAS_ENVIRON    shell = getenv("SHELL");    if (shell == NULL)        shell = "/bin/csh";#endif        cp_ccon(false);#ifdef HAS_VFORK	/* XXX Needs to switch process groups.  Also, worry about suspend */	/* Only bother for efficiency */        pid = vfork();        if (pid == 0) {            fixdescriptors();	    if (wl == NULL) {		(void) execl(shell, shell, 0);		_exit(99);	    } else {		com = wl_flatten(wl);		(void) execl("/bin/sh", "sh", "-c", com, 0);	    }        } else {	    /* XXX Better have all these signals */	    svint = signal(SIGINT, SIG_DFL);	    svquit = signal(SIGQUIT, SIG_DFL);	    svtstp = signal(SIGTSTP, SIG_DFL);	    /* XXX Sig on proc group */            do {                r = wait((union wait *) NULL);            } while ((r != pid) && pid != -1);	    (void) signal(SIGINT, (SIGNAL_FUNCTION) svint);	    (void) signal(SIGQUIT, (SIGNAL_FUNCTION) svquit);	    (void) signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp);        }#else    /* Easier to forget about changing the io descriptors. */    if (wl) {        com = wl_flatten(wl);        (void) system(com);    } else        (void) system(shell);#endif    return;}#else/* ARGSUSED */voidcom_shell(wl)    wordlist *wl;{    fprintf(cp_err, "Error: No shell available.\n");    return;}#endif/* Do this only right before an exec, since we lose the old std*'s. */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;}/* 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;}#ifdef HAS_CHDIRvoidcom_chdir(wl)    wordlist *wl;{    char *s;    struct passwd *pw;    extern struct passwd *getpwuid( );    char localbuf[257];    int copied = 0;    s = NULL;    if (wl == NULL) {#ifdef HAS_ENVIRON	s = getenv("HOME");#endif#ifdef HAS_GETPW	if (s == NULL) {	    pw = getpwuid(getuid());	    if (pw == NULL) {		fprintf(cp_err, "Can't get your password entry\n");		return;	    }           	    s = pw->pw_dir;	}#endif    } else {        s = cp_unquote(wl->wl_word);	copied = 1;    }#ifdef HAS_DOSDIRS    if (s && *s && s[1] == ':') {	char	buf[1000];	sprintf(buf, "%c:", *s);	system(buf);	strcpy(s, s + 2);    }#endif    if (*s && chdir(s) == -1)        perror(s);    if (copied)	tfree(s);#ifdef HAS_GETCWD    if (s = (char *)getcwd(localbuf, sizeof(localbuf)))	    printf("Current directory: %s\n", s);    else	    fprintf(cp_err, "Can't get current working directory.\n");#endif    return;}#elsevoidcom_chdir(wl)    wordlist *wl;{    fprintf(cp_err, "Error: 'chdir' no available.\n");    return;}#endif/* 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 + -