From c62d0dbc47b1bc0df4274c7241b3ae17cb974d0e Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sat, 8 May 1982 02:37:29 -0800 Subject: [PATCH] date and time created 82/05/07 19:37:29 by mckusick SCCS-vsn: old/sh/expand.c 4.1 --- usr/src/old/sh/expand.c | 191 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 usr/src/old/sh/expand.c diff --git a/usr/src/old/sh/expand.c b/usr/src/old/sh/expand.c new file mode 100644 index 0000000000..2f791f05c1 --- /dev/null +++ b/usr/src/old/sh/expand.c @@ -0,0 +1,191 @@ +/* expand.c 4.1 82/05/07 */ + +# +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include +#include +#include + + + +/* globals (file name generation) + * + * "*" in params matches r.e ".*" + * "?" in params matches r.e. "." + * "[...]" in params matches character class + * "[...a-z...]" in params matches a through z. + * + */ + +PROC VOID addg(); + + +INT expand(as,rflg) + STRING as; +{ + INT count; + DIR *dirf; + BOOL dir=0; + STRING rescan = 0; + REG STRING s, cs; + ARGPTR schain = gchain; + struct direct *dp; + STATBUF statb; + + IF trapnote&SIGSET THEN return(0); FI + + s=cs=as; + + /* check for meta chars */ + BEGIN + REG BOOL slash; slash=0; + WHILE !fngchar(*cs) + DO IF *cs++==0 + THEN IF rflg ANDF slash THEN break; ELSE return(0) FI + ELIF *cs=='/' + THEN slash++; + FI + OD + END + + LOOP IF cs==s + THEN s=nullstr; + break; + ELIF *--cs == '/' + THEN *cs=0; + IF s==cs THEN s="/" FI + break; + FI + POOL + IF stat(s,&statb)>=0 + ANDF (statb.st_mode&S_IFMT)==S_IFDIR + ANDF (dirf=opendir(s))>0 + THEN dir++; + FI + count=0; + IF *cs==0 THEN *cs++=0200 FI + IF dir + THEN /* check for rescan */ + REG STRING rs; rs=cs; + + REP IF *rs=='/' THEN rescan=rs; *rs=0; gchain=0 FI + PER *rs++ DONE + + WHILE (dp = readdir(dirf)) != NULL ANDF (trapnote&SIGSET) == 0 + DO IF (*dp->d_name=='.' ANDF *cs!='.') + THEN continue; + FI + IF gmatch(dp->d_name, cs) + THEN addg(s,dp->d_name,rescan); count++; + FI + OD + closedir(dirf); + + IF rescan + THEN REG ARGPTR rchain; + rchain=gchain; gchain=schain; + IF count + THEN count=0; + WHILE rchain + DO count += expand(rchain->argval,1); + rchain=rchain->argnxt; + OD + FI + *rescan='/'; + FI + FI + + BEGIN + REG CHAR c; + s=as; + WHILE c = *s + DO *s++=(c&STRIP?c:'/') OD + END + return(count); +} + +gmatch(s, p) + REG STRING s, p; +{ + REG INT scc; + CHAR c; + + IF scc = *s++ + THEN IF (scc &= STRIP)==0 + THEN scc=0200; + FI + FI + SWITCH c = *p++ IN + + case '[': + {BOOL ok; INT lc; + ok=0; lc=077777; + WHILE c = *p++ + DO IF c==']' + THEN return(ok?gmatch(s,p):0); + ELIF c==MINUS + THEN IF lc<=scc ANDF scc<=(*p++) THEN ok++ FI + ELSE IF scc==(lc=(c&STRIP)) THEN ok++ FI + FI + OD + return(0); + } + + default: + IF (c&STRIP)!=scc THEN return(0) FI + + case '?': + return(scc?gmatch(s,p):0); + + case '*': + IF *p==0 THEN return(1) FI + --s; + WHILE *s + DO IF gmatch(s++,p) THEN return(1) FI OD + return(0); + + case 0: + return(scc==0); + ENDSW +} + +LOCAL VOID addg(as1,as2,as3) + STRING as1, as2, as3; +{ + REG STRING s1, s2; + REG INT c; + + s2 = locstak()+BYTESPERWORD; + + s1=as1; + WHILE c = *s1++ + DO IF (c &= STRIP)==0 + THEN *s2++='/'; + break; + FI + *s2++=c; + OD + s1=as2; + WHILE *s2 = *s1++ DO s2++ OD + IF s1=as3 + THEN *s2++='/'; + WHILE *s2++ = *++s1 DONE + FI + makearg(endstak(s2)); +} + +makearg(args) + REG STRING args; +{ + args->argnxt=gchain; + gchain=args; +} + -- 2.20.1