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 /*LINTLIBRARY*/
36
37 #include <sys/types.h>
38 #include <stdlib.h>
39 #include "utility.h"
40
41 /* this code was taken from REGCMP(3X) */
42
43 #define SSIZE 16
44 #define TGRP 48
45 #define A256 02
46 #define ZERO 01
47 #define NBRA 10
48 #define CIRCFL 32;
49 #define SLOP 5
50 #define FEOF 0 /* This was originally EOF but it clashes with the header */
51 /* definition so it was changed to FEOF */
52
53 #define CBRA 60
54 #define GRP 40
55 #define SGRP 56
56 #define PGRP 68
57 #define EGRP 44
58 #define RNGE 03
59 #define CCHR 20
60 #define CDOT 64
61 #define CCL 24
62 #define NCCL 8
63 #define CDOL 28
64 #define FCEOF 52 /* This was originally CEOF but it clashes with the header */
65 /* definition so it was changed to FCEOF */
66 #define CKET 12
67
68 #define STAR 01
69 #define PLUS 02
70 #define MINUS 16
71
72 intptr_t *__sp_;
73 intptr_t *__stmax;
74 int __i_size;
75
76 /*ARGSUSED2*/
77 char *
78 libform_regcmp(char *cs1, char *cs2)
79 {
80 char c;
81 char *ep, *sp;
82 int *adx;
83 int i, cflg;
84 char *lastep, *sep, *eptr;
85 int nbra, ngrp;
86 int cclcnt;
87 intptr_t stack[SSIZE];
88
89 __sp_ = stack;
90 *__sp_ = -1;
91 __stmax = &stack[SSIZE];
92
93 adx = (int *)&cs1;
94 i = nbra = ngrp = 0;
95 while (*adx)
96 i += __size((char *)(intptr_t)*adx++);
97 adx = (int *)&cs1;
98 sp = (char *)(intptr_t)*adx++;
99 if ((sep = ep = malloc((unsigned)(2 * i + SLOP))) == NULL)
100 return (NULL);
101 if ((c = *sp++) == FEOF)
102 goto cerror;
103 if (c == '^') {
104 c = *sp++;
105 *ep++ = CIRCFL;
106 }
107 if ((c == '*') || (c == '+') || (c == '{'))
108 goto cerror;
109 sp--;
110 for (;;) {
111 if ((c = *sp++) == FEOF) {
112 if (*adx) {
113 sp = (char *)(intptr_t)*adx++;
114 continue;
115 }
116 *ep++ = FCEOF;
117 if (--nbra > NBRA || *__sp_ != -1)
118 goto cerror;
119 __i_size = (int) (ep - sep);
120 return (sep);
121 }
122 if ((c != '*') && (c != '{') && (c != '+'))
123 lastep = ep;
124 switch (c) {
125
126 case '(':
127 if (!__rpush(ep)) goto cerror;
128 *ep++ = CBRA;
129 *ep++ = -1;
130 continue;
131 case ')':
132 if (!(eptr = (char *)__rpop())) goto cerror;
133 if ((c = *sp++) == '$') {
134 if ('0' > (c = *sp++) || c > '9')
135 goto cerror;
136 *ep++ = CKET;
137 *ep++ = *++eptr = nbra++;
138 *ep++ = (c-'0');
139 continue;
140 }
141 *ep++ = EGRP;
142 *ep++ = ngrp++;
143 sp--;
144 switch (c) {
145 case '+':
146 *eptr = PGRP;
147 break;
148 case '*':
149 *eptr = SGRP;
150 break;
151 case '{':
152 *eptr = TGRP;
153 break;
154 default:
155 *eptr = GRP;
156 continue;
157 }
158 i = (int) (ep - eptr - 2);
159 for (cclcnt = 0; i >= 256; cclcnt++)
160 i -= 256;
161 if (cclcnt > 3) goto cerror;
162 *eptr |= cclcnt;
163 *++eptr = (char) i;
164 continue;
165
166 case '\\':
167 *ep++ = CCHR;
168 if ((c = *sp++) == FEOF)
169 goto cerror;
170 *ep++ = c;
171 continue;
172
173 case '{':
174 *lastep |= RNGE;
175 cflg = 0;
176 nlim:
177 if ((c = *sp++) == '}') goto cerror;
178 i = 0;
179 do {
180 if ('0' <= c && c <= '9')
181 i = (i*10+(c-'0'));
182 else goto cerror;
183 } while (((c = *sp++) != '}') && (c != ','));
184 if (i > 255) goto cerror;
185 *ep++ = (char) i;
186 if (c == ',') {
187 if (cflg++) goto cerror;
188 if ((c = *sp++) == '}') {
189 *ep++ = -1;
190 continue;
191 } else {
192 sp--;
193 goto nlim;
194 }
195 }
196 if (!cflg)
197 *ep++ = (char) i;
198 else if ((ep[-1]&0377) < (ep[-2]&0377))
199 goto cerror;
200 continue;
201
202 case '.':
203 *ep++ = CDOT;
204 continue;
205
206 case '+':
207 if (*lastep == CBRA || *lastep == CKET)
208 goto cerror;
209 *lastep |= PLUS;
210 continue;
211
212 case '*':
213 if (*lastep == CBRA || *lastep == CKET)
214 goto cerror;
215 *lastep |= STAR;
216 continue;
217
218 case '$':
219 if ((*sp != FEOF) || (*adx))
220 goto defchar;
221 *ep++ = CDOL;
222 continue;
223
224 case '[':
225 *ep++ = CCL;
226 *ep++ = 0;
227 cclcnt = 1;
228 if ((c = *sp++) == '^') {
229 c = *sp++;
230 ep[-2] = NCCL;
231 }
232 do {
233 if (c == FEOF)
234 goto cerror;
235 if ((c == '-') && (cclcnt > 1) &&
236 (*sp != ']')) {
237 *ep = ep[-1];
238 ep++;
239 ep[-2] = MINUS;
240 cclcnt++;
241 continue;
242 }
243 *ep++ = c;
244 cclcnt++;
245 } while ((c = *sp++) != ']');
246 lastep[1] = (char) cclcnt;
247 continue;
248
249 defchar:
250 default:
251 *ep++ = CCHR;
252 *ep++ = c;
253 }
254 }
255 cerror:
256 free(sep);
257 return (0);
258 }
259
260 int
261 __size(char *strg)
262 {
263 int i;
264
265 i = 1;
266 while (*strg++)
267 i++;
268 return (i);
269 }
270
271 intptr_t
272 __rpop(void)
273 {
274 return ((*__sp_ == -1)?0:*__sp_--);
275 }
276
277 int
278 __rpush(char *ptr)
279 {
280 if (__sp_ >= __stmax)
281 return (0);
282 *++__sp_ = (intptr_t)ptr;
283 return (1);
284 }