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