1*a4c2757aSmarc /*
2*a4c2757aSmarc
3*a4c2757aSmarc * Copyright (c) 1984, 1985, 1986 AT&T
4*a4c2757aSmarc * All Rights Reserved
5*a4c2757aSmarc
6*a4c2757aSmarc * THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*a4c2757aSmarc * CODE OF AT&T.
8*a4c2757aSmarc * The copyright notice above does not
9*a4c2757aSmarc * evidence any actual or intended
10*a4c2757aSmarc * publication of such source code.
11*a4c2757aSmarc
12*a4c2757aSmarc */
13*a4c2757aSmarc /* @(#)gmatch.c 1.1 */
14*a4c2757aSmarc
15*a4c2757aSmarc /*
16*a4c2757aSmarc * gmatch - match Shell expression patterns
17*a4c2757aSmarc *
18*a4c2757aSmarc * David Korn
19*a4c2757aSmarc * AT&T Bell Laboratories
20*a4c2757aSmarc * Room 5D-112
21*a4c2757aSmarc * Murray Hill, N. J. 07974
22*a4c2757aSmarc * Tel. x7975
23*a4c2757aSmarc *
24*a4c2757aSmarc * Derived from Bourne Shell
25*a4c2757aSmarc */
26*a4c2757aSmarc
27*a4c2757aSmarc /*
28*a4c2757aSmarc * gmatch compares the string s with the shell pattern p.
29*a4c2757aSmarc * returns 1 for match, 0 otherwise.
30*a4c2757aSmarc * The ESCAPE character is used to remove special meaning in pattern only.
31*a4c2757aSmarc */
32*a4c2757aSmarc
33*a4c2757aSmarc #define ESCAPE '\\'
34*a4c2757aSmarc
35*a4c2757aSmarc #ifdef MULTIBYTE
36*a4c2757aSmarc # include "national.h"
37*a4c2757aSmarc # define C_MASK (3<<(7*ESS_MAXCHAR)) /* character classes */
38*a4c2757aSmarc # define peekchar(x) (_save=x,_c=getchar(x),x=_save,_c)
39*a4c2757aSmarc # define getchar(x) ja_getchar((unsigned char**)(&(x)))
40*a4c2757aSmarc int ja_getchar();
41*a4c2757aSmarc static char *_save;
42*a4c2757aSmarc static int _c;
43*a4c2757aSmarc #else
44*a4c2757aSmarc # define getchar(x) (*x++)
45*a4c2757aSmarc # define peekchar(x) (*x)
46*a4c2757aSmarc #endif /* MULTIBYTE */
47*a4c2757aSmarc
gmatch(s,p)48*a4c2757aSmarc gmatch(s, p)
49*a4c2757aSmarc #ifdef MULTIBYTE
50*a4c2757aSmarc char *p;
51*a4c2757aSmarc #else
52*a4c2757aSmarc register char *p;
53*a4c2757aSmarc #endif /* MULTIBYTE */
54*a4c2757aSmarc char *s;
55*a4c2757aSmarc {
56*a4c2757aSmarc register int scc,c;
57*a4c2757aSmarc register int d;
58*a4c2757aSmarc char *olds;
59*a4c2757aSmarc while((olds=s,scc = getchar(s)))
60*a4c2757aSmarc {
61*a4c2757aSmarc switch(c = getchar(p))
62*a4c2757aSmarc {
63*a4c2757aSmarc case '[':
64*a4c2757aSmarc {
65*a4c2757aSmarc char ok = 0;
66*a4c2757aSmarc int lc = -1;
67*a4c2757aSmarc int notflag=0;
68*a4c2757aSmarc if(*p == '!' )
69*a4c2757aSmarc {
70*a4c2757aSmarc notflag=1;
71*a4c2757aSmarc p++;
72*a4c2757aSmarc }
73*a4c2757aSmarc while(c = getchar(p))
74*a4c2757aSmarc {
75*a4c2757aSmarc if(c==']' && lc>=0)
76*a4c2757aSmarc return(ok?gmatch(s,p):0);
77*a4c2757aSmarc else if(c=='-' && lc>=0 && *p!=']')
78*a4c2757aSmarc /*character range */
79*a4c2757aSmarc {
80*a4c2757aSmarc c = getchar(p);
81*a4c2757aSmarc #ifdef MULTIBYTE
82*a4c2757aSmarc /* must be in same char set */
83*a4c2757aSmarc if((c&C_MASK) != (lc&C_MASK))
84*a4c2757aSmarc {
85*a4c2757aSmarc int match;
86*a4c2757aSmarc match = (scc==c||scc==lc);
87*a4c2757aSmarc if(notflag)
88*a4c2757aSmarc {
89*a4c2757aSmarc if(!match)
90*a4c2757aSmarc ok++;
91*a4c2757aSmarc else
92*a4c2757aSmarc return(0);
93*a4c2757aSmarc }
94*a4c2757aSmarc else
95*a4c2757aSmarc {
96*a4c2757aSmarc if(match)
97*a4c2757aSmarc ok++;
98*a4c2757aSmarc }
99*a4c2757aSmarc lc = c;
100*a4c2757aSmarc }
101*a4c2757aSmarc #endif /* MULTIBYTE */
102*a4c2757aSmarc if(notflag)
103*a4c2757aSmarc {
104*a4c2757aSmarc if(lc>scc || scc>c)
105*a4c2757aSmarc ok++;
106*a4c2757aSmarc else
107*a4c2757aSmarc return(0);
108*a4c2757aSmarc }
109*a4c2757aSmarc else
110*a4c2757aSmarc if(lc<scc && scc<=c)
111*a4c2757aSmarc ok++;
112*a4c2757aSmarc }
113*a4c2757aSmarc else
114*a4c2757aSmarc {
115*a4c2757aSmarc if(c == ESCAPE)
116*a4c2757aSmarc c = *p++;
117*a4c2757aSmarc if(notflag)
118*a4c2757aSmarc {
119*a4c2757aSmarc if(scc!=c)
120*a4c2757aSmarc ok++;
121*a4c2757aSmarc else
122*a4c2757aSmarc return(0);
123*a4c2757aSmarc }
124*a4c2757aSmarc else
125*a4c2757aSmarc {
126*a4c2757aSmarc if(scc==c)
127*a4c2757aSmarc ok++;
128*a4c2757aSmarc }
129*a4c2757aSmarc lc = c;
130*a4c2757aSmarc }
131*a4c2757aSmarc }
132*a4c2757aSmarc return(0);
133*a4c2757aSmarc }
134*a4c2757aSmarc case '\\':
135*a4c2757aSmarc c = getchar(p); /* need exact match */
136*a4c2757aSmarc default:
137*a4c2757aSmarc if(c != scc)
138*a4c2757aSmarc return(0);
139*a4c2757aSmarc case '?':
140*a4c2757aSmarc break;
141*a4c2757aSmarc case '*':
142*a4c2757aSmarc /* several asterisks are the same as one */
143*a4c2757aSmarc while(*p=='*' )
144*a4c2757aSmarc p++;
145*a4c2757aSmarc if(*p==0)
146*a4c2757aSmarc return(1);
147*a4c2757aSmarc d = scc;
148*a4c2757aSmarc c = peekchar(p);
149*a4c2757aSmarc scc = (c!='?' && c !='[');
150*a4c2757aSmarc if(c==ESCAPE)
151*a4c2757aSmarc c = *(p+1);
152*a4c2757aSmarc while(d)
153*a4c2757aSmarc {
154*a4c2757aSmarc if(scc && c != d)
155*a4c2757aSmarc ;
156*a4c2757aSmarc else if(gmatch(olds,p))
157*a4c2757aSmarc return(1);
158*a4c2757aSmarc olds = s;
159*a4c2757aSmarc d = getchar(s);
160*a4c2757aSmarc
161*a4c2757aSmarc }
162*a4c2757aSmarc return(0);
163*a4c2757aSmarc
164*a4c2757aSmarc case 0:
165*a4c2757aSmarc return(scc==0);
166*a4c2757aSmarc }
167*a4c2757aSmarc }
168*a4c2757aSmarc while(*p == '*')
169*a4c2757aSmarc p++;
170*a4c2757aSmarc return(*p==0);
171*a4c2757aSmarc }
172*a4c2757aSmarc
173*a4c2757aSmarc #ifdef MULTIBYTE
174*a4c2757aSmarc
175*a4c2757aSmarc /*
176*a4c2757aSmarc * This character read from one to three bytes and returns a character
177*a4c2757aSmarc * The character set designation is in the bits defined by C_MASK
178*a4c2757aSmarc */
179*a4c2757aSmarc
ja_getchar(address)180*a4c2757aSmarc int ja_getchar(address)
181*a4c2757aSmarc unsigned char **address;
182*a4c2757aSmarc {
183*a4c2757aSmarc register unsigned char *cp = *(unsigned char**)address;
184*a4c2757aSmarc register int c = *cp++;
185*a4c2757aSmarc register int size;
186*a4c2757aSmarc int d;
187*a4c2757aSmarc if(size = echarset(c))
188*a4c2757aSmarc {
189*a4c2757aSmarc d = (size==1?c:0);
190*a4c2757aSmarc c = size;
191*a4c2757aSmarc size = in_csize(c);
192*a4c2757aSmarc c <<= 7*(ESS_MAXCHAR-size);
193*a4c2757aSmarc if(d)
194*a4c2757aSmarc {
195*a4c2757aSmarc size--;
196*a4c2757aSmarc c = (c<<7) | (d&~HIGHBIT);
197*a4c2757aSmarc }
198*a4c2757aSmarc while(size-- >0)
199*a4c2757aSmarc c = (c<<7) | ((*cp++)&~HIGHBIT);
200*a4c2757aSmarc }
201*a4c2757aSmarc *address = cp;
202*a4c2757aSmarc return(c);
203*a4c2757aSmarc }
204*a4c2757aSmarc #endif /*MULTIBYTE*/
205