regcomp.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:42k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-
  2.  * Copyright (c) 1992, 1993, 1994 Henry Spencer.
  3.  * Copyright (c) 1992, 1993, 1994
  4.  * The Regents of the University of California.  All rights reserved.
  5.  *
  6.  * This code is derived from software contributed to Berkeley by
  7.  * Henry Spencer.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *   notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *   notice, this list of conditions and the following disclaimer in the
  16.  *   documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *   must display the following acknowledgement:
  19.  * This product includes software developed by the University of
  20.  * California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *   may be used to endorse or promote products derived from this software
  23.  *   without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  *
  37.  * @(#)regcomp.c 8.5 (Berkeley) 3/20/94
  38.  */
  39. #if defined(LIBC_SCCS) && !defined(lint)
  40. static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94";
  41. #endif  /* LIBC_SCCS and not lint */
  42. #include <sys/types.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46. #include <limits.h>
  47. #include <stdlib.h>
  48. #include <assert.h>
  49. #include <regex/regex.h>
  50. #include <regex/utils.h>
  51. #include <regex/regex2.h>
  52. #include <regex/cclass.h>
  53. #include <regex/cname.h>
  54. /*
  55.  * parse structure, passed up and down to avoid global variables and
  56.  * other clumsinesses
  57.  */
  58. struct parse
  59. {
  60. pg_wchar   *next; /* next character in RE */
  61. pg_wchar   *end; /* end of string (-> NUL normally) */
  62. int error; /* has an error been seen? */
  63. sop    *strip; /* malloced strip */
  64. sopno ssize; /* malloced strip size (allocated) */
  65. sopno slen; /* malloced strip length (used) */
  66. int ncsalloc; /* number of csets allocated */
  67. struct re_guts *g;
  68. #define  NPAREN  10 /* we need to remember () 1-9 for back
  69.  * refs */
  70. sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
  71. sopno pend[NPAREN]; /* -> ) ([0] unused) */
  72. };
  73. /* ========= begin header generated by ./mkh ========= */
  74. #ifdef __cplusplus
  75. extern "C"
  76. {
  77. #endif
  78. /* === regcomp.c === */
  79. static void p_ere(struct parse * p, int stop);
  80. static void p_ere_exp(struct parse * p);
  81. static void p_str(struct parse * p);
  82. static void p_bre(struct parse * p, int end1, int end2);
  83. static int p_simp_re(struct parse * p, int starordinary);
  84. static int p_count(struct parse * p);
  85. static void p_bracket(struct parse * p);
  86. static void p_b_term(struct parse * p, cset *cs);
  87. static void p_b_cclass(struct parse * p, cset *cs);
  88. static void p_b_eclass(struct parse * p, cset *cs);
  89. static pg_wchar p_b_symbol(struct parse * p);
  90. static char p_b_coll_elem(struct parse * p, int endc);
  91. #ifdef MULTIBYTE
  92. static unsigned char othercase(int ch);
  93. #else
  94. static char othercase(int ch);
  95. #endif
  96. static void bothcases(struct parse * p, int ch);
  97. static void ordinary(struct parse * p, int ch);
  98. static void nonnewline(struct parse * p);
  99. static void repeat(struct parse * p, sopno start, int from, int to);
  100. static int seterr(struct parse * p, int e);
  101. static cset *allocset(struct parse * p);
  102. static void freeset(struct parse * p, cset *cs);
  103. static int freezeset(struct parse * p, cset *cs);
  104. static int firstch(struct parse * p, cset *cs);
  105. static int nch(struct parse * p, cset *cs);
  106. static void mcadd(struct parse * p, cset *cs, char *cp);
  107. static void mcinvert(struct parse * p, cset *cs);
  108. static void mccase(struct parse * p, cset *cs);
  109. static int isinsets(struct re_guts * g, int c);
  110. static int samesets(struct re_guts * g, int c1, int c2);
  111. static void categorize(struct parse * p, struct re_guts * g);
  112. static sopno dupl(struct parse * p, sopno start, sopno finish);
  113. static void doemit(struct parse * p, sop op, size_t opnd);
  114. static void doinsert(struct parse * p, sop op, size_t opnd, sopno pos);
  115. static void dofwd(struct parse * p, sopno pos, sop value);
  116. static void enlarge(struct parse * p, sopno size);
  117. static void stripsnug(struct parse * p, struct re_guts * g);
  118. static void findmust(struct parse * p, struct re_guts * g);
  119. static sopno pluscount(struct parse * p, struct re_guts * g);
  120. static int pg_isdigit(int c);
  121. static int pg_isalpha(int c);
  122. static int pg_isupper(int c);
  123. static int pg_islower(int c);
  124. #ifdef __cplusplus
  125. }
  126. #endif
  127. /* ========= end header generated by ./mkh ========= */
  128. static pg_wchar nuls[10]; /* place to point scanner in event of
  129.  * error */
  130. /*
  131.  * macros for use with parse structure
  132.  * BEWARE: these know that the parse structure is named `p' !!!
  133.  */
  134. #define PEEK() (*p->next)
  135. #define PEEK2() (*(p->next+1))
  136. #define MORE() (p->next < p->end)
  137. #define MORE2() (p->next+1 < p->end)
  138. #define SEE(c) (MORE() && PEEK() == (c))
  139. #define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
  140. #define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
  141. #define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
  142. #define NEXT() (p->next++)
  143. #define NEXT2() (p->next += 2)
  144. #define NEXTn(n) (p->next += (n))
  145. #define GETNEXT() (*p->next++)
  146. #define SETERROR(e) seterr(p, (e))
  147. #define REQUIRE(co, e) if (!(co)) SETERROR(e)
  148. #define MUSTSEE(c, e) REQUIRE(MORE() && PEEK() == (c), e)
  149. #define MUSTEAT(c, e) REQUIRE(MORE() && GETNEXT() == (c), e)
  150. #define MUSTNOTSEE(c, e) REQUIRE(!MORE() || PEEK() != (c), e)
  151. #define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
  152. #define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
  153. #define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
  154. #define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
  155. #define HERE() (p->slen)
  156. #define THERE() (p->slen - 1)
  157. #define THERETHERE() (p->slen - 2)
  158. #define DROP(n) (p->slen -= (n))
  159. #ifndef NDEBUG
  160. static int never = 0; /* for use in asserts; shuts lint up */
  161. #else
  162. #define never 0 /* some <assert.h>s have bugs too */
  163. #endif
  164. /*
  165.  - regcomp - interface for parser and compilation
  166.  = extern int regcomp(regex_t *, const char *, int);
  167.  = #define REG_BASIC 0000
  168.  = #define REG_EXTENDED 0001
  169.  = #define REG_ICASE 0002
  170.  = #define REG_NOSUB 0004
  171.  = #define REG_NEWLINE 0010
  172.  = #define REG_NOSPEC 0020
  173.  = #define REG_PEND 0040
  174.  = #define REG_DUMP 0200
  175.  */
  176. int /* 0 success, otherwise REG_something */
  177. pg95_regcomp(preg, pattern, cflags)
  178. regex_t    *preg;
  179. const char *pattern;
  180. int cflags;
  181. {
  182. struct parse pa;
  183. struct re_guts *g;
  184. struct parse *p = &pa;
  185. int i;
  186. size_t len;
  187. #ifdef MULTIBYTE
  188. pg_wchar   *wcp;
  189. #endif
  190. #ifdef REDEBUG
  191. #define  GOODFLAGS(f)  (f)
  192. #else
  193. #define  GOODFLAGS(f)  ((f)&~REG_DUMP)
  194. #endif
  195. cflags = GOODFLAGS(cflags);
  196. if ((cflags & REG_EXTENDED) && (cflags & REG_NOSPEC))
  197. return REG_INVARG;
  198. if (cflags & REG_PEND)
  199. {
  200. #ifdef MULTIBYTE
  201. wcp = preg->patsave;
  202. if (preg->re_endp < wcp)
  203. return REG_INVARG;
  204. len = preg->re_endp - wcp;
  205. #else
  206. if (preg->re_endp < pattern)
  207. return REG_INVARG;
  208. len = preg->re_endp - pattern;
  209. #endif
  210. }
  211. else
  212. {
  213. #ifdef MULTIBYTE
  214. wcp = (pg_wchar *) malloc((strlen(pattern) + 1) * sizeof(pg_wchar));
  215. if (wcp == NULL)
  216. return REG_ESPACE;
  217. preg->patsave = wcp;
  218. (void) pg_mb2wchar((unsigned char *) pattern, wcp);
  219. len = pg_wchar_strlen(wcp);
  220. #else
  221. len = strlen((char *) pattern);
  222. #endif
  223. }
  224. /* do the mallocs early so failure handling is easy */
  225. g = (struct re_guts *) malloc(sizeof(struct re_guts) +
  226.   (NC - 1) * sizeof(cat_t));
  227. if (g == NULL)
  228. return REG_ESPACE;
  229. p->ssize = len / (size_t) 2 *(size_t) 3 + (size_t) 1; /* ugh */
  230. p->strip = (sop *) malloc(p->ssize * sizeof(sop));
  231. p->slen = 0;
  232. if (p->strip == NULL)
  233. {
  234. free((char *) g);
  235. return REG_ESPACE;
  236. }
  237. /* set things up */
  238. p->g = g;
  239. #ifdef MULTIBYTE
  240. p->next = wcp;
  241. #else
  242. p->next = (pg_wchar *) pattern; /* convenience; we do not modify
  243.  * it */
  244. #endif
  245. p->end = p->next + len;
  246. p->error = 0;
  247. p->ncsalloc = 0;
  248. for (i = 0; i < NPAREN; i++)
  249. {
  250. p->pbegin[i] = 0;
  251. p->pend[i] = 0;
  252. }
  253. g->csetsize = NC;
  254. g->sets = NULL;
  255. g->setbits = NULL;
  256. g->ncsets = 0;
  257. g->cflags = cflags;
  258. g->iflags = 0;
  259. g->nbol = 0;
  260. g->neol = 0;
  261. g->must = NULL;
  262. g->mlen = 0;
  263. g->nsub = 0;
  264. g->ncategories = 1; /* category 0 is "everything else" */
  265. g->categories = &g->catspace[-(CHAR_MIN)];
  266. memset((char *) g->catspace, 0, NC * sizeof(cat_t));
  267. g->backrefs = 0;
  268. /* do it */
  269. EMIT(OEND, 0);
  270. g->firststate = THERE();
  271. if (cflags & REG_EXTENDED)
  272. p_ere(p, OUT);
  273. else if (cflags & REG_NOSPEC)
  274. p_str(p);
  275. else
  276. p_bre(p, OUT, OUT);
  277. EMIT(OEND, 0);
  278. g->laststate = THERE();
  279. /* tidy up loose ends and fill things in */
  280. categorize(p, g);
  281. stripsnug(p, g);
  282. findmust(p, g);
  283. g->nplus = pluscount(p, g);
  284. g->magic = MAGIC2;
  285. preg->re_nsub = g->nsub;
  286. preg->re_g = g;
  287. preg->re_magic = MAGIC1;
  288. #ifndef REDEBUG
  289. /* not debugging, so can't rely on the assert() in regexec() */
  290. if (g->iflags & BAD)
  291. SETERROR(REG_ASSERT);
  292. #endif
  293. /* win or lose, we're done */
  294. if (p->error != 0) /* lose */
  295. pg95_regfree(preg);
  296. return p->error;
  297. }
  298. /*
  299.  - p_ere - ERE parser top level, concatenation and alternation
  300.  == static void p_ere(struct parse *p, int stop);
  301.  */
  302. static void
  303. p_ere(p, stop)
  304. struct parse *p;
  305. int stop; /* character this ERE should end at */
  306. {
  307. char c;
  308. sopno prevback = 0;
  309. sopno prevfwd = 0;
  310. sopno conc;
  311. int first = 1; /* is this the first alternative? */
  312. for (;;)
  313. {
  314. /* do a bunch of concatenated expressions */
  315. conc = HERE();
  316. while (MORE() && (c = PEEK()) != '|' && c != stop)
  317. p_ere_exp(p);
  318. REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
  319. if (!EAT('|'))
  320. break; /* NOTE BREAK OUT */
  321. if (first)
  322. {
  323. INSERT(OCH_, conc); /* offset is wrong */
  324. prevfwd = conc;
  325. prevback = conc;
  326. first = 0;
  327. }
  328. ASTERN(OOR1, prevback);
  329. prevback = THERE();
  330. AHEAD(prevfwd); /* fix previous offset */
  331. prevfwd = HERE();
  332. EMIT(OOR2, 0); /* offset is very wrong */
  333. }
  334. if (!first)
  335. { /* tail-end fixups */
  336. AHEAD(prevfwd);
  337. ASTERN(O_CH, prevback);
  338. }
  339. assert(!MORE() || SEE(stop));
  340. }
  341. /*
  342.  - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
  343.  == static void p_ere_exp(struct parse *p);
  344.  */
  345. static void
  346. p_ere_exp(p)
  347. struct parse *p;
  348. {
  349. pg_wchar c;
  350. sopno pos;
  351. int count;
  352. int count2;
  353. sopno subno;
  354. int wascaret = 0;
  355. assert(MORE()); /* caller should have ensured this */
  356. c = GETNEXT();
  357. pos = HERE();
  358. switch (c)
  359. {
  360. case '(':
  361. REQUIRE(MORE(), REG_EPAREN);
  362. p->g->nsub++;
  363. subno = p->g->nsub;
  364. if (subno < NPAREN)
  365. p->pbegin[subno] = HERE();
  366. EMIT(OLPAREN, subno);
  367. if (!SEE(')'))
  368. p_ere(p, ')');
  369. if (subno < NPAREN)
  370. {
  371. p->pend[subno] = HERE();
  372. assert(p->pend[subno] != 0);
  373. }
  374. EMIT(ORPAREN, subno);
  375. MUSTEAT(')', REG_EPAREN);
  376. break;
  377. #ifndef POSIX_MISTAKE
  378. case ')': /* happens only if no current unmatched ( */
  379. /*
  380.  * You may ask, why the ifndef?  Because I didn't notice this
  381.  * until slightly too late for 1003.2, and none of the other
  382.  * 1003.2 regular-expression reviewers noticed it at all.  So
  383.  * an unmatched ) is legal POSIX, at least until we can get it
  384.  * fixed.
  385.  */
  386. SETERROR(REG_EPAREN);
  387. break;
  388. #endif
  389. case '^':
  390. EMIT(OBOL, 0);
  391. p->g->iflags |= USEBOL;
  392. p->g->nbol++;
  393. wascaret = 1;
  394. break;
  395. case '$':
  396. EMIT(OEOL, 0);
  397. p->g->iflags |= USEEOL;
  398. p->g->neol++;
  399. break;
  400. case '|':
  401. SETERROR(REG_EMPTY);
  402. break;
  403. case '*':
  404. case '+':
  405. case '?':
  406. SETERROR(REG_BADRPT);
  407. break;
  408. case '.':
  409. if (p->g->cflags & REG_NEWLINE)
  410. nonnewline(p);
  411. else
  412. EMIT(OANY, 0);
  413. break;
  414. case '[':
  415. p_bracket(p);
  416. break;
  417. case '\':
  418. REQUIRE(MORE(), REG_EESCAPE);
  419. c = GETNEXT();
  420. ordinary(p, c);
  421. break;
  422. case '{': /* okay as ordinary except if digit
  423.  * follows */
  424. REQUIRE(!MORE() || !pg_isdigit(PEEK()), REG_BADRPT);
  425. /* FALLTHROUGH */
  426. default:
  427. ordinary(p, c);
  428. break;
  429. }
  430. if (!MORE())
  431. return;
  432. c = PEEK();
  433. /* we call { a repetition if followed by a digit */
  434. if (!(c == '*' || c == '+' || c == '?' ||
  435.   (c == '{' && MORE2() && pg_isdigit(PEEK2()))))
  436. return; /* no repetition, we're done */
  437. NEXT();
  438. REQUIRE(!wascaret, REG_BADRPT);
  439. switch (c)
  440. {
  441. case '*': /* implemented as +? */
  442. /* this case does not require the (y|) trick, noKLUDGE */
  443. INSERT(OPLUS_, pos);
  444. ASTERN(O_PLUS, pos);
  445. INSERT(OQUEST_, pos);
  446. ASTERN(O_QUEST, pos);
  447. break;
  448. case '+':
  449. INSERT(OPLUS_, pos);
  450. ASTERN(O_PLUS, pos);
  451. break;
  452. case '?':
  453. /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
  454. INSERT(OCH_, pos); /* offset slightly wrong */
  455. ASTERN(OOR1, pos); /* this one's right */
  456. AHEAD(pos); /* fix the OCH_ */
  457. EMIT(OOR2, 0); /* offset very wrong... */
  458. AHEAD(THERE()); /* ...so fix it */
  459. ASTERN(O_CH, THERETHERE());
  460. break;
  461. case '{':
  462. count = p_count(p);
  463. if (EAT(','))
  464. {
  465. if (pg_isdigit(PEEK()))
  466. {
  467. count2 = p_count(p);
  468. REQUIRE(count <= count2, REG_BADBR);
  469. }
  470. else
  471. /* single number with comma */
  472. count2 = INFINITY;
  473. }
  474. else
  475. /* just a single number */
  476. count2 = count;
  477. repeat(p, pos, count, count2);
  478. if (!EAT('}'))
  479. { /* error heuristics */
  480. while (MORE() && PEEK() != '}')
  481. NEXT();
  482. REQUIRE(MORE(), REG_EBRACE);
  483. SETERROR(REG_BADBR);
  484. }
  485. break;
  486. }
  487. if (!MORE())
  488. return;
  489. c = PEEK();
  490. if (!(c == '*' || c == '+' || c == '?' ||
  491.   (c == '{' && MORE2() && pg_isdigit(PEEK2()))))
  492. return;
  493. SETERROR(REG_BADRPT);
  494. }
  495. /*
  496.  - p_str - string (no metacharacters) "parser"
  497.  == static void p_str(struct parse *p);
  498.  */
  499. static void
  500. p_str(p)
  501. struct parse *p;
  502. {
  503. REQUIRE(MORE(), REG_EMPTY);
  504. while (MORE())
  505. ordinary(p, GETNEXT());
  506. }
  507. /*
  508.  - p_bre - BRE parser top level, anchoring and concatenation
  509.  == static void p_bre(struct parse *p, int end1, 
  510.  == int end2);
  511.  * Giving end1 as OUT essentially eliminates the end1/end2 check.
  512.  *
  513.  * This implementation is a bit of a kludge, in that a trailing $ is first
  514.  * taken as an ordinary character and then revised to be an anchor.  The
  515.  * only undesirable side effect is that '$' gets included as a character
  516.  * category in such cases. This is fairly harmless; not worth fixing.
  517.  * The amount of lookahead needed to avoid this kludge is excessive.
  518.  */
  519. static void
  520. p_bre(p, end1, end2)
  521. struct parse *p;
  522. int end1; /* first terminating character */
  523. int end2; /* second terminating character */
  524. {
  525. sopno start = HERE();
  526. int first = 1; /* first subexpression? */
  527. int wasdollar = 0;
  528. if (EAT('^'))
  529. {
  530. EMIT(OBOL, 0);
  531. p->g->iflags |= USEBOL;
  532. p->g->nbol++;
  533. }
  534. while (MORE() && !SEETWO(end1, end2))
  535. {
  536. wasdollar = p_simp_re(p, first);
  537. first = 0;
  538. }
  539. if (wasdollar)
  540. { /* oops, that was a trailing anchor */
  541. DROP(1);
  542. EMIT(OEOL, 0);
  543. p->g->iflags |= USEEOL;
  544. p->g->neol++;
  545. }
  546. REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
  547. }
  548. /*
  549.  - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
  550.  == static int p_simp_re(struct parse *p, int starordinary);
  551.  */
  552. static int /* was the simple RE an unbackslashed $? */
  553. p_simp_re(p, starordinary)
  554. struct parse *p;
  555. int starordinary; /* is a leading * an ordinary character? */
  556. {
  557. int c;
  558. int count;
  559. int count2;
  560. sopno pos;
  561. int i;
  562. sopno subno;
  563. #define  BACKSL  (1<<24)
  564. pos = HERE(); /* repetion op, if any, covers from here */
  565. assert(MORE()); /* caller should have ensured this */
  566. c = GETNEXT();
  567. if (c == '\')
  568. {
  569. REQUIRE(MORE(), REG_EESCAPE);
  570. #ifdef MULTIBYTE
  571. c = BACKSL | (pg_wchar) GETNEXT();
  572. #else
  573. c = BACKSL | (unsigned char) GETNEXT();
  574. #endif
  575. }
  576. switch (c)
  577. {
  578. case '.':
  579. if (p->g->cflags & REG_NEWLINE)
  580. nonnewline(p);
  581. else
  582. EMIT(OANY, 0);
  583. break;
  584. case '[':
  585. p_bracket(p);
  586. break;
  587. case BACKSL | '{':
  588. SETERROR(REG_BADRPT);
  589. break;
  590. case BACKSL | '(':
  591. p->g->nsub++;
  592. subno = p->g->nsub;
  593. if (subno < NPAREN)
  594. p->pbegin[subno] = HERE();
  595. EMIT(OLPAREN, subno);
  596. /* the MORE here is an error heuristic */
  597. if (MORE() && !SEETWO('\', ')'))
  598. p_bre(p, '\', ')');
  599. if (subno < NPAREN)
  600. {
  601. p->pend[subno] = HERE();
  602. assert(p->pend[subno] != 0);
  603. }
  604. EMIT(ORPAREN, subno);
  605. REQUIRE(EATTWO('\', ')'), REG_EPAREN);
  606. break;
  607. case BACKSL | ')': /* should not get here -- must be user */
  608. case BACKSL | '}':
  609. SETERROR(REG_EPAREN);
  610. break;
  611. case BACKSL | '1':
  612. case BACKSL | '2':
  613. case BACKSL | '3':
  614. case BACKSL | '4':
  615. case BACKSL | '5':
  616. case BACKSL | '6':
  617. case BACKSL | '7':
  618. case BACKSL | '8':
  619. case BACKSL | '9':
  620. i = (c & ~BACKSL) - '0';
  621. assert(i < NPAREN);
  622. if (p->pend[i] != 0)
  623. {
  624. assert(i <= p->g->nsub);
  625. EMIT(OBACK_, i);
  626. assert(p->pbegin[i] != 0);
  627. assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
  628. assert(OP(p->strip[p->pend[i]]) == ORPAREN);
  629. dupl(p, p->pbegin[i] + 1, p->pend[i]);
  630. EMIT(O_BACK, i);
  631. }
  632. else
  633. SETERROR(REG_ESUBREG);
  634. p->g->backrefs = 1;
  635. break;
  636. case '*':
  637. REQUIRE(starordinary, REG_BADRPT);
  638. /* FALLTHROUGH */
  639. default:
  640. ordinary(p, c & ~BACKSL);
  641. break;
  642. }
  643. if (EAT('*'))
  644. { /* implemented as +? */
  645. /* this case does not require the (y|) trick, noKLUDGE */
  646. INSERT(OPLUS_, pos);
  647. ASTERN(O_PLUS, pos);
  648. INSERT(OQUEST_, pos);
  649. ASTERN(O_QUEST, pos);
  650. }
  651. else if (EATTWO('\', '{'))
  652. {
  653. count = p_count(p);
  654. if (EAT(','))
  655. {
  656. if (MORE() && pg_isdigit(PEEK()))
  657. {
  658. count2 = p_count(p);
  659. REQUIRE(count <= count2, REG_BADBR);
  660. }
  661. else
  662. /* single number with comma */
  663. count2 = INFINITY;
  664. }
  665. else
  666. /* just a single number */
  667. count2 = count;
  668. repeat(p, pos, count, count2);
  669. if (!EATTWO('\', '}'))
  670. { /* error heuristics */
  671. while (MORE() && !SEETWO('\', '}'))
  672. NEXT();
  673. REQUIRE(MORE(), REG_EBRACE);
  674. SETERROR(REG_BADBR);
  675. }
  676. }
  677. else if (c == (unsigned char) '$') /* $ (but not $) ends it */
  678. return 1;
  679. return 0;
  680. }
  681. /*
  682.  - p_count - parse a repetition count
  683.  == static int p_count(struct parse *p);
  684.  */
  685. static int /* the value */
  686. p_count(p)
  687. struct parse *p;
  688. {
  689. int count = 0;
  690. int ndigits = 0;
  691. while (MORE() && pg_isdigit(PEEK()) && count <= DUPMAX)
  692. {
  693. count = count * 10 + (GETNEXT() - '0');
  694. ndigits++;
  695. }
  696. REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
  697. return count;
  698. }
  699. /*
  700.  - p_bracket - parse a bracketed character list
  701.  == static void p_bracket(struct parse *p);
  702.  *
  703.  * Note a significant property of this code:  if the allocset() did SETERROR,
  704.  * no set operations are done.
  705.  */
  706. static void
  707. p_bracket(p)
  708. struct parse *p;
  709. {
  710. cset    *cs = allocset(p);
  711. int invert = 0;
  712. #ifdef MULTIBYTE
  713. pg_wchar sp1[] = {'[', ':', '<', ':', ']', ']'};
  714. pg_wchar sp2[] = {'[', ':', '>', ':', ']', ']'};
  715. #endif
  716. /* Dept of Truly Sickening Special-Case Kludges */
  717. #ifdef MULTIBYTE
  718. if (p->next + 5 < p->end && pg_wchar_strncmp(p->next, sp1, 6) == 0)
  719. #else
  720. if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0)
  721. #endif
  722. {
  723. EMIT(OBOW, 0);
  724. NEXTn(6);
  725. return;
  726. }
  727. #ifdef MULTIBYTE
  728. if (p->next + 5 < p->end && pg_wchar_strncmp(p->next, sp2, 6) == 0)
  729. #else
  730. if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0)
  731. #endif
  732. {
  733. EMIT(OEOW, 0);
  734. NEXTn(6);
  735. return;
  736. }
  737. if (EAT('^'))
  738. invert++; /* make note to invert set at end */
  739. if (EAT(']'))
  740. CHadd(cs, ']');
  741. else if (EAT('-'))
  742. CHadd(cs, '-');
  743. while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
  744. p_b_term(p, cs);
  745. if (EAT('-'))
  746. CHadd(cs, '-');
  747. MUSTEAT(']', REG_EBRACK);
  748. if (p->error != 0) /* don't mess things up further */
  749. return;
  750. if (p->g->cflags & REG_ICASE)
  751. {
  752. int i;
  753. int ci;
  754. for (i = p->g->csetsize - 1; i >= 0; i--)
  755. if (CHIN(cs, i) && pg_isalpha(i))
  756. {
  757. ci = othercase(i);
  758. if (ci != i)
  759. CHadd(cs, ci);
  760. }
  761. if (cs->multis != NULL)
  762. mccase(p, cs);
  763. }
  764. if (invert)
  765. {
  766. int i;
  767. for (i = p->g->csetsize - 1; i >= 0; i--)
  768. if (CHIN(cs, i))
  769. CHsub(cs, i);
  770. else
  771. CHadd(cs, i);
  772. if (p->g->cflags & REG_NEWLINE)
  773. CHsub(cs, 'n');
  774. if (cs->multis != NULL)
  775. mcinvert(p, cs);
  776. }
  777. assert(cs->multis == NULL); /* xxx */
  778. if (nch(p, cs) == 1)
  779. { /* optimize singleton sets */
  780. ordinary(p, firstch(p, cs));
  781. freeset(p, cs);
  782. }
  783. else
  784. EMIT(OANYOF, freezeset(p, cs));
  785. }
  786. /*
  787.  - p_b_term - parse one term of a bracketed character list
  788.  == static void p_b_term(struct parse *p, cset *cs);
  789.  */
  790. static void
  791. p_b_term(p, cs)
  792. struct parse *p;
  793. cset    *cs;
  794. {
  795. pg_wchar c;
  796. pg_wchar start,
  797. finish;
  798. int i;
  799. /* classify what we've got */
  800. switch ((MORE()) ? PEEK() : '')
  801. {
  802. case '[':
  803. c = (MORE2()) ? PEEK2() : '';
  804. break;
  805. case '-':
  806. SETERROR(REG_ERANGE);
  807. return; /* NOTE RETURN */
  808. break;
  809. default:
  810. c = '';
  811. break;
  812. }
  813. switch (c)
  814. {
  815. case ':': /* character class */
  816. NEXT2();
  817. REQUIRE(MORE(), REG_EBRACK);
  818. c = PEEK();
  819. REQUIRE(c != '-' && c != ']', REG_ECTYPE);
  820. p_b_cclass(p, cs);
  821. REQUIRE(MORE(), REG_EBRACK);
  822. REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
  823. break;
  824. case '=': /* equivalence class */
  825. NEXT2();
  826. REQUIRE(MORE(), REG_EBRACK);
  827. c = PEEK();
  828. REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
  829. p_b_eclass(p, cs);
  830. REQUIRE(MORE(), REG_EBRACK);
  831. REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
  832. break;
  833. default: /* symbol, ordinary character, or range */
  834. /* xxx revision needed for multichar stuff */
  835. start = p_b_symbol(p);
  836. if (SEE('-') && MORE2() && PEEK2() != ']')
  837. {
  838. /* range */
  839. NEXT();
  840. if (EAT('-'))
  841. finish = '-';
  842. else
  843. finish = p_b_symbol(p);
  844. }
  845. else
  846. finish = start;
  847. /* xxx what about signed chars here... */
  848. REQUIRE(start <= finish, REG_ERANGE);
  849. #ifdef MULTIBYTE
  850. if (CHlc(start) != CHlc(finish))
  851. SETERROR(REG_ERANGE);
  852. #endif
  853. for (i = start; i <= finish; i++)
  854. CHadd(cs, i);
  855. break;
  856. }
  857. }
  858. /*
  859.  - p_b_cclass - parse a character-class name and deal with it
  860.  == static void p_b_cclass(struct parse *p, cset *cs);
  861.  */
  862. static void
  863. p_b_cclass(p, cs)
  864. struct parse *p;
  865. cset    *cs;
  866. {
  867. pg_wchar   *sp = p->next;
  868. struct cclass *cp;
  869. size_t len;
  870. char    *u;
  871. char c;
  872. while (MORE() && pg_isalpha(PEEK()))
  873. NEXT();
  874. len = p->next - sp;
  875. for (cp = cclasses; cp->name != NULL; cp++)
  876. #ifdef MULTIBYTE
  877. if (pg_char_and_wchar_strncmp(cp->name, sp, len) == 0 && cp->name[len] == '')
  878. #else
  879. if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '')
  880. #endif
  881. break;
  882. if (cp->name == NULL)
  883. {
  884. /* oops, didn't find it */
  885. SETERROR(REG_ECTYPE);
  886. return;
  887. }
  888. u = cp->chars;
  889. while ((c = *u++) != '')
  890. CHadd(cs, c);
  891. for (u = cp->multis; *u != ''; u += strlen(u) + 1)
  892. MCadd(p, cs, u);
  893. }
  894. /*
  895.  - p_b_eclass - parse an equivalence-class name and deal with it
  896.  == static void p_b_eclass(struct parse *p, cset *cs);
  897.  *
  898.  * This implementation is incomplete. xxx
  899.  */
  900. static void
  901. p_b_eclass(p, cs)
  902. struct parse *p;
  903. cset    *cs;
  904. {
  905. char c;
  906. c = p_b_coll_elem(p, '=');
  907. CHadd(cs, c);
  908. }
  909. /*
  910.  - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
  911.  == static char p_b_symbol(struct parse *p);
  912.  */
  913. static pg_wchar /* value of symbol */
  914. p_b_symbol(p)
  915. struct parse *p;
  916. {
  917. pg_wchar value;
  918. REQUIRE(MORE(), REG_EBRACK);
  919. if (!EATTWO('[', '.'))
  920. return GETNEXT();
  921. /* collating symbol */
  922. value = p_b_coll_elem(p, '.');
  923. REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
  924. return value;
  925. }
  926. /*
  927.  - p_b_coll_elem - parse a collating-element name and look it up
  928.  == static char p_b_coll_elem(struct parse *p, int endc);
  929.  */
  930. static char /* value of collating element */
  931. p_b_coll_elem(p, endc)
  932. struct parse *p;
  933. int endc; /* name ended by endc,']' */
  934. {
  935. pg_wchar   *sp = p->next;
  936. struct cname *cp;
  937. int len;
  938. while (MORE() && !SEETWO(endc, ']'))
  939. NEXT();
  940. if (!MORE())
  941. {
  942. SETERROR(REG_EBRACK);
  943. return 0;
  944. }
  945. len = p->next - sp;
  946. for (cp = cnames; cp->name != NULL; cp++)
  947. #ifdef MULTIBYTE
  948. if (pg_char_and_wchar_strncmp(cp->name, sp, len) == 0 && cp->name[len] == '')
  949. #else
  950. if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '')
  951. #endif
  952. return cp->code; /* known name */
  953. if (len == 1)
  954. return *sp; /* single character */
  955. SETERROR(REG_ECOLLATE); /* neither */
  956. return 0;
  957. }
  958. /*
  959.  - othercase - return the case counterpart of an alphabetic
  960.  == static char othercase(int ch);
  961.  */
  962. #ifdef MULTIBYTE
  963. static unsigned char /* if no counterpart, return ch */
  964. #else
  965. static char /* if no counterpart, return ch */
  966. #endif
  967. othercase(ch)
  968. int ch;
  969. {
  970. assert(pg_isalpha(ch));
  971. if (pg_isupper(ch))
  972. #ifdef MULTIBYTE
  973. return (unsigned char) tolower(ch);
  974. #else
  975. return tolower(ch);
  976. #endif
  977. else if (pg_islower(ch))
  978. #ifdef MULTIBYTE
  979. return (unsigned char) toupper(ch);
  980. #else
  981. return toupper(ch);
  982. #endif
  983. else
  984. /* peculiar, but could happen */
  985. #ifdef MULTIBYTE
  986. return (unsigned char) ch;
  987. #else
  988. return ch;
  989. #endif
  990. }
  991. /*
  992.  - bothcases - emit a dualcase version of a two-case character
  993.  == static void bothcases(struct parse *p, int ch);
  994.  *
  995.  * Boy, is this implementation ever a kludge...
  996.  */
  997. static void
  998. bothcases(p, ch)
  999. struct parse *p;
  1000. int ch;
  1001. {
  1002. pg_wchar   *oldnext = p->next;
  1003. pg_wchar   *oldend = p->end;
  1004. pg_wchar bracket[3];
  1005. assert(othercase(ch) != ch);/* p_bracket() would recurse */
  1006. p->next = bracket;
  1007. p->end = bracket + 2;
  1008. bracket[0] = ch;
  1009. bracket[1] = ']';
  1010. bracket[2] = '';
  1011. p_bracket(p);
  1012. assert(p->next == bracket + 2);
  1013. p->next = oldnext;
  1014. p->end = oldend;
  1015. }
  1016. /*
  1017.  - ordinary - emit an ordinary character
  1018.  == static void ordinary(struct parse *p, int ch);
  1019.  */
  1020. static void
  1021. ordinary(p, ch)
  1022. struct parse *p;
  1023. int ch;
  1024. {
  1025. cat_t    *cap = p->g->categories;
  1026. if ((p->g->cflags & REG_ICASE) && pg_isalpha(ch) && othercase(ch) != ch)
  1027. bothcases(p, ch);
  1028. else
  1029. {
  1030. #ifdef MULTIBYTE
  1031. EMIT(OCHAR, (pg_wchar) ch);
  1032. #else
  1033. EMIT(OCHAR, (unsigned char) ch);
  1034. #endif
  1035. if (ch >= CHAR_MIN && ch <= CHAR_MAX && cap[ch] == 0)
  1036. cap[ch] = p->g->ncategories++;
  1037. }
  1038. }
  1039. /*
  1040.  - nonnewline - emit REG_NEWLINE version of OANY
  1041.  == static void nonnewline(struct parse *p);
  1042.  *
  1043.  * Boy, is this implementation ever a kludge...
  1044.  */
  1045. static void
  1046. nonnewline(p)
  1047. struct parse *p;
  1048. {
  1049. pg_wchar   *oldnext = p->next;
  1050. pg_wchar   *oldend = p->end;
  1051. pg_wchar bracket[4];
  1052. p->next = bracket;
  1053. p->end = bracket + 3;
  1054. bracket[0] = '^';
  1055. bracket[1] = 'n';
  1056. bracket[2] = ']';
  1057. bracket[3] = '';
  1058. p_bracket(p);
  1059. assert(p->next == bracket + 3);
  1060. p->next = oldnext;
  1061. p->end = oldend;
  1062. }
  1063. /*
  1064.  - repeat - generate code for a bounded repetition, recursively if needed
  1065.  == static void repeat(struct parse *p, sopno start, int from, int to);
  1066.  */
  1067. static void
  1068. repeat(p, start, from, to)
  1069. struct parse *p;
  1070. sopno start; /* operand from here to end of strip */
  1071. int from; /* repeated from this number */
  1072. int to; /* to this number of times (maybe
  1073.  * INFINITY) */
  1074. {
  1075. sopno finish = HERE();
  1076. #define  N  2
  1077. #define  INF  3
  1078. #define  REP(f, t)  ((f)*8 + (t))
  1079. #define  MAP(n)  (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
  1080. sopno copy;
  1081. if (p->error != 0) /* head off possible runaway recursion */
  1082. return;
  1083. assert(from <= to);
  1084. switch (REP(MAP(from), MAP(to)))
  1085. {
  1086. case REP(0, 0): /* must be user doing this */
  1087. DROP(finish - start); /* drop the operand */
  1088. break;
  1089. case REP(0, 1): /* as x{1,1}? */
  1090. case REP(0, N): /* as x{1,n}? */
  1091. case REP(0, INF): /* as x{1,}? */
  1092. /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
  1093. INSERT(OCH_, start);/* offset is wrong... */
  1094. repeat(p, start + 1, 1, to);
  1095. ASTERN(OOR1, start);
  1096. AHEAD(start); /* ... fix it */
  1097. EMIT(OOR2, 0);
  1098. AHEAD(THERE());
  1099. ASTERN(O_CH, THERETHERE());
  1100. break;
  1101. case REP(1, 1): /* trivial case */
  1102. /* done */
  1103. break;
  1104. case REP(1, N): /* as x?x{1,n-1} */
  1105. /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
  1106. INSERT(OCH_, start);
  1107. ASTERN(OOR1, start);
  1108. AHEAD(start);
  1109. EMIT(OOR2, 0); /* offset very wrong... */
  1110. AHEAD(THERE()); /* ...so fix it */
  1111. ASTERN(O_CH, THERETHERE());
  1112. copy = dupl(p, start + 1, finish + 1);
  1113. assert(copy == finish + 4);
  1114. repeat(p, copy, 1, to - 1);
  1115. break;
  1116. case REP(1, INF): /* as x+ */
  1117. INSERT(OPLUS_, start);
  1118. ASTERN(O_PLUS, start);
  1119. break;
  1120. case REP(N, N): /* as xx{m-1,n-1} */
  1121. copy = dupl(p, start, finish);
  1122. repeat(p, copy, from - 1, to - 1);
  1123. break;
  1124. case REP(N, INF): /* as xx{n-1,INF} */
  1125. copy = dupl(p, start, finish);
  1126. repeat(p, copy, from - 1, to);
  1127. break;
  1128. default: /* "can't happen" */
  1129. SETERROR(REG_ASSERT); /* just in case */
  1130. break;
  1131. }
  1132. }
  1133. /*
  1134.  - seterr - set an error condition
  1135.  == static int seterr(struct parse *p, int e);
  1136.  */
  1137. static int /* useless but makes type checking happy */
  1138. seterr(p, e)
  1139. struct parse *p;
  1140. int e;
  1141. {
  1142. if (p->error == 0) /* keep earliest error condition */
  1143. p->error = e;
  1144. p->next = nuls; /* try to bring things to a halt */
  1145. p->end = nuls;
  1146. return 0; /* make the return value well-defined */
  1147. }
  1148. /*
  1149.  - allocset - allocate a set of characters for []
  1150.  == static cset *allocset(struct parse *p);
  1151.  */
  1152. static cset *
  1153. allocset(p)
  1154. struct parse *p;
  1155. {
  1156. int no = p->g->ncsets++;
  1157. size_t nc;
  1158. size_t nbytes;
  1159. cset    *cs;
  1160. size_t css = (size_t) p->g->csetsize;
  1161. int i;
  1162. if (no >= p->ncsalloc)
  1163. { /* need another column of space */
  1164. p->ncsalloc += CHAR_BIT;
  1165. nc = p->ncsalloc;
  1166. assert(nc % CHAR_BIT == 0);
  1167. nbytes = nc / CHAR_BIT * css;
  1168. if (p->g->sets == NULL)
  1169. p->g->sets = (cset *) malloc(nc * sizeof(cset));
  1170. else
  1171. p->g->sets = (cset *) realloc((char *) p->g->sets,
  1172.   nc * sizeof(cset));
  1173. if (p->g->setbits == NULL)
  1174. p->g->setbits = (uch *) malloc(nbytes);
  1175. else
  1176. {
  1177. p->g->setbits = (uch *) realloc((char *) p->g->setbits,
  1178. nbytes);
  1179. /* xxx this isn't right if setbits is now NULL */
  1180. for (i = 0; i < no; i++)
  1181. p->g->sets[i].ptr = p->g->setbits + css * (i / CHAR_BIT);
  1182. }
  1183. if (p->g->sets != NULL && p->g->setbits != NULL)
  1184. memset((char *) p->g->setbits + (nbytes - css),
  1185.    0, css);
  1186. else
  1187. {
  1188. no = 0;
  1189. SETERROR(REG_ESPACE);
  1190. /* caller's responsibility not to do set ops */
  1191. }
  1192. }
  1193. assert(p->g->sets != NULL); /* xxx */
  1194. cs = &p->g->sets[no];
  1195. cs->ptr = p->g->setbits + css * ((no) / CHAR_BIT);
  1196. cs->mask = 1 << ((no) % CHAR_BIT);
  1197. cs->hash = 0;
  1198. cs->smultis = 0;
  1199. cs->multis = NULL;
  1200. return cs;
  1201. }
  1202. /*
  1203.  - freeset - free a now-unused set
  1204.  == static void freeset(struct parse *p, cset *cs);
  1205.  */
  1206. static void
  1207. freeset(p, cs)
  1208. struct parse *p;
  1209. cset    *cs;
  1210. {
  1211. int i;
  1212. cset    *top = &p->g->sets[p->g->ncsets];
  1213. size_t css = (size_t) p->g->csetsize;
  1214. for (i = 0; i < css; i++)
  1215. CHsub(cs, i);
  1216. if (cs == top - 1) /* recover only the easy case */
  1217. p->g->ncsets--;
  1218. }
  1219. /*
  1220.  - freezeset - final processing on a set of characters
  1221.  == static int freezeset(struct parse *p, cset *cs);
  1222.  *
  1223.  * The main task here is merging identical sets.  This is usually a waste
  1224.  * of time (although the hash code minimizes the overhead), but can win
  1225.  * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
  1226.  * is done using addition rather than xor -- all ASCII [aA] sets xor to
  1227.  * the same value!
  1228.  */
  1229. static int /* set number */
  1230. freezeset(p, cs)
  1231. struct parse *p;
  1232. cset    *cs;
  1233. {
  1234. uch h = cs->hash;
  1235. int i;
  1236. cset    *top = &p->g->sets[p->g->ncsets];
  1237. cset    *cs2;
  1238. size_t css = (size_t) p->g->csetsize;
  1239. /* look for an earlier one which is the same */
  1240. for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
  1241. if (cs2->hash == h && cs2 != cs)
  1242. {
  1243. /* maybe */
  1244. for (i = 0; i < css; i++)
  1245. if (!!CHIN(cs2, i) != !!CHIN(cs, i))
  1246. break; /* no */
  1247. if (i == css)
  1248. break; /* yes */
  1249. }
  1250. if (cs2 < top)
  1251. { /* found one */
  1252. freeset(p, cs);
  1253. cs = cs2;
  1254. }
  1255. return (int) (cs - p->g->sets);
  1256. }
  1257. /*
  1258.  - firstch - return first character in a set (which must have at least one)
  1259.  == static int firstch(struct parse *p, cset *cs);
  1260.  */
  1261. static int /* character; there is no "none" value */
  1262. firstch(p, cs)
  1263. struct parse *p;
  1264. cset    *cs;
  1265. {
  1266. int i;
  1267. size_t css = (size_t) p->g->csetsize;
  1268. for (i = 0; i < css; i++)
  1269. if (CHIN(cs, i))
  1270. return i;
  1271. assert(never);
  1272. return 0; /* arbitrary */
  1273. }
  1274. /*
  1275.  - nch - number of characters in a set
  1276.  == static int nch(struct parse *p, cset *cs);
  1277.  */
  1278. static int
  1279. nch(p, cs)
  1280. struct parse *p;
  1281. cset    *cs;
  1282. {
  1283. int i;
  1284. size_t css = (size_t) p->g->csetsize;
  1285. int n = 0;
  1286. for (i = 0; i < css; i++)
  1287. if (CHIN(cs, i))
  1288. n++;
  1289. return n;
  1290. }
  1291. /*
  1292.  - mcadd - add a collating element to a cset
  1293.  == static void mcadd(struct parse *p, cset *cs, 
  1294.  == char *cp);
  1295.  */
  1296. static void
  1297. mcadd(p, cs, cp)
  1298. struct parse *p;
  1299. cset    *cs;
  1300. char    *cp;
  1301. {
  1302. size_t oldend = cs->smultis;
  1303. cs->smultis += strlen(cp) + 1;
  1304. if (cs->multis == NULL)
  1305. cs->multis = malloc(cs->smultis);
  1306. else
  1307. cs->multis = realloc(cs->multis, cs->smultis);
  1308. if (cs->multis == NULL)
  1309. {
  1310. SETERROR(REG_ESPACE);
  1311. return;
  1312. }
  1313. strcpy(cs->multis + oldend - 1, cp);
  1314. cs->multis[cs->smultis - 1] = '';
  1315. }
  1316. /*
  1317.  - mcsub - subtract a collating element from a cset
  1318.  == static void mcsub(cset *cs, char *cp);
  1319.  */
  1320. /*
  1321. static void
  1322. mcsub(cs, cp)
  1323. cset *cs;
  1324. char *cp;
  1325. {
  1326. char *fp = mcfind(cs, cp);
  1327. size_t len = strlen(fp);
  1328. assert(fp != NULL);
  1329. memmove(fp, fp + len + 1,
  1330. cs->smultis - (fp + len + 1 - cs->multis));
  1331. cs->smultis -= len;
  1332. if (cs->smultis == 0) {
  1333. free(cs->multis);
  1334. cs->multis = NULL;
  1335. return;
  1336. }
  1337. cs->multis = realloc(cs->multis, cs->smultis);
  1338. assert(cs->multis != NULL);
  1339. }
  1340. */
  1341. /*
  1342.  - mcin - is a collating element in a cset?
  1343.  == static int mcin(cset *cs, char *cp);
  1344.  */
  1345. /*
  1346. static int
  1347. mcin(cs, cp)
  1348. cset *cs;
  1349. char *cp;
  1350. {
  1351. return(mcfind(cs, cp) != NULL);
  1352. }
  1353. */
  1354. /*
  1355.  - mcfind - find a collating element in a cset
  1356.  == static char *mcfind(cset *cs, char *cp);
  1357.  */
  1358. /*
  1359. static char *
  1360. mcfind(cs, cp)
  1361. cset *cs;
  1362. char *cp;
  1363. {
  1364. char *p;
  1365. if (cs->multis == NULL)
  1366. return(NULL);
  1367. for (p = cs->multis; *p != ''; p += strlen(p) + 1)
  1368. if (strcmp(cp, p) == 0)
  1369. return(p);
  1370. return(NULL);
  1371. }
  1372. */
  1373. /*
  1374.  - mcinvert - invert the list of collating elements in a cset
  1375.  == static void mcinvert(struct parse *p, cset *cs);
  1376.  *
  1377.  * This would have to know the set of possibilities.  Implementation
  1378.  * is deferred.
  1379.  */
  1380. static void
  1381. mcinvert(p, cs)
  1382. struct parse *p;
  1383. cset    *cs;
  1384. {
  1385. assert(cs->multis == NULL); /* xxx */
  1386. }
  1387. /*
  1388.  - mccase - add case counterparts of the list of collating elements in a cset
  1389.  == static void mccase(struct parse *p, cset *cs);
  1390.  *
  1391.  * This would have to know the set of possibilities.  Implementation
  1392.  * is deferred.
  1393.  */
  1394. static void
  1395. mccase(p, cs)
  1396. struct parse *p;
  1397. cset    *cs;
  1398. {
  1399. assert(cs->multis == NULL); /* xxx */
  1400. }
  1401. /*
  1402.  - isinsets - is this character in any sets?
  1403.  == static int isinsets(struct re_guts *g, int c);
  1404.  */
  1405. static int /* predicate */
  1406. isinsets(g, c)
  1407. struct re_guts *g;
  1408. int c;
  1409. {
  1410. uch    *col;
  1411. int i;
  1412. int ncols = (g->ncsets + (CHAR_BIT - 1)) / CHAR_BIT;
  1413. unsigned uc = (unsigned char) c;
  1414. for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
  1415. if (col[uc] != 0)
  1416. return 1;
  1417. return 0;
  1418. }
  1419. /*
  1420.  - samesets - are these two characters in exactly the same sets?
  1421.  == static int samesets(struct re_guts *g, int c1, int c2);
  1422.  */
  1423. static int /* predicate */
  1424. samesets(g, c1, c2)
  1425. struct re_guts *g;
  1426. int c1;
  1427. int c2;
  1428. {
  1429. uch    *col;
  1430. int i;
  1431. int ncols = (g->ncsets + (CHAR_BIT - 1)) / CHAR_BIT;
  1432. unsigned uc1 = (unsigned char) c1;
  1433. unsigned uc2 = (unsigned char) c2;
  1434. for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
  1435. if (col[uc1] != col[uc2])
  1436. return 0;
  1437. return 1;
  1438. }
  1439. /*
  1440.  - categorize - sort out character categories
  1441.  == static void categorize(struct parse *p, struct re_guts *g);
  1442.  */
  1443. static void
  1444. categorize(p, g)
  1445. struct parse *p;
  1446. struct re_guts *g;
  1447. {
  1448. cat_t    *cats = g->categories;
  1449. int c;
  1450. int c2;
  1451. cat_t cat;
  1452. /* avoid making error situations worse */
  1453. if (p->error != 0)
  1454. return;
  1455. for (c = CHAR_MIN; c <= CHAR_MAX; c++)
  1456. if (cats[c] == 0 && isinsets(g, c))
  1457. {
  1458. cat = g->ncategories++;
  1459. cats[c] = cat;
  1460. for (c2 = c + 1; c2 <= CHAR_MAX; c2++)
  1461. if (cats[c2] == 0 && samesets(g, c, c2))
  1462. cats[c2] = cat;
  1463. }
  1464. }
  1465. /*
  1466.  - dupl - emit a duplicate of a bunch of sops
  1467.  == static sopno dupl(struct parse *p, sopno start, sopno finish);
  1468.  */
  1469. static sopno /* start of duplicate */
  1470. dupl(p, start, finish)
  1471. struct parse *p;
  1472. sopno start; /* from here */
  1473. sopno finish; /* to this less one */
  1474. {
  1475. sopno ret = HERE();
  1476. sopno len = finish - start;
  1477. assert(finish >= start);
  1478. if (len == 0)
  1479. return ret;
  1480. enlarge(p, p->ssize + len); /* this many unexpected additions */
  1481. assert(p->ssize >= p->slen + len);
  1482. memcpy((char *) (p->strip + p->slen),
  1483.    (char *) (p->strip + start), (size_t) len * sizeof(sop));
  1484. p->slen += len;
  1485. return ret;
  1486. }
  1487. /*
  1488.  - doemit - emit a strip operator
  1489.  == static void doemit(struct parse *p, sop op, size_t opnd);
  1490.  *
  1491.  * It might seem better to implement this as a macro with a function as
  1492.  * hard-case backup, but it's just too big and messy unless there are
  1493.  * some changes to the data structures.  Maybe later.
  1494.  */
  1495. static void
  1496. doemit(p, op, opnd)
  1497. struct parse *p;
  1498. sop op;
  1499. size_t opnd;
  1500. {
  1501. /* avoid making error situations worse */
  1502. if (p->error != 0)
  1503. return;
  1504. /* deal with oversize operands ("can't happen", more or less) */
  1505. assert(opnd < 1 << OPSHIFT);
  1506. /* deal with undersized strip */
  1507. if (p->slen >= p->ssize)
  1508. enlarge(p, (p->ssize + 1) / 2 * 3); /* +50% */
  1509. assert(p->slen < p->ssize);
  1510. /* finally, it's all reduced to the easy case */
  1511. p->strip[p->slen++] = SOP(op, opnd);
  1512. }
  1513. /*
  1514.  - doinsert - insert a sop into the strip
  1515.  == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
  1516.  */
  1517. static void
  1518. doinsert(p, op, opnd, pos)
  1519. struct parse *p;
  1520. sop op;
  1521. size_t opnd;
  1522. sopno pos;
  1523. {
  1524. sopno sn;
  1525. sop s;
  1526. int i;
  1527. /* avoid making error situations worse */
  1528. if (p->error != 0)
  1529. return;
  1530. sn = HERE();
  1531. EMIT(op, opnd); /* do checks, ensure space */
  1532. assert(HERE() == sn + 1);
  1533. s = p->strip[sn];
  1534. /* adjust paren pointers */
  1535. assert(pos > 0);
  1536. for (i = 1; i < NPAREN; i++)
  1537. {
  1538. if (p->pbegin[i] >= pos)
  1539. p->pbegin[i]++;
  1540. if (p->pend[i] >= pos)
  1541. p->pend[i]++;
  1542. }
  1543. memmove((char *) &p->strip[pos + 1], (char *) &p->strip[pos],
  1544. (HERE() - pos - 1) * sizeof(sop));
  1545. p->strip[pos] = s;
  1546. }
  1547. /*
  1548.  - dofwd - complete a forward reference
  1549.  == static void dofwd(struct parse *p, sopno pos, sop value);
  1550.  */
  1551. static void
  1552. dofwd(p, pos, value)
  1553. struct parse *p;
  1554. sopno pos;
  1555. sop value;
  1556. {
  1557. /* avoid making error situations worse */
  1558. if (p->error != 0)
  1559. return;
  1560. assert(value < 1 << OPSHIFT);
  1561. p->strip[pos] = OP(p->strip[pos]) | value;
  1562. }
  1563. /*
  1564.  - enlarge - enlarge the strip
  1565.  == static void enlarge(struct parse *p, sopno size);
  1566.  */
  1567. static void
  1568. enlarge(p, size)
  1569. struct parse *p;
  1570. sopno size;
  1571. {
  1572. sop    *sp;
  1573. if (p->ssize >= size)
  1574. return;
  1575. sp = (sop *) realloc(p->strip, size * sizeof(sop));
  1576. if (sp == NULL)
  1577. {
  1578. SETERROR(REG_ESPACE);
  1579. return;
  1580. }
  1581. p->strip = sp;
  1582. p->ssize = size;
  1583. }
  1584. /*
  1585.  - stripsnug - compact the strip
  1586.  == static void stripsnug(struct parse *p, struct re_guts *g);
  1587.  */
  1588. static void
  1589. stripsnug(p, g)
  1590. struct parse *p;
  1591. struct re_guts *g;
  1592. {
  1593. g->nstates = p->slen;
  1594. g->strip = (sop *) realloc((char *) p->strip, p->slen * sizeof(sop));
  1595. if (g->strip == NULL)
  1596. {
  1597. SETERROR(REG_ESPACE);
  1598. g->strip = p->strip;
  1599. }
  1600. }
  1601. /*
  1602.  - findmust - fill in must and mlen with longest mandatory literal string
  1603.  == static void findmust(struct parse *p, struct re_guts *g);
  1604.  *
  1605.  * This algorithm could do fancy things like analyzing the operands of |
  1606.  * for common subsequences.  Someday.  This code is simple and finds most
  1607.  * of the interesting cases.
  1608.  *
  1609.  * Note that must and mlen got initialized during setup.
  1610.  */
  1611. static void
  1612. findmust(p, g)
  1613. struct parse *p;
  1614. struct re_guts *g;
  1615. {
  1616. sop    *scan;
  1617. sop    *start = 0;
  1618. sop    *newstart = 0;
  1619. sopno newlen;
  1620. sop s;
  1621. pg_wchar   *cp;
  1622. sopno i;
  1623. /* avoid making error situations worse */
  1624. if (p->error != 0)
  1625. return;
  1626. /* find the longest OCHAR sequence in strip */
  1627. newlen = 0;
  1628. scan = g->strip + 1;
  1629. do
  1630. {
  1631. s = *scan++;
  1632. switch (OP(s))
  1633. {
  1634. case OCHAR: /* sequence member */
  1635. if (newlen == 0)/* new sequence */
  1636. newstart = scan - 1;
  1637. newlen++;
  1638. break;
  1639. case OPLUS_: /* things that don't break one */
  1640. case OLPAREN:
  1641. case ORPAREN:
  1642. break;
  1643. case OQUEST_: /* things that must be skipped */
  1644. case OCH_:
  1645. scan--;
  1646. do
  1647. {
  1648. scan += OPND(s);
  1649. s = *scan;
  1650. /* assert() interferes w debug printouts */
  1651. if (OP(s) != O_QUEST && OP(s) != O_CH &&
  1652. OP(s) != OOR2)
  1653. {
  1654. g->iflags |= BAD;
  1655. return;
  1656. }
  1657. } while (OP(s) != O_QUEST && OP(s) != O_CH);
  1658. /* fallthrough */
  1659. default: /* things that break a sequence */
  1660. if (newlen > g->mlen)
  1661. { /* ends one */
  1662. start = newstart;
  1663. g->mlen = newlen;
  1664. }
  1665. newlen = 0;
  1666. break;
  1667. }
  1668. } while (OP(s) != OEND);
  1669. if (g->mlen == 0) /* there isn't one */
  1670. return;
  1671. /* turn it into a character string */
  1672. #ifdef MULTIBYTE
  1673. g->must = (pg_wchar *) malloc((size_t) (g->mlen + 1) * sizeof(pg_wchar));
  1674. #else
  1675. g->must = malloc((size_t) g->mlen + 1);
  1676. #endif
  1677. if (g->must == NULL)
  1678. { /* argh; just forget it */
  1679. g->mlen = 0;
  1680. return;
  1681. }
  1682. cp = g->must;
  1683. scan = start;
  1684. for (i = g->mlen; i > 0; i--)
  1685. {
  1686. while (OP(s = *scan++) != OCHAR)
  1687. continue;
  1688. assert(cp < g->must + g->mlen);
  1689. *cp++ = (pg_wchar) OPND(s);
  1690. }
  1691. assert(cp == g->must + g->mlen);
  1692. *cp++ = ''; /* just on general principles */
  1693. }
  1694. /*
  1695.  - pluscount - count + nesting
  1696.  == static sopno pluscount(struct parse *p, struct re_guts *g);
  1697.  */
  1698. static sopno /* nesting depth */
  1699. pluscount(p, g)
  1700. struct parse *p;
  1701. struct re_guts *g;
  1702. {
  1703. sop    *scan;
  1704. sop s;
  1705. sopno plusnest = 0;
  1706. sopno maxnest = 0;
  1707. if (p->error != 0)
  1708. return 0; /* there may not be an OEND */
  1709. scan = g->strip + 1;
  1710. do
  1711. {
  1712. s = *scan++;
  1713. switch (OP(s))
  1714. {
  1715. case OPLUS_:
  1716. plusnest++;
  1717. break;
  1718. case O_PLUS:
  1719. if (plusnest > maxnest)
  1720. maxnest = plusnest;
  1721. plusnest--;
  1722. break;
  1723. }
  1724. } while (OP(s) != OEND);
  1725. if (plusnest != 0)
  1726. g->iflags |= BAD;
  1727. return maxnest;
  1728. }
  1729. /*
  1730.  * some ctype functions with none-ascii-char guard
  1731.  */
  1732. static int
  1733. pg_isdigit(int c)
  1734. {
  1735. #ifdef MULTIBYTE
  1736. return (c >= 0 && c <= UCHAR_MAX && isdigit(c));
  1737. #else
  1738. return (isdigit(c));
  1739. #endif
  1740. }
  1741. static int
  1742. pg_isalpha(int c)
  1743. {
  1744. #ifdef MULTIBYTE
  1745. return (c >= 0 && c <= UCHAR_MAX && isalpha(c));
  1746. #else
  1747. return (isalpha(c));
  1748. #endif
  1749. }
  1750. static int
  1751. pg_isupper(int c)
  1752. {
  1753. #ifdef MULTIBYTE
  1754. return (c >= 0 && c <= UCHAR_MAX && isupper(c));
  1755. #else
  1756. return (isupper(c));
  1757. #endif
  1758. }
  1759. static int
  1760. pg_islower(int c)
  1761. {
  1762. #ifdef MULTIBYTE
  1763. return (c >= 0 && c <= UCHAR_MAX && islower(c));
  1764. #else
  1765. return (islower(c));
  1766. #endif
  1767. }