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 }