* mips.h: Correct comment typo.
[binutils-gdb.git] / libiberty / regex.c
index 555d3bbf66aaebe74dd139b151277d5015216d15..f9d9a4e26dce9b3c73f916b8695564c84398b548 100644 (file)
@@ -2,7 +2,7 @@
    version 0.12.
    (Implements POSIX draft P1003.2/D11.2, except for some of the
    internationalization features.)
-   Copyright (C) 1993-1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1993-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -25,7 +25,7 @@
    routines with an "x" prefix so they do not collide with the native regex
    routines or with other components regex routines. */
 /* AIX requires this to be the first thing in the file. */
-#if defined _AIX && !defined REGEX_MALLOC
+#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
   #pragma alloca
 #endif
 
@@ -95,7 +95,7 @@
 # endif
 
 /* This is for other GNU distributions with internationalized messages.  */
-# if HAVE_LIBINTL_H || defined _LIBC
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
 #  include <libintl.h>
 #  ifdef _LIBC
 #   undef gettext
@@ -301,7 +301,7 @@ init_syntax_once ()
 # endif /* emacs */
 \f
 /* Integer type for pointers.  */
-# if !defined _LIBC
+# if !defined _LIBC && !defined HAVE_UINTPTR_T
 typedef unsigned long int uintptr_t;
 # endif
 
@@ -612,7 +612,11 @@ typedef enum
 # define UCHAR_T unsigned char
 # define COMPILED_BUFFER_VAR bufp->buffer
 # define OFFSET_ADDRESS_SIZE 2
-# define PREFIX(name) byte_##name
+# if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#  define PREFIX(name) byte_##name
+# else
+#  define PREFIX(name) byte_/**/name
+# endif
 # define ARG_PREFIX(name) name
 # define PUT_CHAR(c) putchar (c)
 #else
@@ -622,8 +626,13 @@ typedef enum
 #  define COMPILED_BUFFER_VAR wc_buffer
 #  define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
 #  define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
-#  define PREFIX(name) wcs_##name
-#  define ARG_PREFIX(name) c##name
+#  if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#   define PREFIX(name) wcs_##name
+#   define ARG_PREFIX(name) c##name
+#  else
+#   define PREFIX(name) wcs_/**/name
+#   define ARG_PREFIX(name) c/**/name
+#  endif
 /* Should we use wide stream??  */
 #  define PUT_CHAR(c) printf ("%C", c);
 #  define TRUE 1
@@ -1288,7 +1297,11 @@ convert_mbs_to_wcs (dest, src, len, offset_buffer, is_binary)
   for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
         psrc += consumed)
     {
+#ifdef _LIBC
+      consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
+#else
       consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
+#endif
 
       if (consumed <= 0)
        /* failed to convert. maybe src contains binary data.
@@ -1360,80 +1373,26 @@ weak_alias (__re_set_syntax, re_set_syntax)
    POSIX doesn't require that we do anything for REG_NOERROR,
    but why not be nice?  */
 
-static const char re_error_msgid[] =
+static const char *re_error_msgid[] =
   {
-# define REG_NOERROR_IDX       0
-    gettext_noop ("Success")   /* REG_NOERROR */
-    "\0"
-# define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
-    gettext_noop ("No match")  /* REG_NOMATCH */
-    "\0"
-# define REG_BADPAT_IDX        (REG_NOMATCH_IDX + sizeof "No match")
-    gettext_noop ("Invalid regular expression") /* REG_BADPAT */
-    "\0"
-# define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
-    gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
-    "\0"
-# define REG_ECTYPE_IDX        (REG_ECOLLATE_IDX + sizeof "Invalid collation character")
-    gettext_noop ("Invalid character class name") /* REG_ECTYPE */
-    "\0"
-# define REG_EESCAPE_IDX       (REG_ECTYPE_IDX + sizeof "Invalid character class name")
-    gettext_noop ("Trailing backslash") /* REG_EESCAPE */
-    "\0"
-# define REG_ESUBREG_IDX       (REG_EESCAPE_IDX + sizeof "Trailing backslash")
-    gettext_noop ("Invalid back reference") /* REG_ESUBREG */
-    "\0"
-# define REG_EBRACK_IDX        (REG_ESUBREG_IDX + sizeof "Invalid back reference")
-    gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
-    "\0"
-# define REG_EPAREN_IDX        (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
-    gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
-    "\0"
-# define REG_EBRACE_IDX        (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
-    gettext_noop ("Unmatched \\{") /* REG_EBRACE */
-    "\0"
-# define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{")
-    gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
-    "\0"
-# define REG_ERANGE_IDX        (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
-    gettext_noop ("Invalid range end") /* REG_ERANGE */
-    "\0"
-# define REG_ESPACE_IDX        (REG_ERANGE_IDX + sizeof "Invalid range end")
-    gettext_noop ("Memory exhausted") /* REG_ESPACE */
-    "\0"
-# define REG_BADRPT_IDX        (REG_ESPACE_IDX + sizeof "Memory exhausted")
-    gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
-    "\0"
-# define REG_EEND_IDX  (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
-    gettext_noop ("Premature end of regular expression") /* REG_EEND */
-    "\0"
-# define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression")
-    gettext_noop ("Regular expression too big") /* REG_ESIZE */
-    "\0"
-# define REG_ERPAREN_IDX       (REG_ESIZE_IDX + sizeof "Regular expression too big")
+    gettext_noop ("Success"),  /* REG_NOERROR */
+    gettext_noop ("No match"), /* REG_NOMATCH */
+    gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
+    gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
+    gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
+    gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
+    gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
+    gettext_noop ("Unmatched [ or [^"),        /* REG_EBRACK */
+    gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
+    gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
+    gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
+    gettext_noop ("Invalid range end"),        /* REG_ERANGE */
+    gettext_noop ("Memory exhausted"), /* REG_ESPACE */
+    gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
+    gettext_noop ("Premature end of regular expression"), /* REG_EEND */
+    gettext_noop ("Regular expression too big"), /* REG_ESIZE */
     gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
   };
-
-static const size_t re_error_msgid_idx[] =
-  {
-    REG_NOERROR_IDX,
-    REG_NOMATCH_IDX,
-    REG_BADPAT_IDX,
-    REG_ECOLLATE_IDX,
-    REG_ECTYPE_IDX,
-    REG_EESCAPE_IDX,
-    REG_ESUBREG_IDX,
-    REG_EBRACK_IDX,
-    REG_EPAREN_IDX,
-    REG_EBRACE_IDX,
-    REG_BADBR_IDX,
-    REG_ERANGE_IDX,
-    REG_ESPACE_IDX,
-    REG_BADRPT_IDX,
-    REG_EEND_IDX,
-    REG_ESIZE_IDX,
-    REG_ERPAREN_IDX
-  };
 \f
 #endif /* INSIDE_RECURSION */
 
@@ -3059,7 +3018,7 @@ PREFIX(regex_compile) (ARG_PREFIX(pattern), ARG_PREFIX(size), syntax, bufp)
                                    /* First compare the hashing value.  */
                                    if (symb_table[2 * elem] == hash
                                        && c1 == extra[symb_table[2 * elem + 1]]
-                                       && memcmp (str,
+                                       && memcmp (char_str,
                                                   &extra[symb_table[2 * elem + 1]
                                                         + 1], c1) == 0)
                                      {
@@ -3079,7 +3038,7 @@ PREFIX(regex_compile) (ARG_PREFIX(pattern), ARG_PREFIX(size), syntax, bufp)
                                       in the table.  */
                                    idx += 1 + extra[idx];
                                    /* Adjust for the alignment.  */
-                                   idx = (idx + 3) & ~4;
+                                   idx = (idx + 3) & ~3;
 
                                    str[0] = (wchar_t) idx + 4;
                                  }
@@ -4627,9 +4586,16 @@ static unsigned char
 truncate_wchar (c)
      CHAR_T c;
 {
-  unsigned char buf[MB_LEN_MAX];
-  int retval = wctomb(buf, c);
-  return retval > 0 ? buf[0] : (unsigned char)c;
+  unsigned char buf[MB_CUR_MAX];
+  mbstate_t state;
+  int retval;
+  memset (&state, '\0', sizeof (state));
+# ifdef _LIBC
+  retval = __wcrtomb (buf, c, &state);
+# else
+  retval = wcrtomb (buf, c, &state);
+# endif
+  return retval > 0 ? buf[0] : (unsigned char) c;
 }
 #endif /* WCHAR */
 
@@ -4682,7 +4648,7 @@ PREFIX(re_compile_fastmap) (bufp)
 
   while (1)
     {
-      if (p == pend || *p == succeed)
+      if (p == pend || *p == (UCHAR_T) succeed)
        {
          /* We have reached the (effective) end of pattern.  */
          if (!FAIL_STACK_EMPTY ())
@@ -6337,8 +6303,13 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                                      & ~(uintptr_t)(__alignof__(wctype_t) - 1);
                wctype = *((wctype_t*)alignedp);
                workp += CHAR_CLASS_SIZE;
+# ifdef _LIBC
+               if (__iswctype((wint_t)c, wctype))
+                 goto char_set_matched;
+# else
                if (iswctype((wint_t)c, wctype))
                  goto char_set_matched;
+# endif
              }
 
             /* match with collating_symbol?  */
@@ -6374,12 +6345,20 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
                  {
                    const CHAR_T *backup_d = d, *backup_dend = dend;
-                   length = wcslen(workp);
+# ifdef _LIBC
+                   length = __wcslen (workp);
+# else
+                   length = wcslen (workp);
+# endif
 
                    /* If wcscoll(the collating symbol, whole string) > 0,
                       any substring of the string never match with the
                       collating symbol.  */
-                   if (wcscoll(workp, d) > 0)
+# ifdef _LIBC
+                   if (__wcscoll (workp, d) > 0)
+# else
+                   if (wcscoll (workp, d) > 0)
+# endif
                      {
                        workp += length + 1;
                        continue;
@@ -6404,7 +6383,11 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                        str_buf[i] = TRANSLATE(*d);
                        str_buf[i+1] = '\0';
 
-                       match = wcscoll(workp, str_buf);
+# ifdef _LIBC
+                       match = __wcscoll (workp, str_buf);
+# else
+                       match = wcscoll (workp, str_buf);
+# endif
                        if (match == 0)
                          goto char_set_matched;
 
@@ -6515,12 +6498,20 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
                  {
                    const CHAR_T *backup_d = d, *backup_dend = dend;
-                   length = wcslen(workp);
+# ifdef _LIBC
+                   length = __wcslen (workp);
+# else
+                   length = wcslen (workp);
+# endif
 
                    /* If wcscoll(the collating symbol, whole string) > 0,
                       any substring of the string never match with the
                       collating symbol.  */
-                   if (wcscoll(workp, d) > 0)
+# ifdef _LIBC
+                   if (__wcscoll (workp, d) > 0)
+# else
+                   if (wcscoll (workp, d) > 0)
+# endif
                      {
                        workp += length + 1;
                        break;
@@ -6545,7 +6536,11 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                        str_buf[i] = TRANSLATE(*d);
                        str_buf[i+1] = '\0';
 
-                       match = wcscoll(workp, str_buf);
+# ifdef _LIBC
+                       match = __wcscoll (workp, str_buf);
+# else
+                       match = wcscoll (workp, str_buf);
+# endif
 
                        if (match == 0)
                          goto char_set_matched;
@@ -6568,7 +6563,7 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
              }
 
             /* match with char_range?  */
-#ifdef _LIBC
+# ifdef _LIBC
            if (nrules != 0)
              {
                uint32_t collseqval;
@@ -6591,7 +6586,7 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                  }
              }
            else
-#endif
+# endif
              {
                /* We set range_start_char at str_buf[0], range_end_char
                   at str_buf[4], and compared char at str_buf[2].  */
@@ -6627,9 +6622,13 @@ byte_re_match_2_internal (bufp, string1, size1,string2, size2, pos,
                        range_end_char = str_buf + 4;
                      }
 
-                   if (wcscoll(range_start_char, str_buf+2) <= 0 &&
-                       wcscoll(str_buf+2, range_end_char) <= 0)
-
+# ifdef _LIBC
+                   if (__wcscoll (range_start_char, str_buf+2) <= 0
+                       && __wcscoll (str_buf+2, range_end_char) <= 0)
+# else
+                   if (wcscoll (range_start_char, str_buf+2) <= 0
+                       && wcscoll (str_buf+2, range_end_char) <= 0)
+# endif
                      goto char_set_matched;
                  }
              }
@@ -7891,7 +7890,7 @@ re_compile_pattern (pattern, length, bufp)
 
   if (!ret)
     return NULL;
-  return gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
+  return gettext (re_error_msgid[(int) ret]);
 }
 #ifdef _LIBC
 weak_alias (__re_compile_pattern, re_compile_pattern)
@@ -7928,14 +7927,12 @@ re_comp (s)
     {
       re_comp_buf.buffer = (unsigned char *) malloc (200);
       if (re_comp_buf.buffer == NULL)
-        return (char *) gettext (re_error_msgid
-                                + re_error_msgid_idx[(int) REG_ESPACE]);
+        return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
       re_comp_buf.allocated = 200;
 
       re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
       if (re_comp_buf.fastmap == NULL)
-       return (char *) gettext (re_error_msgid
-                                + re_error_msgid_idx[(int) REG_ESPACE]);
+       return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
     }
 
   /* Since `re_exec' always passes NULL for the `regs' argument, we
@@ -7955,7 +7952,7 @@ re_comp (s)
     return NULL;
 
   /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
-  return (char *) gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
+  return (char *) gettext (re_error_msgid[(int) ret]);
 }
 
 
@@ -8186,15 +8183,15 @@ regerror (errcode, preg, errbuf, errbuf_size)
   size_t msg_size;
 
   if (errcode < 0
-      || errcode >= (int) (sizeof (re_error_msgid_idx)
-                          / sizeof (re_error_msgid_idx[0])))
+      || errcode >= (int) (sizeof (re_error_msgid)
+                          / sizeof (re_error_msgid[0])))
     /* Only error codes returned by the rest of the code should be passed
        to this routine.  If we are given anything else, or if other regex
        code generates an invalid error code, then the program has a bug.
        Dump core so we can fix it.  */
     abort ();
 
-  msg = gettext (re_error_msgid + re_error_msgid_idx[errcode]);
+  msg = gettext (re_error_msgid[errcode]);
 
   msg_size = strlen (msg) + 1; /* Includes the null.  */