freebsd-ports/shells/v7sh/files/patch-expand.c
Pav Lucistnik 6b787b91fc Add v7sh, the original Steve R. Bourne shell from the 7th edition Unix including
System III, 4.3BSD-Reno, Ultrix 3.1 and `home made'' fixes and enhancements

PR:		ports/68127
Submitted by:	Cyrille Lefevre <cyrille.lefevre@laposte.net>
2004-06-22 08:24:19 +00:00

299 lines
5.6 KiB
C

diff -u -x CVS -x work -x core -x *.core -x #* -x *~ -x *.orig -x *.rej -I $Id.*$ -I $.+BSD.*$ expand.c.orig expand.c
--- expand.c.orig Fri Jun 4 02:51:01 2004
+++ expand.c Sat Jun 19 18:42:22 2004
@@ -8,10 +8,6 @@
*/
#include "defs.h"
-#include <sys/types.h>
-#define DIRSIZ 15
-#include <sys/stat.h>
-#include <sys/dir.h>
@@ -24,52 +20,98 @@
*
*/
-PROC VOID addg();
+LOCAL VOID addg(STRING, STRING, STRING);
+#if defined(SYSIII)
+LOCAL VOID chgquot(STRING, INT);
+#endif
+
+ARGPTR gchain;
INT expand(as,rflg)
STRING as;
+ INT rflg;
{
- INT count, dirf;
+ INT count;
+ DIR *dirf;
BOOL dir=0;
STRING rescan = 0;
REG STRING s, cs;
ARGPTR schain = gchain;
- struct direct entry;
+ DIRPTR dp;
STATBUF statb;
+ CHAR buf[2];
IF trapnote&SIGSET THEN return(0); FI
- s=cs=as; entry.d_name[DIRSIZ-1]=0; /* to end the string */
+ s=cs=as;
/* check for meta chars */
BEGIN
+#if defined(SYSIII)
+#define open open_
+ REG BOOL slash, open; slash=0;open=0;
+ LOOP
+ SWITCH *cs++ IN
+ case 0: IF rflg ANDF slash THEN break;
+ ELSE return(0);
+ FI
+ case '/': slash++;
+ open = 0;
+ continue;
+ case '[': open++;
+ continue;
+ case ']': IF open THEN break FI
+ continue;
+ case '?':
+ case '*': cs--;
+ break;
+ default: continue;
+ ENDSW
+ break;
+ POOL
+#undef open
+#else /* V7 */
REG BOOL slash; slash=0;
- WHILE !fngchar(*cs)
+ WHILE !fngchar((INT) *cs)
DO IF *cs++==0
THEN IF rflg ANDF slash THEN break; ELSE return(0) FI
ELIF *cs=='/'
THEN slash++;
FI
OD
+#endif
END
LOOP IF cs==s
- THEN s=nullstr;
+ THEN movstr(nullstr,s=buf);
break;
ELIF *--cs == '/'
THEN *cs=0;
- IF s==cs THEN s="/" FI
+ IF s==cs THEN movstr("/",s=buf) FI
break;
FI
POOL
+#if defined(SYSIII)
+ chgquot(s, 0);
+ IF stat(*s?s:".",&statb)>=0
+#else /* V7 */
IF stat(s,&statb)>=0
+#endif
ANDF (statb.st_mode&S_IFMT)==S_IFDIR
- ANDF (dirf=open(s,0))>0
+#if defined(SYSIII)
+ ANDF (dirf=opendir(*s?s:".")) != NULL
+#else /* V7 */
+ ANDF (dirf=opendir(s)) != NULL
+#endif
THEN dir++;
+ ELSE dirf=NULL;
FI
+#if defined(SYSIII)
+ chgquot(s, 1);
+#endif
count=0;
- IF *cs==0 THEN *cs++=0200 FI
+ IF *cs==0 THEN *cs++=QUOTE FI
IF dir
THEN /* check for rescan */
REG STRING rs; rs=cs;
@@ -77,16 +119,33 @@
REP IF *rs=='/' THEN rescan=rs; *rs=0; gchain=0 FI
PER *rs++ DONE
- WHILE read(dirf, &entry, 16) == 16 ANDF (trapnote&SIGSET) == 0
- DO IF entry.d_ino==0 ORF
- (*entry.d_name=='.' ANDF *cs!='.')
+#if defined(RENO)
+ IF setjmp(INTbuf) == 0 THEN trapjmp[INTR] = 1; FI
+ WHILE (trapnote&SIGSET) == 0 ANDF (dp = readdir(dirf)) != NULL
+#else /* V7 */
+ WHILE (dp = readdir(dirf)) != NULL ANDF (trapnote&SIGSET) == 0
+#endif
+ DO IF (*dp->d_name=='.' ANDF *cs!='.')
THEN continue;
FI
- IF gmatch(entry.d_name, cs)
- THEN addg(s,entry.d_name,rescan); count++;
+#if defined(SYSIII)
+/*
+ * Here lies the fix for the "echo * ^H/." problem when
+ * there are files with metacharacters in there names.
+ */
+ chgquot(dp->d_name, 1);
+#endif
+ IF gmatch(dp->d_name, cs)
+ THEN addg(s,dp->d_name,rescan); count++;
FI
+#if defined(SYSIII)
+ chgquot(dp->d_name, 0);
+#endif
OD
- close(dirf);
+ closedir(dirf);
+#if defined(RENO)
+ trapjmp[INTR] = 0;
+#endif
IF rescan
THEN REG ARGPTR rchain;
@@ -103,43 +162,68 @@
FI
BEGIN
- REG CHAR c;
+ REG INT c;
s=as;
- WHILE c = *s
+ WHILE (c = *s)!=0 /* GCC */
DO *s++=(c&STRIP?c:'/') OD
END
return(count);
}
-gmatch(s, p)
+INT gmatch(s, p)
REG STRING s, p;
{
REG INT scc;
- CHAR c;
+ INT c;
- IF scc = *s++
+ IF (scc = *s++)!=0 /* GCC */
THEN IF (scc &= STRIP)==0
- THEN scc=0200;
+ THEN scc=QUOTE;
FI
FI
SWITCH c = *p++ IN
case '[':
- {BOOL ok; INT lc;
+ BEGIN
+ BOOL ok; INT lc;
+#if defined(SYSIII)
+ INT notflag=0;
+#endif
ok=0; lc=077777;
- WHILE c = *p++
+#if defined(SYSIII)
+ IF *p == '!' ORF *p == '^' THEN notflag=1; p++; FI
+#endif
+ WHILE (c = *p++)!=0 /* GCC */
DO IF c==']'
THEN return(ok?gmatch(s,p):0);
ELIF c==MINUS
+#if defined(SYSIII)
+ THEN IF notflag
+ THEN IF lc>scc ORF scc>*(p++)
+ THEN ok++;
+ ELSE return(0)
+ FI
+ ELSE IF lc<=scc ANDF scc<=(*p++) THEN ok++ FI
+ FI
+ ELSE IF notflag
+ THEN IF scc!=(lc=(c&STRIP))
+ THEN ok++;
+ ELSE return(0)
+ FI
+ ELSE IF scc==(lc=(c&STRIP)) THEN ok++ FI
+ FI
+#else /* V7 */
THEN IF lc<=scc ANDF scc<=(*p++) THEN ok++ FI
ELSE IF scc==(lc=(c&STRIP)) THEN ok++ FI
+#endif
FI
OD
return(0);
- }
+ END
default:
IF (c&STRIP)!=scc THEN return(0) FI
+ /*FALLTHROUGH*/
case '?':
return(scc?gmatch(s,p):0);
@@ -165,7 +249,7 @@
s2 = locstak()+BYTESPERWORD;
s1=as1;
- WHILE c = *s1++
+ WHILE (c = *s1++)!=0 /* GCC */
DO IF (c &= STRIP)==0
THEN *s2++='/';
break;
@@ -173,18 +257,42 @@
*s2++=c;
OD
s1=as2;
- WHILE *s2 = *s1++ DO s2++ OD
- IF s1=as3
+ WHILE (*s2 = *s1++)!=0 DO s2++ OD /* GCC */
+ IF (s1=as3)!=NIL /* GCC */
THEN *s2++='/';
- WHILE *s2++ = *++s1 DONE
+ WHILE (*s2++ = *++s1)!=0 DONE /* GCC */
FI
- makearg(endstak(s2));
+ makearg((ARGPTR) endstak(s2));
}
-makearg(args)
- REG STRING args;
+VOID makearg(args)
+ REG ARGPTR args;
{
args->argnxt=gchain;
- gchain=args;
+ gchain=(ARGPTR) args;
}
+#if defined(SYSIII)
+LOCAL VOID chgquot(str, flg)
+ REG STRING str;
+ REG INT flg;
+{
+ REG INT i;
+
+ FOR i=0;str[i];i++
+ DO
+ SWITCH str[i] IN
+ case '*':
+ case '?':
+ case '[':
+ case '*'|QUOTE:
+ case '?'|QUOTE:
+ case '['|QUOTE:
+ IF flg==0
+ THEN str[i] &= (~QUOTE);
+ ELSE str[i] |= QUOTE;
+ FI
+ ENDSW
+ OD
+}
+#endif