/[m4]/m4/lib/regex.c
ViewVC logotype

Diff of /m4/lib/regex.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1.2.2 by gary, Mon Feb 7 12:56:34 2005 UTC revision 1.1.1.1.2.3 by gary, Sun May 1 11:54:12 2005 UTC
# Line 7  Line 7 
7    
8     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2, or (at your option)     the Free Software Foundation; either version 2 of the License, or
11     any later version.     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
# Line 17  Line 17 
17    
18     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21       02110-1301  USA
22    */
23    
24  /* AIX requires this to be the first thing in the file. */  /* AIX requires this to be the first thing in the file. */
25  #if defined (_AIX) && !defined (REGEX_MALLOC)  #if defined (_AIX) && !defined (REGEX_MALLOC)
# Line 77  char *realloc (); Line 79  char *realloc ();
79    
80  /* This must be nonzero for the wordchar and notwordchar pattern  /* This must be nonzero for the wordchar and notwordchar pattern
81     commands in re_match_2.  */     commands in re_match_2.  */
82  #ifndef Sword  #ifndef Sword
83  #define Sword 1  #define Sword 1
84  #endif  #endif
85    
# Line 188  init_syntax_once () Line 190  init_syntax_once ()
190     use `alloca' instead of `malloc'.  This is because using malloc in     use `alloca' instead of `malloc'.  This is because using malloc in
191     re_search* or re_match* could cause memory leaks when C-g is used in     re_search* or re_match* could cause memory leaks when C-g is used in
192     Emacs; also, malloc is slower and causes storage fragmentation.  On     Emacs; also, malloc is slower and causes storage fragmentation.  On
193     the other hand, malloc is more portable, and easier to debug.       the other hand, malloc is more portable, and easier to debug.
194      
195     Because we sometimes use alloca, some routines have to be macros,     Because we sometimes use alloca, some routines have to be macros,
196     not functions -- `alloca'-allocated space disappears at the end of the     not functions -- `alloca'-allocated space disappears at the end of the
197     function it is called in.  */     function it is called in.  */
# Line 214  init_syntax_once () Line 216  init_syntax_once ()
216  #ifndef _AIX /* Already did AIX, up at the top.  */  #ifndef _AIX /* Already did AIX, up at the top.  */
217  char *alloca ();  char *alloca ();
218  #endif /* not _AIX */  #endif /* not _AIX */
219  #endif /* not HAVE_ALLOCA_H */  #endif /* not HAVE_ALLOCA_H */
220  #endif /* not __GNUC__ */  #endif /* not __GNUC__ */
221    
222  #endif /* not alloca */  #endif /* not alloca */
# Line 319  typedef enum Line 321  typedef enum
321    
322          /* Analogously, for end of buffer/string.  */          /* Analogously, for end of buffer/string.  */
323    endbuf,    endbuf,
324    
325          /* Followed by two byte relative address to which to jump.  */          /* Followed by two byte relative address to which to jump.  */
326    jump,    jump,
327    
328          /* Same as jump, but marks the end of an alternative.  */          /* Same as jump, but marks the end of an alternative.  */
329    jump_past_alt,    jump_past_alt,
# Line 329  typedef enum Line 331  typedef enum
331          /* Followed by two-byte relative address of place to resume at          /* Followed by two-byte relative address of place to resume at
332             in case of failure.  */             in case of failure.  */
333    on_failure_jump,    on_failure_jump,
334            
335          /* Like on_failure_jump, but pushes a placeholder instead of the          /* Like on_failure_jump, but pushes a placeholder instead of the
336             current string position when executed.  */             current string position when executed.  */
337    on_failure_keep_string_jump,    on_failure_keep_string_jump,
338      
339          /* Throw away latest failure point and then jump to following          /* Throw away latest failure point and then jump to following
340             two-byte relative address.  */             two-byte relative address.  */
341    pop_failure_jump,    pop_failure_jump,
# Line 429  extract_number (dest, source) Line 431  extract_number (dest, source)
431      int *dest;      int *dest;
432      unsigned char *source;      unsigned char *source;
433  {  {
434    int temp = SIGN_EXTEND_CHAR (*(source + 1));    int temp = SIGN_EXTEND_CHAR (*(source + 1));
435    *dest = *source & 0377;    *dest = *source & 0377;
436    *dest += temp << 8;    *dest += temp << 8;
437  }  }
# Line 455  static void Line 457  static void
457  extract_number_and_incr (destination, source)  extract_number_and_incr (destination, source)
458      int *destination;      int *destination;
459      unsigned char **source;      unsigned char **source;
460  {  {
461    extract_number (destination, *source);    extract_number (destination, *source);
462    *source += 2;    *source += 2;
463  }  }
# Line 504  print_fastmap (fastmap) Line 506  print_fastmap (fastmap)
506      char *fastmap;      char *fastmap;
507  {  {
508    unsigned was_a_range = 0;    unsigned was_a_range = 0;
509    unsigned i = 0;      unsigned i = 0;
510      
511    while (i < (1 << BYTEWIDTH))    while (i < (1 << BYTEWIDTH))
512      {      {
513        if (fastmap[i++])        if (fastmap[i++])
# Line 524  print_fastmap (fastmap) Line 526  print_fastmap (fastmap)
526              }              }
527          }          }
528      }      }
529    putchar ('\n');    putchar ('\n');
530  }  }
531    
532    
# Line 545  print_partial_compiled_pattern (start, e Line 547  print_partial_compiled_pattern (start, e
547        printf ("(null)\n");        printf ("(null)\n");
548        return;        return;
549      }      }
550        
551    /* Loop over pattern commands.  */    /* Loop over pattern commands.  */
552    while (p < pend)    while (p < pend)
553      {      {
# Line 594  print_partial_compiled_pattern (start, e Line 596  print_partial_compiled_pattern (start, e
596    
597              printf ("/charset [%s",              printf ("/charset [%s",
598                      (re_opcode_t) *(p - 1) == charset_not ? "^" : "");                      (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
599                
600              assert (p + *p < pend);              assert (p + *p < pend);
601    
602              for (c = 0; c < 256; c++)              for (c = 0; c < 256; c++)
# Line 613  print_partial_compiled_pattern (start, e Line 615  print_partial_compiled_pattern (start, e
615                        printchar (last);                        printchar (last);
616                        in_range = 0;                        in_range = 0;
617                      }                      }
618                    
619                    if (! in_range)                    if (! in_range)
620                      printchar (c);                      printchar (c);
621    
# Line 655  print_partial_compiled_pattern (start, e Line 657  print_partial_compiled_pattern (start, e
657          case push_dummy_failure:          case push_dummy_failure:
658            printf ("/push_dummy_failure");            printf ("/push_dummy_failure");
659            break;            break;
660              
661          case maybe_pop_jump:          case maybe_pop_jump:
662            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
663            printf ("/maybe_pop_jump to %d", p + mcnt - start);            printf ("/maybe_pop_jump to %d", p + mcnt - start);
# Line 664  print_partial_compiled_pattern (start, e Line 666  print_partial_compiled_pattern (start, e
666          case pop_failure_jump:          case pop_failure_jump:
667            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
668            printf ("/pop_failure_jump to %d", p + mcnt - start);            printf ("/pop_failure_jump to %d", p + mcnt - start);
669            break;                      break;
670              
671          case jump_past_alt:          case jump_past_alt:
672            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
673            printf ("/jump_past_alt to %d", p + mcnt - start);            printf ("/jump_past_alt to %d", p + mcnt - start);
674            break;                      break;
675              
676          case jump:          case jump:
677            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
678            printf ("/jump to %d", p + mcnt - start);            printf ("/jump to %d", p + mcnt - start);
679            break;            break;
680    
681          case succeed_n:          case succeed_n:
682            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
683            extract_number_and_incr (&mcnt2, &p);            extract_number_and_incr (&mcnt2, &p);
684            printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);            printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);
685            break;            break;
686            
687          case jump_n:          case jump_n:
688            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
689            extract_number_and_incr (&mcnt2, &p);            extract_number_and_incr (&mcnt2, &p);
690            printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);            printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);
691            break;            break;
692            
693          case set_number_at:          case set_number_at:
694            extract_number_and_incr (&mcnt, &p);            extract_number_and_incr (&mcnt, &p);
695            extract_number_and_incr (&mcnt2, &p);            extract_number_and_incr (&mcnt2, &p);
696            printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);            printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);
697            break;            break;
698            
699          case wordbound:          case wordbound:
700            printf ("/wordbound");            printf ("/wordbound");
701            break;            break;
# Line 705  print_partial_compiled_pattern (start, e Line 707  print_partial_compiled_pattern (start, e
707          case wordbeg:          case wordbeg:
708            printf ("/wordbeg");            printf ("/wordbeg");
709            break;            break;
710              
711          case wordend:          case wordend:
712            printf ("/wordend");            printf ("/wordend");
713              
714  #ifdef emacs  #ifdef emacs
715          case before_dot:          case before_dot:
716            printf ("/before_dot");            printf ("/before_dot");
# Line 727  print_partial_compiled_pattern (start, e Line 729  print_partial_compiled_pattern (start, e
729            mcnt = *p++;            mcnt = *p++;
730            printf ("/%d", mcnt);            printf ("/%d", mcnt);
731            break;            break;
732              
733          case notsyntaxspec:          case notsyntaxspec:
734            printf ("/notsyntaxspec");            printf ("/notsyntaxspec");
735            mcnt = *p++;            mcnt = *p++;
# Line 738  print_partial_compiled_pattern (start, e Line 740  print_partial_compiled_pattern (start, e
740          case wordchar:          case wordchar:
741            printf ("/wordchar");            printf ("/wordchar");
742            break;            break;
743              
744          case notwordchar:          case notwordchar:
745            printf ("/notwordchar");            printf ("/notwordchar");
746            break;            break;
# Line 798  print_double_string (where, string1, siz Line 800  print_double_string (where, string1, siz
800      int size2;      int size2;
801  {  {
802    unsigned this_char;    unsigned this_char;
803      
804    if (where == NULL)    if (where == NULL)
805      printf ("(null)");      printf ("(null)");
806    else    else
# Line 808  print_double_string (where, string1, siz Line 810  print_double_string (where, string1, siz
810            for (this_char = where - string1; this_char < size1; this_char++)            for (this_char = where - string1; this_char < size1; this_char++)
811              printchar (string1[this_char]);              printchar (string1[this_char]);
812    
813            where = string2;                where = string2;
814          }          }
815    
816        for (this_char = where - string2; this_char < size2; this_char++)        for (this_char = where - string2; this_char < size2; this_char++)
# Line 849  re_set_syntax (syntax) Line 851  re_set_syntax (syntax)
851      reg_syntax_t syntax;      reg_syntax_t syntax;
852  {  {
853    reg_syntax_t ret = re_syntax_options;    reg_syntax_t ret = re_syntax_options;
854      
855    re_syntax_options = syntax;    re_syntax_options = syntax;
856    return ret;    return ret;
857  }  }
# Line 887  static const char *re_error_msg[] = Line 889  static const char *re_error_msg[] =
889     ralloc heap) shift the data out from underneath the regexp     ralloc heap) shift the data out from underneath the regexp
890     routines.     routines.
891    
892     Here's another reason to avoid allocation: Emacs     Here's another reason to avoid allocation: Emacs
893     processes input from X in a signal handler; processing X input may     processes input from X in a signal handler; processing X input may
894     call malloc; if input arrives while a matching routine is calling     call malloc; if input arrives while a matching routine is calling
895     malloc, then we're scrod.  But Emacs can't just block input while     malloc, then we're scrod.  But Emacs can't just block input while
# Line 909  static const char *re_error_msg[] = Line 911  static const char *re_error_msg[] =
911  /* Failure stack declarations and macros; both re_compile_fastmap and  /* Failure stack declarations and macros; both re_compile_fastmap and
912     re_match_2 use a failure stack.  These have to be macros because of     re_match_2 use a failure stack.  These have to be macros because of
913     REGEX_ALLOCATE.  */     REGEX_ALLOCATE.  */
914      
915    
916  /* Number of failure points for which to initially allocate space  /* Number of failure points for which to initially allocate space
917     when matching.  If this number is exceeded, we allocate more     when matching.  If this number is exceeded, we allocate more
# Line 964  typedef struct Line 966  typedef struct
966  /* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.  /* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
967    
968     Return 1 if succeeds, and 0 if either ran out of memory     Return 1 if succeeds, and 0 if either ran out of memory
969     allocating space for it or it was already too large.       allocating space for it or it was already too large.
970      
971     REGEX_REALLOCATE requires `destination' be declared.   */     REGEX_REALLOCATE requires `destination' be declared.   */
972    
973  #define DOUBLE_FAIL_STACK(fail_stack)                                   \  #define DOUBLE_FAIL_STACK(fail_stack)                                   \
# Line 982  typedef struct Line 984  typedef struct
984           1)))           1)))
985    
986    
987  /* Push PATTERN_OP on FAIL_STACK.  /* Push PATTERN_OP on FAIL_STACK.
988    
989     Return 1 if was able to do so and 0 if ran out of memory allocating     Return 1 if was able to do so and 0 if ran out of memory allocating
990     space to do so.  */     space to do so.  */
# Line 1013  typedef struct Line 1015  typedef struct
1015    
1016    
1017  /* Push the information about the state we will need  /* Push the information about the state we will need
1018     if we ever fail back to it.       if we ever fail back to it.
1019      
1020     Requires variables fail_stack, regstart, regend, reg_info, and     Requires variables fail_stack, regstart, regend, reg_info, and
1021     num_regs be declared.  DOUBLE_FAIL_STACK requires `destination' be     num_regs be declared.  DOUBLE_FAIL_STACK requires `destination' be
1022     declared.     declared.
1023      
1024     Does `return FAILURE_CODE' if runs out of memory.  */     Does `return FAILURE_CODE' if runs out of memory.  */
1025    
1026  #define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code)   \  #define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code)   \
# Line 1126  typedef struct Line 1128  typedef struct
1128       LOW_REG, HIGH_REG -- the highest and lowest active registers.       LOW_REG, HIGH_REG -- the highest and lowest active registers.
1129       REGSTART, REGEND -- arrays of string positions.       REGSTART, REGEND -- arrays of string positions.
1130       REG_INFO -- array of information about each subexpression.       REG_INFO -- array of information about each subexpression.
1131      
1132     Also assumes the variables `fail_stack' and (if debugging), `bufp',     Also assumes the variables `fail_stack' and (if debugging), `bufp',
1133     `pend', `string1', `size1', `string2', and `size2'.  */     `pend', `string1', `size1', `string2', and `size2'.  */
1134    
# Line 1194  typedef struct Line 1196  typedef struct
1196     onto the failure stack.  Other register information, such as the     onto the failure stack.  Other register information, such as the
1197     starting and ending positions (which are addresses), and the list of     starting and ending positions (which are addresses), and the list of
1198     inner groups (which is a bits list) are maintained in separate     inner groups (which is a bits list) are maintained in separate
1199     variables.       variables.
1200      
1201     We are making a (strictly speaking) nonportable assumption here: that     We are making a (strictly speaking) nonportable assumption here: that
1202     the compiler will pack our bit fields into something that fits into     the compiler will pack our bit fields into something that fits into
1203     the type of `word', i.e., is something that fits into one item on the     the type of `word', i.e., is something that fits into one item on the
# Line 1253  static fail_stack_type fail_stack; Line 1255  static fail_stack_type fail_stack;
1255  static const char **     regstart, **     regend;  static const char **     regstart, **     regend;
1256  static const char ** old_regstart, ** old_regend;  static const char ** old_regstart, ** old_regend;
1257  static const char **best_regstart, **best_regend;  static const char **best_regstart, **best_regend;
1258  static register_info_type *reg_info;  static register_info_type *reg_info;
1259  static const char **reg_dummy;  static const char **reg_dummy;
1260  static register_info_type *reg_info_dummy;  static register_info_type *reg_info_dummy;
1261  #endif  #endif
# Line 1267  static boolean at_begline_loc_p (), at_e Line 1269  static boolean at_begline_loc_p (), at_e
1269  static boolean group_in_compile_stack ();  static boolean group_in_compile_stack ();
1270  static reg_errcode_t compile_range ();  static reg_errcode_t compile_range ();
1271    
1272  /* Fetch the next character in the uncompiled pattern---translating it  /* Fetch the next character in the uncompiled pattern---translating it
1273     if necessary.  Also cast from a signed character in the constant     if necessary.  Also cast from a signed character in the constant
1274     string passed to us by the user to an unsigned char that we can use     string passed to us by the user to an unsigned char that we can use
1275     as an array index (in, e.g., `translate').  */     as an array index (in, e.g., `translate').  */
# Line 1407  typedef struct Line 1409  typedef struct
1409    pattern_offset_t begalt_offset;    pattern_offset_t begalt_offset;
1410    pattern_offset_t fixup_alt_jump;    pattern_offset_t fixup_alt_jump;
1411    pattern_offset_t inner_group_offset;    pattern_offset_t inner_group_offset;
1412    pattern_offset_t laststart_offset;      pattern_offset_t laststart_offset;
1413    regnum_t regnum;    regnum_t regnum;
1414  } compile_stack_elt_t;  } compile_stack_elt_t;
1415    
# Line 1450  typedef struct Line 1452  typedef struct
1452             PATFETCH (c);                                                \             PATFETCH (c);                                                \
1453           }                                                              \           }                                                              \
1454         }                                                                \         }                                                                \
1455      }                }
1456    
1457  #define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */  #define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
1458    
# Line 1476  typedef struct Line 1478  typedef struct
1478       `fastmap_accurate' is zero;       `fastmap_accurate' is zero;
1479       `re_nsub' is the number of subexpressions in PATTERN;       `re_nsub' is the number of subexpressions in PATTERN;
1480       `not_bol' and `not_eol' are zero;       `not_bol' and `not_eol' are zero;
1481      
1482     The `fastmap' and `newline_anchor' fields are neither     The `fastmap' and `newline_anchor' fields are neither
1483     examined nor set.  */     examined nor set.  */
1484    
# Line 1495  regex_compile (pattern, size, syntax, bu Line 1497  regex_compile (pattern, size, syntax, bu
1497       `char *' (i.e., signed), we declare these variables as unsigned, so       `char *' (i.e., signed), we declare these variables as unsigned, so
1498       they can be reliably used as array indices.  */       they can be reliably used as array indices.  */
1499    register unsigned char c, c1;    register unsigned char c, c1;
1500      
1501    /* A random temporary spot in PATTERN.  */    /* A random temporary spot in PATTERN.  */
1502    const char *p1;    const char *p1;
1503    
1504    /* Points to the end of the buffer, where we should append.  */    /* Points to the end of the buffer, where we should append.  */
1505    register unsigned char *b;    register unsigned char *b;
1506      
1507    /* Keeps track of unclosed groups.  */    /* Keeps track of unclosed groups.  */
1508    compile_stack_type compile_stack;    compile_stack_type compile_stack;
1509    
1510    /* Points to the current (ending) position in the pattern.  */    /* Points to the current (ending) position in the pattern.  */
1511    const char *p = pattern;    const char *p = pattern;
1512    const char *pend = pattern + size;    const char *pend = pattern + size;
1513      
1514    /* How to translate the characters in the pattern.  */    /* How to translate the characters in the pattern.  */
1515    char *translate = bufp->translate;    char *translate = bufp->translate;
1516    
# Line 1529  regex_compile (pattern, size, syntax, bu Line 1531  regex_compile (pattern, size, syntax, bu
1531    /* Place in the uncompiled pattern (i.e., the {) to    /* Place in the uncompiled pattern (i.e., the {) to
1532       which to go back if the interval is invalid.  */       which to go back if the interval is invalid.  */
1533    const char *beg_interval;    const char *beg_interval;
1534                    
1535    /* Address of the place where a forward jump should go to the end of    /* Address of the place where a forward jump should go to the end of
1536       the containing expression.  Each alternative of an `or' -- except the       the containing expression.  Each alternative of an `or' -- except the
1537       last -- ends with a forward jump of this sort.  */       last -- ends with a forward jump of this sort.  */
# Line 1545  regex_compile (pattern, size, syntax, bu Line 1547  regex_compile (pattern, size, syntax, bu
1547    if (debug)    if (debug)
1548      {      {
1549        unsigned debug_count;        unsigned debug_count;
1550          
1551        for (debug_count = 0; debug_count < size; debug_count++)        for (debug_count = 0; debug_count < size; debug_count++)
1552          printchar (pattern[debug_count]);          printchar (pattern[debug_count]);
1553        putchar ('\n');        putchar ('\n');
# Line 1569  regex_compile (pattern, size, syntax, bu Line 1571  regex_compile (pattern, size, syntax, bu
1571       printer (for debugging) will think there's no pattern.  We reset it       printer (for debugging) will think there's no pattern.  We reset it
1572       at the end.  */       at the end.  */
1573    bufp->used = 0;    bufp->used = 0;
1574      
1575    /* Always count groups, whether or not bufp->no_sub is set.  */    /* Always count groups, whether or not bufp->no_sub is set.  */
1576    bufp->re_nsub = 0;                                bufp->re_nsub = 0;
1577    
1578  #if !defined (emacs) && !defined (SYNTAX_TABLE)  #if !defined (emacs) && !defined (SYNTAX_TABLE)
1579    /* Initialize the syntax table.  */    /* Initialize the syntax table.  */
# Line 1622  regex_compile (pattern, size, syntax, bu Line 1624  regex_compile (pattern, size, syntax, bu
1624          case '$':          case '$':
1625            {            {
1626              if (   /* If at end of pattern, it's an operator.  */              if (   /* If at end of pattern, it's an operator.  */
1627                     p == pend                     p == pend
1628                     /* If context independent, it's an operator.  */                     /* If context independent, it's an operator.  */
1629                  || syntax & RE_CONTEXT_INDEP_ANCHORS                  || syntax & RE_CONTEXT_INDEP_ANCHORS
1630                     /* Otherwise, depends on what's next.  */                     /* Otherwise, depends on what's next.  */
# Line 1653  regex_compile (pattern, size, syntax, bu Line 1655  regex_compile (pattern, size, syntax, bu
1655            {            {
1656              /* Are we optimizing this jump?  */              /* Are we optimizing this jump?  */
1657              boolean keep_string_p = false;              boolean keep_string_p = false;
1658                
1659              /* 1 means zero (many) matches is allowed.  */              /* 1 means zero (many) matches is allowed.  */
1660              char zero_times_ok = 0, many_times_ok = 0;              char zero_times_ok = 0, many_times_ok = 0;
1661    
# Line 1701  regex_compile (pattern, size, syntax, bu Line 1703  regex_compile (pattern, size, syntax, bu
1703    
1704              /* Star, etc. applied to an empty pattern is equivalent              /* Star, etc. applied to an empty pattern is equivalent
1705                 to an empty pattern.  */                 to an empty pattern.  */
1706              if (!laststart)                if (!laststart)
1707                break;                break;
1708    
1709              /* Now we know whether or not zero matches is allowed              /* Now we know whether or not zero matches is allowed
# Line 1710  regex_compile (pattern, size, syntax, bu Line 1712  regex_compile (pattern, size, syntax, bu
1712                { /* More than one repetition is allowed, so put in at the                { /* More than one repetition is allowed, so put in at the
1713                     end a backward relative jump from `b' to before the next                     end a backward relative jump from `b' to before the next
1714                     jump we're going to put in below (which jumps from                     jump we're going to put in below (which jumps from
1715                     laststart to after this jump).                       laststart to after this jump).
1716    
1717                     But if we are at the `*' in the exact sequence `.*\n',                     But if we are at the `*' in the exact sequence `.*\n',
1718                     insert an unconditional jump backwards to the .,                     insert an unconditional jump backwards to the .,
# Line 1787  regex_compile (pattern, size, syntax, bu Line 1789  regex_compile (pattern, size, syntax, bu
1789    
1790              /* We test `*p == '^' twice, instead of using an if              /* We test `*p == '^' twice, instead of using an if
1791                 statement, so we only need one BUF_PUSH.  */                 statement, so we only need one BUF_PUSH.  */
1792              BUF_PUSH (*p == '^' ? charset_not : charset);              BUF_PUSH (*p == '^' ? charset_not : charset);
1793              if (*p == '^')              if (*p == '^')
1794                p++;                p++;
1795    
# Line 1837  regex_compile (pattern, size, syntax, bu Line 1839  regex_compile (pattern, size, syntax, bu
1839                     was a character: if this is a hyphen not at the                     was a character: if this is a hyphen not at the
1840                     beginning or the end of a list, then it's the range                     beginning or the end of a list, then it's the range
1841                     operator.  */                     operator.  */
1842                  if (c == '-'                  if (c == '-'
1843                      && !(p - 2 >= pattern && p[-2] == '[')                      && !(p - 2 >= pattern && p[-2] == '[')
1844                      && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')                      && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
1845                      && *p != ']')                      && *p != ']')
1846                    {                    {
# Line 1853  regex_compile (pattern, size, syntax, bu Line 1855  regex_compile (pattern, size, syntax, bu
1855    
1856                      /* Move past the `-'.  */                      /* Move past the `-'.  */
1857                      PATFETCH (c1);                      PATFETCH (c1);
1858                        
1859                      ret = compile_range (&p, pend, translate, syntax, b);                      ret = compile_range (&p, pend, translate, syntax, b);
1860                      if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);                      if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
1861                    }                    }
# Line 1882  regex_compile (pattern, size, syntax, bu Line 1884  regex_compile (pattern, size, syntax, bu
1884                      str[c1] = '\0';                      str[c1] = '\0';
1885    
1886                      /* If isn't a word bracketed by `[:' and:`]':                      /* If isn't a word bracketed by `[:' and:`]':
1887                         undo the ending character, the letters, and leave                         undo the ending character, the letters, and leave
1888                         the leading `:' and `[' (but set bits for them).  */                         the leading `:' and `[' (but set bits for them).  */
1889                      if (c == ':' && *p == ']')                      if (c == ':' && *p == ']')
1890                        {                        {
# Line 1899  regex_compile (pattern, size, syntax, bu Line 1901  regex_compile (pattern, size, syntax, bu
1901                          boolean is_space = STREQ (str, "space");                          boolean is_space = STREQ (str, "space");
1902                          boolean is_upper = STREQ (str, "upper");                          boolean is_upper = STREQ (str, "upper");
1903                          boolean is_xdigit = STREQ (str, "xdigit");                          boolean is_xdigit = STREQ (str, "xdigit");
1904                            
1905                          if (!IS_CHAR_CLASS (str))                          if (!IS_CHAR_CLASS (str))
1906                            FREE_STACK_RETURN (REG_ECTYPE);                            FREE_STACK_RETURN (REG_ECTYPE);
1907    
1908                          /* Throw away the ] at the end of the character                          /* Throw away the ] at the end of the character
1909                             class.  */                             class.  */
1910                          PATFETCH (c);                                                            PATFETCH (c);
1911    
1912                          if (p == pend) FREE_STACK_RETURN (REG_EBRACK);                          if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
1913    
# Line 1934  regex_compile (pattern, size, syntax, bu Line 1936  regex_compile (pattern, size, syntax, bu
1936                      else                      else
1937                        {                        {
1938                          c1++;                          c1++;
1939                          while (c1--)                              while (c1--)
1940                            PATUNFETCH;                            PATUNFETCH;
1941                          SET_LIST_BIT ('[');                          SET_LIST_BIT ('[');
1942                          SET_LIST_BIT (':');                          SET_LIST_BIT (':');
# Line 1950  regex_compile (pattern, size, syntax, bu Line 1952  regex_compile (pattern, size, syntax, bu
1952    
1953              /* Discard any (non)matching list bytes that are all 0 at the              /* Discard any (non)matching list bytes that are all 0 at the
1954                 end of the map.  Decrease the map-length byte too.  */                 end of the map.  Decrease the map-length byte too.  */
1955              while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)              while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
1956                b[-1]--;                b[-1]--;
1957              b += b[-1];              b += b[-1];
1958            }            }
1959            break;            break;
# Line 2011  regex_compile (pattern, size, syntax, bu Line 2013  regex_compile (pattern, size, syntax, bu
2013                regnum++;                regnum++;
2014    
2015                if (COMPILE_STACK_FULL)                if (COMPILE_STACK_FULL)
2016                  {                  {
2017                    RETALLOC (compile_stack.stack, compile_stack.size << 1,                    RETALLOC (compile_stack.stack, compile_stack.size << 1,
2018                              compile_stack_elt_t);                              compile_stack_elt_t);
2019                    if (compile_stack.stack == NULL) return REG_ESPACE;                    if (compile_stack.stack == NULL) return REG_ESPACE;
# Line 2024  regex_compile (pattern, size, syntax, bu Line 2026  regex_compile (pattern, size, syntax, bu
2026                   whole pattern moves because of realloc, they will still                   whole pattern moves because of realloc, they will still
2027                   be valid.  */                   be valid.  */
2028                COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;                COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
2029                COMPILE_STACK_TOP.fixup_alt_jump                COMPILE_STACK_TOP.fixup_alt_jump
2030                  = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;                  = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
2031                COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;                COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
2032                COMPILE_STACK_TOP.regnum = regnum;                COMPILE_STACK_TOP.regnum = regnum;
# Line 2038  regex_compile (pattern, size, syntax, bu Line 2040  regex_compile (pattern, size, syntax, bu
2040                    COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;                    COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
2041                    BUF_PUSH_3 (start_memory, regnum, 0);                    BUF_PUSH_3 (start_memory, regnum, 0);
2042                  }                  }
2043                    
2044                compile_stack.avail++;                compile_stack.avail++;
2045    
2046                fixup_alt_jump = 0;                fixup_alt_jump = 0;
# Line 2067  regex_compile (pattern, size, syntax, bu Line 2069  regex_compile (pattern, size, syntax, bu
2069                       `pop_failure_jump' to pop.  See comments at                       `pop_failure_jump' to pop.  See comments at
2070                       `push_dummy_failure' in `re_match_2'.  */                       `push_dummy_failure' in `re_match_2'.  */
2071                    BUF_PUSH (push_dummy_failure);                    BUF_PUSH (push_dummy_failure);
2072                      
2073                    /* We allocated space for this jump when we assigned                    /* We allocated space for this jump when we assigned
2074                       to `fixup_alt_jump', in the `handle_alt' case below.  */                       to `fixup_alt_jump', in the `handle_alt' case below.  */
2075                    STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);                    STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
# Line 2089  regex_compile (pattern, size, syntax, bu Line 2091  regex_compile (pattern, size, syntax, bu
2091                     as in `(ab)c(de)' -- the second group is #2.  */                     as in `(ab)c(de)' -- the second group is #2.  */
2092                  regnum_t this_group_regnum;                  regnum_t this_group_regnum;
2093    
2094                  compile_stack.avail--;                            compile_stack.avail--;
2095                  begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;                  begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
2096                  fixup_alt_jump                  fixup_alt_jump
2097                    = COMPILE_STACK_TOP.fixup_alt_jump                    = COMPILE_STACK_TOP.fixup_alt_jump
2098                      ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1                      ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
2099                      : 0;                      : 0;
2100                  laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;                  laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
2101                  this_group_regnum = COMPILE_STACK_TOP.regnum;                  this_group_regnum = COMPILE_STACK_TOP.regnum;
# Line 2108  regex_compile (pattern, size, syntax, bu Line 2110  regex_compile (pattern, size, syntax, bu
2110                    {                    {
2111                      unsigned char *inner_group_loc                      unsigned char *inner_group_loc
2112                        = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;                        = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
2113                        
2114                      *inner_group_loc = regnum - this_group_regnum;                      *inner_group_loc = regnum - this_group_regnum;
2115                      BUF_PUSH_3 (stop_memory, this_group_regnum,                      BUF_PUSH_3 (stop_memory, this_group_regnum,
2116                                  regnum - this_group_regnum);                                  regnum - this_group_regnum);
# Line 2137  regex_compile (pattern, size, syntax, bu Line 2139  regex_compile (pattern, size, syntax, bu
2139                   jump (put in below, which in turn will jump to the next                   jump (put in below, which in turn will jump to the next
2140                   (if any) alternative's such jump, etc.).  The last such                   (if any) alternative's such jump, etc.).  The last such
2141                   jump jumps to the correct final destination.  A picture:                   jump jumps to the correct final destination.  A picture:
2142                            _____ _____                            _____ _____
2143                            |   | |   |                              |   | |   |
2144                            |   v |   v                            |   v |   v
2145                           a | b   | c                             a | b   | c
2146    
2147                   If we are at `b', then fixup_alt_jump right now points to a                   If we are at `b', then fixup_alt_jump right now points to a
2148                   three-byte space after `a'.  We'll put in the jump, set                   three-byte space after `a'.  We'll put in the jump, set
# Line 2162  regex_compile (pattern, size, syntax, bu Line 2164  regex_compile (pattern, size, syntax, bu
2164                break;                break;
2165    
2166    
2167              case '{':              case '{':
2168                /* If \{ is a literal.  */                /* If \{ is a literal.  */
2169                if (!(syntax & RE_INTERVALS)                if (!(syntax & RE_INTERVALS)
2170                       /* If we're at `\{' and it's not the open-interval                       /* If we're at `\{' and it's not the open-interval
2171                          operator.  */                          operator.  */
2172                    || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))                    || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
2173                    || (p - 2 == pattern  &&  p == pend))                    || (p - 2 == pattern  &&  p == pend))
# Line 2204  regex_compile (pattern, size, syntax, bu Line 2206  regex_compile (pattern, size, syntax, bu
2206                    {                    {
2207                      if (syntax & RE_NO_BK_BRACES)                      if (syntax & RE_NO_BK_BRACES)
2208                        goto unfetch_interval;                        goto unfetch_interval;
2209                      else                      else
2210                        FREE_STACK_RETURN (REG_BADBR);                        FREE_STACK_RETURN (REG_BADBR);
2211                    }                    }
2212    
2213                  if (!(syntax & RE_NO_BK_BRACES))                  if (!(syntax & RE_NO_BK_BRACES))
2214                    {                    {
2215                      if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);                      if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
2216    
# Line 2219  regex_compile (pattern, size, syntax, bu Line 2221  regex_compile (pattern, size, syntax, bu
2221                    {                    {
2222                      if (syntax & RE_NO_BK_BRACES)                      if (syntax & RE_NO_BK_BRACES)
2223                        goto unfetch_interval;                        goto unfetch_interval;
2224                      else                      else
2225                        FREE_STACK_RETURN (REG_BADBR);                        FREE_STACK_RETURN (REG_BADBR);
2226                    }                    }
2227    
# Line 2255  regex_compile (pattern, size, syntax, bu Line 2257  regex_compile (pattern, size, syntax, bu
2257                        jump_n <succeed_n addr> <jump count>                        jump_n <succeed_n addr> <jump count>
2258                      (The upper bound and `jump_n' are omitted if                      (The upper bound and `jump_n' are omitted if
2259                      `upper_bound' is 1, though.)  */                      `upper_bound' is 1, though.)  */
2260                   else                   else
2261                     { /* If the upper bound is > 1, we need to insert                     { /* If the upper bound is > 1, we need to insert
2262                          more at the end of the loop.  */                          more at the end of the loop.  */
2263                       unsigned nbytes = 10 + (upper_bound > 1) * 10;                       unsigned nbytes = 10 + (upper_bound > 1) * 10;
# Line 2272  regex_compile (pattern, size, syntax, bu Line 2274  regex_compile (pattern, size, syntax, bu
2274                                     lower_bound);                                     lower_bound);
2275                       b += 5;                       b += 5;
2276    
2277                       /* Code to initialize the lower bound.  Insert                       /* Code to initialize the lower bound.  Insert
2278                          before the `succeed_n'.  The `5' is the last two                          before the `succeed_n'.  The `5' is the last two
2279                          bytes of this `set_number_at', plus 3 bytes of                          bytes of this `set_number_at', plus 3 bytes of
2280                          the following `succeed_n'.  */                          the following `succeed_n'.  */
# Line 2283  regex_compile (pattern, size, syntax, bu Line 2285  regex_compile (pattern, size, syntax, bu
2285                         { /* More than one repetition is allowed, so                         { /* More than one repetition is allowed, so
2286                              append a backward jump to the `succeed_n'                              append a backward jump to the `succeed_n'
2287                              that starts this interval.                              that starts this interval.
2288                                
2289                              When we've reached this during matching,                              When we've reached this during matching,
2290                              we'll have matched the interval once, so                              we'll have matched the interval once, so
2291                              jump back only `upper_bound - 1' times.  */                              jump back only `upper_bound - 1' times.  */
# Line 2301  regex_compile (pattern, size, syntax, bu Line 2303  regex_compile (pattern, size, syntax, bu
2303                              so everything is getting moved up by 5.                              so everything is getting moved up by 5.
2304                              Conclusion: (b - 2) - (laststart + 3) + 5,                              Conclusion: (b - 2) - (laststart + 3) + 5,
2305                              i.e., b - laststart.                              i.e., b - laststart.
2306                                
2307                              We insert this at the beginning of the loop                              We insert this at the beginning of the loop
2308                              so that if we fail during matching, we'll                              so that if we fail during matching, we'll
2309                              reinitialize the bounds.  */                              reinitialize the bounds.  */
# Line 2322  regex_compile (pattern, size, syntax, bu Line 2324  regex_compile (pattern, size, syntax, bu
2324                 beg_interval = NULL;                 beg_interval = NULL;
2325    
2326                 /* normal_char and normal_backslash need `c'.  */                 /* normal_char and normal_backslash need `c'.  */
2327                 PATFETCH (c);                     PATFETCH (c);
2328    
2329                 if (!(syntax & RE_NO_BK_BRACES))                 if (!(syntax & RE_NO_BK_BRACES))
2330                   {                   {
# Line 2338  regex_compile (pattern, size, syntax, bu Line 2340  regex_compile (pattern, size, syntax, bu
2340                BUF_PUSH (at_dot);                BUF_PUSH (at_dot);
2341                break;                break;
2342    
2343              case 's':                case 's':
2344                laststart = b;                laststart = b;
2345                PATFETCH (c);                PATFETCH (c);
2346                BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);                BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
# Line 2429  regex_compile (pattern, size, syntax, bu Line 2431  regex_compile (pattern, size, syntax, bu
2431          /* Expects the character in `c'.  */          /* Expects the character in `c'.  */
2432          normal_char:          normal_char:
2433                /* If no exactn currently being built.  */                /* If no exactn currently being built.  */
2434            if (!pending_exact            if (!pending_exact
2435    
2436                /* If last exactn not at current position.  */                /* If last exactn not at current position.  */
2437                || pending_exact + *pending_exact + 1 != b                || pending_exact + *pending_exact + 1 != b
2438                  
2439                /* We have only one byte following the exactn for the count.  */                /* We have only one byte following the exactn for the count.  */
2440                || *pending_exact == (1 << BYTEWIDTH) - 1                || *pending_exact == (1 << BYTEWIDTH) - 1
2441    
# Line 2448  regex_compile (pattern, size, syntax, bu Line 2450  regex_compile (pattern, size, syntax, bu
2450                        : (p[0] == '\\' && p[1] == '{'))))                        : (p[0] == '\\' && p[1] == '{'))))
2451              {              {
2452                /* Start building a new exactn.  */                /* Start building a new exactn.  */
2453                  
2454                laststart = b;                laststart = b;
2455    
2456                BUF_PUSH_2 (exactn, 0);                BUF_PUSH_2 (exactn, 0);
2457                pending_exact = b - 1;                pending_exact = b - 1;
2458              }              }
2459                
2460            BUF_PUSH (c);            BUF_PUSH (c);
2461            (*pending_exact)++;            (*pending_exact)++;
2462            break;            break;
2463          } /* switch (c) */          } /* switch (c) */
2464      } /* while p != pend */      } /* while p != pend */
2465    
2466      
2467    /* Through the pattern now.  */    /* Through the pattern now.  */
2468      
2469    if (fixup_alt_jump)    if (fixup_alt_jump)
2470      STORE_JUMP (jump_past_alt, fixup_alt_jump, b);      STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
2471    
2472    if (!COMPILE_STACK_EMPTY)    if (!COMPILE_STACK_EMPTY)
2473      FREE_STACK_RETURN (REG_EPAREN);      FREE_STACK_RETURN (REG_EPAREN);
2474    
2475    free (compile_stack.stack);    free (compile_stack.stack);
# Line 2500  regex_compile (pattern, size, syntax, bu Line 2502  regex_compile (pattern, size, syntax, bu
2502  #ifdef emacs  #ifdef emacs
2503          if (! fail_stack.stack)          if (! fail_stack.stack)
2504            fail_stack.stack            fail_stack.stack
2505              = (fail_stack_elt_t *) xmalloc (fail_stack.size              = (fail_stack_elt_t *) xmalloc (fail_stack.size
2506                                              * sizeof (fail_stack_elt_t));                                              * sizeof (fail_stack_elt_t));
2507          else          else
2508            fail_stack.stack            fail_stack.stack
# Line 2510  regex_compile (pattern, size, syntax, bu Line 2512  regex_compile (pattern, size, syntax, bu
2512  #else /* not emacs */  #else /* not emacs */
2513          if (! fail_stack.stack)          if (! fail_stack.stack)
2514            fail_stack.stack            fail_stack.stack
2515              = (fail_stack_elt_t *) malloc (fail_stack.size              = (fail_stack_elt_t *) malloc (fail_stack.size
2516                                             * sizeof (fail_stack_elt_t));                                             * sizeof (fail_stack_elt_t));
2517          else          else
2518            fail_stack.stack            fail_stack.stack
# Line 2573  insert_op1 (op, loc, arg, end) Line 2575  insert_op1 (op, loc, arg, end)
2575      re_opcode_t op;      re_opcode_t op;
2576      unsigned char *loc;      unsigned char *loc;
2577      int arg;      int arg;
2578      unsigned char *end;          unsigned char *end;
2579  {  {
2580    register unsigned char *pfrom = end;    register unsigned char *pfrom = end;
2581    register unsigned char *pto = end + 3;    register unsigned char *pto = end + 3;
2582    
2583    while (pfrom != loc)    while (pfrom != loc)
2584      *--pto = *--pfrom;      *--pto = *--pfrom;
2585        
2586    store_op1 (op, loc, arg);    store_op1 (op, loc, arg);
2587  }  }
2588    
# Line 2592  insert_op2 (op, loc, arg1, arg2, end) Line 2594  insert_op2 (op, loc, arg1, arg2, end)
2594      re_opcode_t op;      re_opcode_t op;
2595      unsigned char *loc;      unsigned char *loc;
2596      int arg1, arg2;      int arg1, arg2;
2597      unsigned char *end;          unsigned char *end;
2598  {  {
2599    register unsigned char *pfrom = end;    register unsigned char *pfrom = end;
2600    register unsigned char *pto = end + 5;    register unsigned char *pto = end + 5;
2601    
2602    while (pfrom != loc)    while (pfrom != loc)
2603      *--pto = *--pfrom;      *--pto = *--pfrom;
2604        
2605    store_op2 (op, loc, arg1, arg2);    store_op2 (op, loc, arg1, arg2);
2606  }  }
2607    
# Line 2615  at_begline_loc_p (pattern, p, syntax) Line 2617  at_begline_loc_p (pattern, p, syntax)
2617  {  {
2618    const char *prev = p - 2;    const char *prev = p - 2;
2619    boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';    boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
2620      
2621    return    return
2622         /* After a subexpression?  */         /* After a subexpression?  */
2623         (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))         (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
# Line 2635  at_endline_loc_p (p, pend, syntax) Line 2637  at_endline_loc_p (p, pend, syntax)
2637    const char *next = p;    const char *next = p;
2638    boolean next_backslash = *next == '\\';    boolean next_backslash = *next == '\\';
2639    const char *next_next = p + 1 < pend ? p + 1 : NULL;    const char *next_next = p + 1 < pend ? p + 1 : NULL;
2640      
2641    return    return
2642         /* Before a subexpression?  */         /* Before a subexpression?  */
2643         (syntax & RE_NO_BK_PARENS ? *next == ')'         (syntax & RE_NO_BK_PARENS ? *next == ')'
# Line 2646  at_endline_loc_p (p, pend, syntax) Line 2648  at_endline_loc_p (p, pend, syntax)
2648  }  }
2649    
2650    
2651  /* Returns true if REGNUM is in one of COMPILE_STACK's elements and  /* Returns true if REGNUM is in one of COMPILE_STACK's elements and
2652     false if it's not.  */     false if it's not.  */
2653    
2654  static boolean  static boolean
# Line 2656  group_in_compile_stack (compile_stack, r Line 2658  group_in_compile_stack (compile_stack, r
2658  {  {
2659    int this_element;    int this_element;
2660    
2661    for (this_element = compile_stack.avail - 1;      for (this_element = compile_stack.avail - 1;
2662         this_element >= 0;         this_element >= 0;
2663         this_element--)         this_element--)
2664      if (compile_stack.stack[this_element].regnum == regnum)      if (compile_stack.stack[this_element].regnum == regnum)
2665        return true;        return true;
# Line 2671  group_in_compile_stack (compile_stack, r Line 2673  group_in_compile_stack (compile_stack, r
2673     starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)     starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)
2674     Then we set the translation of all bits between the starting and     Then we set the translation of all bits between the starting and
2675     ending characters (inclusive) in the compiled pattern B.     ending characters (inclusive) in the compiled pattern B.
2676      
2677     Return an error code.     Return an error code.
2678      
2679     We use these short variable names so we can use the same macros as     We use these short variable names so we can use the same macros as
2680     `regex_compile' itself.  */     `regex_compile' itself.  */
2681    
# Line 2688  compile_range (p_ptr, pend, translate, s Line 2690  compile_range (p_ptr, pend, translate, s
2690    
2691    const char *p = *p_ptr;    const char *p = *p_ptr;
2692    int range_start, range_end;    int range_start, range_end;
2693      
2694    if (p == pend)    if (p == pend)
2695      return REG_ERANGE;      return REG_ERANGE;
2696    
# Line 2697  compile_range (p_ptr, pend, translate, s Line 2699  compile_range (p_ptr, pend, translate, s
2699       is set, the range endpoints will be negative if we fetch using a       is set, the range endpoints will be negative if we fetch using a
2700       signed char *.       signed char *.
2701    
2702       We also want to fetch the endpoints without translating them; the       We also want to fetch the endpoints without translating them; the
2703       appropriate translation is done in the bit-setting loop below.  */       appropriate translation is done in the bit-setting loop below.  */
2704    /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *.  */    /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *.  */
2705    range_start = ((const unsigned char *) p)[-2];    range_start = ((const unsigned char *) p)[-2];
# Line 2719  compile_range (p_ptr, pend, translate, s Line 2721  compile_range (p_ptr, pend, translate, s
2721      {      {
2722        SET_LIST_BIT (TRANSLATE (this_char));        SET_LIST_BIT (TRANSLATE (this_char));
2723      }      }
2724      
2725    return REG_NOERROR;    return REG_NOERROR;
2726  }  }
2727    
# Line 2730  compile_range (p_ptr, pend, translate, s Line 2732  compile_range (p_ptr, pend, translate, s
2732    
2733     The caller must supply the address of a (1 << BYTEWIDTH)-byte data     The caller must supply the address of a (1 << BYTEWIDTH)-byte data
2734     area as BUFP->fastmap.     area as BUFP->fastmap.
2735      
2736     We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in     We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
2737     the pattern buffer.     the pattern buffer.
2738    
# Line 2749  re_compile_fastmap (bufp) Line 2751  re_compile_fastmap (bufp)
2751  #endif  #endif
2752    /* We don't push any register information onto the failure stack.  */    /* We don't push any register information onto the failure stack.  */
2753    unsigned num_regs = 0;    unsigned num_regs = 0;
2754      
2755    register char *fastmap = bufp->fastmap;    register char *fastmap = bufp->fastmap;
2756    unsigned char *pattern = bufp->buffer;    unsigned char *pattern = bufp->buffer;
2757    unsigned long size = bufp->used;    unsigned long size = bufp->used;
# Line 2766  re_compile_fastmap (bufp) Line 2768  re_compile_fastmap (bufp)
2768    boolean succeed_n_p = false;    boolean succeed_n_p = false;
2769    
2770    assert (fastmap != NULL && p != NULL);    assert (fastmap != NULL && p != NULL);
2771      
2772    INIT_FAIL_STACK ();    INIT_FAIL_STACK ();
2773    bzero (fastmap, 1 << BYTEWIDTH);  /* Assume nothing's valid.  */    bzero (fastmap, 1 << BYTEWIDTH);  /* Assume nothing's valid.  */
2774    bufp->fastmap_accurate = 1;       /* It will be when we're done.  */    bufp->fastmap_accurate = 1;       /* It will be when we're done.  */
2775    bufp->can_be_null = 0;    bufp->can_be_null = 0;
2776          
2777    while (p != pend || !FAIL_STACK_EMPTY ())    while (p != pend || !FAIL_STACK_EMPTY ())
2778      {      {
2779        if (p == pend)        if (p == pend)
2780          {          {
2781            bufp->can_be_null |= path_can_be_null;            bufp->can_be_null |= path_can_be_null;
2782              
2783            /* Reset for next path.  */            /* Reset for next path.  */
2784            path_can_be_null = true;            path_can_be_null = true;
2785              
2786            p = fail_stack.stack[--fail_stack.avail];            p = fail_stack.stack[--fail_stack.avail];
2787          }          }
2788    
2789        /* We should never be about to go beyond the end of the pattern.  */        /* We should never be about to go beyond the end of the pattern.  */
2790        assert (p < pend);        assert (p < pend);
2791          
2792  #ifdef SWITCH_ENUM_BUG  #ifdef SWITCH_ENUM_BUG
2793        switch ((int) ((re_opcode_t) *p++))        switch ((int) ((re_opcode_t) *p++))
2794  #else  #else
# Line 2913  re_compile_fastmap (bufp) Line 2915  re_compile_fastmap (bufp)
2915          case jump_past_alt:          case jump_past_alt:
2916          case dummy_failure_jump:          case dummy_failure_jump:
2917            EXTRACT_NUMBER_AND_INCR (j, p);            EXTRACT_NUMBER_AND_INCR (j, p);
2918            p += j;                  p += j;
2919            if (j > 0)            if (j > 0)
2920              continue;              continue;
2921                
2922            /* Jump backward implies we just went through the body of a            /* Jump backward implies we just went through the body of a
2923               loop and matched nothing.  Opcode jumped to should be               loop and matched nothing.  Opcode jumped to should be
2924               `on_failure_jump' or `succeed_n'.  Just treat it like an               `on_failure_jump' or `succeed_n'.  Just treat it like an
# Line 2928  re_compile_fastmap (bufp) Line 2930  re_compile_fastmap (bufp)
2930    
2931            p++;            p++;
2932            EXTRACT_NUMBER_AND_INCR (j, p);            EXTRACT_NUMBER_AND_INCR (j, p);
2933            p += j;                          p += j;
2934              
2935            /* If what's on the stack is where we are now, pop it.  */            /* If what's on the stack is where we are now, pop it.  */
2936            if (!FAIL_STACK_EMPTY ()            if (!FAIL_STACK_EMPTY ()
2937                && fail_stack.stack[fail_stack.avail - 1] == p)                && fail_stack.stack[fail_stack.avail - 1] == p)
2938              fail_stack.avail--;              fail_stack.avail--;
2939    
# Line 2969  re_compile_fastmap (bufp) Line 2971  re_compile_fastmap (bufp)
2971    
2972          case succeed_n:          case succeed_n:
2973            /* Get to the number of times to succeed.  */            /* Get to the number of times to succeed.  */
2974            p += 2;                          p += 2;
2975    
2976            /* Increment p past the n for when k != 0.  */            /* Increment p past the n for when k != 0.  */
2977            EXTRACT_NUMBER_AND_INCR (k, p);            EXTRACT_NUMBER_AND_INCR (k, p);
# Line 3060  re_search (bufp, string, size, startpos, Line 3062  re_search (bufp, string, size, startpos,
3062       int size, startpos, range;       int size, startpos, range;
3063       struct re_registers *regs;       struct re_registers *regs;
3064  {  {
3065    return re_search_2 (bufp, NULL, 0, string, size, startpos, range,    return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
3066                        regs, size);                        regs, size);
3067  }  }
3068    
# Line 3068  re_search (bufp, string, size, startpos, Line 3070  re_search (bufp, string, size, startpos,
3070  /* Using the compiled pattern in BUFP->buffer, first tries to match the  /* Using the compiled pattern in BUFP->buffer, first tries to match the
3071     virtual concatenation of STRING1 and STRING2, starting first at index     virtual concatenation of STRING1 and STRING2, starting first at index
3072     STARTPOS, then at STARTPOS + 1, and so on.     STARTPOS, then at STARTPOS + 1, and so on.
3073      
3074     STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.     STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
3075      
3076     RANGE is how far to scan while trying to match.  RANGE = 0 means try     RANGE is how far to scan while trying to match.  RANGE = 0 means try
3077     only at STARTPOS; in general, the last start tried is STARTPOS +     only at STARTPOS; in general, the last start tried is STARTPOS +
3078     RANGE.     RANGE.
3079      
3080     In REGS, return the indices of the virtual concatenation of STRING1     In REGS, return the indices of the virtual concatenation of STRING1
3081     and STRING2 that matched the entire BUFP->buffer and its contained     and STRING2 that matched the entire BUFP->buffer and its contained
3082     subexpressions.     subexpressions.
3083      
3084     Do not consider matching one past the index STOP in the virtual     Do not consider matching one past the index STOP in the virtual
3085     concatenation of STRING1 and STRING2.     concatenation of STRING1 and STRING2.
3086    
# Line 3105  re_search_2 (bufp, string1, size1, strin Line 3107  re_search_2 (bufp, string1, size1, strin
3107    /* Check for out-of-range STARTPOS.  */    /* Check for out-of-range STARTPOS.  */
3108    if (startpos < 0 || startpos > total_size)    if (startpos < 0 || startpos > total_size)
3109      return -1;      return -1;
3110        
3111    /* Fix up RANGE if it might eventually take us outside    /* Fix up RANGE if it might eventually take us outside
3112       the virtual concatenation of STRING1 and STRING2.  */       the virtual concatenation of STRING1 and STRING2.  */
3113    if (endpos < -1)    if (endpos < -1)
# Line 3127  re_search_2 (bufp, string1, size1, strin Line 3129  re_search_2 (bufp, string1, size1, strin
3129    if (fastmap && !bufp->fastmap_accurate)    if (fastmap && !bufp->fastmap_accurate)
3130      if (re_compile_fastmap (bufp) == -2)      if (re_compile_fastmap (bufp) == -2)
3131        return -2;        return -2;
3132      
3133    /* Loop through the string, looking for a place to start matching.  */    /* Loop through the string, looking for a place to start matching.  */
3134    for (;;)    for (;;)
3135      {      {
3136        /* If a fastmap is supplied, skip quickly over characters that        /* If a fastmap is supplied, skip quickly over characters that
3137           cannot be the start of a match.  If the pattern can match the           cannot be the start of a match.  If the pattern can match the
3138           null string, however, we don't need to skip characters; we want           null string, however, we don't need to skip characters; we want
# Line 3147  re_search_2 (bufp, string1, size1, strin Line 3149  re_search_2 (bufp, string1, size1, strin
3149                  lim = range - (size1 - startpos);                  lim = range - (size1 - startpos);
3150    
3151                d = (startpos >= size1 ? string2 - size1 : string1) + startpos;                d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
3152      
3153                /* Written out as an if-else to avoid testing `translate'                /* Written out as an if-else to avoid testing `translate'
3154                   inside the loop.  */                   inside the loop.  */
3155                if (translate)                if (translate)
# Line 3164  re_search_2 (bufp, string1, size1, strin Line 3166  re_search_2 (bufp, string1, size1, strin
3166            else                          /* Searching backwards.  */            else                          /* Searching backwards.  */
3167              {              {
3168                register char c = (size1 == 0 || startpos >= size1                register char c = (size1 == 0 || startpos >= size1
3169                                   ? string2[startpos - size1]                                   ? string2[startpos - size1]
3170                                   : string1[startpos]);                                   : string1[startpos]);
3171    
3172                if (!fastmap[(unsigned char) TRANSLATE (c)])                if (!fastmap[(unsigned char) TRANSLATE (c)])
# Line 3187  re_search_2 (bufp, string1, size1, strin Line 3189  re_search_2 (bufp, string1, size1, strin
3189    
3190        if (val >= 0)        if (val >= 0)
3191          return startpos;          return startpos;
3192            
3193        if (val == -2)        if (val == -2)
3194          return -2;          return -2;
3195    
3196      advance:      advance:
3197        if (!range)        if (!range)
3198          break;          break;
3199        else if (range > 0)        else if (range > 0)
3200          {          {
3201            range--;            range--;
3202            startpos++;            startpos++;
3203          }          }
3204        else        else
3205          {          {
3206            range++;            range++;
3207            startpos--;            startpos--;
3208          }          }
3209      }      }
# Line 3243  static boolean alt_match_null_string_p ( Line 3245  static boolean alt_match_null_string_p (
3245  /* Test if at very beginning or at very end of the virtual concatenation  /* Test if at very beginning or at very end of the virtual concatenation
3246     of `string1' and `string2'.  If only one string, it's `string2'.  */     of `string1' and `string2'.  If only one string, it's `string2'.  */
3247  #define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)  #define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
3248  #define AT_STRINGS_END(d) ((d) == end2)  #define AT_STRINGS_END(d) ((d) == end2)
3249    
3250    
3251  /* Test if D points to a character which is word-constituent.  We have  /* Test if D points to a character which is word-constituent.  We have
# Line 3321  re_match (bufp, string, size, pos, regs) Line 3323  re_match (bufp, string, size, pos, regs)
3323     the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1     the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
3324     and SIZE2, respectively).  We start matching at POS, and stop     and SIZE2, respectively).  We start matching at POS, and stop
3325     matching at STOP.     matching at STOP.
3326      
3327     If REGS is non-null and the `no_sub' field of BUFP is nonzero, we     If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
3328     store offsets for the substring each group matched in REGS.  See the     store offsets for the substring each group matched in REGS.  See the
3329     documentation for exactly how many groups we fill.     documentation for exactly how many groups we fill.
# Line 3369  re_match_2_internal (bufp, string1, size Line 3371  re_match_2_internal (bufp, string1, size
3371    
3372    /* Where we are in the data, and the end of the current string.  */    /* Where we are in the data, and the end of the current string.  */
3373    const char *d, *dend;    const char *d, *dend;
3374      
3375    /* Where we are in the pattern, and the end of the pattern.  */    /* Where we are in the pattern, and the end of the pattern.  */
3376    unsigned char *p = bufp->buffer;    unsigned char *p = bufp->buffer;
3377    register unsigned char *pend = p + bufp->used;    register unsigned char *pend = p + bufp->used;
# Line 3402  re_match_2_internal (bufp, string1, size Line 3404  re_match_2_internal (bufp, string1, size
3404       return, for use in backreferences.  The number here includes       return, for use in backreferences.  The number here includes
3405       an element for register zero.  */       an element for register zero.  */
3406    unsigned num_regs = bufp->re_nsub + 1;    unsigned num_regs = bufp->re_nsub + 1;
3407      
3408    /* The currently active registers.  */    /* The currently active registers.  */
3409    unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;    unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;
3410    unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;    unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;
# Line 3434  re_match_2_internal (bufp, string1, size Line 3436  re_match_2_internal (bufp, string1, size
3436       subexpression.  These two fields get reset each time through any       subexpression.  These two fields get reset each time through any
3437       loop their register is in.  */       loop their register is in.  */
3438  #ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */  #ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
3439    register_info_type *reg_info;    register_info_type *reg_info;
3440  #endif  #endif
3441    
3442    /* The following record the register info as found in the above    /* The following record the register info as found in the above
3443       variables when we find a match better than any we've seen before.       variables when we find a match better than any we've seen before.
3444       This happens as we backtrack through the failure points, which in       This happens as we backtrack through the failure points, which in
3445       turn happens only if we have not yet matched the entire string. */       turn happens only if we have not yet matched the entire string. */
3446    unsigned best_regs_set = false;    unsigned best_regs_set = false;
3447  #ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */  #ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
3448    const char **best_regstart, **best_regend;    const char **best_regstart, **best_regend;
3449  #endif  #endif
3450      
3451    /* Logically, this is `best_regend[0]'.  But we don't want to have to    /* Logically, this is `best_regend[0]'.  But we don't want to have to
3452       allocate space for that if we're not allocating space for anything       allocate space for that if we're not allocating space for anything
3453       else (see below).  Also, we never need info about register 0 for       else (see below).  Also, we never need info about register 0 for
# Line 3464  re_match_2_internal (bufp, string1, size Line 3466  re_match_2_internal (bufp, string1, size
3466    
3467  #ifdef DEBUG  #ifdef DEBUG
3468    /* Counts the total number of registers pushed.  */    /* Counts the total number of registers pushed.  */
3469    unsigned num_regs_pushed = 0;            unsigned num_regs_pushed = 0;
3470  #endif  #endif
3471    
3472    DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");    DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
3473      
3474    INIT_FAIL_STACK ();    INIT_FAIL_STACK ();
3475      
3476  #ifdef MATCH_MAY_ALLOCATE  #ifdef MATCH_MAY_ALLOCATE
3477    /* Do not bother to initialize all the register variables if there are    /* Do not bother to initialize all the register variables if there are
3478       no groups in the pattern, as it takes a fair amount of time.  If       no groups in the pattern, as it takes a fair amount of time.  If
# Line 3489  re_match_2_internal (bufp, string1, size Line 3491  re_match_2_internal (bufp, string1, size
3491        reg_dummy = REGEX_TALLOC (num_regs, const char *);        reg_dummy = REGEX_TALLOC (num_regs, const char *);
3492        reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);        reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
3493    
3494        if (!(regstart && regend && old_regstart && old_regend && reg_info        if (!(regstart && regend && old_regstart && old_regend && reg_info
3495              && best_regstart && best_regend && reg_dummy && reg_info_dummy))              && best_regstart && best_regend && reg_dummy && reg_info_dummy))
3496          {          {
3497            FREE_VARIABLES ();            FREE_VARIABLES ();
3498            return -2;            return -2;
# Line 3514  re_match_2_internal (bufp, string1, size Line 3516  re_match_2_internal (bufp, string1, size
3516        FREE_VARIABLES ();        FREE_VARIABLES ();
3517        return -1;        return -1;
3518      }      }
3519        
3520    /* Initialize subexpression text positions to -1 to mark ones that no    /* Initialize subexpression text positions to -1 to mark ones that no
3521       start_memory/stop_memory has been seen for. Also initialize the       start_memory/stop_memory has been seen for. Also initialize the
3522       register information struct.  */       register information struct.  */
3523    for (mcnt = 1; mcnt < num_regs; mcnt++)    for (mcnt = 1; mcnt < num_regs; mcnt++)
3524      {      {
3525        regstart[mcnt] = regend[mcnt]        regstart[mcnt] = regend[mcnt]
3526          = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;          = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
3527            
3528        REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;        REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
3529        IS_ACTIVE (reg_info[mcnt]) = 0;        IS_ACTIVE (reg_info[mcnt]) = 0;
3530        MATCHED_SOMETHING (reg_info[mcnt]) = 0;        MATCHED_SOMETHING (reg_info[mcnt]) = 0;
3531        EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;        EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
3532      }      }
3533      
3534    /* We move `string1' into `string2' if the latter's empty -- but not if    /* We move `string1' into `string2' if the latter's empty -- but not if
3535       `string1' is null.  */       `string1' is null.  */
3536    if (size2 == 0 && string1 != NULL)    if (size2 == 0 && string1 != NULL)
# Line 3553  re_match_2_internal (bufp, string1, size Line 3555  re_match_2_internal (bufp, string1, size
3555        end_match_2 = string2 + stop - size1;        end_match_2 = string2 + stop - size1;
3556      }      }
3557    
3558    /* `p' scans through the pattern as `d' scans through the data.    /* `p' scans through the pattern as `d' scans through the data.
3559       `dend' is the end of the input string that `d' points within.  `d'       `dend' is the end of the input string that `d' points within.  `d'
3560       is advanced into the following input string whenever necessary, but       is advanced into the following input string whenever necessary, but
3561       this happens before fetching; therefore, at the beginning of the       this happens before fetching; therefore, at the beginning of the
# Line 3575  re_match_2_internal (bufp, string1, size Line 3577  re_match_2_internal (bufp, string1, size
3577    DEBUG_PRINT1 ("The string to match is: `");    DEBUG_PRINT1 ("The string to match is: `");
3578    DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);    DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
3579    DEBUG_PRINT1 ("'\n");    DEBUG_PRINT1 ("'\n");
3580      
3581    /* This loops over pattern commands.  It exits by returning from the    /* This loops over pattern commands.  It exits by returning from the
3582       function if the match is complete, or it drops through if the match       function if the match is complete, or it drops through if the match
3583       fails at this starting point in the input data.  */       fails at this starting point in the input data.  */
# Line 3586  re_match_2_internal (bufp, string1, size Line 3588  re_match_2_internal (bufp, string1, size
3588        if (p == pend)        if (p == pend)
3589          { /* End of pattern means we might have succeeded.  */          { /* End of pattern means we might have succeeded.  */
3590            DEBUG_PRINT1 ("end of pattern ... ");            DEBUG_PRINT1 ("end of pattern ... ");
3591              
3592            /* If we haven't matched the entire string, and we want the            /* If we haven't matched the entire string, and we want the
3593               longest match, try backtracking.  */               longest match, try backtracking.  */
3594            if (d != end_match_2)            if (d != end_match_2)
3595              {              {
3596                /* 1 if this match ends in the same string (string1 or string2)                /* 1 if this match ends in the same string (string1 or string2)
3597                   as the best previous match.  */                   as the best previous match.  */
3598                boolean same_str_p = (FIRST_STRING_P (match_end)                boolean same_str_p = (FIRST_STRING_P (match_end)
3599                                      == MATCHING_IN_FIRST_STRING);                                      == MATCHING_IN_FIRST_STRING);
3600                /* 1 if this match is the best seen so far.  */                /* 1 if this match is the best seen so far.  */
3601                boolean best_match_p;                boolean best_match_p;
# Line 3606  re_match_2_internal (bufp, string1, size Line 3608  re_match_2_internal (bufp, string1, size
3608                  best_match_p = !MATCHING_IN_FIRST_STRING;                  best_match_p = !MATCHING_IN_FIRST_STRING;
3609    
3610                DEBUG_PRINT1 ("backtracking.\n");                DEBUG_PRINT1 ("backtracking.\n");
3611                  
3612                if (!FAIL_STACK_EMPTY ())                if (!FAIL_STACK_EMPTY ())
3613                  { /* More failure points to try.  */                  { /* More failure points to try.  */
3614    
# Line 3615  re_match_2_internal (bufp, string1, size Line 3617  re_match_2_internal (bufp, string1, size
3617                      {                      {
3618                        best_regs_set = true;                        best_regs_set = true;
3619                        match_end = d;                        match_end = d;
3620                          
3621                        DEBUG_PRINT1 ("\nSAVING match as best so far.\n");                        DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
3622                          
3623                        for (mcnt = 1; mcnt < num_regs; mcnt++)                        for (mcnt = 1; mcnt < num_regs; mcnt++)
3624                          {                          {
3625                            best_regstart[mcnt] = regstart[mcnt];                            best_regstart[mcnt] = regstart[mcnt];
3626                            best_regend[mcnt] = regend[mcnt];                            best_regend[mcnt] = regend[mcnt];
3627                          }                          }
3628                      }                      }
3629                    goto fail;                              goto fail;
3630                  }                  }
3631    
3632                /* If no failure points, don't restore garbage.  And if                /* If no failure points, don't restore garbage.  And if
# Line 3639  re_match_2_internal (bufp, string1, size Line 3641  re_match_2_internal (bufp, string1, size
3641                       strings `x-' and `y-z-', if the two strings are                       strings `x-' and `y-z-', if the two strings are
3642                       not consecutive in memory.  */                       not consecutive in memory.  */
3643                    DEBUG_PRINT1 ("Restoring best registers.\n");                    DEBUG_PRINT1 ("Restoring best registers.\n");
3644                      
3645                    d = match_end;                    d = match_end;
3646                    dend = ((d >= string1 && d <= end1)                    dend = ((d >= string1 && d <= end1)
3647                             ? end_match_1 : end_match_2);                             ? end_match_1 : end_match_2);
# Line 3699  re_match_2_internal (bufp, string1, size Line 3701  re_match_2_internal (bufp, string1, size
3701                                    ? ((regoff_t) (d - string1))                                    ? ((regoff_t) (d - string1))
3702                                    : ((regoff_t) (d - string2 + size1)));                                    : ((regoff_t) (d - string2 + size1)));
3703                  }                  }
3704                  
3705                /* Go through the first `min (num_regs, regs->num_regs)'                /* Go through the first `min (num_regs, regs->num_regs)'
3706                   registers, since that is all we initialized.  */                   registers, since that is all we initialized.  */
3707                for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)                for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
# Line 3714  re_match_2_internal (bufp, string1, size Line 3716  re_match_2_internal (bufp, string1, size
3716                          = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);                          = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
3717                      }                      }
3718                  }                  }
3719                  
3720                /* If the regs structure we return has more elements than                /* If the regs structure we return has more elements than
3721                   were in the pattern, set the extra elements to -1.  If                   were in the pattern, set the extra elements to -1.  If
3722                   we (re)allocated the registers, this is the case,                   we (re)allocated the registers, this is the case,
# Line 3730  re_match_2_internal (bufp, string1, size Line 3732  re_match_2_internal (bufp, string1, size
3732                          nfailure_points_pushed - nfailure_points_popped);                          nfailure_points_pushed - nfailure_points_popped);
3733            DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);            DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
3734    
3735            mcnt = d - pos - (MATCHING_IN_FIRST_STRING            mcnt = d - pos - (MATCHING_IN_FIRST_STRING
3736                              ? string1                              ? string1
3737                              : string2 - size1);                              : string2 - size1);
3738    
3739            DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);            DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
# Line 3821  re_match_2_internal (bufp, string1, size Line 3823  re_match_2_internal (bufp, string1, size
3823              p += 1 + *p;              p += 1 + *p;
3824    
3825              if (!not) goto fail;              if (!not) goto fail;
3826                
3827              SET_REGS_MATCHED ();              SET_REGS_MATCHED ();
3828              d++;              d++;
3829              break;              break;
# Line 3838  re_match_2_internal (bufp, string1, size Line 3840  re_match_2_internal (bufp, string1, size
3840    
3841            /* Find out if this group can match the empty string.  */            /* Find out if this group can match the empty string.  */
3842            p1 = p;               /* To send to group_match_null_string_p.  */            p1 = p;               /* To send to group_match_null_string_p.  */
3843              
3844            if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)            if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
3845              REG_MATCH_NULL_STRING_P (reg_info[*p])              REG_MATCH_NULL_STRING_P (reg_info[*p])
3846                = group_match_null_string_p (&p1, pend, reg_info);                = group_match_null_string_p (&p1, pend, reg_info);
3847    
3848            /* Save the position in the string where we were the last time            /* Save the position in the string where we were the last time
# Line 3851  re_match_2_internal (bufp, string1, size Line 3853  re_match_2_internal (bufp, string1, size
3853            old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])            old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
3854                               ? REG_UNSET (regstart[*p]) ? d : regstart[*p]                               ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
3855                               : regstart[*p];                               : regstart[*p];
3856            DEBUG_PRINT2 ("  old_regstart: %d\n",            DEBUG_PRINT2 ("  old_regstart: %d\n",
3857                           POINTER_TO_OFFSET (old_regstart[*p]));                           POINTER_TO_OFFSET (old_regstart[*p]));
3858    
3859            regstart[*p] = d;            regstart[*p] = d;
# Line 3859  re_match_2_internal (bufp, string1, size Line 3861  re_match_2_internal (bufp, string1, size
3861    
3862            IS_ACTIVE (reg_info[*p]) = 1;            IS_ACTIVE (reg_info[*p]) = 1;
3863            MATCHED_SOMETHING (reg_info[*p]) = 0;            MATCHED_SOMETHING (reg_info[*p]) = 0;
3864              
3865            /* This is the new highest active register.  */            /* This is the new highest active register.  */
3866            highest_active_reg = *p;            highest_active_reg = *p;
3867              
3868            /* If nothing was active before, this is the new lowest active            /* If nothing was active before, this is the new lowest active
3869               register.  */               register.  */
3870            if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)            if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
# Line 3879  re_match_2_internal (bufp, string1, size Line 3881  re_match_2_internal (bufp, string1, size
3881             number, and the number of inner groups.  */             number, and the number of inner groups.  */
3882          case stop_memory:          case stop_memory:
3883            DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);            DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
3884                
3885            /* We need to save the string position the last time we were at            /* We need to save the string position the last time we were at
3886               this close-group operator in case the group is operated               this close-group operator in case the group is operated
3887               upon by a repetition operator, e.g., with `((a*)*(b*)*)*'               upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
# Line 3888  re_match_2_internal (bufp, string1, size Line 3890  re_match_2_internal (bufp, string1, size
3890            old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])            old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
3891                             ? REG_UNSET (regend[*p]) ? d : regend[*p]                             ? REG_UNSET (regend[*p]) ? d : regend[*p]
3892                             : regend[*p];                             : regend[*p];
3893            DEBUG_PRINT2 ("      old_regend: %d\n",            DEBUG_PRINT2 ("      old_regend: %d\n",
3894                           POINTER_TO_OFFSET (old_regend[*p]));                           POINTER_TO_OFFSET (old_regend[*p]));
3895    
3896            regend[*p] = d;            regend[*p] = d;
# Line 3896  re_match_2_internal (bufp, string1, size Line 3898  re_match_2_internal (bufp, string1, size
3898    
3899            /* This register isn't active anymore.  */            /* This register isn't active anymore.  */
3900            IS_ACTIVE (reg_info[*p]) = 0;            IS_ACTIVE (reg_info[*p]) = 0;
3901              
3902            /* If this was the only register active, nothing is active            /* If this was the only register active, nothing is active
3903               anymore.  */               anymore.  */
3904            if (lowest_active_reg == highest_active_reg)            if (lowest_active_reg == highest_active_reg)
# Line 3912  re_match_2_internal (bufp, string1, size Line 3914  re_match_2_internal (bufp, string1, size
3914                unsigned char r = *p - 1;                unsigned char r = *p - 1;
3915                while (r > 0 && !IS_ACTIVE (reg_info[r]))                while (r > 0 && !IS_ACTIVE (reg_info[r]))
3916                  r--;                  r--;
3917                  
3918                /* If we end up at register zero, that means that we saved                /* If we end up at register zero, that means that we saved
3919                   the registers as the result of an `on_failure_jump', not                   the registers as the result of an `on_failure_jump', not
3920                   a `start_memory', and we jumped to past the innermost                   a `start_memory', and we jumped to past the innermost
# Line 3928  re_match_2_internal (bufp, string1, size Line 3930  re_match_2_internal (bufp, string1, size
3930                else                else
3931                  highest_active_reg = r;                  highest_active_reg = r;
3932              }              }
3933              
3934            /* If just failed to match something this time around with a            /* If just failed to match something this time around with a
3935               group that's operated on by a repetition operator, try to               group that's operated on by a repetition operator, try to
3936               force exit from the ``loop'', and restore the register               force exit from the ``loop'', and restore the register
# Line 3936  re_match_2_internal (bufp, string1, size Line 3938  re_match_2_internal (bufp, string1, size
3938               last match.  */               last match.  */
3939            if ((!MATCHED_SOMETHING (reg_info[*p])            if ((!MATCHED_SOMETHING (reg_info[*p])
3940                 || just_past_start_mem == p - 1)                 || just_past_start_mem == p - 1)
3941                && (p + 2) < pend)                              && (p + 2) < pend)
3942              {              {
3943                boolean is_a_jump_n = false;                boolean is_a_jump_n = false;
3944                  
3945                p1 = p + 2;                p1 = p + 2;
3946                mcnt = 0;                mcnt = 0;
3947                switch ((re_opcode_t) *p1++)                switch ((re_opcode_t) *p1++)
# Line 3954  re_match_2_internal (bufp, string1, size Line 3956  re_match_2_internal (bufp, string1, size
3956                      if (is_a_jump_n)                      if (is_a_jump_n)
3957                        p1 += 2;                        p1 += 2;
3958                      break;                      break;
3959                      
3960                    default:                    default:
3961                      /* do nothing */ ;                      /* do nothing */ ;
3962                  }                  }
3963                p1 += mcnt;                p1 += mcnt;
3964            
3965                /* If the next operation is a jump backwards in the pattern                /* If the next operation is a jump backwards in the pattern
3966                   to an on_failure_jump right before the start_memory                   to an on_failure_jump right before the start_memory
3967                   corresponding to this stop_memory, exit from the loop                   corresponding to this stop_memory, exit from the loop
# Line 3973  re_match_2_internal (bufp, string1, size Line 3975  re_match_2_internal (bufp, string1, size
3975                       failed match, e.g., with `(a*)*b' against `ab' for                       failed match, e.g., with `(a*)*b' against `ab' for
3976                       regstart[1], and, e.g., with `((a*)*(b*)*)*'                       regstart[1], and, e.g., with `((a*)*(b*)*)*'
3977                       against `aba' for regend[3].                       against `aba' for regend[3].
3978                        
3979                       Also restore the registers for inner groups for,                       Also restore the registers for inner groups for,
3980                       e.g., `((a*)(b*))*' against `aba' (register 3 would                       e.g., `((a*)(b*))*' against `aba' (register 3 would
3981                       otherwise get trashed).  */                       otherwise get trashed).  */
3982                        
3983                    if (EVER_MATCHED_SOMETHING (reg_info[*p]))                    if (EVER_MATCHED_SOMETHING (reg_info[*p]))
3984                      {                      {
3985                        unsigned r;                        unsigned r;
3986            
3987                        EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;                        EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
3988                          
3989                        /* Restore this and inner groups' (if any) registers.  */                        /* Restore this and inner groups' (if any) registers.  */
3990                        for (r = *p; r < *p + *(p + 1); r++)                        for (r = *p; r < *p + *(p + 1); r++)
3991                          {                          {
# Line 3992  re_match_2_internal (bufp, string1, size Line 3994  re_match_2_internal (bufp, string1, size
3994                            /* xx why this test?  */                            /* xx why this test?  */
3995                            if ((int) old_regend[r] >= (int) regstart[r])                            if ((int) old_regend[r] >= (int) regstart[r])
3996                              regend[r] = old_regend[r];                              regend[r] = old_regend[r];
3997                          }                              }
3998                      }                      }
3999                    p1++;                    p1++;
4000                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);
# Line 4001  re_match_2_internal (bufp, string1, size Line 4003  re_match_2_internal (bufp, string1, size
4003                    goto fail;                    goto fail;
4004                  }                  }
4005              }              }
4006              
4007            /* Move past the register number and the inner group count.  */            /* Move past the register number and the inner group count.  */
4008            p += 2;            p += 2;
4009            break;            break;
# Line 4018  re_match_2_internal (bufp, string1, size Line 4020  re_match_2_internal (bufp, string1, size
4020              /* Can't back reference a group which we've never matched.  */              /* Can't back reference a group which we've never matched.  */
4021              if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))              if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
4022                goto fail;                goto fail;
4023                  
4024              /* Where in input to try to start matching.  */              /* Where in input to try to start matching.  */
4025              d2 = regstart[regno];              d2 = regstart[regno];
4026                
4027              /* Where to stop matching; if both the place to start and              /* Where to stop matching; if both the place to start and
4028                 the place to stop matching are in the same string, then                 the place to stop matching are in the same string, then
4029                 set to the place to stop, otherwise, for now have to use                 set to the place to stop, otherwise, for now have to use
4030                 the end of the first string.  */                 the end of the first string.  */
4031    
4032              dend2 = ((FIRST_STRING_P (regstart[regno])              dend2 = ((FIRST_STRING_P (regstart[regno])
4033                        == FIRST_STRING_P (regend[regno]))                        == FIRST_STRING_P (regend[regno]))
4034                       ? regend[regno] : end_match_1);                       ? regend[regno] : end_match_1);
4035              for (;;)              for (;;)
# Line 4051  re_match_2_internal (bufp, string1, size Line 4053  re_match_2_internal (bufp, string1, size
4053    
4054                  /* How many characters left in this segment to match.  */                  /* How many characters left in this segment to match.  */
4055                  mcnt = dend - d;                  mcnt = dend - d;
4056                    
4057                  /* Want how many consecutive characters we can match in                  /* Want how many consecutive characters we can match in
4058                     one shot, so, if necessary, adjust the count.  */                     one shot, so, if necessary, adjust the count.  */
4059                  if (mcnt > dend2 - d2)                  if (mcnt > dend2 - d2)
4060                    mcnt = dend2 - d2;                    mcnt = dend2 - d2;
4061                      
4062                  /* Compare that many; failure if mismatch, else move                  /* Compare that many; failure if mismatch, else move
4063                     past them.  */                     past them.  */
4064                  if (translate                  if (translate
4065                      ? bcmp_translate (d, d2, mcnt, translate)                      ? bcmp_translate (d, d2, mcnt, translate)
4066                      : bcmp (d, d2, mcnt))                      : bcmp (d, d2, mcnt))
4067                    goto fail;                    goto fail;
4068                  d += mcnt, d2 += mcnt;                  d += mcnt, d2 += mcnt;
# Line 4074  re_match_2_internal (bufp, string1, size Line 4076  re_match_2_internal (bufp, string1, size
4076             `newline_anchor' is set, after newlines.  */             `newline_anchor' is set, after newlines.  */
4077          case begline:          case begline:
4078            DEBUG_PRINT1 ("EXECUTING begline.\n");            DEBUG_PRINT1 ("EXECUTING begline.\n");
4079              
4080            if (AT_STRINGS_BEG (d))            if (AT_STRINGS_BEG (d))
4081              {              {
4082                if (!bufp->not_bol) break;                if (!bufp->not_bol) break;
# Line 4095  re_match_2_internal (bufp, string1, size Line 4097  re_match_2_internal (bufp, string1, size
4097              {              {
4098                if (!bufp->not_eol) break;                if (!bufp->not_eol) break;
4099              }              }
4100              
4101            /* We have to ``prefetch'' the next character.  */            /* We have to ``prefetch'' the next character.  */
4102            else if ((d == end1 ? *string2 : *d) == '\n'            else if ((d == end1 ? *string2 : *d) == '\n'
4103                     && bufp->newline_anchor)                     && bufp->newline_anchor)
# Line 4129  re_match_2_internal (bufp, string1, size Line 4131  re_match_2_internal (bufp, string1, size
4131             then the . fails against the \n.  But the next thing we want             then the . fails against the \n.  But the next thing we want
4132             to do is match the \n against the \n; if we restored the             to do is match the \n against the \n; if we restored the
4133             string value, we would be back at the foo.             string value, we would be back at the foo.
4134              
4135             Because this is used only in specific cases, we don't need to             Because this is used only in specific cases, we don't need to
4136             check all the things that `on_failure_jump' does, to make             check all the things that `on_failure_jump' does, to make
4137             sure the right things get saved on the stack.  Hence we don't             sure the right things get saved on the stack.  Hence we don't
# Line 4139  re_match_2_internal (bufp, string1, size Line 4141  re_match_2_internal (bufp, string1, size
4141             case; that seems worse than this.  */             case; that seems worse than this.  */
4142          case on_failure_keep_string_jump:          case on_failure_keep_string_jump:
4143            DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");            DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
4144              
4145            EXTRACT_NUMBER_AND_INCR (mcnt, p);            EXTRACT_NUMBER_AND_INCR (mcnt, p);
4146            DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);            DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
4147    
# Line 4148  re_match_2_internal (bufp, string1, size Line 4150  re_match_2_internal (bufp, string1, size
4150    
4151    
4152          /* Uses of on_failure_jump:          /* Uses of on_failure_jump:
4153            
4154             Each alternative starts with an on_failure_jump that points             Each alternative starts with an on_failure_jump that points
4155             to the beginning of the next alternative.  Each alternative             to the beginning of the next alternative.  Each alternative
4156             except the last ends with a jump that in effect jumps past             except the last ends with a jump that in effect jumps past
# Line 4214  re_match_2_internal (bufp, string1, size Line 4216  re_match_2_internal (bufp, string1, size
4216                 would have to backtrack because of (as in, e.g., `a*a')                 would have to backtrack because of (as in, e.g., `a*a')
4217                 then we can change to pop_failure_jump, because we'll                 then we can change to pop_failure_jump, because we'll
4218                 never have to backtrack.                 never have to backtrack.
4219                  
4220                 This is not true in the case of alternatives: in                 This is not true in the case of alternatives: in
4221                 `(a|ab)*' we do need to backtrack to the `ab' alternative                 `(a|ab)*' we do need to backtrack to the `ab' alternative
4222                 (e.g., if the string was `ab').  But instead of trying to                 (e.g., if the string was `ab').  But instead of trying to
# Line 4240  re_match_2_internal (bufp, string1, size Line 4242  re_match_2_internal (bufp, string1, size
4242    
4243              p1 = p + mcnt;              p1 = p + mcnt;
4244              /* p1[0] ... p1[2] are the `on_failure_jump' corresponding              /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
4245                 to the `maybe_finalize_jump' of this case.  Examine what                 to the `maybe_finalize_jump' of this case.  Examine what
4246                 follows.  */                 follows.  */
4247    
4248              /* If we're at the end of the pattern, we can change.  */              /* If we're at the end of the pattern, we can change.  */
# Line 4266  re_match_2_internal (bufp, string1, size Line 4268  re_match_2_internal (bufp, string1, size
4268                      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",                      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
4269                                    c, p1[5]);                                    c, p1[5]);
4270                    }                    }
4271                      
4272                  else if ((re_opcode_t) p1[3] == charset                  else if ((re_opcode_t) p1[3] == charset
4273                           || (re_opcode_t) p1[3] == charset_not)                           || (re_opcode_t) p1[3] == charset_not)
4274                    {                    {
4275                      int not = (re_opcode_t) p1[3] == charset_not;                      int not = (re_opcode_t) p1[3] == charset_not;
4276                        
4277                      if (c < (unsigned char) (p1[4] * BYTEWIDTH)                      if (c < (unsigned char) (p1[4] * BYTEWIDTH)
4278                          && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))                          && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
4279                        not = !not;                        not = !not;
# Line 4301  re_match_2_internal (bufp, string1, size Line 4303  re_match_2_internal (bufp, string1, size
4303                      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",                      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
4304                                    c, p1[5]);                                    c, p1[5]);
4305                    }                    }
4306                      
4307                  else if ((re_opcode_t) p1[3] == charset_not)                  else if ((re_opcode_t) p1[3] == charset_not)
4308                    {                    {
4309                      int idx;                      int idx;
# Line 4372  re_match_2_internal (bufp, string1, size Line 4374  re_match_2_internal (bufp, string1, size
4374            }            }
4375            /* Note fall through.  */            /* Note fall through.  */
4376    
4377              
4378          /* Unconditionally jump (without popping any failure points).  */          /* Unconditionally jump (without popping any failure points).  */
4379          case jump:          case jump:
4380          unconditional_jump:          unconditional_jump:
# Line 4382  re_match_2_internal (bufp, string1, size Line 4384  re_match_2_internal (bufp, string1, size
4384            DEBUG_PRINT2 ("(to 0x%x).\n", p);            DEBUG_PRINT2 ("(to 0x%x).\n", p);
4385            break;            break;
4386    
4387            
4388          /* We need this opcode so we can detect where alternatives end          /* We need this opcode so we can detect where alternatives end
4389             in `group_match_null_string_p' et al.  */             in `group_match_null_string_p' et al.  */
4390          case jump_past_alt:          case jump_past_alt:
# Line 4417  re_match_2_internal (bufp, string1, size Line 4419  re_match_2_internal (bufp, string1, size
4419    
4420          /* Have to succeed matching what follows at least n times.          /* Have to succeed matching what follows at least n times.
4421             After that, handle like `on_failure_jump'.  */             After that, handle like `on_failure_jump'.  */
4422          case succeed_n:          case succeed_n:
4423            EXTRACT_NUMBER (mcnt, p + 2);            EXTRACT_NUMBER (mcnt, p + 2);
4424            DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);            DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
4425    
# Line 4438  re_match_2_internal (bufp, string1, size Line 4440  re_match_2_internal (bufp, string1, size
4440                goto on_failure;                goto on_failure;
4441              }              }
4442            break;            break;
4443            
4444          case jump_n:          case jump_n:
4445            EXTRACT_NUMBER (mcnt, p + 2);            EXTRACT_NUMBER (mcnt, p + 2);
4446            DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);            DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
4447    
# Line 4448  re_match_2_internal (bufp, string1, size Line 4450  re_match_2_internal (bufp, string1, size
4450              {              {
4451                 mcnt--;                 mcnt--;
4452                 STORE_NUMBER (p + 2, mcnt);                 STORE_NUMBER (p + 2, mcnt);
4453                 goto unconditional_jump;                       goto unconditional_jump;
4454              }              }
4455            /* If don't have to jump any more, skip over the rest of command.  */            /* If don't have to jump any more, skip over the rest of command.  */
4456            else                  else
4457              p += 4;                                p += 4;
4458            break;            break;
4459            
4460          case set_number_at:          case set_number_at:
4461            {            {
4462              DEBUG_PRINT1 ("EXECUTING set_number_at.\n");              DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
# Line 4498  re_match_2_internal (bufp, string1, size Line 4500  re_match_2_internal (bufp, string1, size
4500            if (PTR_CHAR_POS ((unsigned char *) d) >= point)            if (PTR_CHAR_POS ((unsigned char *) d) >= point)
4501              goto fail;              goto fail;
4502            break;            break;
4503      
4504          case at_dot:          case at_dot:
4505            DEBUG_PRINT1 ("EXECUTING at_dot.\n");            DEBUG_PRINT1 ("EXECUTING at_dot.\n");
4506            if (PTR_CHAR_POS ((unsigned char *) d) != point)            if (PTR_CHAR_POS ((unsigned char *) d) != point)
4507              goto fail;              goto fail;
4508            break;            break;
4509      
4510          case after_dot:          case after_dot:
4511            DEBUG_PRINT1 ("EXECUTING after_dot.\n");            DEBUG_PRINT1 ("EXECUTING after_dot.\n");
4512            if (PTR_CHAR_POS ((unsigned char *) d) <= point)            if (PTR_CHAR_POS ((unsigned char *) d) <= point)
# Line 4561  re_match_2_internal (bufp, string1, size Line 4563  re_match_2_internal (bufp, string1, size
4563            SET_REGS_MATCHED ();            SET_REGS_MATCHED ();
4564            d++;            d++;
4565            break;            break;
4566              
4567          case notwordchar:          case notwordchar:
4568            DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");            DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
4569            PREFETCH ();            PREFETCH ();
# Line 4571  re_match_2_internal (bufp, string1, size Line 4573  re_match_2_internal (bufp, string1, size
4573            d++;            d++;
4574            break;            break;
4575  #endif /* not emacs */  #endif /* not emacs */
4576              
4577          default:          default:
4578            abort ();            abort ();
4579          }          }
# Line 4596  re_match_2_internal (bufp, string1, size Line 4598  re_match_2_internal (bufp, string1, size
4598            if (p < pend)            if (p < pend)
4599              {              {
4600                boolean is_a_jump_n = false;                boolean is_a_jump_n = false;
4601                  
4602                /* If failed to a backwards jump that's part of a repetition                /* If failed to a backwards jump that's part of a repetition
4603                   loop, need to pop this failure point and use the next one.  */                   loop, need to pop this failure point and use the next one.  */
4604                switch ((re_opcode_t) *p)                switch ((re_opcode_t) *p)
# Line 4608  re_match_2_internal (bufp, string1, size Line 4610  re_match_2_internal (bufp, string1, size
4610                  case jump:                  case jump:
4611                    p1 = p + 1;                    p1 = p + 1;
4612                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);
4613                    p1 += mcnt;                      p1 += mcnt;
4614    
4615                    if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)                    if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
4616                        || (!is_a_jump_n                        || (!is_a_jump_n
# Line 4639  re_match_2_internal (bufp, string1, size Line 4641  re_match_2_internal (bufp, string1, size
4641    
4642    
4643  /* We are passed P pointing to a register number after a start_memory.  /* We are passed P pointing to a register number after a start_memory.
4644      
4645     Return true if the pattern up to the corresponding stop_memory can     Return true if the pattern up to the corresponding stop_memory can
4646     match the empty string, and false otherwise.     match the empty string, and false otherwise.
4647      
4648     If we find the matching stop_memory, sets P to point to one past its number.     If we find the matching stop_memory, sets P to point to one past its number.
4649     Otherwise, sets P to an undefined byte less than or equal to END.     Otherwise, sets P to an undefined byte less than or equal to END.
4650    
# Line 4656  group_match_null_string_p (p, end, reg_i Line 4658  group_match_null_string_p (p, end, reg_i
4658    int mcnt;    int mcnt;
4659    /* Point to after the args to the start_memory.  */    /* Point to after the args to the start_memory.  */
4660    unsigned char *p1 = *p + 2;    unsigned char *p1 = *p + 2;
4661      
4662    while (p1 < end)    while (p1 < end)
4663      {      {
4664        /* Skip over opcodes that can match nothing, and return true or        /* Skip over opcodes that can match nothing, and return true or
4665           false, as appropriate, when we get to one that can't, or to the           false, as appropriate, when we get to one that can't, or to the
4666           matching stop_memory.  */           matching stop_memory.  */
4667          
4668        switch ((re_opcode_t) *p1)        switch ((re_opcode_t) *p1)
4669          {          {
4670          /* Could be either a loop or a series of alternatives.  */          /* Could be either a loop or a series of alternatives.  */
4671          case on_failure_jump:          case on_failure_jump:
4672            p1++;            p1++;
4673            EXTRACT_NUMBER_AND_INCR (mcnt, p1);            EXTRACT_NUMBER_AND_INCR (mcnt, p1);
4674              
4675            /* If the next operation is not a jump backwards in the            /* If the next operation is not a jump backwards in the
4676               pattern.  */               pattern.  */
4677    
# Line 4683  group_match_null_string_p (p, end, reg_i Line 4685  group_match_null_string_p (p, end, reg_i
4685    
4686                   /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6                   /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
4687                   /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3                   /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
4688                   /exactn/1/c                                                               /exactn/1/c
4689    
4690                   So, we have to first go through the first (n-1)                   So, we have to first go through the first (n-1)
4691                   alternatives and then deal with the last one separately.  */                   alternatives and then deal with the last one separately.  */
# Line 4699  group_match_null_string_p (p, end, reg_i Line 4701  group_match_null_string_p (p, end, reg_i
4701                       is, including the ending `jump_past_alt' and                       is, including the ending `jump_past_alt' and
4702                       its number.  */                       its number.  */
4703    
4704                    if (!alt_match_null_string_p (p1, p1 + mcnt - 3,                    if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
4705                                                        reg_info))                                                        reg_info))
4706                      return false;                      return false;
4707    
4708                    /* Move to right after this alternative, including the                    /* Move to right after this alternative, including the
4709                       jump_past_alt.  */                       jump_past_alt.  */
4710                    p1 += mcnt;                      p1 += mcnt;
4711    
4712                    /* Break if it's the beginning of an n-th alternative                    /* Break if it's the beginning of an n-th alternative
4713                       that doesn't begin with an on_failure_jump.  */                       that doesn't begin with an on_failure_jump.  */
4714                    if ((re_opcode_t) *p1 != on_failure_jump)                    if ((re_opcode_t) *p1 != on_failure_jump)
4715                      break;                      break;
4716                    
4717                    /* Still have to check that it's not an n-th                    /* Still have to check that it's not an n-th
4718                       alternative that starts with an on_failure_jump.  */                       alternative that starts with an on_failure_jump.  */
4719                    p1++;                    p1++;
# Line 4736  group_match_null_string_p (p, end, reg_i Line 4738  group_match_null_string_p (p, end, reg_i
4738              } /* if mcnt > 0 */              } /* if mcnt > 0 */
4739            break;            break;
4740    
4741              
4742          case stop_memory:          case stop_memory:
4743            assert (p1[1] == **p);            assert (p1[1] == **p);
4744            *p = p1 + 2;            *p = p1 + 2;
4745            return true;            return true;
4746    
4747            
4748          default:          default:
4749            if (!common_op_match_null_string_p (&p1, end, reg_info))            if (!common_op_match_null_string_p (&p1, end, reg_info))
4750              return false;              return false;
4751          }          }
# Line 4756  group_match_null_string_p (p, end, reg_i Line 4758  group_match_null_string_p (p, end, reg_i
4758  /* Similar to group_match_null_string_p, but doesn't deal with alternatives:  /* Similar to group_match_null_string_p, but doesn't deal with alternatives:
4759     It expects P to be the first byte of a single alternative and END one     It expects P to be the first byte of a single alternative and END one
4760     byte past the last. The alternative can contain groups.  */     byte past the last. The alternative can contain groups.  */
4761      
4762  static boolean  static boolean
4763  alt_match_null_string_p (p, end, reg_info)  alt_match_null_string_p (p, end, reg_info)
4764      unsigned char *p, *end;      unsigned char *p, *end;
# Line 4764  alt_match_null_string_p (p, end, reg_inf Line 4766  alt_match_null_string_p (p, end, reg_inf
4766  {  {
4767    int mcnt;    int mcnt;
4768    unsigned char *p1 = p;    unsigned char *p1 = p;
4769      
4770    while (p1 < end)    while (p1 < end)
4771      {      {
4772        /* Skip over opcodes that can match nothing, and break when we get        /* Skip over opcodes that can match nothing, and break when we get
4773           to one that can't.  */           to one that can't.  */
4774          
4775        switch ((re_opcode_t) *p1)        switch ((re_opcode_t) *p1)
4776          {          {
4777          /* It's a loop.  */          /* It's a loop.  */
# Line 4778  alt_match_null_string_p (p, end, reg_inf Line 4780  alt_match_null_string_p (p, end, reg_inf
4780            EXTRACT_NUMBER_AND_INCR (mcnt, p1);            EXTRACT_NUMBER_AND_INCR (mcnt, p1);
4781            p1 += mcnt;            p1 += mcnt;
4782            break;            break;
4783              
4784          default:          default:
4785            if (!common_op_match_null_string_p (&p1, end, reg_info))            if (!common_op_match_null_string_p (&p1, end, reg_info))
4786              return false;              return false;
4787          }          }
# Line 4790  alt_match_null_string_p (p, end, reg_inf Line 4792  alt_match_null_string_p (p, end, reg_inf
4792    
4793    
4794  /* Deals with the ops common to group_match_null_string_p and  /* Deals with the ops common to group_match_null_string_p and
4795     alt_match_null_string_p.       alt_match_null_string_p.
4796      
4797     Sets P to one after the op and its arguments, if any.  */     Sets P to one after the op and its arguments, if any.  */
4798    
4799  static boolean  static boolean
# Line 4826  common_op_match_null_string_p (p, end, r Line 4828  common_op_match_null_string_p (p, end, r
4828        reg_no = *p1;        reg_no = *p1;
4829        assert (reg_no > 0 && reg_no <= MAX_REGNUM);        assert (reg_no > 0 && reg_no <= MAX_REGNUM);
4830        ret = group_match_null_string_p (&p1, end, reg_info);        ret = group_match_null_string_p (&p1, end, reg_info);
4831          
4832        /* Have to set this here in case we're checking a group which        /* Have to set this here in case we're checking a group which
4833           contains a group and a back reference to it.  */           contains a group and a back reference to it.  */
4834    
# Line 4836  common_op_match_null_string_p (p, end, r Line 4838  common_op_match_null_string_p (p, end, r
4838        if (!ret)        if (!ret)
4839          return false;          return false;
4840        break;        break;
4841              
4842      /* If this is an optimized succeed_n for zero times, make the jump.  */      /* If this is an optimized succeed_n for zero times, make the jump.  */
4843      case jump:      case jump:
4844        EXTRACT_NUMBER_AND_INCR (mcnt, p1);        EXTRACT_NUMBER_AND_INCR (mcnt, p1);
# Line 4848  common_op_match_null_string_p (p, end, r Line 4850  common_op_match_null_string_p (p, end, r
4850    
4851      case succeed_n:      case succeed_n:
4852        /* Get to the number of times to succeed.  */        /* Get to the number of times to succeed.  */
4853        p1 += 2;                  p1 += 2;
4854        EXTRACT_NUMBER_AND_INCR (mcnt, p1);        EXTRACT_NUMBER_AND_INCR (mcnt, p1);
4855    
4856        if (mcnt == 0)        if (mcnt == 0)
# Line 4861  common_op_match_null_string_p (p, end, r Line 4863  common_op_match_null_string_p (p, end, r
4863          return false;          return false;
4864        break;        break;
4865    
4866      case duplicate:      case duplicate:
4867        if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))        if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
4868          return false;          return false;
4869        break;        break;
# Line 4881  common_op_match_null_string_p (p, end, r Line 4883  common_op_match_null_string_p (p, end, r
4883    
4884  /* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN  /* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
4885     bytes; nonzero otherwise.  */     bytes; nonzero otherwise.  */
4886      
4887  static int  static int
4888  bcmp_translate (s1, s2, len, translate)  bcmp_translate (s1, s2, len, translate)
4889       unsigned char *s1, *s2;       unsigned char *s1, *s2;
# Line 4902  bcmp_translate (s1, s2, len, translate) Line 4904  bcmp_translate (s1, s2, len, translate)
4904  /* re_compile_pattern is the GNU regular expression compiler: it  /* re_compile_pattern is the GNU regular expression compiler: it
4905     compiles PATTERN (of length SIZE) and puts the result in BUFP.     compiles PATTERN (of length SIZE) and puts the result in BUFP.
4906     Returns 0 if the pattern was valid, otherwise an error string.     Returns 0 if the pattern was valid, otherwise an error string.
4907      
4908     Assumes the `allocated' (and perhaps `buffer') and `translate' fields     Assumes the `allocated' (and perhaps `buffer') and `translate' fields
4909     are set in BUFP on entry.     are set in BUFP on entry.
4910      
4911     We call regex_compile to do the actual compilation.  */     We call regex_compile to do the actual compilation.  */
4912    
4913  const char *  const char *
# Line 4915  re_compile_pattern (pattern, length, buf Line 4917  re_compile_pattern (pattern, length, buf
4917       struct re_pattern_buffer *bufp;       struct re_pattern_buffer *bufp;
4918  {  {
4919    reg_errcode_t ret;    reg_errcode_t ret;
4920      
4921    /* GNU code is written to assume at least RE_NREGS registers will be set    /* GNU code is written to assume at least RE_NREGS registers will be set
4922       (and at least one extra will be -1).  */       (and at least one extra will be -1).  */
4923    bufp->regs_allocated = REGS_UNALLOCATED;    bufp->regs_allocated = REGS_UNALLOCATED;
4924      
4925    /* And GNU code determines whether or not to get register information    /* And GNU code determines whether or not to get register information
4926       by passing null for the REGS argument to re_match, etc., not by       by passing null for the REGS argument to re_match, etc., not by
4927       setting no_sub.  */       setting no_sub.  */
4928    bufp->no_sub = 0;    bufp->no_sub = 0;
4929      
4930    /* Match anchors at newline.  */    /* Match anchors at newline.  */
4931    bufp->newline_anchor = 1;    bufp->newline_anchor = 1;
4932      
4933    ret = regex_compile (pattern, length, re_syntax_options, bufp);    ret = regex_compile (pattern, length, re_syntax_options, bufp);
4934    
4935    return re_error_msg[(int) ret];    return re_error_msg[(int) ret];
4936  }      }
4937    
4938  /* Entry points compatible with 4.2 BSD regex library.  We don't define  /* Entry points compatible with 4.2 BSD regex library.  We don't define
4939     them unless specifically requested.  */     them unless specifically requested.  */
# Line 4946  re_comp (s) Line 4948  re_comp (s)
4948      const char *s;      const char *s;
4949  {  {
4950    reg_errcode_t ret;    reg_errcode_t ret;
4951      
4952    if (!s)    if (!s)
4953      {      {
4954        if (!re_comp_buf.buffer)        if (!re_comp_buf.buffer)
# Line 4973  re_comp (s) Line 4975  re_comp (s)
4975    re_comp_buf.newline_anchor = 1;    re_comp_buf.newline_anchor = 1;
4976    
4977    ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);    ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
4978      
4979    /* Yes, we're discarding `const' here.  */    /* Yes, we're discarding `const' here.  */
4980    return (char *) re_error_msg[(int) ret];    return (char *) re_error_msg[(int) ret];
4981  }  }
# Line 5030  re_exec (s) Line 5032  re_exec (s)
5032  int  int
5033  regcomp (preg, pattern, cflags)  regcomp (preg, pattern, cflags)
5034      regex_t *preg;      regex_t *preg;
5035      const char *pattern;      const char *pattern;
5036      int cflags;      int cflags;
5037  {  {
5038    reg_errcode_t ret;    reg_errcode_t ret;
# Line 5042  regcomp (preg, pattern, cflags) Line 5044  regcomp (preg, pattern, cflags)
5044    preg->buffer = 0;    preg->buffer = 0;
5045    preg->allocated = 0;    preg->allocated = 0;
5046    preg->used = 0;    preg->used = 0;
5047      
5048    /* Don't bother to use a fastmap when searching.  This simplifies the    /* Don't bother to use a fastmap when searching.  This simplifies the
5049       REG_NEWLINE case: if we used a fastmap, we'd have to put all the       REG_NEWLINE case: if we used a fastmap, we'd have to put all the
5050       characters after newlines into the fastmap.  This way, we just try       characters after newlines into the fastmap.  This way, we just try
5051       every character.  */       every character.  */
5052    preg->fastmap = 0;    preg->fastmap = 0;
5053      
5054    if (cflags & REG_ICASE)    if (cflags & REG_ICASE)
5055      {      {
5056        unsigned i;        unsigned i;
5057          
5058        preg->translate = (char *) malloc (CHAR_SET_SIZE);        preg->translate = (char *) malloc (CHAR_SET_SIZE);
5059        if (preg->translate == NULL)        if (preg->translate == NULL)
5060          return (int) REG_ESPACE;          return (int) REG_ESPACE;
# Line 5077  regcomp (preg, pattern, cflags) Line 5079  regcomp (preg, pattern, cflags)
5079    
5080    preg->no_sub = !!(cflags & REG_NOSUB);    preg->no_sub = !!(cflags & REG_NOSUB);
5081    
5082    /* POSIX says a null character in the pattern terminates it, so we    /* POSIX says a null character in the pattern terminates it, so we
5083       can use strlen here in compiling the pattern.  */       can use strlen here in compiling the pattern.  */
5084    ret = regex_compile (pattern, strlen (pattern), syntax, preg);    ret = regex_compile (pattern, strlen (pattern), syntax, preg);
5085      
5086    /* POSIX doesn't distinguish between an unmatched open-group and an    /* POSIX doesn't distinguish between an unmatched open-group and an
5087       unmatched close-group: both are REG_EPAREN.  */       unmatched close-group: both are REG_EPAREN.  */
5088    if (ret == REG_ERPAREN) ret = REG_EPAREN;    if (ret == REG_ERPAREN) ret = REG_EPAREN;
5089      
5090    return (int) ret;    return (int) ret;
5091  }  }
5092    
5093    
5094  /* regexec searches for a given pattern, specified by PREG, in the  /* regexec searches for a given pattern, specified by PREG, in the
5095     string STRING.     string STRING.
5096      
5097     If NMATCH is zero or REG_NOSUB was set in the cflags argument to     If NMATCH is zero or REG_NOSUB was set in the cflags argument to
5098     `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at     `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
5099     least NMATCH elements, and we set them to the offsets of the     least NMATCH elements, and we set them to the offsets of the
5100     corresponding matched substrings.     corresponding matched substrings.
5101      
5102     EFLAGS specifies `execution flags' which affect matching: if     EFLAGS specifies `execution flags' which affect matching: if
5103     REG_NOTBOL is set, then ^ does not match at the beginning of the     REG_NOTBOL is set, then ^ does not match at the beginning of the
5104     string; if REG_NOTEOL is set, then $ does not match at the end.     string; if REG_NOTEOL is set, then $ does not match at the end.
5105      
5106     We return 0 if we find a match and REG_NOMATCH if not.  */     We return 0 if we find a match and REG_NOMATCH if not.  */
5107    
5108  int  int
5109  regexec (preg, string, nmatch, pmatch, eflags)  regexec (preg, string, nmatch, pmatch, eflags)
5110      const regex_t *preg;      const regex_t *preg;
5111      const char *string;      const char *string;
5112      size_t nmatch;      size_t nmatch;
5113      regmatch_t pmatch[];      regmatch_t pmatch[];
5114      int eflags;      int eflags;
5115  {  {
5116    int ret;    int ret;
# Line 5118  regexec (preg, string, nmatch, pmatch, e Line 5120  regexec (preg, string, nmatch, pmatch, e
5120    boolean want_reg_info = !preg->no_sub && nmatch > 0;    boolean want_reg_info = !preg->no_sub && nmatch > 0;
5121    
5122    private_preg = *preg;    private_preg = *preg;
5123      
5124    private_preg.not_bol = !!(eflags & REG_NOTBOL);    private_preg.not_bol = !!(eflags & REG_NOTBOL);
5125    private_preg.not_eol = !!(eflags & REG_NOTEOL);    private_preg.not_eol = !!(eflags & REG_NOTEOL);
5126      
5127    /* The user has told us exactly how many registers to return    /* The user has told us exactly how many registers to return
5128       information about, via `nmatch'.  We have to pass that on to the       information about, via `nmatch'.  We have to pass that on to the
5129       matching routines.  */       matching routines.  */
5130    private_preg.regs_allocated = REGS_FIXED;    private_preg.regs_allocated = REGS_FIXED;
5131      
5132    if (want_reg_info)    if (want_reg_info)
5133      {      {
5134        regs.num_regs = nmatch;        regs.num_regs = nmatch;
# Line 5140  regexec (preg, string, nmatch, pmatch, e Line 5142  regexec (preg, string, nmatch, pmatch, e
5142    ret = re_search (&private_preg, string, len,    ret = re_search (&private_preg, string, len,
5143                     /* start: */ 0, /* range: */ len,                     /* start: */ 0, /* range: */ len,
5144                     want_reg_info ? &regs : (struct re_registers *) 0);                     want_reg_info ? &regs : (struct re_registers *) 0);
5145      
5146    /* Copy the register information to the POSIX structure.  */    /* Copy the register information to the POSIX structure.  */
5147    if (want_reg_info)    if (want_reg_info)
5148      {      {
# Line 5180  regerror (errcode, preg, errbuf, errbuf_ Line 5182  regerror (errcode, preg, errbuf, errbuf_
5182    
5183    if (errcode < 0    if (errcode < 0
5184        || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))        || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
5185      /* Only error codes returned by the rest of the code should be passed      /* Only error codes returned by the rest of the code should be passed
5186         to this routine.  If we are given anything else, or if other regex         to this routine.  If we are given anything else, or if other regex
5187         code generates an invalid error code, then the program has a bug.         code generates an invalid error code, then the program has a bug.
5188         Dump core so we can fix it.  */         Dump core so we can fix it.  */
# Line 5194  regerror (errcode, preg, errbuf, errbuf_ Line 5196  regerror (errcode, preg, errbuf, errbuf_
5196      msg = "Success";      msg = "Success";
5197    
5198    msg_size = strlen (msg) + 1; /* Includes the null.  */    msg_size = strlen (msg) + 1; /* Includes the null.  */
5199      
5200    if (errbuf_size != 0)    if (errbuf_size != 0)
5201      {      {
5202        if (msg_size > errbuf_size)        if (msg_size > errbuf_size)
# Line 5219  regfree (preg) Line 5221  regfree (preg)
5221    if (preg->buffer != NULL)    if (preg->buffer != NULL)
5222      free (preg->buffer);      free (preg->buffer);
5223    preg->buffer = NULL;    preg->buffer = NULL;
5224      
5225    preg->allocated = 0;    preg->allocated = 0;
5226    preg->used = 0;    preg->used = 0;
5227    

Legend:
Removed from v.1.1.1.1.2.2  
changed lines
  Added in v.1.1.1.1.2.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26