v18i089: zsh2.00 - The Z shell, Part06/15
Paul Falstad
pfalstad at phoenix.princeton.edu
Wed Apr 24 13:04:08 AEST 1991
Submitted-by: Paul Falstad <pfalstad at phoenix.princeton.edu>
Posting-number: Volume 18, Issue 89
Archive-name: zsh2.00/part06
#!/bin/sh
# this is zsh2.00.00.shar.06 (part 6 of zsh2.00.00)
# do not concatenate these parts, unpack them in order with /bin/sh
# file zsh2.00/src/glob.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 6; 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/glob.c'
else
echo 'x - continuing file zsh2.00/src/glob.c'
sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.00/src/glob.c' &&
X
X for (; *c == *d && *c; c++,d++);
X return ((int) (unsigned char) *c-(int) (unsigned char) *d);
X}
X
Xint forstrcmp(a,b) /**/
Xchar **a;char **b;
X{
Xchar *c = *b,*d = *a;
X
X for (; *c == *d && *c; c++,d++);
X return ((int) (unsigned char) *d-(int) (unsigned char) *c);
X}
X
X/* add a match to the list */
X
Xvoid insert(s) /**/
Xchar *s;
X{
Xstruct stat buf;
X
X if (isset(MARKDIRS) && !lstat(s,&buf) && S_ISDIR(buf.st_mode)) /* grrr */
X {
X char *t;
X int ll = strlen(s);
X
X t = zalloc(ll+2);
X strcpy(t,s);
X t[ll] = '/';
X t[ll+1] = '\0';
X free(s);
X s = t;
X }
X *matchptr++ = s;
X if (++matchct == matchsz)
X {
X matchbuf = (char **) realloc((char *) matchbuf,
X sizeof(char **)*(matchsz *= 2));
X matchptr = matchbuf+matchct;
X }
X}
X
X/* check to see if str is eligible for filename generation */
X
Xint haswilds(str) /**/
Xchar *str;
X{
X if (!str[1] && (*str == Inbrack || *str == Outbrack))
X return 0;
X if (str[0] == '%')
X return 0;
X for (; *str; str++)
X if (!strncmp(str,"..../",5))
X return 1;
X else if (*str == Pound || *str == Hat || *str == Star ||
X *str == Bar || *str == Inbrack || *str == Inang ||
X *str == Quest)
X return 1;
X return 0;
X}
X
X/* check to see if str is eligible for brace expansion */
X
Xint hasbraces(str) /**/
Xchar *str;
X{
Xint mb,bc,cmct1,cmct2;
Xchar *lbr = NULL;
X
X if (str[0] == Inbrace && str[1] == Outbrace)
X return 0;
X for (mb = bc = cmct1 = cmct2 = 0; *str; str++)
X {
X if (*str == Inbrace)
X {
X if (!bc)
X lbr = str;
X bc++;
X if (str[4] == Outbrace && str[2] == '-') /* {a-z} */
X {
X cmct1++;
X if (bc == 1)
X cmct2++;
X }
X }
X else if (*str == Outbrace)
X {
X bc--;
X if (!bc && !cmct2)
X {
X *lbr = '{';
X *str = '}';
X }
X cmct2 = 0;
X }
X else if (*str == Comma && bc)
X {
X cmct1++;
X if (bc == 1)
X cmct2++;
X }
X if (bc > mb)
X mb = bc;
X if (bc < 0)
X return 0;
X }
X return (mb && bc == 0 && cmct1);
X}
X
X/* expand stuff like >>*.c */
X
Xint xpandredir(fn,tab) /**/
Xstruct redir *fn;Lklist tab;
X{
XLklist fake;
Xchar *nam;
Xstruct redir *ff;
Xint ret = 0;
X
X fake = newlist();
X addnode(fake,fn->name);
X prefork(fake);
X if (!errflag)
X postfork(fake,1);
X if (errflag)
X return 0;
X if (full(fake) && !nextnode(firstnode(fake)))
X {
X fn->name = peekfirst(fake);
X untokenize(fn->name);
X }
X else
X while (nam = ugetnode(fake))
X {
X ff = alloc(sizeof *ff);
X *ff = *fn;
X ff->name = nam;
X addnode(tab,ff);
X ret = 1;
X }
X return ret;
X}
X
X/* concatenate s1 and s2 in dynamically allocated buffer */
X
Xchar *dyncat(s1,s2) /**/
Xchar *s1;char *s2;
X{
Xchar *ptr;
X
X ptr = ncalloc(strlen(s1)+strlen(s2)+1);
X strcpy(ptr,s1);
X strcat(ptr,s2);
X return ptr;
X}
X
X/* concatenate s1, s2, and s3 in dynamically allocated buffer */
X
Xchar *tricat(s1,s2,s3) /**/
Xchar *s1;char *s2;char *s3;
X{
Xchar *ptr;
X
X ptr = zalloc(strlen(s1)+strlen(s2)+strlen(s3)+1);
X strcpy(ptr,s1);
X strcat(ptr,s2);
X strcat(ptr,s3);
X return ptr;
X}
X
X/* brace expansion */
X
Xvoid xpandbraces(list,np) /**/
XLklist list;Lknode *np;
X{
XLknode node = (*np),last = prevnode(node);
Xchar *str = getdata(node),*str3 = str,*str2;
Xint prev;
X
X for (; *str != Inbrace; str++);
X if (str[2] == '-' && str[4] == Outbrace) /* {a-z} */
X {
X char c1,c2;
X
X uremnode(list,node);
X chuck(str);
X c1 = *str;
X chuck(str);
X chuck(str);
X c2 = *str;
X chuck(str);
X if (itok(c1))
X c1 = ztokens[c1-Pound];
X if (itok(c2))
X c2 = ztokens[c2-Pound];
X if (c1 < c2)
X for (; c2 >= c1; c2--) /* {a-z} */
X {
X *str = c2;
X insnode(list,last,strdup(str3));
X }
X else
X for (; c2 <= c1; c2++) /* {z-a} */
X {
X *str = c2;
X insnode(list,last,strdup(str3));
X }
X *np = nextnode(last);
X return;
X }
X prev = str-str3;
X str2 = getparen(str++);
X if (!str2)
X {
X zerr("how did you get this error?",NULL,0);
X return;
X }
X uremnode(list,node);
X node = last;
X for(;;)
X {
X char *zz,*str4;
X int cnt;
X
X for (str4 = str, cnt = 0; cnt || *str != Comma && *str !=
X Outbrace; str++)
X if (*str == Inbrace)
X cnt++;
X else if (*str == Outbrace)
X cnt--;
X else if (!*str)
X exit(10);
X zz = zalloc(prev+(str-str4)+strlen(str2)+1);
X strncpy(zz,str3,prev);
X zz[prev] = '\0';
X strncat(zz,str4,str-str4);
X strcat(zz,str2);
X insnode(list,node,zz);
X incnode(node);
X if (*str != Outbrace)
X str++;
X else
X break;
X }
X *np = nextnode(last);
X}
X
X/* get closing paren, given pointer to opening paren */
X
Xchar *getparen(str) /**/
Xchar *str;
X{
Xint cnt = 1;
Xchar typein = *str++,typeout = typein+1;
X
X for (; *str && cnt; str++)
X if (*str == typein)
X cnt++;
X else if (*str == typeout)
X cnt--;
X if (!str && cnt)
X return NULL;
X return str;
X}
X
X/* check to see if a matches b (b is not a filename pattern) */
X
Xint matchpat(a,b) /**/
Xchar *a;char *b;
X{
XComp c;
Xint val;
X
X c = parsereg(b);
X if (!c)
X {
X zerr("bad pattern: %s",b,0);
X return 0;
X }
X val = domatch(a,c,0);
X return val;
X}
X
X/* do the ${foo%%bar}, ${foo#bar} stuff */
X/* please do not laugh at this code. */
X
Xvoid getmatch(sp,pat,dd) /**/
Xchar **sp;char *pat;int dd;
X{
XComp c;
Xchar *t,*lng = NULL,cc,*s = *sp;
X
X c = parsereg(pat);
X if (!c)
X {
X zerr("bad pattern: %s",pat,0);
X return;
X }
X if (!(dd & 2))
X {
X for (t = s; t==s || t[-1]; t++)
X {
X cc = *t;
X *t = '\0';
X if (domatch(s,c,0))
X {
X if (!(dd & 1))
X {
X *t = cc;
X t = strdup(t);
X *sp = t;
X return;
X }
X lng = t;
X }
X *t = cc;
X }
X if (lng)
X {
X t = strdup(lng);
X *sp = t;
X return;
X }
X }
X else
X {
X for (t = s+strlen(s); t >= s; t--)
X {
X if (domatch(t,c,0))
X {
X if (!(dd & 1))
X {
X *t = '\0';
X return;
X }
X lng = t;
X }
X }
X if (lng)
X {
X *lng = '\0';
X return;
X }
X }
X}
X
X/* add a component to pathbuf */
X
Xvoid addpath(s) /**/
Xchar *s;
X{
X while (pathbuf[pathpos++] = *s++);
X pathbuf[pathpos-1] = '/';
X pathbuf[pathpos] = '\0';
X}
X
Xchar *getfullpath(s) /**/
Xchar *s;
X{
Xstatic char buf[MAXPATHLEN];
X
X strcpy(buf,pathbuf);
X strcat(buf,s);
X return buf;
X}
X
X/* do the globbing */
X
Xvoid scanner(q) /**/
XComplist q;
X{
XComp c;
Xint closure;
X
X if (closure = q->closure) /* (foo/)# */
X if (q->closure == 2) /* (foo/)## */
X q->closure = 1;
X else
X scanner(q->next);
X if (c = q->comp)
X {
X if (!(c->next || c->left) && !haswilds(c->str))
X if (q->next)
X {
X int oppos = pathpos;
X
X if (errflag)
X return;
X addpath(c->str);
X if (!closure || exists(pathbuf))
X scanner((q->closure) ? q : q->next);
X pathbuf[pathpos = oppos] = '\0';
X }
X else
X {
X char *s;
X
X if (exists(s = getfullpath(c->str)))
X insert(strdup(s));
X }
X else
X {
X char *fn;
X int dirs = !!q->next;
X struct direct *de;
X DIR *lock = opendir(pathbuf);
X
X if (lock == NULL)
X return;
X readdir(lock); readdir(lock); /* skip . and .. */
X while (de = readdir(lock))
X {
X if (errflag)
X break;
X fn = &de->d_name[0];
X if (domatch(fn,c,unset(GLOBDOTS)))
X {
X int oppos = pathpos;
X
X if (dirs)
X {
X if (closure)
X {
X int type3;
X struct stat buf;
X
X if (lstat(getfullpath(fn),&buf) == -1)
X {
X if (errno != ENOENT && errno != EINTR &&
X errno != ENOTDIR)
X {
X zerr("%e: %s",fn,errno);
X errflag = 0;
X }
X continue;
X }
X type3 = buf.st_mode & S_IFMT;
X if (type3 != S_IFDIR)
X continue;
X }
X addpath(fn);
X scanner((q->closure) ? q : q->next); /* scan next level */
X pathbuf[pathpos = oppos] = '\0';
X }
X else
X {
X if (qualct) /* do the (X) (^X) stuff */
X {
X int (**fptr)DCLPROTO((struct stat *,long)) = qualfuncs;
X int *sptr = qualsense;
X long *lptr = qualdata;
X struct stat buf;
X
X if (lstat(getfullpath(fn),&buf) == -1)
X {
X if (errno != ENOENT && errno != EINTR)
X {
X zerr("%e: %s",fn,errno);
X errflag = 0;
X }
X continue;
X }
X while (*fptr)
X if (!(!!((*fptr++)(&buf,*lptr++)) ^ *sptr++))
X {
X fptr = NULL;
X break;
X }
X if (!fptr)
X continue;
X }
X insert(dyncat(pathbuf,fn));
X }
X }
X }
X closedir(lock);
X }
X }
X else
X zerr("no idea how you got this error message.",NULL,0);
X}
X
X/* do the [..(foo)..] business */
X
Xint minimatch(pat,str) /**/
Xchar **pat;char **str;
X{
Xchar *pt = *pat+1,*s = *str;
X
X for (; *pt != Outpar; s++,pt++)
X if ((*pt != Quest || !*s) && *pt != *s)
X {
X *pat = getparen(*pat)-1;
X return 0;
X }
X *str = s-1;
X return 1;
X}
X
Xstatic char *pptr;
Xstatic int first;
X
Xint domatch(str,c,fist) /**/
Xchar *str;Comp c;int fist;
X{
X pptr = str;
X first = fist;
X return doesmatch(c);
X}
X
X/* see if current pattern matches c */
X
Xint doesmatch(c) /**/
XComp c;
X{
Xchar *pat = c->str;
X
X if (c->closure)
X {
X char *saves = pptr;
X int savei = first;
X
X if (doesmatch(c->next))
X return 1;
X pptr = saves;
X first = savei;
X }
X for(;;)
X {
X if (!pat || !*pat)
X {
X char *saves;
X int savei;
X
X if (errflag)
X return 0;
X saves = pptr;
X savei = first;
X if (c->left || c->right)
X if (!doesmatch(c->left))
X if (c->right)
X {
X pptr = saves;
X first = savei;
X if (!doesmatch(c->right))
X return 0;
X }
X else
X return 0;
X if (c->closure)
X return doesmatch(c);
X if (!c->next)
X return (!c->last || !*pptr);
X return doesmatch(c->next);
X }
X if (first && *pptr == '.' && *pat != '.')
X return 0;
X if (*pat == Star) /* final * is not expanded to ?#; returns success */
X {
X while (*pptr) pptr++;
X return 1;
X }
X first = 0;
X if (*pat == Quest && *pptr)
X {
X pptr++;
X pat++;
X continue;
X }
X if (*pat == Hat)
X return 1-doesmatch(c->next);
X if (*pat == Inbrack)
X if (pat[1] == Hat)
X {
X for (pat += 2; *pat != Outbrack && *pat; pat++)
X if (*pat == '-' && pat[-1] != Hat && pat[1] != Outbrack)
X {
X if (pat[-1] <= *pptr && pat[1] >= *pptr)
X break;
X }
X else if (*pptr == *pat)
X break;
X if (!*pat)
X {
X zerr("something is very wrong.",NULL,0);
X return 0;
X }
X if (*pat != Outbrack)
X break;
X pat++;
X pptr++;
X continue;
X }
X else
X {
X for (pat++; *pat != Outbrack && *pat; pat++)
X if (*pat == Inpar)
X {
X if (minimatch(&pat,&pptr))
X break;
X }
X else if (*pat == '-' && pat[-1] != Inbrack && pat[1] != Outbrack)
X {
X if (pat[-1] <= *pptr && pat[1] >= *pptr)
X break;
X }
X else if (*pptr == *pat)
X break;
X if (!pat || !*pat)
X {
X zerr("oh dear. that CAN'T be right.",NULL,0);
X return 0;
X }
X if (*pat == Outbrack)
X break;
X for (pptr++; *pat != Outbrack; pat++);
X pat++;
X continue;
X }
X if (*pat == Inang)
X {
X int t1,t2,t3;
X char *ptr;
X
X if (*++pat == Outang) /* handle <> case */
X {
X ( void ) zstrtol(pptr,&ptr,10);
X if (ptr == pptr)
X break;
X pptr = ptr;
X pat++;
X }
X else
X {
X t1 = zstrtol(pptr,&ptr,10);
X if (ptr == pptr)
X break;
X pptr = ptr;
X t2 = zstrtol(pat,&ptr,10);
X if (*ptr != '-')
X exit(31);
X t3 = zstrtol(ptr+1,&pat,10);
X if (!t3)
X t3 = INT_MAX;
X if (*pat++ != Outang)
X exit(21);
X if (t1 < t2 || t1 > t3)
X break;
X }
X continue;
X }
X if (*pptr == *pat)
X {
X pptr++;
X pat++;
X continue;
X }
X break;
X }
X return 0;
X}
X
XComplist parsepat(str) /**/
Xchar *str;
X{
X mode = 0;
X pptr = str;
X return parsecomplist();
X}
X
XComp parsereg(str) /**/
Xchar *str;
X{
X mode = 1;
X pptr = str;
X return parsecompsw();
X}
X
XComplist parsecomplist() /**/
X{
XComp c1;
XComplist p1;
X
X if (pptr[0] == '.' && pptr[1] == '.' && pptr[2] == '.' && pptr[3] ==
X '.' && pptr[4] == '/')
X {
X pptr[0] = Inpar;
X pptr[1] = Star;
X pptr[2] = '/';
X pptr[3] = Outpar;
X pptr[4] = Pound; /* "..../" -> "( * /)#" */
X }
X if (*pptr == Inpar)
X {
X char *str;
X int pars = 1;
X
X for (str = pptr+1; *str && pars; str++)
X if (*str == Inpar)
X pars++;
X else if (*str == Outpar)
X pars--;
X if (str[0] != Pound || str[-1] != Outpar || str[-2] != '/')
X goto kludge;
X pptr++;
X if (!(c1 = parsecompsw()))
X return NULL;
X if (pptr[0] == '/' && pptr[1] == Outpar && pptr[2] == Pound)
X {
X int pdflag = 0;
X
X pptr += 3;
X if (*pptr == Pound)
X {
X pdflag = 1;
X pptr++;
X }
X p1 = (Complist) alloc(sizeof *p1);
X p1->comp = c1;
X p1->closure = 1+pdflag;
X p1->next = parsecomplist();
X return (p1->comp) ? p1 : NULL;
X }
X }
X else
X {
Xkludge:
X if (!(c1 = parsecompsw()))
X return NULL;
X if (*pptr == '/' || !*pptr)
X {
X int ef = *pptr == '/';
X
X p1 = (Complist) alloc(sizeof *p1);
X p1->comp = c1;
X p1->closure = 0;
X p1->next = (*pptr == '/') ? (pptr++,parsecomplist()) : NULL;
X return (ef && !p1->next) ? NULL : p1;
X }
X }
X errflag = 1;
X return NULL;
X}
X
XComp parsecomp() /**/
X{
XComp c = (Comp) alloc(sizeof *c),c1,c2;
Xchar *s = c->str = alloc(MAXPATHLEN*2),*ls = NULL;
X
X while (*pptr && (mode || *pptr != '/') && *pptr != Bar &&
X *pptr != Outpar)
X {
X if (*pptr == Hat)
X {
X *s++ = Hat;
X *s++ = '\0';
X pptr++;
X if (!(c->next = parsecomp()))
X return NULL;
X return c;
X }
X if (*pptr == Star && pptr[1] && (mode || pptr[1] != '/'))
X {
X *s++ = '\0';
X pptr++;
X c1 = (Comp) alloc(sizeof *c1);
X *(c1->str = strdup("?")) = Quest;
X c1->closure = 1;
X c2 = parsecomp();
X c1->next = c2;
X c->next = c1;
X return c;
X }
X if (*pptr == Inpar)
X {
X *s++ = '\0';
X pptr++;
X c->next = (Comp) alloc(sizeof *c);
X c->next->left = c1 = parsecompsw();
X if (*pptr != Outpar)
X {
X errflag = 1;
X return NULL;
X }
X pptr++;
X if (*pptr == Pound)
X {
X int dpnd = 1;
X
X pptr++;
X if (*pptr == Pound)
X {
X pptr++;
X dpnd = 2;
X }
X c->next->closure = dpnd;
X }
X c2 = parsecomp();
X if (!c2)
X return NULL;
X c->next->next = c2;
X return c;
X }
X if (*pptr == Pound)
X {
X *s = '\0';
X pptr++;
X if (!ls)
X return NULL;
X c->next = c1 = (Comp) alloc(sizeof *c);
X c1->str = strdup(ls);
X c1->closure = 1;
X c1->next = parsecomp();
X if (!c1->next)
X return NULL;
X *ls++ = '\0';
X return c;
X }
X ls = s;
X if (*pptr == Inang)
X {
X int dshct;
X
X dshct = (pptr[1] == Outang);
X *s++ = *pptr++;
X while (*pptr && (*s++ = *pptr++) != Outang)
X if (s[-1] == '-')
X dshct++;
X else if (!idigit(s[-1]))
X break;
X if (s[-1] != Outang || dshct != 1)
X return NULL;
X }
X else if (*pptr == Inbrack)
X {
X while (*pptr && (*s++ = *pptr++) != Outbrack);
X if (s[-1] != Outbrack)
X return NULL;
X }
X else if (itok(*pptr) && *pptr != Star && *pptr != Quest)
X *s++ = ztokens[*pptr++-Pound];
X else
X *s++ = *pptr++;
X }
X if (*pptr == '/' || !*pptr)
X c->last = 1;
X *s++ = '\0';
X return c;
X}
X
XComp parsecompsw() /**/
X{
XComp c1,c2,c3;
X
X c1 = parsecomp();
X if (!c1)
X return NULL;
X if (*pptr == Bar)
X {
X c2 = (Comp) alloc(sizeof *c2);
X pptr++;
X c3 = parsecompsw();
X if (!c3)
X return NULL;
X c2->str = strdup("");
X c2->left = c1;
X c2->right = c3;
X return c2;
X }
X return c1;
X}
X
X/* tokenize and see if ss matches tt */
X
Xint patmatch(ss,tt) /**/
Xchar *ss;char *tt;
X{
Xchar *s = ss,*t;
X
X for (; *s; s++)
X if (*s == '\\')
X chuck(s);
X else
X for (t = ztokens; *t; t++)
X if (*t == *s)
X {
X *s = (t-ztokens)+Pound;
X break;
X }
X return matchpat(ss,tt);
X}
X
X/* remove unnecessary Nulargs */
X
Xvoid remnulargs(s) /**/
Xchar *s;
X{
Xint nl = *s;
Xchar *t = s;
X
X while (*s)
X if (*s == Nularg)
X chuck(s);
X else
X s++;
X if (!*t && nl)
X {
X t[0] = Nularg;
X t[1] = '\0';
X }
X}
X
X/* qualifier functions */
X
Xint qualdev(buf,dv) /**/
Xstruct stat *buf;long dv;
X{
X return buf->st_dev == dv;
X}
X
Xint qualnlink(buf,ct) /**/
Xstruct stat *buf;long ct;
X{
X return buf->st_nlink == ct;
X}
X
Xint qualuid(buf,uid) /**/
Xstruct stat *buf;long uid;
X{
X return buf->st_uid == uid;
X}
X
Xint qualgid(buf,gid) /**/
Xstruct stat *buf;long gid;
X{
X return buf->st_gid == gid;
X}
X
Xint qualisdev(buf,junk) /**/
Xstruct stat *buf;long junk;
X{
X junk = buf->st_mode & S_IFMT;
X return junk == S_IFBLK || junk == S_IFCHR;
X}
X
Xint qualmode(buf,mod) /**/
Xstruct stat *buf;long mod;
X{
X return (buf->st_mode & S_IFMT) == mod;
X}
X
Xint qualflags(buf,mod) /**/
Xstruct stat *buf;long mod;
X{
X return buf->st_mode & mod;
X}
SHAR_EOF
echo 'File zsh2.00/src/glob.c is complete' &&
chmod 0644 zsh2.00/src/glob.c ||
echo 'restore of zsh2.00/src/glob.c failed'
Wc_c="`wc -c < 'zsh2.00/src/glob.c'`"
test 21953 -eq "$Wc_c" ||
echo 'zsh2.00/src/glob.c: original size 21953, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/glob.pro ==============
if test -f 'zsh2.00/src/glob.pro' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/glob.pro (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/glob.pro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/glob.pro' &&
Xvoid glob DCLPROTO((Lklist list,Lknode *np));
Xlong qgetnum DCLPROTO((char **s));
Xint notstrcmp DCLPROTO((char **a,char **b));
Xint forstrcmp DCLPROTO((char **a,char **b));
Xvoid insert DCLPROTO((char *s));
Xint haswilds DCLPROTO((char *str));
Xint hasbraces DCLPROTO((char *str));
Xint xpandredir DCLPROTO((struct redir *fn,Lklist tab));
Xchar *dyncat DCLPROTO((char *s1,char *s2));
Xchar *tricat DCLPROTO((char *s1,char *s2,char *s3));
Xvoid xpandbraces DCLPROTO((Lklist list,Lknode *np));
Xchar *getparen DCLPROTO((char *str));
Xint matchpat DCLPROTO((char *a,char *b));
Xvoid getmatch DCLPROTO((char **sp,char *pat,int dd));
Xvoid addpath DCLPROTO((char *s));
Xchar *getfullpath DCLPROTO((char *s));
Xvoid scanner DCLPROTO((Complist q));
Xint minimatch DCLPROTO((char **pat,char **str));
Xint domatch DCLPROTO((char *str,Comp c,int fist));
Xint doesmatch DCLPROTO((Comp c));
XComplist parsepat DCLPROTO((char *str));
XComp parsereg DCLPROTO((char *str));
XComplist parsecomplist DCLPROTO((void));
XComp parsecomp DCLPROTO((void));
XComp parsecompsw DCLPROTO((void));
Xint patmatch DCLPROTO((char *ss,char *tt));
Xvoid remnulargs DCLPROTO((char *s));
Xint qualdev DCLPROTO((struct stat *buf,long dv));
Xint qualnlink DCLPROTO((struct stat *buf,long ct));
Xint qualuid DCLPROTO((struct stat *buf,long uid));
Xint qualgid DCLPROTO((struct stat *buf,long gid));
Xint qualisdev DCLPROTO((struct stat *buf,long junk));
Xint qualmode DCLPROTO((struct stat *buf,long mod));
Xint qualflags DCLPROTO((struct stat *buf,long mod));
SHAR_EOF
chmod 0644 zsh2.00/src/glob.pro ||
echo 'restore of zsh2.00/src/glob.pro failed'
Wc_c="`wc -c < 'zsh2.00/src/glob.pro'`"
test 1492 -eq "$Wc_c" ||
echo 'zsh2.00/src/glob.pro: original size 1492, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/hist.c ==============
if test -f 'zsh2.00/src/hist.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/hist.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/hist.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/hist.c' &&
X/*
X
X hist.c - history expansion
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 int lastc;
X
X/* add a character to the current history word */
X
Xvoid hwaddc(c) /**/
Xint c;
X{
X if (hlastw && hline && (!errflag || c == HISTSPACE))
X {
X if (c == EOF || c == HERR)
X c = ' ';
X *hptr++ = c;
X if (hptr-hline >= hlinesz)
X {
X int ll,flag = 0;
X
X ll = hptr-hlastw;
X if (full(histlist) && getdata(lastnode(histlist)) == hline)
X flag = 1;
X hline = realloc(hline,hlinesz *= 4);
X if (flag)
X setdata(lastnode(histlist),hline);
X hptr = hline+(hlinesz/4);
X hlastw = hptr-ll;
X }
X }
X}
X
X#define habort() { errflag = 1; return HERR; }
X
X/* get a character after performing history substitution */
X
Xint hgetc() /**/
X{
Xint c,ev,farg,larg,argc,marg = -1,cflag = 0,bflag = 0;
Xchar buf[256],*ptr;
Xchar *sline,*eline;
X
Xtailrec:
X c = hgetch();
X if (stophist)
X {
X hwaddc(c);
X return c;
X }
X if (isfirstch && c == hatchar)
X {
X isfirstch = 0;
X hungets(":s^");
X c = bangchar;
X goto hatskip;
X }
X if (c != ' ')
X isfirstch = 0;
X if (c == '\\')
X {
X int g = hgetch();
X
X if (g != bangchar)
X hungetch(g);
X else
X {
X hwaddc(bangchar);
X return bangchar;
X }
X }
X if (c != bangchar)
X {
X hwaddc(c);
X return c;
X }
Xhatskip:
X *hptr = '\0';
X if ((c = hgetch()) == '{')
X {
X bflag = cflag = 1;
X c = hgetch();
X }
X if (c == '\"')
X {
X stophist = 1;
X goto tailrec;
X }
X if (!cflag && inblank(c) || c == '=' || c == '(' || c == EOF)
X {
X hungetch(c);
X hwaddc(bangchar);
X return bangchar;
X }
X cflag = 0;
X ptr = buf;
X
X /* get event number */
X
X if (c == '?')
X {
X for(;;)
X {
X c = hgetch();
X if (c == '?' || c == '\n' || c == -1)
X break;
X else
X *ptr++ = c;
X }
X if (c != '\n' && c != -1)
X c = hgetch();
X *ptr = '\0';
X ev = hconsearch(hsubl = ztrdup(buf),&marg);
X if (ev == -1)
X {
X herrflush();
X zerr("no such event: %s",buf,0);
X habort();
X }
X }
X else
X {
X int t0;
X
X for (;;)
X {
X if (inblank(c) || c == ':' || c == '^' || c == '$' || c == '*'
X || c == '%' || c == '}' || c == -1)
X break;
X if (ptr != buf && c == '-')
X break;
X *ptr++ = c;
X if (c == '#' || c == '!')
X {
X c = hgetch();
X break;
X }
X c = hgetch();
X }
X *ptr = 0;
X if (!*buf)
X ev = defev;
X else if (t0 = atoi(buf))
X ev = (t0 < 0) ? curhist+t0 : t0;
X else if (*buf == '!')
X ev = curhist-1;
X else if (*buf == '#')
X ev = curhist;
X else if ((ev = hcomsearch(buf)) == -1)
X {
X zerr("event not found: %s",buf,0);
X while (c != '\n' && c != -1)
X c = hgetch();
X habort();
X }
X }
X
X /* get the event */
X
X if (!(eline = getevent(defev = ev)))
X habort();
X
X /* extract the relevant arguments */
X
X argc = getargc(eline);
X if (c == ':')
X {
X cflag = 1;
X c = hgetch();
X }
X if (c == '*')
X {
X farg = 1;
X larg = argc;
X cflag = 0;
X }
X else
X {
X hungetch(c);
X larg = farg = getargspec(argc,marg);
X if (larg == -2)
X habort();
X if (farg != -1)
X cflag = 0;
X c = hgetch();
X if (c == '*')
X {
X cflag = 0;
X larg = argc;
X }
X else if (c == '-')
X {
X cflag = 0;
X larg = getargspec(argc,marg);
X if (larg == -2)
X habort();
X if (larg == -1)
X larg = argc-1;
X }
X else
X hungetch(c);
X }
X if (farg == -1)
X farg = 0;
X if (larg == -1)
X larg = argc;
X if (!(sline = getargs(eline,farg,larg)))
X habort();
X
X /* do the modifiers */
X
X for(;;)
X {
X c = (cflag) ? ':' : hgetch();
X cflag = 0;
X if (c == ':')
X {
X int gbal = 0;
X
X if ((c = hgetch()) == 'g')
X {
X gbal = 1;
X c = hgetch();
X }
X switch(c)
X {
X case 'p':
X histdone = 2;
X break;
X case 'h':
X if (!remtpath(&sline))
X {
X herrflush();
X zerr("modifier failed: h",NULL,0);
X habort();
X }
X break;
X case 'e':
X if (!rembutext(&sline))
X {
X herrflush();
X zerr("modifier failed: e",NULL,0);
X habort();
X }
X break;
X case 'r':
X if (!remtext(&sline))
X {
X herrflush();
X zerr("modifier failed: r",NULL,0);
X habort();
X }
X break;
X case 't':
X if (!remlpaths(&sline))
X {
X herrflush();
X zerr("modifier failed: t",NULL,0);
X habort();
X }
X break;
X case 's':
X {
X int del;
X char *ptr1,*ptr2;
X
X del = hgetch();
X ptr1 = hdynread(del);
X if (!ptr1)
X habort();
X ptr2 = hdynread2(del);
X if (strlen(ptr1))
X {
X if (hsubl)
X free(hsubl);
X hsubl = ptr1;
X }
X if (hsubr)
X free(hsubr);
X hsubr = ptr2;
X }
X case '&':
X if (hsubl && hsubr)
X {
X if (subst(&sline,hsubl,hsubr,gbal))
X habort();
X }
X else
X {
X herrflush();
X zerr("no previous substitution with &",NULL,0);
X habort();
X }
X break;
X case 'q':
X quote(&sline);
X break;
X case 'x':
X quotebreak(&sline);
X break;
X case 'l':
X downcase(&sline);
X break;
X case 'u':
X upcase(&sline);
X break;
X default:
X herrflush();
X zerr("illegal modifier: %c",NULL,c);
X habort();
X break;
X }
X }
X else
X {
X if (c != '}' || !bflag)
X hungetch(c);
X if (c != '}' && bflag)
X {
X zerr("'}' expected",NULL,0);
X habort();
X }
X break;
X }
X }
X
X /* stuff the resulting string in the input queue and start over */
X
X if (alstackind != MAXAL)
X {
X hungets(HISTMARK);
X alstack[alstackind++] = NULL;
X }
X hungets(sline);
X histdone |= 1;
X goto tailrec;
X}
X
X/* get a character without history expansion */
X
Xint hgetch() /**/
X{
Xchar *line,*pmpt,*pmpt2 = NULL;
Xint plen;
X
Xstart:
X if (inbufct)
X {
X inbufct--;
X if ((lastc = *inbufptr++) == ALPOP)
X {
X Alias ix;
X char *t;
X
X if (!alstackind)
X {
X zerr("alias stack underflow",NULL,0);
X return lastc = HERR;
X }
X ix = alstack[--alstackind];
X if (ix)
X {
X ix->inuse = 0;
X t = ix->text;
X if (*t && t[strlen(t)-1] == ' ')
X alstat = ALSTAT_MORE;
X else
X alstat = ALSTAT_JUNK;
X }
X goto start;
X }
X return lastc;
X }
X if (strin)
X return lastc = EOF;
X if (errflag)
X return lastc = HERR;
X if (interact && isset(SHINSTDIN))
X if (!isfirstln)
X pmpt = putprompt(prompt2,&plen);
X else
X {
X int foo;
X
X pmpt = putprompt(prompt,&plen);
X pmpt2 = (rprompt) ? putprompt(rprompt,&foo) : NULL;
X }
X if (!(interact && isset(SHINSTDIN) && SHTTY != -1) || unset(USEZLE))
X {
X if (interact && isset(SHINSTDIN))
X write(2,pmpt,strlen(pmpt));
X line = fgets(zalloc(256),256,bshin);
X }
X else
X line = zleread(pmpt,pmpt2,plen);
X if (!line)
X return lastc = EOF;
X if (interact && isset(SHINSTDIN))
X {
X char *s = getdata(lastnode(lithistlist));
X
X if (!*s)
X {
X free(s);
X setdata(lastnode(lithistlist),ztrdup(line));
X }
X else
X {
X char *t = zalloc(strlen(s)+strlen(line)+3);
X
X strcpy(t,s);
X strcat(t,line);
X free(s);
X setdata(lastnode(lithistlist),t);
X }
X }
X if (isfirstln)
X spaceflag = *line == ' ';
X if (isset(VERBOSE))
X {
X fputs(line,stderr);
X fflush(stderr);
X }
X if (line[strlen(line)-1] == '\n')
X {
X lineno++;
X if (interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) &&
X SHTTY != -1 && *line && line[1] && line[strlen(line)-2] == '`')
X {
X int ct;
X char *ptr;
X
X for (ct = 0, ptr = line; *ptr; ptr++)
X if (*ptr == '`')
X ct++;
X if (ct & 1)
X {
X ptr[-2] = '\n';
X ptr[-1] = '\0';
X }
X }
X }
X isfirstch = 1;
X hungets(line);
X free(line);
X goto start;
X}
X
X/* put a string in the input queue */
X
Xvoid hungets(str) /**/
Xchar *str;
X{
Xint slen = strlen(str);
X
X/* shrink inbuf if it gets too big */
X
X if (!inbufct && inbufsz > 65536)
X {
X free(inbuf);
X inbuf = zalloc(inbufsz = 256);
X inbufptr = inbuf+inbufsz;
X inbufct = 0;
X }
X if (slen+inbufct > inbufsz)
X {
X char *x;
X
X while (slen+inbufct > inbufsz)
X inbufsz *= 4;
X x = zalloc(inbufsz);
X memcpy(x+inbufsz-inbufct,inbufptr,inbufct);
X inbufptr = x+inbufsz-inbufct;
X free(inbuf);
X inbuf = x;
X }
X memcpy(inbufptr -= slen,str,slen);
X inbufct += slen;
X}
X
X/* unget a char and remove it from hline */
X
Xvoid hungetc(c) /**/
Xint c;
X{
X if (c == -1)
X return;
X if (hlastw)
X {
X if (hlastw == hptr)
X zerr("hungetc attempted at buffer start",NULL,0);
X else
X hptr--;
X }
X hungetch(c);
X}
X
Xvoid hungetch(c) /**/
Xint c;
X{
X if (c == -1)
X return;
X if (inbufct == inbufsz)
X {
X hungets(" ");
X *inbufptr = c;
X }
X else
X {
X *--inbufptr = c;
X inbufct++;
X }
X}
X
X/* begin reading a string */
X
Xvoid strinbeg() /**/
X{
X strin = 1;
X hbegin();
X}
X
X/* done reading a string */
X
Xvoid strinend() /**/
X{
X strin = 0;
X isfirstch = 1;
X histdone = 0;
X hend();
X}
X
X/* stuff a whole file into the input queue and print it */
X
Xint stuff(fn) /**/
Xchar *fn;
X{
XFILE *in;
Xchar *buf;
Xint len;
X
X if (!(in = fopen(fn,"r")))
X {
X zerr("can't open %s",fn,0);
X return 1;
X }
X fseek(in,0,2);
X len = ftell(in);
X fseek(in,0,0);
X buf = alloc(len+1);
X if (!(fread(buf,len,1,in)))
X {
X zerr("read error on %s",fn,0);
X fclose(in);
X free(buf);
X return 1;
X }
X fclose(in);
X buf[len] = '\0';
X fwrite(buf,len,1,stdout);
X hungets(buf);
X return 0;
X}
X
X/* flush input queue */
X
Xvoid hflush() /**/
X{
X inbufptr += inbufct;
X inbufct = 0;
X}
X
X/* initialize the history mechanism */
X
Xvoid hbegin() /**/
X{
X isfirstln = isfirstch = 1;
X histremmed = errflag = histdone = spaceflag = 0;
X stophist = isset(NOBANGHIST);
X lithist = isset(HISTLIT);
X hline = hptr = zalloc(hlinesz = 32);
X if (interact && isset(SHINSTDIN) && !strin)
X {
X inittty();
X defev = curhist++;
X while (curhist-firsthist >= histsiz)
X {
X free(getnode(histlist));
X firsthist++;
X }
X while (curhist-firstlithist >= lithistsiz)
X {
X free(getnode(lithistlist));
X firstlithist++;
X }
X permalloc();
X addnode(histlist,hline);
X addnode(lithistlist,ztrdup(""));
X heapalloc();
X }
X else
X histremmed = 1;
X}
X
Xvoid inittty() /**/
X{
X attachtty(mypgrp);
X settyinfo(&shttyinfo);
X}
X
X/* say we're done using the history mechanism */
X
Xint hend() /**/
X{
Xint flag,save = 1;
X
X if (!hline)
X return 1;
X if (!interact || strin || unset(SHINSTDIN))
X {
X free(hline);
X return 1;
X }
X flag = histdone;
X histdone = 0;
X if (hptr < hline+2)
X save = 0;
X else
X {
X char *s = getdata(lastnode(lithistlist));
X
X if (*s)
X s[strlen(s)-1] = '\0';
X hptr[-1] = '\0';
X if (hptr[-2] == '\n')
X if (hline[1])
X hptr[-3] = '\0';
X else
X save = 0;
X if (!strcmp(hline,"\n") ||
X (isset(HISTIGNOREDUPS) && firstnode(histlist) &&
X nextnode(firstnode(histlist)) &&
X !strcmp(hline,getdata(prevnode(lastnode(histlist))))) ||
X (isset(HISTIGNORESPACE) && spaceflag) )
X save = 0;
X }
X if (!save)
X {
X free(hline);
X if (!histremmed)
X {
X remnode(histlist,lastnode(histlist));
X free(remnode(lithistlist,lastnode(lithistlist)));
X curhist--;
X }
X flag = 0;
X }
X if (flag)
X {
X char *ptr,*p;
X
X p = ptr = ztrdup(hline);
X for (;*p;p++)
X if (*p == HISTSPACE)
X *p = ' ';
X fprintf(stderr,"%s\n",ptr);
X fflush(stderr);
X free(ptr);
X }
X hline = NULL;
X return !(flag & 2 || errflag);
X}
X
X/* remove the current line from the history List */
X
Xvoid remhist() /**/
X{
X if (!histremmed)
X {
X histremmed = 1;
X free(remnode(histlist,lastnode(histlist)));
X free(remnode(lithistlist,lastnode(lithistlist)));
X curhist--;
X }
X}
X
X/* begin a word */
X
Xvoid hwbegin() /**/
X{
X hlastw = hptr;
X}
X
X/* add a word to the history List */
X
Xchar *hwadd() /**/
X{
Xchar *ret = hlastw;
X
X if (hlastw && hline)
X {
X hwaddc(HISTSPACE);
X if (alstackind || strin)
X if (!(alstackind == 1 && !alstack[0]))
X hptr = hlastw;
X }
X if (alstat == ALSTAT_JUNK)
X alstat = 0;
X return ret;
X}
X
X/* get an argument specification */
X
Xint getargspec(argc,marg) /**/
Xint argc;int marg;
X{
Xint c,ret = -1;
X
X if ((c = hgetch()) == '0')
X return 0;
X if (idigit(c))
X {
X ret = 0;
X while (idigit(c))
X {
X ret = ret*10+c-'0';
X c = hgetch();
X }
X hungetch(c);
X }
X else if (c == '^')
X ret = 1;
X else if (c == '$')
X ret = argc;
X else if (c == '%')
X {
X if (marg == -1)
X {
X herrflush();
X zerr("%% with no previous word matched",NULL,0);
X return -2;
X }
X ret = marg;
X }
X else
X hungetch(c);
X return ret;
X}
X
X/* do ?foo? search */
X
Xint hconsearch(str,marg) /**/
Xchar *str;int *marg;
X{
Xint t0,t1 = 0;
XLknode node;
Xchar *s;
X
X if (curhist-firsthist < 1)
X return -1;
X for (t0 = curhist-1,node = prevnode(lastnode(histlist));
X t0 >= firsthist; t0--,node = prevnode(node))
X if (s = strstr(getdata(node),str))
X {
X while (s != (char *) getdata(node))
X if (*s-- == HISTSPACE)
X t1++;
X *marg = t1;
X return t0;
X }
X return -1;
X}
X
X/* do !foo search */
X
Xint hcomsearch(str) /**/
Xchar *str;
X{
Xint t0;
XLknode node;
Xchar *s,*t;
X
X if (curhist-firsthist < 1)
X return -1;
X for (t0 = curhist-1,node = prevnode(lastnode(histlist)); t0 >= firsthist;
X t0--,node = prevnode(node))
X {
X for (s = getdata(node); *s; s++)
X if (*s == HISTSPACE)
X break;
X t = strstr(getdata(node),str);
X if (t && t < s)
X return t0;
X }
X return -1;
X}
X
X/* various utilities for : modifiers */
X
Xint remtpath(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if (cut = strrchr(str,'/'))
X {
X *cut = '\0';
X return 1;
X }
X return 0;
X}
X
Xint remtext(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if ((cut = strrchr(str,'.')) && cut != str)
X {
X *cut = '\0';
X return 1;
X }
X return 0;
X}
X
Xint rembutext(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if ((cut = strrchr(str,'.')) && cut != str)
X {
X *junkptr = strdup(cut+1); /* .xx or xx? */
X return 1;
X }
X return 0;
X}
X
Xint remlpaths(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr,*cut;
X
X if (cut = strrchr(str,'/'))
X {
X *cut = '\0';
X *junkptr = strdup(cut+1);
X return 1;
X }
X return 0;
X}
X
Xint makeuppercase(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr;
X
X for (; *str; str++)
X *str = toupper(*str);
X return 1;
X}
X
Xint makelowercase(junkptr) /**/
Xchar **junkptr;
X{
Xchar *str = *junkptr;
X
X for (; *str; str++)
X *str = tolower(*str);
X return 1;
X}
X
Xint subst(strptr,in,out,gbal) /**/
Xchar **strptr;char *in;char *out;int gbal;
X{
Xchar *str = *strptr,*cut,*sptr;
Xint ret = 0,off;
X
Xconsidered_harmful:
X if (cut = (char *) strstr(str,in))
X {
X *cut = '\0';
X cut += strlen(in);
X off = cut-*strptr;
X *strptr = tricat(*strptr,sptr = convamps(out,in),cut);
X if (gbal)
X {
X str = (char *) *strptr+off+strlen(sptr);
X ret = 1;
X goto considered_harmful;
X }
X return 0;
X }
X if (!ret)
X {
X herrflush();
X zerr("string not found: %s",in,0);
X return 1;
X }
X return 0;
X}
X
Xchar *convamps(out,in) /**/
Xchar *out;char *in;
X{
Xchar *ptr,*ret,*pp;
Xint slen,inlen = strlen(in);
X
X for (ptr = out, slen = 0; *ptr; ptr++,slen++)
X if (*ptr == '\\')
X ptr++;
X else if (*ptr == '&')
X slen += inlen-1;
X ret = pp = alloc(slen+1);
X for (ptr = out; *ptr; ptr++)
X if (*ptr == '\\')
X *pp++ = *++ptr;
X else if (*ptr == '&')
X {
X strcpy(pp,in);
X pp += inlen;
X }
X else
X *pp++ = *ptr;
X *pp = '\0';
X return ret;
X}
X
Xchar *makehstr(s) /**/
Xchar *s;
X{
Xchar *t;
X
X t = s = strdup(s);
X for (; *t; t++)
X if (*t == HISTSPACE)
X *t = ' ';
X return s;
X}
X
Xchar *quietgetevent(ev) /**/
Xint ev;
X{
XLknode node;
X
X ev -= (lithist) ? firstlithist : firsthist;
X if (ev < 0)
X return NULL;
X for (node = firstnode((lithist) ? lithistlist : histlist);
X ev && node; incnode(node), ev--);
X if (!node)
X return NULL;
X return getdata(node);
X}
X
Xchar *getevent(ev) /**/
Xint ev;
X{
XLknode node;
Xint oev = ev;
X
X ev -= firsthist;
X for (node = firstnode(histlist); ev && node; incnode(node), ev--);
X if (!node)
X {
X herrflush();
X zerr("no such event: %d",NULL,oev);
X return NULL;
X }
X return getdata(node);
X}
X
Xint getargc(list) /**/
Xchar *list;
X{
Xint argc = 0;
X
X for (; *list; list++)
X if (*list == HISTSPACE)
X argc++;
X return argc;
X}
X
Xchar *getargs(elist,arg1,arg2) /**/
Xchar *elist;int arg1;int arg2;
X{
Xchar *ret = elist,*retn;
Xint acnt = arg2-arg1+1;
X
X while (arg1--)
X while (*ret && *ret++ != HISTSPACE);
X if (!*ret)
X {
X herrflush();
X zerr("no such word in event",NULL,0);
X return NULL;
X }
X retn = ret = strdup(ret);
X while (acnt > 0)
X {
X while (*ret && *ret != HISTSPACE)
X ret++;
X if (*ret == HISTSPACE)
X *ret = ' ';
X else
X break;
X acnt--;
X }
X if (acnt > 1 && !*ret)
X {
X herrflush();
X zerr("no such word in event",NULL,0);
X return NULL;
X }
X *ret = '\0';
X return retn;
X}
X
Xvoid upcase(x) /**/
Xchar **x;
X{
Xchar *pp = *(char **) x;
X
X for (; *pp; pp++)
X *pp = toupper(*pp);
X}
X
Xvoid downcase(x) /**/
Xchar **x;
X{
Xchar *pp = *(char **) x;
X
X for (; *pp; pp++)
X *pp = tolower(*pp);
X}
X
Xint quote(tr) /**/
Xchar **tr;
X{
Xchar *ptr,*rptr,**str = (char **) tr;
Xint len = 1;
X
X for (ptr = *str; *ptr; ptr++,len++)
X if (*ptr == '\'')
X len += 3;
X ptr = *str;
X *str = rptr = zalloc(len);
X for (ptr = *str; *ptr; )
X if (*ptr == '\'')
X {
X *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
X ptr++;
X }
X else
X *rptr++ = *ptr++;
X return 0;
X}
X
Xint quotebreak(tr) /**/
Xchar **tr;
X{
Xchar *ptr,*rptr,**str = (char **) tr;
Xint len = 1;
X
X for (ptr = *str; *ptr; ptr++,len++)
X if (*ptr == '\'')
X len += 3;
X else if (inblank(*ptr))
X len += 2;
X ptr = *str;
X *str = rptr = zalloc(len);
X for (ptr = *str; *ptr; )
X if (*ptr == '\'')
X {
X *rptr++ = '\''; *rptr++ = '\\'; *rptr++ = '\''; *rptr++ = '\'';
X ptr++;
X }
X else if (inblank(*ptr))
X {
X *rptr++ = '\''; *rptr++ = *ptr++; *rptr++ = '\'';
X }
X else
X *rptr++ = *ptr++;
X return 0;
X}
X
Xstatic char *bp;
Xstatic int lensb;
X
Xvoid stradd(d) /**/
Xchar *d;
X{
X while (*bp++ = *d++);
X bp--;
X}
X
Xint putstr(d) /**/
Xint d;
X{
X *bp++ = d;
X lensb++; return 0;
X}
X
X#define tstradd(X) \
X if (termok && unset(SINGLELINEZLE)) { \
X char tbuf[2048],*tptr = tbuf; \
X if (tgetstr(X,&tptr)) \
X tputs(tbuf,1,putstr); \
X } \
X break
X
X/* get a prompt string */
X
Xchar *putprompt(fm,lenp) /**/
Xchar *fm;int *lenp;
X{
Xchar *ss,*ttyname DCLPROTO((int)),*bl0;
Xstatic char buf1[256],buf2[256],*buf;
Xint t0;
Xstruct tm *tm = NULL;
Xtime_t timet;
X
X lensb = 0;
X if (!fm)
X {
X *lenp = 0;
X return "";
X }
X /* kludge alert! */
X buf = (buf == buf1) ? buf2 : buf1;
X bp = bl0 = buf;
X clearerr(stdin);
X for(;*fm;fm++)
X {
X if (bp-buf >= 220)
X break;
X if (*fm == '%')
X switch (*++fm)
X {
X case '~':
X t0 = finddir(cwd);
X if (t0 != -1)
X {
X *bp++ = '~';
X stradd(usernames[t0]);
X stradd(cwd+strlen(userdirs[t0]));
X break;
X }
X if (!strncmp(cwd,home,t0 = strlen(home)))
X {
X *bp++ = '~';
X stradd(cwd+t0);
X break;
X }
X case 'd': case '/': stradd(cwd); break;
X case 'c': case '.':
X for (ss = cwd+strlen(cwd); ss > cwd; ss--)
X if (*ss == '/')
X {
X ss++;
X break;
X }
X stradd(ss);
X break;
X case 'h': case '!':
X sprintf(bp,"%d",curhist);
X bp += strlen(bp);
X break;
X case 'M': stradd(hostM); break;
X case 'm': stradd(hostm); break;
X case 'S': tstradd("so"); /* <- this is a macro */
X case 's': tstradd("se");
X case 'B': tstradd("md");
X case 'b': tstradd("me");
X case 'U': tstradd("us");
X case 'u': tstradd("ue");
X case 't': case '@':
X timet = time(NULL);
X tm = localtime(&timet);
X ztrftime(bp,16,"%l:%M%p",tm);
X if (*bp == ' ')
X chuck(bp);
X bp += strlen(bp);
X break;
X case 'T':
X timet = time(NULL);
X tm = localtime(&timet);
X ztrftime(bp,16,"%k:%M",tm);
X bp += strlen(bp);
X break;
X case '*':
X timet = time(NULL);
X tm = localtime(&timet);
X ztrftime(bp,16,"%k:%M:%S",tm);
X bp += strlen(bp);
X break;
X case 'n': stradd(username); break;
X case 'w':
X timet = time(NULL);
X tm = localtime(&timet);
X ztrftime(bp,16,"%a %e",tm);
X bp += strlen(bp);
X break;
X case 'W':
X timet = time(NULL);
X tm = localtime(&timet);
X ztrftime(bp,16,"%m/%d/%y",tm);
X bp += strlen(bp);
X break;
X case 'D':
X timet = time(NULL);
X tm = localtime(&timet);
X ztrftime(bp,16,"%y-%m-%d",tm);
X bp += strlen(bp);
X break;
X case 'l':
X if (ss = ttyname(SHTTY))
X stradd((strncmp(ss,"/dev/tty",8) ? ss : ss+8));
X else
X stradd("()");
X break;
X case '?':
X sprintf(bp,"%d",lastval);
X bp += strlen(bp);
X break;
X case '%': *bp++ = '%'; break;
X case '#': *bp++ = (geteuid()) ? '%' : '#'; break;
X default: *bp++ = '%'; *bp++ = *fm; break;
X }
X else if (*fm == '!')
X {
X sprintf(bp,"%d",curhist);
X bp += strlen(bp);
X }
X else
X if ((*bp++ = *fm) == '\n')
X bl0 = bp;
X }
X *lenp = (bp-bl0)-lensb;
X if (columns)
X *lenp %= columns;
X if (*lenp == columns-1)
X {
X *lenp = 0;
X *bp++ = ' ';
X }
X *bp = '\0';
X return buf;
X}
X
Xvoid herrflush() /**/
X{
X if (strin)
X hflush();
X else while (lastc != '\n' && lastc != HERR)
X hgetch();
X}
X
X/* read an arbitrary amount of data into a buffer until stop is found */
X
Xchar *hdynread(stop) /**/
Xint stop;
X{
Xint bsiz = 256,ct = 0,c;
Xchar *buf = zalloc(bsiz),*ptr;
X
X ptr = buf;
X while ((c = hgetch()) != stop && c != '\n' && c != EOF && c != HERR)
X {
X if (c == '\\')
X c = hgetch();
X *ptr++ = c;
X if (++ct == bsiz)
X {
X buf = realloc(buf,bsiz *= 2);
X ptr = buf+ct;
X }
X }
X *ptr = 0;
X if (c == '\n')
X {
X hungetch('\n');
X zerr("delimiter expected",NULL,0);
X free(buf);
X return NULL;
X }
X return buf;
X}
X
Xchar *hdynread2(stop) /**/
Xint stop;
X{
Xint bsiz = 256,ct = 0,c;
Xchar *buf = zalloc(bsiz),*ptr;
X
X ptr = buf;
X while ((c = hgetch()) != stop && c != '\n' && c != EOF && c != HERR)
X {
X if (c == '\n')
X {
X hungetch(c);
X break;
X }
X if (c == '\\')
X c = hgetch();
X *ptr++ = c;
X if (++ct == bsiz)
X {
X buf = realloc(buf,bsiz *= 2);
X ptr = buf+ct;
X }
X }
X *ptr = 0;
X if (c == '\n')
X hungetch('\n');
X return buf;
X}
X
X/* set cbreak mode, or the equivalent */
X
Xvoid setcbreak() /**/
X{
Xstruct ttyinfo ti;
X
X ti = shttyinfo;
X#ifdef TERMIOS
X ti.termios.c_lflag &= ~ICANON;
X ti.termios.c_cc[VMIN] = 1;
X ti.termios.c_cc[VTIME] = 0;
X#else
X#ifdef TERMIO
X ti.termio.c_lflag &= ~ICANON;
X ti.termio.c_cc[VMIN] = 1;
X ti.termio.c_cc[VTIME] = 0;
X#else
X ti.sgttyb.sg_flags |= CBREAK;
X#endif
X#endif
X settyinfo(&ti);
X}
X
Xint getlineleng() /**/
X{
Xint z;
X
X z = shttyinfo.winsize.ws_col;
X return (z) ? z : 80;
X}
X
Xvoid unsetcbreak() /**/
X{
X settyinfo(&shttyinfo);
X}
X
X/* give the tty to some process */
X
Xvoid attachtty(pgrp) /**/
Xlong pgrp;
X{
Xstatic int ep = 0;
Xint arg = pgrp;
X
X if (jobbing)
X#ifdef TCSETPGRP
X if (SHTTY != -1 && tcsetpgrp(SHTTY,pgrp) == -1 && !ep)
X#else
X if (SHTTY != -1 && ioctl(SHTTY,TIOCSPGRP,&arg) == -1 && !ep)
X#endif
X {
X zerr("can't set tty pgrp: %e",NULL,errno);
X fflush(stderr);
X opts[MONITOR] = OPT_UNSET;
X ep =1;
X errflag = 0;
X }
X}
X
SHAR_EOF
chmod 0644 zsh2.00/src/hist.c ||
echo 'restore of zsh2.00/src/hist.c failed'
Wc_c="`wc -c < 'zsh2.00/src/hist.c'`"
test 23645 -eq "$Wc_c" ||
echo 'zsh2.00/src/hist.c: original size 23645, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/hist.pro ==============
if test -f 'zsh2.00/src/hist.pro' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/hist.pro (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/hist.pro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/hist.pro' &&
Xvoid hwaddc DCLPROTO((int c));
Xint hgetc DCLPROTO((void));
Xint hgetch DCLPROTO((void));
Xvoid hungets DCLPROTO((char *str));
Xvoid hungetc DCLPROTO((int c));
Xvoid hungetch DCLPROTO((int c));
Xvoid strinbeg DCLPROTO((void));
Xvoid strinend DCLPROTO((void));
Xint stuff DCLPROTO((char *fn));
Xvoid hflush DCLPROTO((void));
Xvoid hbegin DCLPROTO((void));
Xvoid inittty DCLPROTO((void));
Xint hend DCLPROTO((void));
Xvoid remhist DCLPROTO((void));
Xvoid hwbegin DCLPROTO((void));
Xchar *hwadd DCLPROTO((void));
Xint getargspec DCLPROTO((int argc,int marg));
Xint hconsearch DCLPROTO((char *str,int *marg));
Xint hcomsearch DCLPROTO((char *str));
Xint remtpath DCLPROTO((char **junkptr));
Xint remtext DCLPROTO((char **junkptr));
Xint rembutext DCLPROTO((char **junkptr));
Xint remlpaths DCLPROTO((char **junkptr));
Xint makeuppercase DCLPROTO((char **junkptr));
Xint makelowercase DCLPROTO((char **junkptr));
Xint subst DCLPROTO((char **strptr,char *in,char *out,int gbal));
Xchar *convamps DCLPROTO((char *out,char *in));
Xchar *makehstr DCLPROTO((char *s));
Xchar *quietgetevent DCLPROTO((int ev));
Xchar *getevent DCLPROTO((int ev));
Xint getargc DCLPROTO((char *list));
Xchar *getargs DCLPROTO((char *elist,int arg1,int arg2));
Xvoid upcase DCLPROTO((char **x));
Xvoid downcase DCLPROTO((char **x));
Xint quote DCLPROTO((char **tr));
Xint quotebreak DCLPROTO((char **tr));
Xvoid stradd DCLPROTO((char *d));
Xint putstr DCLPROTO((int d));
Xchar *putprompt DCLPROTO((char *fm,int *lenp));
Xvoid herrflush DCLPROTO((void));
Xchar *hdynread DCLPROTO((int stop));
Xchar *hdynread2 DCLPROTO((int stop));
Xvoid setcbreak DCLPROTO((void));
Xint getlineleng DCLPROTO((void));
Xvoid unsetcbreak DCLPROTO((void));
Xvoid attachtty DCLPROTO((long pgrp));
SHAR_EOF
chmod 0644 zsh2.00/src/hist.pro ||
echo 'restore of zsh2.00/src/hist.pro failed'
Wc_c="`wc -c < 'zsh2.00/src/hist.pro'`"
test 1700 -eq "$Wc_c" ||
echo 'zsh2.00/src/hist.pro: original size 1700, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= zsh2.00/src/init.c ==============
if test -f 'zsh2.00/src/init.c' -a X"$1" != X"-c"; then
echo 'x - skipping zsh2.00/src/init.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting zsh2.00/src/init.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'zsh2.00/src/init.c' &&
X/*
X
X init.c - main loop and initialization routines
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 GLOBALS
X#include "zsh.h"
X#include "funcs.h"
X#include <pwd.h>
X
Xextern int yydebug;
X
Xvoid main(argc,argv,envp) /**/
Xint argc; char **argv; char **envp;
X{
Xint notect = 0;
X
X environ = envp;
X pathsuppress = 1;
X meminit();
X setflags();
X parseargs(argv);
X setmoreflags();
X setupvals();
X initialize();
X heapalloc();
X runscripts();
X if (interact)
X {
X pathsuppress = 0;
X newcmdnamtab();
X }
X for(;;)
X {
X do
X loop();
X while (!eofseen);
X if (!(isset(IGNOREEOF) && interact))
X {
X#if 0
X if (interact)
X fputs(islogin ? "logout\n" : "exit\n",stderr);
X#endif
X zexit(NULL);
X continue;
X }
X zerrnam("\nzsh",(!islogin) ? "use 'exit' to exit."
X : "use 'logout' to logout.",NULL,0);
X notect++;
X if (notect == 10)
X zexit(NULL);
X }
X}
X
X/* keep executing lists until EOF found */
X
Xvoid loop() /**/
X{
XList list;
X
X pushheap();
X for(;;)
X {
X freeheap();
X if (interact && isset(SHINSTDIN))
X preprompt();
X hbegin(); /* init history mech */
SHAR_EOF
true || echo 'restore of zsh2.00/src/init.c failed'
fi
echo 'End of zsh2.00.00 part 6'
echo 'File zsh2.00/src/init.c is continued in part 7'
echo 7 > _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