str.c (0da30e9aa76c5df66cd092f30b904824b0594ccc) | str.c (af647767ed8f2ec38251e8185ef0b6adb35529e6) |
---|---|
1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint | 1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint |
35#if 0 |
|
35static char sccsid[] = "@(#)str.c 8.2 (Berkeley) 4/28/95"; | 36static char sccsid[] = "@(#)str.c 8.2 (Berkeley) 4/28/95"; |
37#endif 38static const char rcsid[] = 39 "$Id$"; |
|
36#endif /* not lint */ 37 38#include <sys/cdefs.h> 39#include <sys/types.h> 40 | 40#endif /* not lint */ 41 42#include <sys/cdefs.h> 43#include <sys/types.h> 44 |
41#include <errno.h> | 45#include <ctype.h> 46#include <err.h> |
42#include <stddef.h> 43#include <stdio.h> 44#include <stdlib.h> 45#include <string.h> 46 47#include "extern.h" 48 49static int backslash __P((STR *)); --- 11 unchanged lines hidden (view full) --- 61 register int ch; 62 63 switch (s->state) { 64 case EOS: 65 return (0); 66 case INFINITE: 67 return (1); 68 case NORMAL: | 47#include <stddef.h> 48#include <stdio.h> 49#include <stdlib.h> 50#include <string.h> 51 52#include "extern.h" 53 54static int backslash __P((STR *)); --- 11 unchanged lines hidden (view full) --- 66 register int ch; 67 68 switch (s->state) { 69 case EOS: 70 return (0); 71 case INFINITE: 72 return (1); 73 case NORMAL: |
69 switch (ch = *s->str) { | 74 switch (ch = (u_char)*s->str) { |
70 case '\0': 71 s->state = EOS; 72 return (0); 73 case '\\': 74 s->lastch = backslash(s); 75 break; 76 case '[': 77 if (bracket(s)) --- 60 unchanged lines hidden (view full) --- 138 return (0); 139 s->str += 1; 140 genseq(s); 141 return (1); 142 } 143 /* NOTREACHED */ 144} 145 | 75 case '\0': 76 s->state = EOS; 77 return (0); 78 case '\\': 79 s->lastch = backslash(s); 80 break; 81 case '[': 82 if (bracket(s)) --- 60 unchanged lines hidden (view full) --- 143 return (0); 144 s->str += 1; 145 genseq(s); 146 return (1); 147 } 148 /* NOTREACHED */ 149} 150 |
146int isalnum __P((int)), 147 isalpha __P((int)), 148 isblank __P((int)), 149 isspace __P((int)), 150 iscntrl __P((int)), 151 isdigit __P((int)), 152 isgraph __P((int)), 153 islower __P((int)), 154 isprint __P((int)), 155 ispunct __P((int)), 156 isupper __P((int)), 157 isxdigit __P((int)); 158 | |
159typedef struct { 160 char *name; 161 int (*func) __P((int)); 162 int *set; 163} CLASS; 164 165static CLASS classes[] = { | 151typedef struct { 152 char *name; 153 int (*func) __P((int)); 154 int *set; 155} CLASS; 156 157static CLASS classes[] = { |
158#undef isalnum |
|
166 { "alnum", isalnum, }, | 159 { "alnum", isalnum, }, |
160#undef isalpha |
|
167 { "alpha", isalpha, }, | 161 { "alpha", isalpha, }, |
162#undef isblank |
|
168 { "blank", isblank, }, | 163 { "blank", isblank, }, |
164#undef iscntrl |
|
169 { "cntrl", iscntrl, }, | 165 { "cntrl", iscntrl, }, |
166#undef isdigit |
|
170 { "digit", isdigit, }, | 167 { "digit", isdigit, }, |
168#undef isgraph |
|
171 { "graph", isgraph, }, | 169 { "graph", isgraph, }, |
170#undef islower |
|
172 { "lower", islower, }, | 171 { "lower", islower, }, |
173 { "print", isupper, }, | 172#undef isprint 173 { "print", isprint, }, 174#undef ispunct |
174 { "punct", ispunct, }, | 175 { "punct", ispunct, }, |
176#undef isspace |
|
175 { "space", isspace, }, | 177 { "space", isspace, }, |
178#undef isupper |
|
176 { "upper", isupper, }, | 179 { "upper", isupper, }, |
180#undef isxdigit |
|
177 { "xdigit", isxdigit, }, 178}; 179 180static void 181genclass(s) 182 STR *s; 183{ 184 register int cnt, (*func) __P((int)); 185 CLASS *cp, tmp; 186 int *p; 187 188 tmp.name = s->str; 189 if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) / 190 sizeof(CLASS), sizeof(CLASS), c_class)) == NULL) | 181 { "xdigit", isxdigit, }, 182}; 183 184static void 185genclass(s) 186 STR *s; 187{ 188 register int cnt, (*func) __P((int)); 189 CLASS *cp, tmp; 190 int *p; 191 192 tmp.name = s->str; 193 if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) / 194 sizeof(CLASS), sizeof(CLASS), c_class)) == NULL) |
191 err("unknown class %s", s->str); | 195 errx(1, "unknown class %s", s->str); |
192 193 if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL) | 196 197 if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL) |
194 err("%s", strerror(errno)); | 198 errx(1, "malloc"); |
195 bzero(p, (NCHARS + 1) * sizeof(int)); 196 for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt) 197 if ((func)(cnt)) 198 *p++ = cnt; 199 *p = OOBCH; 200 201 s->cnt = 0; 202 s->state = SET; --- 13 unchanged lines hidden (view full) --- 216 */ 217static void 218genequiv(s) 219 STR *s; 220{ 221 if (*s->str == '\\') { 222 s->equiv[0] = backslash(s); 223 if (*s->str != '=') | 199 bzero(p, (NCHARS + 1) * sizeof(int)); 200 for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt) 201 if ((func)(cnt)) 202 *p++ = cnt; 203 *p = OOBCH; 204 205 s->cnt = 0; 206 s->state = SET; --- 13 unchanged lines hidden (view full) --- 220 */ 221static void 222genequiv(s) 223 STR *s; 224{ 225 if (*s->str == '\\') { 226 s->equiv[0] = backslash(s); 227 if (*s->str != '=') |
224 err("misplaced equivalence equals sign"); | 228 errx(1, "misplaced equivalence equals sign"); |
225 } else { 226 s->equiv[0] = s->str[0]; 227 if (s->str[1] != '=') | 229 } else { 230 s->equiv[0] = s->str[0]; 231 if (s->str[1] != '=') |
228 err("misplaced equivalence equals sign"); | 232 errx(1, "misplaced equivalence equals sign"); |
229 } 230 s->str += 2; 231 s->cnt = 0; 232 s->state = SET; 233 s->set = s->equiv; 234} 235 236static int 237genrange(s) 238 STR *s; 239{ 240 int stopval; 241 char *savestart; 242 243 savestart = s->str; | 233 } 234 s->str += 2; 235 s->cnt = 0; 236 s->state = SET; 237 s->set = s->equiv; 238} 239 240static int 241genrange(s) 242 STR *s; 243{ 244 int stopval; 245 char *savestart; 246 247 savestart = s->str; |
244 stopval = *++s->str == '\\' ? backslash(s) : *s->str++; | 248 stopval = *++s->str == '\\' ? backslash(s) : (u_char)*s->str++; |
245 if (stopval < (u_char)s->lastch) { 246 s->str = savestart; 247 return (0); 248 } 249 s->cnt = stopval - s->lastch + 1; 250 s->state = RANGE; 251 --s->lastch; 252 return (1); 253} 254 255static void 256genseq(s) 257 STR *s; 258{ 259 char *ep; 260 261 if (s->which == STRING1) | 249 if (stopval < (u_char)s->lastch) { 250 s->str = savestart; 251 return (0); 252 } 253 s->cnt = stopval - s->lastch + 1; 254 s->state = RANGE; 255 --s->lastch; 256 return (1); 257} 258 259static void 260genseq(s) 261 STR *s; 262{ 263 char *ep; 264 265 if (s->which == STRING1) |
262 err("sequences only valid in string2"); | 266 errx(1, "sequences only valid in string2"); |
263 264 if (*s->str == '\\') 265 s->lastch = backslash(s); 266 else 267 s->lastch = *s->str++; 268 if (*s->str != '*') | 267 268 if (*s->str == '\\') 269 s->lastch = backslash(s); 270 else 271 s->lastch = *s->str++; 272 if (*s->str != '*') |
269 err("misplaced sequence asterisk"); | 273 errx(1, "misplaced sequence asterisk"); |
270 271 switch (*++s->str) { 272 case '\\': 273 s->cnt = backslash(s); 274 break; 275 case ']': 276 s->cnt = 0; 277 ++s->str; 278 break; 279 default: | 274 275 switch (*++s->str) { 276 case '\\': 277 s->cnt = backslash(s); 278 break; 279 case ']': 280 s->cnt = 0; 281 ++s->str; 282 break; 283 default: |
280 if (isdigit(*s->str)) { | 284 if (isdigit((u_char)*s->str)) { |
281 s->cnt = strtol(s->str, &ep, 0); 282 if (*ep == ']') { 283 s->str = ep + 1; 284 break; 285 } 286 } | 285 s->cnt = strtol(s->str, &ep, 0); 286 if (*ep == ']') { 287 s->str = ep + 1; 288 break; 289 } 290 } |
287 err("illegal sequence count"); | 291 errx(1, "illegal sequence count"); |
288 /* NOTREACHED */ 289 } 290 291 s->state = s->cnt ? SEQUENCE : INFINITE; 292} 293 | 292 /* NOTREACHED */ 293 } 294 295 s->state = s->cnt ? SEQUENCE : INFINITE; 296} 297 |
294/* Use the #defines isXXX() here, DON'T use them above. */ 295#include <ctype.h> 296 | |
297/* 298 * Translate \??? into a character. Up to 3 octal digits, if no digits either 299 * an escape code or a literal character. 300 */ 301static int 302backslash(s) 303 register STR *s; 304{ 305 register int ch, cnt, val; 306 307 for (cnt = val = 0;;) { | 298/* 299 * Translate \??? into a character. Up to 3 octal digits, if no digits either 300 * an escape code or a literal character. 301 */ 302static int 303backslash(s) 304 register STR *s; 305{ 306 register int ch, cnt, val; 307 308 for (cnt = val = 0;;) { |
308 ch = *++s->str; | 309 ch = (u_char)*++s->str; |
309 if (!isascii(ch) || !isdigit(ch)) 310 break; 311 val = val * 8 + ch - '0'; 312 if (++cnt == 3) { 313 ++s->str; 314 break; 315 } 316 } --- 26 unchanged lines hidden --- | 310 if (!isascii(ch) || !isdigit(ch)) 311 break; 312 val = val * 8 + ch - '0'; 313 if (++cnt == 3) { 314 ++s->str; 315 break; 316 } 317 } --- 26 unchanged lines hidden --- |