regc_lex.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:24k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * lexical analyzer
  3.  * This file is #included by regcomp.c.
  4.  *
  5.  * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
  6.  * 
  7.  * Development of this software was funded, in part, by Cray Research Inc.,
  8.  * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
  9.  * Corporation, none of whom are responsible for the results.  The author
  10.  * thanks all of them. 
  11.  * 
  12.  * Redistribution and use in source and binary forms -- with or without
  13.  * modification -- are permitted for any purpose, provided that
  14.  * redistributions in source form retain this entire copyright notice and
  15.  * indicate the origin and nature of any modifications.
  16.  * 
  17.  * I'd appreciate being given credit for this package in the documentation
  18.  * of software which uses it, but that is not a requirement.
  19.  * 
  20.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  21.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  22.  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
  23.  * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  26.  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  *
  31.  */
  32. /* scanning macros (know about v) */
  33. #define ATEOS() (v->now >= v->stop)
  34. #define HAVE(n) (v->stop - v->now >= (n))
  35. #define NEXT1(c) (!ATEOS() && *v->now == CHR(c))
  36. #define NEXT2(a,b) (HAVE(2) && *v->now == CHR(a) && *(v->now+1) == CHR(b))
  37. #define NEXT3(a,b,c) (HAVE(3) && *v->now == CHR(a) && 
  38. *(v->now+1) == CHR(b) && 
  39. *(v->now+2) == CHR(c))
  40. #define SET(c) (v->nexttype = (c))
  41. #define SETV(c, n) (v->nexttype = (c), v->nextvalue = (n))
  42. #define RET(c) return (SET(c), 1)
  43. #define RETV(c, n) return (SETV(c, n), 1)
  44. #define FAILW(e) return (ERR(e), 0) /* ERR does SET(EOS) */
  45. #define LASTTYPE(t) (v->lasttype == (t))
  46. /* lexical contexts */
  47. #define L_ERE 1 /* mainline ERE/ARE */
  48. #define L_BRE 2 /* mainline BRE */
  49. #define L_Q 3 /* REG_QUOTE */
  50. #define L_EBND 4 /* ERE/ARE bound */
  51. #define L_BBND 5 /* BRE bound */
  52. #define L_BRACK 6 /* brackets */
  53. #define L_CEL 7 /* collating element */
  54. #define L_ECL 8 /* equivalence class */
  55. #define L_CCL 9 /* character class */
  56. #define INTOCON(c) (v->lexcon = (c))
  57. #define INCON(con) (v->lexcon == (con))
  58. /* construct pointer past end of chr array */
  59. #define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
  60. /*
  61.  - lexstart - set up lexical stuff, scan leading options
  62.  ^ static VOID lexstart(struct vars *);
  63.  */
  64. static VOID
  65. lexstart(v)
  66. struct vars *v;
  67. {
  68. prefixes(v); /* may turn on new type bits etc. */
  69. NOERR();
  70. if (v->cflags&REG_QUOTE) {
  71. assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
  72. INTOCON(L_Q);
  73. } else if (v->cflags&REG_EXTENDED) {
  74. assert(!(v->cflags&REG_QUOTE));
  75. INTOCON(L_ERE);
  76. } else {
  77. assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
  78. INTOCON(L_BRE);
  79. }
  80. v->nexttype = EMPTY; /* remember we were at the start */
  81. next(v); /* set up the first token */
  82. }
  83. /*
  84.  - prefixes - implement various special prefixes
  85.  ^ static VOID prefixes(struct vars *);
  86.  */
  87. static VOID
  88. prefixes(v)
  89. struct vars *v;
  90. {
  91. /* literal string doesn't get any of this stuff */
  92. if (v->cflags&REG_QUOTE)
  93. return;
  94. /* initial "***" gets special things */
  95. if (HAVE(4) && NEXT3('*', '*', '*'))
  96. switch (*(v->now + 3)) {
  97. case CHR('?'): /* "***?" error, msg shows version */
  98. ERR(REG_BADPAT);
  99. return; /* proceed no further */
  100. break;
  101. case CHR('='): /* "***=" shifts to literal string */
  102. NOTE(REG_UNONPOSIX);
  103. v->cflags |= REG_QUOTE;
  104. v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
  105. v->now += 4;
  106. return; /* and there can be no more prefixes */
  107. break;
  108. case CHR(':'): /* "***:" shifts to AREs */
  109. NOTE(REG_UNONPOSIX);
  110. v->cflags |= REG_ADVANCED;
  111. v->now += 4;
  112. break;
  113. default: /* otherwise *** is just an error */
  114. ERR(REG_BADRPT);
  115. return;
  116. break;
  117. }
  118. /* BREs and EREs don't get embedded options */
  119. if ((v->cflags&REG_ADVANCED) != REG_ADVANCED)
  120. return;
  121. /* embedded options (AREs only) */
  122. if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
  123. NOTE(REG_UNONPOSIX);
  124. v->now += 2;
  125. for (; !ATEOS() && iscalpha(*v->now); v->now++)
  126. switch (*v->now) {
  127. case CHR('b'): /* BREs (but why???) */
  128. v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
  129. break;
  130. case CHR('c'): /* case sensitive */
  131. v->cflags &= ~REG_ICASE;
  132. break;
  133. case CHR('e'): /* plain EREs */
  134. v->cflags |= REG_EXTENDED;
  135. v->cflags &= ~(REG_ADVF|REG_QUOTE);
  136. break;
  137. case CHR('i'): /* case insensitive */
  138. v->cflags |= REG_ICASE;
  139. break;
  140. case CHR('m'): /* Perloid synonym for n */
  141. case CHR('n'): /* n affects ^ $ . [^ */
  142. v->cflags |= REG_NEWLINE;
  143. break;
  144. case CHR('p'): /* ~Perl, n affects . [^ */
  145. v->cflags |= REG_NLSTOP;
  146. v->cflags &= ~REG_NLANCH;
  147. break;
  148. case CHR('q'): /* literal string */
  149. v->cflags |= REG_QUOTE;
  150. v->cflags &= ~REG_ADVANCED;
  151. break;
  152. case CHR('s'): /* single line, n ordinary */
  153. v->cflags &= ~REG_NEWLINE;
  154. break;
  155. case CHR('t'): /* tight syntax */
  156. v->cflags &= ~REG_EXPANDED;
  157. break;
  158. case CHR('w'): /* weird, n affects ^ $ only */
  159. v->cflags &= ~REG_NLSTOP;
  160. v->cflags |= REG_NLANCH;
  161. break;
  162. case CHR('x'): /* expanded syntax */
  163. v->cflags |= REG_EXPANDED;
  164. break;
  165. default:
  166. ERR(REG_BADOPT);
  167. return;
  168. }
  169. if (!NEXT1(')')) {
  170. ERR(REG_BADOPT);
  171. return;
  172. }
  173. v->now++;
  174. if (v->cflags&REG_QUOTE)
  175. v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
  176. }
  177. }
  178. /*
  179.  - lexnest - "call a subroutine", interpolating string at the lexical level
  180.  * Note, this is not a very general facility.  There are a number of
  181.  * implicit assumptions about what sorts of strings can be subroutines.
  182.  ^ static VOID lexnest(struct vars *, chr *, chr *);
  183.  */
  184. static VOID
  185. lexnest(v, beginp, endp)
  186. struct vars *v;
  187. chr *beginp; /* start of interpolation */
  188. chr *endp; /* one past end of interpolation */
  189. {
  190. assert(v->savenow == NULL); /* only one level of nesting */
  191. v->savenow = v->now;
  192. v->savestop = v->stop;
  193. v->now = beginp;
  194. v->stop = endp;
  195. }
  196. /*
  197.  * string constants to interpolate as expansions of things like d
  198.  */
  199. static chr backd[] = { /* d */
  200. CHR('['), CHR('['), CHR(':'),
  201. CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
  202. CHR(':'), CHR(']'), CHR(']')
  203. };
  204. static chr backD[] = { /* D */
  205. CHR('['), CHR('^'), CHR('['), CHR(':'),
  206. CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
  207. CHR(':'), CHR(']'), CHR(']')
  208. };
  209. static chr brbackd[] = { /* d within brackets */
  210. CHR('['), CHR(':'),
  211. CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
  212. CHR(':'), CHR(']')
  213. };
  214. static chr backs[] = { /* s */
  215. CHR('['), CHR('['), CHR(':'),
  216. CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
  217. CHR(':'), CHR(']'), CHR(']')
  218. };
  219. static chr backS[] = { /* S */
  220. CHR('['), CHR('^'), CHR('['), CHR(':'),
  221. CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
  222. CHR(':'), CHR(']'), CHR(']')
  223. };
  224. static chr brbacks[] = { /* s within brackets */
  225. CHR('['), CHR(':'),
  226. CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
  227. CHR(':'), CHR(']')
  228. };
  229. static chr backw[] = { /* w */
  230. CHR('['), CHR('['), CHR(':'),
  231. CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
  232. CHR(':'), CHR(']'), CHR('_'), CHR(']')
  233. };
  234. static chr backW[] = { /* W */
  235. CHR('['), CHR('^'), CHR('['), CHR(':'),
  236. CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
  237. CHR(':'), CHR(']'), CHR('_'), CHR(']')
  238. };
  239. static chr brbackw[] = { /* w within brackets */
  240. CHR('['), CHR(':'),
  241. CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
  242. CHR(':'), CHR(']'), CHR('_')
  243. };
  244. /*
  245.  - lexword - interpolate a bracket expression for word characters
  246.  * Possibly ought to inquire whether there is a "word" character class.
  247.  ^ static VOID lexword(struct vars *);
  248.  */
  249. static VOID
  250. lexword(v)
  251. struct vars *v;
  252. {
  253. lexnest(v, backw, ENDOF(backw));
  254. }
  255. /*
  256.  - next - get next token
  257.  ^ static int next(struct vars *);
  258.  */
  259. static int /* 1 normal, 0 failure */
  260. next(v)
  261. struct vars *v;
  262. {
  263. chr c;
  264. /* errors yield an infinite sequence of failures */
  265. if (ISERR())
  266. return 0; /* the error has set nexttype to EOS */
  267. /* remember flavor of last token */
  268. v->lasttype = v->nexttype;
  269. /* REG_BOSONLY */
  270. if (v->nexttype == EMPTY && (v->cflags&REG_BOSONLY)) {
  271. /* at start of a REG_BOSONLY RE */
  272. RETV(SBEGIN, 0); /* same as A */
  273. }
  274. /* if we're nested and we've hit end, return to outer level */
  275. if (v->savenow != NULL && ATEOS()) {
  276. v->now = v->savenow;
  277. v->stop = v->savestop;
  278. v->savenow = v->savestop = NULL;
  279. }
  280. /* skip white space etc. if appropriate (not in literal or []) */
  281. if (v->cflags&REG_EXPANDED)
  282. switch (v->lexcon) {
  283. case L_ERE:
  284. case L_BRE:
  285. case L_EBND:
  286. case L_BBND:
  287. skip(v);
  288. break;
  289. }
  290. /* handle EOS, depending on context */
  291. if (ATEOS()) {
  292. switch (v->lexcon) {
  293. case L_ERE:
  294. case L_BRE:
  295. case L_Q:
  296. RET(EOS);
  297. break;
  298. case L_EBND:
  299. case L_BBND:
  300. FAILW(REG_EBRACE);
  301. break;
  302. case L_BRACK:
  303. case L_CEL:
  304. case L_ECL:
  305. case L_CCL:
  306. FAILW(REG_EBRACK);
  307. break;
  308. }
  309. assert(NOTREACHED);
  310. }
  311. /* okay, time to actually get a character */
  312. c = *v->now++;
  313. /* deal with the easy contexts, punt EREs to code below */
  314. switch (v->lexcon) {
  315. case L_BRE: /* punt BREs to separate function */
  316. return brenext(v, c);
  317. break;
  318. case L_ERE: /* see below */
  319. break;
  320. case L_Q: /* literal strings are easy */
  321. RETV(PLAIN, c);
  322. break;
  323. case L_BBND: /* bounds are fairly simple */
  324. case L_EBND:
  325. switch (c) {
  326. case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
  327. case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
  328. case CHR('8'): case CHR('9'):
  329. RETV(DIGIT, (chr)DIGITVAL(c));
  330. break;
  331. case CHR(','):
  332. RET(',');
  333. break;
  334. case CHR('}'): /* ERE bound ends with } */
  335. if (INCON(L_EBND)) {
  336. INTOCON(L_ERE);
  337. if ((v->cflags&REG_ADVF) && NEXT1('?')) {
  338. v->now++;
  339. NOTE(REG_UNONPOSIX);
  340. RETV('}', 0);
  341. }
  342. RETV('}', 1);
  343. } else
  344. FAILW(REG_BADBR);
  345. break;
  346. case CHR('\'): /* BRE bound ends with } */
  347. if (INCON(L_BBND) && NEXT1('}')) {
  348. v->now++;
  349. INTOCON(L_BRE);
  350. RET('}');
  351. } else
  352. FAILW(REG_BADBR);
  353. break;
  354. default:
  355. FAILW(REG_BADBR);
  356. break;
  357. }
  358. assert(NOTREACHED);
  359. break;
  360. case L_BRACK: /* brackets are not too hard */
  361. switch (c) {
  362. case CHR(']'):
  363. if (LASTTYPE('['))
  364. RETV(PLAIN, c);
  365. else {
  366. INTOCON((v->cflags&REG_EXTENDED) ?
  367. L_ERE : L_BRE);
  368. RET(']');
  369. }
  370. break;
  371. case CHR('\'):
  372. NOTE(REG_UBBS);
  373. if (!(v->cflags&REG_ADVF))
  374. RETV(PLAIN, c);
  375. NOTE(REG_UNONPOSIX);
  376. if (ATEOS())
  377. FAILW(REG_EESCAPE);
  378. (DISCARD)lexescape(v);
  379. switch (v->nexttype) { /* not all escapes okay here */
  380. case PLAIN:
  381. return 1;
  382. break;
  383. case CCLASS:
  384. switch (v->nextvalue) {
  385. case 'd':
  386. lexnest(v, brbackd, ENDOF(brbackd));
  387. break;
  388. case 's':
  389. lexnest(v, brbacks, ENDOF(brbacks));
  390. break;
  391. case 'w':
  392. lexnest(v, brbackw, ENDOF(brbackw));
  393. break;
  394. default:
  395. FAILW(REG_EESCAPE);
  396. break;
  397. }
  398. /* lexnest done, back up and try again */
  399. v->nexttype = v->lasttype;
  400. return next(v);
  401. break;
  402. }
  403. /* not one of the acceptable escapes */
  404. FAILW(REG_EESCAPE);
  405. break;
  406. case CHR('-'):
  407. if (LASTTYPE('[') || NEXT1(']'))
  408. RETV(PLAIN, c);
  409. else
  410. RETV(RANGE, c);
  411. break;
  412. case CHR('['):
  413. if (ATEOS())
  414. FAILW(REG_EBRACK);
  415. switch (*v->now++) {
  416. case CHR('.'):
  417. INTOCON(L_CEL);
  418. /* might or might not be locale-specific */
  419. RET(COLLEL);
  420. break;
  421. case CHR('='):
  422. INTOCON(L_ECL);
  423. NOTE(REG_ULOCALE);
  424. RET(ECLASS);
  425. break;
  426. case CHR(':'):
  427. INTOCON(L_CCL);
  428. NOTE(REG_ULOCALE);
  429. RET(CCLASS);
  430. break;
  431. default: /* oops */
  432. v->now--;
  433. RETV(PLAIN, c);
  434. break;
  435. }
  436. assert(NOTREACHED);
  437. break;
  438. default:
  439. RETV(PLAIN, c);
  440. break;
  441. }
  442. assert(NOTREACHED);
  443. break;
  444. case L_CEL: /* collating elements are easy */
  445. if (c == CHR('.') && NEXT1(']')) {
  446. v->now++;
  447. INTOCON(L_BRACK);
  448. RETV(END, '.');
  449. } else
  450. RETV(PLAIN, c);
  451. break;
  452. case L_ECL: /* ditto equivalence classes */
  453. if (c == CHR('=') && NEXT1(']')) {
  454. v->now++;
  455. INTOCON(L_BRACK);
  456. RETV(END, '=');
  457. } else
  458. RETV(PLAIN, c);
  459. break;
  460. case L_CCL: /* ditto character classes */
  461. if (c == CHR(':') && NEXT1(']')) {
  462. v->now++;
  463. INTOCON(L_BRACK);
  464. RETV(END, ':');
  465. } else
  466. RETV(PLAIN, c);
  467. break;
  468. default:
  469. assert(NOTREACHED);
  470. break;
  471. }
  472. /* that got rid of everything except EREs and AREs */
  473. assert(INCON(L_ERE));
  474. /* deal with EREs and AREs, except for backslashes */
  475. switch (c) {
  476. case CHR('|'):
  477. RET('|');
  478. break;
  479. case CHR('*'):
  480. if ((v->cflags&REG_ADVF) && NEXT1('?')) {
  481. v->now++;
  482. NOTE(REG_UNONPOSIX);
  483. RETV('*', 0);
  484. }
  485. RETV('*', 1);
  486. break;
  487. case CHR('+'):
  488. if ((v->cflags&REG_ADVF) && NEXT1('?')) {
  489. v->now++;
  490. NOTE(REG_UNONPOSIX);
  491. RETV('+', 0);
  492. }
  493. RETV('+', 1);
  494. break;
  495. case CHR('?'):
  496. if ((v->cflags&REG_ADVF) && NEXT1('?')) {
  497. v->now++;
  498. NOTE(REG_UNONPOSIX);
  499. RETV('?', 0);
  500. }
  501. RETV('?', 1);
  502. break;
  503. case CHR('{'): /* bounds start or plain character */
  504. if (v->cflags&REG_EXPANDED)
  505. skip(v);
  506. if (ATEOS() || !iscdigit(*v->now)) {
  507. NOTE(REG_UBRACES);
  508. NOTE(REG_UUNSPEC);
  509. RETV(PLAIN, c);
  510. } else {
  511. NOTE(REG_UBOUNDS);
  512. INTOCON(L_EBND);
  513. RET('{');
  514. }
  515. assert(NOTREACHED);
  516. break;
  517. case CHR('('): /* parenthesis, or advanced extension */
  518. if ((v->cflags&REG_ADVF) && NEXT1('?')) {
  519. NOTE(REG_UNONPOSIX);
  520. v->now++;
  521. switch (*v->now++) {
  522. case CHR(':'): /* non-capturing paren */
  523. RETV('(', 0);
  524. break;
  525. case CHR('#'): /* comment */
  526. while (!ATEOS() && *v->now != CHR(')'))
  527. v->now++;
  528. if (!ATEOS())
  529. v->now++;
  530. assert(v->nexttype == v->lasttype);
  531. return next(v);
  532. break;
  533. case CHR('='): /* positive lookahead */
  534. NOTE(REG_ULOOKAHEAD);
  535. RETV(LACON, 1);
  536. break;
  537. case CHR('!'): /* negative lookahead */
  538. NOTE(REG_ULOOKAHEAD);
  539. RETV(LACON, 0);
  540. break;
  541. default:
  542. FAILW(REG_BADRPT);
  543. break;
  544. }
  545. assert(NOTREACHED);
  546. }
  547. if (v->cflags&REG_NOSUB)
  548. RETV('(', 0); /* all parens non-capturing */
  549. else
  550. RETV('(', 1);
  551. break;
  552. case CHR(')'):
  553. if (LASTTYPE('(')) {
  554. NOTE(REG_UUNSPEC);
  555. }
  556. RETV(')', c);
  557. break;
  558. case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
  559. if (HAVE(6) && *(v->now+0) == CHR('[') &&
  560. *(v->now+1) == CHR(':') &&
  561. (*(v->now+2) == CHR('<') ||
  562. *(v->now+2) == CHR('>')) &&
  563. *(v->now+3) == CHR(':') &&
  564. *(v->now+4) == CHR(']') &&
  565. *(v->now+5) == CHR(']')) {
  566. c = *(v->now+2);
  567. v->now += 6;
  568. NOTE(REG_UNONPOSIX);
  569. RET((c == CHR('<')) ? '<' : '>');
  570. }
  571. INTOCON(L_BRACK);
  572. if (NEXT1('^')) {
  573. v->now++;
  574. RETV('[', 0);
  575. }
  576. RETV('[', 1);
  577. break;
  578. case CHR('.'):
  579. RET('.');
  580. break;
  581. case CHR('^'):
  582. RET('^');
  583. break;
  584. case CHR('$'):
  585. RET('$');
  586. break;
  587. case CHR('\'): /* mostly punt backslashes to code below */
  588. if (ATEOS())
  589. FAILW(REG_EESCAPE);
  590. break;
  591. default: /* ordinary character */
  592. RETV(PLAIN, c);
  593. break;
  594. }
  595. /* ERE/ARE backslash handling; backslash already eaten */
  596. assert(!ATEOS());
  597. if (!(v->cflags&REG_ADVF)) { /* only AREs have non-trivial escapes */
  598. if (iscalnum(*v->now)) {
  599. NOTE(REG_UBSALNUM);
  600. NOTE(REG_UUNSPEC);
  601. }
  602. RETV(PLAIN, *v->now++);
  603. }
  604. (DISCARD)lexescape(v);
  605. if (ISERR())
  606. FAILW(REG_EESCAPE);
  607. if (v->nexttype == CCLASS) { /* fudge at lexical level */
  608. switch (v->nextvalue) {
  609. case 'd': lexnest(v, backd, ENDOF(backd)); break;
  610. case 'D': lexnest(v, backD, ENDOF(backD)); break;
  611. case 's': lexnest(v, backs, ENDOF(backs)); break;
  612. case 'S': lexnest(v, backS, ENDOF(backS)); break;
  613. case 'w': lexnest(v, backw, ENDOF(backw)); break;
  614. case 'W': lexnest(v, backW, ENDOF(backW)); break;
  615. default:
  616. assert(NOTREACHED);
  617. FAILW(REG_ASSERT);
  618. break;
  619. }
  620. /* lexnest done, back up and try again */
  621. v->nexttype = v->lasttype;
  622. return next(v);
  623. }
  624. /* otherwise, lexescape has already done the work */
  625. return !ISERR();
  626. }
  627. /*
  628.  - lexescape - parse an ARE backslash escape (backslash already eaten)
  629.  * Note slightly nonstandard use of the CCLASS type code.
  630.  ^ static int lexescape(struct vars *);
  631.  */
  632. static int /* not actually used, but convenient for RETV */
  633. lexescape(v)
  634. struct vars *v;
  635. {
  636. chr c;
  637. static chr alert[] = {
  638. CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
  639. };
  640. static chr esc[] = {
  641. CHR('E'), CHR('S'), CHR('C')
  642. };
  643. chr *save;
  644. assert(v->cflags&REG_ADVF);
  645. assert(!ATEOS());
  646. c = *v->now++;
  647. if (!iscalnum(c))
  648. RETV(PLAIN, c);
  649. NOTE(REG_UNONPOSIX);
  650. switch (c) {
  651. case CHR('a'):
  652. RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('07')));
  653. break;
  654. case CHR('A'):
  655. RETV(SBEGIN, 0);
  656. break;
  657. case CHR('b'):
  658. RETV(PLAIN, CHR('b'));
  659. break;
  660. case CHR('B'):
  661. RETV(PLAIN, CHR('\'));
  662. break;
  663. case CHR('c'):
  664. NOTE(REG_UUNPORT);
  665. if (ATEOS())
  666. FAILW(REG_EESCAPE);
  667. RETV(PLAIN, (chr)(*v->now++ & 037));
  668. break;
  669. case CHR('d'):
  670. NOTE(REG_ULOCALE);
  671. RETV(CCLASS, 'd');
  672. break;
  673. case CHR('D'):
  674. NOTE(REG_ULOCALE);
  675. RETV(CCLASS, 'D');
  676. break;
  677. case CHR('e'):
  678. NOTE(REG_UUNPORT);
  679. RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('33')));
  680. break;
  681. case CHR('f'):
  682. RETV(PLAIN, CHR('f'));
  683. break;
  684. case CHR('m'):
  685. RET('<');
  686. break;
  687. case CHR('M'):
  688. RET('>');
  689. break;
  690. case CHR('n'):
  691. RETV(PLAIN, CHR('n'));
  692. break;
  693. case CHR('r'):
  694. RETV(PLAIN, CHR('r'));
  695. break;
  696. case CHR('s'):
  697. NOTE(REG_ULOCALE);
  698. RETV(CCLASS, 's');
  699. break;
  700. case CHR('S'):
  701. NOTE(REG_ULOCALE);
  702. RETV(CCLASS, 'S');
  703. break;
  704. case CHR('t'):
  705. RETV(PLAIN, CHR('t'));
  706. break;
  707. case CHR('u'):
  708. c = lexdigits(v, 16, 4, 4);
  709. if (ISERR())
  710. FAILW(REG_EESCAPE);
  711. RETV(PLAIN, c);
  712. break;
  713. case CHR('U'):
  714. c = lexdigits(v, 16, 8, 8);
  715. if (ISERR())
  716. FAILW(REG_EESCAPE);
  717. RETV(PLAIN, c);
  718. break;
  719. case CHR('v'):
  720. RETV(PLAIN, CHR('v'));
  721. break;
  722. case CHR('w'):
  723. NOTE(REG_ULOCALE);
  724. RETV(CCLASS, 'w');
  725. break;
  726. case CHR('W'):
  727. NOTE(REG_ULOCALE);
  728. RETV(CCLASS, 'W');
  729. break;
  730. case CHR('x'):
  731. NOTE(REG_UUNPORT);
  732. c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
  733. if (ISERR())
  734. FAILW(REG_EESCAPE);
  735. RETV(PLAIN, c);
  736. break;
  737. case CHR('y'):
  738. NOTE(REG_ULOCALE);
  739. RETV(WBDRY, 0);
  740. break;
  741. case CHR('Y'):
  742. NOTE(REG_ULOCALE);
  743. RETV(NWBDRY, 0);
  744. break;
  745. case CHR('Z'):
  746. RETV(SEND, 0);
  747. break;
  748. case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
  749. case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
  750. case CHR('9'):
  751. save = v->now;
  752. v->now--; /* put first digit back */
  753. c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
  754. if (ISERR())
  755. FAILW(REG_EESCAPE);
  756. /* ugly heuristic (first test is "exactly 1 digit?") */
  757. if (v->now-save == 0 || ((int)c > 0 && (int)c <= v->nsubexp)) {
  758. NOTE(REG_UBACKREF);
  759. RETV(BACKREF, (chr)c);
  760. }
  761. /* oops, doesn't look like it's a backref after all... */
  762. v->now = save;
  763. /* and fall through into octal number */
  764. case CHR('0'):
  765. NOTE(REG_UUNPORT);
  766. v->now--; /* put first digit back */
  767. c = lexdigits(v, 8, 1, 3);
  768. if (ISERR())
  769. FAILW(REG_EESCAPE);
  770. RETV(PLAIN, c);
  771. break;
  772. default:
  773. assert(iscalpha(c));
  774. FAILW(REG_EESCAPE); /* unknown alphabetic escape */
  775. break;
  776. }
  777. assert(NOTREACHED);
  778. }
  779. /*
  780.  - lexdigits - slurp up digits and return chr value
  781.  ^ static chr lexdigits(struct vars *, int, int, int);
  782.  */
  783. static chr /* chr value; errors signalled via ERR */
  784. lexdigits(v, base, minlen, maxlen)
  785. struct vars *v;
  786. int base;
  787. int minlen;
  788. int maxlen;
  789. {
  790. uchr n; /* unsigned to avoid overflow misbehavior */
  791. int len;
  792. chr c;
  793. int d;
  794. CONST uchr ub = (uchr) base;
  795. n = 0;
  796. for (len = 0; len < maxlen && !ATEOS(); len++) {
  797. c = *v->now++;
  798. switch (c) {
  799. case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
  800. case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
  801. case CHR('8'): case CHR('9'):
  802. d = DIGITVAL(c);
  803. break;
  804. case CHR('a'): case CHR('A'): d = 10; break;
  805. case CHR('b'): case CHR('B'): d = 11; break;
  806. case CHR('c'): case CHR('C'): d = 12; break;
  807. case CHR('d'): case CHR('D'): d = 13; break;
  808. case CHR('e'): case CHR('E'): d = 14; break;
  809. case CHR('f'): case CHR('F'): d = 15; break;
  810. default:
  811. v->now--; /* oops, not a digit at all */
  812. d = -1;
  813. break;
  814. }
  815. if (d >= base) { /* not a plausible digit */
  816. v->now--;
  817. d = -1;
  818. }
  819. if (d < 0)
  820. break; /* NOTE BREAK OUT */
  821. n = n*ub + (uchr)d;
  822. }
  823. if (len < minlen)
  824. ERR(REG_EESCAPE);
  825. return (chr)n;
  826. }
  827. /*
  828.  - brenext - get next BRE token
  829.  * This is much like EREs except for all the stupid backslashes and the
  830.  * context-dependency of some things.
  831.  ^ static int brenext(struct vars *, pchr);
  832.  */
  833. static int /* 1 normal, 0 failure */
  834. brenext(v, pc)
  835. struct vars *v;
  836. pchr pc;
  837. {
  838. chr c = (chr)pc;
  839. switch (c) {
  840. case CHR('*'):
  841. if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
  842. RETV(PLAIN, c);
  843. RET('*');
  844. break;
  845. case CHR('['):
  846. if (HAVE(6) && *(v->now+0) == CHR('[') &&
  847. *(v->now+1) == CHR(':') &&
  848. (*(v->now+2) == CHR('<') ||
  849. *(v->now+2) == CHR('>')) &&
  850. *(v->now+3) == CHR(':') &&
  851. *(v->now+4) == CHR(']') &&
  852. *(v->now+5) == CHR(']')) {
  853. c = *(v->now+2);
  854. v->now += 6;
  855. NOTE(REG_UNONPOSIX);
  856. RET((c == CHR('<')) ? '<' : '>');
  857. }
  858. INTOCON(L_BRACK);
  859. if (NEXT1('^')) {
  860. v->now++;
  861. RETV('[', 0);
  862. }
  863. RETV('[', 1);
  864. break;
  865. case CHR('.'):
  866. RET('.');
  867. break;
  868. case CHR('^'):
  869. if (LASTTYPE(EMPTY))
  870. RET('^');
  871. if (LASTTYPE('(')) {
  872. NOTE(REG_UUNSPEC);
  873. RET('^');
  874. }
  875. RETV(PLAIN, c);
  876. break;
  877. case CHR('$'):
  878. if (v->cflags&REG_EXPANDED)
  879. skip(v);
  880. if (ATEOS())
  881. RET('$');
  882. if (NEXT2('\', ')')) {
  883. NOTE(REG_UUNSPEC);
  884. RET('$');
  885. }
  886. RETV(PLAIN, c);
  887. break;
  888. case CHR('\'):
  889. break; /* see below */
  890. default:
  891. RETV(PLAIN, c);
  892. break;
  893. }
  894. assert(c == CHR('\'));
  895. if (ATEOS())
  896. FAILW(REG_EESCAPE);
  897. c = *v->now++;
  898. switch (c) {
  899. case CHR('{'):
  900. INTOCON(L_BBND);
  901. NOTE(REG_UBOUNDS);
  902. RET('{');
  903. break;
  904. case CHR('('):
  905. RETV('(', 1);
  906. break;
  907. case CHR(')'):
  908. RETV(')', c);
  909. break;
  910. case CHR('<'):
  911. NOTE(REG_UNONPOSIX);
  912. RET('<');
  913. break;
  914. case CHR('>'):
  915. NOTE(REG_UNONPOSIX);
  916. RET('>');
  917. break;
  918. case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
  919. case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
  920. case CHR('9'):
  921. NOTE(REG_UBACKREF);
  922. RETV(BACKREF, (chr)DIGITVAL(c));
  923. break;
  924. default:
  925. if (iscalnum(c)) {
  926. NOTE(REG_UBSALNUM);
  927. NOTE(REG_UUNSPEC);
  928. }
  929. RETV(PLAIN, c);
  930. break;
  931. }
  932. assert(NOTREACHED);
  933. }
  934. /*
  935.  - skip - skip white space and comments in expanded form
  936.  ^ static VOID skip(struct vars *);
  937.  */
  938. static VOID
  939. skip(v)
  940. struct vars *v;
  941. {
  942. chr *start = v->now;
  943. assert(v->cflags&REG_EXPANDED);
  944. for (;;) {
  945. while (!ATEOS() && iscspace(*v->now))
  946. v->now++;
  947. if (ATEOS() || *v->now != CHR('#'))
  948. break; /* NOTE BREAK OUT */
  949. assert(NEXT1('#'));
  950. while (!ATEOS() && *v->now != CHR('n'))
  951. v->now++;
  952. /* leave the newline to be picked up by the iscspace loop */
  953. }
  954. if (v->now != start)
  955. NOTE(REG_UNONPOSIX);
  956. }
  957. /*
  958.  - newline - return the chr for a newline
  959.  * This helps confine use of CHR to this source file.
  960.  ^ static chr newline(NOPARMS);
  961.  */
  962. static chr
  963. newline()
  964. {
  965. return CHR('n');
  966. }
  967. /*
  968.  - ch - return the chr sequence for regc_locale.c's fake collating element ch
  969.  * This helps confine use of CHR to this source file.  Beware that the caller
  970.  * knows how long the sequence is.
  971.  ^ #ifdef REG_DEBUG
  972.  ^ static chr *ch(NOPARMS);
  973.  ^ #endif
  974.  */
  975. #ifdef REG_DEBUG
  976. static chr *
  977. ch()
  978. {
  979. static chr chstr[] = { CHR('c'), CHR('h'), CHR('') };
  980. return chstr;
  981. }
  982. #endif
  983. /*
  984.  - chrnamed - return the chr known by a given (chr string) name
  985.  * The code is a bit clumsy, but this routine gets only such specialized
  986.  * use that it hardly matters.
  987.  ^ static chr chrnamed(struct vars *, chr *, chr *, pchr);
  988.  */
  989. static chr
  990. chrnamed(v, startp, endp, lastresort)
  991. struct vars *v;
  992. chr *startp; /* start of name */
  993. chr *endp; /* just past end of name */
  994. pchr lastresort; /* what to return if name lookup fails */
  995. {
  996. celt c;
  997. int errsave;
  998. int e;
  999. struct cvec *cv;
  1000. errsave = v->err;
  1001. v->err = 0;
  1002. c = element(v, startp, endp);
  1003. e = v->err;
  1004. v->err = errsave;
  1005. if (e != 0)
  1006. return (chr)lastresort;
  1007. cv = range(v, c, c, 0);
  1008. if (cv->nchrs == 0)
  1009. return (chr)lastresort;
  1010. return cv->chrs[0];
  1011. }