1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 /*
32 * Copyright (c) 2018, Joyent, Inc.
33 */
34
35 #include <sys/types.h>
36 #include <stdlib.h>
37 #include "utility.h"
38
39 /* this code was taken from regcmp(3C) */
40
41 #define SSIZE 16
42 #define TGRP 48
43 #define A256 02
44 #define ZERO 01
45 #define NBRA 10
46 #define CIRCFL 32;
47 #define SLOP 5
48 #define FEOF 0 /* This was originally EOF but it clashes with the header */
49 /* definition so it was changed to FEOF */
50
51 #define CBRA 60
52 #define GRP 40
53 #define SGRP 56
54 #define PGRP 68
55 #define EGRP 44
56 #define RNGE 03
57 #define CCHR 20
58 #define CDOT 64
59 #define CCL 24
60 #define NCCL 8
61 #define CDOL 28
62 #define FCEOF 52 /* This was originally CEOF but it clashes with the header */
63 /* definition so it was changed to FCEOF */
64 #define CKET 12
65
66 #define STAR 01
67 #define PLUS 02
68 #define MINUS 16
69
70 intptr_t *__sp_;
71 intptr_t *__stmax;
72 extern int __i_size;
73
74 /*ARGSUSED2*/
75 char *
libform_regcmp(char * cs1,char * cs2)76 libform_regcmp(char *cs1, char *cs2)
77 {
78 char c;
79 char *ep, *sp;
80 int *adx;
81 int i, cflg;
82 char *lastep, *sep, *eptr;
83 int nbra, ngrp;
84 int cclcnt;
85 intptr_t stack[SSIZE];
86
87 __sp_ = stack;
88 *__sp_ = -1;
89 __stmax = &stack[SSIZE];
90
91 adx = (int *)&cs1;
92 i = nbra = ngrp = 0;
93 while (*adx)
94 i += __size((char *)(intptr_t)*adx++);
95 adx = (int *)&cs1;
96 sp = (char *)(intptr_t)*adx++;
97 if ((sep = ep = malloc((unsigned)(2 * i + SLOP))) == NULL)
98 return (NULL);
99 if ((c = *sp++) == FEOF)
100 goto cerror;
101 if (c == '^') {
102 c = *sp++;
103 *ep++ = CIRCFL;
104 }
105 if ((c == '*') || (c == '+') || (c == '{'))
106 goto cerror;
107 sp--;
108 for (;;) {
109 if ((c = *sp++) == FEOF) {
110 if (*adx) {
111 sp = (char *)(intptr_t)*adx++;
112 continue;
113 }
114 *ep++ = FCEOF;
115 if (--nbra > NBRA || *__sp_ != -1)
116 goto cerror;
117 __i_size = (int)(ep - sep);
118 return (sep);
119 }
120 if ((c != '*') && (c != '{') && (c != '+'))
121 lastep = ep;
122 switch (c) {
123
124 case '(':
125 if (!__rpush(ep)) goto cerror;
126 *ep++ = CBRA;
127 *ep++ = -1;
128 continue;
129 case ')':
130 if (!(eptr = (char *)__rpop())) goto cerror;
131 if ((c = *sp++) == '$') {
132 if ('0' > (c = *sp++) || c > '9')
133 goto cerror;
134 *ep++ = CKET;
135 *ep++ = *++eptr = nbra++;
136 *ep++ = (c-'0');
137 continue;
138 }
139 *ep++ = EGRP;
140 *ep++ = ngrp++;
141 sp--;
142 switch (c) {
143 case '+':
144 *eptr = PGRP;
145 break;
146 case '*':
147 *eptr = SGRP;
148 break;
149 case '{':
150 *eptr = TGRP;
151 break;
152 default:
153 *eptr = GRP;
154 continue;
155 }
156 i = (int)(ep - eptr - 2);
157 for (cclcnt = 0; i >= 256; cclcnt++)
158 i -= 256;
159 if (cclcnt > 3) goto cerror;
160 *eptr |= cclcnt;
161 *++eptr = (char)i;
162 continue;
163
164 case '\\':
165 *ep++ = CCHR;
166 if ((c = *sp++) == FEOF)
167 goto cerror;
168 *ep++ = c;
169 continue;
170
171 case '{':
172 *lastep |= RNGE;
173 cflg = 0;
174 nlim:
175 if ((c = *sp++) == '}') goto cerror;
176 i = 0;
177 do {
178 if ('0' <= c && c <= '9')
179 i = (i*10+(c-'0'));
180 else goto cerror;
181 } while (((c = *sp++) != '}') && (c != ','));
182 if (i > 255) goto cerror;
183 *ep++ = (char)i;
184 if (c == ',') {
185 if (cflg++) goto cerror;
186 if ((c = *sp++) == '}') {
187 *ep++ = -1;
188 continue;
189 } else {
190 sp--;
191 goto nlim;
192 }
193 }
194 if (!cflg)
195 *ep++ = (char)i;
196 else if ((ep[-1]&0377) < (ep[-2]&0377))
197 goto cerror;
198 continue;
199
200 case '.':
201 *ep++ = CDOT;
202 continue;
203
204 case '+':
205 if (*lastep == CBRA || *lastep == CKET)
206 goto cerror;
207 *lastep |= PLUS;
208 continue;
209
210 case '*':
211 if (*lastep == CBRA || *lastep == CKET)
212 goto cerror;
213 *lastep |= STAR;
214 continue;
215
216 case '$':
217 if ((*sp != FEOF) || (*adx))
218 goto defchar;
219 *ep++ = CDOL;
220 continue;
221
222 case '[':
223 *ep++ = CCL;
224 *ep++ = 0;
225 cclcnt = 1;
226 if ((c = *sp++) == '^') {
227 c = *sp++;
228 ep[-2] = NCCL;
229 }
230 do {
231 if (c == FEOF)
232 goto cerror;
233 if ((c == '-') && (cclcnt > 1) &&
234 (*sp != ']')) {
235 *ep = ep[-1];
236 ep++;
237 ep[-2] = MINUS;
238 cclcnt++;
239 continue;
240 }
241 *ep++ = c;
242 cclcnt++;
243 } while ((c = *sp++) != ']');
244 lastep[1] = (char)cclcnt;
245 continue;
246
247 defchar:
248 default:
249 *ep++ = CCHR;
250 *ep++ = c;
251 }
252 }
253 cerror:
254 free(sep);
255 return (0);
256 }
257
258 int
__size(char * strg)259 __size(char *strg)
260 {
261 int i;
262
263 i = 1;
264 while (*strg++)
265 i++;
266 return (i);
267 }
268
269 intptr_t
__rpop(void)270 __rpop(void)
271 {
272 return ((*__sp_ == -1)?0:*__sp_--);
273 }
274
275 int
__rpush(char * ptr)276 __rpush(char *ptr)
277 {
278 if (__sp_ >= __stmax)
279 return (0);
280 *++__sp_ = (intptr_t)ptr;
281 return (1);
282 }
283