home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities3 / gnu_sed_rx / c / rx < prev    next >
Text File  |  1994-02-25  |  222KB  |  8,779 lines

  1. /*    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with this software; see the file COPYING.  If not, write to
  15. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17. #include "config.h"
  18.  
  19. static char rx_version_string[] = "GNU Rx version 0.03";
  20.  
  21.             /* ``Too hard!''
  22.              *        -- anon.
  23.              */
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #ifndef isgraph
  27. #define isgraph(c) (isprint (c) && !isspace (c))
  28. #endif
  29. #ifndef isblank
  30. #define isblank(c) ((c) == ' ' || (c) == '\t')
  31. #endif
  32.  
  33. /*#include <sys/types.h>*/
  34. #include <stdio.h>
  35. #include "rx.h"
  36.  
  37. #undef MAX
  38. #undef MIN
  39. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  40. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  41.  
  42. typedef char boolean;
  43. #define false 0
  44. #define true 1
  45.  
  46.  
  47. /* This page is decls to the interesting subsystems and lower layers
  48.  * of rx.  Everything which doesn't have a public counterpart in 
  49.  * regex.c is declared here.
  50.  * 
  51.  * A useful (i hope) system is obtained by removing all or part of the regex.c
  52.  * reimplementation and making these all extern.  I think this package
  53.  * could be used to implement on-line lexers and parsers and who knows what 
  54.  * else.
  55.  */
  56. /* In the definitions, these functions are qualified by `RX_DECL' */
  57. #define RX_DECL static
  58.  
  59. #ifdef __STDC__
  60.  
  61. RX_DECL int rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b);
  62. RX_DECL void rx_bitset_null (int size, rx_Bitset b);
  63. RX_DECL void rx_bitset_universe (int size, rx_Bitset b);
  64. RX_DECL void rx_bitset_complement (int size, rx_Bitset b);
  65. RX_DECL void rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b);
  66. RX_DECL void rx_bitset_union (int size, rx_Bitset a, rx_Bitset b);
  67. RX_DECL void rx_bitset_intersection (int size,
  68.                      rx_Bitset a, rx_Bitset b);
  69. RX_DECL void rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b);
  70. RX_DECL unsigned long rx_bitset_hash (int size, rx_Bitset b);
  71. RX_DECL struct rx_hash_item * rx_hash_find (struct rx_hash * table,
  72.                         unsigned long hash,
  73.                         void * value,
  74.                         struct rx_hash_rules * rules);
  75. RX_DECL struct rx_hash_item * rx_hash_store (struct rx_hash * table,
  76.                          unsigned long hash,
  77.                          void * value,
  78.                          struct rx_hash_rules * rules);
  79. RX_DECL void rx_hash_free (struct rx_hash_item * it,
  80.                struct rx_hash_rules * rules);
  81. RX_DECL rx_Bitset rx_cset (struct rx *rx);
  82. RX_DECL rx_Bitset rx_copy_cset (struct rx *rx, rx_Bitset a);
  83. RX_DECL void rx_free_cset (struct rx * rx, rx_Bitset c);
  84. RX_DECL struct rexp_node * rexp_node (struct rx *rx,
  85.                       enum rexp_node_type type);
  86. RX_DECL struct rexp_node * rx_mk_r_cset (struct rx * rx,
  87.                      rx_Bitset b);
  88. RX_DECL struct rexp_node * rx_mk_r_concat (struct rx * rx,
  89.                        struct rexp_node * a,
  90.                        struct rexp_node * b);
  91. RX_DECL struct rexp_node * rx_mk_r_alternate (struct rx * rx,
  92.                           struct rexp_node * a,
  93.                           struct rexp_node * b);
  94. RX_DECL struct rexp_node * rx_mk_r_opt (struct rx * rx,
  95.                     struct rexp_node * a);
  96. RX_DECL struct rexp_node * rx_mk_r_star (struct rx * rx,
  97.                      struct rexp_node * a);
  98. RX_DECL struct rexp_node * rx_mk_r_2phase_star (struct rx * rx,
  99.                         struct rexp_node * a,
  100.                         struct rexp_node * b);
  101. RX_DECL struct rexp_node * rx_mk_r_side_effect (struct rx * rx,
  102.                         rx_side_effect a);
  103. RX_DECL struct rexp_node * rx_mk_r_data  (struct rx * rx,
  104.                       void * a);
  105. RX_DECL void rx_free_rexp (struct rx * rx, struct rexp_node * node);
  106. RX_DECL struct rexp_node * rx_copy_rexp (struct rx *rx,
  107.                      struct rexp_node *node);
  108. RX_DECL struct rx_nfa_state * rx_nfa_state (struct rx *rx);
  109. RX_DECL void rx_free_nfa_state (struct rx_nfa_state * n);
  110. RX_DECL struct rx_nfa_state * rx_id_to_nfa_state (struct rx * rx,
  111.                           int id);
  112. RX_DECL struct rx_nfa_edge * rx_nfa_edge (struct rx *rx,
  113.                       enum rx_nfa_etype type,
  114.                       struct rx_nfa_state *start,
  115.                       struct rx_nfa_state *dest);
  116. RX_DECL void rx_free_nfa_edge (struct rx_nfa_edge * e);
  117. RX_DECL void rx_free_nfa (struct rx *rx);
  118. RX_DECL int rx_build_nfa (struct rx *rx,
  119.               struct rexp_node *rexp,
  120.               struct rx_nfa_state **start,
  121.               struct rx_nfa_state **end);
  122. RX_DECL void rx_name_nfa_states (struct rx *rx);
  123. RX_DECL int rx_eclose_nfa (struct rx *rx);
  124. RX_DECL void rx_delete_epsilon_transitions (struct rx *rx);
  125. RX_DECL int rx_compactify_nfa (struct rx *rx,
  126.                    void **mem, unsigned long *size);
  127. RX_DECL struct rx_superset * rx_superstate_eclosure_union
  128.   (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl) ;
  129. RX_DECL void rx_release_superset (struct rx *rx,
  130.                   struct rx_superset *set);
  131. RX_DECL struct rx_superstate * rx_superstate (struct rx *rx,
  132.                           struct rx_superset *set);
  133. RX_DECL struct rx_inx * rx_handle_cache_miss
  134.   (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data) ;
  135.  
  136. #else /* ndef __STDC__ */
  137. RX_DECL int rx_bitset_is_subset ();
  138. RX_DECL void rx_bitset_null ();
  139. RX_DECL void rx_bitset_universe ();
  140. RX_DECL void rx_bitset_complement ();
  141. RX_DECL void rx_bitset_assign ();
  142. RX_DECL void rx_bitset_union ();
  143. RX_DECL void rx_bitset_intersection ();
  144. RX_DECL void rx_bitset_difference ();
  145. RX_DECL unsigned long rx_bitset_hash ();
  146. RX_DECL struct rx_hash_item * rx_hash_find ();
  147. RX_DECL struct rx_hash_item * rx_hash_store ();
  148. RX_DECL void rx_hash_free ();
  149. RX_DECL rx_Bitset rx_cset ();
  150. RX_DECL rx_Bitset rx_copy_cset ();
  151. RX_DECL void rx_free_cset ();
  152. RX_DECL struct rexp_node * rexp_node ();
  153. RX_DECL struct rexp_node * rx_mk_r_cset ();
  154. RX_DECL struct rexp_node * rx_mk_r_concat ();
  155. RX_DECL struct rexp_node * rx_mk_r_alternate ();
  156. RX_DECL struct rexp_node * rx_mk_r_opt ();
  157. RX_DECL struct rexp_node * rx_mk_r_star ();
  158. RX_DECL struct rexp_node * rx_mk_r_2phase_star ();
  159. RX_DECL struct rexp_node * rx_mk_r_side_effect ();
  160. RX_DECL struct rexp_node * rx_mk_r_data  ();
  161. RX_DECL void rx_free_rexp ();
  162. RX_DECL struct rexp_node * rx_copy_rexp ();
  163. RX_DECL struct rx_nfa_state * rx_nfa_state ();
  164. RX_DECL void rx_free_nfa_state ();
  165. RX_DECL struct rx_nfa_state * rx_id_to_nfa_state ();
  166. RX_DECL struct rx_nfa_edge * rx_nfa_edge ();
  167. RX_DECL void rx_free_nfa_edge ();
  168. RX_DECL void rx_free_nfa ();
  169. RX_DECL int rx_build_nfa ();
  170. RX_DECL void rx_name_nfa_states ();
  171. RX_DECL int rx_eclose_nfa ();
  172. RX_DECL void rx_delete_epsilon_transitions ();
  173. RX_DECL int rx_compactify_nfa ();
  174. RX_DECL struct rx_superset * rx_superstate_eclosure_union ();
  175. RX_DECL void rx_release_superset ();
  176. RX_DECL struct rx_superstate * rx_superstate ();
  177. RX_DECL struct rx_inx * rx_handle_cache_miss ();
  178.   
  179. #endif /* ndef __STDC__ */
  180.  
  181.  
  182.  
  183. /* Emacs already defines alloca, sometimes.  */
  184. #ifndef alloca
  185.  
  186. /* Make alloca work the best possible way.  */
  187. #ifdef __GNUC__
  188. #define alloca __builtin_alloca
  189. #else /* not __GNUC__ */
  190. #if HAVE_ALLOCA_H
  191. #include <alloca.h>
  192. #else /* not __GNUC__ or HAVE_ALLOCA_H */
  193. #ifndef _AIX /* Already did AIX, up at the top.  */
  194. char *alloca ();
  195. #endif /* not _AIX */
  196. #endif /* not HAVE_ALLOCA_H */ 
  197. #endif /* not __GNUC__ */
  198.  
  199. #endif /* not alloca */
  200.  
  201.  
  202. /* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
  203.  * use `alloca' instead of `malloc' for the backtracking stack.
  204.  *
  205.  * Emacs will die miserably if we don't do this.
  206.  */
  207.  
  208. #ifdef REGEX_MALLOC
  209.  
  210. #define REGEX_ALLOCATE malloc
  211.  
  212. #else /* not REGEX_MALLOC  */
  213.  
  214. #define REGEX_ALLOCATE alloca
  215.  
  216. #endif /* not REGEX_MALLOC */
  217.  
  218.  
  219.  
  220.  
  221. /* Memory management and stuff for emacs. */
  222.  
  223. #define BYTEWIDTH 8 /* In bits.  */
  224.  
  225. /* (Re)Allocate N items of type T using malloc.  */
  226. #define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
  227. #define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
  228.  
  229. #define remalloc(M, S) (M ? realloc (M, S) : malloc (S))
  230.  
  231. #ifdef emacs
  232. /* The `emacs' switch turns on certain matching commands
  233.  * that make sense only in Emacs. 
  234.  */
  235.  
  236. #include "config.h"
  237. #include "lisp.h"
  238. #include "buffer.h"
  239. #include "syntax.h"
  240.  
  241. /* Emacs uses `NULL' as a predicate.  */
  242. #undef NULL
  243. #else  /* not emacs */
  244.  
  245. /* Setting RX_MEMDBUG is useful if you have dbmalloc.  Maybe with similar
  246.  * packages too.
  247.  */
  248. #ifdef RX_MEMDBUG
  249. #include <malloc.h>
  250. #else /* not RX_RX_MEMDBUG */
  251.  
  252. /* We used to test for `BSTRING' here, but only GCC and Emacs define
  253.  * `BSTRING', as far as I know, and neither of them use this code.  
  254.  */
  255. #if HAVE_STRING_H || STDC_HEADERS
  256. #include <string.h>
  257. #ifndef bcmp
  258. #define bcmp(s1, s2, n)    memcmp ((s1), (s2), (n))
  259. #endif
  260. #ifndef bcopy
  261. #define bcopy(s, d, n)    memcpy ((d), (s), (n))
  262. #endif
  263. #ifndef bzero
  264. #define bzero(s, n)    memset ((s), 0, (n))
  265. #endif
  266. #else
  267. #include <strings.h>
  268. #endif
  269.  
  270. #ifdef STDC_HEADERS
  271. #include <stdlib.h>
  272. #else /* not STDC_HEADERS */
  273.  
  274. char *malloc ();
  275. char *realloc ();
  276. #endif /* not STDC_HEADERS */
  277.  
  278. #endif /* not RX_RX_MEMDBUG */
  279.  
  280.  
  281.  
  282. /* Define the syntax basics for \<, \>, etc.
  283.  * This must be nonzero for the wordchar and notwordchar pattern
  284.  * commands in re_match_2.
  285.  */
  286. #ifndef Sword 
  287. #define Sword 1
  288. #endif
  289.  
  290. #ifdef SYNTAX_TABLE
  291. extern char *re_syntax_table;
  292. #else /* not SYNTAX_TABLE */
  293.  
  294. /* How many characters in the character set.  */
  295. #define CHAR_SET_SIZE (1 << BYTEWIDTH)
  296. static char re_syntax_table[CHAR_SET_SIZE];
  297.  
  298. #ifdef __STDC__
  299. static void
  300. init_syntax_once (void)
  301. #else
  302. static void
  303. init_syntax_once ()
  304. #endif
  305. {
  306.    register int c;
  307.    static int done = 0;
  308.  
  309.    if (done)
  310.      return;
  311.  
  312.    bzero (re_syntax_table, sizeof re_syntax_table);
  313.  
  314.    for (c = 'a'; c <= 'z'; c++)
  315.      re_syntax_table[c] = Sword;
  316.  
  317.    for (c = 'A'; c <= 'Z'; c++)
  318.      re_syntax_table[c] = Sword;
  319.  
  320.    for (c = '0'; c <= '9'; c++)
  321.      re_syntax_table[c] = Sword;
  322.  
  323.    re_syntax_table['_'] = Sword;
  324.  
  325.    done = 1;
  326. }
  327. #endif /* not SYNTAX_TABLE */
  328.  
  329. #define SYNTAX(c) re_syntax_table[c]
  330.  
  331. #endif /* not emacs */
  332.  
  333.  
  334. /* Compile with `-DRX_DEBUG' and use the following flags.
  335.  *
  336.  * Debugging flags:
  337.  *       rx_debug - print information as a regexp is compiled
  338.  *     rx_debug_trace - print information as a regexp is executed
  339.  */
  340.  
  341. #ifdef RX_DEBUG
  342.  
  343. int rx_debug_compile = 0;
  344. int rx_debug_trace = 0;
  345. static struct re_pattern_buffer * dbug_rxb = 0;
  346.  
  347. #ifdef __STDC__
  348. typedef void (*side_effect_printer) (struct rx *, void *, FILE *);
  349. #else
  350. typedef void (*side_effect_printer) ();
  351. #endif
  352.  
  353. #ifdef __STDC__
  354. static void print_cset (struct rx *rx, rx_Bitset cset, FILE * fp);
  355. #else
  356. static void print_cset ();
  357. #endif
  358.  
  359. #ifdef __STDC__
  360. static void
  361. print_rexp (struct rx *rx,
  362.         struct rexp_node *node, int depth,
  363.         side_effect_printer seprint, FILE * fp)
  364. #else
  365. static void
  366. print_rexp (rx, node, depth, seprint, fp)
  367.      struct rx *rx;
  368.      struct rexp_node *node;
  369.      int depth;
  370.      side_effect_printer seprint;
  371.      FILE * fp;
  372. #endif
  373. {
  374.   if (!node)
  375.     return;
  376.   else
  377.     {
  378.       switch (node->type)
  379.     {
  380.     case r_cset:
  381.       {
  382.         fprintf (fp, "%*s", depth, "");
  383.         print_cset (rx, node->params.cset, fp);
  384.         fputc ('\n', fp);
  385.         break;
  386.       }
  387.  
  388.      case r_opt:
  389.     case r_star:
  390.       fprintf (fp, "%*s%s\n", depth, "",
  391.            node->type == r_opt ? "opt" : "star");
  392.       print_rexp (rx, node->params.pair.left, depth + 3, seprint, fp);
  393.       break;
  394.  
  395.     case r_2phase_star:
  396.       fprintf (fp, "%*s2phase star\n", depth, "");
  397.       print_rexp (rx, node->params.pair.right, depth + 3, seprint, fp);
  398.       print_rexp (rx, node->params.pair.left, depth + 3, seprint, fp);
  399.       break;
  400.  
  401.  
  402.     case r_alternate:
  403.     case r_concat:
  404.       fprintf (fp, "%*s%s\n", depth, "",
  405.            node->type == r_alternate ? "alt" : "concat");
  406.       print_rexp (rx, node->params.pair.left, depth + 3, seprint, fp);
  407.       print_rexp (rx, node->params.pair.right, depth + 3, seprint, fp);
  408.       break;
  409.     case r_side_effect:
  410.       fprintf (fp, "%*sSide effect: ", depth, "");
  411.       seprint (rx, node->params.side_effect, fp);
  412.       fputc ('\n', fp);
  413.     }
  414.     }
  415. }
  416.  
  417.  
  418. #ifdef __STDC__
  419. static void
  420. print_nfa (struct rx * rx,
  421.        struct rx_nfa_state * n,
  422.        side_effect_printer seprint, FILE * fp)
  423. #else
  424. static void
  425. print_nfa (rx, n, seprint, fp)
  426.      struct rx * rx;
  427.      struct rx_nfa_state * n;
  428.      side_effect_printer seprint;
  429.      FILE * fp;
  430. #endif
  431. {
  432.   while (n)
  433.     {
  434.       struct rx_nfa_edge *e = n->edges;
  435.       struct rx_possible_future *ec = n->futures;
  436.       fprintf (fp, "node %d %s\n", n->id,
  437.            n->is_final ? "final" : (n->is_start ? "start" : ""));
  438.       while (e)
  439.     {
  440.       fprintf (fp, "   edge to %d, ", e->dest->id);
  441.       switch (e->type)
  442.         {
  443.         case ne_epsilon:
  444.           fprintf (fp, "epsilon\n");
  445.           break;
  446.         case ne_side_effect:
  447.           fprintf (fp, "side effect ");
  448.           seprint (rx, e->params.side_effect, fp);
  449.           fputc ('\n', fp);
  450.           break;
  451.         case ne_cset:
  452.           fprintf (fp, "cset ");
  453.           print_cset (rx, e->params.cset, fp);
  454.           fputc ('\n', fp);
  455.           break;
  456.         }
  457.       e = e->next;
  458.     }
  459.  
  460.       while (ec)
  461.     {
  462.       int x;
  463.       struct rx_nfa_state_set * s;
  464.       struct rx_se_list * l;
  465.       fprintf (fp, "   eclosure to {");
  466.       for (s = ec->destset; s; s = s->cdr)
  467.         fprintf (fp, "%d ", s->car->id);
  468.       fprintf (fp, "} (");
  469.       for (l = ec->effects; l; l = l->cdr)
  470.         {
  471.           seprint (rx, l->car, fp);
  472.           fputc (' ', fp);
  473.         }
  474.       fprintf (fp, ")\n");
  475.       ec = ec->next;
  476.     }
  477.       n = n->next;
  478.     }
  479. }
  480.  
  481. static char * efnames [] =
  482. {
  483.   "bogon",
  484.   "re_se_try",
  485.   "re_se_pushback",
  486.   "re_se_push0",
  487.   "re_se_pushpos",
  488.   "re_se_chkpos",
  489.   "re_se_poppos",
  490.   "re_se_at_dot",
  491.   "re_se_syntax",
  492.   "re_se_not_syntax",
  493.   "re_se_begbuf",
  494.   "re_se_hat",
  495.   "re_se_wordbeg",
  496.   "re_se_wordbound",
  497.   "re_se_notwordbound",
  498.   "re_se_wordend",
  499.   "re_se_endbuf",
  500.   "re_se_dollar",
  501.   "re_se_fail",
  502. };
  503.  
  504. static char * efnames2[] =
  505. {
  506.   "re_se_win"
  507.   "re_se_lparen",
  508.   "re_se_rparen",
  509.   "re_se_backref",
  510.   "re_se_iter",
  511.   "re_se_end_iter",
  512.   "re_se_tv"
  513. };
  514.  
  515. static char * inx_names[] = 
  516. {
  517.   "rx_backtrack_point",
  518.   "rx_do_side_effects",
  519.   "rx_cache_miss",
  520.   "rx_next_char",
  521.   "rx_backtrack",
  522.   "rx_error_inx",
  523.   "rx_num_instructions"
  524. };
  525.  
  526.  
  527. #ifdef __STDC__
  528. static void
  529. re_seprint (struct rx * rx, void * effect, FILE * fp)
  530. #else
  531. static void
  532. re_seprint (rx, effect, fp)
  533.      struct rx * rx;
  534.      void * effect;
  535.      FILE * fp;
  536. #endif
  537. {
  538.   if ((int)effect < 0)
  539.     fputs (efnames[-(int)effect], fp);
  540.   else if (dbug_rxb)
  541.     {
  542.       struct re_se_params * p = &dbug_rxb->se_params[(int)effect];
  543.       fprintf (fp, "%s(%d,%d)", efnames2[p->se], p->op1, p->op2);
  544.     }
  545.   else
  546.     fprintf (fp, "[complex op # %d]", (int)effect);
  547. }
  548.  
  549.  
  550. /* These are for so the regex.c regression tests will compile. */
  551. void
  552. print_compiled_pattern (rxb)
  553.      struct re_pattern_buffer * rxb;
  554. {
  555. }
  556.  
  557. void
  558. print_fastmap (fm)
  559.      char * fm;
  560. {
  561. }
  562.  
  563.  
  564.  
  565. #endif /* RX_DEBUG */
  566.  
  567.  
  568.  
  569. /* This page: Bitsets.  Completely unintersting. */
  570.  
  571. #if 0
  572. #ifdef __STDC__
  573. RX_DECL int
  574. rx_bitset_is_equal (int size, rx_Bitset a, rx_Bitset b)
  575. #else
  576. RX_DECL int
  577. rx_bitset_is_equal (size, a, b)
  578.      int size;
  579.      rx_Bitset a;
  580.      rx_Bitset b;
  581. #endif
  582. {
  583.   int x;
  584.   RX_subset s = b[0];
  585.   b[0] = ~a[0];
  586.  
  587.   for (x = rx_bitset_numb_subsets(size) - 1; a[x] == b[x]; --x)
  588.     ;
  589.  
  590.   b[0] = s;
  591.   return !x && s == a[0];
  592. }
  593. #endif
  594.  
  595. #ifdef __STDC__
  596. RX_DECL int
  597. rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b)
  598. #else
  599. RX_DECL int
  600. rx_bitset_is_subset (size, a, b)
  601.      int size;
  602.      rx_Bitset a;
  603.      rx_Bitset b;
  604. #endif
  605. {
  606.   int x = rx_bitset_numb_subsets(size) - 1;
  607.   while (x-- && (a[x] & b[x]) == a[x]);
  608.   return x == -1;
  609. }
  610.  
  611.  
  612. #if 0
  613. #ifdef __STDC__
  614. RX_DECL int
  615. rx_bitset_empty (int size, rx_Bitset set)
  616. #else
  617. RX_DECL int
  618. rx_bitset_empty (size, set)
  619.      int size;
  620.      rx_Bitset set;
  621. #endif
  622. {
  623.   int x;
  624.   RX_subset s = set[0];
  625.   set[0] = 1;
  626.   for (x = rx_bitset_numb_subsets(size) - 1; !set[x]; --x)
  627.     ;
  628.   set[0] = s;
  629.   return !s;
  630. }
  631. #endif
  632.  
  633. #ifdef __STDC__
  634. RX_DECL void
  635. rx_bitset_null (int size, rx_Bitset b)
  636. #else
  637. RX_DECL void
  638. rx_bitset_null (size, b)
  639.      int size;
  640.      rx_Bitset b;
  641. #endif
  642. {
  643.   bzero (b, rx_sizeof_bitset(size));
  644. }
  645.  
  646.  
  647. #ifdef __STDC__
  648. RX_DECL void
  649. rx_bitset_universe (int size, rx_Bitset b)
  650. #else
  651. RX_DECL void
  652. rx_bitset_universe (size, b)
  653.      int size;
  654.      rx_Bitset b;
  655. #endif
  656. {
  657.   int x = rx_bitset_numb_subsets (size);
  658.   while (x--)
  659.     *b++ = ~(RX_subset)0;
  660. }
  661.  
  662.  
  663. #ifdef __STDC__
  664. RX_DECL void
  665. rx_bitset_complement (int size, rx_Bitset b)
  666. #else
  667. RX_DECL void
  668. rx_bitset_complement (size, b)
  669.      int size;
  670.      rx_Bitset b;
  671. #endif
  672. {
  673.   int x = rx_bitset_numb_subsets (size);
  674.   while (x--)
  675.     {
  676.       *b = ~*b;
  677.       ++b;
  678.     }
  679. }
  680.  
  681.  
  682. #ifdef __STDC__
  683. RX_DECL void
  684. rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b)
  685. #else
  686. RX_DECL void
  687. rx_bitset_assign (size, a, b)
  688.      int size;
  689.      rx_Bitset a;
  690.      rx_Bitset b;
  691. #endif
  692. {
  693.   int x;
  694.   for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
  695.     a[x] = b[x];
  696. }
  697.  
  698.  
  699. #ifdef __STDC__
  700. RX_DECL void
  701. rx_bitset_union (int size, rx_Bitset a, rx_Bitset b)
  702. #else
  703. RX_DECL void
  704. rx_bitset_union (size, a, b)
  705.      int size;
  706.      rx_Bitset a;
  707.      rx_Bitset b;
  708. #endif
  709. {
  710.   int x;
  711.   for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
  712.     a[x] |= b[x];
  713. }
  714.  
  715.  
  716. #ifdef __STDC__
  717. RX_DECL void
  718. rx_bitset_intersection (int size,
  719.             rx_Bitset a, rx_Bitset b)
  720. #else
  721. RX_DECL void
  722. rx_bitset_intersection (size, a, b)
  723.      int size;
  724.      rx_Bitset a;
  725.      rx_Bitset b;
  726. #endif
  727. {
  728.   int x;
  729.   for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
  730.     a[x] &= b[x];
  731. }
  732.  
  733.  
  734. #ifdef __STDC__
  735. RX_DECL void
  736. rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b)
  737. #else
  738. RX_DECL void
  739. rx_bitset_difference (size, a, b)
  740.      int size;
  741.      rx_Bitset a;
  742.      rx_Bitset b;
  743. #endif
  744. {
  745.   int x;
  746.   for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
  747.     a[x] &=  ~ b[x];
  748. }
  749.  
  750.  
  751. #if 0
  752. #ifdef __STDC__
  753. RX_DECL void
  754. rx_bitset_revdifference (int size,
  755.              rx_Bitset a, rx_Bitset b)
  756. #else
  757. RX_DECL void
  758. rx_bitset_revdifference (size, a, b)
  759.      int size;
  760.      rx_Bitset a;
  761.      rx_Bitset b;
  762. #endif
  763. {
  764.   int x;
  765.   for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
  766.     a[x] = ~a[x] & b[x];
  767. }
  768.  
  769. #ifdef __STDC__
  770. RX_DECL void
  771. rx_bitset_xor (int size, rx_Bitset a, rx_Bitset b)
  772. #else
  773. RX_DECL void
  774. rx_bitset_xor (size, a, b)
  775.      int size;
  776.      rx_Bitset a;
  777.      rx_Bitset b;
  778. #endif
  779. {
  780.   int x;
  781.   for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
  782.     a[x] ^= b[x];
  783. }
  784. #endif
  785.  
  786.  
  787. #ifdef __STDC__
  788. RX_DECL unsigned long
  789. rx_bitset_hash (int size, rx_Bitset b)
  790. #else
  791. RX_DECL unsigned long
  792. rx_bitset_hash (size, b)
  793.      int size;
  794.      rx_Bitset b;
  795. #endif
  796. {
  797.   int x;
  798.   unsigned long hash = (unsigned long)rx_bitset_hash;
  799.  
  800.   for (x = rx_bitset_numb_subsets(size) - 1; x >= 0; --x)
  801.     hash ^= rx_bitset_subset_val(b, x);
  802.  
  803.   return hash;
  804. }
  805.  
  806.  
  807. RX_DECL RX_subset rx_subset_singletons [RX_subset_bits] = 
  808. {
  809.   0x1,
  810.   0x2,
  811.   0x4,
  812.   0x8,
  813.   0x10,
  814.   0x20,
  815.   0x40,
  816.   0x80,
  817.   0x100,
  818.   0x200,
  819.   0x400,
  820.   0x800,
  821.   0x1000,
  822.   0x2000,
  823.   0x4000,
  824.   0x8000,
  825.   0x10000,
  826.   0x20000,
  827.   0x40000,
  828.   0x80000,
  829.   0x100000,
  830.   0x200000,
  831.   0x400000,
  832.   0x800000,
  833.   0x1000000,
  834.   0x2000000,
  835.   0x4000000,
  836.   0x8000000,
  837.   0x10000000,
  838.   0x20000000,
  839.   0x40000000,
  840.   0x80000000
  841. };
  842.  
  843. #ifdef RX_DEBUG
  844.  
  845. #ifdef __STDC__
  846. static void
  847. print_cset (struct rx *rx, rx_Bitset cset, FILE * fp)
  848. #else
  849. static void
  850. print_cset (rx, cset, fp)
  851.      struct rx *rx;
  852.      rx_Bitset cset;
  853.      FILE * fp;
  854. #endif
  855. {
  856.   int x;
  857.   fputc ('[', fp);
  858.   for (x = 0; x < rx->local_cset_size; ++x)
  859.     if (isprint(x) && RX_bitset_member (cset, x))
  860.       fputc (x, fp);
  861.   fputc (']', fp);
  862. }
  863.  
  864. #endif /*  RX_DEBUG */
  865.  
  866.  
  867.  
  868. /* This page: small object pools.
  869.  */
  870.  
  871. struct freelist
  872. {
  873.   struct freelist * next;
  874. };
  875.  
  876. struct chunked_pool
  877. {
  878.   int size;
  879.   struct freelist * freelist;
  880.   char * chunk;
  881.   int num_left;
  882. #if RX_DEBUG
  883.   int leakiness;
  884. #endif
  885. };
  886.  
  887. #define DEF_POOL(NAME,TYPE) \
  888.   struct chunked_pool NAME = { sizeof(TYPE), 0, 0, 0 }
  889.  
  890.  
  891. #ifdef __STDC__
  892. static char *
  893. chunk_malloc (struct chunked_pool * pool)
  894. #else
  895. static char *
  896. chunk_malloc (pool)
  897.      struct chunked_pool * pool;
  898. #endif
  899. {
  900.   struct freelist * it;
  901.   if (pool->freelist)
  902.     {
  903.       it = pool->freelist;
  904.       pool->freelist = it->next;
  905.     }
  906.   else
  907.     {
  908.       if (!pool->num_left)
  909.     {
  910.       pool->chunk = (char *)malloc (pool->size * 128);
  911.       if (!pool->chunk)
  912.         return 0;
  913.       pool->num_left = 128;
  914.     }
  915.       it = (struct freelist *)pool->chunk;
  916.       pool->chunk += pool->size;
  917.       --pool->num_left;
  918.     }
  919. #if RX_DEBUG
  920.   if (it)
  921.     ++pool->leakiness;
  922. #endif
  923.   return (char *)it;
  924. }
  925.  
  926.  
  927. #ifdef __STDC__
  928. static void
  929. chunk_free (struct chunked_pool * pool, char * mem)
  930. #else
  931. static void
  932. chunk_free (pool, mem)
  933.      struct chunked_pool * pool;
  934.      char * mem;
  935. #endif
  936. {
  937.   struct freelist * it = (struct freelist *)mem;
  938.   it->next = pool->freelist;
  939.   pool->freelist = it;
  940. #if RX_DEBUG
  941.   --pool->leakiness;
  942. #endif
  943. }
  944.  
  945. /* This is for pools of variable size objects where there are only a few
  946.  * sizes and where we tend to burst on one size at a time.
  947.  */
  948.  
  949. struct linked_chunk
  950. {
  951.   struct chunked_pool pool;
  952.   struct linked_chunk * next;
  953. };
  954.  
  955. struct chunk_group
  956. {
  957.   struct linked_chunk * list;
  958.   struct linked_chunk * current;
  959. };
  960.  
  961.  
  962. #ifdef __STDC__
  963. static int
  964. cg_find_pool (struct chunk_group * group, int size)
  965. #else
  966. static int
  967. cg_find_pool (group, size)
  968.      struct chunk_group * group;
  969.      int size;
  970. #endif
  971. {
  972.   if (!(group->current && (group->current->pool.size == size)))
  973.     {
  974.       struct linked_chunk * lc = group->list;
  975.       while (lc)
  976.     if (lc->pool.size == size)
  977.       {
  978.         group->current = lc;
  979.         return 1;
  980.       }
  981.       else
  982.     lc = lc->next;
  983.       lc = (struct linked_chunk *)malloc (sizeof (*lc));
  984.       if (!lc)
  985.     return 0;
  986.       bzero (lc, sizeof (*lc));
  987.       lc->pool.size = size;
  988.       lc->next = group->list;
  989.       group->list = lc;
  990.       group->current = lc;
  991.     }
  992.   return 1;
  993. }
  994.  
  995.  
  996. #ifdef __STDC__
  997. static char *
  998. cg_malloc (struct chunk_group * group, int size)
  999. #else
  1000. static char *
  1001. cg_malloc (group, size)
  1002.      struct chunk_group * group;
  1003.      int size;
  1004. #endif
  1005. {
  1006.   return (cg_find_pool (group, size)
  1007.       ?  chunk_malloc (&group->current->pool)
  1008.       : 0);
  1009. }
  1010.  
  1011.  
  1012. #ifdef __STDC__
  1013. static void
  1014. cg_free (struct chunk_group * group, int size, char * mem)
  1015. #else
  1016. static void
  1017. cg_free (group, size, mem)
  1018.      struct chunk_group * group;
  1019.      int size;
  1020.      char * mem;
  1021. #endif
  1022. {
  1023.   if (cg_find_pool (group, size))
  1024.     chunk_free (&group->current->pool, mem);
  1025. }
  1026.  
  1027.  
  1028.  
  1029. static unsigned long rx_hash_masks[4] =
  1030. {
  1031.   0x12488421,
  1032.   0x96699669,
  1033.   0xbe7dd7eb,
  1034.   0xffffffff
  1035. };
  1036.  
  1037.  
  1038. /* Hash tables */
  1039. #ifdef __STDC__
  1040. RX_DECL struct rx_hash_item * 
  1041. rx_hash_find (struct rx_hash * table,
  1042.           unsigned long hash,
  1043.           void * value,
  1044.           struct rx_hash_rules * rules)
  1045. #else
  1046. RX_DECL struct rx_hash_item * 
  1047. rx_hash_find (table, hash, value, rules)
  1048.      struct rx_hash * table;
  1049.      unsigned long hash;
  1050.      void * value;
  1051.      struct rx_hash_rules * rules;
  1052. #endif
  1053. {
  1054.   rx_hash_eq eq = rules->eq;
  1055.   int maskc = 0;
  1056.   int mask = rx_hash_masks [0];
  1057.   int bucket = (hash & mask) % 13;
  1058.  
  1059.   while (table->children [bucket])
  1060.     {
  1061.       table = table->children [bucket];
  1062.       ++maskc;
  1063.       mask = rx_hash_masks[maskc];
  1064.       bucket = (hash & mask) % 13;
  1065.     }
  1066.  
  1067.   {
  1068.     struct rx_hash_item * it = table->buckets[bucket];
  1069.     while (it)
  1070.       if (eq (it->data, value))
  1071.     return it;
  1072.       else
  1073.     it = it->next_same_hash;
  1074.   }
  1075.  
  1076.   return 0;
  1077. }
  1078.  
  1079. #ifdef __STDC__
  1080. RX_DECL struct rx_hash_item *
  1081. rx_hash_store (struct rx_hash * table,
  1082.            unsigned long hash,
  1083.            void * value,
  1084.            struct rx_hash_rules * rules)
  1085. #else
  1086. RX_DECL struct rx_hash_item *
  1087. rx_hash_store (table, hash, value, rules)
  1088.      struct rx_hash * table;
  1089.      unsigned long hash;
  1090.      void * value;
  1091.      struct rx_hash_rules * rules;
  1092. #endif
  1093. {
  1094.   rx_hash_eq eq = rules->eq;
  1095.   int maskc = 0;
  1096.   int mask = rx_hash_masks[0];
  1097.   int bucket = (hash & mask) % 13;
  1098.   int depth = 0;
  1099.   
  1100.   while (table->children [bucket])
  1101.     {
  1102.       table = table->children [bucket];
  1103.       ++maskc;
  1104.       mask = rx_hash_masks[maskc];
  1105.       bucket = (hash & mask) % 13;
  1106.       ++depth;
  1107.     }
  1108.   
  1109.   {
  1110.     struct rx_hash_item * it = table->buckets[bucket];
  1111.     while (it)
  1112.       if (eq (it->data, value))
  1113.     return it;
  1114.       else
  1115.     it = it->next_same_hash;
  1116.   }
  1117.   
  1118.   {
  1119.     if (   (depth < 3)
  1120.     && (table->bucket_size [bucket] >= 4))
  1121.       {
  1122.     struct rx_hash * newtab = ((struct rx_hash *)
  1123.                    rules->hash_alloc (rules));
  1124.     if (!newtab)
  1125.       goto add_to_bucket;
  1126.     bzero (newtab, sizeof (*newtab));
  1127.     newtab->parent = table;
  1128.     {
  1129.       struct rx_hash_item * them = table->buckets[bucket];
  1130.       unsigned long newmask = rx_hash_masks[maskc + 1];
  1131.       while (them)
  1132.         {
  1133.           struct rx_hash_item * save = them->next_same_hash;
  1134.           int new_buck = (them->hash & newmask) % 13;
  1135.           them->next_same_hash = newtab->buckets[new_buck];
  1136.           newtab->buckets[new_buck] = them;
  1137.           them->table = newtab;
  1138.           them = save;
  1139.           ++newtab->bucket_size[new_buck];
  1140.           ++newtab->refs;
  1141.         }
  1142.       table->refs = (table->refs - table->bucket_size[bucket] + 1);
  1143.       table->bucket_size[bucket] = 0;
  1144.       table->buckets[bucket] = 0;
  1145.       table->children[bucket] = newtab;
  1146.       table = newtab;
  1147.       bucket = (hash & newmask) % 13;
  1148.     }
  1149.       }
  1150.   }
  1151.  add_to_bucket:
  1152.   {
  1153.     struct rx_hash_item  * it = ((struct rx_hash_item *)
  1154.                  rules->hash_item_alloc (rules, value));
  1155.     if (!it)
  1156.       return 0;
  1157.     it->hash = hash;
  1158.     it->table = table;
  1159.     /* DATA and BINDING are to be set in hash_item_alloc */
  1160.     it->next_same_hash = table->buckets [bucket];
  1161.     table->buckets[bucket] = it;
  1162.     ++table->bucket_size [bucket];
  1163.     ++table->refs;
  1164.     return it;
  1165.   }
  1166. }
  1167.  
  1168. #ifdef __STDC__
  1169. RX_DECL void
  1170. rx_hash_free (struct rx_hash_item * it, struct rx_hash_rules * rules)
  1171. #else
  1172. RX_DECL void
  1173. rx_hash_free (it, rules)
  1174.      struct rx_hash_item * it;
  1175.      struct rx_hash_rules * rules;
  1176. #endif
  1177. {
  1178.   if (it)
  1179.     {
  1180.       struct rx_hash * table = it->table;
  1181.       unsigned long hash = it->hash;
  1182.       int depth = (table->parent
  1183.            ? (table->parent->parent
  1184.               ? (table->parent->parent->parent
  1185.              ? 3
  1186.              : 2)
  1187.               : 1)
  1188.            : 0);
  1189.       int bucket = (hash & rx_hash_masks [depth]) % 13;
  1190.       struct rx_hash_item ** pos = &table->buckets [bucket];
  1191.       
  1192.       while (*pos != it)
  1193.     pos = &(*pos)->next_same_hash;
  1194.       *pos = it->next_same_hash;
  1195.       rules->free_hash_item (it, rules);
  1196.       --table->bucket_size[bucket];
  1197.       --table->refs;
  1198.       while (!table->refs && depth)
  1199.     {
  1200.       struct rx_hash * save = table;
  1201.       table = table->parent;
  1202.       --depth;
  1203.       bucket = (hash & rx_hash_masks [depth]) % 13;
  1204.       --table->refs;
  1205.       table->children[bucket] = 0;
  1206.       rules->free_hash (save, rules);
  1207.     }
  1208.     }
  1209. }
  1210.  
  1211. #ifdef __STDC__
  1212. typedef void (*rx_hash_freefn) (struct rx_hash_item * it);
  1213. #else /* ndef __STDC__ */
  1214. typedef void (*rx_hash_freefn) ();
  1215. #endif /* ndef __STDC__ */
  1216.  
  1217. #ifdef __STDC__
  1218. RX_DECL void
  1219. rx_free_hash_table (struct rx_hash * tab, rx_hash_freefn freefn,
  1220.             struct rx_hash_rules * rules)
  1221. #else
  1222. RX_DECL void
  1223. rx_free_hash_table (tab, freefn, rules)
  1224.      struct rx_hash * tab;
  1225.      rx_hash_freefn freefn;
  1226.      struct rx_hash_rules * rules;
  1227. #endif
  1228. {
  1229.   int x;
  1230.  
  1231.   for (x = 0; x < 13; ++x)
  1232.     if (tab->children[x])
  1233.       {
  1234.     rx_free_hash_table (tab->children[x], freefn, rules);
  1235.     rules->free_hash (tab->children[x], rules);
  1236.       }
  1237.     else
  1238.       {
  1239.     struct rx_hash_item * them = tab->buckets[x];
  1240.     while (them)
  1241.       {
  1242.         struct rx_hash_item * that = them;
  1243.         them = that->next_same_hash;
  1244.         freefn (that);
  1245.         rules->free_hash_item (that, rules);
  1246.       }
  1247.       }
  1248. }
  1249.  
  1250.  
  1251.  
  1252. /* Utilities for manipulating bitset represntations of characters sets. */
  1253.  
  1254. static struct chunk_group cset_chunks = {0, 0};
  1255.  
  1256. #ifdef __STDC__
  1257. RX_DECL rx_Bitset
  1258. rx_cset (struct rx *rx)
  1259. #else
  1260. RX_DECL rx_Bitset
  1261. rx_cset (rx)
  1262.      struct rx *rx;
  1263. #endif
  1264. {
  1265.   rx_Bitset b = (rx_Bitset) cg_malloc (&cset_chunks,
  1266.                        rx_sizeof_bitset (rx->local_cset_size));
  1267.   if (b)
  1268.     rx_bitset_null (rx->local_cset_size, b);
  1269.   return b;
  1270. }
  1271.  
  1272.  
  1273. #ifdef __STDC__
  1274. RX_DECL rx_Bitset
  1275. rx_copy_cset (struct rx *rx, rx_Bitset a)
  1276. #else
  1277. RX_DECL rx_Bitset
  1278. rx_copy_cset (rx, a)
  1279.      struct rx *rx;
  1280.      rx_Bitset a;
  1281. #endif
  1282. {
  1283.   rx_Bitset cs = rx_cset (rx);
  1284.  
  1285.   if (cs)
  1286.     rx_bitset_union (rx->local_cset_size, cs, a);
  1287.  
  1288.   return cs;
  1289. }
  1290.  
  1291.  
  1292. #ifdef __STDC__
  1293. RX_DECL void
  1294. rx_free_cset (struct rx * rx, rx_Bitset c)
  1295. #else
  1296. RX_DECL void
  1297. rx_free_cset (rx, c)
  1298.      struct rx * rx;
  1299.      rx_Bitset c;
  1300. #endif
  1301. {
  1302.   if (c)
  1303.     cg_free (&cset_chunks, rx_sizeof_bitset (rx->local_cset_size), (char *)c);
  1304. }
  1305.  
  1306.  
  1307. /* Hash table memory allocation policy for the regexp compiler */
  1308.  
  1309. static DEF_POOL(hash_tabs, struct rx_hash);
  1310. static DEF_POOL(hash_items, struct rx_hash_item);
  1311.  
  1312. #ifdef __STDC__
  1313. struct rx_hash *
  1314. compiler_hash_alloc (struct rx_hash_rules * rules)
  1315. #else
  1316. struct rx_hash *
  1317. compiler_hash_alloc (rules)
  1318.      struct rx_hash_rules * rules;
  1319. #endif
  1320. {
  1321.   return (struct rx_hash *)chunk_malloc (&hash_tabs);
  1322. }
  1323.  
  1324. #ifdef __STDC__
  1325. struct rx_hash_item *
  1326. compiler_hash_item_alloc (struct rx_hash_rules * rules, void * value)
  1327. #else
  1328. struct rx_hash_item *
  1329. compiler_hash_item_alloc (rules, value)
  1330.      struct rx_hash_rules * rules;
  1331.      void * value;
  1332. #endif
  1333. {
  1334.   struct rx_hash_item * it = (struct rx_hash_item *)chunk_malloc (&hash_items);
  1335.   if (it)
  1336.     {
  1337.       it->data = value;
  1338.       it->binding = 0;
  1339.     }
  1340.   return it;
  1341. }
  1342.  
  1343. #ifdef __STDC__
  1344. void
  1345. compiler_free_hash (struct rx_hash * tab,
  1346.             struct rx_hash_rules * rules)
  1347. #else
  1348. void
  1349. compiler_free_hash (tab, rules)
  1350.      struct rx_hash * tab;
  1351.      struct rx_hash_rules * rules;
  1352. #endif
  1353. {
  1354.   chunk_free (&hash_tabs, (char *)tab);
  1355. }
  1356.  
  1357. #ifdef __STDC__
  1358. void
  1359. compiler_free_hash_item (struct rx_hash_item * item,
  1360.              struct rx_hash_rules * rules)
  1361. #else
  1362. void
  1363. compiler_free_hash_item (item, rules)
  1364.      struct rx_hash_item * item;
  1365.      struct rx_hash_rules * rules;
  1366. #endif
  1367. {
  1368.   chunk_free (&hash_items, (char *)item);
  1369. }
  1370.  
  1371.  
  1372. /* This page: REXP_NODE (expression tree) structures. */
  1373.  
  1374. static DEF_POOL (rexp_pool, struct rexp_node);
  1375.  
  1376. #ifdef __STDC__
  1377. RX_DECL struct rexp_node *
  1378. rexp_node (struct rx *rx,
  1379.        enum rexp_node_type type)
  1380. #else
  1381. RX_DECL struct rexp_node *
  1382. rexp_node (rx, type)
  1383.      struct rx *rx;
  1384.      enum rexp_node_type type;
  1385. #endif
  1386. {
  1387.   struct rexp_node *n;
  1388.  
  1389.   n = (struct rexp_node *)chunk_malloc (&rexp_pool);
  1390.   bzero (n, sizeof (*n));
  1391.   if (n)
  1392.     n->type = type;
  1393.   return n;
  1394. }
  1395.  
  1396.  
  1397. /* free_rexp_node assumes that the bitset passed to rx_mk_r_cset
  1398.  * can be freed using rx_free_cset.
  1399.  */
  1400. #ifdef __STDC__
  1401. RX_DECL struct rexp_node *
  1402. rx_mk_r_cset (struct rx * rx,
  1403.           rx_Bitset b)
  1404. #else
  1405. RX_DECL struct rexp_node *
  1406. rx_mk_r_cset (rx, b)
  1407.      struct rx * rx;
  1408.      rx_Bitset b;
  1409. #endif
  1410. {
  1411.   struct rexp_node * n = rexp_node (rx, r_cset);
  1412.   if (n)
  1413.     n->params.cset = b;
  1414.   return n;
  1415. }
  1416.  
  1417.  
  1418. #ifdef __STDC__
  1419. RX_DECL struct rexp_node *
  1420. rx_mk_r_concat (struct rx * rx,
  1421.         struct rexp_node * a,
  1422.         struct rexp_node * b)
  1423. #else
  1424. RX_DECL struct rexp_node *
  1425. rx_mk_r_concat (rx, a, b)
  1426.      struct rx * rx;
  1427.      struct rexp_node * a;
  1428.      struct rexp_node * b;
  1429. #endif
  1430. {
  1431.   struct rexp_node * n = rexp_node (rx, r_concat);
  1432.   if (n)
  1433.     {
  1434.       n->params.pair.left = a;
  1435.       n->params.pair.right = b;
  1436.     }
  1437.   return n;
  1438. }
  1439.  
  1440.  
  1441. #ifdef __STDC__
  1442. RX_DECL struct rexp_node *
  1443. rx_mk_r_alternate (struct rx * rx,
  1444.            struct rexp_node * a,
  1445.            struct rexp_node * b)
  1446. #else
  1447. RX_DECL struct rexp_node *
  1448. rx_mk_r_alternate (rx, a, b)
  1449.      struct rx * rx;
  1450.      struct rexp_node * a;
  1451.      struct rexp_node * b;
  1452. #endif
  1453. {
  1454.   struct rexp_node * n = rexp_node (rx, r_alternate);
  1455.   if (n)
  1456.     {
  1457.       n->params.pair.left = a;
  1458.       n->params.pair.right = b;
  1459.     }
  1460.   return n;
  1461. }
  1462.  
  1463.  
  1464. #ifdef __STDC__
  1465. RX_DECL struct rexp_node *
  1466. rx_mk_r_opt (struct rx * rx,
  1467.          struct rexp_node * a)
  1468. #else
  1469. RX_DECL struct rexp_node *
  1470. rx_mk_r_opt (rx, a)
  1471.      struct rx * rx;
  1472.      struct rexp_node * a;
  1473. #endif
  1474. {
  1475.   struct rexp_node * n = rexp_node (rx, r_opt);
  1476.   if (n)
  1477.     {
  1478.       n->params.pair.left = a;
  1479.       n->params.pair.right = 0;
  1480.     }
  1481.   return n;
  1482. }
  1483.  
  1484.  
  1485. #ifdef __STDC__
  1486. RX_DECL struct rexp_node *
  1487. rx_mk_r_star (struct rx * rx,
  1488.           struct rexp_node * a)
  1489. #else
  1490. RX_DECL struct rexp_node *
  1491. rx_mk_r_star (rx, a)
  1492.      struct rx * rx;
  1493.      struct rexp_node * a;
  1494. #endif
  1495. {
  1496.   struct rexp_node * n = rexp_node (rx, r_star);
  1497.   if (n)
  1498.     {
  1499.       n->params.pair.left = a;
  1500.       n->params.pair.right = 0;
  1501.     }
  1502.   return n;
  1503. }
  1504.  
  1505.  
  1506. #ifdef __STDC__
  1507. RX_DECL struct rexp_node *
  1508. rx_mk_r_2phase_star (struct rx * rx,
  1509.              struct rexp_node * a,
  1510.              struct rexp_node * b)
  1511. #else
  1512. RX_DECL struct rexp_node *
  1513. rx_mk_r_2phase_star (rx, a, b)
  1514.      struct rx * rx;
  1515.      struct rexp_node * a;
  1516.      struct rexp_node * b;
  1517. #endif
  1518. {
  1519.   struct rexp_node * n = rexp_node (rx, r_2phase_star);
  1520.   if (n)
  1521.     {
  1522.       n->params.pair.left = a;
  1523.       n->params.pair.right = b;
  1524.     }
  1525.   return n;
  1526. }
  1527.  
  1528.  
  1529.  
  1530. #ifdef __STDC__
  1531. RX_DECL struct rexp_node *
  1532. rx_mk_r_side_effect (struct rx * rx,
  1533.              rx_side_effect a)
  1534. #else
  1535. RX_DECL struct rexp_node *
  1536. rx_mk_r_side_effect (rx, a)
  1537.      struct rx * rx;
  1538.      rx_side_effect a;
  1539. #endif
  1540. {
  1541.   struct rexp_node * n = rexp_node (rx, r_side_effect);
  1542.   if (n)
  1543.     {
  1544.       n->params.side_effect = a;
  1545.       n->params.pair.right = 0;
  1546.     }
  1547.   return n;
  1548. }
  1549.  
  1550.  
  1551. #ifdef __STDC__
  1552. RX_DECL struct rexp_node *
  1553. rx_mk_r_data  (struct rx * rx,
  1554.            void * a)
  1555. #else
  1556. RX_DECL struct rexp_node *
  1557. rx_mk_r_data  (rx, a)
  1558.      struct rx * rx;
  1559.      void * a;
  1560. #endif
  1561. {
  1562.   struct rexp_node * n = rexp_node (rx, r_data);
  1563.   if (n)
  1564.     {
  1565.       n->params.pair.left = a;
  1566.       n->params.pair.right = 0;
  1567.     }
  1568.   return n;
  1569. }
  1570.  
  1571.  
  1572. #ifdef __STDC__
  1573. RX_DECL void
  1574. rx_free_rexp (struct rx * rx, struct rexp_node * node)
  1575. #else
  1576. RX_DECL void
  1577. rx_free_rexp (rx, node)
  1578.      struct rx * rx;
  1579.      struct rexp_node * node;
  1580. #endif
  1581. {
  1582.   if (node)
  1583.     {
  1584.       switch (node->type)
  1585.     {
  1586.     case r_cset:
  1587.       if (node->params.cset)
  1588.         rx_free_cset (rx, node->params.cset);
  1589.  
  1590.     case r_side_effect:
  1591.       break;
  1592.       
  1593.     case r_concat:
  1594.     case r_alternate:
  1595.     case r_2phase_star:
  1596.     case r_opt:
  1597.     case r_star:
  1598.       rx_free_rexp (rx, node->params.pair.left);
  1599.       rx_free_rexp (rx, node->params.pair.right);
  1600.       break;
  1601.  
  1602.     case r_data:
  1603.       /* This shouldn't occur. */
  1604.       break;
  1605.     }
  1606.       chunk_free (&rexp_pool, (char *)node);
  1607.     }
  1608. }
  1609.  
  1610.  
  1611. #ifdef __STDC__
  1612. RX_DECL struct rexp_node * 
  1613. rx_copy_rexp (struct rx *rx,
  1614.        struct rexp_node *node)
  1615. #else
  1616. RX_DECL struct rexp_node * 
  1617. rx_copy_rexp (rx, node)
  1618.      struct rx *rx;
  1619.      struct rexp_node *node;
  1620. #endif
  1621. {
  1622.   if (!node)
  1623.     return 0;
  1624.   else
  1625.     {
  1626.       struct rexp_node *n = rexp_node (rx, node->type);
  1627.       if (!n)
  1628.     return 0;
  1629.       switch (node->type)
  1630.     {
  1631.     case r_cset:
  1632.       n->params.cset = rx_copy_cset (rx, node->params.cset);
  1633.       if (!n->params.cset)
  1634.         {
  1635.           rx_free_rexp (rx, n);
  1636.           return 0;
  1637.         }
  1638.       break;
  1639.  
  1640.     case r_side_effect:
  1641.       n->params.side_effect = node->params.side_effect;
  1642.       break;
  1643.  
  1644.     case r_concat:
  1645.     case r_alternate:
  1646.     case r_opt:
  1647.     case r_2phase_star:
  1648.     case r_star:
  1649.       n->params.pair.left =
  1650.         rx_copy_rexp (rx, node->params.pair.left);
  1651.       n->params.pair.right =
  1652.         rx_copy_rexp (rx, node->params.pair.right);
  1653.       if (   (node->params.pair.left && !n->params.pair.left)
  1654.           || (node->params.pair.right && !n->params.pair.right))
  1655.         {
  1656.           rx_free_rexp  (rx, n);
  1657.           return 0;
  1658.         }
  1659.       break;
  1660.     case r_data:
  1661.       /* shouldn't happen */
  1662.       break;
  1663.     }
  1664.       return n;
  1665.     }
  1666. }
  1667.  
  1668.  
  1669.  
  1670. /* This page: functions to build and destroy graphs that describe nfa's */
  1671.  
  1672. static DEF_POOL(state_pool, struct rx_nfa_state);
  1673.  
  1674. /* Constructs a new nfa node. */
  1675. #ifdef __STDC__
  1676. RX_DECL struct rx_nfa_state *
  1677. rx_nfa_state (struct rx *rx)
  1678. #else
  1679. RX_DECL struct rx_nfa_state *
  1680. rx_nfa_state (rx)
  1681.      struct rx *rx;
  1682. #endif
  1683. {
  1684.   struct rx_nfa_state * n = (struct rx_nfa_state *)chunk_malloc (&state_pool);
  1685.   if (!n)
  1686.     return 0;
  1687.   bzero (n, sizeof (*n));
  1688.   n->next = rx->nfa_states;
  1689.   rx->nfa_states = n;
  1690.   return n;
  1691. }
  1692.  
  1693.  
  1694. #ifdef __STDC__
  1695. RX_DECL void
  1696. rx_free_nfa_state (struct rx_nfa_state * n)
  1697. #else
  1698. RX_DECL void
  1699. rx_free_nfa_state (n)
  1700.   struct rx_nfa_state * n;
  1701. #endif
  1702. {
  1703.   chunk_free (&state_pool, (char *)n);
  1704. }
  1705.  
  1706.  
  1707. /* This looks up an nfa node, given a numeric id.  Numeric id's are
  1708.  * assigned after the nfa has been built.
  1709.  */
  1710. #ifdef __STDC__
  1711. RX_DECL struct rx_nfa_state * 
  1712. rx_id_to_nfa_state (struct rx * rx,
  1713.             int id)
  1714. #else
  1715. RX_DECL struct rx_nfa_state * 
  1716. rx_id_to_nfa_state (rx, id)
  1717.      struct rx * rx;
  1718.      int id;
  1719. #endif
  1720. {
  1721.   struct rx_nfa_state * n;
  1722.   for (n = rx->nfa_states; n; n = n->next)
  1723.     if (n->id == id)
  1724.       return n;
  1725.   return 0;
  1726. }
  1727.  
  1728.  
  1729. /* This adds an edge between two nodes, but doesn't initialize the 
  1730.  * edge label.
  1731.  */
  1732.  
  1733. static DEF_POOL(edge_pool, struct rx_nfa_edge);
  1734.  
  1735. #ifdef __STDC__
  1736. RX_DECL struct rx_nfa_edge * 
  1737. rx_nfa_edge (struct rx *rx,
  1738.          enum rx_nfa_etype type,
  1739.          struct rx_nfa_state *start,
  1740.          struct rx_nfa_state *dest)
  1741. #else
  1742. RX_DECL struct rx_nfa_edge * 
  1743. rx_nfa_edge (rx, type, start, dest)
  1744.      struct rx *rx;
  1745.      enum rx_nfa_etype type;
  1746.      struct rx_nfa_state *start;
  1747.      struct rx_nfa_state *dest;
  1748. #endif
  1749. {
  1750.   struct rx_nfa_edge *e = (struct rx_nfa_edge *)chunk_malloc (&edge_pool);
  1751.   if (!e)
  1752.     return 0;
  1753.   e->next = start->edges;
  1754.   start->edges = e;
  1755.   e->type = type;
  1756.   e->dest = dest;
  1757.   return e;
  1758. }
  1759.  
  1760.  
  1761. #ifdef __STDC__
  1762. RX_DECL void
  1763. rx_free_nfa_edge (struct rx_nfa_edge * e)
  1764. #else
  1765. RX_DECL void
  1766. rx_free_nfa_edge (e)
  1767.      struct rx_nfa_edge * e;
  1768. #endif
  1769. {
  1770.   chunk_free (&edge_pool, (char *)e);
  1771. }
  1772.  
  1773.  
  1774. /* This constructs a POSSIBLE_FUTURE, which is a kind epsilon-closure
  1775.  * of an NFA.  These are added to an nfa automaticly by eclose_nfa.
  1776.  */  
  1777.  
  1778. static DEF_POOL(pf_pool, struct rx_possible_future);
  1779.  
  1780. #ifdef __STDC__
  1781. static struct rx_possible_future * 
  1782. rx_possible_future (struct rx * rx,
  1783.          struct rx_se_list * effects)
  1784. #else
  1785. static struct rx_possible_future * 
  1786. rx_possible_future (rx, effects)
  1787.      struct rx * rx;
  1788.      struct rx_se_list * effects;
  1789. #endif
  1790. {
  1791.   struct rx_possible_future *ec = ((struct rx_possible_future *)
  1792.                 chunk_malloc (&pf_pool));
  1793.   if (!ec)
  1794.     return 0;
  1795.   ec->destset = 0;
  1796.   ec->next = 0;
  1797.   ec->effects = effects;
  1798.   return ec;
  1799. }
  1800.  
  1801.  
  1802. #ifdef __STDC__
  1803. static void
  1804. rx_free_possible_future (struct rx_possible_future * pf)
  1805. #else
  1806. static void
  1807. rx_free_possible_future (pf)
  1808.      struct rx_possible_future * pf;
  1809. #endif
  1810. {
  1811.   chunk_free (&pf_pool, (char *)pf);
  1812. }
  1813.  
  1814.  
  1815. #ifdef __STDC__
  1816. RX_DECL void
  1817. rx_free_nfa (struct rx *rx)
  1818. #else
  1819. RX_DECL void
  1820. rx_free_nfa (rx)
  1821.      struct rx *rx;
  1822. #endif
  1823. {
  1824.   while (rx->nfa_states)
  1825.     {
  1826.       while (rx->nfa_states->edges)
  1827.     {
  1828.       switch (rx->nfa_states->edges->type)
  1829.         {
  1830.         case ne_cset:
  1831.           rx_free_cset (rx, rx->nfa_states->edges->params.cset);
  1832.           break;
  1833.         default:
  1834.           break;
  1835.         }
  1836.       {
  1837.         struct rx_nfa_edge * e;
  1838.         e = rx->nfa_states->edges;
  1839.         rx->nfa_states->edges = rx->nfa_states->edges->next;
  1840.         rx_free_nfa_edge (e);
  1841.       }
  1842.     } /* while (rx->nfa_states->edges) */
  1843.       {
  1844.     /* Iterate over the partial epsilon closures of rx->nfa_states */
  1845.     struct rx_possible_future * pf = rx->nfa_states->futures;
  1846.     while (pf)
  1847.       {
  1848.         struct rx_possible_future * pft = pf;
  1849.         pf = pf->next;
  1850.         rx_free_possible_future (pft);
  1851.       }
  1852.       }
  1853.       {
  1854.     struct rx_nfa_state *n;
  1855.     n = rx->nfa_states;
  1856.     rx->nfa_states = rx->nfa_states->next;
  1857.     rx_free_nfa_state (n);
  1858.       }
  1859.     }
  1860. }
  1861.  
  1862.  
  1863.  
  1864. /* This page: translating a pattern expression in to an nfa and doing the 
  1865.  * static part of the nfa->super-nfa translation.
  1866.  */
  1867.  
  1868. /* This is the thompson regexp->nfa algorithm. */
  1869. #ifdef __STDC__
  1870. RX_DECL int
  1871. rx_build_nfa (struct rx *rx,
  1872.           struct rexp_node *rexp,
  1873.           struct rx_nfa_state **start,
  1874.           struct rx_nfa_state **end)
  1875. #else
  1876. RX_DECL int
  1877. rx_build_nfa (rx, rexp, start, end)
  1878.      struct rx *rx;
  1879.      struct rexp_node *rexp;
  1880.      struct rx_nfa_state **start;
  1881.      struct rx_nfa_state **end;
  1882. #endif
  1883. {
  1884.   struct rx_nfa_edge *edge;
  1885.  
  1886.   /* Start & end nodes may have been allocated by the caller. */
  1887.   *start = *start ? *start : rx_nfa_state (rx);
  1888.  
  1889.   if (!*start)
  1890.     return 0;
  1891.  
  1892.   if (!rexp)
  1893.     {
  1894.       *end = *start;
  1895.       return 1;
  1896.     }
  1897.  
  1898.   *end = *end ? *end : rx_nfa_state (rx);
  1899.  
  1900.   if (!*end)
  1901.     {
  1902.       rx_free_nfa_state (*start);
  1903.       return 0;
  1904.     }
  1905.  
  1906.   switch (rexp->type)
  1907.     {
  1908.     case r_data:
  1909.       return 0;
  1910.       break;
  1911.     case r_cset:
  1912.       edge = rx_nfa_edge (rx, ne_cset, *start, *end);
  1913.       if (!edge)
  1914.     return 0;
  1915.       edge->params.cset = rx_copy_cset (rx, rexp->params.cset);
  1916.       if (!edge->params.cset)
  1917.     {
  1918.       rx_free_nfa_edge (edge);
  1919.       return 0;
  1920.     }
  1921.       return 1;
  1922.  
  1923.     case r_opt:
  1924.       return (rx_build_nfa (rx, rexp->params.pair.left, start, end)
  1925.           && rx_nfa_edge (rx, ne_epsilon, *start, *end));
  1926.  
  1927.     case r_star:
  1928.       {
  1929.     struct rx_nfa_state * star_start = 0;
  1930.     struct rx_nfa_state * star_end = 0;
  1931.     return (rx_build_nfa (rx, rexp->params.pair.left,
  1932.                   &star_start, &star_end)
  1933.         && star_start
  1934.         && star_end
  1935.         && rx_nfa_edge (rx, ne_epsilon, star_start, star_end)
  1936.         && rx_nfa_edge (rx, ne_epsilon, *start, star_start)
  1937.         && rx_nfa_edge (rx, ne_epsilon, star_end, *end)
  1938.  
  1939.         && rx_nfa_edge (rx, ne_epsilon, star_end, star_start));
  1940.       }
  1941.  
  1942.     case r_2phase_star:
  1943.       {
  1944.     struct rx_nfa_state * star_start = 0;
  1945.     struct rx_nfa_state * star_end = 0;
  1946.     struct rx_nfa_state * loop_exp_start = 0;
  1947.     struct rx_nfa_state * loop_exp_end = 0;
  1948.  
  1949.     return (rx_build_nfa (rx, rexp->params.pair.left,
  1950.                   &star_start, &star_end)
  1951.         && rx_build_nfa (rx, rexp->params.pair.right,
  1952.                  &loop_exp_start, &loop_exp_end)
  1953.         && star_start
  1954.         && star_end
  1955.         && loop_exp_end
  1956.         && loop_exp_start
  1957.         && rx_nfa_edge (rx, ne_epsilon, star_start, *end)
  1958.         && rx_nfa_edge (rx, ne_epsilon, *start, star_start)
  1959.         && rx_nfa_edge (rx, ne_epsilon, star_end, *end)
  1960.  
  1961.         && rx_nfa_edge (rx, ne_epsilon, star_end, loop_exp_start)
  1962.         && rx_nfa_edge (rx, ne_epsilon, loop_exp_end, star_start));
  1963.       }
  1964.  
  1965.  
  1966.     case r_concat:
  1967.       {
  1968.     struct rx_nfa_state *shared = 0;
  1969.     return
  1970.       (rx_build_nfa (rx, rexp->params.pair.left, start, &shared)
  1971.        && rx_build_nfa (rx, rexp->params.pair.right, &shared, end));
  1972.       }
  1973.  
  1974.     case r_alternate:
  1975.       {
  1976.     struct rx_nfa_state *ls = 0;
  1977.     struct rx_nfa_state *le = 0;
  1978.     struct rx_nfa_state *rs = 0;
  1979.     struct rx_nfa_state *re = 0;
  1980.     return (rx_build_nfa (rx, rexp->params.pair.left, &ls, &le)
  1981.         && rx_build_nfa (rx, rexp->params.pair.right, &rs, &re)
  1982.         && rx_nfa_edge (rx, ne_epsilon, *start, ls)
  1983.         && rx_nfa_edge (rx, ne_epsilon, *start, rs)
  1984.         && rx_nfa_edge (rx, ne_epsilon, le, *end)
  1985.         && rx_nfa_edge (rx, ne_epsilon, re, *end));
  1986.       }
  1987.  
  1988.     case r_side_effect:
  1989.       edge = rx_nfa_edge (rx, ne_side_effect, *start, *end);
  1990.       if (!edge)
  1991.     return 0;
  1992.       edge->params.side_effect = rexp->params.side_effect;
  1993.       return 1;
  1994.     };
  1995. }
  1996.  
  1997.  
  1998. /* NAME_RX->NFA_STATES identifies all nodes with non-epsilon transitions.
  1999.  * These nodes can occur in super-states.  All nodes are given an integer id.
  2000.  * The id is non-negative if the node has non-epsilon out-transitions, negative
  2001.  * otherwise (this is because we want the non-negative ids to be used as 
  2002.  * array indexes in a few places).
  2003.  */
  2004.  
  2005. #ifdef __STDC__
  2006. RX_DECL void
  2007. rx_name_nfa_states (struct rx *rx)
  2008. #else
  2009. RX_DECL void
  2010. rx_name_nfa_states (rx)
  2011.      struct rx *rx;
  2012. #endif
  2013. {
  2014.   struct rx_nfa_state *n = rx->nfa_states;
  2015.  
  2016.   rx->nodec = 0;
  2017.   rx->epsnodec = -1;
  2018.  
  2019.   while (n)
  2020.     {
  2021.       struct rx_nfa_edge *e = n->edges;
  2022.  
  2023.       if (n->is_start)
  2024.     n->eclosure_needed = 1;
  2025.  
  2026.       while (e)
  2027.     {
  2028.       switch (e->type)
  2029.         {
  2030.         case ne_epsilon:
  2031.         case ne_side_effect:
  2032.           break;
  2033.  
  2034.         case ne_cset:
  2035.           n->id = rx->nodec++;
  2036.           {
  2037.         struct rx_nfa_edge *from_n = n->edges;
  2038.         while (from_n)
  2039.           {
  2040.             from_n->dest->eclosure_needed = 1;
  2041.             from_n = from_n->next;
  2042.           }
  2043.           }
  2044.           goto cont;
  2045.         }
  2046.       e = e->next;
  2047.     }
  2048.       n->id = rx->epsnodec--;
  2049.     cont:
  2050.       n = n->next;
  2051.     }
  2052.   rx->epsnodec = -rx->epsnodec;
  2053. }
  2054.  
  2055.  
  2056. /* This page: data structures for the static part of the nfa->supernfa
  2057.  * translation.
  2058.  */
  2059.  
  2060. /* The next several functions compare, construct, etc. lists of side
  2061.  * effects.  See ECLOSE_NFA (below) for details.
  2062.  */
  2063.  
  2064. /* Ordering of rx_se_list
  2065.  * (-1, 0, 1 return value convention).
  2066.  */
  2067.  
  2068. #ifdef __STDC__
  2069. static int 
  2070. se_list_cmp (void * va, void * vb)
  2071. #else
  2072. static int 
  2073. se_list_cmp (va, vb)
  2074.      void * va;
  2075.      void * vb;
  2076. #endif
  2077. {
  2078.   struct rx_se_list * a = (struct rx_se_list *)va;
  2079.   struct rx_se_list * b = (struct rx_se_list *)vb;
  2080.  
  2081.   return ((va == vb)
  2082.       ? 0
  2083.       : (!va
  2084.          ? -1
  2085.          : (!vb
  2086.         ? 1
  2087.         : ((long)a->car < (long)b->car
  2088.            ? 1
  2089.            : ((long)a->car > (long)b->car
  2090.               ? -1
  2091.               : se_list_cmp ((void *)a->cdr, (void *)b->cdr))))));
  2092. }
  2093.  
  2094.  
  2095. #ifdef __STDC__
  2096. static int 
  2097. se_list_equal (void * va, void * vb)
  2098. #else
  2099. static int 
  2100. se_list_equal (va, vb)
  2101.      void * va;
  2102.      void * vb;
  2103. #endif
  2104. {
  2105.   return !(se_list_cmp (va, vb));
  2106. }
  2107.  
  2108. static struct rx_hash_rules se_list_hash_rules =
  2109. {
  2110.   se_list_equal,
  2111.   compiler_hash_alloc,
  2112.   compiler_free_hash,
  2113.   compiler_hash_item_alloc,
  2114.   compiler_free_hash_item
  2115. };
  2116.  
  2117. static DEF_POOL(sel_pool, struct rx_se_list);
  2118.  
  2119. #ifdef __STDC__
  2120. static struct rx_se_list * 
  2121. side_effect_cons (struct rx * rx,
  2122.           void * se, struct rx_se_list * list)
  2123. #else
  2124. static struct rx_se_list * 
  2125. side_effect_cons (rx, se, list)
  2126.      struct rx * rx;
  2127.      void * se;
  2128.      struct rx_se_list * list;
  2129. #endif
  2130. {
  2131.   struct rx_se_list * l = ((struct rx_se_list *)
  2132.                chunk_malloc (&sel_pool));
  2133.   if (!l)
  2134.     return 0;
  2135.   l->car = se;
  2136.   l->cdr = list;
  2137.   return l;
  2138. }
  2139.  
  2140.  
  2141. #ifdef __STDC__
  2142. static struct rx_se_list *
  2143. hash_cons_se_prog (struct rx * rx,
  2144.            struct rx_hash * memo,
  2145.            void * car, struct rx_se_list * cdr)
  2146. #else
  2147. static struct rx_se_list *
  2148. hash_cons_se_prog (rx, memo, car, cdr)
  2149.      struct rx * rx;
  2150.      struct rx_hash * memo;
  2151.      void * car;
  2152.      struct rx_se_list * cdr;
  2153. #endif
  2154. {
  2155.   long hash = (long)car ^ (long)cdr;
  2156.   struct rx_se_list template;
  2157.  
  2158.   template.car = car;
  2159.   template.cdr = cdr;
  2160.   {
  2161.     struct rx_hash_item * it = rx_hash_store (memo, hash,
  2162.                           (void *)&template,
  2163.                           &se_list_hash_rules);
  2164.     if (!it)
  2165.       return 0;
  2166.     if (it->data == (void *)&template)
  2167.       {
  2168.     struct rx_se_list * consed = ((struct rx_se_list *)
  2169.                       chunk_malloc (&sel_pool));
  2170.     *consed = template;
  2171.     it->data = (void *)consed;
  2172.       }
  2173.     return (struct rx_se_list *)it->data;
  2174.   }
  2175. }
  2176.      
  2177.  
  2178. #ifdef __STDC__
  2179. static struct rx_se_list *
  2180. hash_se_prog (struct rx * rx, struct rx_hash * memo, struct rx_se_list * prog)
  2181. #else
  2182. static struct rx_se_list *
  2183. hash_se_prog (rx, memo, prog)
  2184.      struct rx * rx;
  2185.      struct rx_hash * memo;
  2186.      struct rx_se_list * prog;
  2187. #endif
  2188. {
  2189.   struct rx_se_list * answer = 0;
  2190.   while (prog)
  2191.     {
  2192.       answer = hash_cons_se_prog (rx, memo, prog->car, answer);
  2193.       if (!answer)
  2194.     return 0;
  2195.       prog = prog->cdr;
  2196.     }
  2197.   return answer;
  2198. }
  2199.  
  2200.  
  2201. /* This page: more data structures for nfa->supernfa.  Specificly,
  2202.  * sets of nfa states.
  2203.  */
  2204.  
  2205. #ifdef __STDC__
  2206. static int 
  2207. nfa_set_cmp (void * va, void * vb)
  2208. #else
  2209. static int 
  2210. nfa_set_cmp (va, vb)
  2211.      void * va;
  2212.      void * vb;
  2213. #endif
  2214. {
  2215.   struct rx_nfa_state_set * a = (struct rx_nfa_state_set *)va;
  2216.   struct rx_nfa_state_set * b = (struct rx_nfa_state_set *)vb;
  2217.  
  2218.   return ((va == vb)
  2219.       ? 0
  2220.       : (!va
  2221.          ? -1
  2222.          : (!vb
  2223.         ? 1
  2224.         : (a->car->id < b->car->id
  2225.            ? 1
  2226.            : (a->car->id > b->car->id
  2227.               ? -1
  2228.               : nfa_set_cmp ((void *)a->cdr, (void *)b->cdr))))));
  2229. }
  2230.  
  2231. #ifdef __STDC__
  2232. static int 
  2233. nfa_set_equal (void * va, void * vb)
  2234. #else
  2235. static int 
  2236. nfa_set_equal (va, vb)
  2237.      void * va;
  2238.      void * vb;
  2239. #endif
  2240. {
  2241.   return !nfa_set_cmp (va, vb);
  2242. }
  2243.  
  2244. static struct rx_hash_rules nfa_set_hash_rules =
  2245. {
  2246.   nfa_set_equal,
  2247.   compiler_hash_alloc,
  2248.   compiler_free_hash,
  2249.   compiler_hash_item_alloc,
  2250.   compiler_free_hash_item
  2251. };
  2252.  
  2253.  
  2254. /* CONS -- again, sets with == elements are ==. */
  2255.  
  2256. static DEF_POOL(nfa_sets, struct rx_nfa_state_set);
  2257.  
  2258. #ifdef __STDC__
  2259. static struct rx_nfa_state_set * 
  2260. nfa_set_cons (struct rx * rx,
  2261.           struct rx_hash * memo, struct rx_nfa_state * state,
  2262.           struct rx_nfa_state_set * set)
  2263. #else
  2264. static struct rx_nfa_state_set * 
  2265. nfa_set_cons (rx, memo, state, set)
  2266.      struct rx * rx;
  2267.      struct rx_hash * memo;
  2268.      struct rx_nfa_state * state;
  2269.      struct rx_nfa_state_set * set;
  2270. #endif
  2271. {
  2272.   struct rx_nfa_state_set template;
  2273.   struct rx_hash_item * node;
  2274.   template.car = state;
  2275.   template.cdr = set;
  2276.   node = rx_hash_store (memo,
  2277.             (((long)state) >> 8) ^ (long)set,
  2278.             &template, &nfa_set_hash_rules);
  2279.   if (!node)
  2280.     return 0;
  2281.   if (node->data == &template)
  2282.     {
  2283.       struct rx_nfa_state_set * l = ((struct rx_nfa_state_set *)
  2284.                   chunk_malloc (&nfa_sets));
  2285.       node->data = (void *) l;
  2286.       if (!l)
  2287.     return 0;
  2288.       *l = template;
  2289.     }
  2290.   return (struct rx_nfa_state_set *)node->data;
  2291. }
  2292.  
  2293.  
  2294. #ifdef __STDC__
  2295. static struct rx_nfa_state_set * 
  2296. nfa_set_enjoin (struct rx * rx,
  2297.         struct rx_hash * memo, struct rx_nfa_state * state,
  2298.         struct rx_nfa_state_set * set)
  2299. #else
  2300. static struct rx_nfa_state_set * 
  2301. nfa_set_enjoin (rx, memo, state, set)
  2302.      struct rx * rx;
  2303.      struct rx_hash * memo;
  2304.      struct rx_nfa_state * state;
  2305.      struct rx_nfa_state_set * set;
  2306. #endif
  2307. {
  2308.   if (!set || state->id < set->car->id)
  2309.     return nfa_set_cons (rx, memo, state, set);
  2310.   if (state->id == set->car->id)
  2311.     return set;
  2312.   else
  2313.     {
  2314.       struct rx_nfa_state_set * newcdr
  2315.     = nfa_set_enjoin (rx, memo, state, set->cdr);
  2316.       if (newcdr != set->cdr)
  2317.     set = nfa_set_cons (rx, memo, set->car, newcdr);
  2318.       return set;
  2319.     }
  2320. }
  2321.  
  2322.  
  2323.  
  2324. /* This page: computing epsilon closures.  The closures aren't total.
  2325.  * Each node's closures are partitioned according to the side effects entailed
  2326.  * along the epsilon edges.  Return true on success.
  2327.  */ 
  2328.  
  2329. struct eclose_frame
  2330. {
  2331.   struct rx_se_list *prog_backwards;
  2332. };
  2333.  
  2334.  
  2335. #ifdef __STDC__
  2336. static int 
  2337. eclose_node (struct rx *rx, struct rx_nfa_state *outnode,
  2338.          struct rx_nfa_state *node, struct eclose_frame *frame)
  2339. #else
  2340. static int 
  2341. eclose_node (rx, outnode, node, frame)
  2342.      struct rx *rx;
  2343.      struct rx_nfa_state *outnode;
  2344.      struct rx_nfa_state *node;
  2345.      struct eclose_frame *frame;
  2346. #endif
  2347. {
  2348.   struct rx_nfa_edge *e = node->edges;
  2349.  
  2350.   /* For each node, we follow all epsilon paths to build the closure.
  2351.    * The closure omits nodes that have only epsilon edges.
  2352.    * The closure is split into partial closures -- all the states in
  2353.    * a partial closure are reached by crossing the same list of
  2354.    * of side effects (though not necessarily the same path).
  2355.    */
  2356.   if (node->mark)
  2357.     return 1;
  2358.   node->mark = 1;
  2359.  
  2360.   if (node->id >= 0 || node->is_final)
  2361.     {
  2362.       struct rx_possible_future **ec;
  2363.       struct rx_se_list * prog_in_order
  2364.     = ((struct rx_se_list *)hash_se_prog (rx,
  2365.                           &rx->se_list_memo,
  2366.                           frame->prog_backwards));
  2367.       int cmp;
  2368.  
  2369.       ec = &outnode->futures;
  2370.  
  2371.       while (*ec)
  2372.     {
  2373.       cmp = se_list_cmp ((void *)(*ec)->effects, (void *)prog_in_order);
  2374.       if (cmp <= 0)
  2375.         break;
  2376.       ec = &(*ec)->next;
  2377.     }
  2378.       if (!*ec || (cmp < 0))
  2379.     {
  2380.       struct rx_possible_future * saved = *ec;
  2381.       *ec = rx_possible_future (rx, prog_in_order);
  2382.       (*ec)->next = saved;
  2383.       if (!*ec)
  2384.         return 0;
  2385.     }
  2386.       if (node->id >= 0)
  2387.     {
  2388.       (*ec)->destset = nfa_set_enjoin (rx, &rx->set_list_memo,
  2389.                        node, (*ec)->destset);
  2390.       if (!(*ec)->destset)
  2391.         return 0;
  2392.     }
  2393.     }
  2394.  
  2395.   while (e)
  2396.     {
  2397.       switch (e->type)
  2398.     {
  2399.     case ne_epsilon:
  2400.       if (!eclose_node (rx, outnode, e->dest, frame))
  2401.         return 0;
  2402.       break;
  2403.     case ne_side_effect:
  2404.       {
  2405.         frame->prog_backwards = side_effect_cons (rx, 
  2406.                               e->params.side_effect,
  2407.                               frame->prog_backwards);
  2408.         if (!frame->prog_backwards)
  2409.           return 0;
  2410.         if (!eclose_node (rx, outnode, e->dest, frame))
  2411.           return 0;
  2412.         {
  2413.           struct rx_se_list * dying = frame->prog_backwards;
  2414.           frame->prog_backwards = frame->prog_backwards->cdr;
  2415.           chunk_free (&sel_pool, (char *)dying);
  2416.         }
  2417.         break;
  2418.       }
  2419.     default:
  2420.       break;
  2421.     }
  2422.       e = e->next;
  2423.     }
  2424.   node->mark = 0;
  2425.   return 1;
  2426. }
  2427.  
  2428.  
  2429. #ifdef __STDC__
  2430. RX_DECL int 
  2431. rx_eclose_nfa (struct rx *rx)
  2432. #else
  2433. RX_DECL int 
  2434. rx_eclose_nfa (rx)
  2435.      struct rx *rx;
  2436. #endif
  2437. {
  2438.   struct rx_nfa_state *n = rx->nfa_states;
  2439.   struct eclose_frame frame;
  2440.   static int rx_id = 0;
  2441.   
  2442.   frame.prog_backwards = 0;
  2443.   rx->rx_id = rx_id++;
  2444.   bzero (&rx->se_list_memo, sizeof (rx->se_list_memo));
  2445.   bzero (&rx->set_list_memo, sizeof (rx->set_list_memo));
  2446.   while (n)
  2447.     {
  2448.       n->futures = 0;
  2449.       if (n->eclosure_needed && !eclose_node (rx, n, n, &frame))
  2450.     return 0;
  2451.       /* clear_marks (rx); */
  2452.       n = n->next;
  2453.     }
  2454.   return 1;
  2455. }
  2456.  
  2457.  
  2458. /* This deletes epsilon edges from an NFA.  After running eclose_node,
  2459.  * we have no more need for these edges.  They are removed to simplify
  2460.  * further operations on the NFA.
  2461.  */
  2462.  
  2463. #ifdef __STDC__
  2464. RX_DECL void 
  2465. rx_delete_epsilon_transitions (struct rx *rx)
  2466. #else
  2467. RX_DECL void 
  2468. rx_delete_epsilon_transitions (rx)
  2469.      struct rx *rx;
  2470. #endif
  2471. {
  2472.   struct rx_nfa_state *n = rx->nfa_states;
  2473.   struct rx_nfa_edge **e;
  2474.  
  2475.   while (n)
  2476.     {
  2477.       e = &n->edges;
  2478.       while (*e)
  2479.     {
  2480.       struct rx_nfa_edge *t;
  2481.       switch ((*e)->type)
  2482.         {
  2483.         case ne_epsilon:
  2484.         case ne_side_effect:
  2485.           t = *e;
  2486.           *e = t->next;
  2487.           rx_free_nfa_edge (t);
  2488.           break;
  2489.  
  2490.         default:
  2491.           e = &(*e)->next;
  2492.           break;
  2493.         }
  2494.     }
  2495.       n = n->next;
  2496.     }
  2497. }
  2498.  
  2499.  
  2500. /* This page: storing the nfa in a contiguous region of memory for
  2501.  * subsequent conversion to a super-nfa.
  2502.  */
  2503.  
  2504.  
  2505. /* This is for qsort on an array of nfa_states. The order
  2506.  * is based on state ids and goes 
  2507.  *        [0...MAX][MIN..-1] where (MAX>=0) and (MIN<0)
  2508.  * This way, positive ids double as array indices.
  2509.  */
  2510.  
  2511. #ifdef __STDC__
  2512. static int 
  2513. nfacmp (void * va, void * vb)
  2514. #else
  2515. static int 
  2516. nfacmp (va, vb)
  2517.      void * va;
  2518.      void * vb;
  2519. #endif
  2520. {
  2521.   struct rx_nfa_state **a = (struct rx_nfa_state **)va;
  2522.   struct rx_nfa_state **b = (struct rx_nfa_state **)vb;
  2523.   return (*a == *b        /* &&&& 3.18 */
  2524.       ? 0
  2525.       : (((*a)->id < 0) == ((*b)->id < 0)
  2526.          ? (((*a)->id  < (*b)->id) ? -1 : 1)
  2527.          : (((*a)->id < 0)
  2528.         ? 1 : -1)));
  2529. }
  2530.  
  2531. #ifdef __STDC__
  2532. static int 
  2533. count_hash_nodes (struct rx_hash * st)
  2534. #else
  2535. static int 
  2536. count_hash_nodes (st)
  2537.      struct rx_hash * st;
  2538. #endif
  2539. {
  2540.   int x;
  2541.   int count = 0;
  2542.   for (x = 0; x < 13; ++x)
  2543.     count += ((st->children[x])
  2544.           ? count_hash_nodes (st->children[x])
  2545.           : st->bucket_size[x]);
  2546.   
  2547.   return count;
  2548. }
  2549.  
  2550.  
  2551. #ifdef __STDC__
  2552. static void 
  2553. se_memo_freer (struct rx_hash_item * node)
  2554. #else
  2555. static void 
  2556. se_memo_freer (node)
  2557.      struct rx_hash_item * node;
  2558. #endif
  2559. {
  2560.   chunk_free (&sel_pool, (char *)node->data);
  2561. }
  2562.  
  2563.  
  2564. #ifdef __STDC__
  2565. static void 
  2566. nfa_set_freer (struct rx_hash_item * node)
  2567. #else
  2568. static void 
  2569. nfa_set_freer (node)
  2570.      struct rx_hash_item * node;
  2571. #endif
  2572. {
  2573.   chunk_free (&nfa_sets, (char *)node->data);
  2574. }
  2575.  
  2576.  
  2577. /* This copies an entire NFA into a single malloced block of memory.
  2578.  * Mostly this is for compatability with regex.c, though it is convenient
  2579.  * to have the nfa nodes in an array.
  2580.  */
  2581.  
  2582. #ifdef __STDC__
  2583. RX_DECL int 
  2584. rx_compactify_nfa (struct rx *rx,
  2585.            void **mem, unsigned long *size)
  2586. #else
  2587. RX_DECL int 
  2588. rx_compactify_nfa (rx, mem, size)
  2589.      struct rx *rx;
  2590.      void **mem;
  2591.      unsigned long *size;
  2592. #endif
  2593. {
  2594.   int total_nodec;
  2595.   struct rx_nfa_state *n;
  2596.   int edgec = 0;
  2597.   int eclosec = 0;
  2598.   int se_list_consc = count_hash_nodes (&rx->se_list_memo);
  2599.   int nfa_setc = count_hash_nodes (&rx->set_list_memo);
  2600.   unsigned long total_size;
  2601.  
  2602.   /* This takes place in two stages.   First, the total size of the
  2603.    * nfa is computed, then structures are copied.  
  2604.    */   
  2605.   n = rx->nfa_states;
  2606.   total_nodec = 0;
  2607.   while (n)
  2608.     {
  2609.       struct rx_nfa_edge *e = n->edges;
  2610.       struct rx_possible_future *ec = n->futures;
  2611.       ++total_nodec;
  2612.       while (e)
  2613.     {
  2614.       ++edgec;
  2615.       e = e->next;
  2616.     }
  2617.       while (ec)
  2618.     {
  2619.       ++eclosec;
  2620.       ec = ec->next;
  2621.     }
  2622.       n = n->next;
  2623.     }
  2624.  
  2625.   total_size = (total_nodec * sizeof (struct rx_nfa_state)
  2626.         + edgec * rx_sizeof_bitset (rx->local_cset_size)
  2627.         + edgec * sizeof (struct rx_nfa_edge)
  2628.         + nfa_setc * sizeof (struct rx_nfa_state_set)
  2629.         + eclosec * sizeof (struct rx_possible_future)
  2630.         + se_list_consc * sizeof (struct rx_se_list)
  2631.         + rx->reserved);
  2632.  
  2633.   if (total_size > *size)
  2634.     {
  2635.       *mem = remalloc (*mem, total_size);
  2636.       if (*mem)
  2637.     *size = total_size;
  2638.       else
  2639.     return 0;
  2640.     }
  2641.   /* Now we've allocated the memory; this copies the NFA. */
  2642.   {
  2643.     static struct rx_nfa_state **scratch = 0;
  2644.     static int scratch_alloc = 0;
  2645.     struct rx_nfa_state *state_base = (struct rx_nfa_state *) * mem;
  2646.     struct rx_nfa_state *new_state = state_base;
  2647.     struct rx_nfa_edge *new_edge =
  2648.       (struct rx_nfa_edge *)
  2649.     ((char *) state_base + total_nodec * sizeof (struct rx_nfa_state));
  2650.     struct rx_se_list * new_se_list =
  2651.       (struct rx_se_list *)
  2652.     ((char *)new_edge + edgec * sizeof (struct rx_nfa_edge));
  2653.     struct rx_possible_future *new_close =
  2654.       ((struct rx_possible_future *)
  2655.        ((char *) new_se_list
  2656.     + se_list_consc * sizeof (struct rx_se_list)));
  2657.     struct rx_nfa_state_set * new_nfa_set =
  2658.       ((struct rx_nfa_state_set *)
  2659.        ((char *)new_close + eclosec * sizeof (struct rx_possible_future)));
  2660.     char *new_bitset =
  2661.       ((char *) new_nfa_set + nfa_setc * sizeof (struct rx_nfa_state_set));
  2662.     int x;
  2663.     struct rx_nfa_state *n;
  2664.  
  2665.     if (scratch_alloc < total_nodec)
  2666.       {
  2667.     scratch = ((struct rx_nfa_state **)
  2668.            remalloc (scratch, total_nodec * sizeof (*scratch)));
  2669.     if (scratch)
  2670.       scratch_alloc = total_nodec;
  2671.     else
  2672.       {
  2673.         scratch_alloc = 0;
  2674.         return 0;
  2675.       }
  2676.       }
  2677.  
  2678.     for (x = 0, n = rx->nfa_states; n; n = n->next)
  2679.       scratch[x++] = n;
  2680.  
  2681.     qsort (scratch, total_nodec,
  2682.        sizeof (struct rx_nfa_state *), (int (*)())nfacmp);
  2683.  
  2684.     for (x = 0; x < total_nodec; ++x)
  2685.       {
  2686.     struct rx_possible_future *eclose = scratch[x]->futures;
  2687.     struct rx_nfa_edge *edge = scratch[x]->edges;
  2688.     struct rx_nfa_state *cn = new_state++;
  2689.     cn->futures = 0;
  2690.     cn->edges = 0;
  2691.     cn->next = (x == total_nodec - 1) ? 0 : (cn + 1);
  2692.     cn->id = scratch[x]->id;
  2693.     cn->is_final = scratch[x]->is_final;
  2694.     cn->is_start = scratch[x]->is_start;
  2695.     cn->mark = 0;
  2696.     while (edge)
  2697.       {
  2698.         int indx = (edge->dest->id < 0
  2699.              ? (total_nodec + edge->dest->id)
  2700.              : edge->dest->id);
  2701.         struct rx_nfa_edge *e = new_edge++;
  2702.         rx_Bitset cset = (rx_Bitset) new_bitset;
  2703.         new_bitset += rx_sizeof_bitset (rx->local_cset_size);
  2704.         rx_bitset_null (rx->local_cset_size, cset);
  2705.         rx_bitset_union (rx->local_cset_size, cset, edge->params.cset);
  2706.         e->next = cn->edges;
  2707.         cn->edges = e;
  2708.         e->type = edge->type;
  2709.         e->dest = state_base + indx;
  2710.         e->params.cset = cset;
  2711.         edge = edge->next;
  2712.       }
  2713.     while (eclose)
  2714.       {
  2715.         struct rx_possible_future *ec = new_close++;
  2716.         struct rx_hash_item * sp;
  2717.         struct rx_se_list ** sepos;
  2718.         struct rx_se_list * sesrc;
  2719.         struct rx_nfa_state_set * destlst;
  2720.         struct rx_nfa_state_set ** destpos;
  2721.         ec->next = cn->futures;
  2722.         cn->futures = ec;
  2723.         for (sepos = &ec->effects, sesrc = eclose->effects;
  2724.          sesrc;
  2725.          sesrc = sesrc->cdr, sepos = &(*sepos)->cdr)
  2726.           {
  2727.         sp = rx_hash_find (&rx->se_list_memo,
  2728.                    (long)sesrc->car ^ (long)sesrc->cdr,
  2729.                    sesrc, &se_list_hash_rules);
  2730.         if (sp->binding)
  2731.           {
  2732.             sesrc = (struct rx_se_list *)sp->binding;
  2733.             break;
  2734.           }
  2735.         *new_se_list = *sesrc;
  2736.         sp->binding = (void *)new_se_list;
  2737.         *sepos = new_se_list;
  2738.         ++new_se_list;
  2739.           }
  2740.         *sepos = sesrc;
  2741.         for (destpos = &ec->destset, destlst = eclose->destset;
  2742.          destlst;
  2743.          destpos = &(*destpos)->cdr, destlst = destlst->cdr)
  2744.           {
  2745.         sp = rx_hash_find (&rx->set_list_memo,
  2746.                    ((((long)destlst->car) >> 8)
  2747.                     ^ (long)destlst->cdr),
  2748.                    destlst, &nfa_set_hash_rules);
  2749.         if (sp->binding)
  2750.           {
  2751.             destlst = (struct rx_nfa_state_set *)sp->binding;
  2752.             break;
  2753.           }
  2754.         *new_nfa_set = *destlst;
  2755.         new_nfa_set->car = state_base + destlst->car->id;
  2756.         sp->binding = (void *)new_nfa_set;
  2757.         *destpos = new_nfa_set;
  2758.         ++new_nfa_set;
  2759.           }
  2760.         *destpos = destlst;
  2761.         eclose = eclose->next;
  2762.       }
  2763.       }
  2764.   }
  2765.   rx_free_hash_table (&rx->se_list_memo, se_memo_freer, &se_list_hash_rules);
  2766.   bzero (&rx->se_list_memo, sizeof (rx->se_list_memo));
  2767.   rx_free_hash_table (&rx->set_list_memo, nfa_set_freer, &nfa_set_hash_rules);
  2768.   bzero (&rx->set_list_memo, sizeof (rx->set_list_memo));
  2769.  
  2770.   rx_free_nfa (rx);
  2771.   rx->nfa_states = (struct rx_nfa_state *)*mem;
  2772.   return 1;
  2773. }
  2774.  
  2775.  
  2776. /* The functions in the next several pages define the lazy-NFA-conversion used
  2777.  * by matchers.  The input to this construction is an NFA such as 
  2778.  * is built by compactify_nfa (rx.c).  The output is the superNFA.
  2779.  */
  2780.  
  2781.  
  2782. /* Match engines can use arbitrary values for opcodes.  So, the parse tree 
  2783.  * is built using instructions names (enum rx_opcode), but the superstate
  2784.  * nfa is populated with mystery opcodes (void *).
  2785.  *
  2786.  * For convenience, here is an id table.  The opcodes are == to their inxs
  2787.  *
  2788.  * The lables in re_search_2 would make good values for instructions.
  2789.  */
  2790.  
  2791. void * rx_id_instruction_table[rx_num_instructions] =
  2792. {
  2793.   (void *) rx_backtrack_point,
  2794.   (void *) rx_do_side_effects,
  2795.   (void *) rx_cache_miss,
  2796.   (void *) rx_next_char,
  2797.   (void *) rx_backtrack,
  2798.   (void *) rx_error_inx
  2799. };
  2800.  
  2801.  
  2802.  
  2803. /* Memory mgt. for superstate graphs. */
  2804.  
  2805. #ifdef __STDC__
  2806. static char *
  2807. rx_cache_malloc (struct rx_cache * cache, int bytes)
  2808. #else
  2809. static char *
  2810. rx_cache_malloc (cache, bytes)
  2811.      struct rx_cache * cache;
  2812.      int bytes;
  2813. #endif
  2814. {
  2815.   while (cache->bytes_left < bytes)
  2816.     {
  2817.       if (cache->memory_pos)
  2818.     cache->memory_pos = cache->memory_pos->next;
  2819.       if (!cache->memory_pos)
  2820.     {
  2821.       cache->morecore (cache);
  2822.       if (!cache->memory_pos)
  2823.         return 0;
  2824.     }
  2825.       cache->bytes_left = cache->memory_pos->bytes;
  2826.       cache->memory_addr = ((char *)cache->memory_pos
  2827.                 + sizeof (struct rx_blocklist));
  2828.     }
  2829.   cache->bytes_left -= bytes;
  2830.   {
  2831.     char * addr = cache->memory_addr;
  2832.     cache->memory_addr += bytes;
  2833.     return addr;
  2834.   }
  2835. }
  2836.  
  2837. #ifdef __STDC__
  2838. static void
  2839. rx_cache_free (struct rx_cache * cache,
  2840.            struct rx_freelist ** freelist, char * mem)
  2841. #else
  2842. static void
  2843. rx_cache_free (cache, freelist, mem)
  2844.      struct rx_cache * cache;
  2845.      struct rx_freelist ** freelist;
  2846.      char * mem;
  2847. #endif
  2848. {
  2849.   struct rx_freelist * it = (struct rx_freelist *)mem;
  2850.   it->next = *freelist;
  2851.   *freelist = it;
  2852. }
  2853.  
  2854.  
  2855. /* The partially instantiated superstate graph has a transition 
  2856.  * table at every node.  There is one entry for every character.
  2857.  * This fills in the transition for a set.
  2858.  */
  2859. #ifdef __STDC__
  2860. static void 
  2861. install_transition (struct rx_superstate *super,
  2862.             struct rx_inx *answer, rx_Bitset trcset) 
  2863. #else
  2864. static void 
  2865. install_transition (super, answer, trcset)
  2866.      struct rx_superstate *super;
  2867.      struct rx_inx *answer;
  2868.      rx_Bitset trcset;
  2869. #endif
  2870. {
  2871.   struct rx_inx * transitions = super->transitions;
  2872.   int chr;
  2873.   for (chr = 0; chr < 256; )
  2874.     if (!*trcset)
  2875.       {
  2876.     ++trcset;
  2877.     chr += 32;
  2878.       }
  2879.     else
  2880.       {
  2881.     RX_subset sub = *trcset;
  2882.     RX_subset mask = 1;
  2883.     int bound = chr + 32;
  2884.     while (chr < bound)
  2885.       {
  2886.         if (sub & mask)
  2887.           transitions [chr] = *answer;
  2888.         ++chr;
  2889.         mask <<= 1;
  2890.       }
  2891.     ++trcset;
  2892.       }
  2893. }
  2894.  
  2895.  
  2896. #if 1
  2897. static int
  2898. qlen (q)
  2899.      struct rx_superstate * q;
  2900. {
  2901.   int count = 1;
  2902.   struct rx_superstate * it;
  2903.   if (!q)
  2904.     return 0;
  2905.   for (it = q->next_recyclable; it != q; it = it->next_recyclable)
  2906.     ++count;
  2907.   return count;
  2908. }
  2909.  
  2910. static void
  2911. check_cache (cache)
  2912.      struct rx_cache * cache;
  2913. {
  2914.   struct rx_cache * you_fucked_up = 0;
  2915.   int total = cache->superstates;
  2916.   int semi = cache->semifree_superstates;
  2917.   if (semi != qlen (cache->semifree_superstate))
  2918.     check_cache (you_fucked_up);
  2919.   if ((total - semi) != qlen (cache->lru_superstate))
  2920.     check_cache (you_fucked_up);
  2921. }
  2922. #endif
  2923.  
  2924. #ifdef __STDC__
  2925. static void
  2926. semifree_superstate (struct rx_cache * cache)
  2927. #else
  2928. static void
  2929. semifree_superstate (cache)
  2930.      struct rx_cache * cache;
  2931. #endif
  2932. {
  2933.   int disqualified = cache->semifree_superstates;
  2934.   if (disqualified == cache->superstates)
  2935.     return;
  2936.   while (cache->lru_superstate->locks)
  2937.     {
  2938.       cache->lru_superstate = cache->lru_superstate->next_recyclable;
  2939.       ++disqualified;
  2940.       if (disqualified == cache->superstates)
  2941.     return;
  2942.     }
  2943.   {
  2944.     struct rx_superstate * it = cache->lru_superstate;
  2945.     it->next_recyclable->prev_recyclable = it->prev_recyclable;
  2946.     it->prev_recyclable->next_recyclable = it->next_recyclable;
  2947.     cache->lru_superstate = (it == it->next_recyclable
  2948.                  ? 0
  2949.                  : it->next_recyclable);
  2950.     if (!cache->semifree_superstate)
  2951.       {
  2952.     cache->semifree_superstate = it;
  2953.     it->next_recyclable = it;
  2954.     it->prev_recyclable = it;
  2955.       }
  2956.     else
  2957.       {
  2958.     it->prev_recyclable = cache->semifree_superstate->prev_recyclable;
  2959.     it->next_recyclable = cache->semifree_superstate;
  2960.     it->prev_recyclable->next_recyclable = it;
  2961.     it->next_recyclable->prev_recyclable = it;
  2962.       }
  2963.     {
  2964.       struct rx_distinct_future *df;
  2965.       it->is_semifree = 1;
  2966.       ++cache->semifree_superstates;
  2967.       df = it->transition_refs;
  2968.       if (df)
  2969.     {
  2970.       df->prev_same_dest->next_same_dest = 0;
  2971.       for (df = it->transition_refs; df; df = df->next_same_dest)
  2972.         {
  2973.           df->future_frame.inx = cache->instruction_table[rx_cache_miss];
  2974.           df->future_frame.data = 0;
  2975.           df->future_frame.data_2 = (void *) df;
  2976.           /* If there are any NEXT-CHAR instruction frames that
  2977.            * refer to this state, we convert them to CACHE-MISS frames.
  2978.            */
  2979.           if (!df->effects
  2980.           && (df->edge->options->next_same_super_edge[0]
  2981.               == df->edge->options))
  2982.         install_transition (df->present, &df->future_frame,
  2983.                     df->edge->cset);
  2984.         }
  2985.       df = it->transition_refs;
  2986.       df->prev_same_dest->next_same_dest = df;
  2987.     }
  2988.     }
  2989.   }
  2990. }
  2991.  
  2992.  
  2993. #ifdef __STDC__
  2994. static void 
  2995. refresh_semifree_superstate (struct rx_cache * cache,
  2996.                  struct rx_superstate * super)
  2997. #else
  2998. static void 
  2999. refresh_semifree_superstate (cache, super)
  3000.      struct rx_cache * cache;
  3001.      struct rx_superstate * super;
  3002. #endif
  3003. {
  3004.   struct rx_distinct_future *df;
  3005.  
  3006.   if (super->transition_refs)
  3007.     {
  3008.       super->transition_refs->prev_same_dest->next_same_dest = 0; 
  3009.       for (df = super->transition_refs; df; df = df->next_same_dest)
  3010.     {
  3011.       df->future_frame.inx = cache->instruction_table[rx_next_char];
  3012.       df->future_frame.data = (void *) super->transitions;
  3013.       /* CACHE-MISS instruction frames that refer to this state,
  3014.        * must be converted to NEXT-CHAR frames.
  3015.        */
  3016.       if (!df->effects
  3017.           && (df->edge->options->next_same_super_edge[0]
  3018.           == df->edge->options))
  3019.         install_transition (df->present, &df->future_frame,
  3020.                 df->edge->cset);
  3021.     }
  3022.       super->transition_refs->prev_same_dest->next_same_dest
  3023.     = super->transition_refs;
  3024.     }
  3025.   if (cache->semifree_superstate == super)
  3026.     cache->semifree_superstate = (super->prev_recyclable == super
  3027.                   ? 0
  3028.                   : super->prev_recyclable);
  3029.   super->next_recyclable->prev_recyclable = super->prev_recyclable;
  3030.   super->prev_recyclable->next_recyclable = super->next_recyclable;
  3031.  
  3032.   if (!cache->lru_superstate)
  3033.     (cache->lru_superstate
  3034.      = super->next_recyclable
  3035.      = super->prev_recyclable
  3036.      = super);
  3037.   else
  3038.     {
  3039.       super->next_recyclable = cache->lru_superstate;
  3040.       super->prev_recyclable = cache->lru_superstate->prev_recyclable;
  3041.       super->next_recyclable->prev_recyclable = super;
  3042.       super->prev_recyclable->next_recyclable = super;
  3043.     }
  3044.   super->is_semifree = 0;
  3045.   --cache->semifree_superstates;
  3046. }
  3047.  
  3048. #ifdef __STDC__
  3049. static void
  3050. rx_refresh_this_superstate (struct rx_cache * cache, struct rx_superstate * superstate)
  3051. #else
  3052. static void
  3053. rx_refresh_this_superstate (cache, superstate)
  3054.      struct rx_cache * cache;
  3055.      struct rx_superstate * superstate;
  3056. #endif
  3057. {
  3058.   if (superstate->is_semifree)
  3059.     refresh_semifree_superstate (cache, superstate);
  3060.   else if (cache->lru_superstate == superstate)
  3061.     cache->lru_superstate = superstate->next_recyclable;
  3062.   else if (superstate != cache->lru_superstate->prev_recyclable)
  3063.     {
  3064.       superstate->next_recyclable->prev_recyclable
  3065.     = superstate->prev_recyclable;
  3066.       superstate->prev_recyclable->next_recyclable
  3067.     = superstate->next_recyclable;
  3068.       superstate->next_recyclable = cache->lru_superstate;
  3069.       superstate->prev_recyclable = cache->lru_superstate->prev_recyclable;
  3070.       superstate->next_recyclable->prev_recyclable = superstate;
  3071.       superstate->prev_recyclable->next_recyclable = superstate;
  3072.     }
  3073. }
  3074.  
  3075. #ifdef __STDC__
  3076. static void 
  3077. release_superset_low (struct rx_cache * cache,
  3078.              struct rx_superset *set)
  3079. #else
  3080. static void 
  3081. release_superset_low (cache, set)
  3082.      struct rx_cache * cache;
  3083.      struct rx_superset *set;
  3084. #endif
  3085. {
  3086.   if (!--set->refs)
  3087.     {
  3088.       if (set->cdr)
  3089.     release_superset_low (cache, set->cdr);
  3090.  
  3091.       set->starts_for = 0;
  3092.  
  3093.       rx_hash_free
  3094.     (rx_hash_find
  3095.      (&cache->superset_table,
  3096.       (unsigned long)set->car ^ set->id ^ (unsigned long)set->cdr,
  3097.       (void *)set,
  3098.       &cache->superset_hash_rules),
  3099.      &cache->superset_hash_rules);
  3100.       rx_cache_free (cache, &cache->free_supersets, (char *)set);
  3101.     }
  3102. }
  3103.  
  3104. /* This tries to add a new superstate to the superstate freelist.
  3105.  * It might, as a result, free some edge pieces or hash tables.
  3106.  * If nothing can be freed because too many locks are being held, fail.
  3107.  */
  3108.  
  3109. #ifdef __STDC__
  3110. static int
  3111. rx_really_free_superstate (struct rx_cache * cache)
  3112. #else
  3113. static int
  3114. rx_really_free_superstate (cache)
  3115.      struct rx_cache * cache;
  3116. #endif
  3117. {
  3118.   int locked_superstates = 0;
  3119.   struct rx_superstate * it;
  3120.  
  3121.   if (!cache->superstates)
  3122.     return 0;
  3123.  
  3124.   {
  3125.     /* This is a total guess.  The idea is that we should expect as
  3126.      * many misses as we've recently experienced.  I.e., cache->misses
  3127.      * should be the same as cache->semifree_superstates.
  3128.      */
  3129.     while ((cache->hits + cache->misses) > cache->superstates_allowed)
  3130.       {
  3131.     cache->hits >>= 1;
  3132.     cache->misses >>= 1;
  3133.       }
  3134.     if (  ((cache->hits + cache->misses) * cache->semifree_superstates)
  3135.     < (cache->superstates         * cache->misses))
  3136.       {
  3137.     semifree_superstate (cache);
  3138.     semifree_superstate (cache);
  3139.       }
  3140.   }
  3141.  
  3142.   while (cache->semifree_superstate && cache->semifree_superstate->locks)
  3143.     {
  3144.       refresh_semifree_superstate (cache, cache->semifree_superstate);
  3145.       ++locked_superstates;
  3146.       if (locked_superstates == cache->superstates)
  3147.     return 0;
  3148.     }
  3149.  
  3150.   if (cache->semifree_superstate)
  3151.     {
  3152.       it = cache->semifree_superstate;
  3153.       it->next_recyclable->prev_recyclable = it->prev_recyclable;
  3154.       it->prev_recyclable->next_recyclable = it->next_recyclable;
  3155.       cache->semifree_superstate = ((it == it->next_recyclable)
  3156.                     ? 0
  3157.                     : it->next_recyclable);
  3158.       --cache->semifree_superstates;
  3159.     }
  3160.   else
  3161.     {
  3162.       while (cache->lru_superstate->locks)
  3163.     {
  3164.       cache->lru_superstate = cache->lru_superstate->next_recyclable;
  3165.       ++locked_superstates;
  3166.       if (locked_superstates == cache->superstates)
  3167.         return 0;
  3168.     }
  3169.       it = cache->lru_superstate;
  3170.       it->next_recyclable->prev_recyclable = it->prev_recyclable;
  3171.       it->prev_recyclable->next_recyclable = it->next_recyclable;
  3172.       cache->lru_superstate = ((it == it->next_recyclable)
  3173.                     ? 0
  3174.                     : it->next_recyclable);
  3175.     }
  3176.  
  3177.   if (it->transition_refs)
  3178.     {
  3179.       struct rx_distinct_future *df;
  3180.       for (df = it->transition_refs,
  3181.        df->prev_same_dest->next_same_dest = 0;
  3182.        df;
  3183.        df = df->next_same_dest)
  3184.     {
  3185.       df->future_frame.inx = cache->instruction_table[rx_cache_miss];
  3186.       df->future_frame.data = 0;
  3187.       df->future_frame.data_2 = (void *) df;
  3188.       df->future = 0;
  3189.     }
  3190.       it->transition_refs->prev_same_dest->next_same_dest =
  3191.     it->transition_refs;
  3192.     }
  3193.   {
  3194.     struct rx_super_edge *tc = it->edges;
  3195.     while (tc)
  3196.       {
  3197.     struct rx_distinct_future * df;
  3198.     struct rx_super_edge *tct = tc->next;
  3199.     df = tc->options;
  3200.     df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
  3201.     while (df)
  3202.       {
  3203.         struct rx_distinct_future *dft = df;
  3204.         df = df->next_same_super_edge[0];
  3205.         
  3206.         
  3207.         if (dft->future && dft->future->transition_refs == dft)
  3208.           {
  3209.         dft->future->transition_refs = dft->next_same_dest;
  3210.         if (dft->future->transition_refs == dft)
  3211.           dft->future->transition_refs = 0;
  3212.           }
  3213.         dft->next_same_dest->prev_same_dest = dft->prev_same_dest;
  3214.         dft->prev_same_dest->next_same_dest = dft->next_same_dest;
  3215.         rx_cache_free (cache, &cache->free_discernable_futures,
  3216.                (char *)dft);
  3217.       }
  3218.     rx_cache_free (cache, &cache->free_transition_classes, (char *)tc);
  3219.     tc = tct;
  3220.       }
  3221.   }
  3222.   
  3223.   if (it->contents->superstate == it)
  3224.     it->contents->superstate = 0;
  3225.   release_superset_low (cache, it->contents);
  3226.   rx_cache_free (cache, &cache->free_superstates, (char *)it);
  3227.   --cache->superstates;
  3228.   return 1;
  3229. }
  3230.  
  3231. #ifdef __STDC__
  3232. static char *
  3233. rx_cache_get (struct rx_cache * cache,
  3234.           struct rx_freelist ** freelist)
  3235. #else
  3236. static char *
  3237. rx_cache_get (cache, freelist)
  3238.      struct rx_cache * cache;
  3239.      struct rx_freelist ** freelist;
  3240. #endif
  3241. {
  3242.   while (!*freelist && rx_really_free_superstate (cache))
  3243.     ;
  3244.   if (!*freelist)
  3245.     return 0;
  3246.   {
  3247.     struct rx_freelist * it = *freelist;
  3248.     *freelist = it->next;
  3249.     return (char *)it;
  3250.   }
  3251. }
  3252.  
  3253. #ifdef __STDC__
  3254. static char *
  3255. rx_cache_malloc_or_get (struct rx_cache * cache,
  3256.             struct rx_freelist ** freelist, int bytes)
  3257. #else
  3258. static char *
  3259. rx_cache_malloc_or_get (cache, freelist, bytes)
  3260.      struct rx_cache * cache;
  3261.      struct rx_freelist ** freelist;
  3262.      int bytes;
  3263. #endif
  3264. {
  3265.   if (!*freelist)
  3266.     {
  3267.       char * answer = rx_cache_malloc (cache, bytes);
  3268.       if (answer)
  3269.     return answer;
  3270.     }
  3271.  
  3272.   return rx_cache_get (cache, freelist);
  3273. }
  3274.  
  3275. #ifdef __STDC__
  3276. static char *
  3277. rx_cache_get_superstate (struct rx_cache * cache)
  3278. #else
  3279. static char *
  3280. rx_cache_get_superstate (cache)
  3281.       struct rx_cache * cache;
  3282. #endif
  3283. {
  3284.   char * answer;
  3285.   int bytes = (   sizeof (struct rx_superstate)
  3286.            +  cache->local_cset_size * sizeof (struct rx_inx));
  3287.   if (!cache->free_superstates
  3288.       && (cache->superstates < cache->superstates_allowed))
  3289.     {
  3290.       answer = rx_cache_malloc (cache, bytes);
  3291.       if (answer)
  3292.     {
  3293.       ++cache->superstates;
  3294.       return answer;
  3295.     }
  3296.     }
  3297.   answer = rx_cache_get (cache, &cache->free_superstates);
  3298.   if (!answer)
  3299.     {
  3300.       answer = rx_cache_malloc (cache, bytes);
  3301.       if (answer)
  3302.     ++cache->superstates_allowed;
  3303.     }
  3304.   ++cache->superstates;
  3305.   return answer;
  3306. }
  3307.  
  3308.  
  3309.  
  3310. static int
  3311. supersetcmp (va, vb)
  3312.      void * va;
  3313.      void * vb;
  3314. {
  3315.   struct rx_superset * a = (struct rx_superset *)va;
  3316.   struct rx_superset * b = (struct rx_superset *)vb;
  3317.   return (   (a == b)
  3318.       || (a && b && (a->car == b->car) && (a->cdr == b->cdr)));
  3319. }
  3320.  
  3321.  
  3322. #ifdef __STDC__
  3323. static struct rx_hash_item *
  3324. superset_allocator (struct rx_hash_rules * rules, void * val)
  3325. #else
  3326. static struct rx_hash_item *
  3327. superset_allocator (rules, val)
  3328.      struct rx_hash_rules * rules;
  3329.      void * val;
  3330. #endif
  3331. {
  3332.   struct rx_cache * cache
  3333.     = ((struct rx_cache *)
  3334.        ((char *)rules
  3335.     - (unsigned long)(&((struct rx_cache *)0)->superset_hash_rules)));
  3336.   struct rx_superset * template = (struct rx_superset *)val;
  3337.   struct rx_superset * newset
  3338.     = ((struct rx_superset *)
  3339.        rx_cache_malloc_or_get (cache,
  3340.                    &cache->free_supersets,
  3341.                    sizeof (*template)));
  3342.   newset->refs = 0;
  3343.   newset->car = template->car;
  3344.   newset->id = template->car->id;
  3345.   newset->cdr = template->cdr;
  3346.   newset->superstate = 0;
  3347.   rx_protect_superset (rx, template->cdr);
  3348.   newset->hash_item.data = (void *)newset;
  3349.   newset->hash_item.binding = 0;
  3350.   return &newset->hash_item;
  3351. }
  3352.  
  3353. #ifdef __STDC__
  3354. static struct rx_hash * 
  3355. super_hash_allocator (struct rx_hash_rules * rules)
  3356. #else
  3357. static struct rx_hash * 
  3358. super_hash_allocator (rules)
  3359.      struct rx_hash_rules * rules;
  3360. #endif
  3361. {
  3362.   struct rx_cache * cache
  3363.     = ((struct rx_cache *)
  3364.        ((char *)rules
  3365.     - (unsigned long)(&((struct rx_cache *)0)->superset_hash_rules)));
  3366.   return ((struct rx_hash *)
  3367.       rx_cache_malloc_or_get (cache,
  3368.                   &cache->free_hash, sizeof (struct rx_hash)));
  3369. }
  3370.  
  3371.  
  3372. #ifdef __STDC__
  3373. static void
  3374. super_hash_liberator (struct rx_hash * hash, struct rx_hash_rules * rules)
  3375. #else
  3376. static void
  3377. super_hash_liberator (hash, rules)
  3378.      struct rx_hash * hash;
  3379.      struct rx_hash_rules * rules;
  3380. #endif
  3381. {
  3382.   struct rx_cache * cache
  3383.     = ((struct rx_cache *)
  3384.        (char *)rules - (long)(&((struct rx_cache *)0)->superset_hash_rules));
  3385.   rx_cache_free (cache, &cache->free_hash, (char *)hash);
  3386. }
  3387.  
  3388. #ifdef __STDC__
  3389. static void
  3390. superset_hash_item_liberator (struct rx_hash_item * it,
  3391.                   struct rx_hash_rules * rules)
  3392. #else
  3393. static void
  3394. superset_hash_item_liberator (it, rules) /* Well, it does ya know. */
  3395.      struct rx_hash_item * it;
  3396.      struct rx_hash_rules * rules;
  3397. #endif
  3398. {
  3399. }
  3400.  
  3401. int rx_cache_bound = 128;
  3402. static int rx_default_cache_got = 0;
  3403.  
  3404. #ifdef __STDC__
  3405. static int
  3406. bytes_for_cache_size (int supers, int cset_size)
  3407. #else
  3408. static int
  3409. bytes_for_cache_size (supers, cset_size)
  3410.      int supers;
  3411.      int cset_size;
  3412. #endif
  3413. {
  3414.   return (int)
  3415.     ((float)supers *
  3416.      (  (1.03 * (float) (  rx_sizeof_bitset (cset_size)
  3417.              + sizeof (struct rx_super_edge)))
  3418.       + (1.80 * (float) sizeof (struct rx_possible_future))
  3419.       + (float) (  sizeof (struct rx_superstate)
  3420.          + cset_size * sizeof (struct rx_inx))));
  3421. }
  3422.  
  3423. #ifdef __STDC__
  3424. static void
  3425. rx_morecore (struct rx_cache * cache)
  3426. #else
  3427. static void
  3428. rx_morecore (cache)
  3429.      struct rx_cache * cache;
  3430. #endif
  3431. {
  3432.   if (rx_default_cache_got >= rx_cache_bound)
  3433.     return;
  3434.  
  3435.   rx_default_cache_got += 16;
  3436.   cache->superstates_allowed = rx_cache_bound;
  3437.   {
  3438.     struct rx_blocklist ** pos = &cache->memory;
  3439.     int size = bytes_for_cache_size (16, cache->local_cset_size);
  3440.     while (*pos)
  3441.       pos = &(*pos)->next;
  3442.     *pos = ((struct rx_blocklist *)
  3443.         malloc (size + sizeof (struct rx_blocklist))); 
  3444.     if (!*pos)
  3445.       return;
  3446.  
  3447.     (*pos)->next = 0;
  3448.     (*pos)->bytes = size;
  3449.     cache->memory_pos = *pos;
  3450.     cache->memory_addr = (char *)*pos + sizeof (**pos);
  3451.     cache->bytes_left = size;
  3452.   }
  3453. }
  3454.  
  3455. static struct rx_cache default_cache = 
  3456. {
  3457.   {
  3458.     supersetcmp,
  3459.     super_hash_allocator,
  3460.     super_hash_liberator,
  3461.     superset_allocator,
  3462.     superset_hash_item_liberator,
  3463.   },
  3464.   0,
  3465.   0,
  3466.   0,
  3467.   0,
  3468.   rx_morecore,
  3469.  
  3470.   0,
  3471.   0,
  3472.   0,
  3473.   0,
  3474.   0,
  3475.  
  3476.   0,
  3477.   0,
  3478.  
  3479.   0,
  3480.  
  3481.   0,
  3482.   0,
  3483.   0,
  3484.   0,
  3485.   128,
  3486.  
  3487.   256,
  3488.   rx_id_instruction_table,
  3489.  
  3490.   {
  3491.     0,
  3492.     0,
  3493.     {0},
  3494.     {0},
  3495.     {0}
  3496.   }
  3497. };
  3498.  
  3499. /* This adds an element to a superstate set.  These sets are lists, such
  3500.  * that lists with == elements are ==.  The empty set is returned by
  3501.  * superset_cons (rx, 0, 0) and is NOT equivelent to 
  3502.  * (struct rx_superset)0.
  3503.  */
  3504.  
  3505. #ifdef __STDC__
  3506. RX_DECL struct rx_superset *
  3507. rx_superset_cons (struct rx * rx,
  3508.           struct rx_nfa_state *car, struct rx_superset *cdr)
  3509. #else
  3510. RX_DECL struct rx_superset *
  3511. rx_superset_cons (rx, car, cdr)
  3512.      struct rx * rx;
  3513.      struct rx_nfa_state *car;
  3514.      struct rx_superset *cdr;
  3515. #endif
  3516. {
  3517.   struct rx_cache * cache = rx->cache;
  3518.   if (!car && !cdr)
  3519.     {
  3520.       if (!cache->empty_superset)
  3521.     {
  3522.       cache->empty_superset
  3523.         = ((struct rx_superset *)
  3524.            rx_cache_malloc_or_get (cache, &cache->free_supersets,
  3525.                        sizeof (struct rx_superset)));
  3526.       if (!cache->empty_superset)
  3527.         return 0;
  3528.       bzero (cache->empty_superset, sizeof (struct rx_superset));
  3529.       cache->empty_superset->refs = 1000;
  3530.     }
  3531.       return cache->empty_superset;
  3532.     }
  3533.   {
  3534.     struct rx_superset template;
  3535.     struct rx_hash_item * hit;
  3536.     template.car = car;
  3537.     template.cdr = cdr;
  3538.     template.id = car->id;
  3539.     hit = rx_hash_store (&cache->superset_table,
  3540.              (unsigned long)car ^ car->id ^ (unsigned long)cdr,
  3541.              (void *)&template,
  3542.              &cache->superset_hash_rules);
  3543.     return (hit
  3544.         ?  (struct rx_superset *)hit->data
  3545.         : 0);
  3546.   }
  3547. }
  3548.  
  3549. /* This computes a union of two NFA state sets.  The sets do not have the
  3550.  * same representation though.  One is a RX_SUPERSET structure (part
  3551.  * of the superstate NFA) and the other is an NFA_STATE_SET (part of the NFA).
  3552.  */
  3553.  
  3554. #ifdef __STDC__
  3555. RX_DECL struct rx_superset *
  3556. rx_superstate_eclosure_union
  3557.   (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl) 
  3558. #else
  3559. RX_DECL struct rx_superset *
  3560. rx_superstate_eclosure_union (rx, set, ecl)
  3561.      struct rx * rx;
  3562.      struct rx_superset *set;
  3563.      struct rx_nfa_state_set *ecl;
  3564. #endif
  3565. {
  3566.   if (!ecl)
  3567.     return set;
  3568.   if (!set->car)
  3569.     return rx_superset_cons (rx, ecl->car,
  3570.                 rx_superstate_eclosure_union (rx, set, ecl->cdr));
  3571.   {
  3572.     if (set->car == ecl->car)
  3573.       return rx_superstate_eclosure_union (rx, set, ecl->cdr);
  3574.     if (set->car > ecl->car)
  3575.       return rx_superset_cons (rx, set->car,
  3576.                   rx_superstate_eclosure_union (rx,
  3577.                                 set->cdr, ecl));
  3578.     return rx_superset_cons (rx, ecl->car,
  3579.                 rx_superstate_eclosure_union (rx, set, ecl->cdr));
  3580.   }
  3581. }
  3582.  
  3583.  
  3584. #ifdef __STDC__
  3585. RX_DECL void 
  3586. rx_release_superset (struct rx *rx,
  3587.              struct rx_superset *set)
  3588. #else
  3589. RX_DECL void 
  3590. rx_release_superset (rx, set)
  3591.      struct rx *rx;
  3592.      struct rx_superset *set;
  3593. #endif
  3594. {
  3595.   release_superset_low (rx->cache, set);
  3596. }
  3597.  
  3598.  
  3599.  
  3600. /*
  3601.  * This makes sure that a list of rx_distinct_futures contains
  3602.  * a future for each possible set of side effects in the eclosure
  3603.  * of a given state.  This is some of the work of filling in a
  3604.  * superstate transition. 
  3605.  */
  3606.  
  3607. #ifdef __STDC__
  3608. static struct rx_distinct_future *
  3609. include_futures (struct rx *rx,
  3610.          struct rx_distinct_future *df, struct rx_nfa_state
  3611.          *state, struct rx_superstate *superstate) 
  3612. #else
  3613. static struct rx_distinct_future *
  3614. include_futures (rx, df, state, superstate)
  3615.      struct rx *rx;
  3616.      struct rx_distinct_future *df;
  3617.      struct rx_nfa_state *state;
  3618.      struct rx_superstate *superstate;
  3619. #endif
  3620. {
  3621.   struct rx_possible_future *future;
  3622.   struct rx_cache * cache = rx->cache;
  3623.   for (future = state->futures; future; future = future->next)
  3624.     {
  3625.       struct rx_distinct_future *dfp;
  3626.       struct rx_distinct_future *insert_before = 0;
  3627.       if (df)
  3628.     df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
  3629.       for (dfp = df; dfp; dfp = dfp->next_same_super_edge[0])
  3630.     if (dfp->effects == future->effects)
  3631.       break;
  3632.     else
  3633.       {
  3634.         int order = rx->se_list_cmp (rx, dfp->effects, future->effects);
  3635.         if (order > 0)
  3636.           {
  3637.         insert_before = dfp;
  3638.         dfp = 0;
  3639.         break;
  3640.           }
  3641.       }
  3642.       if (df)
  3643.     df->next_same_super_edge[1]->next_same_super_edge[0] = df;
  3644.       if (!dfp)
  3645.     {
  3646.       dfp
  3647.         = ((struct rx_distinct_future *)
  3648.            rx_cache_malloc_or_get (cache, &cache->free_discernable_futures,
  3649.                        sizeof (struct rx_distinct_future)));
  3650.       if (!dfp)
  3651.         return 0;
  3652.       if (!df)
  3653.         {
  3654.           df = insert_before = dfp;
  3655.           df->next_same_super_edge[0] = df->next_same_super_edge[1] = df;
  3656.         }
  3657.       else if (!insert_before)
  3658.         insert_before = df;
  3659.       else if (insert_before == df)
  3660.         df = dfp;
  3661.  
  3662.       dfp->next_same_super_edge[0] = insert_before;
  3663.       dfp->next_same_super_edge[1]
  3664.         = insert_before->next_same_super_edge[1];
  3665.       dfp->next_same_super_edge[1]->next_same_super_edge[0] = dfp;
  3666.       dfp->next_same_super_edge[0]->next_same_super_edge[1] = dfp;
  3667.       dfp->next_same_dest = dfp->prev_same_dest = dfp;
  3668.       dfp->future = 0;
  3669.       dfp->present = superstate;
  3670.       dfp->future_frame.inx = rx->instruction_table[rx_cache_miss];
  3671.       dfp->future_frame.data = 0;
  3672.       dfp->future_frame.data_2 = (void *) dfp;
  3673.       dfp->side_effects_frame.inx
  3674.         = rx->instruction_table[rx_do_side_effects];
  3675.       dfp->side_effects_frame.data = 0;
  3676.       dfp->side_effects_frame.data_2 = (void *) dfp;
  3677.       dfp->effects = future->effects;
  3678.     }
  3679.     }
  3680.   return df;
  3681. }
  3682.  
  3683.  
  3684.  
  3685.  
  3686. /* This constructs a new superstate from its state set.  The only 
  3687.  * complexity here is memory management.
  3688.  */
  3689. #ifdef __STDC__
  3690. RX_DECL struct rx_superstate *
  3691. rx_superstate (struct rx *rx,
  3692.            struct rx_superset *set)
  3693. #else
  3694. RX_DECL struct rx_superstate *
  3695. rx_superstate (rx, set)
  3696.      struct rx *rx;
  3697.      struct rx_superset *set;
  3698. #endif
  3699. {
  3700.   struct rx_cache * cache = rx->cache;
  3701.   struct rx_superstate * superstate = 0;
  3702.  
  3703.   /* Does the superstate already exist in the cache? */
  3704.   if (set->superstate)
  3705.     {
  3706.       if (set->superstate->rx_id != rx->rx_id)
  3707.     {
  3708.       /* Aha.  It is in the cache, but belongs to a superstate
  3709.        * that refers to an NFA that no longer exists.
  3710.        * (We know it no longer exists because it was evidently
  3711.        *  stored in the same region of memory as the current nfa
  3712.        *  yet it has a different id.)
  3713.        */
  3714.       superstate = set->superstate;
  3715.       if (!superstate->is_semifree)
  3716.         {
  3717.           if (cache->lru_superstate == superstate)
  3718.         {
  3719.           cache->lru_superstate = superstate->next_recyclable;
  3720.           if (cache->lru_superstate == superstate)
  3721.             cache->lru_superstate = 0;
  3722.         }
  3723.           {
  3724.         superstate->next_recyclable->prev_recyclable
  3725.           = superstate->prev_recyclable;
  3726.         superstate->prev_recyclable->next_recyclable
  3727.           = superstate->next_recyclable;
  3728.         if (!cache->semifree_superstate)
  3729.           {
  3730.             (cache->semifree_superstate
  3731.              = superstate->next_recyclable
  3732.              = superstate->prev_recyclable
  3733.              = superstate);
  3734.           }
  3735.         else
  3736.           {
  3737.             superstate->next_recyclable = cache->semifree_superstate;
  3738.             superstate->prev_recyclable
  3739.               = cache->semifree_superstate->prev_recyclable;
  3740.             superstate->next_recyclable->prev_recyclable
  3741.               = superstate;
  3742.             superstate->prev_recyclable->next_recyclable
  3743.               = superstate;
  3744.             cache->semifree_superstate = superstate;
  3745.           }
  3746.         ++cache->semifree_superstates;
  3747.           }
  3748.         }
  3749.       set->superstate = 0;
  3750.       goto handle_cache_miss;
  3751.     }
  3752.       ++cache->hits;
  3753.       superstate = set->superstate;
  3754.  
  3755.       rx_refresh_this_superstate (cache, superstate);
  3756.       return superstate;
  3757.     }
  3758.  
  3759.  handle_cache_miss:
  3760.  
  3761.   /* This point reached only for cache misses. */
  3762.   ++cache->misses;
  3763. #if RX_DEBUG
  3764.   if (rx_debug_trace > 1)
  3765.     {
  3766.       struct rx_superset * setp = set;
  3767.       fprintf (stderr, "Building a superstet %d(%d): ", rx->rx_id, set);
  3768.       while (setp)
  3769.     {
  3770.       fprintf (stderr, "%d ", setp->id);
  3771.       setp = setp->cdr;
  3772.     }
  3773.       fprintf (stderr, "(%d)\n", set);
  3774.     }
  3775. #endif
  3776.   superstate = (struct rx_superstate *)rx_cache_get_superstate (cache);
  3777.   if (!superstate)
  3778.     return 0;
  3779.  
  3780.   if (!cache->lru_superstate)
  3781.     (cache->lru_superstate
  3782.      = superstate->next_recyclable
  3783.      = superstate->prev_recyclable
  3784.      = superstate);
  3785.   else
  3786.     {
  3787.       superstate->next_recyclable = cache->lru_superstate;
  3788.       superstate->prev_recyclable = cache->lru_superstate->prev_recyclable;
  3789.       (  superstate->prev_recyclable->next_recyclable
  3790.        = superstate->next_recyclable->prev_recyclable
  3791.        = superstate);
  3792.     }
  3793.   superstate->rx_id = rx->rx_id;
  3794.   superstate->transition_refs = 0;
  3795.   superstate->locks = 0;
  3796.   superstate->is_semifree = 0;
  3797.   set->superstate = superstate;
  3798.   superstate->contents = set;
  3799.   rx_protect_superset (rx, set);
  3800.   superstate->edges = 0;
  3801.   {
  3802.     int x;
  3803.     /* None of the transitions from this superstate are known yet. */
  3804.     for (x = 0; x < rx->local_cset_size; ++x) /* &&&&& 3.8 % */
  3805.       {
  3806.     struct rx_inx * ifr = &superstate->transitions[x];
  3807.     ifr->inx = rx->instruction_table [rx_cache_miss];
  3808.     ifr->data = ifr->data_2 = 0;
  3809.       }
  3810.   }
  3811.   return superstate;
  3812. }
  3813.  
  3814.  
  3815. /* This computes the destination set of one edge of the superstate NFA.
  3816.  * Note that a RX_DISTINCT_FUTURE is a superstate edge.
  3817.  * Returns 0 on an allocation failure.
  3818.  */
  3819.  
  3820. #ifdef __STDC__
  3821. static int 
  3822. solve_destination (struct rx *rx, struct rx_distinct_future *df)
  3823. #else
  3824. static int 
  3825. solve_destination (rx, df)
  3826.      struct rx *rx;
  3827.      struct rx_distinct_future *df;
  3828. #endif
  3829. {
  3830.   struct rx_super_edge *tc = df->edge;
  3831.   struct rx_superset *nfa_state;
  3832.   struct rx_superset *nil_set = rx_superset_cons (rx, 0, 0);
  3833.   struct rx_superset *solution = nil_set;
  3834.   struct rx_superstate *dest;
  3835.  
  3836.   /* Iterate over all NFA states in the state set of this superstate. */
  3837.   for (nfa_state = df->present->contents;
  3838.        nfa_state->car;
  3839.        nfa_state = nfa_state->cdr)
  3840.     {
  3841.       struct rx_nfa_edge *e;
  3842.       /* Iterate over all edges of each NFA state. */
  3843.       for (e = nfa_state->car->edges; e; e = e->next)
  3844.         /* If we find an edge that is labeled with 
  3845.      * the characters we are solving for.....
  3846.      */
  3847.     if (rx_bitset_is_subset (rx->local_cset_size,
  3848.                  tc->cset, e->params.cset))
  3849.       {
  3850.         struct rx_nfa_state *n = e->dest;
  3851.         struct rx_possible_future *pf;
  3852.         /* ....search the partial epsilon closures of the destination
  3853.          * of that edge for a path that involves the same set of
  3854.          * side effects we are solving for.
  3855.          * If we find such a RX_POSSIBLE_FUTURE, we add members to the
  3856.          * stateset we are computing.
  3857.          */
  3858.         for (pf = n->futures; pf; pf = pf->next)
  3859.           if (pf->effects == df->effects)
  3860.         {
  3861.           struct rx_superset * old_sol = solution;
  3862.           rx_protect_superset (rx, solution);
  3863.           solution =
  3864.             rx_superstate_eclosure_union (rx, solution, pf->destset);
  3865.           if (!solution)
  3866.             return 0;
  3867.           rx_release_superset (rx, old_sol);
  3868.         }
  3869.       }
  3870.     }
  3871.   /* It is possible that the RX_DISTINCT_FUTURE we are working on has 
  3872.    * the empty set of NFA states as its definition.  In that case, this
  3873.    * is a failure point.
  3874.    */
  3875.   if (solution == nil_set)
  3876.     {
  3877.       df->future_frame.inx = (void *) rx_backtrack;
  3878.       df->future_frame.data = 0;
  3879.       df->future_frame.data_2 = 0;
  3880.       return 1;
  3881.     }
  3882.   rx_protect_superset (rx, solution);
  3883.   dest = rx_superstate (rx, solution);
  3884.   rx_release_superset (rx, solution);
  3885.   if (!dest)
  3886.     return 0;
  3887.  
  3888.   {
  3889.     struct rx_distinct_future *dft;
  3890.     dft = df;
  3891.     df->prev_same_dest->next_same_dest = 0;
  3892.     while (dft)
  3893.       {
  3894.     dft->future = dest;
  3895.     dft->future_frame.inx = rx->instruction_table[rx_next_char];
  3896.     dft->future_frame.data = (void *) dest->transitions;
  3897.     dft = dft->next_same_dest;
  3898.       }
  3899.     df->prev_same_dest->next_same_dest = df;
  3900.   }
  3901.   if (!dest->transition_refs)
  3902.     dest->transition_refs = df;
  3903.   else
  3904.     {
  3905.       struct rx_distinct_future *dft = dest->transition_refs->next_same_dest;
  3906.       dest->transition_refs->next_same_dest = df->next_same_dest;
  3907.       df->next_same_dest->prev_same_dest = dest->transition_refs;
  3908.       df->next_same_dest = dft;
  3909.       dft->prev_same_dest = df;
  3910.     }
  3911.   return 1;
  3912. }
  3913.  
  3914.  
  3915. /* This takes a superstate and a character, and computes some edges
  3916.  * from the superstate NFA.  In particular, this computes all edges
  3917.  * that lead from SUPERSTATE given CHR.   This function also 
  3918.  * computes the set of characters that share this edge set.
  3919.  * This returns 0 on allocation error.
  3920.  * The character set and list of edges are returned through 
  3921.  * the paramters CSETOUT and DFOUT.
  3922. } */
  3923.  
  3924. #ifdef __STDC__
  3925. static int 
  3926. compute_super_edge (struct rx *rx, struct rx_distinct_future **dfout,
  3927.               rx_Bitset csetout, struct rx_superstate *superstate,
  3928.               unsigned char chr)  
  3929. #else
  3930. static int 
  3931. compute_super_edge (rx, dfout, csetout, superstate, chr)
  3932.      struct rx *rx;
  3933.      struct rx_distinct_future **dfout;
  3934.      rx_Bitset csetout;
  3935.      struct rx_superstate *superstate;
  3936.      unsigned char chr;
  3937. #endif
  3938. {
  3939.   struct rx_superset *stateset = superstate->contents;
  3940.  
  3941.   /* To compute the set of characters that share edges with CHR, 
  3942.    * we start with the full character set, and subtract.
  3943.    */
  3944.   rx_bitset_universe (rx->local_cset_size, csetout);
  3945.   *dfout = 0;
  3946.  
  3947.   /* Iterate over the NFA states in the superstate state-set. */
  3948.   while (stateset->car)
  3949.     {
  3950.       struct rx_nfa_edge *e;
  3951.       for (e = stateset->car->edges; e; e = e->next)
  3952.     if (RX_bitset_member (e->params.cset, chr))
  3953.       {
  3954.         /* If we find an NFA edge that applies, we make sure there
  3955.          * are corresponding edges in the superstate NFA.
  3956.          */
  3957.         *dfout = include_futures (rx, *dfout, e->dest, superstate);
  3958.         if (!*dfout)
  3959.           return 0;
  3960.         /* We also trim the character set a bit. */
  3961.         rx_bitset_intersection (rx->local_cset_size,
  3962.                     csetout, e->params.cset);
  3963.       }
  3964.     else
  3965.       /* An edge that doesn't apply at least tells us some characters
  3966.        * that don't share the same edge set as CHR.
  3967.        */
  3968.       rx_bitset_difference (rx->local_cset_size, csetout, e->params.cset);
  3969.       stateset = stateset->cdr;
  3970.     }
  3971.   return 1;
  3972. }
  3973.  
  3974.  
  3975. /* This is a constructor for RX_SUPER_EDGE structures.  These are
  3976.  * wrappers for lists of superstate NFA edges that share character sets labels.
  3977.  * If a transition class contains more than one rx_distinct_future (superstate
  3978.  * edge), then it represents a non-determinism in the superstate NFA.
  3979.  */
  3980.  
  3981. #ifdef __STDC__
  3982. static struct rx_super_edge *
  3983. rx_super_edge (struct rx *rx,
  3984.            struct rx_superstate *super, rx_Bitset cset,
  3985.            struct rx_distinct_future *df) 
  3986. #else
  3987. static struct rx_super_edge *
  3988. rx_super_edge (rx, super, cset, df)
  3989.      struct rx *rx;
  3990.      struct rx_superstate *super;
  3991.      rx_Bitset cset;
  3992.      struct rx_distinct_future *df;
  3993. #endif
  3994. {
  3995.   struct rx_super_edge *tc =
  3996.     (struct rx_super_edge *)rx_cache_malloc_or_get
  3997.       (rx->cache, &rx->cache->free_transition_classes,
  3998.        sizeof (struct rx_super_edge) + rx_sizeof_bitset (rx->local_cset_size));
  3999.  
  4000.   if (!tc)
  4001.     return 0;
  4002.   tc->next = super->edges;
  4003.   super->edges = tc;
  4004.   tc->rx_backtrack_frame.inx = rx->instruction_table[rx_backtrack_point];
  4005.   tc->rx_backtrack_frame.data = 0;
  4006.   tc->rx_backtrack_frame.data_2 = (void *) tc;
  4007.   tc->options = df;
  4008.   tc->cset = (rx_Bitset) ((char *) tc + sizeof (*tc));
  4009.   rx_bitset_assign (rx->local_cset_size, tc->cset, cset);
  4010.   if (df)
  4011.     {
  4012.       struct rx_distinct_future * dfp = df;
  4013.       df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
  4014.       while (dfp)
  4015.     {
  4016.       dfp->edge = tc;
  4017.       dfp = dfp->next_same_super_edge[0];
  4018.     }
  4019.       df->next_same_super_edge[1]->next_same_super_edge[0] = df;
  4020.     }
  4021.   return tc;
  4022. }
  4023.  
  4024.  
  4025. /* There are three kinds of cache miss.  The first occurs when a
  4026.  * transition is taken that has never been computed during the
  4027.  * lifetime of the source superstate.  That cache miss is handled by
  4028.  * calling COMPUTE_SUPER_EDGE.  The second kind of cache miss
  4029.  * occurs when the destination superstate of a transition doesn't
  4030.  * exist.  SOLVE_DESTINATION is used to construct the destination superstate.
  4031.  * Finally, the third kind of cache miss occurs when the destination
  4032.  * superstate of a transition is in a `semi-free state'.  That case is
  4033.  * handled by UNFREE_SUPERSTATE.
  4034.  *
  4035.  * The function of HANDLE_CACHE_MISS is to figure out which of these
  4036.  * cases applies.
  4037.  */
  4038.  
  4039. #ifdef __STDC__
  4040. static void
  4041. install_partial_transition  (struct rx_superstate *super,
  4042.                  struct rx_inx *answer,
  4043.                  RX_subset set, int offset)
  4044. #else
  4045. static void
  4046. install_partial_transition  (super, answer, set, offset)
  4047.      struct rx_superstate *super;
  4048.      struct rx_inx *answer;
  4049.      RX_subset set;
  4050.      int offset;
  4051. #endif
  4052. {
  4053.   int start = offset;
  4054.   int end = start + 32;
  4055.   RX_subset pos = 1;
  4056.   struct rx_inx * transitions = super->transitions;
  4057.   
  4058.   while (start < end)
  4059.     {
  4060.       if (set & pos)
  4061.     transitions[start] = *answer;
  4062.       pos <<= 1;
  4063.       ++start;
  4064.     }
  4065. }
  4066.  
  4067.  
  4068. #ifdef __STDC__
  4069. RX_DECL struct rx_inx *
  4070. rx_handle_cache_miss
  4071.   (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data) 
  4072. #else
  4073. RX_DECL struct rx_inx *
  4074. rx_handle_cache_miss (rx, super, chr, data)
  4075.      struct rx *rx;
  4076.      struct rx_superstate *super;
  4077.      unsigned char chr;
  4078.      void *data;
  4079. #endif
  4080. {
  4081.   int offset = chr / RX_subset_bits;
  4082.   struct rx_distinct_future *df = data;
  4083.  
  4084.   if (!df)            /* must be the shared_cache_miss_frame */
  4085.     {
  4086.       /* Perhaps this is just a transition waiting to be filled. */
  4087.       struct rx_super_edge *tc;
  4088.       RX_subset mask = rx_subset_singletons [chr % RX_subset_bits];
  4089.  
  4090.       for (tc = super->edges; tc; tc = tc->next)
  4091.     if (tc->cset[offset] & mask)
  4092.       {
  4093.         struct rx_inx * answer;
  4094.         df = tc->options;
  4095.         answer = ((tc->options->next_same_super_edge[0] != tc->options)
  4096.               ? &tc->rx_backtrack_frame
  4097.               : (df->effects
  4098.              ? &df->side_effects_frame
  4099.              : &df->future_frame));
  4100.         install_partial_transition (super, answer,
  4101.                     tc->cset [offset], offset * 32);
  4102.         return answer;
  4103.       }
  4104.       /* Otherwise, it's a flushed or  newly encountered edge. */
  4105.       {
  4106.     rx_Bitset trcset = rx_cset (rx);
  4107.     struct rx_inx *answer;
  4108.     if (!trcset)
  4109.       return 0;
  4110.     rx_lock_superstate (rx, super);
  4111.     if (!compute_super_edge (rx, &df, trcset, super, chr))
  4112.       {
  4113.         rx_unlock_superstate (rx, super);
  4114.         return 0;
  4115.       }
  4116.     if (!df)        /* We just computed the fail transition. */
  4117.       {
  4118.         static struct rx_inx
  4119.           shared_fail_frame = { (void *)rx_backtrack, 0, 0 };
  4120.         answer = &shared_fail_frame;
  4121.       }
  4122.     else
  4123.       {
  4124.         tc = rx_super_edge (rx, super, trcset, df);
  4125.         if (!tc)
  4126.           {
  4127.         rx_unlock_superstate (rx, super);
  4128.         return 0;
  4129.           }
  4130.         answer = ((tc->options->next_same_super_edge[0] != tc->options)
  4131.               ? &tc->rx_backtrack_frame
  4132.               : (df->effects
  4133.              ? &df->side_effects_frame
  4134.              : &df->future_frame));
  4135.       }
  4136.     install_partial_transition (super, answer,
  4137.                     trcset[offset], offset * 32);
  4138.     rx_free_cset (rx, trcset);
  4139.     rx_unlock_superstate (rx, super);
  4140.     return answer;
  4141.       }
  4142.     }
  4143.   else if (df->future) /* A cache miss on an edge with a future? Must be
  4144.             * a semi-free destination. */
  4145.     {                
  4146.       if (df->future->is_semifree)
  4147.     refresh_semifree_superstate (rx->cache, df->future);
  4148.       return &df->future_frame;
  4149.     }
  4150.   else
  4151.     /* no future superstate on an existing edge */
  4152.     {
  4153.       rx_lock_superstate (rx, super);
  4154.       if (!solve_destination (rx, df))
  4155.     {
  4156.       rx_unlock_superstate (rx, super);
  4157.       return 0;
  4158.     }
  4159.       if (!df->effects
  4160.       && (df->edge->options->next_same_super_edge[0] == df->edge->options))
  4161.     install_partial_transition (super, &df->future_frame,
  4162.                     df->edge->cset[offset], offset * 32);
  4163.       rx_unlock_superstate (rx, super);
  4164.       return &df->future_frame;
  4165.     }
  4166. }
  4167.  
  4168.  
  4169.  
  4170.  
  4171. /* The rest of the code provides a regex.c compatable interface. */
  4172.  
  4173.  
  4174. const char *re_error_msg[] =
  4175. {
  4176.   0,                        /* REG_NOUT */
  4177.   "No match",                    /* REG_NOMATCH */
  4178.   "Invalid regular expression",            /* REG_BADPAT */
  4179.   "Invalid collation character",        /* REG_ECOLLATE */
  4180.   "Invalid character class name",        /* REG_ECTYPE */
  4181.   "Trailing backslash",                /* REG_EESCAPE */
  4182.   "Invalid back reference",            /* REG_ESUBREG */
  4183.   "Unmatched [ or [^",                /* REG_EBRACK */
  4184.   "Unmatched ( or \\(",                /* REG_EPAREN */
  4185.   "Unmatched \\{",                /* REG_EBRACE */
  4186.   "Invalid content of \\{\\}",            /* REG_BADBR */
  4187.   "Invalid range end",                /* REG_ERANGE */
  4188.   "Memory exhausted",                /* REG_ESPACE */
  4189.   "Invalid preceding regular expression",    /* REG_BADRPT */
  4190.   "Premature end of regular expression",    /* REG_EEND */
  4191.   "Regular expression too big",            /* REG_ESIZE */
  4192.   "Unmatched ) or \\)",                /* REG_ERPAREN */
  4193. };
  4194.  
  4195.  
  4196.  
  4197. /* 
  4198.  * Macros used while compiling patterns.
  4199.  *
  4200.  * By convention, PEND points just past the end of the uncompiled pattern,
  4201.  * P points to the read position in the pattern.  `translate' is the name
  4202.  * of the translation table (`TRANSLATE' is the name of a macro that looks
  4203.  * things up in `translate').
  4204.  */
  4205.  
  4206.  
  4207. /*
  4208.  * Fetch the next character in the uncompiled pattern---translating it 
  4209.  * if necessary. *Also cast from a signed character in the constant
  4210.  * string passed to us by the user to an unsigned char that we can use
  4211.  * as an array index (in, e.g., `translate').
  4212.  */
  4213. #define PATFETCH(c)                            \
  4214.  do {if (p == pend) return REG_EEND;                    \
  4215.     c = (unsigned char) *p++;                        \
  4216.     c = translate[c];                             \
  4217.  } while (0)
  4218.  
  4219. /* 
  4220.  * Fetch the next character in the uncompiled pattern, with no
  4221.  * translation.
  4222.  */
  4223. #define PATFETCH_RAW(c)                            \
  4224.   do {if (p == pend) return REG_EEND;                    \
  4225.     c = (unsigned char) *p++;                         \
  4226.   } while (0)
  4227.  
  4228. /* Go backwards one character in the pattern.  */
  4229. #define PATUNFETCH p--
  4230.  
  4231.  
  4232. #define TRANSLATE(d) translate[(unsigned char) (d)]
  4233.  
  4234. typedef unsigned regnum_t;
  4235.  
  4236. /* Since offsets can go either forwards or backwards, this type needs to
  4237.  * be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1.
  4238.  */
  4239. typedef int pattern_offset_t;
  4240.  
  4241. typedef struct
  4242. {
  4243.   struct rexp_node ** top_expression; /* was begalt */
  4244.   struct rexp_node ** last_expression; /* was laststart */
  4245.   pattern_offset_t inner_group_offset;
  4246.   regnum_t regnum;
  4247. } compile_stack_elt_t;
  4248.  
  4249. typedef struct
  4250. {
  4251.   compile_stack_elt_t *stack;
  4252.   unsigned size;
  4253.   unsigned avail;            /* Offset of next open position.  */
  4254. } compile_stack_type;
  4255.  
  4256.  
  4257. #define INIT_COMPILE_STACK_SIZE 32
  4258.  
  4259. #define COMPILE_STACK_EMPTY  (compile_stack.avail == 0)
  4260. #define COMPILE_STACK_FULL  (compile_stack.avail == compile_stack.size)
  4261.  
  4262. /* The next available element.  */
  4263. #define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
  4264.  
  4265.  
  4266. /* Set the bit for character C in a list.  */
  4267. #define SET_LIST_BIT(c)                               \
  4268.   (b[((unsigned char) (c)) / BYTEWIDTH]               \
  4269.    |= 1 << (((unsigned char) c) % BYTEWIDTH))
  4270.  
  4271. /* Get the next unsigned number in the uncompiled pattern.  */
  4272. #define GET_UNSIGNED_NUMBER(num)                     \
  4273.   { if (p != pend)                            \
  4274.      {                                    \
  4275.        PATFETCH (c);                             \
  4276.        while (isdigit (c))                         \
  4277.          {                                 \
  4278.            if (num < 0)                            \
  4279.               num = 0;                            \
  4280.            num = num * 10 + c - '0';                     \
  4281.            if (p == pend)                         \
  4282.               break;                             \
  4283.            PATFETCH (c);                        \
  4284.          }                                 \
  4285.        }                                 \
  4286.     }        
  4287.  
  4288. #define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
  4289.  
  4290. #define IS_CHAR_CLASS(string)                        \
  4291.    (!strcmp (string, "alpha") || !strcmp (string, "upper")        \
  4292.     || !strcmp (string, "lower") || !strcmp (string, "digit")        \
  4293.     || !strcmp (string, "alnum") || !strcmp (string, "xdigit")        \
  4294.     || !strcmp (string, "space") || !strcmp (string, "print")        \
  4295.     || !strcmp (string, "punct") || !strcmp (string, "graph")        \
  4296.     || !strcmp (string, "cntrl") || !strcmp (string, "blank"))
  4297.  
  4298.  
  4299. /* These predicates are used in regex_compile. */
  4300.  
  4301. /* P points to just after a ^ in PATTERN.  Return true if that ^ comes
  4302.  * after an alternative or a begin-subexpression.  We assume there is at
  4303.  * least one character before the ^.  
  4304.  */
  4305.  
  4306. #ifdef __STDC__
  4307. static boolean
  4308. at_begline_loc_p (const char *pattern, const char * p, reg_syntax_t syntax)
  4309. #else
  4310. static boolean
  4311. at_begline_loc_p (pattern, p, syntax)
  4312.      const char *pattern;
  4313.      const char * p;
  4314.      reg_syntax_t syntax;
  4315. #endif
  4316. {
  4317.   const char *prev = p - 2;
  4318.   boolean prev_prev_backslash = ((prev > pattern) && (prev[-1] == '\\'));
  4319.   
  4320.     return
  4321.       
  4322.       (/* After a subexpression?  */
  4323.        ((*prev == '(') && ((syntax & RE_NO_BK_PARENS) || prev_prev_backslash))
  4324.        ||
  4325.        /* After an alternative?  */
  4326.        ((*prev == '|') && ((syntax & RE_NO_BK_VBAR) || prev_prev_backslash))
  4327.        );
  4328. }
  4329.  
  4330. /* The dual of at_begline_loc_p.  This one is for $.  We assume there is
  4331.  * at least one character after the $, i.e., `P < PEND'.
  4332.  */
  4333.  
  4334. #ifdef __STDC__
  4335. static boolean
  4336. at_endline_loc_p (const char *p, const char *pend, int syntax)
  4337. #else
  4338. static boolean
  4339. at_endline_loc_p (p, pend, syntax)
  4340.      const char *p;
  4341.      const char *pend;
  4342.      int syntax;
  4343. #endif
  4344. {
  4345.   const char *next = p;
  4346.   boolean next_backslash = (*next == '\\');
  4347.   const char *next_next = (p + 1 < pend) ? (p + 1) : 0;
  4348.   
  4349.   return
  4350.     (
  4351.      /* Before a subexpression?  */
  4352.      ((syntax & RE_NO_BK_PARENS)
  4353.       ? (*next == ')')
  4354.       : (next_backslash && next_next && (*next_next == ')')))
  4355.     ||
  4356.      /* Before an alternative?  */
  4357.      ((syntax & RE_NO_BK_VBAR)
  4358.       ? (*next == '|')
  4359.       : (next_backslash && next_next && (*next_next == '|')))
  4360.      );
  4361. }
  4362.  
  4363.  
  4364. static char id_translation[256] =
  4365. {
  4366.   0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
  4367.  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  4368.  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  4369.  30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  4370.  40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  4371.  50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  4372.  60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  4373.  70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  4374.  80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
  4375.  90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  4376.  
  4377.  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
  4378.  110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
  4379.  120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
  4380.  130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
  4381.  140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
  4382.  150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  4383.  160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
  4384.  170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
  4385.  180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
  4386.  190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
  4387.  
  4388.  200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
  4389.  210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
  4390.  220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
  4391.  230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  4392.  240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
  4393.  250, 251, 252, 253, 254, 255
  4394. };
  4395.  
  4396. /* The compiler keeps an inverted translation table.
  4397.  * This looks up/inititalize elements.
  4398.  * VALID is an array of booleans that validate CACHE.
  4399.  */
  4400.  
  4401. #ifdef __STDC__
  4402. static rx_Bitset
  4403. inverse_translation (struct re_pattern_buffer * rxb,
  4404.              char * valid, rx_Bitset cache,
  4405.              char * translate, int c)
  4406. #else
  4407. static rx_Bitset
  4408. inverse_translation (rxb, valid, cache, translate, c)
  4409.      struct re_pattern_buffer * rxb;
  4410.      char * valid;
  4411.      rx_Bitset cache;
  4412.      char * translate;
  4413.      int c;
  4414. #endif
  4415. {
  4416.   rx_Bitset cs
  4417.     = cache + c * rx_bitset_numb_subsets (rxb->rx.local_cset_size); 
  4418.  
  4419.   if (!valid[c])
  4420.     {
  4421.       int x;
  4422.       int c_tr = TRANSLATE(c);
  4423.       rx_bitset_null (rxb->rx.local_cset_size, cs);
  4424.       for (x = 0; x < 256; ++x)    /* &&&& 13.37 */
  4425.     if (TRANSLATE(x) == c_tr)
  4426.       RX_bitset_enjoin (cs, x);
  4427.       valid[c] = 1;
  4428.     }
  4429.   return cs;
  4430. }
  4431.  
  4432.  
  4433.  
  4434.  
  4435. /* More subroutine declarations and macros for regex_compile.  */
  4436.  
  4437. /* Returns true if REGNUM is in one of COMPILE_STACK's elements and 
  4438.    false if it's not.  */
  4439.  
  4440. #ifdef __STDC__
  4441. static boolean
  4442. group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
  4443. #else
  4444. static boolean
  4445. group_in_compile_stack (compile_stack, regnum)
  4446.     compile_stack_type compile_stack;
  4447.     regnum_t regnum;
  4448. #endif
  4449. {
  4450.   int this_element;
  4451.  
  4452.   for (this_element = compile_stack.avail - 1;  
  4453.        this_element >= 0; 
  4454.        this_element--)
  4455.     if (compile_stack.stack[this_element].regnum == regnum)
  4456.       return true;
  4457.  
  4458.   return false;
  4459. }
  4460.  
  4461.  
  4462. /*
  4463.  * Read the ending character of a range (in a bracket expression) from the
  4464.  * uncompiled pattern *P_PTR (which ends at PEND).  We assume the
  4465.  * starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)
  4466.  * Then we set the translation of all bits between the starting and
  4467.  * ending characters (inclusive) in the compiled pattern B.
  4468.  * 
  4469.  * Return an error code.
  4470.  * 
  4471.  * We use these short variable names so we can use the same macros as
  4472.  * `regex_compile' itself.  
  4473.  */
  4474.  
  4475. #ifdef __STDC__
  4476. static reg_errcode_t
  4477. compile_range (struct re_pattern_buffer * rxb, rx_Bitset cs,
  4478.            const char ** p_ptr, const char * pend,
  4479.            char * translate, reg_syntax_t syntax,
  4480.            rx_Bitset inv_tr,  char * valid_inv_tr)
  4481. #else
  4482. static reg_errcode_t
  4483. compile_range (rxb, cs, p_ptr, pend, translate, syntax, inv_tr, valid_inv_tr)
  4484.      struct re_pattern_buffer * rxb;
  4485.      rx_Bitset cs;
  4486.      const char ** p_ptr;
  4487.      const char * pend;
  4488.      char * translate;
  4489.      reg_syntax_t syntax;
  4490.      rx_Bitset inv_tr;
  4491.      char * valid_inv_tr;
  4492. #endif
  4493. {
  4494.   unsigned this_char;
  4495.  
  4496.   const char *p = *p_ptr;
  4497.  
  4498.   unsigned char range_end;
  4499.   unsigned char range_start = TRANSLATE(p[-2]);
  4500.  
  4501.   if (p == pend)
  4502.     return REG_ERANGE;
  4503.  
  4504.   PATFETCH (range_end);
  4505.  
  4506.   (*p_ptr)++;
  4507.  
  4508.   if (range_start > range_end)
  4509.     return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
  4510.  
  4511.   for (this_char = range_start; this_char <= range_end; this_char++)
  4512.     {
  4513.       rx_Bitset it =
  4514.     inverse_translation (rxb, valid_inv_tr, inv_tr, translate, this_char);
  4515.       rx_bitset_union (rxb->rx.local_cset_size, cs, it);
  4516.     }
  4517.   
  4518.   return REG_NOERROR;
  4519. }
  4520.  
  4521.  
  4522. /* This searches a regexp for backreference side effects.
  4523.  * It fills in the array OUT with 1 at the index of every register pair
  4524.  * referenced by a backreference.
  4525.  *
  4526.  * This is used to help optimize patterns for searching.  The information is
  4527.  * useful because, if the caller doesn't want register values, backreferenced
  4528.  * registers are the only registers for which we need rx_backtrack.
  4529.  */
  4530.  
  4531. #ifdef __STDC__
  4532. static void
  4533. find_backrefs (char * out, struct rexp_node * rexp,
  4534.            struct re_se_params * params)
  4535. #else
  4536. static void
  4537. find_backrefs (out, rexp, params)
  4538.      char * out;
  4539.      struct rexp_node * rexp;
  4540.      struct re_se_params * params;
  4541. #endif
  4542. {
  4543.   if (rexp)
  4544.     switch (rexp->type)
  4545.       {
  4546.       case r_cset:
  4547.       case r_data:
  4548.     return;
  4549.       case r_alternate:
  4550.       case r_concat:
  4551.       case r_opt:
  4552.       case r_star:
  4553.       case r_2phase_star:
  4554.     find_backrefs (out, rexp->params.pair.left, params);
  4555.     find_backrefs (out, rexp->params.pair.right, params);
  4556.     return;
  4557.       case r_side_effect:
  4558.     if (   ((int)rexp->params.side_effect >= 0)
  4559.         && (params [(int)rexp->params.side_effect].se == re_se_backref))
  4560.       out[ params [(int)rexp->params.side_effect].op1] = 1;
  4561.     return;
  4562.       }
  4563. }
  4564.  
  4565.  
  4566.  
  4567. /* Returns 0 unless the pattern can match the empty string. */
  4568.  
  4569. #ifdef __STDC__
  4570. static int
  4571. compute_fastset (struct re_pattern_buffer * rxb, struct rexp_node * rexp)
  4572. #else
  4573. static int
  4574. compute_fastset (rxb, rexp)
  4575.      struct re_pattern_buffer * rxb;
  4576.      struct rexp_node * rexp;
  4577. #endif
  4578. {
  4579.   if (!rexp)
  4580.     return 1;
  4581.   switch (rexp->type)
  4582.     {
  4583.     case r_data:
  4584.       return 1;
  4585.     case r_cset:
  4586.       {
  4587.     rx_bitset_union (rxb->rx.local_cset_size,
  4588.              rxb->fastset, rexp->params.cset);
  4589.       }
  4590.       return 0;
  4591.     case r_concat:
  4592.       return (compute_fastset (rxb, rexp->params.pair.left)
  4593.           && compute_fastset (rxb, rexp->params.pair.right));
  4594.     case r_2phase_star:
  4595.       compute_fastset (rxb, rexp->params.pair.left);
  4596.       /* compute_fastset (rxb, rexp->params.pair.right);  nope... */
  4597.       return 1;
  4598.     case r_alternate:
  4599.       return !!(compute_fastset (rxb, rexp->params.pair.left)
  4600.         + compute_fastset (rxb, rexp->params.pair.right));
  4601.     case r_opt:
  4602.     case r_star:
  4603.       compute_fastset (rxb, rexp->params.pair.left);
  4604.       return 1;
  4605.     case r_side_effect:
  4606.       return 1;
  4607.     }
  4608. }
  4609.  
  4610.  
  4611. /* returns
  4612.  *  1 -- yes, definately anchored by the given side effect.
  4613.  *  2 -- maybe anchored, maybe the empty string.
  4614.  *  0 -- definately not anchored
  4615.  *  There is simply no other possibility.
  4616.  */
  4617.  
  4618. #ifdef __STDC__
  4619. static int
  4620. is_anchored (struct rexp_node * rexp, rx_side_effect se)
  4621. #else
  4622. static int
  4623. is_anchored (rexp, se)
  4624.      struct rexp_node * rexp;
  4625.      rx_side_effect se;
  4626. #endif
  4627. {
  4628.   if (!rexp)
  4629.     return 2;
  4630.   switch (rexp->type)
  4631.     {
  4632.     case r_cset:
  4633.     case r_data:
  4634.       return 0;
  4635.     case r_concat:
  4636.     case r_2phase_star:
  4637.       {
  4638.     int l = is_anchored (rexp->params.pair.left, se);
  4639.     return (l == 2 ? is_anchored (rexp->params.pair.right, se) : l);
  4640.       }
  4641.     case r_alternate:
  4642.       {
  4643.     int l = is_anchored (rexp->params.pair.left, se);
  4644.     int r = l ? is_anchored (rexp->params.pair.right, se) : 0;
  4645.     return MAX (l, r);
  4646.       }
  4647.     case r_opt:
  4648.     case r_star:
  4649.       return is_anchored (rexp->params.pair.left, se) ? 2 : 0;
  4650.       
  4651.     case r_side_effect:
  4652.       return ((rexp->params.side_effect == se)
  4653.           ? 1 : 2);
  4654.     }
  4655. }
  4656.  
  4657.  
  4658. /* This removes register assignments that aren't required by backreferencing.
  4659.  * This can speed up explore_future, especially if it eliminates
  4660.  * non-determinism in the superstate NFA.
  4661.  * 
  4662.  * NEEDED is an array of characters, presumably filled in by FIND_BACKREFS.
  4663.  * The non-zero elements of the array indicate which register assignments
  4664.  * can NOT be removed from the expression.
  4665.  */
  4666.  
  4667. #ifdef __STDC__
  4668. static struct rexp_node *
  4669. remove_unecessary_side_effects (struct rx * rx, char * needed,
  4670.                 struct rexp_node * rexp,
  4671.                 struct re_se_params * params)
  4672. #else
  4673. static struct rexp_node *
  4674. remove_unecessary_side_effects (rx, needed, rexp, params)
  4675.      struct rx * rx;
  4676.      char * needed;
  4677.      struct rexp_node * rexp;
  4678.      struct re_se_params * params;
  4679. #endif
  4680. {
  4681.   struct rexp_node * l;
  4682.   struct rexp_node * r;
  4683.   if (!rexp)
  4684.     return 0;
  4685.   else
  4686.     switch (rexp->type)
  4687.       {
  4688.       case r_cset:
  4689.       case r_data:
  4690.     return rexp;
  4691.       case r_alternate:
  4692.       case r_concat:
  4693.       case r_2phase_star:
  4694.     l = remove_unecessary_side_effects (rx, needed,
  4695.                         rexp->params.pair.left, params);
  4696.     r = remove_unecessary_side_effects (rx, needed,
  4697.                         rexp->params.pair.right, params);
  4698.     if ((l && r) || (rexp->type != r_concat))
  4699.       {
  4700.         rexp->params.pair.left = l;
  4701.         rexp->params.pair.right = r;
  4702.         return rexp;
  4703.       }
  4704.     else
  4705.       {
  4706.         rexp->params.pair.left = rexp->params.pair.right = 0;
  4707.         rx_free_rexp (rx, rexp);
  4708.         return l ? l : r;
  4709.       }
  4710.       case r_opt:
  4711.       case r_star:
  4712.     l = remove_unecessary_side_effects (rx, needed,
  4713.                         rexp->params.pair.left, params);
  4714.     if (l)
  4715.       {
  4716.         rexp->params.pair.left = l;
  4717.         return rexp;
  4718.       }
  4719.     else
  4720.       {
  4721.         rexp->params.pair.left = 0;
  4722.         rx_free_rexp (rx, rexp);
  4723.         return 0;
  4724.       }
  4725.       case r_side_effect:
  4726.     {
  4727.       int se = (int)rexp->params.side_effect;
  4728.       if (   (se >= 0)
  4729.           && (   ((enum re_side_effects)params[se].se == re_se_lparen)
  4730.           || ((enum re_side_effects)params[se].se == re_se_rparen))
  4731.           && (params [se].op1 > 0)
  4732.           && (!needed [params [se].op1]))
  4733.         {
  4734.           rx_free_rexp (rx, rexp);
  4735.           return 0;
  4736.         }
  4737.       else
  4738.         return rexp;
  4739.     }
  4740.       }
  4741. }
  4742.  
  4743.  
  4744.  
  4745. #ifdef __STDC__
  4746. static int
  4747. pointless_if_repeated (struct rexp_node * node, struct re_se_params * params)
  4748. #else
  4749. static int
  4750. pointless_if_repeated (node, params)
  4751.      struct rexp_node * node;
  4752.      struct re_se_params * params;
  4753. #endif
  4754. {
  4755.   if (!node)
  4756.     return 1;
  4757.   switch (node->type)
  4758.     {
  4759.     case r_cset:
  4760.       return 0;
  4761.     case r_alternate:
  4762.     case r_concat:
  4763.     case r_2phase_star:
  4764.       return (pointless_if_repeated (node->params.pair.left, params)
  4765.           && pointless_if_repeated (node->params.pair.right, params));
  4766.     case r_opt:
  4767.     case r_star:
  4768.       return pointless_if_repeated (node->params.pair.left, params);
  4769.     case r_side_effect:
  4770.       switch (((int)node->params.side_effect < 0)
  4771.           ? (enum re_side_effects)node->params.side_effect
  4772.           : (enum re_side_effects)params[(int)node->params.side_effect].se)
  4773.     {
  4774.     case re_se_try:
  4775.     case re_se_at_dot:
  4776.     case re_se_begbuf:
  4777.     case re_se_hat:
  4778.     case re_se_wordbeg:
  4779.     case re_se_wordbound:
  4780.     case re_se_notwordbound:
  4781.     case re_se_wordend:
  4782.     case re_se_endbuf:
  4783.     case re_se_dollar:
  4784.     case re_se_fail:
  4785.     case re_se_win:
  4786.       return 1;
  4787.     case re_se_lparen:
  4788.     case re_se_rparen:
  4789.     case re_se_iter:
  4790.     case re_se_end_iter:
  4791.     case re_se_syntax:
  4792.     case re_se_not_syntax:
  4793.     case re_se_backref:
  4794.       return 0;
  4795.     }
  4796.     case r_data:
  4797.     default:
  4798.       return 0;
  4799.     }
  4800. }
  4801.  
  4802.  
  4803.  
  4804. #ifdef __STDC__
  4805. static int
  4806. registers_on_stack (struct re_pattern_buffer * rxb,
  4807.             struct rexp_node * rexp, int in_danger,
  4808.             struct re_se_params * params)
  4809. #else
  4810. static int
  4811. registers_on_stack (rxb, rexp, in_danger, params)
  4812.      struct re_pattern_buffer * rxb;
  4813.      struct rexp_node * rexp;
  4814.      int in_danger;
  4815.      struct re_se_params * params;
  4816. #endif
  4817. {
  4818.   if (!rexp)
  4819.     return 0;
  4820.   else
  4821.     switch (rexp->type)
  4822.       {
  4823.       case r_cset:
  4824.       case r_data:
  4825.     return 0;
  4826.       case r_alternate:
  4827.       case r_concat:
  4828.     return (   registers_on_stack (rxb, rexp->params.pair.left,
  4829.                        in_danger, params)
  4830.         || (registers_on_stack
  4831.             (rxb, rexp->params.pair.right,
  4832.              in_danger, params)));
  4833.       case r_opt:
  4834.     return registers_on_stack (rxb, rexp->params.pair.left, 0, params);
  4835.       case r_star:
  4836.     return registers_on_stack (rxb, rexp->params.pair.left, 1, params);
  4837.       case r_2phase_star:
  4838.     return
  4839.       (   registers_on_stack (rxb, rexp->params.pair.left, 1, params)
  4840.        || registers_on_stack (rxb, rexp->params.pair.right, 1, params));
  4841.       case r_side_effect:
  4842.     {
  4843.       int se = (int)rexp->params.side_effect;
  4844.       if (   in_danger
  4845.           && (se >= 0)
  4846.           && (params [se].op1 > 0)
  4847.           && (   ((enum re_side_effects)params[se].se == re_se_lparen)
  4848.           || ((enum re_side_effects)params[se].se == re_se_rparen)))
  4849.         return 1;
  4850.       else
  4851.         return 0;
  4852.     }
  4853.       }
  4854. }
  4855.  
  4856.  
  4857.  
  4858. static char idempotent_complex_se[] =
  4859. {
  4860. #define RX_WANT_SE_DEFS 1
  4861. #undef RX_DEF_SE
  4862. #undef RX_DEF_CPLX_SE
  4863. #define RX_DEF_SE(IDEM, NAME, VALUE)          
  4864. #define RX_DEF_CPLX_SE(IDEM, NAME, VALUE)     IDEM,
  4865. #include "rx.h"
  4866. #undef RX_DEF_SE
  4867. #undef RX_DEF_CPLX_SE
  4868. #undef RX_WANT_SE_DEFS
  4869.   23
  4870. };
  4871.  
  4872. static char idempotent_se[] =
  4873. {
  4874.   13,
  4875. #define RX_WANT_SE_DEFS 1
  4876. #undef RX_DEF_SE
  4877. #undef RX_DEF_CPLX_SE
  4878. #define RX_DEF_SE(IDEM, NAME, VALUE)          IDEM,
  4879. #define RX_DEF_CPLX_SE(IDEM, NAME, VALUE)     
  4880. #include "rx.h"
  4881. #undef RX_DEF_SE
  4882. #undef RX_DEF_CPLX_SE
  4883. #undef RX_WANT_SE_DEFS
  4884.   42
  4885. };
  4886.  
  4887.  
  4888.  
  4889.  
  4890. #ifdef __STDC__
  4891. static int
  4892. has_any_se (struct rx * rx,
  4893.         struct rexp_node * rexp)
  4894. #else
  4895. static int
  4896. has_any_se (rx, rexp)
  4897.      struct rx * rx;
  4898.      struct rexp_node * rexp;
  4899. #endif
  4900. {
  4901.   if (!rexp)
  4902.     return 0;
  4903.  
  4904.   switch (rexp->type)
  4905.     {
  4906.     case r_cset:
  4907.     case r_data:
  4908.       return 0;
  4909.  
  4910.     case r_side_effect:
  4911.       return 1;
  4912.       
  4913.     case r_2phase_star:
  4914.     case r_concat:
  4915.     case r_alternate:
  4916.       return
  4917.     (   has_any_se (rx, rexp->params.pair.left)
  4918.      || has_any_se (rx, rexp->params.pair.right));
  4919.  
  4920.     case r_opt:
  4921.     case r_star:
  4922.       return has_any_se (rx, rexp->params.pair.left);
  4923.     }
  4924. }
  4925.  
  4926.  
  4927.  
  4928. /* This must be called AFTER `convert_hard_loops' for a given REXP. */
  4929. #ifdef __STDC__
  4930. static int
  4931. has_non_idempotent_epsilon_path (struct rx * rx,
  4932.                  struct rexp_node * rexp,
  4933.                  struct re_se_params * params)
  4934. #else
  4935. static int
  4936. has_non_idempotent_epsilon_path (rx, rexp, params)
  4937.      struct rx * rx;
  4938.      struct rexp_node * rexp;
  4939.      struct re_se_params * params;
  4940. #endif
  4941. {
  4942.   if (!rexp)
  4943.     return 0;
  4944.  
  4945.   switch (rexp->type)
  4946.     {
  4947.     case r_cset:
  4948.     case r_data:
  4949.     case r_star:
  4950.       return 0;
  4951.  
  4952.     case r_side_effect:
  4953.       return
  4954.     !((int)rexp->params.side_effect > 0
  4955.       ? idempotent_complex_se [ params [(int)rexp->params.side_effect].se ]
  4956.       : idempotent_se [-(int)rexp->params.side_effect]);
  4957.       
  4958.     case r_alternate:
  4959.       return
  4960.     (   has_non_idempotent_epsilon_path (rx,
  4961.                          rexp->params.pair.left, params)
  4962.      || has_non_idempotent_epsilon_path (rx,
  4963.                          rexp->params.pair.right, params));
  4964.  
  4965.     case r_2phase_star:
  4966.     case r_concat:
  4967.       return
  4968.     (   has_non_idempotent_epsilon_path (rx,
  4969.                          rexp->params.pair.left, params)
  4970.      && has_non_idempotent_epsilon_path (rx,
  4971.                          rexp->params.pair.right, params));
  4972.  
  4973.     case r_opt:
  4974.       return has_non_idempotent_epsilon_path (rx,
  4975.                           rexp->params.pair.left, params);
  4976.     }
  4977.  
  4978. }
  4979.  
  4980.  
  4981.  
  4982. /* This computes rougly what it's name suggests.   It can (and does) go wrong 
  4983.  * in the direction of returning spurious 0 without causing disasters.
  4984.  */
  4985. #ifdef __STDC__
  4986. static int
  4987. begins_with_complex_se (struct rx * rx, struct rexp_node * rexp)
  4988. #else
  4989. static int
  4990. begins_with_complex_se (rx, rexp)
  4991.      struct rx * rx;
  4992.      struct rexp_node * rexp;
  4993. #endif
  4994. {
  4995.   if (!rexp)
  4996.     return 0;
  4997.  
  4998.   switch (rexp->type)
  4999.     {
  5000.     case r_cset:
  5001.     case r_data:
  5002.       return 0;
  5003.  
  5004.     case r_side_effect:
  5005.       return ((int)rexp->params.side_effect >= 0);
  5006.       
  5007.     case r_alternate:
  5008.       return
  5009.     (   begins_with_complex_se (rx, rexp->params.pair.left)
  5010.      && begins_with_complex_se (rx, rexp->params.pair.right));
  5011.  
  5012.  
  5013.     case r_concat:
  5014.       return has_any_se (rx, rexp->params.pair.left);
  5015.     case r_opt:
  5016.     case r_star:
  5017.     case r_2phase_star:
  5018.       return 0;
  5019.     }
  5020. }
  5021.  
  5022.  
  5023. /* This destructively removes some of the re_se_tv side effects from 
  5024.  * a rexp tree.  In particular, during parsing re_se_tv was inserted on the
  5025.  * right half of every | to guarantee that posix path preference could be 
  5026.  * honored.  This function removes some which it can be determined aren't 
  5027.  * needed.  
  5028.  */
  5029.  
  5030. #ifdef __STDC__
  5031. static void
  5032. speed_up_alt (struct rx * rx,
  5033.           struct rexp_node * rexp,
  5034.           int unposix)
  5035. #else
  5036. static void
  5037. speed_up_alt (rx, rexp, unposix)
  5038.      struct rx * rx;
  5039.      struct rexp_node * rexp;
  5040.      int unposix;
  5041. #endif
  5042. {
  5043.   if (!rexp)
  5044.     return;
  5045.  
  5046.   switch (rexp->type)
  5047.     {
  5048.     case r_cset:
  5049.     case r_data:
  5050.     case r_side_effect:
  5051.       return;
  5052.  
  5053.     case r_opt:
  5054.     case r_star:
  5055.       speed_up_alt (rx, rexp->params.pair.left, unposix);
  5056.       return;
  5057.  
  5058.     case r_2phase_star:
  5059.     case r_concat:
  5060.       speed_up_alt (rx, rexp->params.pair.left, unposix);
  5061.       speed_up_alt (rx, rexp->params.pair.right, unposix);
  5062.       return;
  5063.  
  5064.     case r_alternate:
  5065.       /* the right child is guaranteed to be (concat re_se_tv <subexp>) */
  5066.  
  5067.       speed_up_alt (rx, rexp->params.pair.left, unposix);
  5068.       speed_up_alt (rx, rexp->params.pair.right->params.pair.right, unposix);
  5069.       
  5070.       if (   unposix
  5071.       || (begins_with_complex_se
  5072.           (rx, rexp->params.pair.right->params.pair.right))
  5073.       || !(   has_any_se (rx, rexp->params.pair.right->params.pair.right)
  5074.            || has_any_se (rx, rexp->params.pair.left)))
  5075.     {
  5076.       struct rexp_node * conc = rexp->params.pair.right;
  5077.       rexp->params.pair.right = conc->params.pair.right;
  5078.       conc->params.pair.right = 0;
  5079.       rx_free_rexp (rx, conc);
  5080.     }
  5081.     }
  5082. }
  5083.  
  5084.  
  5085.  
  5086.  
  5087.  
  5088. /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
  5089.    Returns one of error codes defined in `regex.h', or zero for success.
  5090.  
  5091.    Assumes the `allocated' (and perhaps `buffer') and `translate'
  5092.    fields are set in BUFP on entry.
  5093.  
  5094.    If it succeeds, results are put in BUFP (if it returns an error, the
  5095.    contents of BUFP are undefined):
  5096.      `buffer' is the compiled pattern;
  5097.      `syntax' is set to SYNTAX;
  5098.      `used' is set to the length of the compiled pattern;
  5099.      `fastmap_accurate' is set to zero;
  5100.      `re_nsub' is set to the number of groups in PATTERN;
  5101.      `not_bol' and `not_eol' are set to zero.
  5102.    
  5103.    The `fastmap' and `newline_anchor' fields are neither
  5104.    examined nor set.  */
  5105.  
  5106.  
  5107.  
  5108. #ifdef __STDC__
  5109. reg_errcode_t
  5110. rx_compile (const char *pattern, int size,
  5111.         reg_syntax_t syntax,
  5112.         struct re_pattern_buffer * rxb) 
  5113. #else
  5114. reg_errcode_t
  5115. rx_compile (pattern, size, syntax, rxb)
  5116.      const char *pattern;
  5117.      int size;
  5118.      reg_syntax_t syntax;
  5119.      struct re_pattern_buffer * rxb;
  5120. #endif
  5121. {
  5122.   RX_subset
  5123.     inverse_translate [CHAR_SET_SIZE * rx_bitset_numb_subsets(CHAR_SET_SIZE)];
  5124.   char
  5125.     validate_inv_tr [CHAR_SET_SIZE * rx_bitset_numb_subsets(CHAR_SET_SIZE)];
  5126.  
  5127.   /* We fetch characters from PATTERN here.  Even though PATTERN is
  5128.      `char *' (i.e., signed), we declare these variables as unsigned, so
  5129.      they can be reliably used as array indices.  */
  5130.   register unsigned char c, c1;
  5131.   
  5132.   /* A random tempory spot in PATTERN.  */
  5133.   const char *p1;
  5134.   
  5135.   /* Keeps track of unclosed groups.  */
  5136.   compile_stack_type compile_stack;
  5137.  
  5138.   /* Points to the current (ending) position in the pattern.  */
  5139.   const char *p = pattern;
  5140.   const char *pend = pattern + size;
  5141.   
  5142.   /* How to translate the characters in the pattern.  */
  5143.   char *translate = rxb->translate ? rxb->translate : id_translation;
  5144.  
  5145.   /* When parsing is done, this will hold the expression tree. */
  5146.   struct rexp_node * rexp = 0;
  5147.  
  5148.   /* In the midst of compilation, this holds onto the regexp 
  5149.    * first parst while rexp goes on to aquire additional constructs.
  5150.    */
  5151.   struct rexp_node * orig_rexp = 0;
  5152.   struct rexp_node * fewer_side_effects = 0;
  5153.  
  5154.   /* This and top_expression are saved on the compile stack. */
  5155.   struct rexp_node ** top_expression = &rexp;
  5156.   struct rexp_node ** last_expression = top_expression;
  5157.   
  5158.   /* Parameter to `goto append_node' */
  5159.   struct rexp_node * append;
  5160.  
  5161.   /* Counts open-groups as they are encountered.  This is the index of the
  5162.    * innermost group being compiled.
  5163.    */
  5164.   regnum_t regnum = 0;
  5165.  
  5166.   /* Place in the uncompiled pattern (i.e., the {) to
  5167.    * which to go back if the interval is invalid.  
  5168.    */
  5169.   const char *beg_interval;
  5170.  
  5171.   struct re_se_params * params = 0;
  5172.   int paramc = 0;        /* How many complex side effects so far? */
  5173.  
  5174.   rx_side_effect side;        /* param to `goto add_side_effect' */
  5175.  
  5176.   bzero (validate_inv_tr, sizeof (validate_inv_tr));
  5177.  
  5178.   rxb->rx.instruction_table = rx_id_instruction_table;
  5179.  
  5180.  
  5181.   /* Initialize the compile stack.  */
  5182.   compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
  5183.   if (compile_stack.stack == 0)
  5184.     return REG_ESPACE;
  5185.  
  5186.   compile_stack.size = INIT_COMPILE_STACK_SIZE;
  5187.   compile_stack.avail = 0;
  5188.  
  5189.   /* Initialize the pattern buffer.  */
  5190.   rxb->rx.cache = &default_cache;
  5191.   rxb->syntax = syntax;
  5192.   rxb->fastmap_accurate = 0;
  5193.   rxb->not_bol = rxb->not_eol = 0;
  5194.   rxb->least_subs = 0;
  5195.   
  5196.   /* Always count groups, whether or not rxb->no_sub is set.  
  5197.    * The whole pattern is implicitly group 0, so counting begins
  5198.    * with 1.
  5199.    */
  5200.   rxb->re_nsub = 0;
  5201.  
  5202. #if !defined (emacs) && !defined (SYNTAX_TABLE)
  5203.   /* Initialize the syntax table.  */
  5204.    init_syntax_once ();
  5205. #endif
  5206.  
  5207.   /* Loop through the uncompiled pattern until we're at the end.  */
  5208.   while (p != pend)
  5209.     {
  5210.       PATFETCH (c);
  5211.  
  5212.       switch (c)
  5213.         {
  5214.         case '^':
  5215.           {
  5216.             if (   /* If at start of pattern, it's an operator.  */
  5217.                    p == pattern + 1
  5218.                    /* If context independent, it's an operator.  */
  5219.                 || syntax & RE_CONTEXT_INDEP_ANCHORS
  5220.                    /* Otherwise, depends on what's come before.  */
  5221.                 || at_begline_loc_p (pattern, p, syntax))
  5222.           {
  5223.         struct rexp_node * n
  5224.           = rx_mk_r_side_effect (&rxb->rx, (rx_side_effect)re_se_hat);
  5225.         if (!n)
  5226.           return REG_ESPACE;
  5227.         append = n;
  5228.         goto append_node;
  5229.           }
  5230.             else
  5231.               goto normal_char;
  5232.           }
  5233.           break;
  5234.  
  5235.  
  5236.         case '$':
  5237.           {
  5238.             if (   /* If at end of pattern, it's an operator.  */
  5239.                    p == pend 
  5240.                    /* If context independent, it's an operator.  */
  5241.                 || syntax & RE_CONTEXT_INDEP_ANCHORS
  5242.                    /* Otherwise, depends on what's next.  */
  5243.                 || at_endline_loc_p (p, pend, syntax))
  5244.           {
  5245.         struct rexp_node * n
  5246.           = rx_mk_r_side_effect (&rxb->rx, (rx_side_effect)re_se_dollar);
  5247.         if (!n)
  5248.           return REG_ESPACE;
  5249.         append = n;
  5250.         goto append_node;
  5251.           }
  5252.              else
  5253.                goto normal_char;
  5254.            }
  5255.            break;
  5256.  
  5257.  
  5258.     case '+':
  5259.         case '?':
  5260.           if ((syntax & RE_BK_PLUS_QM)
  5261.               || (syntax & RE_LIMITED_OPS))
  5262.             goto normal_char;
  5263.  
  5264.         handle_plus:
  5265.         case '*':
  5266.           /* If there is no previous pattern... */
  5267.           if (pointless_if_repeated (*last_expression, params))
  5268.             {
  5269.               if (syntax & RE_CONTEXT_INVALID_OPS)
  5270.                 return REG_BADRPT;
  5271.               else if (!(syntax & RE_CONTEXT_INDEP_OPS))
  5272.                 goto normal_char;
  5273.             }
  5274.  
  5275.           {
  5276.             /* 1 means zero (many) matches is allowed.  */
  5277.             char zero_times_ok = 0, many_times_ok = 0;
  5278.  
  5279.             /* If there is a sequence of repetition chars, collapse it
  5280.                down to just one (the right one).  We can't combine
  5281.                interval operators with these because of, e.g., `a{2}*',
  5282.                which should only match an even number of `a's.  */
  5283.  
  5284.             for (;;)
  5285.               {
  5286.                 zero_times_ok |= c != '+';
  5287.                 many_times_ok |= c != '?';
  5288.  
  5289.                 if (p == pend)
  5290.                   break;
  5291.  
  5292.                 PATFETCH (c);
  5293.  
  5294.                 if (c == '*'
  5295.                     || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
  5296.                   ;
  5297.  
  5298.                 else if (syntax & RE_BK_PLUS_QM  &&  c == '\\')
  5299.                   {
  5300.                     if (p == pend) return REG_EESCAPE;
  5301.  
  5302.                     PATFETCH (c1);
  5303.                     if (!(c1 == '+' || c1 == '?'))
  5304.                       {
  5305.                         PATUNFETCH;
  5306.                         PATUNFETCH;
  5307.                         break;
  5308.                       }
  5309.  
  5310.                     c = c1;
  5311.                   }
  5312.                 else
  5313.                   {
  5314.                     PATUNFETCH;
  5315.                     break;
  5316.                   }
  5317.  
  5318.                 /* If we get here, we found another repeat character.  */
  5319.                }
  5320.  
  5321.             /* Star, etc. applied to an empty pattern is equivalent
  5322.                to an empty pattern.  */
  5323.             if (!last_expression)
  5324.               break;
  5325.  
  5326.         /* Now we know whether or not zero matches is allowed
  5327.          * and also whether or not two or more matches is allowed.
  5328.          */
  5329.  
  5330.         {
  5331.           struct rexp_node * inner_exp = *last_expression;
  5332.           int need_sync = 0;
  5333.  
  5334.           if (many_times_ok
  5335.           && has_non_idempotent_epsilon_path (&rxb->rx,
  5336.                               inner_exp, params))
  5337.         {
  5338.           struct rexp_node * pusher
  5339.             = rx_mk_r_side_effect (&rxb->rx,
  5340.                        (rx_side_effect)re_se_pushpos);
  5341.           struct rexp_node * checker
  5342.             = rx_mk_r_side_effect (&rxb->rx,
  5343.                        (rx_side_effect)re_se_chkpos);
  5344.           struct rexp_node * pushback
  5345.             = rx_mk_r_side_effect (&rxb->rx,
  5346.                        (rx_side_effect)re_se_pushback);
  5347.           rx_Bitset cs = rx_cset (&rxb->rx);
  5348.           struct rexp_node * lit_t = rx_mk_r_cset (&rxb->rx, cs);
  5349.           struct rexp_node * fake_state
  5350.             = rx_mk_r_concat (&rxb->rx, pushback, lit_t);
  5351.           struct rexp_node * phase2
  5352.             = rx_mk_r_concat (&rxb->rx, checker, fake_state);
  5353.           struct rexp_node * popper
  5354.             = rx_mk_r_side_effect (&rxb->rx,
  5355.                        (rx_side_effect)re_se_poppos);
  5356.           struct rexp_node * star
  5357.             = rx_mk_r_2phase_star (&rxb->rx, inner_exp, phase2);
  5358.           struct rexp_node * a
  5359.             = rx_mk_r_concat (&rxb->rx, pusher, star);
  5360.           struct rexp_node * whole_thing
  5361.             = rx_mk_r_concat (&rxb->rx, a, popper);
  5362.           if (!(pusher && star && pushback && lit_t && fake_state
  5363.             && lit_t && phase2 && checker && popper
  5364.             && a && whole_thing))
  5365.             return REG_ESPACE;
  5366.           RX_bitset_enjoin (cs, 't');
  5367.           *last_expression = whole_thing;
  5368.         }
  5369.           else
  5370.         {
  5371.           struct rexp_node * star =
  5372.             (many_times_ok ? rx_mk_r_star : rx_mk_r_opt)
  5373.               (&rxb->rx, *last_expression);
  5374.           if (!star)
  5375.             return REG_ESPACE;
  5376.           *last_expression = star;
  5377.           need_sync = has_any_se (&rxb->rx, *last_expression);
  5378.         }
  5379.           if (!zero_times_ok)
  5380.         {
  5381.           struct rexp_node * concat
  5382.             = rx_mk_r_concat (&rxb->rx, inner_exp,
  5383.                       rx_copy_rexp (&rxb->rx,
  5384.                             *last_expression));
  5385.           if (!concat)
  5386.             return REG_ESPACE;
  5387.           *last_expression = concat;
  5388.         }
  5389.           if (need_sync)
  5390.         {
  5391.           int sync_se = paramc;
  5392.           params = (params
  5393.                 ? ((struct re_se_params *)
  5394.                    realloc (params,
  5395.                     sizeof (*params) * (1 + paramc)))
  5396.                 : ((struct re_se_params *)
  5397.                    malloc (sizeof (*params))));
  5398.           if (!params)
  5399.             return REG_ESPACE;
  5400.           ++paramc;
  5401.           params [sync_se].se = re_se_tv;
  5402.           side = (rx_side_effect)sync_se;
  5403.           goto add_side_effect;
  5404.         }
  5405.         }
  5406.         /* The old regex.c used to optimize `.*\n'.  
  5407.          * Maybe rx should too?
  5408.          */
  5409.       }
  5410.       break;
  5411.  
  5412.  
  5413.     case '.':
  5414.       {
  5415.         rx_Bitset cs = rx_cset (&rxb->rx);
  5416.         struct rexp_node * n = rx_mk_r_cset (&rxb->rx, cs);
  5417.         if (!(cs && n))
  5418.           return REG_ESPACE;
  5419.  
  5420.         rx_bitset_universe (rxb->rx.local_cset_size, cs);
  5421.         if (!(rxb->syntax & RE_DOT_NEWLINE))
  5422.           RX_bitset_remove (cs, '\n');
  5423.         if (!(rxb->syntax & RE_DOT_NOT_NULL))
  5424.           RX_bitset_remove (cs, 0);
  5425.  
  5426.         append = n;
  5427.         goto append_node;
  5428.         break;
  5429.       }
  5430.  
  5431.  
  5432.         case '[':
  5433.       if (p == pend) return REG_EBRACK;
  5434.           {
  5435.             boolean had_char_class = false;
  5436.         rx_Bitset cs = rx_cset (&rxb->rx);
  5437.         struct rexp_node * node = rx_mk_r_cset (&rxb->rx, cs);
  5438.         int is_inverted = *p == '^';
  5439.         
  5440.         if (!(node && cs))
  5441.           return REG_ESPACE;
  5442.         
  5443.         /* This branch of the switch is normally exited with
  5444.          *`goto append_node'
  5445.          */
  5446.         append = node;
  5447.         
  5448.             if (is_inverted)
  5449.           p++;
  5450.         
  5451.             /* Remember the first position in the bracket expression.  */
  5452.             p1 = p;
  5453.         
  5454.             /* Read in characters and ranges, setting map bits.  */
  5455.             for (;;)
  5456.               {
  5457.                 if (p == pend) return REG_EBRACK;
  5458.         
  5459.                 PATFETCH (c);
  5460.         
  5461.                 /* \ might escape characters inside [...] and [^...].  */
  5462.                 if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
  5463.                   {
  5464.                     if (p == pend) return REG_EESCAPE;
  5465.             
  5466.                     PATFETCH (c1);
  5467.             {
  5468.               rx_Bitset it = inverse_translation (rxb, 
  5469.                               validate_inv_tr,
  5470.                               inverse_translate,
  5471.                               translate,
  5472.                               c1);
  5473.               rx_bitset_union (rxb->rx.local_cset_size, cs, it);
  5474.             }
  5475.                     continue;
  5476.                   }
  5477.         
  5478.                 /* Could be the end of the bracket expression.  If it's
  5479.                    not (i.e., when the bracket expression is `[]' so
  5480.                    far), the ']' character bit gets set way below.  */
  5481.                 if (c == ']' && p != p1 + 1)
  5482.                   goto finalize_class_and_append;
  5483.         
  5484.                 /* Look ahead to see if it's a range when the last thing
  5485.                    was a character class.  */
  5486.                 if (had_char_class && c == '-' && *p != ']')
  5487.                   return REG_ERANGE;
  5488.         
  5489.                 /* Look ahead to see if it's a range when the last thing
  5490.                    was a character: if this is a hyphen not at the
  5491.                    beginning or the end of a list, then it's the range
  5492.                    operator.  */
  5493.                 if (c == '-' 
  5494.                     && !(p - 2 >= pattern && p[-2] == '[') 
  5495.                     && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
  5496.                     && *p != ']')
  5497.                   {
  5498.                     reg_errcode_t ret
  5499.                       = compile_range (rxb, cs, &p, pend, translate, syntax,
  5500.                        inverse_translate, validate_inv_tr);
  5501.                     if (ret != REG_NOERROR) return ret;
  5502.                   }
  5503.         
  5504.                 else if (p[0] == '-' && p[1] != ']')
  5505.                   { /* This handles ranges made up of characters only.  */
  5506.                     reg_errcode_t ret;
  5507.             
  5508.             /* Move past the `-'.  */
  5509.                     PATFETCH (c1);
  5510.                     
  5511.                     ret = compile_range (rxb, cs, &p, pend, translate, syntax,
  5512.                      inverse_translate, validate_inv_tr);
  5513.                     if (ret != REG_NOERROR) return ret;
  5514.                   }
  5515.         
  5516.                 /* See if we're at the beginning of a possible character
  5517.                    class.  */
  5518.         
  5519.         else if ((syntax & RE_CHAR_CLASSES)
  5520.              && (c == '[') && (*p == ':'))
  5521.                   {
  5522.                     char str[CHAR_CLASS_MAX_LENGTH + 1];
  5523.             
  5524.                     PATFETCH (c);
  5525.                     c1 = 0;
  5526.             
  5527.                     /* If pattern is `[[:'.  */
  5528.                     if (p == pend) return REG_EBRACK;
  5529.             
  5530.                     for (;;)
  5531.                       {
  5532.                         PATFETCH (c);
  5533.                         if (c == ':' || c == ']' || p == pend
  5534.                             || c1 == CHAR_CLASS_MAX_LENGTH)
  5535.               break;
  5536.                         str[c1++] = c;
  5537.                       }
  5538.                     str[c1] = '\0';
  5539.             
  5540.                     /* If isn't a word bracketed by `[:' and:`]':
  5541.                        undo the ending character, the letters, and leave 
  5542.                        the leading `:' and `[' (but set bits for them).  */
  5543.                     if (c == ':' && *p == ']')
  5544.                       {
  5545.                         int ch;
  5546.                         boolean is_alnum = !strcmp (str, "alnum");
  5547.                         boolean is_alpha = !strcmp (str, "alpha");
  5548.                         boolean is_blank = !strcmp (str, "blank");
  5549.                         boolean is_cntrl = !strcmp (str, "cntrl");
  5550.                         boolean is_digit = !strcmp (str, "digit");
  5551.                         boolean is_graph = !strcmp (str, "graph");
  5552.                         boolean is_lower = !strcmp (str, "lower");
  5553.                         boolean is_print = !strcmp (str, "print");
  5554.                         boolean is_punct = !strcmp (str, "punct");
  5555.                         boolean is_space = !strcmp (str, "space");
  5556.                         boolean is_upper = !strcmp (str, "upper");
  5557.                         boolean is_xdigit = !strcmp (str, "xdigit");
  5558.                         
  5559.                         if (!IS_CHAR_CLASS (str)) return REG_ECTYPE;
  5560.             
  5561.                         /* Throw away the ] at the end of the character
  5562.                            class.  */
  5563.                         PATFETCH (c);                    
  5564.             
  5565.                         if (p == pend) return REG_EBRACK;
  5566.             
  5567.                         for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
  5568.                           {
  5569.                             if (   (is_alnum  && isalnum (ch))
  5570.                                 || (is_alpha  && isalpha (ch))
  5571.                                 || (is_blank  && isblank (ch))
  5572.                                 || (is_cntrl  && iscntrl (ch))
  5573.                                 || (is_digit  && isdigit (ch))
  5574.                                 || (is_graph  && isgraph (ch))
  5575.                                 || (is_lower  && islower (ch))
  5576.                                 || (is_print  && isprint (ch))
  5577.                                 || (is_punct  && ispunct (ch))
  5578.                                 || (is_space  && isspace (ch))
  5579.                                 || (is_upper  && isupper (ch))
  5580.                                 || (is_xdigit && isxdigit (ch)))
  5581.                   {
  5582.                 rx_Bitset it =
  5583.                   inverse_translation (rxb, 
  5584.                                validate_inv_tr,
  5585.                                inverse_translate,
  5586.                                translate,
  5587.                                ch);
  5588.                 rx_bitset_union (rxb->rx.local_cset_size,
  5589.                          cs, it);
  5590.                   }
  5591.                           }
  5592.                         had_char_class = true;
  5593.                       }
  5594.                     else
  5595.                       {
  5596.                         c1++;
  5597.                         while (c1--)    
  5598.                           PATUNFETCH;
  5599.             {
  5600.               rx_Bitset it =
  5601.                 inverse_translation (rxb, 
  5602.                          validate_inv_tr,
  5603.                          inverse_translate,
  5604.                          translate,
  5605.                          '[');
  5606.               rx_bitset_union (rxb->rx.local_cset_size,
  5607.                        cs, it);
  5608.             }
  5609.             {
  5610.               rx_Bitset it =
  5611.                 inverse_translation (rxb, 
  5612.                          validate_inv_tr,
  5613.                          inverse_translate,
  5614.                          translate,
  5615.                          ':');
  5616.               rx_bitset_union (rxb->rx.local_cset_size,
  5617.                        cs, it);
  5618.             }
  5619.                         had_char_class = false;
  5620.                       }
  5621.                   }
  5622.                 else
  5623.                   {
  5624.                     had_char_class = false;
  5625.             {
  5626.               rx_Bitset it = inverse_translation (rxb, 
  5627.                               validate_inv_tr,
  5628.                               inverse_translate,
  5629.                               translate,
  5630.                               c);
  5631.               rx_bitset_union (rxb->rx.local_cset_size, cs, it);
  5632.             }
  5633.                   }
  5634.               }
  5635.  
  5636.       finalize_class_and_append:
  5637.         if (is_inverted)
  5638.           {
  5639.         rx_bitset_complement (rxb->rx.local_cset_size, cs);
  5640.         if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
  5641.           RX_bitset_remove (cs, '\n');
  5642.           }
  5643.         goto append_node;
  5644.           }
  5645.           break;
  5646.  
  5647.  
  5648.     case '(':
  5649.           if (syntax & RE_NO_BK_PARENS)
  5650.             goto handle_open;
  5651.           else
  5652.             goto normal_char;
  5653.  
  5654.  
  5655.         case ')':
  5656.           if (syntax & RE_NO_BK_PARENS)
  5657.             goto handle_close;
  5658.           else
  5659.             goto normal_char;
  5660.  
  5661.  
  5662.         case '\n':
  5663.           if (syntax & RE_NEWLINE_ALT)
  5664.             goto handle_alt;
  5665.           else
  5666.             goto normal_char;
  5667.  
  5668.  
  5669.     case '|':
  5670.           if (syntax & RE_NO_BK_VBAR)
  5671.             goto handle_alt;
  5672.           else
  5673.             goto normal_char;
  5674.  
  5675.  
  5676.         case '{':
  5677.       if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
  5678.         goto handle_interval;
  5679.       else
  5680.         goto normal_char;
  5681.  
  5682.  
  5683.         case '\\':
  5684.           if (p == pend) return REG_EESCAPE;
  5685.  
  5686.           /* Do not translate the character after the \, so that we can
  5687.              distinguish, e.g., \B from \b, even if we normally would
  5688.              translate, e.g., B to b.  */
  5689.           PATFETCH_RAW (c);
  5690.  
  5691.           switch (c)
  5692.             {
  5693.             case '(':
  5694.               if (syntax & RE_NO_BK_PARENS)
  5695.                 goto normal_backslash;
  5696.  
  5697.             handle_open:
  5698.               rxb->re_nsub++;
  5699.               regnum++;
  5700.               if (COMPILE_STACK_FULL)
  5701.                 { 
  5702.                   RETALLOC (compile_stack.stack, compile_stack.size << 1,
  5703.                             compile_stack_elt_t);
  5704.                   if (compile_stack.stack == 0) return REG_ESPACE;
  5705.  
  5706.                   compile_stack.size <<= 1;
  5707.                 }
  5708.  
  5709.           if (*last_expression)
  5710.         {
  5711.           struct rexp_node * concat
  5712.             = rx_mk_r_concat (&rxb->rx, *last_expression, 0);
  5713.           if (!concat)
  5714.             return REG_ESPACE;
  5715.           *last_expression = concat;
  5716.           last_expression = &concat->params.pair.right;
  5717.         }
  5718.  
  5719.               /*
  5720.            * These are the values to restore when we hit end of this
  5721.                * group.  
  5722.            */
  5723.           COMPILE_STACK_TOP.top_expression = top_expression;
  5724.           COMPILE_STACK_TOP.last_expression = last_expression;
  5725.               COMPILE_STACK_TOP.regnum = regnum;
  5726.           
  5727.               compile_stack.avail++;
  5728.           
  5729.           top_expression = last_expression;
  5730.           break;
  5731.  
  5732.  
  5733.             case ')':
  5734.               if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
  5735.  
  5736.             handle_close:
  5737.               /* See similar code for backslashed left paren above.  */
  5738.               if (COMPILE_STACK_EMPTY)
  5739.                 if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
  5740.                   goto normal_char;
  5741.                 else
  5742.                   return REG_ERPAREN;
  5743.  
  5744.               /* Since we just checked for an empty stack above, this
  5745.                  ``can't happen''.  */
  5746.  
  5747.               {
  5748.                 /* We don't just want to restore into `regnum', because
  5749.                    later groups should continue to be numbered higher,
  5750.                    as in `(ab)c(de)' -- the second group is #2.  */
  5751.                 regnum_t this_group_regnum;
  5752.         struct rexp_node ** inner = top_expression;
  5753.  
  5754.                 compile_stack.avail--;
  5755.         top_expression = COMPILE_STACK_TOP.top_expression;
  5756.         last_expression = COMPILE_STACK_TOP.last_expression;
  5757.                 this_group_regnum = COMPILE_STACK_TOP.regnum;
  5758.         {
  5759.           int left_se = paramc;
  5760.           int right_se = paramc + 1;
  5761.  
  5762.           params = (params
  5763.                 ? ((struct re_se_params *)
  5764.                    realloc (params,
  5765.                     (paramc + 2) * sizeof (params[0])))
  5766.                 : ((struct re_se_params *)
  5767.                    malloc (2 * sizeof (params[0]))));
  5768.           if (!params)
  5769.             return REG_ESPACE;
  5770.           paramc += 2;
  5771.  
  5772.           params[left_se].se = re_se_lparen;
  5773.           params[left_se].op1 = this_group_regnum;
  5774.           params[right_se].se = re_se_rparen;
  5775.           params[right_se].op1 = this_group_regnum;
  5776.           {
  5777.             struct rexp_node * left
  5778.               = rx_mk_r_side_effect (&rxb->rx,
  5779.                          (rx_side_effect)left_se);
  5780.             struct rexp_node * right
  5781.               = rx_mk_r_side_effect (&rxb->rx,
  5782.                          (rx_side_effect)right_se);
  5783.             struct rexp_node * c1
  5784.               = (*inner
  5785.              ? rx_mk_r_concat (&rxb->rx, left, *inner) : left);
  5786.             struct rexp_node * c2
  5787.               = rx_mk_r_concat (&rxb->rx, c1, right);
  5788.             if (!(left && right && c1 && c2))
  5789.               return REG_ESPACE;
  5790.             *inner = c2;
  5791.           }
  5792.         }
  5793.         break;
  5794.           }
  5795.  
  5796.             case '|':                    /* `\|'.  */
  5797.               if ((syntax & RE_LIMITED_OPS) || (syntax & RE_NO_BK_VBAR))
  5798.                 goto normal_backslash;
  5799.             handle_alt:
  5800.               if (syntax & RE_LIMITED_OPS)
  5801.                 goto normal_char;
  5802.  
  5803.           {
  5804.         struct rexp_node * alt
  5805.           = rx_mk_r_alternate (&rxb->rx, *top_expression, 0);
  5806.         if (!alt)
  5807.           return REG_ESPACE;
  5808.         *top_expression = alt;
  5809.         last_expression = &alt->params.pair.right;
  5810.         {
  5811.           int sync_se = paramc;
  5812.  
  5813.           params = (params
  5814.                 ? ((struct re_se_params *)
  5815.                    realloc (params,
  5816.                     (paramc + 1) * sizeof (params[0])))
  5817.                 : ((struct re_se_params *)
  5818.                    malloc (sizeof (params[0]))));
  5819.           if (!params)
  5820.             return REG_ESPACE;
  5821.           ++paramc;
  5822.  
  5823.           params[sync_se].se = re_se_tv;
  5824.           {
  5825.             struct rexp_node * sync
  5826.               = rx_mk_r_side_effect (&rxb->rx,
  5827.                          (rx_side_effect)sync_se);
  5828.             struct rexp_node * conc
  5829.               = rx_mk_r_concat (&rxb->rx, sync, 0);
  5830.  
  5831.             if (!sync || !conc)
  5832.               return REG_ESPACE;
  5833.  
  5834.             *last_expression = conc;
  5835.             last_expression = &conc->params.pair.right;
  5836.           }
  5837.         }
  5838.           }
  5839.               break;
  5840.  
  5841.  
  5842.             case '{': 
  5843.               /* If \{ is a literal.  */
  5844.               if (!(syntax & RE_INTERVALS)
  5845.                      /* If we're at `\{' and it's not the open-interval 
  5846.                         operator.  */
  5847.                   || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
  5848.                   || (p - 2 == pattern  &&  p == pend))
  5849.                 goto normal_backslash;
  5850.  
  5851.             handle_interval:
  5852.               {
  5853.                 /* If got here, then the syntax allows intervals.  */
  5854.  
  5855.                 /* At least (most) this many matches must be made.  */
  5856.                 int lower_bound = -1, upper_bound = -1;
  5857.  
  5858.                 beg_interval = p - 1;
  5859.  
  5860.                 if (p == pend)
  5861.                   {
  5862.                     if (syntax & RE_NO_BK_BRACES)
  5863.                       goto unfetch_interval;
  5864.                     else
  5865.                       return REG_EBRACE;
  5866.                   }
  5867.  
  5868.                 GET_UNSIGNED_NUMBER (lower_bound);
  5869.  
  5870.                 if (c == ',')
  5871.                   {
  5872.                     GET_UNSIGNED_NUMBER (upper_bound);
  5873.                     if (upper_bound < 0) upper_bound = RE_DUP_MAX;
  5874.                   }
  5875.                 else
  5876.                   /* Interval such as `{1}' => match exactly once. */
  5877.                   upper_bound = lower_bound;
  5878.  
  5879.                 if (lower_bound < 0 || upper_bound > RE_DUP_MAX
  5880.                     || lower_bound > upper_bound)
  5881.                   {
  5882.                     if (syntax & RE_NO_BK_BRACES)
  5883.                       goto unfetch_interval;
  5884.                     else 
  5885.                       return REG_BADBR;
  5886.                   }
  5887.  
  5888.                 if (!(syntax & RE_NO_BK_BRACES)) 
  5889.                   {
  5890.                     if (c != '\\') return REG_EBRACE;
  5891.                     PATFETCH (c);
  5892.                   }
  5893.  
  5894.                 if (c != '}')
  5895.                   {
  5896.                     if (syntax & RE_NO_BK_BRACES)
  5897.                       goto unfetch_interval;
  5898.                     else 
  5899.                       return REG_BADBR;
  5900.                   }
  5901.  
  5902.                 /* We just parsed a valid interval.  */
  5903.  
  5904.                 /* If it's invalid to have no preceding re.  */
  5905.                 if (pointless_if_repeated (*last_expression, params))
  5906.                   {
  5907.                     if (syntax & RE_CONTEXT_INVALID_OPS)
  5908.                       return REG_BADRPT;
  5909.                     else if (!(syntax & RE_CONTEXT_INDEP_OPS))
  5910.                       goto unfetch_interval;
  5911.             /* was: else laststart = b; */
  5912.                   }
  5913.  
  5914.                 /* If the upper bound is zero, don't want to iterate
  5915.                  * at all.
  5916.          */
  5917.                  if (upper_bound == 0)
  5918.            {
  5919.              if (*last_expression)
  5920.                {
  5921.              rx_free_rexp (&rxb->rx, *last_expression);
  5922.              *last_expression = 0;
  5923.                }
  5924.            }
  5925.         else
  5926.           /* Otherwise, we have a nontrivial interval. */
  5927.           {
  5928.             int iter_se = paramc;
  5929.             int end_se = paramc + 1;
  5930.             params = (params
  5931.                   ? ((struct re_se_params *)
  5932.                  realloc (params,
  5933.                       sizeof (*params) * (2 + paramc)))
  5934.                   : ((struct re_se_params *)
  5935.                  malloc (2 * sizeof (*params))));
  5936.             if (!params)
  5937.               return REG_ESPACE;
  5938.             paramc += 2;
  5939.             params [iter_se].se = re_se_iter;
  5940.             params [iter_se].op1 = lower_bound;
  5941.             params[iter_se].op2 = upper_bound;
  5942.  
  5943.             params[end_se].se = re_se_end_iter;
  5944.             params[end_se].op1 = lower_bound;
  5945.             params[end_se].op2 = upper_bound;
  5946.             {
  5947.               struct rexp_node * push0
  5948.             = rx_mk_r_side_effect (&rxb->rx,
  5949.                            (rx_side_effect)re_se_push0);
  5950.               struct rexp_node * start_one_iter
  5951.             = rx_mk_r_side_effect (&rxb->rx,
  5952.                            (rx_side_effect)iter_se);
  5953.               struct rexp_node * phase1
  5954.             = rx_mk_r_concat (&rxb->rx, start_one_iter,
  5955.                       *last_expression);
  5956.               struct rexp_node * pushback
  5957.             = rx_mk_r_side_effect (&rxb->rx,
  5958.                            (rx_side_effect)re_se_pushback);
  5959.               rx_Bitset cs = rx_cset (&rxb->rx);
  5960.               struct rexp_node * lit_t
  5961.             = rx_mk_r_cset (&rxb->rx, cs);
  5962.               struct rexp_node * phase2
  5963.             = rx_mk_r_concat (&rxb->rx, pushback, lit_t);
  5964.               struct rexp_node * loop
  5965.             = rx_mk_r_2phase_star (&rxb->rx, phase1, phase2);
  5966.               struct rexp_node * push_n_loop
  5967.             = rx_mk_r_concat (&rxb->rx, push0, loop);
  5968.               struct rexp_node * final_test
  5969.             = rx_mk_r_side_effect (&rxb->rx,
  5970.                            (rx_side_effect)end_se);
  5971.               struct rexp_node * full_exp
  5972.             = rx_mk_r_concat (&rxb->rx, push_n_loop, final_test);
  5973.  
  5974.               if (!(push0 && start_one_iter && phase1
  5975.                 && pushback && lit_t && phase2
  5976.                 && loop && push_n_loop && final_test && full_exp))
  5977.             return REG_ESPACE;
  5978.  
  5979.               RX_bitset_enjoin(cs, 't');
  5980.  
  5981.               *last_expression = full_exp;
  5982.             }
  5983.           }
  5984.                 beg_interval = 0;
  5985.               }
  5986.               break;
  5987.  
  5988.             unfetch_interval:
  5989.               /* If an invalid interval, match the characters as literals.  */
  5990.                p = beg_interval;
  5991.                beg_interval = NULL;
  5992.  
  5993.                /* normal_char and normal_backslash need `c'.  */
  5994.                PATFETCH (c);    
  5995.  
  5996.                if (!(syntax & RE_NO_BK_BRACES))
  5997.                  {
  5998.                    if (p > pattern  &&  p[-1] == '\\')
  5999.                      goto normal_backslash;
  6000.                  }
  6001.                goto normal_char;
  6002.  
  6003. #ifdef emacs
  6004.             /* There is no way to specify the before_dot and after_dot
  6005.                operators.  rms says this is ok.  --karl  */
  6006.             case '=':
  6007.           side = at_dot;
  6008.           goto add_side_effect;
  6009.               break;
  6010.  
  6011.             case 's':
  6012.         case 'S':
  6013.           {
  6014.         rx_Bitset cs = cset (&rxb->rx);
  6015.         struct rexp_node * set = rx_mk_r_cset (&rxb->rx, cs);
  6016.         if (!(cs && set))
  6017.           return REG_ESPACE;
  6018.         if (c == 'S')
  6019.           rx_bitset_universe (rxb->rx.local_cset_size, cs);
  6020.  
  6021.         PATFETCH (c);
  6022.         {
  6023.           int x;
  6024.           char code = syntax_spec_code (c);
  6025.           for (x = 0; x < 256; ++x)
  6026.             {
  6027.               
  6028.               if (SYNTAX (x) & code)
  6029.             {
  6030.               rx_Bitset it =
  6031.                 inverse_translation (rxb, validate_inv_tr,
  6032.                          inverse_translate,
  6033.                          translate, x);
  6034.               rx_bitset_xor (rxb->rx.local_cset_size, cs, it);
  6035.             }
  6036.             }
  6037.         }
  6038.         goto append_node;
  6039.           }
  6040.               break;
  6041. #endif /* emacs */
  6042.  
  6043.  
  6044.             case 'w':
  6045.             case 'W':
  6046.           {
  6047.         rx_Bitset cs = rx_cset (&rxb->rx);
  6048.         struct rexp_node * n = (cs ? rx_mk_r_cset (&rxb->rx, cs) : 0);
  6049.         if (!(cs && n))
  6050.           return REG_ESPACE;
  6051.         if (c == 'W')
  6052.           rx_bitset_universe (rxb->rx.local_cset_size ,cs);
  6053.         {
  6054.           int x;
  6055.           for (x = rxb->rx.local_cset_size - 1; x > 0; --x)
  6056.             if (re_syntax_table[x] & Sword)
  6057.               RX_bitset_toggle (cs, x);
  6058.         }
  6059.         append = n;
  6060.         goto append_node;
  6061.           }
  6062.               break;
  6063.  
  6064. /* With a little extra work, some of these side effects could be optimized
  6065.  * away (basicly by looking at what we already know about the surrounding
  6066.  * chars).  
  6067.  */
  6068.             case '<':
  6069.           side = (rx_side_effect)re_se_wordbeg;
  6070.           goto add_side_effect;
  6071.               break;
  6072.  
  6073.             case '>':
  6074.               side = (rx_side_effect)re_se_wordend;
  6075.           goto add_side_effect;
  6076.               break;
  6077.  
  6078.             case 'b':
  6079.               side = (rx_side_effect)re_se_wordbound;
  6080.           goto add_side_effect;
  6081.               break;
  6082.  
  6083.             case 'B':
  6084.               side = (rx_side_effect)re_se_notwordbound;
  6085.           goto add_side_effect;
  6086.               break;
  6087.  
  6088.             case '`':
  6089.           side = (rx_side_effect)re_se_begbuf;
  6090.           goto add_side_effect;
  6091.           break;
  6092.           
  6093.             case '\'':
  6094.           side = (rx_side_effect)re_se_endbuf;
  6095.           goto add_side_effect;
  6096.               break;
  6097.  
  6098.         add_side_effect:
  6099.           {
  6100.         struct rexp_node * se
  6101.           = rx_mk_r_side_effect (&rxb->rx, side);
  6102.         if (!se)
  6103.           return REG_ESPACE;
  6104.         append = se;
  6105.         goto append_node;
  6106.           }
  6107.           break;
  6108.  
  6109.             case '1': case '2': case '3': case '4': case '5':
  6110.             case '6': case '7': case '8': case '9':
  6111.               if (syntax & RE_NO_BK_REFS)
  6112.                 goto normal_char;
  6113.  
  6114.               c1 = c - '0';
  6115.  
  6116.               if (c1 > regnum)
  6117.                 return REG_ESUBREG;
  6118.  
  6119.               /* Can't back reference to a subexpression if inside of it.  */
  6120.               if (group_in_compile_stack (compile_stack, c1))
  6121.                 goto normal_char;
  6122.           {
  6123.         int backref_se = paramc;
  6124.         params = (params
  6125.               ? ((struct re_se_params *)
  6126.                  realloc (params,
  6127.                       sizeof (*params) * (1 + paramc)))
  6128.               : ((struct re_se_params *)
  6129.                  malloc (sizeof (*params))));
  6130.         if (!params)
  6131.           return REG_ESPACE;
  6132.         ++paramc;
  6133.         params[backref_se].se = re_se_backref;
  6134.         params[backref_se].op1 = c1;
  6135.         side = (rx_side_effect)backref_se;
  6136.         goto add_side_effect;
  6137.           }
  6138.               break;
  6139.  
  6140.             case '+':
  6141.             case '?':
  6142.               if (syntax & RE_BK_PLUS_QM)
  6143.                 goto handle_plus;
  6144.               else
  6145.                 goto normal_backslash;
  6146.  
  6147.             default:
  6148.             normal_backslash:
  6149.               /* You might think it would be useful for \ to mean
  6150.                  not to translate; but if we don't translate it
  6151.                  it will never match anything.  */
  6152.               c = TRANSLATE (c);
  6153.               goto normal_char;
  6154.             }
  6155.           break;
  6156.  
  6157.  
  6158.     default:
  6159.         /* Expects the character in `c'.  */
  6160.     normal_char:
  6161.         {
  6162.           rx_Bitset cs = rx_cset(&rxb->rx);
  6163.           struct rexp_node * match = rx_mk_r_cset (&rxb->rx, cs);
  6164.           rx_Bitset it;
  6165.           if (!(cs && match))
  6166.         return REG_ESPACE;
  6167.           it = inverse_translation (rxb, validate_inv_tr,
  6168.                     inverse_translate, translate, c);
  6169.           rx_bitset_union (CHAR_SET_SIZE, cs, it);
  6170.           append = match;
  6171.  
  6172.         append_node:
  6173.           /* This genericly appends the rexp APPEND to *LAST_EXPRESSION
  6174.            * and then parses the next character normally.
  6175.            */
  6176.           if (*last_expression)
  6177.         {
  6178.           struct rexp_node * concat
  6179.             = rx_mk_r_concat (&rxb->rx, *last_expression, append);
  6180.           if (!concat)
  6181.             return REG_ESPACE;
  6182.           *last_expression = concat;
  6183.           last_expression = &concat->params.pair.right;
  6184.         }
  6185.           else
  6186.         *last_expression = append;
  6187.         }
  6188.     } /* switch (c) */
  6189.     } /* while p != pend */
  6190.  
  6191.   
  6192.   {
  6193.     int win_se = paramc;
  6194.     params = (params
  6195.           ? ((struct re_se_params *)
  6196.          realloc (params,
  6197.               sizeof (*params) * (1 + paramc)))
  6198.           : ((struct re_se_params *)
  6199.          malloc (sizeof (*params))));
  6200.     if (!params)
  6201.       return REG_ESPACE;
  6202.     ++paramc;
  6203.     params[win_se].se = re_se_win;
  6204.     {
  6205.       struct rexp_node * se
  6206.     = rx_mk_r_side_effect (&rxb->rx, (rx_side_effect)win_se);
  6207.       struct rexp_node * concat
  6208.     = rx_mk_r_concat (&rxb->rx, rexp, se);
  6209.       if (!(se && concat))
  6210.     return REG_ESPACE;
  6211.       rexp = concat;
  6212.     }
  6213.   }
  6214.  
  6215.  
  6216.   /* Through the pattern now.  */
  6217.  
  6218.   if (!COMPILE_STACK_EMPTY) 
  6219.     return REG_EPAREN;
  6220.  
  6221.       free (compile_stack.stack);
  6222.  
  6223.   orig_rexp = rexp;
  6224. #ifdef RX_DEBUG
  6225.   if (rx_debug_compile)
  6226.     {
  6227.       dbug_rxb = rxb;
  6228.       fputs ("\n\nCompiling ", stdout);
  6229.       fwrite (pattern, 1, size, stdout);
  6230.       fputs (":\n", stdout);
  6231.       rxb->se_params = params;
  6232.       print_rexp (&rxb->rx, orig_rexp, 2, re_seprint, stdout);
  6233.     }
  6234. #endif
  6235.   {
  6236.     rx_Bitset cs = rx_cset(&rxb->rx);
  6237.     rx_Bitset cs2 = rx_cset(&rxb->rx);
  6238.     char * se_map = (char *) alloca (paramc);
  6239.     struct rexp_node * new_rexp = 0;
  6240.  
  6241.  
  6242.     bzero (se_map, paramc);
  6243.     find_backrefs (se_map, rexp, params);
  6244.     fewer_side_effects =
  6245.       remove_unecessary_side_effects (&rxb->rx, se_map,
  6246.                       rx_copy_rexp (&rxb->rx, rexp), params);
  6247.  
  6248.     speed_up_alt (&rxb->rx, rexp, 0);
  6249.     speed_up_alt (&rxb->rx, fewer_side_effects, 1);
  6250.  
  6251.     {
  6252.       char * syntax_parens = rxb->syntax_parens;
  6253.       if (syntax_parens == (char *)0x1)
  6254.     rexp = remove_unecessary_side_effects
  6255.       (&rxb->rx, se_map, rexp, params);
  6256.       else if (syntax_parens)
  6257.     {
  6258.       int x;
  6259.       for (x = 0; x < paramc; ++x)
  6260.         if ((   (params[x].se == re_se_lparen)
  6261.          || (params[x].se == re_se_rparen))
  6262.         && (!syntax_parens [params[x].op1]))
  6263.           se_map [x] = 1;
  6264.       rexp = remove_unecessary_side_effects
  6265.         (&rxb->rx, se_map, rexp, params);
  6266.     }
  6267.     }
  6268.  
  6269.     /* At least one more optimization would be nice to have here but i ran out 
  6270.      * of time.  The idea would be to delay side effects.  
  6271.      * For examle, `(abc)' is the same thing as `abc()' except that the
  6272.      * left paren is offset by 3 (which we know at compile time).
  6273.      * (In this comment, write that second pattern `abc(:3:)' 
  6274.      * where `(:3:' is a syntactic unit.)
  6275.      *
  6276.      * Trickier:  `(abc|defg)'  is the same as `(abc(:3:|defg(:4:))'
  6277.      * (The paren nesting may be hard to follow -- that's an alternation
  6278.      *    of `abc(:3:' and `defg(:4:' inside (purely syntactic) parens
  6279.      *  followed by the closing paren from the original expression.)
  6280.      *
  6281.      * Neither the expression tree representation nor the the nfa make
  6282.      * this very easy to write. :(
  6283.      */
  6284.  
  6285.   /* What we compile is different than what the parser returns.
  6286.    * Suppose the parser returns expression R.
  6287.    * Let R' be R with unnecessary register assignments removed 
  6288.    * (see REMOVE_UNECESSARY_SIDE_EFFECTS, above).
  6289.    *
  6290.    * What we will compile is the expression:
  6291.    *
  6292.    *    m{try}R{win}\|s{try}R'{win}
  6293.    *
  6294.    * {try} and {win} denote side effect epsilons (see EXPLORE_FUTURE).
  6295.    * 
  6296.    * When trying a match, we insert an `m' at the beginning of the 
  6297.    * string if the user wants registers to be filled, `s' if not.
  6298.    */
  6299.     new_rexp =
  6300.       rx_mk_r_alternate
  6301.     (&rxb->rx,
  6302.      rx_mk_r_concat (&rxb->rx, rx_mk_r_cset (&rxb->rx, cs2), rexp),
  6303.      rx_mk_r_concat (&rxb->rx,
  6304.              rx_mk_r_cset (&rxb->rx, cs), fewer_side_effects));
  6305.  
  6306.     if (!(new_rexp && cs && cs2))
  6307.       return REG_ESPACE;
  6308.     RX_bitset_enjoin (cs2, '\0'); /* prefixed to the rexp used for matching. */
  6309.     RX_bitset_enjoin (cs, '\1'); /* prefixed to the rexp used for searching. */
  6310.     rexp = new_rexp;
  6311.   }
  6312.  
  6313. #ifdef RX_DEBUG
  6314.   if (rx_debug_compile)
  6315.     {
  6316.       fputs ("\n...which is compiled as:\n", stdout);
  6317.       print_rexp (&rxb->rx, rexp, 2, re_seprint, stdout);
  6318.     }
  6319. #endif
  6320.   {
  6321.     struct rx_nfa_state *start = 0;
  6322.     struct rx_nfa_state *end = 0;
  6323.  
  6324.     if (!rx_build_nfa (&rxb->rx, rexp, &start, &end))
  6325.       return REG_ESPACE;    /*  */
  6326.     else
  6327.       {
  6328.     void * mem = (void *)rxb->buffer;
  6329.     unsigned long size = rxb->allocated;
  6330.     int start_id;
  6331.     char * perm_mem;
  6332.     int iterator_size = paramc * sizeof (params[0]);
  6333.  
  6334.     end->is_final = 1;
  6335.     start->is_start = 1;
  6336.     rx_name_nfa_states (&rxb->rx);
  6337.     start_id = start->id;
  6338. #ifdef RX_DEBUG
  6339.     if (rx_debug_compile)
  6340.       {
  6341.         fputs ("...giving the NFA: \n", stdout);
  6342.         dbug_rxb = rxb;
  6343.         print_nfa (&rxb->rx, rxb->rx.nfa_states, re_seprint, stdout);
  6344.       }
  6345. #endif
  6346.     if (!rx_eclose_nfa (&rxb->rx))
  6347.       return REG_ESPACE;
  6348.     else
  6349.       {
  6350.         rx_delete_epsilon_transitions (&rxb->rx);
  6351.         
  6352.         /* For compatability reasons, we need to shove the
  6353.          * compiled nfa into one chunk of malloced memory.
  6354.          */
  6355.         rxb->rx.reserved = (   sizeof (params[0]) * paramc
  6356.                 +  rx_sizeof_bitset (rxb->rx.local_cset_size));
  6357. #ifdef RX_DEBUG
  6358.         if (rx_debug_compile)
  6359.           {
  6360.         dbug_rxb = rxb;
  6361.         fputs ("...which cooks down (uncompactified) to: \n", stdout);
  6362.         print_nfa (&rxb->rx, rxb->rx.nfa_states, re_seprint, stdout);
  6363.           }
  6364. #endif
  6365.         if (!rx_compactify_nfa (&rxb->rx, &mem, &size))
  6366.           return REG_ESPACE;
  6367.         rxb->buffer = mem;
  6368.         rxb->allocated = size;
  6369.         rxb->rx.buffer = mem;
  6370.         rxb->rx.allocated = size;
  6371.         perm_mem = ((char *)rxb->rx.buffer
  6372.             + rxb->rx.allocated - rxb->rx.reserved);
  6373.         rxb->se_params = ((struct re_se_params *)perm_mem);
  6374.         bcopy (params, rxb->se_params, iterator_size);
  6375.         perm_mem += iterator_size;
  6376.         rxb->fastset = (rx_Bitset) perm_mem;
  6377.         rxb->start = rx_id_to_nfa_state (&rxb->rx, start_id);
  6378.       }
  6379.     rx_bitset_null (rxb->rx.local_cset_size, rxb->fastset);
  6380.     rxb->can_match_empty = compute_fastset (rxb, orig_rexp);
  6381.     rxb->match_regs_on_stack =
  6382.       registers_on_stack (rxb, orig_rexp, 0, params); 
  6383.     rxb->search_regs_on_stack =
  6384.       registers_on_stack (rxb, fewer_side_effects, 0, params);
  6385.     if (rxb->can_match_empty)
  6386.       rx_bitset_universe (rxb->rx.local_cset_size, rxb->fastset);
  6387.     rxb->is_anchored = is_anchored (orig_rexp, (rx_side_effect) re_se_hat);
  6388.     rxb->begbuf_only = is_anchored (orig_rexp,
  6389.                     (rx_side_effect) re_se_begbuf);
  6390.       }
  6391.     rx_free_rexp (&rxb->rx, rexp);
  6392.     if (params)
  6393.       free (params);
  6394. #ifdef RX_DEBUG
  6395.     if (rx_debug_compile)
  6396.       {
  6397.     dbug_rxb = rxb;
  6398.     fputs ("...which cooks down to: \n", stdout);
  6399.     print_nfa (&rxb->rx, rxb->rx.nfa_states, re_seprint, stdout);
  6400.       }
  6401. #endif
  6402.   }
  6403.   return REG_NOERROR;
  6404. }
  6405.  
  6406.  
  6407.  
  6408. /* This table gives an error message for each of the error codes listed
  6409.    in regex.h.  Obviously the order here has to be same as there.  */
  6410.  
  6411. const char * rx_error_msg[] =
  6412. { 0,                        /* REG_NOERROR */
  6413.     "No match",                    /* REG_NOMATCH */
  6414.     "Invalid regular expression",        /* REG_BADPAT */
  6415.     "Invalid collation character",        /* REG_ECOLLATE */
  6416.     "Invalid character class name",        /* REG_ECTYPE */
  6417.     "Trailing backslash",            /* REG_EESCAPE */
  6418.     "Invalid back reference",            /* REG_ESUBREG */
  6419.     "Unmatched [ or [^",            /* REG_EBRACK */
  6420.     "Unmatched ( or \\(",            /* REG_EPAREN */
  6421.     "Unmatched \\{",                /* REG_EBRACE */
  6422.     "Invalid content of \\{\\}",        /* REG_BADBR */
  6423.     "Invalid range end",            /* REG_ERANGE */
  6424.     "Memory exhausted",                /* REG_ESPACE */
  6425.     "Invalid preceding regular expression",    /* REG_BADRPT */
  6426.     "Premature end of regular expression",    /* REG_EEND */
  6427.     "Regular expression too big",        /* REG_ESIZE */
  6428.     "Unmatched ) or \\)",            /* REG_ERPAREN */
  6429. };
  6430.  
  6431.  
  6432.  
  6433. /* Test if at very beginning or at very end of the virtual concatenation
  6434.  *  of `string1' and `string2'.  If only one string, it's `string2'.  
  6435.  */
  6436.  
  6437. #define AT_STRINGS_BEG() \
  6438.   (string1 \
  6439.    ? ((tst_half == 0) \
  6440.       && ((unsigned char *)tst_pos == (unsigned char *)string1 - 1)) \
  6441.    : ((unsigned char *)tst_pos == (unsigned char *)string2 - 1))
  6442.  
  6443. #define AT_STRINGS_END() \
  6444.   (string2 \
  6445.    ? ((tst_half == 1) \
  6446.       && ((unsigned char *)tst_pos \
  6447.       == ((unsigned char *)string2 + size2 - 1))) \
  6448.    : ((unsigned char *)tst_pos == ((unsigned char *)string1 + size1 - 1)))
  6449.  
  6450. /* Test if D points to a character which is word-constituent.  We have
  6451.  * two special cases to check for: if past the end of string1, look at
  6452.  * the first character in string2; and if before the beginning of
  6453.  * string2, look at the last character in string1.
  6454.  *
  6455.  * Assumes `string1' exists, so use in conjunction with AT_STRINGS_BEG ().  
  6456.  */
  6457. #define LETTER_P(d)                            \
  6458.   (SYNTAX ((string2 && (tst_half == 0)                    \
  6459.         && ((d) == ((unsigned char *)string1 + size1)))        \
  6460.        ? *(unsigned char *)string2                    \
  6461.        : ((string1 && (tst_half == 1)                \
  6462.            && ((d) == (unsigned char *)string2 - 1))        \
  6463.           ? *((unsigned char *)string1 + size1 - 1)            \
  6464.           : *(d))) == Sword)
  6465.  
  6466. /* Test if the character at D and the one after D differ with respect
  6467.  * to being word-constituent.  
  6468.  */
  6469. #define AT_WORD_BOUNDARY(d)                        \
  6470.   (AT_STRINGS_BEG () || AT_STRINGS_END () || LETTER_P (d) != LETTER_P (d + 1))
  6471.  
  6472.  
  6473. static char slowmap [256] =
  6474. {
  6475.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6476.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6477.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6478.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6479.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6480.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6481.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6482.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6483.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6484.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6485.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6486.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6487.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6488.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6489.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6490.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  6491. };
  6492.  
  6493. #ifdef __STDC__
  6494. static void
  6495. rx_blow_up_fastmap (struct re_pattern_buffer * rxb)
  6496. #else
  6497. static void
  6498. rx_blow_up_fastmap (rxb)
  6499.      struct re_pattern_buffer * rxb;
  6500. #endif
  6501. {
  6502.   int x;
  6503.   for (x = 0; x < 256; ++x)    /* &&&& 3.6 % */
  6504.     rxb->fastmap [x] = !!RX_bitset_member (rxb->fastset, x);
  6505.   rxb->fastmap_accurate = 1;
  6506. }
  6507.  
  6508.  
  6509.  
  6510.  
  6511. struct stack_chunk
  6512. {
  6513.   struct stack_chunk * next_chunk;
  6514.   int bytes_left;
  6515.   char * sp;
  6516. };
  6517.  
  6518. #define PUSH(CHUNK_VAR,BYTES)   \
  6519.   if (!CHUNK_VAR || (CHUNK_VAR->bytes_left < (BYTES)))  \
  6520.     {                    \
  6521.       struct stack_chunk * new_chunk;    \
  6522.       if (free_chunks)            \
  6523.     {                \
  6524.       new_chunk = free_chunks;    \
  6525.       free_chunks = free_chunks->next_chunk; \
  6526.     }                \
  6527.       else                \
  6528.     {                \
  6529.       new_chunk = (struct stack_chunk *)alloca (chunk_bytes); \
  6530.       if (!new_chunk)        \
  6531.         {                \
  6532.           ret_val = 0;        \
  6533.           goto test_do_return;    \
  6534.         }                \
  6535.     }                \
  6536.       new_chunk->sp = (char *)new_chunk + sizeof (struct stack_chunk); \
  6537.       new_chunk->bytes_left = (chunk_bytes \
  6538.                    - (BYTES) \
  6539.                    - sizeof (struct stack_chunk)); \
  6540.       new_chunk->next_chunk = CHUNK_VAR; \
  6541.       CHUNK_VAR = new_chunk;        \
  6542.     } \
  6543.   else \
  6544.     (CHUNK_VAR->sp += (BYTES)), (CHUNK_VAR->bytes_left -= (BYTES))
  6545.  
  6546. #define POP(CHUNK_VAR,BYTES) \
  6547.   if (CHUNK_VAR->sp == ((char *)CHUNK_VAR + sizeof(*CHUNK_VAR))) \
  6548.     { \
  6549.       struct stack_chunk * new_chunk = CHUNK_VAR->next_chunk; \
  6550.       CHUNK_VAR->next_chunk = free_chunks; \
  6551.       free_chunks = CHUNK_VAR; \
  6552.       CHUNK_VAR = new_chunk; \
  6553.     } \
  6554.   else \
  6555.     (CHUNK_VAR->sp -= BYTES), (CHUNK_VAR->bytes_left += BYTES)
  6556.  
  6557. struct counter_frame
  6558. {
  6559.   int tag;
  6560.   int val;
  6561.   struct counter_frame * inherited_from; /* If this is a copy. */
  6562.   struct counter_frame * cdr;
  6563. };
  6564.  
  6565. struct backtrack_frame
  6566. {
  6567.   char * counter_stack_sp;
  6568.  
  6569.   /* A frame is used to save the matchers state when it crosses a 
  6570.    * backtracking point.  The `stk_' fields correspond to variables
  6571.    * in re_search_2 (just strip off thes `stk_').  They are documented
  6572.    * tere.
  6573.    */
  6574.   struct rx_superstate * stk_super;
  6575.   const unsigned char * stk_tst_pos;
  6576.   int stk_tst_half;
  6577.   unsigned int stk_c;
  6578.   const unsigned char * stk_tst_str_half;
  6579.   const unsigned char * stk_tst_end_half;
  6580.   int stk_last_l;
  6581.   int stk_last_r;
  6582.   int stk_test_ret;
  6583.  
  6584.   /* This is the list of options left to explore at the backtrack
  6585.    * point for which this frame was created. 
  6586.    */
  6587.   struct rx_distinct_future * df;
  6588.   struct rx_distinct_future * first_df;
  6589.  
  6590. #ifdef RX_DEBUG
  6591.    int stk_line_no;
  6592. #endif
  6593. };
  6594.  
  6595.  
  6596.  
  6597. #if !defined(REGEX_MALLOC) && !defined(__GNUC__)
  6598. #define RE_SEARCH_2_FN    inner_re_search_2
  6599. #else
  6600. #define RE_SEARCH_2_FN    re_search_2
  6601. #endif
  6602.  
  6603. #ifdef __STDC__
  6604. int
  6605. RE_SEARCH_2_FN (struct re_pattern_buffer *rxb,
  6606.         const char * string1, int size1,
  6607.         const char * string2, int size2,
  6608.         int startpos, int range,
  6609.         struct re_registers *regs,
  6610.         int stop)
  6611. #else
  6612. int
  6613. RE_SEARCH_2_FN (rxb,
  6614.         string1, size1, string2, size2, startpos, range, regs, stop)
  6615.      struct re_pattern_buffer *rxb;
  6616.      const char * string1;
  6617.      int size1;
  6618.      const char * string2;
  6619.      int size2;
  6620.      int startpos;
  6621.      int range;
  6622.      struct re_registers *regs;
  6623.      int stop;
  6624. #endif
  6625. {
  6626.   /* Two groups of registers are kept.  The group with the register state
  6627.    * of the current test match, and the group that holds the state at the end
  6628.    * of the best known match, if any.
  6629.    *
  6630.    * For some patterns, there may also be registers saved on the stack.
  6631.    */
  6632.   regoff_t * lparen = 0; /* scratch space for register returns */
  6633.   regoff_t * rparen = 0;
  6634.   regoff_t * best_lpspace = 0; /* in case the user doesn't want these */
  6635.   regoff_t * best_rpspace = 0; /* values, we still need space to store
  6636.                 * them.  Normally, this memoryis unused
  6637.                 * and the space pointed to by REGS is 
  6638.                 * used instead.
  6639.                 */
  6640.   
  6641.   int last_l;            /* Highest index of a valid lparen. */
  6642.   int last_r;            /* It's dual. */
  6643.  
  6644.   int * best_lparen;        /* This contains the best known register */
  6645.   int * best_rparen;        /* assignments. 
  6646.                  * This may point to the same mem as
  6647.                  * best_lpspace, or it might point to memory
  6648.                  * passed by the caller.
  6649.                  */
  6650.   int best_last_l;        /* best_last_l:best_lparen::last_l:lparen */
  6651.   int best_last_r;
  6652.   
  6653.   
  6654.  
  6655.   /* Figure the number of registers we may need for use in backreferences.
  6656.    * The number here includes an element for register zero.  
  6657.    */
  6658.   unsigned num_regs = rxb->re_nsub + 1;
  6659.  
  6660.   int total_size = size1 + size2;
  6661.  
  6662.  
  6663.   /***** INIT re_search_2 */
  6664.   
  6665.   /* Check for out-of-range STARTPOS.  */
  6666.   if ((startpos < 0) || (startpos > total_size))
  6667.     return -1;
  6668.  
  6669.   /* Fix up RANGE if it might eventually take us outside
  6670.    * the virtual concatenation of STRING1 and STRING2.
  6671.    */
  6672.   {
  6673.     int endpos = startpos + range;
  6674.     if (endpos < -1)
  6675.       range = (-1 - startpos);
  6676.     else if (endpos > total_size)
  6677.       range = total_size - startpos;
  6678.   }
  6679.  
  6680.   /* If the search isn't to be a backwards one, don't waste time in a
  6681.    * long search for a pattern that says it is anchored.
  6682.    */
  6683.   if (rxb->begbuf_only && (range > 0))
  6684.     {
  6685.       if (startpos > 0)
  6686.     return -1;
  6687.       else
  6688.     range = 1;
  6689.     }
  6690.  
  6691.   /* Then, decide whether to use internal or user-provided reg buffers. */
  6692.   if (!regs || rxb->no_sub)
  6693.     {
  6694.       best_lpspace = (regoff_t *)REGEX_ALLOCATE (num_regs * sizeof(regoff_t));
  6695.       best_rpspace = (regoff_t *)REGEX_ALLOCATE (num_regs * sizeof(regoff_t));
  6696.       best_lparen = best_lpspace;
  6697.       best_rparen = best_rpspace;
  6698.     }
  6699.   else
  6700.     {    
  6701.       /* Have the register data arrays been allocated?  */
  6702.       if (rxb->regs_allocated == REGS_UNALLOCATED)
  6703.     { /* No.  So allocate them with malloc.  We need one
  6704.          extra element beyond `num_regs' for the `-1' marker
  6705.          GNU code uses.  */
  6706.       regs->num_regs = MAX (RE_NREGS, rxb->re_nsub + 1);
  6707.       regs->start = TALLOC (regs->num_regs, regoff_t);
  6708.       regs->end = TALLOC (regs->num_regs, regoff_t);
  6709.       if (regs->start == 0 || regs->end == 0)
  6710.         return -2;
  6711.       rxb->regs_allocated = REGS_REALLOCATE;
  6712.     }
  6713.       else if (rxb->regs_allocated == REGS_REALLOCATE)
  6714.     { /* Yes.  If we need more elements than were already
  6715.          allocated, reallocate them.  If we need fewer, just
  6716.          leave it alone.  */
  6717.       if (regs->num_regs < num_regs + 1)
  6718.         {
  6719.           regs->num_regs = num_regs + 1;
  6720.           RETALLOC (regs->start, regs->num_regs, regoff_t);
  6721.           RETALLOC (regs->end, regs->num_regs, regoff_t);
  6722.           if (regs->start == 0 || regs->end == 0)
  6723.         return -2;
  6724.         }
  6725.     }
  6726.       else if (rxb->regs_allocated != REGS_FIXED)
  6727.     return -2;
  6728.  
  6729.       if (regs->num_regs < num_regs + 1)
  6730.     {
  6731.       best_lpspace = ((regoff_t *)
  6732.               REGEX_ALLOCATE (num_regs * sizeof(regoff_t)));
  6733.       best_rpspace = ((regoff_t *)
  6734.               REGEX_ALLOCATE (num_regs * sizeof(regoff_t)));
  6735.       best_lparen = best_lpspace;
  6736.       best_rparen = best_rpspace;
  6737.     }
  6738.       else
  6739.     {
  6740.       best_lparen = regs->start;
  6741.       best_rparen = regs->end;
  6742.     }
  6743.     }
  6744.   
  6745.   lparen = (regoff_t *) REGEX_ALLOCATE (num_regs * sizeof(regoff_t));
  6746.   rparen = (regoff_t *) REGEX_ALLOCATE (num_regs * sizeof(regoff_t)); 
  6747.   
  6748.   if (!(best_rparen && best_lparen && lparen && rparen))
  6749.     return -2;
  6750.   
  6751.   best_last_l = best_last_r = -1;
  6752.  
  6753.  
  6754.  
  6755.   /***** fastmap/search loop, initialization */
  6756.  
  6757.   /* This is the loop that scans using the fastmap, and sometimes tries to 
  6758.    * match. From this point on, don't return.  Instead, assign to ret_val
  6759.    * and goto fail.
  6760.    */
  6761.   {
  6762.     const char * translate = rxb->translate ? rxb->translate : id_translation;
  6763.  
  6764.     /** This is state associated with returning to the caller. */
  6765.  
  6766.     int ret_val = -1;
  6767.  
  6768.     /*   A sentinal is sometimes installed in the fastmap.  This records
  6769.      *   where so it can be removed before returning.
  6770.      */
  6771.     int fastmap_chr = -1;
  6772.     int fastmap_val;
  6773.  
  6774.     /** End of state associated with returning to the caller. */
  6775.  
  6776.     /** Start of variables associated with the fastmap based search: */
  6777.  
  6778.     char * fastmap = rxb->fastmap ? (char *)rxb->fastmap : (char *)slowmap;
  6779.     int search_direction;    /* 1 or -1 */
  6780.     int search_end;        /* first position to not try */
  6781.     int offset;            /* either size1 or 0 as string == string2 */
  6782.  
  6783.     /* The string-pair position of the fastmap/search loop: */
  6784.     const unsigned char * pos;    /* The current pos. */
  6785.     const unsigned char * string; /* The current string half. */
  6786.     const unsigned char * end;    /* End of current string. */
  6787.     int size;            /* Current string's size */
  6788.     int half;            /* 0 means string1, 1 means string2 */
  6789.  
  6790.     /** End of variables associated with the fastmap based search: */
  6791.  
  6792.  
  6793.     /** Start of variables associated with trying a match
  6794.      *  after the fastmap has found a plausible starting point.
  6795.      */
  6796.  
  6797.     struct rx_superstate * start_super = 0; /* The superNFA start state. */
  6798.  
  6799.     /*
  6800.      * Two nfa's were compiled.  
  6801.      * `0' is complete.
  6802.      * `1' faster but gets registers wrong and ends too soon.
  6803.      */
  6804.     int nfa_choice = ((regs && !rxb->least_subs) ? '\0' : '\1');
  6805.  
  6806.     const unsigned char * abs_end; /* Don't fetch a character from here. */
  6807.     int first_found;        /* If true, return after finding any match. */
  6808.  
  6809.     /** End of variables associated with trying a match. */
  6810.  
  6811.     /* Update the fastmap now if not correct already. 
  6812.      * When the regexp was compiled, the fastmap was computed
  6813.      * and stored in a bitset.  This expands the bitset into a
  6814.      * character array containing 1s and 0s.
  6815.      */
  6816.     if ((fastmap == rxb->fastmap) && !rxb->fastmap_accurate)
  6817.       rx_blow_up_fastmap (rxb);
  6818.  
  6819.     /* Now we build the starting state of the supernfa. */
  6820.     {
  6821.       struct rx_superset * start_contents;
  6822.       struct rx_nfa_state_set * start_nfa_set;
  6823.       
  6824.       /* We presume here that the nfa start state has only one
  6825.        * possible future with no side effects.  
  6826.        */
  6827.       start_nfa_set = rxb->start->futures->destset;
  6828.       if (   rxb->rx.start_set
  6829.       && (rxb->rx.start_set->starts_for == &rxb->rx))
  6830.     start_contents = rxb->rx.start_set;
  6831.       else
  6832.     {
  6833.       start_contents =
  6834.         rx_superstate_eclosure_union (&rxb->rx,
  6835.                       rx_superset_cons (&rxb->rx, 0, 0),
  6836.                       start_nfa_set);
  6837.       
  6838.       if (!start_contents)
  6839.         return -1;
  6840.  
  6841.       start_contents->starts_for = &rxb->rx;
  6842.       rxb->rx.start_set = start_contents;
  6843.     }
  6844.       if (   start_contents->superstate
  6845.       && (start_contents->superstate->rx_id == rxb->rx.rx_id))
  6846.     {
  6847.       start_super = start_contents->superstate;
  6848.       rx_lock_superstate (&rxb->rx, start_super);
  6849.     }
  6850.       else
  6851.     {
  6852.       rx_protect_superset (&rxb->rx, start_contents);
  6853.       
  6854.       start_super = rx_superstate (&rxb->rx, start_contents);
  6855.       if (!start_super)
  6856.         return -1;
  6857.       rx_lock_superstate (&rxb->rx, start_super);
  6858.       rx_release_superset (&rxb->rx, start_contents);
  6859.     }
  6860.     }
  6861.     
  6862.     /* This computes an upper bound on string addresses for use by
  6863.      * the match-test.
  6864.      */
  6865.     abs_end = ((const unsigned char *) ((stop <= size1)
  6866.                     ? string1 + stop
  6867.                     : string2 + stop - size1));
  6868.  
  6869.     /* We have the option to look for the best match or the first
  6870.      * one we can find.  If the user isn't asking for register information,
  6871.      * we don't need to find the best match.
  6872.      */
  6873.     first_found = !regs;
  6874.  
  6875.     /* Compute search_end & search_direction for the fastmap loop. */
  6876.     if (range >= 0)
  6877.       {
  6878.     search_end = MIN (size1 + size2, startpos + range) + 1;
  6879.     search_direction = 1;
  6880.       }
  6881.     else
  6882.       {
  6883.     search_end = MAX(-1, startpos + range);
  6884.     search_direction = -1;
  6885.       }
  6886.  
  6887.     /* The vacuous search always turns up nothing. */
  6888.     if ((search_direction == 1)
  6889.     ? (startpos > search_end)
  6890.     : (startpos < search_end))
  6891.       return -1;
  6892.  
  6893.     /* Set string/size/offset/end -- the state that tells the fastmap
  6894.      * loop which half of the string we're in.  Also set pos, which
  6895.      * is the addr of the current fastmap scan position.
  6896.      */
  6897.     if (!string2 || (startpos < size1))
  6898.       {
  6899.     string = (const unsigned char *)string1;
  6900.     size = size1;
  6901.     offset = 0;
  6902.     pos = (const unsigned char *)(string1 + startpos);
  6903.     half = 0;
  6904.     end = (const unsigned char *)MIN(string1 + size1, string1 + stop);
  6905.       }
  6906.     else
  6907.       {
  6908.     string = (const unsigned char *)string2;
  6909.     size = size2;
  6910.     offset = size1;
  6911.     pos = (const unsigned char *)(string2 + startpos - size1);
  6912.     half = 1;
  6913.     end = (const unsigned char *)MIN(string2 + size2,
  6914.                      string2 + stop - size1);
  6915.       }
  6916.  
  6917.  
  6918.  
  6919.  
  6920.     /***** fastmap/search loop,  body */
  6921.  
  6922.  
  6923.   init_fastmap_sentinal:
  6924.  
  6925.     /* For the sake of fast fastmapping, set a sentinal in the fastmap.
  6926.      * This sentinal will trap the fastmap loop when it reaches the last
  6927.      * valid character in a string half.
  6928.      *
  6929.      * This must be reset when the fastmap/search loop crosses a string 
  6930.      * boundry, and before returning to the caller.  So sometimes,
  6931.      * the fastmap loop is restarted with `continue', othertimes by
  6932.      * `goto init_fastmap_sentinal'.
  6933.      */
  6934.     if (size)
  6935.       {
  6936.     fastmap_chr = ((search_direction == 1)
  6937.                ? *(end - 1)
  6938.                : *string);
  6939.     fastmap_val = fastmap[fastmap_chr];
  6940.     fastmap[fastmap_chr] = 1;
  6941.       }
  6942.     else
  6943.       fastmap_chr = -1;
  6944.  
  6945.     do
  6946.       {
  6947.     /* If we haven't reached the end of a string half, and if the
  6948.      * pattern can't match the empty string, then the fastmap 
  6949.      * optimization applies.  This conditional scans using the 
  6950.      * fastmap -- stoping when a string half ends, or when a 
  6951.      * plausible starting point for a match is found.
  6952.      * It updates HIT_BOUND to tell which case occured.
  6953.      */
  6954.     if (pos == end)
  6955.       goto fastmap_hit_bound;
  6956.     else
  6957.       {
  6958.         if (search_direction == 1)
  6959.           {
  6960.         if (fastmap_val)
  6961.           {
  6962.             for (;;)
  6963.               {
  6964.             while (!fastmap[*pos])
  6965.               ++pos;
  6966.             goto commence_a_matchin;
  6967.               }
  6968.           }
  6969.         else
  6970.           {
  6971.             for (;;)
  6972.               {
  6973.             while (!fastmap[*pos])
  6974.               ++pos;
  6975.             if (*pos != fastmap_chr)
  6976.               goto commence_a_matchin;
  6977.             else 
  6978.               {
  6979.                 ++pos;
  6980.                 if (pos == end)
  6981.                   goto fastmap_hit_bound;
  6982.               }
  6983.               }
  6984.           }
  6985.           }
  6986.         else
  6987.           {
  6988.         const unsigned char * bound = string - 1;
  6989.         for (;;)
  6990.           {
  6991.             while (!fastmap[*pos])
  6992.               --pos;
  6993.             if ((*pos != fastmap_chr) || fastmap_val)
  6994.               goto commence_a_matchin;
  6995.             else 
  6996.               {
  6997.             --pos;
  6998.             if (pos == bound)
  6999.               goto fastmap_hit_bound;
  7000.               }
  7001.           }
  7002.           }
  7003.       }
  7004.     
  7005.       fastmap_hit_bound:
  7006.     {
  7007.       /* If we hit a bound, it may simply be time to switch sides
  7008.        * between strings.
  7009.        */
  7010.       if ((search_direction == 1) && string2 && (half == 0))
  7011.         {
  7012.           string = (const unsigned char *)string2;
  7013.           size = size2;
  7014.           offset = size1;
  7015.           half = 1;
  7016.           end = (const unsigned char *)MIN(string2 + size2,
  7017.                            string2 + stop - size1);
  7018.           startpos = size1;
  7019.           pos = (const unsigned char *)string2;
  7020.           goto init_fastmap_sentinal;
  7021.         }
  7022.       else if (   string1
  7023.            && (search_direction == -1)
  7024.            && (half == 1))
  7025.         {
  7026.           string = (const unsigned char *)string1;
  7027.           size = size1;
  7028.           offset = 0;
  7029.           end = (const unsigned char *)string1 + size1;
  7030.           half = 0;
  7031.           startpos = size1 - 1;
  7032.           pos = (const unsigned char *)string1 + size1 - 1;
  7033.           goto init_fastmap_sentinal;
  7034.         }
  7035.       /* ...not a string split, simply no more string. 
  7036.        *
  7037.        * When searching backward, running out of string
  7038.        * is reason to quit.
  7039.        */
  7040.       else if (search_direction == -1)
  7041.         goto finish;
  7042.       
  7043.       /* ...when searching forward, we allow the possibility
  7044.        * of an (empty) match after the last character in the
  7045.        * virtual string.  So, fall through to the matcher
  7046.        */
  7047.     }
  7048.  
  7049.  
  7050.       commence_a_matchin:
  7051.  
  7052.     /***** fastmap/search loop body
  7053.      *          test for a match that begins at pos
  7054.      */
  7055.  
  7056.     /* Now the fastmap loop has brought us to a plausible 
  7057.      * starting point for a match.  So, it's time to run the
  7058.      * NFA and see if a match occured.
  7059.      */
  7060.  
  7061.     startpos = pos - string + offset;
  7062.     if (startpos == search_end)
  7063.       goto finish;
  7064.     
  7065.     last_l = last_r = 0;
  7066.     lparen[0] = startpos;    /* We know match-begin for this test... */
  7067.  
  7068.     /* The test matcher is essentially a recursive function
  7069.      * that does an exhaustive run of the superNFA at the 
  7070.      * test position.  For performance, that function has 
  7071.      * been in-lined by hand.
  7072.      */
  7073.  
  7074. #undef OF
  7075. #ifndef HAVE_GNUC_LABELS
  7076. #define OF(A,B)    A
  7077. #else
  7078. #define OF(A,B)    A: B
  7079.       static void * rx_labels_instruction_table[] =
  7080.         {
  7081.           [rx_backtrack_point] &&backtrack_point,
  7082.           [rx_backtrack] &&backtrack,
  7083.           [rx_do_side_effects] &&do_side_effects,
  7084.           [rx_cache_miss] &&cache_miss,
  7085.           [rx_next_char] 0,
  7086.           [rx_error_inx] 0
  7087.         };
  7088. #endif
  7089.     {      
  7090.       /* The current superNFA position of the matcher. */
  7091.       struct rx_superstate * super = start_super;
  7092.       
  7093.       /* The matcher interprets a series of instruction frames.
  7094.        * This is the `instruction counter' for the interpretation.
  7095.        */
  7096.       struct rx_inx * ifr;
  7097.       
  7098.       /* We insert a ghost character in the string to prime
  7099.        * the nfa.  tst_pos, tst_str_half, and tst_end_half
  7100.        * keep track of the test-match position and string-half.
  7101.        */
  7102.       const unsigned char * tst_pos = pos - 1;
  7103.       int tst_half = half;
  7104.       unsigned char c = nfa_choice;
  7105.       
  7106.       const unsigned char * tst_str_half = string;
  7107.       const unsigned char * tst_end_half = end;
  7108.       
  7109.       struct stack_chunk * counter_stack = 0;
  7110.       struct stack_chunk * backtrack_stack = 0;
  7111.       int backtrack_frame_bytes =
  7112.         (sizeof (struct backtrack_frame)
  7113.          + (rxb->match_regs_on_stack
  7114.         ? sizeof (regoff_t) * (num_regs + 1) * 2
  7115.         : 0));
  7116.       int chunk_bytes = backtrack_frame_bytes * 64;
  7117.       struct stack_chunk * free_chunks = 0;
  7118.  
  7119. #ifdef RX_DEBUG
  7120.       int backtrack_depth = 0;
  7121. #endif
  7122.  
  7123.       /* To return from this function, set test_ret and 
  7124.        * `goto test_do_return'.
  7125.        *
  7126.        * Possible return values are:
  7127.        *     1   --- end of string while the superNFA is still going
  7128.        *     0   --- internal error (out of memory)
  7129.        *    -1   --- search completed by reaching the superNFA fail state
  7130.        *    -2   --- a match was found, maybe not the longest.
  7131.        *
  7132.        * When the search is complete (-1), best_last_r indicates whether
  7133.        * a match was found.
  7134.        *
  7135.        * -2 is return only if first_found is non-zero.
  7136.        *
  7137.        * if first_found is non-zero, a return of -1 indicates no match,
  7138.        * otherwise, best_last_r has to be checked.
  7139.        */
  7140.       int test_ret = -1;
  7141.       
  7142.       while (1)
  7143.         {
  7144.           int inx;
  7145. #ifdef RX_DEBUG
  7146.           /* There is a search tree with every node as set of deterministic
  7147.            * transitions in the super nfa.  For every branch of a 
  7148.            * backtrack point is an edge in the tree.
  7149.            * This counts up a pre-order of nodes in that tree.
  7150.            * It's saved on the search stack and printed when debugging. 
  7151.            */
  7152.           int line_no = 0;
  7153.           int lines_found = 0;
  7154. #endif
  7155.  
  7156.  
  7157.         top_of_cycle:
  7158.           /* A superstate is basicly a transition table, indexed by 
  7159.            * characters from the string being tested, and containing 
  7160.            * RX_INX structures.
  7161.            */
  7162.           ifr = &super->transitions [c];
  7163.           
  7164.         recurse_test_match:
  7165.           /* This is the point to which control is sent when the
  7166.            * test matcher recurses.  Before jumping here, some variables
  7167.            * need to be saved on the stack and setup for the recursion.
  7168.            */
  7169.  
  7170.         restart:
  7171.           /* Some instructions don't advance the matcher, but just
  7172.            * carry out some side effects and fetch a new instruction.
  7173.            * To dispatch that new instruction, `goto restart'.
  7174.            */
  7175.           
  7176.           {
  7177.         struct rx_inx * next_tr_table = (struct rx_inx *)ifr->data;
  7178.         struct rx_inx * this_tr_table = super->transitions;
  7179.         /* The fastest route through the loop is when the instruction 
  7180.          * is RX_NEXT_CHAR.  This case is detected when IFR->DATA
  7181.          * is non-zero.  In that case, it points to the next
  7182.          * superstate. 
  7183.          *
  7184.          * This allows us to not bother fetching the bytecode.
  7185.          */
  7186.         while (next_tr_table)
  7187.           {
  7188. #ifdef RX_DEBUG
  7189.             if (rx_debug_trace)
  7190.               {
  7191.             struct rx_superset * setp;
  7192.  
  7193.             fprintf (stderr, "%d %d>> re_next_char @ %d (%d)",
  7194.                  line_no,
  7195.                  backtrack_depth,
  7196.                  (tst_pos - tst_str_half
  7197.                   + (tst_half == 0
  7198.                      ? 0 : size1)), c);
  7199.             
  7200.             super =
  7201.               ((struct rx_superstate *)
  7202.                ((char *)this_tr_table
  7203.                 - ((unsigned long)
  7204.                    ((struct rx_superstate *)0)->transitions)));
  7205.  
  7206.             setp = super->contents;
  7207.             fprintf (stderr, "   superstet (rx=%d, &=%x: ",
  7208.                  rxb->rx.rx_id, setp);
  7209.             while (setp)
  7210.               {
  7211.                 fprintf (stderr, "%d ", setp->id);
  7212.                 setp = setp->cdr;
  7213.               }
  7214.             fprintf (stderr, "\n");
  7215.               }
  7216. #endif
  7217.             this_tr_table = next_tr_table;
  7218.             ++tst_pos;
  7219.             if (tst_pos == tst_end_half)
  7220.               {
  7221.             if (   (tst_pos != abs_end)
  7222.                 && string2
  7223.                 && half == 0)
  7224.               {
  7225.                 /* Here we are crossing the break 
  7226.                  * in a split string. 
  7227.                  */
  7228.                 tst_str_half = (const unsigned char *)string2;
  7229.                 tst_end_half = abs_end;
  7230.                 tst_pos = (const unsigned char *)string2;
  7231.                 tst_half = 1;
  7232.               }
  7233.             else
  7234.               {
  7235.                 test_ret = 1;
  7236.                 goto test_do_return;
  7237.               }
  7238.               }
  7239.             c = *tst_pos;
  7240.             ifr = this_tr_table + c;
  7241.             next_tr_table = (struct rx_inx *)ifr->data;
  7242.           }
  7243.         
  7244.         /* Here when we ran out cached next-char transitions. 
  7245.          * So, it will be necessary to do a more expensive
  7246.          * dispatch on the current instruction.  The superstate
  7247.          * pointer is allowed to become invalid during next-char
  7248.          * transitions -- now we must bring it up to date.
  7249.          */
  7250.         super =
  7251.           ((struct rx_superstate *)
  7252.            ((char *)this_tr_table
  7253.             - ((unsigned long)
  7254.                ((struct rx_superstate *)0)->transitions)));
  7255.           }
  7256.           
  7257.           /* We've encountered an instruction other than next-char.
  7258.            * Dispatch that instruction:
  7259.            */
  7260.           inx = (int)ifr->inx;
  7261. #ifdef HAVE_GNUC_LABELS
  7262.           goto *rx_labels_instruction_table[inx];
  7263. #endif
  7264. #ifdef RX_DEBUG
  7265.           if (rx_debug_trace)
  7266.         {
  7267.           struct rx_superset * setp = super->contents;
  7268.           
  7269.           fprintf (stderr, "%d %d>> %s @ %d (%d)", line_no,
  7270.                backtrack_depth,
  7271.                inx_names[inx],
  7272.                (tst_pos - tst_str_half
  7273.                 + (tst_half == 0 ? 0 : size1)), c);
  7274.           
  7275.           fprintf (stderr, "   superstet (rx=%d, &=%x: ",
  7276.                rxb->rx.rx_id, setp);
  7277.           while (setp)
  7278.             {
  7279.               fprintf (stderr, "%d ", setp->id);
  7280.               setp = setp->cdr;
  7281.             }
  7282.           fprintf (stderr, "\n");
  7283.         }
  7284. #endif
  7285.           switch ((enum rx_opcode)inx)
  7286.         {
  7287.         case OF(rx_do_side_effects,do_side_effects):
  7288.  
  7289.           /*  RX_DO_SIDE_EFFECTS occurs when we cross epsilon 
  7290.            *  edges associated with parentheses, backreferencing, etc.
  7291.            */
  7292.           {
  7293.             struct rx_distinct_future * df =
  7294.               (struct rx_distinct_future *)ifr->data_2;
  7295.             struct rx_se_list * el = df->effects;
  7296.             /* Side effects come in lists.  This walks down
  7297.              * a list, dispatching.
  7298.              */
  7299.             while (el)
  7300.               {
  7301. #ifdef HAVE_GNUC_LABELS
  7302.             static void * se_labels[] =
  7303.               {
  7304.                 [-re_se_try] &&se_try,
  7305.                 [-re_se_pushback] &&se_pushback,
  7306.                 [-re_se_push0] &&se_push0,
  7307.                 [-re_se_pushpos] &&se_pushpos,
  7308.                 [-re_se_chkpos] &&se_chkpos,
  7309.                 [-re_se_poppos] &&se_poppos,
  7310. #ifdef emacs
  7311.                 [-re_se_at_dot] &&se_at_dot,
  7312.                 [-re_se_syntax] &&se_syntax,
  7313.                 [-re_se_not_syntax] &&se_not_syntax,
  7314. #endif
  7315.                 [-re_se_begbuf] &&se_begbuf,
  7316.                 [-re_se_hat] &&se_hat,
  7317.                 [-re_se_wordbeg] &&se_wordbeg,
  7318.                 [-re_se_wordbound] &&se_wordbound,
  7319.                 [-re_se_notwordbound] &&se_notwordbound,
  7320.                 [-re_se_wordend] &&se_wordend,
  7321.                 [-re_se_endbuf] &&se_endbuf,
  7322.                 [-re_se_dollar] &&se_dollar,
  7323.                 [-re_se_fail] &&se_fail,
  7324.               };
  7325.             static void * se_lables2[] =
  7326.               {
  7327.                 [re_se_win] &&se_win
  7328.                 [re_se_lparen] &&se_lparen,
  7329.                 [re_se_rparen] &&se_rparen,
  7330.                 [re_se_backref] &&se_backref,
  7331.                 [re_se_iter] &&se_iter,
  7332.                 [re_se_end_iter] &&se_end_iter,
  7333.                 [re_se_tv] &&se_tv
  7334.               };
  7335. #endif
  7336.             int effect = (int)el->car;
  7337.             if (effect < 0)
  7338.               {
  7339. #ifdef HAVE_GNUC_LABELS
  7340.                 goto *se_labels[-effect];
  7341. #endif
  7342. #ifdef RX_DEBUG
  7343.                 if (rx_debug_trace)
  7344.                   {
  7345.                 struct rx_superset * setp = super->contents;
  7346.                 
  7347.                 fprintf (stderr, "....%d %d>> %s\n", line_no,
  7348.                      backtrack_depth,
  7349.                      efnames[-effect]);
  7350.                   }
  7351. #endif
  7352.                 switch ((enum re_side_effects) effect)
  7353.                   {
  7354.                   case OF(re_se_pushback,se_pushback):
  7355.                 ifr = &df->future_frame;
  7356.                 if (!ifr->data)
  7357.                   {
  7358.                     struct rx_superstate * sup = super;
  7359.                     rx_lock_superstate (rx, sup);
  7360.                     if (!rx_handle_cache_miss (&rxb->rx,
  7361.                                    super, c,
  7362.                                    ifr->data_2))
  7363.                       {
  7364.                     rx_unlock_superstate (rx, sup);
  7365.                     test_ret = 0;
  7366.                     goto test_do_return;
  7367.                       }
  7368.                     rx_unlock_superstate (rx, sup);
  7369.                   }
  7370.                 /* --tst_pos; */
  7371.                 c = 't';
  7372.                 super
  7373.                   = ((struct rx_superstate *)
  7374.                      ((char *)ifr->data
  7375.                       - (long)(((struct rx_superstate *)0)
  7376.                            ->transitions)));
  7377.                 goto top_of_cycle;
  7378.                 break;
  7379.                   case OF(re_se_push0,se_push0):
  7380.                 {
  7381.                   struct counter_frame * old_cf
  7382.                      = (counter_stack
  7383.                     ? ((struct counter_frame *)
  7384.                        counter_stack->sp)
  7385.                     : 0);
  7386.                   struct counter_frame * cf;
  7387.                   PUSH (counter_stack,
  7388.                     sizeof (struct counter_frame));
  7389.                   cf = ((struct counter_frame *)
  7390.                     counter_stack->sp);
  7391.                   cf->tag = re_se_iter;
  7392.                   cf->val = 0;
  7393.                   cf->inherited_from = 0;
  7394.                   cf->cdr = old_cf;
  7395.                   break;
  7396.                 }
  7397.                   case OF(re_se_fail,se_fail):
  7398.                 goto test_do_return;
  7399.                   case OF(re_se_begbuf,se_begbuf):
  7400.                 if (!AT_STRINGS_BEG ())
  7401.                   goto test_do_return;
  7402.                 break;
  7403.                   case OF(re_se_endbuf,se_endbuf):
  7404.                 if (!AT_STRINGS_END ())
  7405.                   goto test_do_return;
  7406.                 break;
  7407.                   case OF(re_se_wordbeg,se_wordbeg):
  7408.                 if (   LETTER_P (tst_pos + 1)
  7409.                     && (   AT_STRINGS_BEG()
  7410.                     || !LETTER_P (tst_pos)))
  7411.                   break;
  7412.                 else
  7413.                   goto test_do_return;
  7414.                   case OF(re_se_wordend,se_wordend):
  7415.                 if (   !AT_STRINGS_BEG ()
  7416.                     && LETTER_P (tst_pos)
  7417.                     && (AT_STRINGS_END ()
  7418.                     || !LETTER_P (tst_pos + 1)))
  7419.                   break;
  7420.                 else
  7421.                   goto test_do_return;
  7422.                   case OF(re_se_wordbound,se_wordbound):
  7423.                 if (AT_WORD_BOUNDARY (tst_pos))
  7424.                   break;
  7425.                 else
  7426.                   goto test_do_return;
  7427.                   case OF(re_se_notwordbound,se_notwordbound):
  7428.                 if (!AT_WORD_BOUNDARY (tst_pos))
  7429.                   break;
  7430.                 else
  7431.                   goto test_do_return;
  7432.                   case OF(re_se_hat,se_hat):
  7433.                 if (AT_STRINGS_BEG ())
  7434.                   {
  7435.                     if (rxb->not_bol)
  7436.                       goto test_do_return;
  7437.                     else
  7438.                       break;
  7439.                   }
  7440.                 else
  7441.                   {
  7442.                     char pos_c = *tst_pos;
  7443.                     if (   (TRANSLATE (pos_c)
  7444.                         == TRANSLATE('\n'))
  7445.                     && rxb->newline_anchor)
  7446.                       break;
  7447.                     else
  7448.                       goto test_do_return;
  7449.                   }
  7450.                   case OF(re_se_dollar,se_dollar):
  7451.                 if (AT_STRINGS_END ())
  7452.                   {
  7453.                     if (rxb->not_eol)
  7454.                       goto test_do_return;
  7455.                     else
  7456.                       break;
  7457.                   }
  7458.                 else
  7459.                   {
  7460.                     const unsigned char * next_pos
  7461.                       = ((string2 && (tst_half == 0) &&
  7462.                       (tst_pos
  7463.                        == ((unsigned char *)
  7464.                            string1 + size1 - 1)))
  7465.                      ? (unsigned char *)string2
  7466.                      : tst_pos + 1);
  7467.                     
  7468.                     if (   (TRANSLATE (*next_pos)
  7469.                         == TRANSLATE ('\n'))
  7470.                     && rxb->newline_anchor)
  7471.                       break;
  7472.                     else
  7473.                       goto test_do_return;
  7474.                   }
  7475.                 
  7476.                   case OF(re_se_try,se_try):
  7477.                 /* This is the first side effect in every
  7478.                  * expression.
  7479.                  *
  7480.                  *  FOR NO GOOD REASON...get rid of it...
  7481.                  */
  7482.                 break;
  7483.  
  7484.                   case OF(re_se_pushpos,se_pushpos):
  7485.                 {
  7486.                   int urhere =
  7487.                     ((int)(tst_pos - tst_str_half)
  7488.                      + ((tst_half == 0) ? 0 : size1));
  7489.                   struct counter_frame * old_cf
  7490.                     = (counter_stack
  7491.                        ? ((struct counter_frame *)
  7492.                       counter_stack->sp)
  7493.                        : 0);
  7494.                   struct counter_frame * cf;
  7495.                   PUSH(counter_stack,
  7496.                        sizeof (struct counter_frame));
  7497.                   cf = ((struct counter_frame *)
  7498.                     counter_stack->sp);
  7499.                   cf->tag = re_se_pushpos;
  7500.                   cf->val = urhere;
  7501.                   cf->inherited_from = 0;
  7502.                   cf->cdr = old_cf;
  7503.                   break;
  7504.                 }
  7505.                 
  7506.                   case OF(re_se_chkpos,se_chkpos):
  7507.                 {
  7508.                   int urhere =
  7509.                     ((int)(tst_pos - tst_str_half)
  7510.                      + ((tst_half == 0) ? 0 : size1));
  7511.                   struct counter_frame * cf
  7512.                     = ((struct counter_frame *)
  7513.                        counter_stack->sp);
  7514.                   if (cf->val == urhere)
  7515.                     goto test_do_return;
  7516.                   cf->val = urhere;
  7517.                   break;
  7518.                 }
  7519.                 break;
  7520.  
  7521.                   case OF(re_se_poppos,se_poppos):
  7522.                 POP(counter_stack,
  7523.                     sizeof (struct counter_frame));
  7524.                 break;
  7525.                 
  7526.                 
  7527.                   case OF(re_se_at_dot,se_at_dot):
  7528.                   case OF(re_se_syntax,se_syntax):
  7529.                   case OF(re_se_not_syntax,se_not_syntax):
  7530. #ifdef emacs
  7531.                 this release lacks emacs support;
  7532.                 (coming soon);
  7533. #endif
  7534.                 break;
  7535.                   case re_se_win:
  7536.                   case re_se_lparen:
  7537.                   case re_se_rparen:
  7538.                   case re_se_backref:
  7539.                   case re_se_iter:
  7540.                   case re_se_end_iter:
  7541.                   case re_se_tv:
  7542.                   case re_floogle_flap:
  7543.                 ret_val = 0;
  7544.                 goto test_do_return;
  7545.                   }
  7546.               }
  7547.             else
  7548.               {
  7549. #ifdef HAVE_GNUC_LABELS
  7550.                 goto *se_lables2[(rxb->se_params [effect].se)];
  7551. #endif
  7552. #ifdef RX_DEBUG
  7553.               if (rx_debug_trace)
  7554.                 fprintf (stderr, "....%d %d>> %s %d %d\n", line_no,
  7555.                      backtrack_depth,
  7556.                      efnames2[rxb->se_params [effect].se],
  7557.                      rxb->se_params [effect].op1,
  7558.                      rxb->se_params [effect].op2);
  7559. #endif
  7560.                 switch (rxb->se_params [effect].se)
  7561.                   {
  7562.                   case OF(re_se_win,se_win):
  7563.                 /* This side effect indicates that we've 
  7564.                  * found a match, though not necessarily the 
  7565.                  * best match.  This is a fancy assignment to 
  7566.                  * register 0 unless the caller didn't 
  7567.                  * care about registers.  In which case,
  7568.                  * this stops the match.
  7569.                  */
  7570.                 {
  7571.                   int urhere =
  7572.                     ((int)(tst_pos - tst_str_half)
  7573.                      + ((tst_half == 0)
  7574.                     ? 0 : size1));
  7575.  
  7576.                   if (   (best_last_r < 0)
  7577.                       || (urhere + 1 > best_rparen[0]))
  7578.                     {
  7579.                       /* Record the best known and keep
  7580.                        * looking.
  7581.                        */
  7582.                       int x;
  7583.                       for (x = 0; x <= last_l; ++x)
  7584.                     best_lparen[x] = lparen[x];
  7585.                       best_last_l = last_l;
  7586.                       for (x = 0; x <= last_r; ++x)
  7587.                     best_rparen[x] = rparen[x];
  7588.                       best_rparen[0] = urhere + 1;
  7589.                       best_last_r = last_r;
  7590.                     }
  7591.                   /* If we're not reporting the match-length 
  7592.                    * or other register info, we need look no
  7593.                    * further.
  7594.                    */
  7595.                   if (first_found)
  7596.                     {
  7597.                       test_ret = -2;
  7598.                       goto test_do_return;
  7599.                     }
  7600.                 }
  7601.                 break;
  7602.                   case OF(re_se_lparen,se_lparen):
  7603.                 {
  7604.                   int urhere =
  7605.                     ((int)(tst_pos - tst_str_half)
  7606.                      + ((tst_half == 0) ? 0 : size1));
  7607.                   
  7608.                   int reg = rxb->se_params [effect].op1;
  7609. #if 0
  7610.                   if (reg > last_l)
  7611. #endif
  7612.                     {
  7613.                       lparen[reg] = urhere + 1;
  7614.                       /* In addition to making this assignment,
  7615.                        * we now know that lower numbered regs
  7616.                        * that haven't already been assigned,
  7617.                        * won't be.  We make sure they're
  7618.                        * filled with -1, so they can be
  7619.                        * recognized as unassigned.
  7620.                        */
  7621.                       if (last_l < reg)
  7622.                     while (++last_l < reg)
  7623.                       lparen[last_l] = -1;
  7624.                     }
  7625.                   break;
  7626.                 }
  7627.                 
  7628.                   case OF(re_se_rparen,se_rparen):
  7629.                 {
  7630.                   int urhere =
  7631.                     ((int)(tst_pos - tst_str_half)
  7632.                      + ((tst_half == 0) ? 0 : size1));
  7633.                   int reg = rxb->se_params [effect].op1;
  7634.                   rparen[reg] = urhere + 1;
  7635.                   if (last_r < reg)
  7636.                     {
  7637.                       while (++last_r < reg)
  7638.                     rparen[last_r] = -1;
  7639.                     }
  7640.                   break;
  7641.                 }
  7642.                 
  7643.                   case OF(re_se_backref,se_backref):
  7644.                 {
  7645.                   int reg = rxb->se_params [effect].op1;
  7646.                   if (reg > last_r || rparen[reg] < 0)
  7647.                     goto test_do_return;
  7648.                   {
  7649.                     /* fixme */
  7650.                     const unsigned char * there
  7651.                       = tst_str_half + lparen[reg];
  7652.                     const unsigned char * last
  7653.                       = tst_str_half + rparen[reg];
  7654.                     const unsigned char * here = tst_pos + 1;
  7655.  
  7656.                     if ((here == tst_end_half) && string2
  7657.                     && (tst_str_half
  7658.                         == (unsigned char *) string1)
  7659.                     && (tst_end_half != abs_end))
  7660.                       {
  7661.                     here = (unsigned char *)string2;
  7662.                     tst_end_half = abs_end;
  7663.                       }
  7664.                     
  7665.                     while (there < last && here < tst_end_half)    /* 4% */
  7666.                       if (TRANSLATE(*there) /* &&&& 6% */
  7667.                       != TRANSLATE(*here))
  7668.                     goto test_do_return;
  7669.                       else
  7670.                     {
  7671.                       ++there; ++here;
  7672.                       if ((here == tst_end_half) && string2
  7673.                           && (tst_str_half
  7674.                           == (unsigned char *)string1)
  7675.                           && (tst_end_half != abs_end))
  7676.                         {
  7677.                           here = (unsigned char *)string2;
  7678.                           tst_end_half = abs_end;
  7679.                           tst_half = 1;
  7680.                         }
  7681.                     }
  7682.                     if (there != last)
  7683.                       goto test_do_return;
  7684.                     tst_pos = here - 1;
  7685.                     if ((here == (unsigned char *)string2)
  7686.                     && (unsigned char *)string1)
  7687.                       {
  7688.                     tst_pos = ((unsigned char *)string1
  7689.                            + size1 - 1);
  7690.                     tst_end_half = tst_pos + 1;
  7691.                     tst_half = 0;
  7692.                       }
  7693.                   }
  7694.                   break;
  7695.                 }
  7696.                   case OF(re_se_iter,se_iter):
  7697.                 {
  7698.                   struct counter_frame * csp
  7699.                     = ((struct counter_frame *)
  7700.                        counter_stack->sp);
  7701.                   if (csp->val == rxb->se_params[effect].op2)
  7702.                     goto test_do_return;
  7703.                   else
  7704.                     ++csp->val;
  7705.                   break;
  7706.                 }
  7707.                   case OF(re_se_end_iter,se_end_iter):
  7708.                 {
  7709.                   struct counter_frame * csp
  7710.                     = ((struct counter_frame *)
  7711.                        counter_stack->sp);
  7712.                   if (csp->val < rxb->se_params[effect].op1)
  7713.                     goto test_do_return;
  7714.                   else
  7715.                     {
  7716.                       struct counter_frame * source = csp;
  7717.                       while (source->inherited_from)
  7718.                     source = source->inherited_from;
  7719.                       if (!source || !source->cdr)
  7720.                     {
  7721.                       POP(counter_stack,
  7722.                           sizeof(struct counter_frame));
  7723.                     }
  7724.                       else
  7725.                     {
  7726.                       source = source->cdr;
  7727.                       csp->val = source->val;
  7728.                       csp->tag = source->tag;
  7729.                       csp->cdr = 0;
  7730.                       csp->inherited_from = source;
  7731.                     }
  7732.                     }
  7733.                   break;
  7734.                 }
  7735.                   case OF(re_se_tv, se_tv):
  7736.                 /* is a noop */
  7737.                 break;
  7738.                   case re_se_try:
  7739.                   case re_se_pushback:
  7740.                   case re_se_push0:
  7741.                   case re_se_pushpos:
  7742.                   case re_se_chkpos:
  7743.                   case re_se_poppos:
  7744.                   case re_se_at_dot:
  7745.                   case re_se_syntax:
  7746.                   case re_se_not_syntax:
  7747.                   case re_se_begbuf:
  7748.                   case re_se_hat:
  7749.                   case re_se_wordbeg:
  7750.                   case re_se_wordbound:
  7751.                   case re_se_notwordbound:
  7752.                   case re_se_wordend:
  7753.                   case re_se_endbuf:
  7754.                   case re_se_dollar:
  7755.                   case re_se_fail:
  7756.                   case re_floogle_flap:
  7757.                 ret_val = 0;
  7758.                 goto test_do_return;
  7759.                   }
  7760.               }
  7761.             el = el->cdr;
  7762.               }
  7763.             /* Now the side effects are done,
  7764.              * so get the next instruction.
  7765.              * and move on.
  7766.              */
  7767.             ifr = &df->future_frame;
  7768.             goto restart;
  7769.           }
  7770.           
  7771.         case OF(rx_backtrack_point,backtrack_point):
  7772.           {
  7773.             /* A backtrack point indicates that we've reached a
  7774.              * non-determinism in the superstate NFA.  This is a
  7775.              * loop that exhaustively searches the possibilities.
  7776.              *
  7777.              * A backtracking strategy is used.  We keep track of what
  7778.              * registers are valid so we can erase side effects.
  7779.              *
  7780.              * First, make sure there is some stack space to hold 
  7781.              * our state.
  7782.              */
  7783.  
  7784.             struct backtrack_frame * bf;
  7785.  
  7786.             PUSH(backtrack_stack, backtrack_frame_bytes);
  7787. #ifdef RX_DEBUG
  7788.             ++backtrack_depth;
  7789. #endif
  7790.  
  7791.             bf = ((struct backtrack_frame *)
  7792.               backtrack_stack->sp);
  7793.             {
  7794.               bf->stk_super = super;
  7795.               /* We prevent the current superstate from being
  7796.                * deleted from the superstate cache.
  7797.                */
  7798.               rx_lock_superstate (&rxb->rx, super);
  7799.               bf->stk_tst_pos = tst_pos;
  7800. #ifdef RX_DEBUG
  7801.               bf->stk_line_no = line_no;
  7802. #endif
  7803.               bf->stk_tst_half = tst_half;
  7804.               bf->stk_c = c;
  7805.               bf->stk_tst_str_half = tst_str_half;
  7806.               bf->stk_tst_end_half = tst_end_half;
  7807.               bf->stk_last_l = last_l;
  7808.               bf->stk_last_r = last_r;
  7809.               bf->df = ((struct rx_super_edge *)ifr->data_2)->options;
  7810.               bf->first_df = bf->df;
  7811.               bf->counter_stack_sp = (counter_stack
  7812.                           ? counter_stack->sp
  7813.                           : 0);
  7814.               bf->stk_test_ret = test_ret;
  7815.               if (rxb->match_regs_on_stack)
  7816.             {
  7817.               int x;
  7818.               regoff_t * stk =
  7819.                 (regoff_t *)((char *)bf + sizeof (*bf));
  7820.               for (x = 0; x <= last_l; ++x)
  7821.                 stk[x] = lparen[x];
  7822.               stk += x;
  7823.               for (x = 0; x <= last_r; ++x)
  7824.                 stk[x] = rparen[x];
  7825.             }
  7826.  
  7827.             }
  7828.  
  7829.             /* Here is a while loop whose body is mainly a function
  7830.              * call and some code to handle a return from that
  7831.              * function.
  7832.              *
  7833.              * From here on for the rest of `case backtrack_point' it
  7834.              * is unsafe to assume that the variables saved on the
  7835.              * stack are valid -- so reread their values from the stack
  7836.              * as needed.
  7837.              *
  7838.              * This lets us re-use one generation fewer stack saves in
  7839.              * the call-graph of a search.
  7840.              */
  7841.             
  7842.           while_non_det_options:
  7843. #ifdef RX_DEBUG
  7844.             ++lines_found;
  7845.             if (rx_debug_trace)
  7846.               fprintf (stderr, "@@@ %d calls %d @@@\n",
  7847.                    line_no, lines_found);
  7848.             
  7849.             line_no = lines_found;
  7850. #endif
  7851.             
  7852.             if (bf->df->next_same_super_edge[0] == bf->first_df)
  7853.               {
  7854.             /* This is a tail-call optimization -- we don't recurse
  7855.              * for the last of the possible futures.
  7856.              */
  7857.             ifr = (bf->df->effects
  7858.                    ? &bf->df->side_effects_frame
  7859.                    : &bf->df->future_frame);
  7860.  
  7861.             rx_unlock_superstate (&rxb->rx, super);
  7862.             POP(backtrack_stack, backtrack_frame_bytes);
  7863. #ifdef RX_DEBUG
  7864.             --backtrack_depth;
  7865. #endif
  7866.             goto restart;
  7867.               }
  7868.             else
  7869.               {
  7870.             if (counter_stack)
  7871.               {
  7872.                 struct counter_frame * old_cf
  7873.                   = ((struct counter_frame *)counter_stack->sp);
  7874.                 struct counter_frame * cf;
  7875.                 PUSH(counter_stack, sizeof (struct counter_frame));
  7876.                 cf = ((struct counter_frame *)counter_stack->sp);
  7877.                 cf->tag = old_cf->tag;
  7878.                 cf->val = old_cf->val;
  7879.                 cf->inherited_from = old_cf;
  7880.                 cf->cdr = 0;
  7881.               }            
  7882.             /* `Call' this test-match block */
  7883.             ifr = (bf->df->effects
  7884.                    ? &bf->df->side_effects_frame
  7885.                    : &bf->df->future_frame);
  7886.             goto recurse_test_match;
  7887.               }
  7888.  
  7889.             /* Returns in this block are accomplished by
  7890.              * goto test_do_return.  There are two cases.
  7891.              * If there is some search-stack left,
  7892.              * then it is a return from a `recursive' call.
  7893.              * If there is no search-stack left, then
  7894.              * we should return to the fastmap/search loop.
  7895.              */
  7896.             
  7897.           test_do_return:
  7898.  
  7899.             if (!backtrack_stack)
  7900.               {
  7901. #ifdef RX_DEBUG
  7902.             if (rx_debug_trace)
  7903.               fprintf (stderr, "!!! %d bails returning %d !!!\n",
  7904.                    line_no, test_ret);
  7905. #endif
  7906.  
  7907.             /* No more search-stack -- this test is done. */
  7908.             if (test_ret)
  7909.               goto return_from_test_match;
  7910.             else
  7911.               goto error_in_testing_match;
  7912.               }
  7913.  
  7914.             /* Ok..we're returning from a recursive call to 
  7915.              * the test match block:
  7916.              */
  7917.             
  7918.             bf = ((struct backtrack_frame *)
  7919.               backtrack_stack->sp);
  7920. #ifdef RX_DEBUG
  7921.             if (rx_debug_trace)
  7922.               fprintf (stderr, "+++ %d returns %d (to %d)+++\n",
  7923.                    line_no, test_ret, bf->stk_line_no);
  7924. #endif
  7925.  
  7926.             while (counter_stack
  7927.                && (!bf->counter_stack_sp
  7928.                    || (bf->counter_stack_sp != counter_stack->sp)))
  7929.               {
  7930.             POP(counter_stack, sizeof (struct counter_frame));
  7931.               }
  7932.  
  7933.             if (!test_ret)
  7934.               {
  7935.             POP (backtrack_stack, backtrack_frame_bytes);
  7936.             goto test_do_return;
  7937.               }
  7938.  
  7939.             /* If any possible future reaches the end of the 
  7940.              * string without failing, make sure we propogate 
  7941.              * that information to the caller.
  7942.              */
  7943.             if ((test_ret == -2) && first_found)
  7944.               {
  7945.             rx_unlock_superstate (&rxb->rx, bf->stk_super);
  7946.             POP (backtrack_stack, backtrack_frame_bytes);
  7947.             goto test_do_return;
  7948.               }
  7949.  
  7950.             if (bf->stk_test_ret < 0)
  7951.               test_ret = bf->stk_test_ret;
  7952.  
  7953.             last_l = bf->stk_last_l;
  7954.             last_r = bf->stk_last_r;
  7955.             bf->df = bf->df->next_same_super_edge[0];
  7956.             super = bf->stk_super;
  7957.             tst_pos = bf->stk_tst_pos;
  7958.             tst_half = bf->stk_tst_half;
  7959.             c = bf->stk_c;
  7960.             tst_str_half = bf->stk_tst_str_half;
  7961.             tst_end_half = bf->stk_tst_end_half;
  7962. #ifdef RX_DEBUG
  7963.             line_no = bf->stk_line_no;
  7964. #endif
  7965.  
  7966.             if (rxb->match_regs_on_stack)
  7967.               {
  7968.             int x;
  7969.             regoff_t * stk =
  7970.               (regoff_t *)((char *)bf + sizeof (*bf));
  7971.             for (x = 0; x <= last_l; ++x)
  7972.               lparen[x] = stk[x];
  7973.             stk += x;
  7974.             for (x = 0; x <= last_r; ++x)
  7975.               rparen[x] = stk[x];
  7976.               }
  7977.  
  7978.             goto while_non_det_options;
  7979.           }
  7980.  
  7981.           
  7982.         case OF(rx_cache_miss,cache_miss):
  7983.           /* Because the superstate NFA is lazily constructed,
  7984.            * and in fact may erode from underneath us, we sometimes
  7985.            * have to construct the next instruction from the hard way.
  7986.            * This invokes one step in the lazy-conversion.
  7987.            */
  7988.           ifr = rx_handle_cache_miss (&rxb->rx, super, c, ifr->data_2);
  7989.           if (!ifr)
  7990.             {
  7991.               test_ret = 0;
  7992.               goto test_do_return;
  7993.             }
  7994.           goto restart;
  7995.           
  7996.         case OF(rx_backtrack,backtrack):
  7997.           /* RX_BACKTRACK means that we've reached the empty
  7998.            * superstate, indicating that match can't succeed
  7999.            * from this point.
  8000.            */
  8001.           goto test_do_return;
  8002.         case rx_next_char:
  8003.         case rx_error_inx:
  8004.         case rx_num_instructions:
  8005.           ret_val = 0;
  8006.           goto test_do_return;
  8007.         }
  8008.         }
  8009.     }
  8010.  
  8011.  
  8012.     /* Healthy exists from the test-match loop do a 
  8013.      * `goto return_from_test_match'   On the other hand, 
  8014.      * we might end up here.
  8015.      */
  8016.       error_in_testing_match:
  8017.     ret_val = -2;
  8018.     goto finish;
  8019.  
  8020.  
  8021.     /***** fastmap/search loop body
  8022.      *          considering the results testing for a match
  8023.      */
  8024.  
  8025.       return_from_test_match:
  8026.  
  8027.     if (best_last_l >= 0)
  8028.       {
  8029.         if (regs && (regs->start != best_lparen))
  8030.           {
  8031.         bcopy (best_lparen, regs->start,
  8032.                regs->num_regs * sizeof (int));
  8033.         bcopy (best_rparen, regs->end,
  8034.                regs->num_regs * sizeof (int));
  8035.           }
  8036.         if (regs && !rxb->no_sub)
  8037.           {
  8038.         int q;
  8039.         int bound = (regs->num_regs > num_regs
  8040.                  ? regs->num_regs
  8041.                  : num_regs);
  8042.         regoff_t * s = regs->start;
  8043.         regoff_t * e = regs->end;
  8044.         for (q = best_last_l + 1;  q < bound; ++q)
  8045.           s[q] = e[q] = -1;
  8046.           }
  8047.         ret_val = best_lparen[0];
  8048.         goto finish;
  8049.       }
  8050.  
  8051.     /***** fastmap/search loop,  increment and loop-test */
  8052.  
  8053.     pos += search_direction;
  8054.     startpos += search_direction;
  8055.  
  8056.       } while (startpos < search_end);
  8057.  
  8058.  
  8059.   /**** Exit code for fastmap/searchloop and the entire re_search_2 fn. */
  8060.  
  8061.   finish:
  8062.     /* Unset the fastmap sentinel */
  8063.     if (fastmap_chr >= 0)
  8064.       fastmap[fastmap_chr] = fastmap_val;
  8065.  
  8066.     if (start_super)
  8067.       rx_unlock_superstate (&rxb->rx, start_super);
  8068.  
  8069. #ifdef REGEX_MALLOC
  8070.     if (lparen) free (lparen);
  8071.     if (rparen) free (rparen);
  8072.     if (best_lpspace) free (best_lpspace);
  8073.     if (best_rpspace) free (best_rpspace);
  8074. #endif
  8075.     return ret_val;
  8076.   }
  8077. }
  8078.  
  8079. #if !defined(REGEX_MALLOC) && !defined(__GNUC__)
  8080. #ifdef __STDC__
  8081. int
  8082. re_search_2 (struct re_pattern_buffer *rxb,
  8083.          const char * string1, int size1,
  8084.          const char * string2, int size2,
  8085.          int startpos, int range,
  8086.          struct re_registers *regs,
  8087.          int stop)
  8088. #else
  8089. int
  8090. re_search_2 (rxb, string1, size1, string2, size2, startpos, range, regs, stop)
  8091.      struct re_pattern_buffer *rxb;
  8092.      const char * string1;
  8093.      int size1;
  8094.      const char * string2;
  8095.      int size2;
  8096.      int startpos;
  8097.      int range;
  8098.      struct re_registers *regs;
  8099.      int stop;
  8100. #endif
  8101. {
  8102.   int ret;
  8103.   ret = inner_re_search_2 (rxb, string1, size1, string2, size2, startpos,
  8104.                range, regs, stop);
  8105.   alloca (0);
  8106.   return ret;
  8107. }
  8108. #endif
  8109.  
  8110.  
  8111. /* Like re_search_2, above, but only one string is specified, and
  8112.  * doesn't let you say where to stop matching.
  8113.  */
  8114.  
  8115. #ifdef __STDC__
  8116. int
  8117. re_search (struct re_pattern_buffer * rxb, const char *string,
  8118.        int size, int startpos, int range,
  8119.        struct re_registers *regs)
  8120. #else
  8121. int
  8122. re_search (rxb, string, size, startpos, range, regs)
  8123.      struct re_pattern_buffer * rxb;
  8124.      const char * string;
  8125.      int size;
  8126.      int startpos;
  8127.      int range;
  8128.      struct re_registers *regs;
  8129. #endif
  8130. {
  8131.   return re_search_2 (rxb, 0, 0, string, size, startpos, range, regs, size);
  8132. }
  8133.  
  8134. #ifdef __STDC__
  8135. int
  8136. re_match_2 (struct re_pattern_buffer * rxb,
  8137.         const char * string1, int size1,
  8138.         const char * string2, int size2,
  8139.         int pos, struct re_registers *regs, int stop)
  8140. #else
  8141. int
  8142. re_match_2 (rxb, string1, size1, string2, size2, pos, regs, stop)
  8143.      struct re_pattern_buffer * rxb;
  8144.      const char * string1;
  8145.      int size1;
  8146.      const char * string2;
  8147.      int size2;
  8148.      int pos;
  8149.      struct re_registers *regs;
  8150.      int stop;
  8151. #endif
  8152. {
  8153.   struct re_registers some_regs;
  8154.   regoff_t start;
  8155.   regoff_t end;
  8156.   int srch;
  8157.   int save = rxb->regs_allocated;
  8158.   struct re_registers * regs_to_pass = regs;
  8159.  
  8160.   if (!regs)
  8161.     {
  8162.       some_regs.start = &start;
  8163.       some_regs.end = &end;
  8164.       some_regs.num_regs = 1;
  8165.       regs_to_pass = &some_regs;
  8166.       rxb->regs_allocated = REGS_FIXED;
  8167.     }
  8168.  
  8169.   srch = re_search_2 (rxb, string1, size1, string2, size2,
  8170.               pos, 1, regs_to_pass, stop);
  8171.   if (regs_to_pass != regs)
  8172.     rxb->regs_allocated = save;
  8173.   if (srch < 0)
  8174.     return srch;
  8175.   return regs_to_pass->end[0] - regs_to_pass->start[0];
  8176. }
  8177.  
  8178. /* re_match is like re_match_2 except it takes only a single string.  */
  8179.  
  8180. #ifdef __STDC__
  8181. int
  8182. re_match (struct re_pattern_buffer * rxb,
  8183.       const char * string,
  8184.       int size, int pos,
  8185.       struct re_registers *regs)
  8186. #else
  8187. int
  8188. re_match (rxb, string, size, pos, regs)
  8189.      struct re_pattern_buffer * rxb;
  8190.      const char *string;
  8191.      int size;
  8192.      int pos;
  8193.      struct re_registers *regs;
  8194. #endif
  8195. {
  8196.   return re_match_2 (rxb, string, size, 0, 0, pos, regs, size);
  8197. }
  8198.  
  8199.  
  8200.  
  8201. /* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
  8202.    also be assigned to arbitrarily: each pattern buffer stores its own
  8203.    syntax, so it can be changed between regex compilations.  */
  8204. reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
  8205.  
  8206.  
  8207. /* Specify the precise syntax of regexps for compilation.  This provides
  8208.    for compatibility for various utilities which historically have
  8209.    different, incompatible syntaxes.
  8210.  
  8211.    The argument SYNTAX is a bit mask comprised of the various bits
  8212.    defined in regex.h.  We return the old syntax.  */
  8213.  
  8214. #ifdef __STDC__
  8215. reg_syntax_t
  8216. re_set_syntax (reg_syntax_t syntax)
  8217. #else
  8218. reg_syntax_t
  8219. re_set_syntax (syntax)
  8220.     reg_syntax_t syntax;
  8221. #endif
  8222. {
  8223.   reg_syntax_t ret = re_syntax_options;
  8224.  
  8225.   re_syntax_options = syntax;
  8226.   return ret;
  8227. }
  8228.  
  8229.  
  8230. /* Set REGS to hold NUM_REGS registers, storing them in STARTS and
  8231.    ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
  8232.    this memory for recording register information.  STARTS and ENDS
  8233.    must be allocated using the malloc library routine, and must each
  8234.    be at least NUM_REGS * sizeof (regoff_t) bytes long.
  8235.  
  8236.    If NUM_REGS == 0, then subsequent matches should allocate their own
  8237.    register data.
  8238.  
  8239.    Unless this function is called, the first search or match using
  8240.    PATTERN_BUFFER will allocate its own register data, without
  8241.    freeing the old data.  */
  8242.  
  8243. #ifdef __STDC__
  8244. void
  8245. re_set_registers (struct re_pattern_buffer *bufp,
  8246.           struct re_registers *regs,
  8247.           unsigned num_regs,
  8248.           regoff_t * starts, regoff_t * ends)
  8249. #else
  8250. void
  8251. re_set_registers (bufp, regs, num_regs, starts, ends)
  8252.      struct re_pattern_buffer *bufp;
  8253.      struct re_registers *regs;
  8254.      unsigned num_regs;
  8255.      regoff_t * starts;
  8256.      regoff_t * ends;
  8257. #endif
  8258. {
  8259.   if (num_regs)
  8260.     {
  8261.       bufp->regs_allocated = REGS_REALLOCATE;
  8262.       regs->num_regs = num_regs;
  8263.       regs->start = starts;
  8264.       regs->end = ends;
  8265.     }
  8266.   else
  8267.     {
  8268.       bufp->regs_allocated = REGS_UNALLOCATED;
  8269.       regs->num_regs = 0;
  8270.       regs->start = regs->end = (regoff_t) 0;
  8271.     }
  8272. }
  8273.  
  8274.  
  8275.  
  8276.  
  8277. #ifdef __STDC__
  8278. static int 
  8279. cplx_se_sublist_len (struct rx_se_list * list)
  8280. #else
  8281. static int 
  8282. cplx_se_sublist_len (list)
  8283.      struct rx_se_list * list;
  8284. #endif
  8285. {
  8286.   int x = 0;
  8287.   while (list)
  8288.     {
  8289.       if ((int)list->car >= 0)
  8290.     ++x;
  8291.       list = list->cdr;
  8292.     }
  8293.   return x;
  8294. }
  8295.  
  8296.  
  8297. /* For rx->se_list_cmp */
  8298.  
  8299. #ifdef __STDC__
  8300. static int 
  8301. posix_se_list_order (struct rx * rx,
  8302.              struct rx_se_list * a, struct rx_se_list * b)
  8303. #else
  8304. static int 
  8305. posix_se_list_order (rx, a, b)
  8306.      struct rx * rx;
  8307.      struct rx_se_list * a;
  8308.      struct rx_se_list * b;
  8309. #endif
  8310. {
  8311.   int al = cplx_se_sublist_len (a);
  8312.   int bl = cplx_se_sublist_len (b);
  8313.  
  8314.   if (!al && !bl)
  8315.     return ((a == b)
  8316.         ? 0
  8317.         : ((a < b) ? -1 : 1));
  8318.   
  8319.   else if (!al)
  8320.     return -1;
  8321.  
  8322.   else if (!bl)
  8323.     return 1;
  8324.  
  8325.   else
  8326.     {
  8327.       rx_side_effect * av = ((rx_side_effect *)
  8328.                  alloca (sizeof (rx_side_effect) * (al + 1)));
  8329.       rx_side_effect * bv = ((rx_side_effect *)
  8330.                  alloca (sizeof (rx_side_effect) * (bl + 1)));
  8331.       struct rx_se_list * ap = a;
  8332.       struct rx_se_list * bp = b;
  8333.       int ai, bi;
  8334.       
  8335.       for (ai = al - 1; ai >= 0; --ai)
  8336.     {
  8337.       while ((int)ap->car < 0)
  8338.         ap = ap->cdr;
  8339.       av[ai] = ap->car;
  8340.       ap = ap->cdr;
  8341.     }
  8342.       av[al] = (rx_side_effect)-2;
  8343.       for (bi = bl - 1; bi >= 0; --bi)
  8344.     {
  8345.       while ((int)bp->car < 0)
  8346.         bp = bp->cdr;
  8347.       bv[bi] = bp->car;
  8348.       bp = bp->cdr;
  8349.     }
  8350.       bv[bl] = (rx_side_effect)-1;
  8351.  
  8352.       {
  8353.     int ret;
  8354.     int x = 0;
  8355.     while (av[x] == bv[x])
  8356.       ++x;
  8357.     ret = ((av[x] < bv[x]) ? -1 : 1);
  8358.     return ret;
  8359.       }
  8360.     }
  8361. }
  8362.  
  8363.  
  8364.  
  8365.  
  8366. /* re_compile_pattern is the GNU regular expression compiler: it
  8367.    compiles PATTERN (of length SIZE) and puts the result in RXB.
  8368.    Returns 0 if the pattern was valid, otherwise an error string.
  8369.  
  8370.    Assumes the `allocated' (and perhaps `buffer') and `translate' fields
  8371.    are set in RXB on entry.
  8372.  
  8373.    We call rx_compile to do the actual compilation.  */
  8374.  
  8375. #ifdef __STDC__
  8376. const char *
  8377. re_compile_pattern (const char *pattern,
  8378.             int length,
  8379.             struct re_pattern_buffer * rxb)
  8380. #else
  8381. const char *
  8382. re_compile_pattern (pattern, length, rxb)
  8383.      const char *pattern;
  8384.      int length;
  8385.      struct re_pattern_buffer * rxb;
  8386. #endif
  8387. {
  8388.   reg_errcode_t ret;
  8389.  
  8390.   /* GNU code is written to assume at least RE_NREGS registers will be set
  8391.      (and at least one extra will be -1).  */
  8392.   rxb->regs_allocated = REGS_UNALLOCATED;
  8393.  
  8394.   /* And GNU code determines whether or not to get register information
  8395.      by passing null for the REGS argument to re_match, etc., not by
  8396.      setting no_sub.  */
  8397.   rxb->no_sub = 0;
  8398.  
  8399.   rxb->rx.local_cset_size = 256;
  8400.  
  8401.   /* Match anchors at newline.  */
  8402.   rxb->newline_anchor = 1;
  8403.  
  8404.   rxb->re_nsub = 0;
  8405.   rxb->start = 0;
  8406.   rxb->se_params = 0;
  8407.   rxb->rx.nodec = 0;
  8408.   rxb->rx.epsnodec = 0;
  8409.   rxb->rx.instruction_table = 0;
  8410.   rxb->rx.nfa_states = 0;
  8411.   rxb->rx.se_list_cmp = posix_se_list_order;
  8412.   rxb->rx.start_set = 0;
  8413.  
  8414.   ret = rx_compile (pattern, length, re_syntax_options, rxb);
  8415.   alloca (0);
  8416.   return rx_error_msg[(int) ret];
  8417. }
  8418.  
  8419.  
  8420.  
  8421. #ifdef __STDC__
  8422. int
  8423. re_compile_fastmap (struct re_pattern_buffer * rxb)
  8424. #else
  8425. int
  8426. re_compile_fastmap (rxb)
  8427.      struct re_pattern_buffer * rxb;
  8428. #endif
  8429. {
  8430.   rx_blow_up_fastmap (rxb);
  8431.   return 0;
  8432. }
  8433.  
  8434.  
  8435.  
  8436.  
  8437. /* Entry points compatible with 4.2 BSD regex library.  We don't define
  8438.    them if this is an Emacs or POSIX compilation.  */
  8439.  
  8440. #if !defined (emacs) && !defined (_POSIX_SOURCE) && 0
  8441.  
  8442. /* BSD has one and only one pattern buffer.  */
  8443. static struct re_pattern_buffer rx_comp_buf;
  8444.  
  8445. #ifdef __STDC__
  8446. char *
  8447. re_comp (const char *s)
  8448. #else
  8449. char *
  8450. re_comp (s)
  8451.     const char *s;
  8452. #endif
  8453. {
  8454.   reg_errcode_t ret;
  8455.  
  8456.   if (!s)
  8457.     {
  8458.       if (!rx_comp_buf.buffer)
  8459.     return "No previous regular expression";
  8460.       return 0;
  8461.     }
  8462.  
  8463.   if (!rx_comp_buf.fastmap)
  8464.     {
  8465.       rx_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
  8466.       if (!rx_comp_buf.fastmap)
  8467.     return "Memory exhausted";
  8468.     }
  8469.  
  8470.   /* Since `rx_exec' always passes NULL for the `regs' argument, we
  8471.      don't need to initialize the pattern buffer fields which affect it.  */
  8472.  
  8473.   /* Match anchors at newlines.  */
  8474.   rx_comp_buf.newline_anchor = 1;
  8475.  
  8476.   rx_comp_buf.re_nsub = 0;
  8477.   rx_comp_buf.start = 0;
  8478.   rx_comp_buf.se_params = 0;
  8479.   rx_comp_buf.rx.nodec = 0;
  8480.   rx_comp_buf.rx.epsnodec = 0;
  8481.   rx_comp_buf.rx.instruction_table = 0;
  8482.   rx_comp_buf.rx.nfa_states = 0;
  8483.   rx_comp_buf.rx.start = 0;
  8484.   rx_comp_buf.rx.se_list_cmp = posix_se_list_order;
  8485.  
  8486.   ret = rx_compile (s, strlen (s), rx_syntax_options, &rx_comp_buf);
  8487.   alloca (0);
  8488.  
  8489.   /* Yes, we're discarding `const' here.  */
  8490.   return (char *) rx_error_msg[(int) ret];
  8491. }
  8492.  
  8493.  
  8494. #ifdef __STDC__
  8495. int
  8496. rx_exec (const char *s)
  8497. #else
  8498. int
  8499. rx_exec (s)
  8500.     const char *s;
  8501. #endif
  8502. {
  8503.   const int len = strlen (s);
  8504.   return
  8505.     0 <= re_search (&rx_comp_buf, s, len, 0, len, (struct rx_registers *) 0);
  8506. }
  8507. #endif /* not emacs and not _POSIX_SOURCE */
  8508.  
  8509.  
  8510.  
  8511. /* POSIX.2 functions.  Don't define these for Emacs.  */
  8512.  
  8513. #if !defined(emacs)
  8514.  
  8515. /* regcomp takes a regular expression as a string and compiles it.
  8516.  
  8517.    PREG is a regex_t *.  We do not expect any fields to be initialized,
  8518.    since POSIX says we shouldn't.  Thus, we set
  8519.  
  8520.      `buffer' to the compiled pattern;
  8521.      `used' to the length of the compiled pattern;
  8522.      `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
  8523.        REG_EXTENDED bit in CFLAGS is set; otherwise, to
  8524.        RE_SYNTAX_POSIX_BASIC;
  8525.      `newline_anchor' to REG_NEWLINE being set in CFLAGS;
  8526.      `fastmap' and `fastmap_accurate' to zero;
  8527.      `re_nsub' to the number of subexpressions in PATTERN.
  8528.  
  8529.    PATTERN is the address of the pattern string.
  8530.  
  8531.    CFLAGS is a series of bits which affect compilation.
  8532.  
  8533.      If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
  8534.      use POSIX basic syntax.
  8535.  
  8536.      If REG_NEWLINE is set, then . and [^...] don't match newline.
  8537.      Also, regexec will try a match beginning after every newline.
  8538.  
  8539.      If REG_ICASE is set, then we considers upper- and lowercase
  8540.      versions of letters to be equivalent when matching.
  8541.  
  8542.      If REG_NOSUB is set, then when PREG is passed to regexec, that
  8543.      routine will report only success or failure, and nothing about the
  8544.      registers.
  8545.  
  8546.    It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
  8547.    the return codes and their meanings.)  */
  8548.  
  8549.  
  8550. #ifdef __STDC__
  8551. int
  8552. regcomp (regex_t * preg, const char * pattern, int cflags)
  8553. #else
  8554. int
  8555. regcomp (preg, pattern, cflags)
  8556.     regex_t * preg;
  8557.     const char * pattern;
  8558.     int cflags;
  8559. #endif
  8560. {
  8561.   reg_errcode_t ret;
  8562.   unsigned syntax
  8563.     = cflags & REG_EXTENDED ? RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
  8564.  
  8565.   /* regex_compile will allocate the space for the compiled pattern.  */
  8566.   preg->buffer = 0;
  8567.   preg->allocated = 0;
  8568.  
  8569.   preg->fastmap = malloc (256);
  8570.   if (!preg->fastmap)
  8571.     return REG_ESPACE;
  8572.   preg->fastmap_accurate = 0;
  8573.  
  8574.   if (cflags & REG_ICASE)
  8575.     {
  8576.       unsigned i;
  8577.  
  8578.       preg->translate = (char *) malloc (256);
  8579.       if (!preg->translate)
  8580.         return (int) REG_ESPACE;
  8581.  
  8582.       /* Map uppercase characters to corresponding lowercase ones.  */
  8583.       for (i = 0; i < CHAR_SET_SIZE; i++)
  8584.         preg->translate[i] = isupper (i) ? tolower (i) : i;
  8585.     }
  8586.   else
  8587.     preg->translate = 0;
  8588.  
  8589.   /* If REG_NEWLINE is set, newlines are treated differently.  */
  8590.   if (cflags & REG_NEWLINE)
  8591.     { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
  8592.       syntax &= ~RE_DOT_NEWLINE;
  8593.       syntax |= RE_HAT_LISTS_NOT_NEWLINE;
  8594.       /* It also changes the matching behavior.  */
  8595.       preg->newline_anchor = 1;
  8596.     }
  8597.   else
  8598.     preg->newline_anchor = 0;
  8599.  
  8600.   preg->no_sub = !!(cflags & REG_NOSUB);
  8601.  
  8602.   /* POSIX says a null character in the pattern terminates it, so we
  8603.      can use strlen here in compiling the pattern.  */
  8604.   preg->re_nsub = 0;
  8605.   preg->start = 0;
  8606.   preg->se_params = 0;
  8607.   preg->rx.nodec = 0;
  8608.   preg->rx.epsnodec = 0;
  8609.   preg->rx.instruction_table = 0;
  8610.   preg->rx.nfa_states = 0;
  8611.   preg->rx.local_cset_size = 256;
  8612.   preg->rx.start = 0;
  8613.   preg->rx.se_list_cmp = posix_se_list_order;
  8614.   preg->rx.start_set = 0;
  8615.   ret = rx_compile (pattern, strlen (pattern), syntax, preg);
  8616.   alloca (0);
  8617.  
  8618.   /* POSIX doesn't distinguish between an unmatched open-group and an
  8619.      unmatched close-group: both are REG_EPAREN.  */
  8620.   if (ret == REG_ERPAREN) ret = REG_EPAREN;
  8621.  
  8622.   return (int) ret;
  8623. }
  8624.  
  8625.  
  8626. /* regexec searches for a given pattern, specified by PREG, in the
  8627.    string STRING.
  8628.  
  8629.    If NMATCH is zero or REG_NOSUB was set in the cflags argument to
  8630.    `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
  8631.    least NMATCH elements, and we set them to the offsets of the
  8632.    corresponding matched substrings.
  8633.  
  8634.    EFLAGS specifies `execution flags' which affect matching: if
  8635.    REG_NOTBOL is set, then ^ does not match at the beginning of the
  8636.    string; if REG_NOTEOL is set, then $ does not match at the end.
  8637.  
  8638.    We return 0 if we find a match and REG_NOMATCH if not.  */
  8639.  
  8640. #ifdef __STDC__
  8641. int
  8642. regexec (const regex_t *preg, const char *string,
  8643.      size_t nmatch, regmatch_t pmatch[],
  8644.      int eflags)
  8645. #else
  8646. int
  8647. regexec (preg, string, nmatch, pmatch, eflags)
  8648.     const regex_t *preg;
  8649.     const char *string;
  8650.     size_t nmatch;
  8651.     regmatch_t pmatch[];
  8652.     int eflags;
  8653. #endif
  8654. {
  8655.   int ret;
  8656.   struct re_registers regs;
  8657.   regex_t private_preg;
  8658.   int len = strlen (string);
  8659.   boolean want_reg_info = !preg->no_sub && nmatch > 0;
  8660.  
  8661.   private_preg = *preg;
  8662.  
  8663.   private_preg.not_bol = !!(eflags & REG_NOTBOL);
  8664.   private_preg.not_eol = !!(eflags & REG_NOTEOL);
  8665.  
  8666.   /* The user has told us exactly how many registers to return
  8667.    * information about, via `nmatch'.  We have to pass that on to the
  8668.    * matching routines.
  8669.    */
  8670.   private_preg.regs_allocated = REGS_FIXED;
  8671.  
  8672.   if (want_reg_info)
  8673.     {
  8674.       regs.num_regs = nmatch;
  8675.       regs.start = TALLOC (nmatch, regoff_t);
  8676.       regs.end = TALLOC (nmatch, regoff_t);
  8677.       if (regs.start == 0 || regs.end == 0)
  8678.         return (int) REG_NOMATCH;
  8679.     }
  8680.  
  8681.   /* Perform the searching operation.  */
  8682.   ret = re_search (&private_preg,
  8683.            string, len,
  8684.                    /* start: */ 0,
  8685.            /* range: */ len,
  8686.                    want_reg_info ? ®s : (struct re_registers *) 0);
  8687.  
  8688.   /* Copy the register information to the POSIX structure.  */
  8689.   if (want_reg_info)
  8690.     {
  8691.       if (ret >= 0)
  8692.         {
  8693.           unsigned r;
  8694.  
  8695.           for (r = 0; r < nmatch; r++)
  8696.             {
  8697.               pmatch[r].rm_so = regs.start[r];
  8698.               pmatch[r].rm_eo = regs.end[r];
  8699.             }
  8700.         }
  8701.  
  8702.       /* If we needed the temporary register info, free the space now.  */
  8703.       free (regs.start);
  8704.       free (regs.end);
  8705.     }
  8706.  
  8707.   /* We want zero return to mean success, unlike `re_search'.  */
  8708.   return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
  8709. }
  8710.  
  8711.  
  8712. /* Returns a message corresponding to an error code, ERRCODE, returned
  8713.    from either regcomp or regexec.   */
  8714.  
  8715. #ifdef __STDC__
  8716. size_t
  8717. regerror (int errcode, const regex_t *preg,
  8718.       char *errbuf, size_t errbuf_size)
  8719. #else
  8720. size_t
  8721. regerror (errcode, preg, errbuf, errbuf_size)
  8722.     int errcode;
  8723.     const regex_t *preg;
  8724.     char *errbuf;
  8725.     size_t errbuf_size;
  8726. #endif
  8727. {
  8728.   const char *msg
  8729.     = rx_error_msg[errcode] == 0 ? "Success" : rx_error_msg[errcode];
  8730.   size_t msg_size = strlen (msg) + 1; /* Includes the 0.  */
  8731.  
  8732.   if (errbuf_size != 0)
  8733.     {
  8734.       if (msg_size > errbuf_size)
  8735.         {
  8736.           strncpy (errbuf, msg, errbuf_size - 1);
  8737.           errbuf[errbuf_size - 1] = 0;
  8738.         }
  8739.       else
  8740.         strcpy (errbuf, msg);
  8741.     }
  8742.  
  8743.   return msg_size;
  8744. }
  8745.  
  8746.  
  8747. /* Free dynamically allocated space used by PREG.  */
  8748.  
  8749. #ifdef __STDC__
  8750. void
  8751. regfree (regex_t *preg)
  8752. #else
  8753. void
  8754. regfree (preg)
  8755.     regex_t *preg;
  8756. #endif
  8757. {
  8758.   if (preg->buffer != 0)
  8759.     free (preg->buffer);
  8760.   preg->buffer = 0;
  8761.   preg->allocated = 0;
  8762.  
  8763.   if (preg->fastmap != 0)
  8764.     free (preg->fastmap);
  8765.   preg->fastmap = 0;
  8766.   preg->fastmap_accurate = 0;
  8767.  
  8768.   if (preg->translate != 0)
  8769.     free (preg->translate);
  8770.   preg->translate = 0;
  8771. }
  8772.  
  8773. #endif /* not emacs  */
  8774.  
  8775.  
  8776.  
  8777.  
  8778.  
  8779.