v18i092: zsh2.00 - The Z shell, Part09/15
Paul Falstad
pfalstad at phoenix.princeton.edu
Thu Apr 25 05:42:40 AEST 1991
Submitted-by: Paul Falstad <pfalstad at 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 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