v18i090: zsh2.00 - The Z shell, Part07/15
Paul Falstad
pfalstad at phoenix.princeton.edu
Wed Apr 24 13:04:24 AEST 1991
Submitted-by: Paul Falstad <pfalstad at phoenix.princeton.edu>
Posting-number: Volume 18, Issue 90
Archive-name: zsh2.00/part07
#!/bin/sh
# this is zsh2.00.00.shar.07 (part 7 of zsh2.00.00)
# do not concatenate these parts, unpack them in order with /bin/sh
# file zsh2.00/src/init.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 7; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping zsh2.00/src/init.c'
else
echo 'x - continuing file zsh2.00/src/init.c'
sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.00/src/init.c' &&
X intr(); /* interrupts on */
X ainit(); /* init alias mech */
X lexinit();
X errflag = 0;
X if (!(list = parlist()))
X { /* if we couldn't parse a list */
X hend();
X if (eofseen && !errflag)
X break;
X continue;
X }
X if (hend())
X {
X if (stopmsg) /* unset 'you have stopped jobs' flag */
X stopmsg--;
X execlist(list);
X }
X if (ferror(stderr))
X {
X zerr("write error",NULL,0);
X clearerr(stderr);
X }
X if (subsh) /* how'd we get this far in a subshell? */
X exit(lastval);
X if ((!interact && errflag) || retflag)
X break;
X if ((opts['t'] == OPT_SET) || (lastval && opts[ERREXIT] == OPT_SET))
X {
X if (sigtrapped[SIGEXIT])
X dotrap(SIGEXIT);
X exit(lastval);
X }
X }
X popheap();
X}
X
Xvoid setflags() /**/
X{
Xint c;
X
X for (c = 0; c != 128; c++)
X opts[c] = OPT_INVALID;
X for (c = 'a'; c <= 'z'; c++)
X opts[c] = opts[c-'a'+'A'] = OPT_UNSET;
X for (c = '0'; c <= '9'; c++)
X opts[c] = OPT_UNSET;
X opts['A'] = opts['V'] = OPT_INVALID;
X opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
X opts[BGNICE] = opts[NOTIFY] = OPT_SET;
X opts[USEZLE] = (interact && SHTTY != -1) ? OPT_SET : OPT_UNSET;
X}
X
Xstatic char *cmd;
X
Xvoid parseargs(argv) /**/
Xchar **argv;
X{
Xchar **x;
Xint bk = 0,action;
XLklist paramlist;
X
X argzero = *argv;
X opts[LOGINSHELL] = (**(argv++) == '-') ? OPT_SET : OPT_UNSET;
X SHIN = 0;
X while (!bk && *argv && (**argv == '-' || **argv == '+'))
X {
X action = (**argv == '-') ? OPT_SET : OPT_UNSET;
X while (*++*argv)
X {
X if (opts[**argv] == OPT_INVALID)
X {
X zerr("bad option: -%c",NULL,**argv);
X exit(1);
X }
X opts[**argv] = action;
X if (bk = **argv == 'b')
X break;
X if (**argv == 'c') /* -c command */
X {
X argv++;
X if (!*argv)
X {
X zerr("string expected after -c",NULL,0);
X exit(1);
X }
X cmd = *argv;
X opts[INTERACTIVE] = OPT_UNSET;
X break;
X }
X else if (**argv == 'o')
X {
X int c;
X
X argv++;
X c = optlookup(*argv);
X if (c == -1)
X zerr("no such option: %s",argv[-1],0);
X else
X opts[c] = action;
X break;
X }
X }
X argv++;
X }
X paramlist = newlist();
X if (*argv)
X {
X if (opts[SHINSTDIN] == OPT_UNSET)
X {
X SHIN = movefd(open(argzero = *argv,O_RDONLY));
X if (SHIN == -1)
X {
X zerr("can't open input file: %s",*argv,0);
X exit(1);
X }
X opts[INTERACTIVE] = OPT_UNSET;
X argv++;
X }
X while (*argv)
X addnode(paramlist,ztrdup(*argv++));
X }
X else
X opts[SHINSTDIN] = OPT_SET;
X pparams = x = zcalloc((countnodes(paramlist)+1)*sizeof(char *));
X while (*x++ = getnode(paramlist));
X free(paramlist);
X argzero = ztrdup(argzero);
X}
X
Xvoid setmoreflags() /**/
X{
X setvbuf(stdout,NULL,_IOFBF,BUFSIZ); /* stdout,stderr fully buffered */
X setvbuf(stderr,NULL,_IOFBF,BUFSIZ);
X subsh = 0;
X opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
X if (jobbing)
X {
X SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
X if (SHTTY == -1)
X opts[MONITOR] = OPT_UNSET;
X else
X gettyinfo(&shttyinfo); /* get tty state */
X if ((mypgrp = getpgrp(0)) <= 0)
X opts[MONITOR] = OPT_UNSET;
X }
X else
X SHTTY = -1;
X}
X
Xvoid setupvals() /**/
X{
Xstruct passwd *pwd;
Xchar *ptr;
Xstatic long bauds[] = {
X 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
X };
X
X curhist = 0;
X histsiz = 20;
X lithistsiz = 5;
X logcheck = 60;
X dirstacksize = -1;
X listmax = 100;
X bangchar = '!';
X hashchar = '#';
X hatchar = '^';
X termok = 0;
X curjob = prevjob = coprocin = coprocout = -1;
X shtimer = time(NULL); /* init $SECONDS */
X srand((unsigned int) shtimer);
X /* build various hash tables; argument to newhtable is table size */
X aliastab = newhtable(37);
X addreswords();
X paramtab = newhtable(151);
X cmdnamtab = newhtable(13);
X initxbindtab();
X if (interact)
X {
X prompt = ztrdup("%m%# ");
X prompt2 = ztrdup("> ");
X prompt3 = ztrdup("?# ");
X prompt4 = ztrdup("+ ");
X }
X ppid = getppid();
X#ifdef TERMIOS
X baud = bauds[cfgetospeed(&shttyinfo.termios)];
X#else
X#ifdef TERMIO
X baud = bauds[shttyinfo.termio.c_cflag & CBAUD];
X#else
X baud = bauds[shttyinfo.sgttyb.sg_ospeed];
X#endif
X#endif
X if (!(columns = shttyinfo.winsize.ws_col))
X columns = 80;
X if (!(lines = shttyinfo.winsize.ws_row))
X lines = 24;
X home = ztrdup("/");
X ifs = ztrdup(" \t\n");
X if (pwd = getpwuid(getuid()))
X {
X username = ztrdup(pwd->pw_name);
X home = xsymlink(pwd->pw_dir);
X }
X else
X {
X username = ztrdup("");
X home = ztrdup("/");
X }
X timefmt = ztrdup(DEFTIMEFMT);
X watchfmt = ztrdup(DEFWATCHFMT);
X ttystrname = ztrdup(ttyname(SHTTY));
X wordchars = ztrdup(DEFWORDCHARS);
X cwd = zgetwd();
X oldpwd = ztrdup(cwd);
X hostM = zalloc(512); /* get hostname, with and without .podunk.edu */
X hostm = hostM+256;
X underscore = ztrdup("");
X gethostname(hostm,256);
X gethostname(hostM,256);
X mypid = getpid();
X cdpath = mkarray(ztrdup("."));
X fignore = mkarray(NULL);
X fpath = mkarray(NULL);
X mailpath = mkarray(NULL);
X watch = mkarray(NULL);
X userdirs = (char **) zcalloc(sizeof(char **)*2);
X usernames = (char **) zcalloc(sizeof(char **)*2);
X userdirsz = 2;
X userdirct = 0;
X optarg = ztrdup("");
X optind = 1;
X path = (char **) zalloc(4*sizeof *path);
X path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin");
X path[2] = ztrdup("/usr/ucb"); path[3] = NULL;
X for (ptr = hostM; *ptr && *ptr != '.'; ptr++);
X *ptr = '\0';
X inittyptab();
X setupparams();
X setparams();
X inittyptab();
X}
X
Xvoid initialize() /**/
X{
Xint t0;
X
X breaks = loops = incmd = 0;
X lastmailcheck = time(NULL);
X firsthist = firstlithist = 1;
X histsiz = DEFAULT_HISTSIZE;
X histlist = newlist();
X lithistlist = newlist();
X locallist = NULL;
X dirstack = newlist();
X bufstack = newlist();
X newcmdnamtab();
X inbuf = zalloc(inbufsz = 256);
X inbufptr = inbuf+inbufsz;
X inbufct = 0;
X /*signal(SIGQUIT,SIG_IGN);*/
X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
X getrlimit(t0,limits+t0);
X hsubl = hsubr = NULL;
X lastpid = 0;
X bshin = fdopen(SHIN,"r");
X signal(SIGCHLD,handler);
X if (jobbing)
X {
X signal(SIGTTOU,SIG_IGN);
X signal(SIGTSTP,SIG_IGN);
X signal(SIGTTIN,SIG_IGN);
X signal(SIGPIPE,SIG_IGN);
X attachtty(mypgrp);
X }
X if (interact)
X {
X signal(SIGTERM,SIG_IGN);
X signal(SIGWINCH,handler);
X signal(SIGALRM,handler);
X intr();
X }
X}
X
Xvoid addreswords() /**/
X{
Xstatic char *reswds[] = {
X "do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
X "if", "while", "function", "repeat", "time", "until", "exec", "command",
X "select", "coproc", "noglob", "-", NULL
X };
Xint t0;
X
X for (t0 = 0; reswds[t0]; t0++)
X addhperm(reswds[t0],mkanode(NULL,-1-t0),aliastab,NULL);
X}
X
Xvoid runscripts() /**/
X{
X/* if (interact)
X checkfirstmail();*/
X if (opts[NORCS] == OPT_UNSET)
X {
X#ifdef GLOBALZSHRC
X source(GLOBALZSHRC);
X#endif
X sourcehome(".zshrc");
X if (islogin)
X {
X#ifdef GLOBALZLOGIN
X source(GLOBALZLOGIN);
X#endif
X sourcehome(".zlogin");
X }
X }
X if (interact)
X readhistfile();
X if (opts['c'] == OPT_SET)
X {
X if (SHIN >= 10)
X close(SHIN);
X SHIN = movefd(open("/dev/null",O_RDONLY));
X hungets(cmd);
X strinbeg();
X }
X if (!(columns = shttyinfo.winsize.ws_col))
X columns = 80;
X if (!(lines = shttyinfo.winsize.ws_row))
X lines = 24;
X}
X
Xvoid ainit() /**/
X{
X alstackind = 0; /* reset alias stack */
X alstat = 0;
X isfirstln = 1;
X}
X
Xvoid readhistfile() /**/
X{
Xchar *s,buf[1024];
XFILE *in;
X
X if (!(s = getsparam("HISTFILE")))
X return;
X if (in = fopen(s,"r"))
X {
X permalloc();
X while (fgets(buf,1024,in))
X {
X int l = strlen(buf);
X
X if (l && buf[l-1] == '\n')
X buf[l-1] = '\0';
X addnode(histlist,ztrdup(buf));
X addnode(lithistlist,ztrdup(buf));
X curhist++;
X }
X fclose(in);
X lastalloc();
X }
X}
X
Xvoid savehistfile() /**/
X{
Xchar *s,*t;
XLknode n;
XLklist l;
XFILE *out;
X
X if (!(s = getsparam("HISTFILE")) || !interact)
X return;
X if (out = fdopen(open(s,O_CREAT|O_WRONLY|O_TRUNC,0600),"w"))
X {
X n = lastnode(l = (isset(HISTLIT) ? lithistlist : histlist));
X if (n == (Lknode) l)
X {
X fclose(out);
X return;
X }
X while (--savehist && prevnode(n) != (Lknode) l)
X n = prevnode(n);
X for (; n; incnode(n))
X {
X for (s = t = getdata(n); *s; s++)
X if (*s == HISTSPACE)
X *s = ' ';
X fputs(t,out);
X fputc('\n',out);
X }
X fclose(out);
X }
X}
X
SHAR_EOF
echo 'File zsh2.00/src/init.c is complete' &&
chmod 0644 zsh2.00/src/init.c ||
echo 'restore of zsh2.00/src/init.c failed'
Wc_c="`wc -c < 'zsh2.00/src/init.c'`"
test 10131 -eq "$Wc_c" ||
echo 'zsh2.00/src/init.c: original size 10131, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/init.pro ==============
if test -f 'zsh2.00/src/init.pro' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/init.pro (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/init.pro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/init.pro' &&
Xvoid main DCLPROTO((int argc, char **argv, char **envp));
Xvoid loop DCLPROTO((void));
Xvoid setflags DCLPROTO((void));
Xvoid parseargs DCLPROTO((char **argv));
Xvoid setmoreflags DCLPROTO((void));
Xvoid setupvals DCLPROTO((void));
Xvoid initialize DCLPROTO((void));
Xvoid addreswords DCLPROTO((void));
Xvoid runscripts DCLPROTO((void));
Xvoid ainit DCLPROTO((void));
Xvoid readhistfile DCLPROTO((void));
Xvoid savehistfile DCLPROTO((void));
SHAR_EOF
chmod 0644 zsh2.00/src/init.pro ||
echo 'restore of zsh2.00/src/init.pro failed'
Wc_c="`wc -c < 'zsh2.00/src/init.pro'`"
test 431 -eq "$Wc_c" ||
echo 'zsh2.00/src/init.pro: original size 431, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/jobs.c ==============
if test -f 'zsh2.00/src/jobs.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/jobs.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/jobs.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/jobs.c' &&
X/*
X
X jobs.c - job control
X
X This file is part of zsh, the Z shell.
X
X zsh is free software; no one can prevent you from reading the source
X code, or giving it to someone else.
X
X This file is copyrighted under the GNU General Public License, which
X can be found in the file called COPYING.
X
X Copyright (C) 1990, 1991 Paul Falstad
X
X zsh is distributed in the hope that it will be useful, but
X WITHOUT ANY WARRANTY. No author or distributor accepts
X responsibility to anyone for the consequences of using it or for
X whether it serves any particular purpose or works at all, unless he
X says so in writing. Refer to the GNU General Public License
X for full details.
X
X Everyone is granted permission to copy, modify and redistribute
X zsh, but only under the conditions described in the GNU General Public
X License. A copy of this license is supposed to have been given to you
X along with zsh so you can know your rights and responsibilities.
X It should be in a file named COPYING.
X
X Among other things, the copyright notice and this notice must be
X preserved on all copies.
X
X*/
X
X#include "zsh.h"
X#include "funcs.h"
X#include <sys/errno.h>
X
X#define WCOREDUMPED(x) ((x)&0x80)
X
X/* != 0 means the handler is active */
X
Xstatic int handling = 0;
X
X/* != 0 means the shell is waiting for a job to complete */
X
Xstatic int waiting = 0;
X
X#ifdef INTHANDTYPE
X#define RETURN return 0
X#else
X#define RETURN return
X#endif
X
X/* the signal handler */
X
XHANDTYPE handler(sig,code) /**/
Xint sig;int code;
X{
Xlong pid;
Xint statusp;
XJob jn;
Xstruct process *pn;
Xstruct rusage ru;
X
X#ifdef RESETHANDNEEDED
X signal(sig,handler);
X#endif
X if (sig == SIGINT)
X {
X if (sigtrapped[SIGINT])
X dotrap(SIGINT);
X else
X errflag = 1;
X RETURN;
X }
X if (sig == SIGWINCH)
X adjustwinsize();
X if (sig != SIGCHLD)
X {
X dotrap(sig);
X if (sig == SIGALRM && !sigtrapped[SIGALRM])
X {
X zerr("timeout",NULL,0);
X exit(1);
X }
X RETURN;
X }
X for (;;)
X {
X pid = wait3(&statusp,WNOHANG|WUNTRACED,&ru);
X if (pid == -1)
X {
X if (errno != ECHILD)
X zerr("%e",NULL,errno);
X RETURN;
X }
X if (!pid)
X RETURN;
X findproc(pid,&jn,&pn); /* find the process of this pid */
X if (jn)
X {
X pn->statusp = statusp;
X handling = 1;
X pn->ru = ru;
X pn->endtime = time(NULL);
X updatestatus(jn);
X handling = 0;
X if (zleactive)
X refresh();
X }
X else if (WIFSTOPPED(SP(statusp)))
X kill(pid,SIGKILL); /* kill stopped untraced children */
X }
X RETURN;
X}
X
X/* change job table entry from stopped to running */
X
Xvoid makerunning(jn) /**/
XJob jn;
X{
Xstruct process *pn;
X
X jn->stat &= ~STAT_STOPPED;
X for (pn = jn->procs; pn; pn = pn->next)
X if (WIFSTOPPED(SP(pn->statusp)))
X pn->statusp = SP_RUNNING;
X}
X
X/* update status of job, possibly printing it */
X
Xvoid updatestatus(jn) /**/
XJob jn;
X{
Xstruct process *pn;
Xint notrunning = 1,alldone = 1,val,job = jn-jobtab,somestopped = 0;
X
X for (pn = jn->procs; pn; pn = pn->next)
X {
X if (pn->statusp == SP_RUNNING)
X notrunning = 0;
X if (pn->statusp == SP_RUNNING || WIFSTOPPED(SP(pn->statusp)))
X alldone = 0;
X if (WIFSTOPPED(SP(pn->statusp)))
X somestopped = 1;
X if (!pn->next && jn)
X val = (WIFSIGNALED(SP(pn->statusp))) ?
X 0200 | WTERMSIG(SP(pn->statusp)) : WEXITSTATUS(SP(pn->statusp));
X }
X if (!notrunning)
X return;
X if (somestopped && (jn->stat & STAT_STOPPED))
X return;
X jn->stat |= (alldone) ? STAT_CHANGED|STAT_DONE :
X STAT_CHANGED|STAT_STOPPED;
X if (!alldone)
X {
X gettyinfo(&jn->ttyinfo);
X settyinfo(&shttyinfo);
X }
X else if (job == thisjob)
X {
X if (!val)
X {
X gettyinfo(&shttyinfo);
X columns = shttyinfo.winsize.ws_col;
X lines = shttyinfo.winsize.ws_row;
X }
X else
X settyinfo(&shttyinfo);
X lastval = val;
X }
X if (jn->stat & STAT_STOPPED)
X {
X prevjob = curjob;
X curjob = job;
X }
X if ((isset(NOTIFY) || job == thisjob) && jn->stat & STAT_LOCKED)
X printjob(jn,!!isset(LONGLISTJOBS));
X if (sigtrapped[SIGCHLD] && job != thisjob)
X dotrap(SIGCHLD);
X}
X
X/* find process and job associated with pid */
X
Xvoid findproc(pid,jptr,pptr) /**/
Xint pid;Job *jptr;struct process **pptr;
X{
Xstruct process *pn;
Xint jn;
X
X for (jn = 1; jn != MAXJOB; jn++)
X for (pn = jobtab[jn].procs; pn; pn = pn->next)
X if (pn->pid == pid)
X {
X *pptr = pn;
X *jptr = jobtab+jn;
X return;
X }
X *pptr = NULL;
X *jptr = NULL;
X}
X
X/*
X lng = 0 means jobs
X lng = 1 means jobs -l
X lng = 2 means jobs -p
X*/
X
Xvoid printjob(jn,lng) /**/
XJob jn;int lng;
X{
Xint job = jn-jobtab,len = 9,sig = -1,sflag = 0,llen,printed = 0;
Xint conted = 0,lineleng = getlineleng(),doputnl = 0,skip = 0;
Xstruct process *pn;
X
X if (lng < 0)
X {
X conted = 1;
X lng = 0;
X }
X
X /* find length of longest signame, check to see if we
X really need to print this job */
X
X for (pn = jn->procs; pn; pn = pn->next)
X {
X if (pn->statusp != SP_RUNNING)
X if (WIFSIGNALED(SP(pn->statusp)))
X {
X sig = WTERMSIG(SP(pn->statusp));
X llen = strlen(sigmsg[sig]);
X if (WCOREDUMPED(pn->statusp))
X llen += 14;
X if (llen > len)
X len = llen;
X if (sig != SIGINT && sig != SIGPIPE)
X sflag = 1;
X if (sig == SIGINT && job == thisjob && interact)
X doputnl = 1;
X }
X else if (WIFSTOPPED(SP(pn->statusp)))
X {
X sig = WSTOPSIG(SP(pn->statusp));
X if (strlen(sigmsg[sig]) > len)
X len = strlen(sigmsg[sig]);
X if (handling && (!waiting || sig == SIGSTOP))
X doputnl = 1;
X }
X else if (isset(PRINTEXITVALUE) && WEXITSTATUS(SP(pn->statusp)))
X sflag = 1;
X }
X
X /* print if necessary */
X
X if (interact && jobbing && ((jn->stat & STAT_STOPPED) || sflag ||
X job != thisjob))
X {
X int len2,fline = 1;
X struct process *qn;
X
X trashzle();
X if (doputnl)
X putc('\n',stderr);
X for (pn = jn->procs; pn;)
X {
X len2 = ((job == thisjob) ? 5 : 10)+len; /* 2 spaces */
X if (lng)
X qn = pn->next;
X else for (qn = pn->next; qn; qn = qn->next)
X {
X if (qn->statusp != pn->statusp)
X break;
X if (strlen(qn->text)+len2+((qn->next) ? 3 : 0) > lineleng)
X break;
X len2 += strlen(qn->text)+2;
X }
X if (job != thisjob)
X if (fline)
X fprintf(stderr,"[%d] %c ",jn-jobtab,(job == curjob) ? '+' :
X (job == prevjob) ? '-' : ' ');
X else
X fprintf(stderr,(job > 9) ? " " : " ");
X else
X fprintf(stderr,"zsh: ");
X if (lng)
X if (lng == 1)
X fprintf(stderr,"%d ",pn->pid);
X else
X {
X int x = jn->gleader;
X
X fprintf(stderr,"%d ",x);
X do skip++; while (x /= 10);
X skip++;
X lng = 0;
X }
X else
X fprintf(stderr,"%*s",skip,"");
X if (pn->statusp == SP_RUNNING)
X if (!conted)
X fprintf(stderr,"running%*s",len-7+2,"");
X else
X fprintf(stderr,"continued%*s",len-9+2,"");
X else if (WIFEXITED(SP(pn->statusp)))
X if (WEXITSTATUS(SP(pn->statusp)))
X fprintf(stderr,"exit %-4d%*s",WEXITSTATUS(SP(pn->statusp)),
X len-9+2,"");
X else
X fprintf(stderr,"done%*s",len-4+2,"");
X else if (WIFSTOPPED(SP(pn->statusp)))
X fprintf(stderr,"%-*s",len+2,sigmsg[WSTOPSIG(SP(pn->statusp))]);
X else if (WCOREDUMPED(pn->statusp))
X fprintf(stderr,"%s (core dumped)%*s",
X sigmsg[WTERMSIG(SP(pn->statusp))],
X len-14+2-strlen(sigmsg[WTERMSIG(SP(pn->statusp))]),"");
X else
X fprintf(stderr,"%-*s",len+2,sigmsg[WTERMSIG(SP(pn->statusp))]);
X for (; pn != qn; pn = pn->next)
X fprintf(stderr,(pn->next) ? "%s | " : "%s",pn->text);
X putc('\n',stderr);
X fline = 0;
X }
X printed = 1;
X fflush(stderr);
X }
X
X /* print "(pwd now: foo)" messages */
X
X if (interact && job==thisjob && strcmp(jn->cwd,cwd))
X {
X printf("(pwd now: ");
X printdir(cwd);
X printf(")\n");
X fflush(stdout);
X }
X
X /* delete job if done */
X
X if (jn->stat & STAT_DONE)
X {
X static struct job zero;
X struct process *nx;
X char *s;
X
X if (jn->stat & STAT_TIMED)
X {
X dumptime(jn);
X printed = 1;
X }
X for (pn = jn->procs; pn; pn = nx)
X {
X nx = pn->next;
X if (pn->text)
X free(pn->text);
X free(pn);
X }
X free(jn->cwd);
X if (jn->filelist)
X {
X while (s = getnode(jn->filelist))
X {
X unlink(s);
X free(s);
X }
X free(jn->filelist);
X }
X *jn = zero;
X if (job == curjob)
X {
X curjob = prevjob;
X prevjob = job;
X }
X if (job == prevjob)
X setprevjob();
X }
X else
X jn->stat &= ~STAT_CHANGED;
X}
X
X/* set the previous job to something reasonable */
X
Xvoid setprevjob() /**/
X{
Xint t0;
X
X for (t0 = MAXJOB-1; t0; t0--)
X if (jobtab[t0].stat && jobtab[t0].stat & STAT_STOPPED &&
X t0 != curjob && t0 != thisjob)
X break;
X if (!t0)
X for (t0 = MAXJOB-1; t0; t0--)
X if (jobtab[t0].stat && t0 != curjob && t0 != thisjob)
X break;
X prevjob = (t0) ? t0 : -1;
X}
X
X/* initialize a job table entry */
X
Xvoid initjob() /**/
X{
X jobtab[thisjob].cwd = ztrdup(cwd);
X jobtab[thisjob].stat = STAT_INUSE;
X jobtab[thisjob].ttyinfo = shttyinfo;
X jobtab[thisjob].gleader = 0;
X}
X
X/* add a process to the current job */
X
Xstruct process *addproc(pid,text) /**/
Xlong pid;char *text;
X{
Xstruct process *process;
X
X if (!jobtab[thisjob].gleader)
X jobtab[thisjob].gleader = lastpid = pid;
X lastpid = pid;
X process = zcalloc(sizeof *process);
X process->pid = pid;
X process->text = text;
X process->next = NULL;
X process->statusp = SP_RUNNING;
X process->bgtime = time(NULL);
X if (jobtab[thisjob].procs)
X {
X struct process *n;
X
X for (n = jobtab[thisjob].procs; n->next && !n->next->lastfg; n = n->next);
X process->next = n->next;
X n->next = process;
X }
X else
X jobtab[thisjob].procs = process;
X return process;
X}
X
X/* determine if it's all right to exec a command without
X forking in last component of subshells; it's not ok if we have files
X to delete */
X
Xint execok() /**/
X{
XJob jn;
X
X if (!exiting)
X return 0;
X for (jn = jobtab+1; jn != jobtab+MAXJOB; jn++)
X if (jn->stat && jn->filelist)
X return 0;
X return 1;
X}
X
X/* wait for a SIGCHLD, wait for the handler to execute, and return */
X
Xvoid chldsuspend() /**/
X{
X#ifdef SIGVEC
Xstatic struct sigvec vec = { handler,sigmask(SIGCHLD),SV_INTERRUPT };
X
X sigvec(SIGCHLD,&vec,NULL);
X sigpause(0);
X signal(SIGCHLD,handler);
X#else
X pause();
X#endif
X}
X
X/* wait for a job to finish */
X
Xvoid waitjob(job) /**/
Xint job;
X{
Xstatic struct job zero;
XJob jn;
X
X if (jobtab[job].procs) /* if any forks were done */
X {
X jobtab[job].stat |= STAT_LOCKED;
X waiting = 1;
X if (jobtab[job].stat & STAT_CHANGED)
X printjob(jobtab+job,!!isset(LONGLISTJOBS));
X while (jobtab[job].stat &&
X !(jobtab[job].stat & (STAT_DONE|STAT_STOPPED)))
X chldsuspend();
X waiting = 0;
X }
X else /* else do what printjob() usually does */
X {
X char *s;
X
X jn = jobtab+job;
X free(jn->cwd);
X if (jn->filelist)
X {
X while (s = getnode(jn->filelist))
X {
X unlink(s);
X free(s);
X }
X free(jn->filelist);
X }
X *jn = zero;
X }
X}
X
X/* wait for running job to finish */
X
Xvoid waitjobs() /**/
X{
X waitjob(thisjob);
X thisjob = -1;
X}
X
X/* clear job table when entering subshells */
X
Xvoid clearjobtab() /**/
X{
Xstatic struct job zero;
Xint t0;
X
X for (t0 = 1; t0 != MAXJOB; t0++)
X jobtab[thisjob] = zero;
X}
X
X/* get a free entry in the job table to use */
X
Xint getfreejob() /**/
X{
Xint mask,t0;
X
X mask = sigblock(sigmask(SIGCHLD));
X for (t0 = 1; t0 != MAXJOB; t0++)
X if (!jobtab[t0].stat)
X {
X sigsetmask(mask);
X jobtab[t0].stat |= STAT_INUSE;
X return t0;
X }
X sigsetmask(mask);
X zerr("job table full",NULL,0);
X return -1;
X}
X
X/* print pids for & */
X
Xvoid spawnjob() /**/
X{
Xstruct process *pn;
X
X if (!subsh)
X {
X if (curjob == -1 || !(jobtab[curjob].stat & STAT_STOPPED))
X {
X curjob = thisjob;
X setprevjob();
X }
X else if (prevjob == -1 || !(jobtab[prevjob].stat & STAT_STOPPED))
X prevjob = thisjob;
X if (interact && jobbing && jobtab[thisjob].procs)
X {
X fprintf(stderr,"[%d]",thisjob);
X for (pn = jobtab[thisjob].procs; pn; pn = pn->next)
X fprintf(stderr," %d",pn->pid);
X fprintf(stderr,"\n");
X fflush(stderr);
X }
X }
X if (!jobtab[thisjob].procs)
X {
X char *s;
X static struct job zero;
X struct job *jn;
X
X jn = jobtab+thisjob;
X free(jn->cwd);
X if (jn->filelist)
X {
X while (s = getnode(jn->filelist))
X {
X unlink(s);
X free(s);
X }
X free(jn->filelist);
X }
X *jn = zero;
X }
X else
X jobtab[thisjob].stat |= STAT_LOCKED;
X thisjob = -1;
X}
X
Xvoid fixsigs() /**/
X{
X sigsetmask(0);
X}
X
Xvoid printtime(real,ru,desc) /**/
Xtime_t real;struct rusage *ru;char *desc;
X{
Xchar *s;
X
X if (!desc)
X desc = "";
X for (s = (timefmt) ? timefmt : DEFTIMEFMT; *s; s++)
X if (*s == '%')
X switch(s++,*s)
X {
X case 'E': fprintf(stderr,"%lds",real); break;
X case 'U': fprintf(stderr,"%ld.%03lds",
X ru->ru_utime.tv_sec,ru->ru_utime.tv_usec/1000); break;
X case 'S': fprintf(stderr,"%ld.%03lds",
X ru->ru_stime.tv_sec,ru->ru_stime.tv_usec/1000); break;
X case 'P':
X if (real)
X fprintf(stderr,"%d%%",
X (int) (ru->ru_utime.tv_sec+ru->ru_stime.tv_sec) / real);
X break;
X case 'W': fprintf(stderr,"%ld",ru->ru_nswap); break;
X case 'X': fprintf(stderr,"%ld",ru->ru_ixrss); break;
X case 'D': fprintf(stderr,"%ld",ru->ru_idrss); break;
X case 'K': fprintf(stderr,"%ld",ru->ru_ixrss+ru->ru_idrss); break;
X case 'M': fprintf(stderr,"%ld",ru->ru_maxrss); break;
X case 'F': fprintf(stderr,"%ld",ru->ru_majflt); break;
X case 'R': fprintf(stderr,"%ld",ru->ru_minflt); break;
X case 'I': fprintf(stderr,"%ld",ru->ru_inblock); break;
X case 'O': fprintf(stderr,"%ld",ru->ru_oublock); break;
X case 'r': fprintf(stderr,"%ld",ru->ru_msgrcv); break;
X case 's': fprintf(stderr,"%ld",ru->ru_msgsnd); break;
X case 'k': fprintf(stderr,"%ld",ru->ru_nsignals); break;
X case 'w': fprintf(stderr,"%ld",ru->ru_nvcsw); break;
X case 'c': fprintf(stderr,"%ld",ru->ru_nivcsw); break;
X default: fprintf(stderr,"%%%c",s[-1]); break;
X }
X else
X putc(*s,stderr);
X putc('\n',stderr);
X fflush(stderr);
X}
X
Xvoid dumptime(jn) /**/
XJob jn;
X{
Xstruct process *pn = jn->procs;
X
X if (!jn->procs)
X return;
X for (pn = jn->procs; pn; pn = pn->next)
X printtime(pn->endtime-pn->bgtime,&pn->ru,pn->text);
X}
X
X/* SIGHUP any jobs left running */
X
Xvoid killrunjobs() /**/
X{
Xint t0,killed = 0;
X
X for (t0 = 1; t0 != MAXJOB; t0++)
X if (t0 != thisjob && jobtab[t0].stat &&
X !(jobtab[t0].stat & STAT_STOPPED))
X {
X killpg(jobtab[t0].gleader,SIGHUP);
X killed++;
X }
X if (killed)
X zerr("warning: %d jobs SIGHUPed",NULL,killed);
X}
X
X/* check to see if user has jobs running/stopped */
X
Xvoid checkjobs() /**/
X{
Xint t0;
X
X for (t0 = 1; t0 != MAXJOB; t0++)
X if (t0 != thisjob && jobtab[t0].stat)
X break;
X if (t0 != MAXJOB)
X {
X if (jobtab[t0].stat & STAT_STOPPED)
X {
X#ifdef USE_SUSPENDED
X zerr("you have suspended jobs.",NULL,0);
X#else
X zerr("you have stopped jobs.",NULL,0);
X#endif
X }
X else
X zerr("you have running jobs.",NULL,0);
X stopmsg = 1;
X }
X}
X
X/* send a signal to a job (simply involves killpg if monitoring is on) */
X
Xint killjb(jn,sig) /**/
XJob jn;int sig;
X{
Xstruct process *pn;
Xint err;
X
X if (jobbing)
X return(killpg(jn->gleader,sig));
X for (pn = jn->procs; pn; pn = pn->next)
X if ((err = kill(pn->pid,sig)) == -1 && errno != ESRCH)
X return -1;
X return err;
X}
X
SHAR_EOF
chmod 0644 zsh2.00/src/jobs.c ||
echo 'restore of zsh2.00/src/jobs.c failed'
Wc_c="`wc -c < 'zsh2.00/src/jobs.c'`"
test 14909 -eq "$Wc_c" ||
echo 'zsh2.00/src/jobs.c: original size 14909, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/jobs.pro ==============
if test -f 'zsh2.00/src/jobs.pro' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/jobs.pro (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/jobs.pro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/jobs.pro' &&
XHANDTYPE handler DCLPROTO((int sig,int code));
Xvoid makerunning DCLPROTO((Job jn));
Xvoid updatestatus DCLPROTO((Job jn));
Xvoid findproc DCLPROTO((int pid,Job *jptr,struct process **pptr));
Xvoid printjob DCLPROTO((Job jn,int lng));
Xvoid setprevjob DCLPROTO((void));
Xvoid initjob DCLPROTO((void));
Xstruct process *addproc DCLPROTO((long pid,char *text));
Xint execok DCLPROTO((void));
Xvoid chldsuspend DCLPROTO((void));
Xvoid waitjob DCLPROTO((int job));
Xvoid waitjobs DCLPROTO((void));
Xvoid clearjobtab DCLPROTO((void));
Xint getfreejob DCLPROTO((void));
Xvoid spawnjob DCLPROTO((void));
Xvoid fixsigs DCLPROTO((void));
Xvoid printtime DCLPROTO((time_t real,struct rusage *ru,char *desc));
Xvoid dumptime DCLPROTO((Job jn));
Xvoid killrunjobs DCLPROTO((void));
Xvoid checkjobs DCLPROTO((void));
Xint killjb DCLPROTO((Job jn,int sig));
SHAR_EOF
chmod 0644 zsh2.00/src/jobs.pro ||
echo 'restore of zsh2.00/src/jobs.pro failed'
Wc_c="`wc -c < 'zsh2.00/src/jobs.pro'`"
test 824 -eq "$Wc_c" ||
echo 'zsh2.00/src/jobs.pro: original size 824, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/lex.c ==============
if test -f 'zsh2.00/src/lex.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/lex.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/lex.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/lex.c' &&
X/*
X
X lex.c - lexical analysis
X
X This file is part of zsh, the Z shell.
X
X zsh is free software; no one can prevent you from reading the source
X code, or giving it to someone else.
X This file is copyrighted under the GNU General Public License, which
X can be found in the file called COPYING.
X
X Copyright (C) 1990, 1991 Paul Falstad
X
X zsh is distributed in the hope that it will be useful, but
X WITHOUT ANY WARRANTY. No author or distributor accepts
X responsibility to anyone for the consequences of using it or for
X whether it serves any particular purpose or works at all, unless he
X says so in writing. Refer to the GNU General Public License
X for full details.
X
X Everyone is granted permission to copy, modify and redistribute
X zsh, but only under the conditions described in the GNU General Public
X License. A copy of this license is supposed to have been given to you
X along with zsh so you can know your rights and responsibilities.
X It should be in a file named COPYING.
X
X Among other things, the copyright notice and this notice must be
X preserved on all copies.
X
X*/
X
X#include "zsh.h"
X#include "y.tab.h"
X#include "funcs.h"
X
X/* lexical state */
X
Xstatic int ignl;
X
Xstatic int xignl,xlsep,xincmd,xincond,xinfunc,xinredir,xincase;
Xstatic int dbparens,xdbparens,xalstat;
Xstatic char *xhlastw;
X
Xstatic int xisfirstln, xisfirstch, xhistremmed, xhistdone,
X xspaceflag, xstophist, xlithist, xalstackind,xhlinesz;
Xstatic char *xhline, *xhptr;
X
Xstatic char *tokstr;
X
X/* initialize lexical state */
X
Xvoid lexinit() /**/
X{
X ignl = lsep = incmd = incond = infunc = inredir = incase =
X dbparens = alstat = 0;
X}
X
X/* save the lexical state */
X
X/* is this a hack or what? */
X
Xvoid lexsave() /**/
X{
X xignl = ignl;
X xlsep = lsep;
X xincmd = incmd;
X xincond = incond;
X xinredir = inredir;
X xinfunc = infunc;
X xincase = incase;
X xdbparens = dbparens;
X xalstat = alstat;
X xalstackind = alstackind;
X xisfirstln = isfirstln;
X xisfirstch = isfirstch;
X xhistremmed = histremmed;
X xhistdone = histdone;
X xspaceflag = spaceflag;
X xstophist = stophist;
X xlithist = lithist;
X xhline = hline;
X xhptr = hptr;
X xhlastw = hlastw;
X xhlinesz = hlinesz;
X}
X
X/* restore lexical state */
X
Xvoid lexrestore() /**/
X{
X ignl = xignl;
X lsep = xlsep;
X incmd = xincmd;
X incond = xincond;
X inredir = xinredir;
X infunc = xinfunc;
X incase = xincase;
X dbparens = xdbparens;
X alstat = xalstat;
X isfirstln = xisfirstln;
X isfirstch = xisfirstch;
X histremmed = xhistremmed;
X histdone = xhistdone;
X spaceflag = xspaceflag;
X stophist = xstophist;
X lithist = xlithist;
X hline = xhline;
X hptr = xhptr;
X hlastw = xhlastw;
X alstackind = xalstackind;
X hlinesz = xhlinesz;
X eofseen = errflag = 0;
X}
X
Xint yylex() /**/
X{
Xint x;
X
X for (;;)
X {
X do
X x = gettok();
X while (x != ENDINPUT && exalias(&x));
X if (x == NEWLIN && ignl)
X continue;
X if (x == SEMI || x == NEWLIN)
X {
X if (lsep)
X continue;
X x = SEPER;
X lsep = 1;
X }
X else
X lsep = (x == AMPER);
X break;
X }
X ignl = 0;
X switch (x)
X {
X case OUTPAR: infunc = incmd = incase = 0; break;
X case INPAR:case INBRACE:case DBAR:case DAMPER:case DO:
X case THEN:case ELIF:case BAR:case BARAMP:case IF:case WHILE:
X case ELSE:ignl = 1;infunc = 0;
X case INOUTPAR: case SEPER:
X case AMPER:incmd = 0; break;
X case ESAC: incase = 0;
X case STRING: case ENVARRAY:
X if (!inredir && !infunc) incmd = 1; inredir = 0; break;
X case OUTANG:case OUTANGBANG:case DOUTANG:case INANG:
X case DINANG:case TRINANG:case INANGAMP:case OUTANGAMP:case OUTANGAMPBANG:
X case DOUTANGAMP:case DOUTANGAMPBANG: inredir = 1; break;
X case FUNC:infunc = 1;break;
X case DINBRACK: incond = 1; break;
X case DOUTBRACK: incond = 0; break;
X case DSEMI: ignl = 1; incmd = 0; case CASE: incase = 1; break;
X }
X return x;
X}
X
Xint len = 0,bsiz = 256;
Xchar *bptr;
X
X/* add a char to the string buffer */
X
Xvoid add(c) /**/
Xint c;
X{
X *bptr++ = c;
X if (bsiz == ++len)
X {
X int newbsiz;
X
X newbsiz = bsiz * 8;
X while (newbsiz < inbufct)
X newbsiz *= 2;
X bptr = len+(tokstr = hrealloc(tokstr,bsiz,newbsiz));
X bsiz = newbsiz;
X }
X}
X
Xint gettok() /**/
X{
Xint bct = 0,pct = 0,brct = 0;
Xint c,d,intpos = 1;
Xint peekfd = -1,peek,incm;
X
Xbeginning:
X hlastw = NULL;
X tokstr = NULL;
X incm = incmd || incond || inredir || incase;
X while (iblank(c = hgetc()));
X isfirstln = 0;
X wordbeg = inbufct;
X hwbegin();
X hwaddc(c);
X if (dbparens) /* handle ((...)) */
X {
X pct = 2;
X peek = STRING;
X len = dbparens = 0;
X bptr = tokstr = ncalloc(bsiz = 256);
X for (;;)
X {
X if (c == '(')
X pct++;
X else if (c == ')')
X pct--;
X else if (c == '\n')
X {
X zerr("parse error: )) expected",NULL,0);
X peek = LEXERR;
X return peek;
X }
X else if (c == '$')
X c = Qstring;
X if (pct >= 2)
X add(c);
X if (pct)
X c = hgetc();
X else
X break;
X }
X *bptr = '\0';
X yylval.str = tokstr;
X return peek;
X }
X if (idigit(c)) /* handle 1< foo */
X {
X d = hgetc();
X hungetc(d);
X if (d == '>' || d == '<')
X {
X peekfd = c-'0';
X c = hgetc();
X }
X }
X
X /* chars in initial position in word */
X
X if ((!interact || unset(SHINSTDIN) || strin ||
X isset(INTERACTIVECOMMENTS)) && c == hashchar)
X {
X while ((c = hgetch()) != '\n' && !itok(c) && c != EOF);
X if (c == '\n')
X peek = NEWLIN;
X else
X errflag = 1;
X return peek;
X }
X switch (c)
X {
X case '\\':
X d = hgetc();
X if (d == '\n')
X goto beginning;
X hungetc(d);
X break;
X case EOF:
X peek = ENDINPUT;
X return peek;
X case HERR:
X peek = LEXERR;
X return peek;
X case '\n':
X peek = NEWLIN;
X return peek;
X case ';':
X d = hgetc();
X if (d != ';')
X {
X hungetc(d);
X peek = SEMI;
X }
X else
X peek = DSEMI;
X return peek;
X case '!':
X if (!incm || incond)
X {
X peek = BANG;
X return peek;
X }
X break;
X case '&':
X d = hgetc();
X if (d != '&')
X {
X hungetc(d);
X peek = AMPER;
X }
X else
X peek = DAMPER;
X return peek;
X case '|':
X d = hgetc();
X if (d == '|')
X peek = DBAR;
X else if (d == '&')
X peek = BARAMP;
X else
X {
X hungetc(d);
X peek = BAR;
X }
X return peek;
X case '(':
X d = hgetc();
X if (d == '(' && !incm)
X {
X yylval.str = tokstr = strdup("let");
X dbparens = 1;
X return STRING;
X }
X else if (d == ')')
X return INOUTPAR;
X hungetc(d);
X if (incm && !incond)
X break;
X return INPAR;
X case ')':
X return OUTPAR;
X case '{':
X if (incm)
X break;
X return INBRACE;
X case '}':
X return OUTBRACE;
X case '[':
X if (incm)
X break;
X d = hgetc();
X if (d == '[')
X return DINBRACK;
X hungetc(d);
X break;
X case ']':
X if (!incond)
X break;
X d = hgetc();
X if (d == ']')
X return DOUTBRACK;
X hungetc(d);
X break;
X case '<':
X d = hgetc();
X if ((incmd && d == '(') || incase)
X {
X hungetc(d);
X break;
X }
X else if (d == '<')
X {
X int e = hgetc();
X
X if (e == '(')
X {
X hungetc(e);
X hungetc(d);
X peek = INANG;
X }
X else if (e == '<')
X peek = TRINANG;
X else
X {
X hungetc(e);
X peek = DINANG;
X }
X }
X else if (d == '&')
X peek = INANGAMP;
X else
X {
X peek = INANG;
X hungetc(d);
X }
X yylval.fds.fd1 = peekfd;
X return peek;
X case '>':
X d = hgetc();
X if (d == '(')
X {
X hungetc(d);
X break;
X }
X else if (d == '&')
X {
X d = hgetc();
X if (d == '!')
X peek = OUTANGAMPBANG;
X else
X {
X hungetc(d);
X peek = OUTANGAMP;
X }
X }
X else if (d == '!')
X peek = OUTANGBANG;
X else if (d == '>')
X {
X d = hgetc();
X if (d == '&')
X {
X d = hgetc();
X if (d == '!')
X peek = DOUTANGAMPBANG;
X else
X {
X hungetc(d);
X peek = DOUTANGAMP;
X }
X }
X else if (d == '!')
X peek = DOUTANGBANG;
X else if (d == '(')
X {
X hungetc(d);
X hungetc('>');
X peek = OUTANG;
X }
X else
X {
X hungetc(d);
X peek = DOUTANG;
X }
X }
X else
X {
X hungetc(d);
X peek = OUTANG;
X }
X yylval.fds.fd1 = peekfd;
X return peek;
X }
X
X /* we've started a string, now get the rest of it, performing
X tokenization */
X
X peek = STRING;
X len = 0;
X bptr = tokstr = ncalloc(bsiz = 256);
X for(;;)
X {
X if (c == ';' || c == '&' || c == EOF ||
X c == HERR || inblank(c))
X break;
X if (c == '#')
X c = Pound;
X else if (c == ')')
X {
X if (!pct)
X break;
X pct--;
X c = Outpar;
X }
X else if (c == ',')
X c = Comma;
X else if (c == '|')
X {
X if (!pct && !incase)
X break;
X c = Bar;
X }
X else if (c == '$')
X {
X d = hgetc();
X
X c = String;
X if (d == '[')
X {
X add(String);
X add(Inbrack);
X while ((c = hgetc()) != ']' && !itok(c) && c != EOF)
X add(c);
X c = Outbrack;
X }
X else if (d == '(')
X {
X add(String);
X skipcomm();
X c = Outpar;
X }
X else
X hungetc(d);
X }
X else if (c == '^')
X c = Hat;
X else if (c == '[')
X {
X brct++;
X c = Inbrack;
X }
X else if (c == ']')
X {
X if (incond && !brct)
X break;
X brct--;
X c = Outbrack;
X }
X else if (c == '*')
X c = Star;
X else if (intpos && c == '~')
X c = Tilde;
X else if (c == '?')
X c = Quest;
X else if (c == '(')
X {
X d = hgetc();
X hungetc(d);
X if (d == ')' || !incm)
X break;
X pct++;
X c = Inpar;
X }
X else if (c == '{')
X {
X c = Inbrace;
X bct++;
X }
X else if (c == '}')
X {
X if (!bct)
X break;
X c = Outbrace;
X bct--;
X }
X else if (c == '>')
X {
X d = hgetc();
X if (d != '(')
X {
X hungetc(d);
X break;
X }
X add(Outang);
X skipcomm();
X c = Outpar;
X }
X else if (c == '<')
X {
X d = hgetc();
X if (!(idigit(d) || d == '-' || d == '>' || d == '(' || d == ')'))
X {
X hungetc(d);
X break;
X }
X c = Inang;
X if (d == '(')
X {
X add(c);
X skipcomm();
X c = Outpar;
X }
X else if (d == ')')
X hungetc(d);
X else
X {
X add(c);
X c = d;
X while (c != '>' && !itok(c) && c != EOF)
X add(c),c = hgetc();
X c = Outang;
X }
X }
X else if (c == '=')
X {
X if (intpos)
X {
X d = hgetc();
X if (d != '(')
X {
X hungetc(d);
X c = Equals;
X }
X else
X {
X add(Equals);
X skipcomm();
X c = Outpar;
X }
X }
X else if (peek != ENVSTRING && !incm)
X {
X d = hgetc();
X if (d == '(' && !incm)
X {
X *bptr = '\0';
X yylval.str = tokstr;
X return ENVARRAY;
X }
X hungetc(d);
X peek = ENVSTRING;
X intpos = 2;
X }
X }
X else if (c == '\\')
X {
X c = hgetc();
X
X if (c == '\n')
X {
X c = hgetc();
X continue;
X }
X add(c);
X c = hgetc();
X continue;
X }
X else if (c == '\'')
X {
X add(Nularg);
X
X /* we add the Nularg to prevent this:
X
X echo $PA'TH'
X
X from printing the path. */
X
X while ((c = hgetc()) != '\'' && !itok(c) && c != EOF)
X add(c);
X c = Nularg;
X }
X else if (c == '\"')
X {
X add(Nularg);
X while ((c = hgetc()) != '\"' && !itok(c) && c != EOF)
X if (c == '\\')
X {
X c = hgetc();
X if (c != '\n')
X {
X if (c != '$' && c != '\\' && c != '\"' && c != '`')
X add('\\');
X add(c);
X }
X }
X else
X {
X if (c == '$')
X {
X d = hgetc();
X if (d == '(')
X {
X add(Qstring);
X skipcomm();
X c = Outpar;
X }
X else if (d == '[')
X {
X add(String);
X add(Inbrack);
X while ((c = hgetc()) != ']' && c != EOF)
X add(c);
X c = Outbrack;
X }
X else
X {
X c = Qstring;
X hungetc(d);
X }
X }
X else if (c == '`')
X c = Qtick;
X add(c);
X }
X c = Nularg;
X }
X else if (c == '`')
X {
X add(Tick);
X while ((c = hgetc()) != '`' && !itok(c) && c != EOF)
X if (c == '\\')
X {
X c = hgetc();
X if (c != '\n')
X {
X if (c != '`' && c != '\\' && c != '$')
X add('\\');
X add(c);
X }
X }
X else
X {
X if (c == '$')
X c = String;
X add(c);
X }
X c = Tick;
X }
X add(c);
X c = hgetc();
X if (intpos)
X intpos--;
X }
X if (c == LEXERR)
X {
X peek = LEXERR;
X return peek;
X }
X hungetc(c);
X *bptr = '\0';
X yylval.str = tokstr;
X return peek;
X}
X
X/* expand aliases, perhaps */
X
Xint exalias(pk) /**/
Xint *pk;
X{
Xstruct alias *an;
Xchar *s,*t;
X
X if (interact && isset(SHINSTDIN) && !strin && !incase && *pk == STRING)
X {
X int ic = incmd || incond || inredir;
X
X if (isset(CORRECTALL) || (isset(CORRECT) && !ic))
X spckword(&yylval.str,ic);
X }
X s = yytext = hwadd();
X for (t = s; *t && *t != HISTSPACE; t++);
X if (!*t)
X t = NULL;
X else
X *t = '\0';
X if (zleparse && !alstackind)
X gotword(s);
X an = gethnode(s,aliastab);
X if (t)
X *t = HISTSPACE;
X if (alstackind != MAXAL && an && !an->inuse &&
X !(an->cmd && incmd && alstat != ALSTAT_MORE))
X {
X if (an->cmd < 0)
X {
X *pk = DO-an->cmd-1;
X return 0;
X }
X an->inuse = 1;
X hungets(ALPOPS);
X hungets((alstack[alstackind++] = an)->text);
X alstat = 0;
X return 1;
X }
X return 0;
X}
X
X/* skip (...) */
X
Xvoid skipcomm() /**/
X{
Xint pct = 1,c;
X
X c = Inpar;
X do
X {
X add(c);
X c = hgetc();
X if (itok(c) || c == EOF)
X break;
X else if (c == '(') pct++;
X else if (c == ')') pct--;
X else if (c == '\\')
X {
X add(c);
X c = hgetc();
X }
X else if (c == '\'')
X {
X add(c);
X while ((c = hgetc()) != '\'' && !itok(c) && c != EOF)
X add(c);
X }
X else if (c == '\"')
X {
X add(c);
X while ((c = hgetc()) != '\"' && !itok(c) && c != EOF)
X if (c == '\\')
X {
X add(c);
X add(hgetc());
X }
X else add(c);
X }
X else if (c == '`')
X {
X add(c);
X while ((c = hgetc()) != '`' && c != HERR && c != EOF)
X if (c == '\\') add(c), add(hgetc());
X else add(c);
X }
X }
X while(pct);
X}
X
SHAR_EOF
chmod 0644 zsh2.00/src/lex.c ||
echo 'restore of zsh2.00/src/lex.c failed'
Wc_c="`wc -c < 'zsh2.00/src/lex.c'`"
test 13477 -eq "$Wc_c" ||
echo 'zsh2.00/src/lex.c: original size 13477, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/lex.pro ==============
if test -f 'zsh2.00/src/lex.pro' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/lex.pro (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/lex.pro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/lex.pro' &&
Xvoid lexinit DCLPROTO((void));
Xvoid lexsave DCLPROTO((void));
Xvoid lexrestore DCLPROTO((void));
Xint yylex DCLPROTO((void));
Xvoid add DCLPROTO((int c));
Xint gettok DCLPROTO((void));
Xint exalias DCLPROTO((int *pk));
Xvoid skipcomm DCLPROTO((void));
SHAR_EOF
chmod 0644 zsh2.00/src/lex.pro ||
echo 'restore of zsh2.00/src/lex.pro failed'
Wc_c="`wc -c < 'zsh2.00/src/lex.pro'`"
test 246 -eq "$Wc_c" ||
echo 'zsh2.00/src/lex.pro: original size 246, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/loop.c ==============
if test -f 'zsh2.00/src/loop.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/loop.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/loop.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/loop.c' &&
X/*
X
X loop.c - loop execution
X
X This file is part of zsh, the Z shell.
X
X zsh is free software; no one can prevent you from reading the source
X code, or giving it to someone else.
X This file is copyrighted under the GNU General Public License, which
X can be found in the file called COPYING.
X
X Copyright (C) 1990, 1991 Paul Falstad
X
X zsh is distributed in the hope that it will be useful, but
X WITHOUT ANY WARRANTY. No author or distributor accepts
X responsibility to anyone for the consequences of using it or for
X whether it serves any particular purpose or works at all, unless he
X says so in writing. Refer to the GNU General Public License
X for full details.
X
X Everyone is granted permission to copy, modify and redistribute
X zsh, but only under the conditions described in the GNU General Public
X License. A copy of this license is supposed to have been given to you
X along with zsh so you can know your rights and responsibilities.
X It should be in a file named COPYING.
X
X Among other things, the copyright notice and this notice must be
X preserved on all copies.
X
X*/
X
X#include "zsh.h"
X#include "funcs.h"
X
Xint execfor(cmd) /**/
XCmd cmd;
X{
XList list;
Xstruct forcmd *node;
Xchar *str;
XLklist args;
Xint cj = thisjob;
X
X loops++;
X exiting = 0;
X node = cmd->u.forcmd;
X args = cmd->args;
X if (!node->inflag)
X {
X char **x;
X
X args = newlist();
X for (x = pparams; *x; x++)
X addnode(args,ztrdup(*x));
X }
X pushheap();
X while (str = ugetnode(args))
X {
X setsparam(node->name,ztrdup(str));
X list = dupstruct(node->list);
X execlist(list);
X if (breaks)
X {
X breaks--;
X if (breaks || !contflag)
X break;
X contflag = 0;
X }
X if (errflag)
X {
X lastval = 1;
X break;
X }
X freeheap();
X }
X popheap();
X thisjob = cj;
X return lastval;
X}
X
Xint execselect(cmd) /**/
XCmd cmd;
X{
XList list;
Xstruct forcmd *node;
Xchar *str,*s;
XLklist args;
XLknode n;
Xint cj = thisjob,t0;
X
X loops++;
X node = cmd->u.forcmd;
X args = cmd->args;
X if (!full(args))
X return 1;
X exiting = 0;
X pushheap();
X for (;;)
X {
X do
X {
X selectlist(args);
X if (interact && SHTTY != -1 && isset(USEZLE))
X {
X int pl;
X
X inittty();
X str = zleread(putprompt(prompt3,&pl),NULL,pl);
X }
X else
X str = fgets(zalloc(256),256,bshin);
X if (!str || errflag)
X {
X fprintf(stderr,"\n");
X fflush(stderr);
X goto done;
X }
X if (s = strchr(str,'\n'))
X *s = '\0';
X }
X while (!*str);
X setsparam("REPLY",ztrdup(str));
X t0 = atoi(str);
X if (!t0)
X str = "";
X else
X {
X for (t0--,n = firstnode(args); n && t0; incnode(n),t0--);
X if (n)
X str = getdata(n);
X else
X str = "";
X }
X setsparam(node->name,ztrdup(str));
X list = dupstruct(node->list);
X execlist(list);
X freeheap();
X if (breaks)
X {
X breaks--;
X if (breaks || !contflag)
X break;
X contflag = 0;
X }
X if (errflag)
X break;
X }
Xdone:
X popheap();
X thisjob = cj;
X return lastval;
X}
X
Xint execwhile(cmd) /**/
XCmd cmd;
X{
XList list;
Xstruct whilecmd *node;
Xint cj = thisjob;
X
X loops++;
X node = cmd->u.whilecmd;
X exiting = 0;
X pushheap();
X for(;;)
X {
X list = dupstruct(node->cont);
X execlist(list);
X if (!((lastval == 0) ^ node->cond))
X break;
X if (breaks)
X {
X breaks--;
X if (breaks || !contflag)
X break;
X contflag = 0;
X }
X list = dupstruct(node->loop);
X execlist(list);
X freeheap();
X if (errflag)
X {
X lastval = 1;
X break;
X }
X }
X popheap();
X thisjob = cj;
X return lastval;
X}
X
Xint execrepeat(cmd) /**/
XCmd cmd;
X{
XList list;
Xint cj = thisjob,count;
X
X loops++;
X exiting = 0;
X if (!full(cmd->args) || nextnode(firstnode(cmd->args)))
X {
X zerr("bad argument for repeat",NULL,0);
X return 1;
X }
X count = atoi(peekfirst(cmd->args));
X pushheap();
X while (count--)
X {
X list = dupstruct(cmd->u.list);
X execlist(list);
X freeheap();
X if (breaks)
X {
X breaks--;
X if (breaks || !contflag)
X break;
X contflag = 0;
X }
X if (lastval)
X break;
X if (errflag)
X {
X lastval = 1;
X break;
X }
X }
X popheap();
X thisjob = cj;
X return lastval;
X}
X
Xint execif(cmd) /**/
XCmd cmd;
X{
Xstruct ifcmd *node;
Xint cj = thisjob;
X
X lastval = 0;
X node = cmd->u.ifcmd;
X exiting = 0;
X while (node)
X {
X if (node->ifl)
X {
X execlist(node->ifl);
X if (lastval)
X {
X node = node->next;
X continue;
X }
X }
X execlist(node->thenl);
X break;
X }
X thisjob = cj;
X return lastval;
X}
X
Xint execcase(cmd) /**/
XCmd cmd;
X{
Xstruct casecmd *node;
Xchar *word;
XLklist args;
Xint cj = thisjob;
X
X node = cmd->u.casecmd;
X args = cmd->args;
X exiting = 0;
X if (firstnode(args) && nextnode(firstnode(args)))
X {
X zerr("bad case statement",NULL,0);
X errflag = 1;
X return 1;
X }
X if (!full(args))
X word = strdup("");
X else
X word = peekfirst(args);
X while (node)
X if (matchpat(word,node->pat))
X break;
X else
X node = node->next;
X if (node)
X execlist(node->list);
X thisjob = cj;
X return lastval;
X}
SHAR_EOF
chmod 0644 zsh2.00/src/loop.c ||
echo 'restore of zsh2.00/src/loop.c failed'
Wc_c="`wc -c < 'zsh2.00/src/loop.c'`"
test 4832 -eq "$Wc_c" ||
echo 'zsh2.00/src/loop.c: original size 4832, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/loop.pro ==============
if test -f 'zsh2.00/src/loop.pro' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/loop.pro (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/loop.pro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/loop.pro' &&
Xint execfor DCLPROTO((Cmd cmd));
Xint execselect DCLPROTO((Cmd cmd));
Xint execwhile DCLPROTO((Cmd cmd));
Xint execrepeat DCLPROTO((Cmd cmd));
Xint execif DCLPROTO((Cmd cmd));
Xint execcase DCLPROTO((Cmd cmd));
SHAR_EOF
chmod 0644 zsh2.00/src/loop.pro ||
echo 'restore of zsh2.00/src/loop.pro failed'
Wc_c="`wc -c < 'zsh2.00/src/loop.pro'`"
test 206 -eq "$Wc_c" ||
echo 'zsh2.00/src/loop.pro: original size 206, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/math.c ==============
if test -f 'zsh2.00/src/math.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/math.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/math.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/math.c' &&
X/*
X
X math.c - mathematical expression evaluation
X
X This file is part of zsh, the Z shell.
X
X zsh is free software; no one can prevent you from reading the source
SHAR_EOF
true || echo 'restore of zsh2.00/src/math.c failed'
fi
echo 'End of zsh2.00.00 part 7'
echo 'File zsh2.00/src/math.c is continued in part 8'
echo 8 > _shar_seq_.tmp
exit 0
--
Paul Falstad pfalstad at phoenix.princeton.edu
And on the roads, too, vicious gangs of KEEP LEFT signs!
If Princeton knew my opinions, they'd have expelled me long ago.
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list