pfalstad@phoenix.princeton.edu (Paul Falstad) (04/25/91)
Submitted-by: Paul Falstad <pfalstad@phoenix.princeton.edu> Posting-number: Volume 18, Issue 92 Archive-name: zsh2.00/part09 #!/bin/sh # this is zsh2.00.00.shar.09 (part 9 of zsh2.00.00) # do not concatenate these parts, unpack them in order with /bin/sh # file zsh2.00/src/parse.y continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 9; 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/parse.y' else echo 'x - continuing file zsh2.00/src/parse.y' sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.00/src/parse.y' && 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 Xstruct list *tree; X%} X X%left DOITNOW X%left EMPTY LEXERR SEPER NEWLIN SEMI X%left DSEMI AMPER INPAR INBRACE OUTPAR X%right DBAR X%right DAMPER X%right BANG X%left OUTBRACE OUTANG OUTANGBANG DOUTANG DOUTANGBANG INANG DINANG X%left INANGAMP OUTANGAMP OUTANGAMPBANG DOUTANGAMP DOUTANGAMPBANG X%left TRINANG X%left BAR BARAMP DINBRACK DOUTBRACK STRING ENVSTRING X%left ENVARRAY ENDINPUT INOUTPAR X%left DO DONE ESAC THEN ELIF ELSE FI FOR CASE IF WHILE X%left FUNC REPEAT TIME UNTIL EXEC COMMAND SELECT COPROC NOGLOB DASH X%left DOITLATER X X%start event X X%union { X Pline Pline; X List List; X Sublist Sublist; X struct cmd *Comm; X struct redir *Fnode; X struct cond *Cond; X struct forcmd *Fornode; X struct casecmd *Casenode; X struct ifcmd *Ifnode; X struct whilecmd *Whilenode; X struct repeatcmd *Repeatnode; X struct varasg *Varnode; X Lklist Table; X struct fdpair fds; X char *str; X int value; X} X X%type <List> event list list1 list2 X%type <Sublist> sublist sublist2 X%type <Pline> pline X%type <Comm> xcommand command simplecommand stufflist X%type <Cond> cond X%type <Table> redirstring X%type <Fnode> redir X%type <fds> redirop BAR X%type <fds> OUTANG OUTANGBANG DOUTANG DOUTANGBANG X%type <fds> INANG DINANG INANGAMP OUTANGAMP TRINANG X%type <fds> OUTANGAMPBANG DOUTANGAMP DOUTANGAMPBANG X%type <str> STRING ENVSTRING ENVARRAY word X%type <Table> optinword wordlist X%type <Ifnode> optelsifs X%type <Casenode> caselist X%% X Xevent : ENDINPUT { tree = NULL; eofseen = 1; return 0; } X | SEPER { tree = NULL; lsep = 0; return 0; } X | list1 { tree = $1; return 0; } X | error ENDINPUT { errflag = 1; tree = NULL; eofseen = 1; return 1; } X | error SEPER { errflag = 1; tree = NULL; return 1; } X | error LEXERR { errflag = 1; tree = NULL; return 1; } X ; X Xlist1 : sublist ENDINPUT { $$ = makelnode($1,SYNC); eofseen = 1; } X | sublist SEPER { $$ = makelnode($1,SYNC); } X | sublist AMPER { $$ = makelnode($1,ASYNC); } X ; X Xlist2 : sublist { $$ = makelnode($1,SYNC); } X ; X Xlist : sublist SEPER list { $$ = makelnode($1,SYNC); $$->right = $3; } X | sublist AMPER list { $$ = makelnode($1,ASYNC); $$->right = $3; } X | sublist { $$ = makelnode($1,SYNC); } X ; X Xsublist : sublist2 X | sublist DBAR sublist X { $$ = $1; $$->right = $3; $$->type = ORNEXT; } X | sublist DAMPER sublist %prec DBAR X { $$ = $1; $$->right = $3; $$->type = ANDNEXT; } X ; X Xsublist2 : pline { $$ = makel2node($1,0); } X | COPROC pline { $$ = makel2node($2,PFLAG_COPROC); } X | BANG pline { $$ = makel2node($2,PFLAG_NOT); } X ; X Xpline : xcommand { $$ = makepnode($1,NULL,END); } X | xcommand BAR pline X { $$ = makepnode($1,$3,PIPE); } X | xcommand BARAMP pline X { struct redir *rdr = alloc(sizeof *rdr); X rdr->type = MERGE; rdr->fd1 = 2; rdr->fd2 = 1; X addnode($1->redir,rdr); $$ = makepnode($1,$3,PIPE); X } X ; X Xxcommand : redirstring command redirstring X { $$ = $2; X inslist($1,(Lknode) ($2->redir),$2->redir); X inslist($3,lastnode($2->redir),$2->redir); } X ; X Xstufflist : STRING stufflist X { $$ = $2; pushnode($$->args,$1); } X | ENVSTRING stufflist X { struct varasg *v = makevarnode(PMFLAG_s); X equalsplit(v->name = $1,&v->str); $$ = $2; X pushnode($$->vars,v); } X | ENVARRAY wordlist OUTPAR stufflist X { struct varasg *v = makevarnode(PMFLAG_A); X v->name = $1; v->arr = $2; $$ = $4; X pushnode($$->vars,v); } X | redir stufflist { $$ = $2; X if ($1->pair) pushnode($2->redir,$1->pair); X pushnode($2->redir,$1); X } X | INOUTPAR INBRACE list OUTBRACE X { $$ = makefuncdef(newlist(),$3); } X | %prec DOITNOW { $$ = makecnode(SIMPLE); } X ; X Xsimplecommand : COMMAND simplecommand X { $$ = $2; $$->flags |= CFLAG_COMMAND; } X | EXEC simplecommand X { $$ = $2; $$->flags |= CFLAG_EXEC; } X | NOGLOB simplecommand X { $$ = $2; $$->flags |= CFLAG_NOGLOB; } X | DASH simplecommand X { $$ = $2; $$->flags |= CFLAG_DASH; } X | stufflist { $$ = $1; X if (full($$->args)) X { X if (underscore) X free(underscore); X underscore = ztrdup(getdata(lastnode($$->args))); X untokenize(underscore); X } X } X ; X Xcommand : simplecommand { $$=$1; } X | FOR STRING optinword SEPER DO list DONE X { $$ = makefornode($2,$3,$6,CFOR); } X | FOR STRING optinword SEPER list2 X { $$ = makefornode($2,$3,$5,CFOR); } X | SELECT STRING optinword SEPER DO list DONE X { $$ = makefornode($2,$3,$6,CSELECT); } X | SELECT STRING optinword SEPER list2 X { $$ = makefornode($2,$3,$5,CSELECT); } X | CASE word STRING optbreak caselist ESAC X { $$ = makecnode(CCASE); $$->u.casecmd = $5; X addnode($$->args,$2); } X | IF list THEN list optelsifs FI X { $$ = makecnode(CIF); $$->u.ifcmd = makeifnode($2,$4,$5); } X | WHILE list DO list DONE X { $$ = makewhilenode($2,$4,0); } X | UNTIL list DO list DONE X { $$ = makewhilenode($2,$4,1); } X | REPEAT word SEPER DO list DONE X { $$ = makecnode(CREPEAT); $$->u.list = $5; X addnode($$->args,$2); } X | REPEAT word list2 X { $$ = makecnode(CREPEAT); $$->u.list = $3; X addnode($$->args,$2); } X | INPAR list OUTPAR X { $$ = makecnode(SUBSH); $$->u.list = $2; } X | INBRACE list OUTBRACE X { $$ = makecnode(CURSH); $$->u.list = $2; } X | FUNC wordlist INBRACE list OUTBRACE X { $$ = makefuncdef($2,$4); } X | TIME sublist2 X { $$ = makecnode(CTIME); $$->u.pline = $2; } X | DINBRACK cond DOUTBRACK X { $$ = makecnode(COND); $$->u.cond = $2; } X ; X Xcond : word word { $$ = makecond(); parcond2($1,$2,$$); } X | word word word { $$ = makecond(); parcond3($1,$2,$3,$$); } X | word INANG word X { $$ = makecond(); $$->left = $1; X $$->right = $3; $$->type = COND_STRLT; X $$->types[0] = $$->types[1] = NT_STR; } X | word OUTANG word X { $$ = makecond(); $$->left = $1; X $$->right = $3; $$->type = COND_STRGTR; X $$->types[0] = $$->types[1] = NT_STR; } X | INPAR cond OUTPAR { $$ = $2; } X | BANG cond { $$ = makecond(); $$->left = $2; $$->type = COND_NOT; } X | cond DAMPER cond X { $$ = makecond(); $$->left = $1; $$->right = $3; X $$->type = COND_AND; } X | cond DBAR cond X { $$ = makecond(); $$->left = $1; $$->right = $3; X $$->type = COND_OR; } X ; X Xredir : redirop word { $$ = parredir($1,$2); } X ; X Xredirstring : redir redirstring { $$ = $2; X pushnode($2,$1); X if ($1->pair) pushnode($2,$1->pair); } X | %prec DOITNOW { $$ = newlist(); } X ; X Xredirop : OUTANG { $$.fd1 = $1.fd1; $$.fd2 = WRITE; } X | OUTANGBANG { $$.fd1 = $1.fd1; $$.fd2 = WRITENOW; } X | DOUTANG { $$.fd1 = $1.fd1; $$.fd2 = APP; } X | DOUTANGBANG { $$.fd1 = $1.fd1; $$.fd2 = APPNOW; } X | INANG { $$.fd1 = $1.fd1; $$.fd2 = READ; } X | DINANG { $$.fd1 = $1.fd1; $$.fd2 = HEREDOC; } X | INANGAMP { $$.fd1 = $1.fd1; $$.fd2 = MERGE; } X | OUTANGAMP { $$.fd1 = $1.fd1; $$.fd2 = MERGEOUT; } X | OUTANGAMPBANG { $$.fd1 = $1.fd1; $$.fd2 = MERGEOUTNOW; } X | DOUTANGAMP { $$.fd1 = $1.fd1; $$.fd2 = ERRAPP; } X | DOUTANGAMPBANG { $$.fd1 = $1.fd1; $$.fd2 = ERRAPPNOW; } X | TRINANG { $$.fd1 = $1.fd1; $$.fd2 = HERESTR; } X ; X Xoptinword : { $$ = NULL; } X | word wordlist { $$ = $2; pushnode($2,$1); } X ; X Xoptelsifs : { $$ = NULL; } X | ELSE list { $$ = makeifnode(NULL,$2,NULL); } X | ELIF list THEN list optelsifs X { $$ = makeifnode($2,$4,$5); $$->ifl = $2; } X ; X Xcaselist : word OUTPAR list DSEMI optbreak caselist X { $$ = makecasenode($1,$3,$6); } X | word OUTPAR list optbreak X { $$ = makecasenode($1,$3,NULL); } X | { $$ = NULL; } X ; X Xword : STRING X | ENVSTRING X ; X Xoptbreak : X | SEPER X ; X Xwordlist : word wordlist { $$ = $2; pushnode($2,$1); } X | { $$ = newlist(); } X ; X%% X X/* get fd associated with str */ X Xint getfdstr(s) /**/ Xchar *s; X{ X if (s[1]) X return -1; X if (idigit(*s)) X return *s-'0'; X if (*s == 'p') X return -2; X return -1; X} X Xstruct redir *parredir(fdp,toks) /**/ Xstruct fdpair fdp;char *toks; X{ Xstruct redir *fn = allocnode(N_REDIR); Xint mrg2 = 0; X X fn->type = fdp.fd2; X if (fdp.fd1 != -1) X fn->fd1 = fdp.fd1; X else X if (fn->type < READ) X fn->fd1 = 1; X else X fn->fd1 = 0; X if ((*toks == Inang || *toks == Outang) && toks[1] == Inpar) X { X if (fn->type == WRITE) X fn->type = OUTPIPE; X else if (fn->type == READ) X fn->type = INPIPE; X else X { X zerr("parse error: bad process redirection",NULL,0); X return fn; X } X fn->name = toks; X } X else if (fn->type == HEREDOC) X { X fn->name = gethere(toks); X fn->type = HERESTR; X } X else if (fn->type >= MERGEOUT && fn->type <= ERRAPPNOW && X getfdstr(toks) == -1) X { X mrg2 = 1; X fn->name = toks; X fn->type = fn->type-MERGEOUT+WRITE; X } X else if (fn->type == ERRAPP || fn->type == ERRAPPNOW) X { X zerr("parse error: filename expected",NULL,0); X return fn; X } X else if (fn->type == MERGEOUT) X { X struct redir *fe = allocnode(N_REDIR); X X fn->type = CLOSE; X fn->pair = fe; X fe->fd1 = fn->fd1; X fe->fd2 = getfdstr(toks); X if (fe->fd2 == -2) X fe->fd2 = coprocout; X fe->type = MERGEOUT; X } X else if (fn->type == MERGE || fn->type == MERGEOUT) X { X if (*toks == '-') X fn->type = CLOSE; X else X { X fn->fd2 = getfdstr(toks); X if (fn->fd2 == -2) X fn->fd2 = (fn->type == MERGEOUT) ? coprocout : coprocin; X } X } X else X fn->name = toks; X if (mrg2) X { X struct redir *fe = allocnode(N_REDIR); X X fe->fd1 = 2; X fe->fd2 = fn->fd1; X fe->type = MERGEOUT; X fn->pair = fe; X } X return fn; X} X Xstruct list *parev() /**/ X{ X yyparse(); X return tree; X} X Xstruct list *parlist() /**/ X{ Xstruct list *l,*lp; X X eofseen = 0; X do X lp = l = parev(); X while (!lp && !errflag && inbufct); X while (!eofseen && inbufct && !errflag) X { X lsep = 0; X if (lp->right = parev()) X lp = lp->right; X } X return (errflag)? NULL : l; X} X Xstruct list *makelnode(x,type) /**/ Xstruct sublist *x;int type; X{ Xstruct list *n = allocnode(N_LIST); X X n->left = x; X n->type = type; X return n; X} X Xstruct sublist *makel2node(p,type) /**/ Xstruct pline *p;int type; X{ Xstruct sublist *n = allocnode(N_SUBLIST); X X n->left = p; X n->flags = type; X return n; X} X Xstruct pline *makepnode(c,p,type) /**/ Xstruct cmd *c;struct pline *p;int type; X{ Xstruct pline *n = allocnode(N_PLINE); X X n->left = c; X n->right = p; X n->type = type; X return n; X} X Xstruct cmd *makefornode(str,t,l,type) /**/ Xchar *str;Lklist t;struct list *l;int type; X{ Xstruct cmd *c = makecnode(type); Xstruct forcmd *f = allocnode(N_FOR); Xchar *s; X X if (t) X { X c->args = t; X s = ugetnode(t); X if (strcmp(s,"in")) X { X errflag = 1; X yyerror(); X } X } X c->u.forcmd = f; X f->name = str; X f->list = l; X f->inflag = !!t; X return c; X} X Xstruct ifcmd *makeifnode(l1,l2,i2) /**/ Xstruct list *l1;struct list *l2; struct ifcmd *i2; X{ Xstruct ifcmd *i1 = allocnode(N_IF); X X i1->next = i2; X i1->ifl = l1; X i1->thenl = l2; X return i1; X} X Xstruct cmd *makewhilenode(l1,l2,sense) /**/ Xstruct list *l1;struct list *l2; int sense; X{ Xstruct cmd *c = makecnode(CWHILE); Xstruct whilecmd *w = allocnode(N_WHILE); X X c->u.whilecmd = w; X w->cont = l1; X w->loop = l2; X w->cond = sense; X return c; X} X Xstruct cmd *makecnode(type) /**/ Xint type; X{ Xstruct cmd *c = allocnode(N_CMD); X X c->args = newlist(); X c->redir = newlist(); X c->vars = newlist(); X c->type = type; X return c; X} X Xstruct cmd *makefuncdef(x,l) /**/ XLklist x;struct list *l; X{ Xstruct cmd *c = makecnode(FUNCDEF); X X c->args = x; X c->u.list = l; X return c; X} X Xstruct cond *makecond() /**/ X{ Xstruct cond *cn = allocnode(N_COND); X X return cn; X} X Xstruct varasg *makevarnode(type) /**/ Xint type; X{ Xstruct varasg *v = allocnode(N_VARASG); X X v->type = type; X return v; X} X Xstruct casecmd *makecasenode(str,l,c) /**/ Xchar *str;struct list *l;struct casecmd *c; X{ Xstruct casecmd *n = allocnode(N_CASE); X X n->next = c; X n->pat = str; X n->list = l; X return n; X} X Xvoid parcond2(a,b,n) /**/ Xchar *a;char *b;struct cond *n; X{ X if (a[0] != '-' || !a[1] || a[2]) X { X zerr("parse error: condition expected: %s",a,0); X return; X } X n->left = b; X n->type = a[1]; X n->types[0] = n->types[1] = NT_STR; X} X Xvoid parcond3(a,b,c,n) /**/ Xchar *a;char *b;char *c;struct cond *n; X{ Xstatic char *condstrs[] = { X "nt","ot","ef","eq","ne","lt","gt","le","ge",NULL X }; Xint t0; X X if (b[0] == Equals && !b[1]) X n->type = COND_STREQ; X else if (b[0] == '!' && b[1] == Equals && !b[2]) X n->type = COND_STRNEQ; X else if (b[0] == '-') X { X for (t0 = 0; condstrs[t0]; t0++) X if (!strcmp(condstrs[t0],b+1)) X break; X if (condstrs[t0]) X n->type = t0+COND_NT; X else X zerr("unrecognized condition: %s",b,0); X } X else X zerr("condition expected: %s",b,0); X n->left = a; X n->right = c; X n->types[0] = n->types[1] = NT_STR; X} X Xyyerror() /* NO PROTO */ X{ Xint t0; X X for (t0 = 0; t0 != 20; t0++) X if (!yytext[t0] || yytext[t0] == '\n' || yytext[t0] == HISTSPACE) X break; X if (t0 == 20) X zerr("parse error near `%l...'",yytext,20); X else if (t0) X zerr("parse error near `%l'",yytext,t0); X else X zerr("parse error",NULL,0); X} X SHAR_EOF echo 'File zsh2.00/src/parse.y is complete' && chmod 0644 zsh2.00/src/parse.y || echo 'restore of zsh2.00/src/parse.y failed' Wc_c="`wc -c < 'zsh2.00/src/parse.y'`" test 13927 -eq "$Wc_c" || echo 'zsh2.00/src/parse.y: original size 13927, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/subst.c ============== if test -f 'zsh2.00/src/subst.c' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/subst.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/subst.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/subst.c' && X/* X X subst.c - various substitutions 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 <pwd.h> X X/* do substitutions before fork */ X Xvoid prefork(list) /**/ XLklist list; X{ XLknode node = firstnode(list); Xint qt; X X while (node) X { X char *str,*str3; X X str = str3 = getdata(node); X if (str[1] == Inpar && (*str == Inang || X *str == Outang || *str == Equals)) X { X if (*str == Inang) X setdata(node,getoutproc(str+2)); /* <(...) */ X else if (*str == Equals) X setdata(node,getoutputfile(str+2)); /* =(...) */ X else X setdata(node,getinproc(str+2)); /* >(...) */ X if (!getdata(node)) X { X zerr("parse error in process substitution",NULL,0); X return; X } X } X else while (*str) X { X if ((qt = *str == Qstring) || *str == String) X if (str[1] != Inpar) X if (str[1] == Inbrack) X { X arithsubst((void **) &str,&str3); /* $[...] */ X setdata(node,str3); X } X else X { X paramsubst(list,node,str,str3,qt); X if (errflag) X return; X str3 = str = getdata(node); X continue; X } X str++; X if (errflag) X return; X } X if (*(char *) getdata(node)) X remnulargs(getdata(node)); X if (unset(IGNOREBRACES)) X while (hasbraces(getdata(node))) X xpandbraces(list,&node); X filesub((char **) getaddrdata(node)); X if (errflag) X return; X incnode(node); X } X} X Xvoid postfork(list,doglob) /**/ XLklist list;int doglob; X{ XLknode node = firstnode(list); Xint glb = 1; X X if (isset(NOGLOBOPT) || !doglob) X glb = 0; X while (node) X { X char *str3,*str; X X str = str3 = getdata(node); X while (*str) X { X if (((*str == String || *str == Qstring) && str[1] == Inpar) || X *str == Tick || *str == Qtick) X { X Lknode n = prevnode(node); X X commsubst(list,node,str,str3, X (*str == Qstring || *str == Qtick)); /* `...`,$(...) */ X if (errflag) X return; X str = str3 = getdata(node = nextnode(n)); X } X str++; X } X if (glb) X { X if (haswilds(getdata(node))) X glob(list,&node); X if (errflag) X return; X } X incnode(node); X } X} X X/* perform substitution on a single word */ X Xvoid singsub(s) /**/ Xchar **s; X{ XLklist foo; Xchar *t; X X for (t = *s; *t; t++) X if (*t == String) X *t = Qstring; X else if (*t == Tick) X *t = Qtick; X foo = newlist(); X addnode(foo,*s); X prefork(foo); X if (errflag) X return; X postfork(foo,0); X if (errflag) X return; X *s = ugetnode(foo); X if (firstnode(foo)) X zerr("ambiguous: %s",*s,0); X} X X/* strdup, but returns "Nularg" if this is a null string */ X Xvoid *nstrdup(s) /**/ Xvoid *s; X{ Xchar *t = s; Xchar u[2]; X X u[0] = Nularg; u[1] = '\0'; X if (!*t) X return strdup(u); X return strdup(t); X} X Xchar *dynread(stop) /**/ Xint stop; X{ Xint bsiz = 256,ct = 0,c; Xchar *buf = zalloc(bsiz),*ptr; X X ptr = buf; X while ((c = hgetc()) != stop) X { X *ptr++ = c; X if (++ct == bsiz) X { X buf = realloc(buf,bsiz *= 2); X ptr = buf+ct; X } X } X *ptr = 0; X return buf; X} X Xint filesub(namptr) /**/ Xchar **namptr; X{ Xchar *str = *namptr,*cnam; X X if (*str == Tilde && str[1] != '=') X { X if (str[1] == '+') X { X char *foo = strdup(cwd); /* ~+ */ X X str+=2; X modify(&foo,&str); X *namptr = dyncat(cwd,str); X return 1; X } X else if (str[1] == '-') /* ~- */ X { X char *foo; X X if (cnam = oldpwd) X foo = cnam; X else X foo = cwd; X str += 2; X foo = strdup(foo); X modify(&foo,&str); X *namptr = dyncat(foo,str); X return 1; X } X if (ialpha(str[1])) /* ~foo */ X { X char *ptr,*hom; X X for (ptr = ++str; *ptr && iuser(*ptr); ptr++) X if (*ptr == '-') X *ptr = '-'; X if (!(hom = gethome(str,ptr-str))) X { X zerr("user not found: %l",str,ptr-str); X errflag = 1; X return 0; X } X modify(&hom,&ptr); X *namptr = dyncat(hom,ptr); X return 1; X } X else if (str[1] == '/') /* ~/foo */ X { X *namptr = dyncat(home,str+1); X return 1; X } X else if (!str[1]) /* ~ by itself */ X { X *namptr = strdup(home); X return 1; X } X } X if (*str == Equals && iuser(str[1])) X { X char *ptr,*s,*ds; X int val; X X untokenize(str); X if (ialpha(str[1])) /* =foo */ X { X struct cmdnam *chn; X struct alias *t; X char sav,*pp; X X for (pp = str+1; *pp && *pp != ':'; pp++); X sav = *pp; X *pp = '\0'; X if ((t = gethnode(str+1,aliastab)) && t->cmd) X if (t->cmd >= 0) X cnam = strdup(t->text); X else X { X zerr("%s: shell reserved word",str+1,0); X errflag = 1; X return 0; X } X else if (chn = gethnode(str+1,cmdnamtab)) X if (chn->type != BUILTIN && chn->type != SHFUNC) X cnam = strdup(chn->u.nam); X else X { X zerr((chn->type == BUILTIN) ? X "shell built-in command: %s" : X "shell function: %s",str+1,0); X errflag = 1; X return 0; X } X else if (!(cnam = findcmd(str+1))) X { X zerr("%s not found",str+1,0); X errflag = 1; X return 0; X } X *namptr = cnam; X if ((*pp = sav) == ':') X { X modify(namptr,&pp); X s = *namptr; X *namptr = dyncat(*namptr,pp); X } X return 1; X } X if (str[1] == '-') /* =- */ X { X val = -1; X ptr = str+2; X } X else X val = strtol(str+1,&ptr,10); /* =# */ X ds = dstackent(val); X if (!ds) X return 1; X s = strdup(ds); X modify(&s,&ptr); X *namptr = dyncat(s,ptr); X return 1; X } X return 0; X} X X/* get a named directory */ X Xchar *gethome(user,len) /**/ Xchar *user;int len; X{ Xchar sav,*str; Xstruct passwd *pw; X X sav = user[len]; X user[len] = '\0'; X if (str = getsparamval(user,len)) X { X str = strdup(str); X adduserdir(user,str); X user[len] = sav; X return str; X } X if (!(pw = getpwnam(user))) X { X user[len] = sav; X return NULL; X } X str = xsymlink(pw->pw_dir); X adduserdir(user,str); X user[len] = sav; X return str; X} X X/* `...`, $(...) */ X Xvoid commsubst(l,n,str3,str,qt) /**/ XLklist l;Lknode n;char *str3;char *str;int qt; X{ Xchar *str2; XLknode where = prevnode(n); XLklist pl; X X if (*str3 == Tick || *str3 == Qtick) X { X *str3 = '\0'; X for (str2 = ++str3; *str3 != Tick && *str3 != Qtick; str3++); X *str3++ = '\0'; X } X else X { X *str3++ = '\0'; X for (str2 = ++str3; *str3 != Outpar; str3++); X *str3++ = '\0'; X } X uremnode(l,n); X if (!(pl = getoutput(str2,qt))) X { X zerr("parse error in command substitution",NULL,0); X errflag = 1; X return; X } X if (full(pl)) X { X setdata(firstnode(pl),dyncat(str,peekfirst(pl))); X setdata(lastnode(pl),dyncat(getdata(lastnode(pl)),str3)); X inslist(pl,where,l); X } X else X insnode(l,where,dyncat(str,str3)); X} X X/* parameter substitution */ X Xvoid paramsubst(l,n,aptr,bptr,qt) /**/ XLklist l;Lknode n;char *aptr;char *bptr;int qt; X{ Xchar *s = aptr,*u,*idbeg,*idend,*ostr = bptr; Xint brs; /* != 0 means ${...}, otherwise $... */ Xint colf; /* != 0 means we found a colon after the name */ Xint doub = 0; /* != 0 means we have %%, not %, or ##, not # */ Xint isarr = 0; Xint plan9 = isset(RCEXPANDPARAM); Xint getlen = 0; Xint vunset = 0; Xint spbreak = isset(SHWORDSPLIT) && !qt; Xchar *val = NULL,**aval = NULL; Xint fwidth = 0; XValue v; X X *s++ = '\0'; X if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' && X *s != '!' && *s != '$' && *s != String && *s != Qstring && X *s != '?' && *s != Quest && *s != '_' && X *s != '*' && *s != Star && *s != '@' && *s != '{' && X *s != Inbrace && *s != '=' && *s != Hat && *s != '^') X { X s[-1] = '$'; X return; X } X if (brs = (*s == '{' || *s == Inbrace)) X s++; X for (;;) X if (*s == '^' || *s == Hat) X plan9 ^= 1,s++; X else if (*s == '=') X spbreak ^= 1,s++; X else if ((*s == '#' || *s == Pound) && iident(s[1])) X getlen = 1,s++; X else X break; X X idbeg = s; X if (!(v = getvalue(&s,1))) X { X vunset = 1; X idend = s; X } X else X if (isarr = v->isarr) X aval = getarrvalue(v); X else X { X val = getstrvalue(v); X fwidth = v->pm->ct; X switch (v->pm->flags & (PMFLAG_L | PMFLAG_R | PMFLAG_Z)) X { X char *t; X int t0; X X case PMFLAG_L: X case PMFLAG_L|PMFLAG_Z: X t = val; X if (v->pm->flags & PMFLAG_Z) X while (*t == '0') t++; X else X while (isep(*t)) t++; X val = ncalloc(fwidth+1); X val[fwidth] = '\0'; X strcpy(val,t); X if ((t0 = strlen(t)) > fwidth) X t0 = fwidth; X memset(val,' ',fwidth); X strncpy(val,t,t0); X break; X case PMFLAG_R: X case PMFLAG_Z: X case PMFLAG_Z|PMFLAG_R: X if (strlen(val) < fwidth) X { X t = ncalloc(fwidth+1); X memset(t,(v->pm->flags & PMFLAG_R) ? ' ' : '0',fwidth); X if ((t0 = strlen(val)) > fwidth) X t0 = fwidth; X strcpy(t+(fwidth-t0),val); X val = t; X } X break; X } X switch (v->pm->flags & (PMFLAG_l | PMFLAG_u)) X { X char *t; X X case PMFLAG_l: X t = val; X for (;*t;t++) X *t = tolower(*t); X break; X case PMFLAG_u: X t = val; X for (;*t;t++) X *t = toupper(*t); X break; X } X } X if (colf = *s == ':') X s++; X X /* check for ${..?...} or ${..=..} or one of those. Only works X if the name is in braces. */ X X if (brs && (*s == '-' || *s == '=' || *s == '?' || *s == '+' || *s == '#' || X *s == '%' || *s == Quest || *s == Pound)) X { X if (v && v->isarr) X { X zerr("operator requires a scalar",NULL,0); X return; X } X if (*s == s[1]) X { X s++; X doub = 1; X } X u = ++s; X if (brs) X while (*s != '}' && *s != Outbrace) X s++; X else X { X while (*s++); X s--; X } X *s = '\0'; X if (colf && !vunset) X vunset = !*val; X switch (u[-1]) X { X case '-': X if (vunset) X val = strdup(u); X break; X case '=': X if (vunset) X { X char sav = *idend; X X *idend = '\0'; X setsparam(idbeg,ztrdup(val = strdup(u))); X *idend = sav; X } X break; X case '?': X case Quest: X if (vunset) X { X zerr("%s",(*u) ? u : "parameter not set",0); X if (!interact) X exit(1); X return; X } X break; X case '+': X if (vunset) X val = strdup(""); X else X val = strdup(u); X break; X case '#': X case Pound: X if (vunset) X val = strdup(""); X getmatch(&val,u,doub); X break; X case '%': X if (vunset) X val = strdup(""); X getmatch(&val,u,doub+2); X break; X } X } X else /* no ${...=...} or anything, but possible modifiers. */ X { X if (vunset) X { X if (isset(NOUNSET)) X { X zerr("parameter not set",NULL,0); X return; X } X val = strdup(""); X } X if (colf) X { X s--; X if (!isarr) X modify(&val,&s); X /*else X modifyarr(&aval,&s);*/ X } X if (brs) X { X if (*s != '}' && *s != Outbrace) X { X zerr("closing brace expected",NULL,0); X errflag = 1; X return; X } X s++; X } X } X if (errflag) X return; X if (getlen) X { X long len = 0; X char buf[14]; X X if (isarr) X { X char **ctr; X for (ctr = aval; *ctr; ctr++,len++); X } X else X len = strlen(val); X sprintf(buf,"%ld",len); X val = strdup(buf); X isarr = 0; X } X if (isarr && !plan9) X if (!aval || !aval[0]) X { X val = strdup(""); X isarr = 0; X } X else if (!aval[1]) X { X val = aval[0]; X isarr = 0; X } X if (qt) X if (isarr) X { X val = spacejoin(aval); X isarr = 0; X } X else if (spbreak) X { X if (isarr) X val = spacejoin(aval); X isarr = 1; X aval = spacesplit(s); X } X if (isarr) X if (plan9) X { X int dlen; X char *y; X X y = ncalloc((dlen = (char *) aptr-bptr+strlen(s)+1)+strlen(aval[0])); X setdata(n,y); X strcpy(y,ostr); X strcat(y,aval[0]); X strcat(y,s); X while (*++aval) X { X char *x = ncalloc(dlen+strlen(*aval)); X X strcpy(x,ostr); X strcat(x,*aval); X strcat(x,s); X insnode(l,n,x), incnode(n); X } X } X else X { X char *zz; X X zz = ncalloc((char *) aptr-(bptr)+strlen(aval[0])+1); X setdata(n,zz); X strcpy(zz,ostr); X strcat(zz,*aval++); X while (aval[1]) X insnode(l,n,*aval++), incnode(n); X zz = ncalloc(strlen(*aval)+strlen(s)+1); X strcpy(zz,*aval); X strcat(zz,s); X insnode(l,n,zz); X } X else X { X bptr = ncalloc((char *) aptr-bptr+strlen(val)+strlen(s)+1); X setdata(n,bptr); X strcpy(bptr,ostr); X strcat(bptr,val); X strcat(bptr,s); X } X} X X/* arithmetic substitution */ X Xvoid arithsubst(aptr,bptr) /**/ Xvoid **aptr;char **bptr; X{ Xchar *s = *aptr,*t,buf[16]; Xlong v; X X *s = '\0'; X for (; *s != Outbrack; s++); X *s++ = '\0'; X v = matheval((char *) *aptr+2); X sprintf(buf,"%ld",v); X t = ncalloc(strlen(*bptr)+strlen(buf)+strlen(s)+1); X strcpy(t,*bptr); X strcat(t,buf); X strcat(t,s); X *bptr = t; X} X Xvoid modify(str,ptr) /**/ Xchar **str;char **ptr; X{ Xchar *ptr1,*ptr2,*ptr3,del,*lptr; Xint gbal; X X if (**ptr == ':') X *str = strdup(*str); X while (**ptr == ':') X { X lptr = *ptr; X (*ptr)++; X gbal = 0; Xhere: X switch(*(*ptr)++) X { X case 'h': remtpath(str); break; X case 'r': remtext(str); break; X case 'e': rembutext(str); break; X case 't': remlpaths(str); break; X case 'l': downcase(str); break; X case 'u': upcase(str); break; X case 's': X if (hsubl) X free(hsubl); X if (hsubr) X free(hsubr); X ptr1 = *ptr; X del = *ptr1++; X for (ptr2 = ptr1; *ptr2 != del && *ptr2; ptr2++); X if (!*ptr2) X { X zerr("bad subtitution",NULL,0); X errflag = 1; X return; X } X *ptr2++ = '\0'; X for (ptr3 = ptr2; *ptr3 != del && *ptr3; ptr3++); X if (*ptr3) X *ptr3++ = '\0'; X hsubl = ztrdup(ptr1); X hsubr = ztrdup(ptr2); X *ptr = ptr3; X case '&': X if (hsubl && hsubr) X subst(str,hsubl,hsubr,gbal); X break; X case 'g': gbal = 1; goto here; X default: *ptr = lptr; return; X } X } X} X X/* get a directory stack entry */ X Xchar *dstackent(val) /**/ Xint val; X{ XLknode node; X X if ((val < 0 && !firstnode(dirstack)) || !val--) X return cwd; X if (val < 0) X node = lastnode(dirstack); X else X for (node = firstnode(dirstack); node && val; val--,incnode(node)); X if (!node) X { X zerr("not enough dir stack entries.",NULL,0); X errflag = 1; X return NULL; X } X return getdata(node); X} X X/* make an alias hash table node */ X Xstruct alias *mkanode(txt,cmflag) /**/ Xchar *txt;int cmflag; X{ Xstruct alias *ptr = (void *) zcalloc(sizeof *ptr); X X ptr->text = txt; X ptr->cmd = cmflag; X ptr->inuse = 0; X return ptr; X} SHAR_EOF chmod 0644 zsh2.00/src/subst.c || echo 'restore of zsh2.00/src/subst.c failed' Wc_c="`wc -c < 'zsh2.00/src/subst.c'`" test 14939 -eq "$Wc_c" || echo 'zsh2.00/src/subst.c: original size 14939, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/subst.pro ============== if test -f 'zsh2.00/src/subst.pro' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/subst.pro (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/subst.pro (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/subst.pro' && Xvoid prefork DCLPROTO((Lklist list)); Xvoid postfork DCLPROTO((Lklist list,int doglob)); Xvoid singsub DCLPROTO((char **s)); Xvoid *nstrdup DCLPROTO((void *s)); Xchar *dynread DCLPROTO((int stop)); Xint filesub DCLPROTO((char **namptr)); Xchar *gethome DCLPROTO((char *user,int len)); Xvoid commsubst DCLPROTO((Lklist l,Lknode n,char *str3,char *str,int qt)); Xvoid paramsubst DCLPROTO((Lklist l,Lknode n,char *aptr,char *bptr,int qt)); Xvoid arithsubst DCLPROTO((void **aptr,char **bptr)); Xvoid modify DCLPROTO((char **str,char **ptr)); Xchar *dstackent DCLPROTO((int val)); Xstruct alias *mkanode DCLPROTO((char *txt,int cmflag)); SHAR_EOF chmod 0644 zsh2.00/src/subst.pro || echo 'restore of zsh2.00/src/subst.pro failed' Wc_c="`wc -c < 'zsh2.00/src/subst.pro'`" test 622 -eq "$Wc_c" || echo 'zsh2.00/src/subst.pro: original size 622, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/table.c ============== if test -f 'zsh2.00/src/table.c' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/table.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/table.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/table.c' && X/* X X table.c - linked lists and hash tables 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#define TABLE_C X#include "zsh.h" X#include "funcs.h" X X/* get an empty linked list header */ X XLklist newlist() /**/ X{ XLklist list; X X list = alloc(sizeof *list); X list->first = 0; X list->last = (Lknode) list; X return list; X} X X/* get an empty hash table */ X XHashtab newhtable(size) /**/ Xint size; X{ XHashtab ret; X X ret = zcalloc(sizeof *ret); X ret->hsize = size; X ret->nodes = zcalloc(size*sizeof(Hashnode)); X return ret; X} X X/* Peter Weinberger's hash function */ X Xint hasher(s) /**/ Xchar *s; X{ Xunsigned hash = 0,g; X X for (; *s; s++) X { X hash = (hash << 4) + *s; X if (g = hash & 0xf0000000) X { X hash ^= g; X hash ^= g >> 24; X } X } X return hash; X} X X/* add a node to a hash table */ X Xvoid Addhnode(nam,dat,ht,freefunc,canfree) /**/ Xchar *nam;void *dat;Hashtab ht;FFunc freefunc;int canfree; X{ Xint hval = hasher(nam) % ht->hsize; Xstruct hashnode *hp = ht->nodes[hval],*hn; X X for (; hp; hp = hp->next) X if (!strcmp(hp->nam,nam)) X { X if (!freefunc) X zerr("attempt to call NULL freefunc",NULL,0); X else X freefunc(hp->dat); X hp->dat = dat; X if (hp->canfree) X { X free(hp->nam); X hp->nam = nam; X } X hp->canfree = canfree; X return; X } X hn = (void *) zcalloc(sizeof *hn); X hn->nam = nam; X hn->dat = dat; X hn->canfree = canfree; X hn->next = ht->nodes[hval]; X ht->nodes[hval] = hn; X if (++ht->ct == ht->hsize*4) X expandhtab(ht); X} X X/* expand hash tables when they get too many entries */ X Xvoid expandhtab(ht) /**/ XHashtab ht; X{ Xstruct hashnode *hp,**arr,**ha,*hn; Xint osize = ht->hsize,nsize = osize*8; X X ht->hsize = nsize; X arr = ht->nodes; X ht->nodes = zcalloc(nsize*sizeof(struct hashnode *)); X for (ha = arr; osize; osize--,ha++) X for (hn = *ha; hn; ) X { X Addhnode(hn->nam,hn->dat,ht,NULL,hn->canfree); X hp = hn->next; X free(hn); X hn = hp; X } X free(arr); X} X X/* get an entry in a hash table */ X Xvoid *gethnode(nam,ht) /**/ Xchar *nam;Hashtab ht; X{ Xint hval = hasher(nam) % ht->hsize; Xstruct hashnode *hn = ht->nodes[hval]; X X for (; hn; hn = hn->next) X if (!strcmp(hn->nam,nam)) X return hn->dat; X return NULL; X} X Xvoid freehtab(ht,freefunc) /**/ XHashtab ht;FFunc freefunc; X{ Xint val; Xstruct hashnode *hn,**hp = &ht->nodes[0],*next; X X for (val = ht->hsize; val; val--,hp++) X for (hn = *hp; hn; ) X { X next = hn->next; X freefunc(hn->dat); X free(hn); X hn = next; X } X} X X/* remove a hash table entry and return a pointer to it */ X Xvoid *remhnode(nam,ht) /**/ Xchar *nam;Hashtab ht; X{ Xint hval = hasher(nam) % ht->hsize; Xstruct hashnode *hn = ht->nodes[hval],*hp; Xvoid *dat; X X if (!hn) X return NULL; X if (!strcmp(hn->nam,nam)) X { X ht->nodes[hval] = hn->next; X dat = hn->dat; X if (hn->canfree) X free(hn->nam); X free(hn); X ht->ct--; X return dat; X } X for (hp = hn, hn = hn->next; hn; hn = (hp = hn)->next) X if (!strcmp(hn->nam,nam)) X { X hp->next = hn->next; X dat = hn->dat; X if (hn->canfree) X free(hn->nam); X free(hn); X ht->ct--; X return dat; X } X return NULL; X} X X/* insert a node in a linked list after 'llast' */ X Xvoid insnode(list,llast,dat) /**/ XLklist list;Lknode llast;void *dat; X{ XLknode tmp; X X tmp = llast->next; X llast->next = alloc(sizeof *tmp); X llast->next->last = llast; X llast->next->dat = dat; X llast->next->next = tmp; X if (tmp) X tmp->last = llast->next; X else X list->last = llast->next; X} X X/* remove a node from a linked list */ X Xvoid *remnode(list,nd) /**/ XLklist list;Lknode nd; X{ Xvoid *dat; X X nd->last->next = nd->next; X if (nd->next) X nd->next->last = nd->last; X else X list->last = nd->last; X free(nd); X dat = nd->dat; X return dat; X} X X/* remove a node from a linked list */ X Xvoid *uremnode(list,nd) /**/ XLklist list;Lknode nd; X{ Xvoid *dat; X X nd->last->next = nd->next; X if (nd->next) X nd->next->last = nd->last; X else X list->last = nd->last; X dat = nd->dat; X return dat; X} X X/* delete a character in a string */ X Xvoid chuck(str) /**/ Xchar *str; X{ X while (str[0] = str[1]) X str++; X} X X/* get top node in a linked list */ X Xvoid *getnode(list) /**/ XLklist list; X{ Xvoid *dat; XLknode node = list->first; X X if (!node) X return NULL; X dat = node->dat; X list->first = node->next; X if (node->next) X node->next->last = (Lknode) list; X else X list->last = (Lknode) list; X free(node); X return dat; X} X X/* get top node in a linked list without freeing */ X Xvoid *ugetnode(list) /**/ XLklist list; X{ Xvoid *dat; XLknode node = list->first; X X if (!node) X return NULL; X dat = node->dat; X list->first = node->next; X if (node->next) X node->next->last = (Lknode) list; X else X list->last = (Lknode) list; X return dat; X} X Xvoid freetable(tab,freefunc) /**/ XLklist tab;FFunc freefunc; X{ XLknode node = tab->first,next; X X while (node) X { X next = node->next; X if (freefunc) X freefunc(node->dat); X free(node); X node = next; X } X free(tab); X} X Xchar *strstr(s,t) /**/ Xchar *s;char *t; X{ Xchar *p1,*p2; X X for (; *s; s++) X { X for (p1 = s, p2 = t; *p2; p1++,p2++) X if (*p1 != *p2) X break; X if (!*p2) X return (char *) s; X } X return NULL; X} X X/* insert a list in another list */ X Xvoid inslist(l,where,x) /**/ XLklist l;Lknode where;Lklist x; X{ XLknode nx = where->next; X X if (!l->first) X return; X where->next = l->first; X l->last->next = nx; X l->first->last = where; X if (nx) X nx->last = l->last; X else X x->last = l->last; X} X Xint countnodes(x) /**/ XLklist x; X{ XLknode y; Xint ct = 0; X X for (y = firstnode(x); y; incnode(y),ct++); X return ct; X} X SHAR_EOF chmod 0644 zsh2.00/src/table.c || echo 'restore of zsh2.00/src/table.c failed' Wc_c="`wc -c < 'zsh2.00/src/table.c'`" test 6472 -eq "$Wc_c" || echo 'zsh2.00/src/table.c: original size 6472, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/table.pro ============== if test -f 'zsh2.00/src/table.pro' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/table.pro (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/table.pro (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/table.pro' && XLklist newlist DCLPROTO((void)); XHashtab newhtable DCLPROTO((int size)); Xint hasher DCLPROTO((char *s)); Xvoid Addhnode DCLPROTO((char *nam,void *dat,Hashtab ht,FFunc freefunc,int canfree)); Xvoid expandhtab DCLPROTO((Hashtab ht)); Xvoid *gethnode DCLPROTO((char *nam,Hashtab ht)); Xvoid freehtab DCLPROTO((Hashtab ht,FFunc freefunc)); Xvoid *remhnode DCLPROTO((char *nam,Hashtab ht)); Xvoid insnode DCLPROTO((Lklist list,Lknode llast,void *dat)); Xvoid *remnode DCLPROTO((Lklist list,Lknode nd)); Xvoid *uremnode DCLPROTO((Lklist list,Lknode nd)); Xvoid chuck DCLPROTO((char *str)); Xvoid *getnode DCLPROTO((Lklist list)); Xvoid *ugetnode DCLPROTO((Lklist list)); Xvoid freetable DCLPROTO((Lklist tab,FFunc freefunc)); Xchar *strstr DCLPROTO((char *s,char *t)); Xvoid inslist DCLPROTO((Lklist l,Lknode where,Lklist x)); Xint countnodes DCLPROTO((Lklist x)); SHAR_EOF chmod 0644 zsh2.00/src/table.pro || echo 'restore of zsh2.00/src/table.pro failed' Wc_c="`wc -c < 'zsh2.00/src/table.pro'`" test 844 -eq "$Wc_c" || echo 'zsh2.00/src/table.pro: original size 844, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= zsh2.00/src/text.c ============== if test -f 'zsh2.00/src/text.c' -a X"$1" != X"-c"; then echo 'x - skipping zsh2.00/src/text.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting zsh2.00/src/text.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/text.c' && X/* X X text.c - textual representations of syntax trees 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 Xstatic char *tptr,*tbuf,*tlim; Xstatic int tsiz,tindent,tnewlins; X X/* add a character to the text buffer */ X Xvoid taddchr(c) /**/ Xint c; X{ X *tptr++ = c; X if (tptr == tlim) X { X tbuf = realloc(tbuf,tsiz *= 2); X tlim = tbuf+tsiz; X tptr = tbuf+tsiz/2; X } X} X X/* add a string to the text buffer */ X Xvoid taddstr(s) /**/ Xchar *s; X{ Xint sl = strlen(s); X X while (tptr+sl >= tlim) X { X int x = tptr-tbuf; X X tbuf = realloc(tbuf,tsiz *= 2); X tlim = tbuf+tsiz; X tptr = tbuf+x; X } X strcpy(tptr,s); X tptr += sl; X} X X/* add an integer to the text buffer */ X Xvoid taddint(x) /**/ Xint x; X{ Xchar buf[10]; X X sprintf(buf,"%d",x); X taddstr(buf); X} X X/* add a newline, or something equivalent, to the text buffer */ X Xvoid taddnl() /**/ X{ Xint t0; X X if (tnewlins) X { X taddchr('\n'); X for (t0 = 0; t0 != tindent; t0++) X taddchr('\t'); X } X else X taddstr("; "); X} X X/* get a textual representation of n */ X Xchar *gettext(n,nls) /**/ Xstruct node *n;int nls; X{ X tnewlins = nls; X tbuf = zalloc(tsiz = 32); X tptr = tbuf; X tlim = tbuf+tsiz; X tindent = 1; X gettext2(n); X *tptr = '\0'; X untokenize(tbuf); X return tbuf; X} X X#define gt2(X) gettext2((struct node *) (X)) X X/* X "gettext2" or "type checking and how to avoid it" X an epic function by Paul Falstad X*/ X X#define _Cond(X) ((Cond) (X)) X#define _Cmd(X) ((Cmd) (X)) X#define _Pline(X) ((Pline) (X)) X#define _Sublist(X) ((Sublist) (X)) X#define _List(X) ((List) (X)) X#define _casecmd(X) ((struct casecmd *) (X)) X#define _ifcmd(X) ((struct ifcmd *) (X)) X#define _whilecmd(X) ((struct whilecmd *) (X)) X Xvoid gettext2(n) /**/ Xstruct node *n; X{ XCmd nn; XCond nm; X X if (!n) X return; X switch (n->type) X { X case N_LIST: X gt2(_List(n)->left); X if (_List(n)->type == ASYNC) X taddstr(" &"); X simplifyright(_List(n)); X if (_List(n)->right) X { X if (tnewlins) X taddnl(); X else X taddstr((_List(n)->type == ASYNC) ? " " : "; "); X gt2(_List(n)->right); X } X break; X case N_SUBLIST: X if (_Sublist(n)->flags & PFLAG_NOT) X taddstr("! "); X if (_Sublist(n)->flags & PFLAG_COPROC) X taddstr("coproc "); X gt2(_Sublist(n)->left); X if (_Sublist(n)->right) X { X taddstr((_Sublist(n)->type == ORNEXT) ? " || " : " && "); X gt2(_Sublist(n)->right); X } X break; X case N_PLINE: X gt2(_Pline(n)->left); X if (_Pline(n)->type == PIPE) X { X taddstr(" | "); X gt2(_Pline(n)->right); X } X break; X case N_CMD: X nn = _Cmd(n); X if (nn->flags & CFLAG_EXEC) X taddstr("exec "); X if (nn->flags & CFLAG_COMMAND) X taddstr("command "); X switch (nn->type) X { X case SIMPLE: X getsimptext(nn); X break; X case SUBSH: X taddstr("( "); X tindent++; X gt2(nn->u.list); X tindent--; X taddstr(" )"); X break; X case CTIME: X taddstr("time "); X tindent++; X gt2(nn->u.pline); X tindent--; X break; X case FUNCDEF: X taddlist(nn->args); X taddstr(" () {"); X tindent++; X taddnl(); X gt2(nn->u.list); X tindent--; X taddnl(); X taddstr("}"); X break; X case CURSH: X taddstr("{ "); X tindent++; X gt2(nn->u.list); X tindent--; X taddstr(" }"); X break; X case CFOR: X case CSELECT: X taddstr((nn->type == CFOR) ? "for " : "select "); X taddstr(nn->u.forcmd->name); X if (nn->u.forcmd->inflag) X { X taddstr(" in "); X taddlist(nn->args); X } X taddnl(); X taddstr("do"); X tindent++; X taddnl(); X gt2(nn->u.forcmd->list); X taddnl(); X tindent--; X taddstr("done"); X break; X case CIF: X gt2(nn->u.ifcmd); X taddstr("fi"); X break; X case CCASE: X taddstr("case "); X taddlist(nn->args); X taddstr(" in"); X tindent++; X taddnl(); X gt2(nn->u.casecmd); X tindent--; X if (tnewlins) X taddnl(); X else X taddchr(' '); X taddstr("esac"); X break; X case COND: X taddstr("[[ "); X gt2(nn->u.cond); X taddstr(" ]]"); X break; X case CREPEAT: X taddstr("repeat "); X taddlist(nn->args); X taddnl(); X taddstr("do"); X tindent++; X taddnl(); X gt2(nn->u.list); X tindent--; X taddnl(); X taddstr("done"); X break; X case CWHILE: X gt2(nn->u.whilecmd); X break; X } X getredirs(nn); X break; X case N_COND: X nm = _Cond(n); X switch (nm->type) X { X case COND_NOT: X taddstr("! "); X gt2(nm->left); X break; X case COND_AND: X taddstr("( "); X gt2(nm->left); X taddstr(" && "); X gt2(nm->right); X taddstr(" )"); X break; X case COND_OR: X taddstr("( "); X gt2(nm->left); X taddstr(" || "); X gt2(nm->right); X taddstr(" )"); X break; X default: X { X static char *c1[] = { X " = "," != "," < "," > "," -nt "," -ot "," -ef "," -eq ", X " -ne "," -lt "," -gt "," -le "," -ge " X }; X if (nm->right) X taddstr(nm->left); X if (nm->type <= COND_GE) X taddstr(c1[nm->type]); X else X { X char c2[5]; X c2[0] = ' '; c2[1] = '-'; X c2[2] = nm->type; X c2[3] = ' '; c2[4] = '\0'; X taddstr(c2); X } X taddstr((nm->right) ? nm->right : nm->left); X } X break; X } X break; X case N_CASE: X taddstr(_casecmd(n)->pat); X taddstr(") "); X tindent++; X gt2(_casecmd(n)->list); X tindent--; X gt2(_casecmd(n)->next); X break; X case N_IF: X if (_ifcmd(n)->ifl) X { X taddstr("if "); X tindent++; X gt2(_ifcmd(n)->ifl); X tindent--; X taddnl(); X taddstr("then"); X } X else X taddchr('e'); X tindent++; X taddnl(); X gt2(_ifcmd(n)->thenl); X tindent--; X taddnl(); X if (_ifcmd(n)->next) X { X taddstr("els"); X gt2(_ifcmd(n)->next); X } X break; X case N_WHILE: X taddstr((_whilecmd(n)->cond) ? "until " : "while "); X tindent++; X gt2(_whilecmd(n)->cont); X tindent--; X taddnl(); X taddstr("do"); X tindent++; X taddnl(); X gt2(_whilecmd(n)->loop); X tindent--; X taddnl(); X taddstr("done"); X break; X } X} X Xvoid getsimptext(cmd) /**/ XCmd cmd; X{ XLknode n; X X for (n = firstnode(cmd->vars); n; incnode(n)) X { X struct varasg *v = getdata(n); X X taddstr(v->name); X taddchr('='); X if ((v->type & PMTYPE) == PMFLAG_A) X { X taddchr('('); X taddlist(v->arr); X taddstr(") "); X } X else X { X taddstr(v->str); X taddchr(' '); X } X } X taddlist(cmd->args); X} X Xvoid getredirs(cmd) /**/ XCmd cmd; X{ XLknode n; Xstatic char *fstr[] = { X ">",">!",">>",">>!",">&",">&!",">>&",">>&!","<","<<","<&",">&",">&-", X ">&-","..","..","<<<" X }; X X taddchr(' '); X for (n = firstnode(cmd->redir); n; incnode(n)) X { X struct redir *f = getdata(n); X X switch(f->type) X { X case WRITE: case WRITENOW: case APP: case APPNOW: case READ: X case HERESTR: X if (f->fd1 != ((f->type == READ) ? 0 : 1)) X taddchr('0'+f->fd1); X taddstr(fstr[f->type]); X taddchr(' '); X taddstr(f->name); X taddchr(' '); X break; X case MERGE: case MERGEOUT: X if (f->fd1 != ((f->type == MERGEOUT) ? 1 : 0)) X taddchr('0'+f->fd1); X taddstr(fstr[f->type]); X taddchr(' '); X taddint(f->fd2); X taddchr(' '); X break; X case CLOSE: X taddchr(f->fd1+'0'); X taddstr(">&- "); X break; X case INPIPE: X case OUTPIPE: X if (f->fd1 != ((f->type == INPIPE) ? 0 : 1)) X taddchr('0'+f->fd1); SHAR_EOF true || echo 'restore of zsh2.00/src/text.c failed' fi echo 'End of zsh2.00.00 part 9' echo 'File zsh2.00/src/text.c is continued in part 10' echo 10 > _shar_seq_.tmp exit 0 -- Paul Falstad pfalstad@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@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@uunet.uu.net.