heirloom-ed

annotate regexp.h @ 0:1493bea5ac22

Initial version of the standalone heirloom-ed
author markus schnalke <meillo@marmaro.de>
date Mon, 05 Sep 2011 16:31:35 +0200
parents
children
rev   line source
meillo@0 1 /*
meillo@0 2 * Simple Regular Expression functions. Derived from Unix 7th Edition,
meillo@0 3 * /usr/src/cmd/expr.y
meillo@0 4 *
meillo@0 5 * Modified by Gunnar Ritter, Freiburg i. Br., Germany, February 2002.
meillo@0 6 *
meillo@0 7 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
meillo@0 8 *
meillo@0 9 * Redistribution and use in source and binary forms, with or without
meillo@0 10 * modification, are permitted provided that the following conditions
meillo@0 11 * are met:
meillo@0 12 * Redistributions of source code and documentation must retain the
meillo@0 13 * above copyright notice, this list of conditions and the following
meillo@0 14 * disclaimer.
meillo@0 15 * Redistributions in binary form must reproduce the above copyright
meillo@0 16 * notice, this list of conditions and the following disclaimer in the
meillo@0 17 * documentation and/or other materials provided with the distribution.
meillo@0 18 * All advertising materials mentioning features or use of this software
meillo@0 19 * must display the following acknowledgement:
meillo@0 20 * This product includes software developed or owned by Caldera
meillo@0 21 * International, Inc.
meillo@0 22 * Neither the name of Caldera International, Inc. nor the names of
meillo@0 23 * other contributors may be used to endorse or promote products
meillo@0 24 * derived from this software without specific prior written permission.
meillo@0 25 *
meillo@0 26 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
meillo@0 27 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
meillo@0 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
meillo@0 29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
meillo@0 30 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
meillo@0 31 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
meillo@0 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
meillo@0 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
meillo@0 34 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
meillo@0 35 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
meillo@0 36 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
meillo@0 37 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
meillo@0 38 */
meillo@0 39
meillo@0 40 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
meillo@0 41 #define REGEXP_H_USED __attribute__ ((used))
meillo@0 42 #elif defined __GNUC__
meillo@0 43 #define REGEXP_H_USED __attribute__ ((unused))
meillo@0 44 #else
meillo@0 45 #define REGEXP_H_USED
meillo@0 46 #endif
meillo@0 47 static const char regexp_h_sccsid[] REGEXP_H_USED =
meillo@0 48 "@(#)regexp.sl 1.56 (gritter) 5/29/05";
meillo@0 49
meillo@0 50 #if !defined (REGEXP_H_USED_FROM_VI) && !defined (__dietlibc__)
meillo@0 51 #define REGEXP_H_WCHARS
meillo@0 52 #endif
meillo@0 53
meillo@0 54 #define CBRA 2
meillo@0 55 #define CCHR 4
meillo@0 56 #define CDOT 8
meillo@0 57 #define CCL 12
meillo@0 58 /* CLNUM 14 used in sed */
meillo@0 59 /* CEND 16 used in sed */
meillo@0 60 #define CDOL 20
meillo@0 61 #define CCEOF 22
meillo@0 62 #define CKET 24
meillo@0 63 #define CBACK 36
meillo@0 64 #define CNCL 40
meillo@0 65 #define CBRC 44
meillo@0 66 #define CLET 48
meillo@0 67 #define CCH1 52
meillo@0 68 #define CCH2 56
meillo@0 69 #define CCH3 60
meillo@0 70
meillo@0 71 #define STAR 01
meillo@0 72 #define RNGE 03
meillo@0 73 #define REGEXP_H_LEAST 0100
meillo@0 74
meillo@0 75 #ifdef REGEXP_H_WCHARS
meillo@0 76 #define CMB 0200
meillo@0 77 #else /* !REGEXP_H_WCHARS */
meillo@0 78 #define CMB 0
meillo@0 79 #endif /* !REGEXP_H_WCHARS */
meillo@0 80
meillo@0 81 #define NBRA 9
meillo@0 82
meillo@0 83 #define PLACE(c) ep[c >> 3] |= bittab[c & 07]
meillo@0 84 #define ISTHERE(c) (ep[c >> 3] & bittab[c & 07])
meillo@0 85
meillo@0 86 #ifdef REGEXP_H_WCHARS
meillo@0 87 #define REGEXP_H_IS_THERE(ep, c) ((ep)[c >> 3] & bittab[c & 07])
meillo@0 88 #endif
meillo@0 89
meillo@0 90 #include <ctype.h>
meillo@0 91 #include <string.h>
meillo@0 92 #include <limits.h>
meillo@0 93 #ifdef REGEXP_H_WCHARS
meillo@0 94 #include <stdlib.h>
meillo@0 95 #include <wchar.h>
meillo@0 96 #include <wctype.h>
meillo@0 97 #endif /* REGEXP_H_WCHARS */
meillo@0 98
meillo@0 99 #define regexp_h_uletter(c) (isalpha(c) || (c) == '_')
meillo@0 100 #ifdef REGEXP_H_WCHARS
meillo@0 101 #define regexp_h_wuletter(c) (iswalpha(c) || (c) == L'_')
meillo@0 102
meillo@0 103 /*
meillo@0 104 * Used to allocate memory for the multibyte star algorithm.
meillo@0 105 */
meillo@0 106 #ifndef regexp_h_malloc
meillo@0 107 #define regexp_h_malloc(n) malloc(n)
meillo@0 108 #endif
meillo@0 109 #ifndef regexp_h_free
meillo@0 110 #define regexp_h_free(p) free(p)
meillo@0 111 #endif
meillo@0 112
meillo@0 113 /*
meillo@0 114 * Can be predefined to 'inline' to inline some multibyte functions;
meillo@0 115 * may improve performance for files that contain many multibyte
meillo@0 116 * sequences.
meillo@0 117 */
meillo@0 118 #ifndef regexp_h_inline
meillo@0 119 #define regexp_h_inline
meillo@0 120 #endif
meillo@0 121
meillo@0 122 /*
meillo@0 123 * Mask to determine whether the first byte of a sequence possibly
meillo@0 124 * starts a multibyte character. Set to 0377 to force mbtowc() for
meillo@0 125 * any byte sequence (except 0).
meillo@0 126 */
meillo@0 127 #ifndef REGEXP_H_MASK
meillo@0 128 #define REGEXP_H_MASK 0200
meillo@0 129 #endif
meillo@0 130 #endif /* REGEXP_H_WCHARS */
meillo@0 131
meillo@0 132 /*
meillo@0 133 * For regexpr.h.
meillo@0 134 */
meillo@0 135 #ifndef regexp_h_static
meillo@0 136 #define regexp_h_static
meillo@0 137 #endif
meillo@0 138 #ifndef REGEXP_H_STEP_INIT
meillo@0 139 #define REGEXP_H_STEP_INIT
meillo@0 140 #endif
meillo@0 141 #ifndef REGEXP_H_ADVANCE_INIT
meillo@0 142 #define REGEXP_H_ADVANCE_INIT
meillo@0 143 #endif
meillo@0 144
meillo@0 145 char *braslist[NBRA];
meillo@0 146 char *braelist[NBRA];
meillo@0 147 int nbra;
meillo@0 148 char *loc1, *loc2, *locs;
meillo@0 149 int sed;
meillo@0 150 int nodelim;
meillo@0 151
meillo@0 152 regexp_h_static int circf;
meillo@0 153 regexp_h_static int low;
meillo@0 154 regexp_h_static int size;
meillo@0 155
meillo@0 156 regexp_h_static unsigned char bittab[] = {
meillo@0 157 1,
meillo@0 158 2,
meillo@0 159 4,
meillo@0 160 8,
meillo@0 161 16,
meillo@0 162 32,
meillo@0 163 64,
meillo@0 164 128
meillo@0 165 };
meillo@0 166 static int regexp_h_advance(register const char *lp,
meillo@0 167 register const char *ep);
meillo@0 168 static void regexp_h_getrnge(register const char *str, int least);
meillo@0 169
meillo@0 170 static const char *regexp_h_bol; /* beginning of input line (for \<) */
meillo@0 171
meillo@0 172 #ifdef REGEXP_H_WCHARS
meillo@0 173 static int regexp_h_wchars;
meillo@0 174 static int regexp_h_mbcurmax;
meillo@0 175
meillo@0 176 static const char *regexp_h_firstwc; /* location of first
meillo@0 177 multibyte character
meillo@0 178 on input line */
meillo@0 179
meillo@0 180 #define regexp_h_getwc(c) { \
meillo@0 181 if (regexp_h_wchars) { \
meillo@0 182 char mbbuf[MB_LEN_MAX + 1], *mbptr; \
meillo@0 183 wchar_t wcbuf; \
meillo@0 184 int mb, len; \
meillo@0 185 mbptr = mbbuf; \
meillo@0 186 do { \
meillo@0 187 mb = GETC(); \
meillo@0 188 *mbptr++ = mb; \
meillo@0 189 *mbptr = '\0'; \
meillo@0 190 } while ((len = mbtowc(&wcbuf, mbbuf, regexp_h_mbcurmax)) < 0 \
meillo@0 191 && mb != eof && mbptr < mbbuf + MB_LEN_MAX); \
meillo@0 192 if (len == -1) \
meillo@0 193 ERROR(67); \
meillo@0 194 c = wcbuf; \
meillo@0 195 } else { \
meillo@0 196 c = GETC(); \
meillo@0 197 } \
meillo@0 198 }
meillo@0 199
meillo@0 200 #define regexp_h_store(wc, mb, me) { \
meillo@0 201 int len; \
meillo@0 202 if (wc == WEOF) \
meillo@0 203 ERROR(67); \
meillo@0 204 if ((len = me - mb) <= regexp_h_mbcurmax) { \
meillo@0 205 char mt[MB_LEN_MAX]; \
meillo@0 206 if (wctomb(mt, wc) >= len) \
meillo@0 207 ERROR(50); \
meillo@0 208 } \
meillo@0 209 switch (len = wctomb(mb, wc)) { \
meillo@0 210 case -1: \
meillo@0 211 ERROR(67); \
meillo@0 212 case 0: \
meillo@0 213 mb++; \
meillo@0 214 break; \
meillo@0 215 default: \
meillo@0 216 mb += len; \
meillo@0 217 } \
meillo@0 218 }
meillo@0 219
meillo@0 220 static regexp_h_inline wint_t
meillo@0 221 regexp_h_fetchwc(const char **mb, int islp)
meillo@0 222 {
meillo@0 223 wchar_t wc;
meillo@0 224 int len;
meillo@0 225
meillo@0 226 if ((len = mbtowc(&wc, *mb, regexp_h_mbcurmax)) < 0) {
meillo@0 227 (*mb)++;
meillo@0 228 return WEOF;
meillo@0 229 }
meillo@0 230 if (islp && regexp_h_firstwc == NULL)
meillo@0 231 regexp_h_firstwc = *mb;
meillo@0 232 /*if (len == 0) {
meillo@0 233 (*mb)++;
meillo@0 234 return L'\0';
meillo@0 235 } handled in singlebyte code */
meillo@0 236 *mb += len;
meillo@0 237 return wc;
meillo@0 238 }
meillo@0 239
meillo@0 240 #define regexp_h_fetch(mb, islp) ((*(mb) & REGEXP_H_MASK) == 0 ? \
meillo@0 241 (*(mb)++&0377): \
meillo@0 242 regexp_h_fetchwc(&(mb), islp))
meillo@0 243
meillo@0 244 static regexp_h_inline wint_t
meillo@0 245 regexp_h_showwc(const char *mb)
meillo@0 246 {
meillo@0 247 wchar_t wc;
meillo@0 248
meillo@0 249 if (mbtowc(&wc, mb, regexp_h_mbcurmax) < 0)
meillo@0 250 return WEOF;
meillo@0 251 return wc;
meillo@0 252 }
meillo@0 253
meillo@0 254 #define regexp_h_show(mb) ((*(mb) & REGEXP_H_MASK) == 0 ? (*(mb)&0377): \
meillo@0 255 regexp_h_showwc(mb))
meillo@0 256
meillo@0 257 /*
meillo@0 258 * Return the character immediately preceding mb. Since no byte is
meillo@0 259 * required to be the first byte of a character, the longest multibyte
meillo@0 260 * character ending at &[mb-1] is searched.
meillo@0 261 */
meillo@0 262 static regexp_h_inline wint_t
meillo@0 263 regexp_h_previous(const char *mb)
meillo@0 264 {
meillo@0 265 const char *p = mb;
meillo@0 266 wchar_t wc, lastwc = WEOF;
meillo@0 267 int len, max = 0;
meillo@0 268
meillo@0 269 if (regexp_h_firstwc == NULL || mb <= regexp_h_firstwc)
meillo@0 270 return (mb > regexp_h_bol ? (mb[-1] & 0377) : WEOF);
meillo@0 271 while (p-- > regexp_h_bol) {
meillo@0 272 mbtowc(NULL, NULL, 0);
meillo@0 273 if ((len = mbtowc(&wc, p, mb - p)) >= 0) {
meillo@0 274 if (len < max || len < mb - p)
meillo@0 275 break;
meillo@0 276 max = len;
meillo@0 277 lastwc = wc;
meillo@0 278 } else if (len < 0 && max > 0)
meillo@0 279 break;
meillo@0 280 }
meillo@0 281 return lastwc;
meillo@0 282 }
meillo@0 283
meillo@0 284 #define regexp_h_cclass(set, c, af) \
meillo@0 285 ((c) == 0 || (c) == WEOF ? 0 : ( \
meillo@0 286 ((c) > 0177) ? \
meillo@0 287 regexp_h_cclass_wc(set, c, af) : ( \
meillo@0 288 REGEXP_H_IS_THERE((set)+1, (c)) ? (af) : !(af) \
meillo@0 289 ) \
meillo@0 290 ) \
meillo@0 291 )
meillo@0 292
meillo@0 293 static regexp_h_inline int
meillo@0 294 regexp_h_cclass_wc(const char *set, register wint_t c, int af)
meillo@0 295 {
meillo@0 296 register wint_t wc, wl = WEOF;
meillo@0 297 const char *end;
meillo@0 298
meillo@0 299 end = &set[18] + set[0] - 1;
meillo@0 300 set += 17;
meillo@0 301 while (set < end) {
meillo@0 302 wc = regexp_h_fetch(set, 0);
meillo@0 303 #ifdef REGEXP_H_VI_BACKSLASH
meillo@0 304 if (wc == '\\' && set < end &&
meillo@0 305 (*set == ']' || *set == '-' ||
meillo@0 306 *set == '^' || *set == '\\')) {
meillo@0 307 wc = regexp_h_fetch(set, 0);
meillo@0 308 } else
meillo@0 309 #endif /* REGEXP_H_VI_BACKSLASH */
meillo@0 310 if (wc == '-' && wl != WEOF && set < end) {
meillo@0 311 wc = regexp_h_fetch(set, 0);
meillo@0 312 #ifdef REGEXP_H_VI_BACKSLASH
meillo@0 313 if (wc == '\\' && set < end &&
meillo@0 314 (*set == ']' || *set == '-' ||
meillo@0 315 *set == '^' || *set == '\\')) {
meillo@0 316 wc = regexp_h_fetch(set, 0);
meillo@0 317 }
meillo@0 318 #endif /* REGEXP_H_VI_BACKSLASH */
meillo@0 319 if (c > wl && c < wc)
meillo@0 320 return af;
meillo@0 321 }
meillo@0 322 if (c == wc)
meillo@0 323 return af;
meillo@0 324 wl = wc;
meillo@0 325 }
meillo@0 326 return !af;
meillo@0 327 }
meillo@0 328 #else /* !REGEXP_H_WCHARS */
meillo@0 329 #define regexp_h_wchars 0
meillo@0 330 #define regexp_h_getwc(c) { c = GETC(); }
meillo@0 331 #endif /* !REGEXP_H_WCHARS */
meillo@0 332
meillo@0 333 regexp_h_static char *
meillo@0 334 compile(char *instring, char *ep, const char *endbuf, int seof)
meillo@0 335 {
meillo@0 336 INIT /* Dependent declarations and initializations */
meillo@0 337 register int c;
meillo@0 338 register int eof = seof;
meillo@0 339 char *lastep = instring;
meillo@0 340 int cclcnt;
meillo@0 341 char bracket[NBRA], *bracketp;
meillo@0 342 int closed;
meillo@0 343 char neg;
meillo@0 344 int lc;
meillo@0 345 int i, cflg;
meillo@0 346
meillo@0 347 #ifdef REGEXP_H_WCHARS
meillo@0 348 char *eq;
meillo@0 349 regexp_h_mbcurmax = MB_CUR_MAX;
meillo@0 350 regexp_h_wchars = regexp_h_mbcurmax > 1 ? CMB : 0;
meillo@0 351 #endif
meillo@0 352 lastep = 0;
meillo@0 353 bracketp = bracket;
meillo@0 354 if((c = GETC()) == eof || c == '\n') {
meillo@0 355 if (c == '\n') {
meillo@0 356 UNGETC(c);
meillo@0 357 nodelim = 1;
meillo@0 358 }
meillo@0 359 if(*ep == 0 && !sed)
meillo@0 360 ERROR(41);
meillo@0 361 if (bracketp > bracket)
meillo@0 362 ERROR(42);
meillo@0 363 RETURN(ep);
meillo@0 364 }
meillo@0 365 circf = closed = nbra = 0;
meillo@0 366 if (c == '^')
meillo@0 367 circf++;
meillo@0 368 else
meillo@0 369 UNGETC(c);
meillo@0 370 for (;;) {
meillo@0 371 if (ep >= endbuf)
meillo@0 372 ERROR(50);
meillo@0 373 regexp_h_getwc(c);
meillo@0 374 if(c != '*' && ((c != '\\') || (PEEKC() != '{')))
meillo@0 375 lastep = ep;
meillo@0 376 if (c == eof) {
meillo@0 377 *ep++ = CCEOF;
meillo@0 378 if (bracketp > bracket)
meillo@0 379 ERROR(42);
meillo@0 380 RETURN(ep);
meillo@0 381 }
meillo@0 382 switch (c) {
meillo@0 383
meillo@0 384 case '.':
meillo@0 385 *ep++ = CDOT|regexp_h_wchars;
meillo@0 386 continue;
meillo@0 387
meillo@0 388 case '\n':
meillo@0 389 if (sed == 0) {
meillo@0 390 UNGETC(c);
meillo@0 391 *ep++ = CCEOF;
meillo@0 392 nodelim = 1;
meillo@0 393 RETURN(ep);
meillo@0 394 }
meillo@0 395 ERROR(36);
meillo@0 396 case '*':
meillo@0 397 if (lastep==0 || *lastep==CBRA || *lastep==CKET ||
meillo@0 398 *lastep==(CBRC|regexp_h_wchars) ||
meillo@0 399 *lastep==(CLET|regexp_h_wchars))
meillo@0 400 goto defchar;
meillo@0 401 *lastep |= STAR;
meillo@0 402 continue;
meillo@0 403
meillo@0 404 case '$':
meillo@0 405 if(PEEKC() != eof)
meillo@0 406 goto defchar;
meillo@0 407 *ep++ = CDOL;
meillo@0 408 continue;
meillo@0 409
meillo@0 410 case '[':
meillo@0 411 #ifdef REGEXP_H_WCHARS
meillo@0 412 if (regexp_h_wchars == 0) {
meillo@0 413 #endif
meillo@0 414 if(&ep[33] >= endbuf)
meillo@0 415 ERROR(50);
meillo@0 416
meillo@0 417 *ep++ = CCL;
meillo@0 418 lc = 0;
meillo@0 419 for(i = 0; i < 32; i++)
meillo@0 420 ep[i] = 0;
meillo@0 421
meillo@0 422 neg = 0;
meillo@0 423 if((c = GETC()) == '^') {
meillo@0 424 neg = 1;
meillo@0 425 c = GETC();
meillo@0 426 }
meillo@0 427
meillo@0 428 do {
meillo@0 429 c &= 0377;
meillo@0 430 if(c == '\0' || c == '\n')
meillo@0 431 ERROR(49);
meillo@0 432 #ifdef REGEXP_H_VI_BACKSLASH
meillo@0 433 if(c == '\\' && ((c = PEEKC()) == ']' ||
meillo@0 434 c == '-' || c == '^' ||
meillo@0 435 c == '\\')) {
meillo@0 436 c = GETC();
meillo@0 437 c &= 0377;
meillo@0 438 } else
meillo@0 439 #endif /* REGEXP_H_VI_BACKSLASH */
meillo@0 440 if(c == '-' && lc != 0) {
meillo@0 441 if ((c = GETC()) == ']') {
meillo@0 442 PLACE('-');
meillo@0 443 break;
meillo@0 444 }
meillo@0 445 #ifdef REGEXP_H_VI_BACKSLASH
meillo@0 446 if(c == '\\' &&
meillo@0 447 ((c = PEEKC()) == ']' ||
meillo@0 448 c == '-' ||
meillo@0 449 c == '^' ||
meillo@0 450 c == '\\'))
meillo@0 451 c = GETC();
meillo@0 452 #endif /* REGEXP_H_VI_BACKSLASH */
meillo@0 453 c &= 0377;
meillo@0 454 while(lc < c) {
meillo@0 455 PLACE(lc);
meillo@0 456 lc++;
meillo@0 457 }
meillo@0 458 }
meillo@0 459 lc = c;
meillo@0 460 PLACE(c);
meillo@0 461 } while((c = GETC()) != ']');
meillo@0 462 if(neg) {
meillo@0 463 for(cclcnt = 0; cclcnt < 32; cclcnt++)
meillo@0 464 ep[cclcnt] ^= 0377;
meillo@0 465 ep[0] &= 0376;
meillo@0 466 }
meillo@0 467
meillo@0 468 ep += 32;
meillo@0 469 #ifdef REGEXP_H_WCHARS
meillo@0 470 } else {
meillo@0 471 if (&ep[18] >= endbuf)
meillo@0 472 ERROR(50);
meillo@0 473 *ep++ = CCL|CMB;
meillo@0 474 *ep++ = 0;
meillo@0 475 lc = 0;
meillo@0 476 for (i = 0; i < 16; i++)
meillo@0 477 ep[i] = 0;
meillo@0 478 eq = &ep[16];
meillo@0 479 regexp_h_getwc(c);
meillo@0 480 if (c == L'^') {
meillo@0 481 regexp_h_getwc(c);
meillo@0 482 ep[-2] = CNCL|CMB;
meillo@0 483 }
meillo@0 484 do {
meillo@0 485 if (c == '\0' || c == '\n')
meillo@0 486 ERROR(49);
meillo@0 487 #ifdef REGEXP_H_VI_BACKSLASH
meillo@0 488 if(c == '\\' && ((c = PEEKC()) == ']' ||
meillo@0 489 c == '-' || c == '^' ||
meillo@0 490 c == '\\')) {
meillo@0 491 regexp_h_store(c, eq, endbuf);
meillo@0 492 regexp_h_getwc(c);
meillo@0 493 } else
meillo@0 494 #endif /* REGEXP_H_VI_BACKSLASH */
meillo@0 495 if (c == '-' && lc != 0 && lc <= 0177) {
meillo@0 496 regexp_h_store(c, eq, endbuf);
meillo@0 497 regexp_h_getwc(c);
meillo@0 498 if (c == ']') {
meillo@0 499 PLACE('-');
meillo@0 500 break;
meillo@0 501 }
meillo@0 502 #ifdef REGEXP_H_VI_BACKSLASH
meillo@0 503 if(c == '\\' &&
meillo@0 504 ((c = PEEKC()) == ']' ||
meillo@0 505 c == '-' ||
meillo@0 506 c == '^' ||
meillo@0 507 c == '\\')) {
meillo@0 508 regexp_h_store(c, eq,
meillo@0 509 endbuf);
meillo@0 510 regexp_h_getwc(c);
meillo@0 511 }
meillo@0 512 #endif /* REGEXP_H_VI_BACKSLASH */
meillo@0 513 while (lc < (c & 0177)) {
meillo@0 514 PLACE(lc);
meillo@0 515 lc++;
meillo@0 516 }
meillo@0 517 }
meillo@0 518 lc = c;
meillo@0 519 if (c <= 0177)
meillo@0 520 PLACE(c);
meillo@0 521 regexp_h_store(c, eq, endbuf);
meillo@0 522 regexp_h_getwc(c);
meillo@0 523 } while (c != L']');
meillo@0 524 if ((i = eq - &ep[16]) > 255)
meillo@0 525 ERROR(50);
meillo@0 526 lastep[1] = i;
meillo@0 527 ep = eq;
meillo@0 528 }
meillo@0 529 #endif /* REGEXP_H_WCHARS */
meillo@0 530
meillo@0 531 continue;
meillo@0 532
meillo@0 533 case '\\':
meillo@0 534 regexp_h_getwc(c);
meillo@0 535 switch(c) {
meillo@0 536
meillo@0 537 case '(':
meillo@0 538 if(nbra >= NBRA)
meillo@0 539 ERROR(43);
meillo@0 540 *bracketp++ = nbra;
meillo@0 541 *ep++ = CBRA;
meillo@0 542 *ep++ = nbra++;
meillo@0 543 continue;
meillo@0 544
meillo@0 545 case ')':
meillo@0 546 if(bracketp <= bracket)
meillo@0 547 ERROR(42);
meillo@0 548 *ep++ = CKET;
meillo@0 549 *ep++ = *--bracketp;
meillo@0 550 closed++;
meillo@0 551 continue;
meillo@0 552
meillo@0 553 case '<':
meillo@0 554 *ep++ = CBRC|regexp_h_wchars;
meillo@0 555 continue;
meillo@0 556
meillo@0 557 case '>':
meillo@0 558 *ep++ = CLET|regexp_h_wchars;
meillo@0 559 continue;
meillo@0 560
meillo@0 561 case '{':
meillo@0 562 if(lastep == (char *) (0))
meillo@0 563 goto defchar;
meillo@0 564 *lastep |= RNGE;
meillo@0 565 cflg = 0;
meillo@0 566 nlim:
meillo@0 567 c = GETC();
meillo@0 568 i = 0;
meillo@0 569 do {
meillo@0 570 if ('0' <= c && c <= '9')
meillo@0 571 i = 10 * i + c - '0';
meillo@0 572 else
meillo@0 573 ERROR(16);
meillo@0 574 } while(((c = GETC()) != '\\') && (c != ','));
meillo@0 575 if (i > 255)
meillo@0 576 ERROR(11);
meillo@0 577 *ep++ = i;
meillo@0 578 if (c == ',') {
meillo@0 579 if(cflg++)
meillo@0 580 ERROR(44);
meillo@0 581 if((c = GETC()) == '\\') {
meillo@0 582 *ep++ = (char)255;
meillo@0 583 *lastep |= REGEXP_H_LEAST;
meillo@0 584 } else {
meillo@0 585 UNGETC(c);
meillo@0 586 goto nlim; /* get 2'nd number */
meillo@0 587 }
meillo@0 588 }
meillo@0 589 if(GETC() != '}')
meillo@0 590 ERROR(45);
meillo@0 591 if(!cflg) /* one number */
meillo@0 592 *ep++ = i;
meillo@0 593 else if((ep[-1] & 0377) < (ep[-2] & 0377))
meillo@0 594 ERROR(46);
meillo@0 595 continue;
meillo@0 596
meillo@0 597 case '\n':
meillo@0 598 ERROR(36);
meillo@0 599
meillo@0 600 case 'n':
meillo@0 601 c = '\n';
meillo@0 602 goto defchar;
meillo@0 603
meillo@0 604 default:
meillo@0 605 if(c >= '1' && c <= '9') {
meillo@0 606 if((c -= '1') >= closed)
meillo@0 607 ERROR(25);
meillo@0 608 *ep++ = CBACK;
meillo@0 609 *ep++ = c;
meillo@0 610 continue;
meillo@0 611 }
meillo@0 612 }
meillo@0 613 /* Drop through to default to use \ to turn off special chars */
meillo@0 614
meillo@0 615 defchar:
meillo@0 616 default:
meillo@0 617 lastep = ep;
meillo@0 618 #ifdef REGEXP_H_WCHARS
meillo@0 619 if (regexp_h_wchars == 0) {
meillo@0 620 #endif
meillo@0 621 *ep++ = CCHR;
meillo@0 622 *ep++ = c;
meillo@0 623 #ifdef REGEXP_H_WCHARS
meillo@0 624 } else {
meillo@0 625 char mbbuf[MB_LEN_MAX];
meillo@0 626
meillo@0 627 switch (wctomb(mbbuf, c)) {
meillo@0 628 case 1: *ep++ = CCH1;
meillo@0 629 break;
meillo@0 630 case 2: *ep++ = CCH2;
meillo@0 631 break;
meillo@0 632 case 3: *ep++ = CCH3;
meillo@0 633 break;
meillo@0 634 default:
meillo@0 635 *ep++ = CCHR|CMB;
meillo@0 636 }
meillo@0 637 regexp_h_store(c, ep, endbuf);
meillo@0 638 }
meillo@0 639 #endif /* REGEXP_H_WCHARS */
meillo@0 640 }
meillo@0 641 }
meillo@0 642 }
meillo@0 643
meillo@0 644 int
meillo@0 645 step(const char *p1, const char *p2)
meillo@0 646 {
meillo@0 647 register int c;
meillo@0 648 #ifdef REGEXP_H_WCHARS
meillo@0 649 register int d;
meillo@0 650 #endif /* REGEXP_H_WCHARS */
meillo@0 651
meillo@0 652 REGEXP_H_STEP_INIT /* get circf */
meillo@0 653 regexp_h_bol = p1;
meillo@0 654 #ifdef REGEXP_H_WCHARS
meillo@0 655 regexp_h_firstwc = NULL;
meillo@0 656 #endif /* REGEXP_H_WCHARS */
meillo@0 657 if (circf) {
meillo@0 658 loc1 = (char *)p1;
meillo@0 659 return(regexp_h_advance(p1, p2));
meillo@0 660 }
meillo@0 661 /* fast check for first character */
meillo@0 662 if (*p2==CCHR) {
meillo@0 663 c = p2[1] & 0377;
meillo@0 664 do {
meillo@0 665 if ((*p1 & 0377) != c)
meillo@0 666 continue;
meillo@0 667 if (regexp_h_advance(p1, p2)) {
meillo@0 668 loc1 = (char *)p1;
meillo@0 669 return(1);
meillo@0 670 }
meillo@0 671 } while (*p1++);
meillo@0 672 return(0);
meillo@0 673 }
meillo@0 674 #ifdef REGEXP_H_WCHARS
meillo@0 675 else if (*p2==CCH1) {
meillo@0 676 do {
meillo@0 677 if (p1[0] == p2[1] && regexp_h_advance(p1, p2)) {
meillo@0 678 loc1 = (char *)p1;
meillo@0 679 return(1);
meillo@0 680 }
meillo@0 681 c = regexp_h_fetch(p1, 1);
meillo@0 682 } while (c);
meillo@0 683 return(0);
meillo@0 684 } else if (*p2==CCH2) {
meillo@0 685 do {
meillo@0 686 if (p1[0] == p2[1] && p1[1] == p2[2] &&
meillo@0 687 regexp_h_advance(p1, p2)) {
meillo@0 688 loc1 = (char *)p1;
meillo@0 689 return(1);
meillo@0 690 }
meillo@0 691 c = regexp_h_fetch(p1, 1);
meillo@0 692 } while (c);
meillo@0 693 return(0);
meillo@0 694 } else if (*p2==CCH3) {
meillo@0 695 do {
meillo@0 696 if (p1[0] == p2[1] && p1[1] == p2[2] && p1[2] == p2[3]&&
meillo@0 697 regexp_h_advance(p1, p2)) {
meillo@0 698 loc1 = (char *)p1;
meillo@0 699 return(1);
meillo@0 700 }
meillo@0 701 c = regexp_h_fetch(p1, 1);
meillo@0 702 } while (c);
meillo@0 703 return(0);
meillo@0 704 } else if ((*p2&0377)==(CCHR|CMB)) {
meillo@0 705 d = regexp_h_fetch(p2, 0);
meillo@0 706 do {
meillo@0 707 c = regexp_h_fetch(p1, 1);
meillo@0 708 if (c == d && regexp_h_advance(p1, p2)) {
meillo@0 709 loc1 = (char *)p1;
meillo@0 710 return(1);
meillo@0 711 }
meillo@0 712 } while(c);
meillo@0 713 return(0);
meillo@0 714 }
meillo@0 715 /* regular algorithm */
meillo@0 716 if (regexp_h_wchars)
meillo@0 717 do {
meillo@0 718 if (regexp_h_advance(p1, p2)) {
meillo@0 719 loc1 = (char *)p1;
meillo@0 720 return(1);
meillo@0 721 }
meillo@0 722 c = regexp_h_fetch(p1, 1);
meillo@0 723 } while (c);
meillo@0 724 else
meillo@0 725 #endif /* REGEXP_H_WCHARS */
meillo@0 726 do {
meillo@0 727 if (regexp_h_advance(p1, p2)) {
meillo@0 728 loc1 = (char *)p1;
meillo@0 729 return(1);
meillo@0 730 }
meillo@0 731 } while (*p1++);
meillo@0 732 return(0);
meillo@0 733 }
meillo@0 734
meillo@0 735 #ifdef REGEXP_H_WCHARS
meillo@0 736 /*
meillo@0 737 * It is painfully slow to read character-wise backwards in a
meillo@0 738 * multibyte string (see regexp_h_previous() above). For the star
meillo@0 739 * algorithm, we therefore keep track of every character as it is
meillo@0 740 * read in forward direction.
meillo@0 741 *
meillo@0 742 * Don't use alloca() for stack blocks since there is no measurable
meillo@0 743 * speedup and huge amounts of memory are used up for long input
meillo@0 744 * lines.
meillo@0 745 */
meillo@0 746 #ifndef REGEXP_H_STAKBLOK
meillo@0 747 #define REGEXP_H_STAKBLOK 1000
meillo@0 748 #endif
meillo@0 749
meillo@0 750 struct regexp_h_stack {
meillo@0 751 struct regexp_h_stack *s_nxt;
meillo@0 752 struct regexp_h_stack *s_prv;
meillo@0 753 const char *s_ptr[REGEXP_H_STAKBLOK];
meillo@0 754 };
meillo@0 755
meillo@0 756 #define regexp_h_push(sb, sp, sc, lp) (regexp_h_wchars ? \
meillo@0 757 regexp_h_pushwc(sb, sp, sc, lp) : (void)0)
meillo@0 758
meillo@0 759 static regexp_h_inline void
meillo@0 760 regexp_h_pushwc(struct regexp_h_stack **sb,
meillo@0 761 struct regexp_h_stack **sp,
meillo@0 762 const char ***sc, const char *lp)
meillo@0 763 {
meillo@0 764 if (regexp_h_firstwc == NULL || lp < regexp_h_firstwc)
meillo@0 765 return;
meillo@0 766 if (*sb == NULL) {
meillo@0 767 if ((*sb = regexp_h_malloc(sizeof **sb)) == NULL)
meillo@0 768 return;
meillo@0 769 (*sb)->s_nxt = (*sb)->s_prv = NULL;
meillo@0 770 *sp = *sb;
meillo@0 771 *sc = &(*sb)->s_ptr[0];
meillo@0 772 } else if (*sc >= &(*sp)->s_ptr[REGEXP_H_STAKBLOK]) {
meillo@0 773 if ((*sp)->s_nxt == NULL) {
meillo@0 774 struct regexp_h_stack *bq;
meillo@0 775
meillo@0 776 if ((bq = regexp_h_malloc(sizeof *bq)) == NULL)
meillo@0 777 return;
meillo@0 778 bq->s_nxt = NULL;
meillo@0 779 bq->s_prv = *sp;
meillo@0 780 (*sp)->s_nxt = bq;
meillo@0 781 *sp = bq;
meillo@0 782 } else
meillo@0 783 *sp = (*sp)->s_nxt;
meillo@0 784 *sc = &(*sp)->s_ptr[0];
meillo@0 785 }
meillo@0 786 *(*sc)++ = lp;
meillo@0 787 }
meillo@0 788
meillo@0 789 static regexp_h_inline const char *
meillo@0 790 regexp_h_pop(struct regexp_h_stack **sb, struct regexp_h_stack **sp,
meillo@0 791 const char ***sc, const char *lp)
meillo@0 792 {
meillo@0 793 if (regexp_h_firstwc == NULL || lp <= regexp_h_firstwc)
meillo@0 794 return &lp[-1];
meillo@0 795 if (*sp == NULL)
meillo@0 796 return regexp_h_firstwc;
meillo@0 797 if (*sc == &(*sp)->s_ptr[0]) {
meillo@0 798 if ((*sp)->s_prv == NULL) {
meillo@0 799 regexp_h_free(*sp);
meillo@0 800 *sp = NULL;
meillo@0 801 *sb = NULL;
meillo@0 802 return regexp_h_firstwc;
meillo@0 803 }
meillo@0 804 *sp = (*sp)->s_prv;
meillo@0 805 regexp_h_free((*sp)->s_nxt);
meillo@0 806 (*sp)->s_nxt = NULL ;
meillo@0 807 *sc = &(*sp)->s_ptr[REGEXP_H_STAKBLOK];
meillo@0 808 }
meillo@0 809 return *(--(*sc));
meillo@0 810 }
meillo@0 811
meillo@0 812 static void
meillo@0 813 regexp_h_zerostak(struct regexp_h_stack **sb, struct regexp_h_stack **sp)
meillo@0 814 {
meillo@0 815 for (*sp = *sb; *sp && (*sp)->s_nxt; *sp = (*sp)->s_nxt)
meillo@0 816 if ((*sp)->s_prv)
meillo@0 817 regexp_h_free((*sp)->s_prv);
meillo@0 818 if (*sp) {
meillo@0 819 if ((*sp)->s_prv)
meillo@0 820 regexp_h_free((*sp)->s_prv);
meillo@0 821 regexp_h_free(*sp);
meillo@0 822 }
meillo@0 823 *sp = *sb = NULL;
meillo@0 824 }
meillo@0 825 #else /* !REGEXP_H_WCHARS */
meillo@0 826 #define regexp_h_push(sb, sp, sc, lp)
meillo@0 827 #endif /* !REGEXP_H_WCHARS */
meillo@0 828
meillo@0 829 static int
meillo@0 830 regexp_h_advance(const char *lp, const char *ep)
meillo@0 831 {
meillo@0 832 register const char *curlp;
meillo@0 833 int c, least;
meillo@0 834 #ifdef REGEXP_H_WCHARS
meillo@0 835 int d;
meillo@0 836 struct regexp_h_stack *sb = NULL, *sp = NULL;
meillo@0 837 const char **sc;
meillo@0 838 #endif /* REGEXP_H_WCHARS */
meillo@0 839 char *bbeg;
meillo@0 840 int ct;
meillo@0 841
meillo@0 842 for (;;) switch (least = *ep++ & 0377, least & ~REGEXP_H_LEAST) {
meillo@0 843
meillo@0 844 case CCHR:
meillo@0 845 #ifdef REGEXP_H_WCHARS
meillo@0 846 case CCH1:
meillo@0 847 #endif
meillo@0 848 if (*ep++ == *lp++)
meillo@0 849 continue;
meillo@0 850 return(0);
meillo@0 851
meillo@0 852 #ifdef REGEXP_H_WCHARS
meillo@0 853 case CCHR|CMB:
meillo@0 854 if (regexp_h_fetch(ep, 0) == regexp_h_fetch(lp, 1))
meillo@0 855 continue;
meillo@0 856 return(0);
meillo@0 857
meillo@0 858 case CCH2:
meillo@0 859 if (ep[0] == lp[0] && ep[1] == lp[1]) {
meillo@0 860 ep += 2, lp += 2;
meillo@0 861 continue;
meillo@0 862 }
meillo@0 863 return(0);
meillo@0 864
meillo@0 865 case CCH3:
meillo@0 866 if (ep[0] == lp[0] && ep[1] == lp[1] && ep[2] == lp[2]) {
meillo@0 867 ep += 3, lp += 3;
meillo@0 868 continue;
meillo@0 869 }
meillo@0 870 return(0);
meillo@0 871 #endif /* REGEXP_H_WCHARS */
meillo@0 872
meillo@0 873 case CDOT:
meillo@0 874 if (*lp++)
meillo@0 875 continue;
meillo@0 876 return(0);
meillo@0 877 #ifdef REGEXP_H_WCHARS
meillo@0 878 case CDOT|CMB:
meillo@0 879 if ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF)
meillo@0 880 continue;
meillo@0 881 return(0);
meillo@0 882 #endif /* REGEXP_H_WCHARS */
meillo@0 883
meillo@0 884 case CDOL:
meillo@0 885 if (*lp==0)
meillo@0 886 continue;
meillo@0 887 return(0);
meillo@0 888
meillo@0 889 case CCEOF:
meillo@0 890 loc2 = (char *)lp;
meillo@0 891 return(1);
meillo@0 892
meillo@0 893 case CCL:
meillo@0 894 c = *lp++ & 0377;
meillo@0 895 if(ISTHERE(c)) {
meillo@0 896 ep += 32;
meillo@0 897 continue;
meillo@0 898 }
meillo@0 899 return(0);
meillo@0 900
meillo@0 901 #ifdef REGEXP_H_WCHARS
meillo@0 902 case CCL|CMB:
meillo@0 903 case CNCL|CMB:
meillo@0 904 c = regexp_h_fetch(lp, 1);
meillo@0 905 if (regexp_h_cclass(ep, c, (ep[-1] & 0377) == (CCL|CMB))) {
meillo@0 906 ep += (*ep & 0377) + 17;
meillo@0 907 continue;
meillo@0 908 }
meillo@0 909 return 0;
meillo@0 910 #endif /* REGEXP_H_WCHARS */
meillo@0 911
meillo@0 912 case CBRA:
meillo@0 913 braslist[*ep++ & 0377] = (char *)lp;
meillo@0 914 continue;
meillo@0 915
meillo@0 916 case CKET:
meillo@0 917 braelist[*ep++ & 0377] = (char *)lp;
meillo@0 918 continue;
meillo@0 919
meillo@0 920 case CBRC:
meillo@0 921 if (lp == regexp_h_bol && locs == NULL)
meillo@0 922 continue;
meillo@0 923 if ((isdigit(lp[0] & 0377) || regexp_h_uletter(lp[0] & 0377))
meillo@0 924 && !regexp_h_uletter(lp[-1] & 0377)
meillo@0 925 && !isdigit(lp[-1] & 0377))
meillo@0 926 continue;
meillo@0 927 return(0);
meillo@0 928
meillo@0 929 #ifdef REGEXP_H_WCHARS
meillo@0 930 case CBRC|CMB:
meillo@0 931 c = regexp_h_show(lp);
meillo@0 932 d = regexp_h_previous(lp);
meillo@0 933 if ((iswdigit(c) || regexp_h_wuletter(c))
meillo@0 934 && !regexp_h_wuletter(d)
meillo@0 935 && !iswdigit(d))
meillo@0 936 continue;
meillo@0 937 return(0);
meillo@0 938 #endif /* REGEXP_H_WCHARS */
meillo@0 939
meillo@0 940 case CLET:
meillo@0 941 if (!regexp_h_uletter(lp[0] & 0377) && !isdigit(lp[0] & 0377))
meillo@0 942 continue;
meillo@0 943 return(0);
meillo@0 944
meillo@0 945 #ifdef REGEXP_H_WCHARS
meillo@0 946 case CLET|CMB:
meillo@0 947 c = regexp_h_show(lp);
meillo@0 948 if (!regexp_h_wuletter(c) && !iswdigit(c))
meillo@0 949 continue;
meillo@0 950 return(0);
meillo@0 951 #endif /* REGEXP_H_WCHARS */
meillo@0 952
meillo@0 953 case CCHR|RNGE:
meillo@0 954 c = *ep++;
meillo@0 955 regexp_h_getrnge(ep, least);
meillo@0 956 while(low--)
meillo@0 957 if(*lp++ != c)
meillo@0 958 return(0);
meillo@0 959 curlp = lp;
meillo@0 960 while(size--) {
meillo@0 961 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 962 if(*lp++ != c)
meillo@0 963 break;
meillo@0 964 }
meillo@0 965 if(size < 0) {
meillo@0 966 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 967 lp++;
meillo@0 968 }
meillo@0 969 ep += 2;
meillo@0 970 goto star;
meillo@0 971
meillo@0 972 #ifdef REGEXP_H_WCHARS
meillo@0 973 case CCHR|RNGE|CMB:
meillo@0 974 case CCH1|RNGE:
meillo@0 975 case CCH2|RNGE:
meillo@0 976 case CCH3|RNGE:
meillo@0 977 c = regexp_h_fetch(ep, 0);
meillo@0 978 regexp_h_getrnge(ep, least);
meillo@0 979 while (low--)
meillo@0 980 if (regexp_h_fetch(lp, 1) != c)
meillo@0 981 return 0;
meillo@0 982 curlp = lp;
meillo@0 983 while (size--) {
meillo@0 984 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 985 if (regexp_h_fetch(lp, 1) != c)
meillo@0 986 break;
meillo@0 987 }
meillo@0 988 if(size < 0) {
meillo@0 989 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 990 regexp_h_fetch(lp, 1);
meillo@0 991 }
meillo@0 992 ep += 2;
meillo@0 993 goto star;
meillo@0 994 #endif /* REGEXP_H_WCHARS */
meillo@0 995
meillo@0 996 case CDOT|RNGE:
meillo@0 997 regexp_h_getrnge(ep, least);
meillo@0 998 while(low--)
meillo@0 999 if(*lp++ == '\0')
meillo@0 1000 return(0);
meillo@0 1001 curlp = lp;
meillo@0 1002 while(size--) {
meillo@0 1003 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1004 if(*lp++ == '\0')
meillo@0 1005 break;
meillo@0 1006 }
meillo@0 1007 if(size < 0) {
meillo@0 1008 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1009 lp++;
meillo@0 1010 }
meillo@0 1011 ep += 2;
meillo@0 1012 goto star;
meillo@0 1013
meillo@0 1014 #ifdef REGEXP_H_WCHARS
meillo@0 1015 case CDOT|RNGE|CMB:
meillo@0 1016 regexp_h_getrnge(ep, least);
meillo@0 1017 while (low--)
meillo@0 1018 if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF)
meillo@0 1019 return 0;
meillo@0 1020 curlp = lp;
meillo@0 1021 while (size--) {
meillo@0 1022 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1023 if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF)
meillo@0 1024 break;
meillo@0 1025 }
meillo@0 1026 if (size < 0) {
meillo@0 1027 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1028 regexp_h_fetch(lp, 1);
meillo@0 1029 }
meillo@0 1030 ep += 2;
meillo@0 1031 goto star;
meillo@0 1032 #endif /* REGEXP_H_WCHARS */
meillo@0 1033
meillo@0 1034 case CCL|RNGE:
meillo@0 1035 regexp_h_getrnge(ep + 32, least);
meillo@0 1036 while(low--) {
meillo@0 1037 c = *lp++ & 0377;
meillo@0 1038 if(!ISTHERE(c))
meillo@0 1039 return(0);
meillo@0 1040 }
meillo@0 1041 curlp = lp;
meillo@0 1042 while(size--) {
meillo@0 1043 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1044 c = *lp++ & 0377;
meillo@0 1045 if(!ISTHERE(c))
meillo@0 1046 break;
meillo@0 1047 }
meillo@0 1048 if(size < 0) {
meillo@0 1049 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1050 lp++;
meillo@0 1051 }
meillo@0 1052 ep += 34; /* 32 + 2 */
meillo@0 1053 goto star;
meillo@0 1054
meillo@0 1055 #ifdef REGEXP_H_WCHARS
meillo@0 1056 case CCL|RNGE|CMB:
meillo@0 1057 case CNCL|RNGE|CMB:
meillo@0 1058 regexp_h_getrnge(ep + (*ep & 0377) + 17, least);
meillo@0 1059 while (low--) {
meillo@0 1060 c = regexp_h_fetch(lp, 1);
meillo@0 1061 if (!regexp_h_cclass(ep, c,
meillo@0 1062 (ep[-1] & 0377 & ~REGEXP_H_LEAST)
meillo@0 1063 == (CCL|RNGE|CMB)))
meillo@0 1064 return 0;
meillo@0 1065 }
meillo@0 1066 curlp = lp;
meillo@0 1067 while (size--) {
meillo@0 1068 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1069 c = regexp_h_fetch(lp, 1);
meillo@0 1070 if (!regexp_h_cclass(ep, c,
meillo@0 1071 (ep[-1] & 0377 & ~REGEXP_H_LEAST)
meillo@0 1072 == (CCL|RNGE|CMB)))
meillo@0 1073 break;
meillo@0 1074 }
meillo@0 1075 if (size < 0) {
meillo@0 1076 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1077 regexp_h_fetch(lp, 1);
meillo@0 1078 }
meillo@0 1079 ep += (*ep & 0377) + 19;
meillo@0 1080 goto star;
meillo@0 1081 #endif /* REGEXP_H_WCHARS */
meillo@0 1082
meillo@0 1083 case CBACK:
meillo@0 1084 bbeg = braslist[*ep & 0377];
meillo@0 1085 ct = braelist[*ep++ & 0377] - bbeg;
meillo@0 1086
meillo@0 1087 if(strncmp(bbeg, lp, ct) == 0) {
meillo@0 1088 lp += ct;
meillo@0 1089 continue;
meillo@0 1090 }
meillo@0 1091 return(0);
meillo@0 1092
meillo@0 1093 case CBACK|STAR:
meillo@0 1094 bbeg = braslist[*ep & 0377];
meillo@0 1095 ct = braelist[*ep++ & 0377] - bbeg;
meillo@0 1096 curlp = lp;
meillo@0 1097 while(strncmp(bbeg, lp, ct) == 0)
meillo@0 1098 lp += ct;
meillo@0 1099
meillo@0 1100 while(lp >= curlp) {
meillo@0 1101 if(regexp_h_advance(lp, ep)) return(1);
meillo@0 1102 lp -= ct;
meillo@0 1103 }
meillo@0 1104 return(0);
meillo@0 1105
meillo@0 1106
meillo@0 1107 case CDOT|STAR:
meillo@0 1108 curlp = lp;
meillo@0 1109 do
meillo@0 1110 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1111 while (*lp++);
meillo@0 1112 goto star;
meillo@0 1113
meillo@0 1114 #ifdef REGEXP_H_WCHARS
meillo@0 1115 case CDOT|STAR|CMB:
meillo@0 1116 curlp = lp;
meillo@0 1117 do
meillo@0 1118 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1119 while ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF);
meillo@0 1120 goto star;
meillo@0 1121 #endif /* REGEXP_H_WCHARS */
meillo@0 1122
meillo@0 1123 case CCHR|STAR:
meillo@0 1124 curlp = lp;
meillo@0 1125 do
meillo@0 1126 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1127 while (*lp++ == *ep);
meillo@0 1128 ep++;
meillo@0 1129 goto star;
meillo@0 1130
meillo@0 1131 #ifdef REGEXP_H_WCHARS
meillo@0 1132 case CCHR|STAR|CMB:
meillo@0 1133 case CCH1|STAR:
meillo@0 1134 case CCH2|STAR:
meillo@0 1135 case CCH3|STAR:
meillo@0 1136 curlp = lp;
meillo@0 1137 d = regexp_h_fetch(ep, 0);
meillo@0 1138 do
meillo@0 1139 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1140 while (regexp_h_fetch(lp, 1) == d);
meillo@0 1141 goto star;
meillo@0 1142 #endif /* REGEXP_H_WCHARS */
meillo@0 1143
meillo@0 1144 case CCL|STAR:
meillo@0 1145 curlp = lp;
meillo@0 1146 do {
meillo@0 1147 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1148 c = *lp++ & 0377;
meillo@0 1149 } while(ISTHERE(c));
meillo@0 1150 ep += 32;
meillo@0 1151 goto star;
meillo@0 1152
meillo@0 1153 #ifdef REGEXP_H_WCHARS
meillo@0 1154 case CCL|STAR|CMB:
meillo@0 1155 case CNCL|STAR|CMB:
meillo@0 1156 curlp = lp;
meillo@0 1157 do {
meillo@0 1158 regexp_h_push(&sb, &sp, &sc, lp);
meillo@0 1159 c = regexp_h_fetch(lp, 1);
meillo@0 1160 } while (regexp_h_cclass(ep, c, (ep[-1] & 0377)
meillo@0 1161 == (CCL|STAR|CMB)));
meillo@0 1162 ep += (*ep & 0377) + 17;
meillo@0 1163 goto star;
meillo@0 1164 #endif /* REGEXP_H_WCHARS */
meillo@0 1165
meillo@0 1166 star:
meillo@0 1167 #ifdef REGEXP_H_WCHARS
meillo@0 1168 if (regexp_h_wchars == 0) {
meillo@0 1169 #endif
meillo@0 1170 do {
meillo@0 1171 if(--lp == locs)
meillo@0 1172 break;
meillo@0 1173 if (regexp_h_advance(lp, ep))
meillo@0 1174 return(1);
meillo@0 1175 } while (lp > curlp);
meillo@0 1176 #ifdef REGEXP_H_WCHARS
meillo@0 1177 } else {
meillo@0 1178 do {
meillo@0 1179 lp = regexp_h_pop(&sb, &sp, &sc, lp);
meillo@0 1180 if (lp <= locs)
meillo@0 1181 break;
meillo@0 1182 if (regexp_h_advance(lp, ep)) {
meillo@0 1183 regexp_h_zerostak(&sb, &sp);
meillo@0 1184 return(1);
meillo@0 1185 }
meillo@0 1186 } while (lp > curlp);
meillo@0 1187 regexp_h_zerostak(&sb, &sp);
meillo@0 1188 }
meillo@0 1189 #endif /* REGEXP_H_WCHARS */
meillo@0 1190 return(0);
meillo@0 1191
meillo@0 1192 }
meillo@0 1193 }
meillo@0 1194
meillo@0 1195 static void
meillo@0 1196 regexp_h_getrnge(register const char *str, int least)
meillo@0 1197 {
meillo@0 1198 low = *str++ & 0377;
meillo@0 1199 size = least & REGEXP_H_LEAST ? /*20000*/INT_MAX : (*str & 0377) - low;
meillo@0 1200 }
meillo@0 1201
meillo@0 1202 int
meillo@0 1203 advance(const char *lp, const char *ep)
meillo@0 1204 {
meillo@0 1205 REGEXP_H_ADVANCE_INIT /* skip past circf */
meillo@0 1206 regexp_h_bol = lp;
meillo@0 1207 #ifdef REGEXP_H_WCHARS
meillo@0 1208 regexp_h_firstwc = NULL;
meillo@0 1209 #endif /* REGEXP_H_WCHARS */
meillo@0 1210 return regexp_h_advance(lp, ep);
meillo@0 1211 }