about summary refs log tree commit diff
path: root/posix
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-04-28 23:13:52 +0000
committerUlrich Drepper <drepper@redhat.com>1999-04-28 23:13:52 +0000
commitc4563d2d668675c2d5083f6ad01c801d6ccbe013 (patch)
tree1e6af86f8c33743c81080dffb17a8e8209825c06 /posix
parent89afc233db58d3de7669332d141113ec2ca4991d (diff)
downloadglibc-c4563d2d668675c2d5083f6ad01c801d6ccbe013.tar.gz
glibc-c4563d2d668675c2d5083f6ad01c801d6ccbe013.tar.xz
glibc-c4563d2d668675c2d5083f6ad01c801d6ccbe013.zip
Update.
1999-04-28  Ulrich Drepper  <drepper@cygnus.com>

	* argp/argp-ba.c (argp_program_bug_address): Don't initialize with 0.
	* argp/argp-parse.c (_argp_hang): Likewise.
	* argp/argp-pv.c (argp_program_version): Likewise.
	* argp/argp-pvh.c (argp_program_version_hook): Likewise.
	* inet/ether_hton.c (ether_hton, startp): Likewise.
	* inet/ether_ntoh.c (ether_ntoh, startp): Likewise.
	* inet/getnetgrent_r.c (setup, startp): Likewise.
	* intl/loadmsgcat.c (_nl_msg_cat_cntr): Likewise.
	* intl/localealias.c (string_space, string_space_act, string_space_max,
	nmap, maxmap): Likewise.
	* libio/iopopen.c (proc_file_chain): Likewise.
	* libio/oldiopopen.c (old_proc_file_chain): Likewise.
	* locale/lc-collate.c (__collate_table, __collate_extra,
	__collate_element_hash, __collate_element_strings,
	__collate_element_values): Likewise.
	* malloc/mcheck.c (mcheck_used): Likewise.
	* malloc/mtrace.c (added_atexit_handler): Likewise.
	* malloc/set-freeres.c (already_called): Likewise.
	* misc/getpass.c (getpass) [buf, bufsize]: Likewise.
	* misc/syslog.c (LogStat, LogTag): Likewise.
	* nss/XXX-lookup.c (DATABASE_NAME_SYMBOL): Likewise.
	* nss/getXXbyYY_r.c (startp): Likewise.
	* posix/getopt.c (optarg, __getopt_initialized): Likewise.
	* posix/regex.c (init_syntax_once) [done]: Likewise.
	(debug): Likewise.
	* string/strfry.c (init): Likewise.
	* sunrpc/svc_run.c (svc_top): Likewise.
	* posix/euidaccess.c (have_ids): Likewise.
	* sysdeps/unix/sysv/linux/poll.c (must_emulate): Likewise.
	* sysdeps/unix/sysv/linux/ttyname.c (__ttyname, namelen): Likewise.
	* time/getdate.c (getdate_err): Likewise.
	* time/tzfile.c (transitions, type_idxs, types, zone_names, leaps):
	Likewise.
	* time/tzset.c (old_tz, is_initialized): Likewise.

	* inet/getnameinfo.c (nrl_domainname): Rewrite to allow initialization
	of static data with zero.
	* signal/allocrtsig.c (init): Likewise.

	* string/Makefile (routines): Add strchrnul.
	* string/Versions [GLIBC_2.1.1]: Add strchrnul.
	* string/string.c: Add strchrnul prototype.
	* include/string.h: Add __strchrnul prototype.
	* sysdeps/generic/strchrnul.c: New file.
	* sysdeps/i386/strchrnul.S: New file.
	* sysdeps/i386/bits/string.c: Add strchrnul optimization.
	* sysdeps/i386/i486/bits/string.c: Likewise.
	* argp/argp-help.c (argp_args_usage): Use __strchrnul.
	* inet/ether_line.c (ether_line): Likewise.
	* nscd/nscd_conf.c (nscd_parse_file): Likewise.
	* nss/nsswitch.c (nss_parse_file): Likewise.
	* posix/execvp.c (execvp): Likewise.
	* posix/fnmatch.c (internal_fnmatch): Likewise.
	* resolv/res_hconf.c (_res_hconv_init): Likewise.
	* resolv/res_init.c (res_init): Likewise.
	* stdlib/fmtmsg.c (init): Likewise.
	* stdlib/getsubopt.c (getsubopt): Likewise.

	* catgets/catgets.c (catopen): Only allocate one memory block.
	(catclose): Only one free call necessary.

	* catgets/open_catalog.c (__open_catalog): Simplify handling of
	file descriptor.

	* ctype/ctype-extn.c: Make __toascii_l and __isascii_l alias instead
	of real functions.  Simplify _tolower and _toupper.

	* grp/initgroups.c (compat_call): Remove unnecessary use of pointer
	variable.

	* iconv/gconv.h (struct gconv_info): Change data element from pointer
	to array of size 0.
	* iconv/gconv_open.c (__gconv_open): Allocate structures accordingly.
	* iconv/gconv_close.c (__gconv_close): Don't free data.

	* iconv/gconv_conf.c (add_alias): Avoid searching in tree twice to
	insert new alias.

	* iconv/gconv_db.c (add_derivation): More efficient copying.  Check
	for error while inserting in tree.

	* include/time.h: Pretty print.

	* inet/ruserpass.c: Rewrite use of toktab to avoid string pointers
	in table and lots of relocations.
	* posix/regex.c (regerror): Rewrite use of re_error_msgid to avoid
	string pointers in table and lots of relocations.

	* intl/finddomain.c: Remove definition of strchr macro.

	* io/ftw.c (nftw_arr, ftw_arr): Make const.

	* locale/loadlocale.c (_nl_load_locale): Optimize string copying.

	* locale/localeinfo.h (_nl_category_names): Change into an array with
	fixed width char string elements.
	* locale/setlocale.c (_nl_category_names): Likewise.
	(_nl_current): Make global.
	* locale/nl_langinfo.c (nldata): Removed.  Use _nl_current now.

	* malloc/Makefile (distribute): Add stackinfo.h.
	* sysdeps/generic/stackinfo.h: New file.
	* sysdeps/i386/stackinfo.h: New file.
	* posix/execl.c: Use stackinfo.h in optimizing alloca use.
	* posix/execle.c: Likewise.
	* posix/execlp.c: Likewise.

	* nis/nis_table.c (__create_ib_request): Always use realloc.

	* posix/execvp.c (execute): Rename to script_execute and keep only
	code to execute using shell.
	(execvp): Call execv directly and only fall back on script_execute.

	* resolv/inet_net_pton.c (inet_net_pton_ipv4): Remove digits define
	and always use xdigits instead.

	* resolv/res_init.c (res_init): Use rawmemchr instead of strchr
	where appropriate.

	* stdlib/fpioconst.h (__tens): New declaration.
	(struct mp_power): Remove array, add arrayoff element.
	* stdlib/fpioconst.c: Replace definitions of _ten_p* arrays by one
	__tens array and add in _fpioconst_pow10 offsets into __tens.
	* stdio-common/printf_fp.c: Rewrite to use new __tens array.
	* stdlib/strtod.c: Likewise.

	* stdlib/a64l.c (a64l_table): Avoid unnecessary elements.

	* stdlib/exit.c: Rewrite to use __exit_funcs being as sign for end
	of the list.
	* stdlib/atexit.c (__exit_funcs): Don't initialize.

	* stdlib/fmtmsg.c (keywords): Make name element fixed width array.

	* sunrpc/clnt_perr.c: Rewrite clnt_sperrno and auth_errmsg to use
	a single and an array with offsets.

	* sunrpc/des_soft.c (partab): Make it const.

	* sunrpc/key_call.c (trytimeout, tottimeout): Make const.
	(__key_encryptsession_pk_LOCAL): Don't initialize with 0.
	(__key_decryptsession_pk_LOCAL): Likewise.
	(__key_gendes_LOCAL): Likewise.
	(MESSENGER): Mark const.
	(key_call_private_main): Don't initialize with 0.
	(use_keyenvoy): Don't initialize with 0.
	(key_call): Rewrite to reverse logic of use_doors variable.

	* sunrpc/netname.c (OPSYS): Define as array, not pointer.
	(startp): Don't initialize with zero.

	* sunrpc/openchild.c (_openchild): Make first argument const.

	* sunrpc/pmap_rmt.c (timeout): Mark const.
	* sunrpc/xcrypt.c (hex): Likewise.

	* sysdeps/unix/sysv/linux/getcwd.c: Rewrite to allow omitting
	initialization of global variables.
	* sysdeps/unix/sysv/linux/getpt.c: Likewise.
	* sysdeps/unix/sysv/linux/if_index.c: Likewise.
	* termios/tcgetsid.c: Likewise.

	* sysdeps/unix/sysv/linux/i386/dl-procinfo.h (x86_cap_flags): Change
	fxsr to osfxsr.

	* time/tzfile.c (__tzfile_read): Rewrite to allocate only one memory
	block.  Add function to free memory if wanted.
	* time/tzset.c (tzset_internal): Pass extra argument to __tzfile_read.

	* wcsmbs/wcsmbsload.c (to_wc, to_mb): Correct initializers.

	* wcsmbs/wmemset.c: Little code optimization.
Diffstat (limited to 'posix')
-rw-r--r--posix/execl.c11
-rw-r--r--posix/execle.c19
-rw-r--r--posix/execlp.c11
-rw-r--r--posix/execvp.c83
-rw-r--r--posix/fnmatch.c3
-rw-r--r--posix/getopt.c6
-rw-r--r--posix/regex.c108
7 files changed, 158 insertions, 83 deletions
diff --git a/posix/execl.c b/posix/execl.c
index 13f8b393d5..5ea1c4ebf0 100644
--- a/posix/execl.c
+++ b/posix/execl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1994, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 94, 97, 98, 99 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
@@ -22,6 +22,8 @@
 #include <stddef.h>
 #include <string.h>
 
+#include <stackinfo.h>
+
 #ifndef	HAVE_GNU_LD
 # define __environ	environ
 #endif
@@ -46,16 +48,21 @@ execl (const char *path, const char *arg, ...)
 	{
 	  const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
 
+#ifndef _STACK_GROWS_UP
 	  if ((char *) nptr + argv_max == (char *) argv)
 	    {
 	      /* Stack grows down.  */
 	      argv = (const char **) memcpy (nptr, argv, i);
 	      argv_max += i;
 	    }
-	  else if ((char *) argv + i == (char *) nptr)
+	  else
+#endif
+#ifndef _STACK_GROWS_DOWN
+	    if ((char *) argv + i == (char *) nptr)
 	    /* Stack grows up.  */
 	    argv_max += i;
 	  else
+#endif
 	    /* We have a hole in the stack.  */
 	    argv = (const char **) memcpy (nptr, argv, i);
 	}
diff --git a/posix/execle.c b/posix/execle.c
index dc150a4702..a8a016ee69 100644
--- a/posix/execle.c
+++ b/posix/execle.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1997, 1998, 1999 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
@@ -22,6 +22,8 @@
 #include <stddef.h>
 #include <string.h>
 
+#include <stackinfo.h>
+
 /* Execute PATH with all arguments after PATH until a NULL pointer,
    and the argument after that for environment.  */
 int
@@ -34,7 +36,7 @@ execle (const char *path, const char *arg, ...)
   va_list args;
   argv[0] = arg;
 
-  va_start(args, arg);
+  va_start (args, arg);
   i = 0;
   while (argv[i++] != NULL)
     {
@@ -42,16 +44,21 @@ execle (const char *path, const char *arg, ...)
 	{
 	  const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
 
+#ifndef _STACK_GROWS_UP
 	  if ((char *) nptr + argv_max == (char *) argv)
 	    {
 	      /* Stack grows down.  */
 	      argv = (const char **) memcpy (nptr, argv, i);
 	      argv_max += i;
 	    }
-	  else if ((char *) argv + i == (char *) nptr)
+	  else
+#endif
+#ifndef _STACK_GROWS_DOWN
+	    if ((char *) argv + i == (char *) nptr)
 	    /* Stack grows up.  */
 	    argv_max += i;
 	  else
+#endif
 	    /* We have a hole in the stack.  */
 	    argv = (const char **) memcpy (nptr, argv, i);
 	}
@@ -59,8 +66,8 @@ execle (const char *path, const char *arg, ...)
       argv[i] = va_arg (args, const char *);
     }
 
-  envp = va_arg(args, const char *const *);
-  va_end(args);
+  envp = va_arg (args, const char *const *);
+  va_end (args);
 
-  return __execve(path, (char *const *) argv, (char *const *) envp);
+  return __execve (path, (char *const *) argv, (char *const *) envp);
 }
diff --git a/posix/execlp.c b/posix/execlp.c
index 6cad6402ec..40456f7817 100644
--- a/posix/execlp.c
+++ b/posix/execlp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 93, 96, 97, 98, 99 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
@@ -22,6 +22,8 @@
 #include <stddef.h>
 #include <string.h>
 
+#include <stackinfo.h>
+
 /* Execute FILE, searching in the `PATH' environment variable if
    it contains no slashes, with all arguments after FILE until a
    NULL pointer and environment from `environ'.  */
@@ -43,16 +45,21 @@ execlp (const char *file, const char *arg, ...)
 	{
 	  const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
 
+#ifndef _STACK_GROWS_UP
 	  if ((char *) nptr + argv_max == (char *) argv)
 	    {
 	      /* Stack grows down.  */
 	      argv = (const char **) memcpy (nptr, argv, i);
 	      argv_max += i;
 	    }
-	  else if ((char *) argv + i == (char *) nptr)
+	  else
+#endif
+#ifndef _STACK_GROWS_DOWN
+	    if ((char *) argv + i == (char *) nptr)
 	    /* Stack grows up.  */
 	    argv_max += i;
 	  else
+#endif
 	    /* We have a hole in the stack.  */
 	    argv = (const char **) memcpy (nptr, argv, i);
 	}
diff --git a/posix/execvp.c b/posix/execvp.c
index 7afb01d11f..3f93357af8 100644
--- a/posix/execvp.c
+++ b/posix/execvp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 95, 96, 97, 98, 99 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
@@ -24,37 +24,31 @@
 #include <paths.h>
 
 
+/* The file is accessible but it is not an executable file.  Invoke
+   the shell to interpret it as a script.  */
 static void
 internal_function
-execute (const char *file, char *const argv[])
+script_execute (const char *file, char *const argv[])
 {
-  execv (file, argv);
-
-  if (errno == ENOEXEC)
-    {
-      /* The file is accessible but it is not an executable file.
-	 Invoke the shell to interpret it as a script.  */
-
-      /* Count the arguments.  */
-      int argc = 0;
-      while (argv[argc++])
-	;
-
-      /* Construct an argument list for the shell.  */
+  /* Count the arguments.  */
+  int argc = 0;
+  while (argv[argc++])
+    ;
+
+  /* Construct an argument list for the shell.  */
+  {
+    char *new_argv[argc + 1];
+    new_argv[0] = (char *) _PATH_BSHELL;
+    new_argv[1] = (char *) file;
+    while (argc > 1)
       {
-	char *new_argv[argc + 1];
-	new_argv[0] = (char *) _PATH_BSHELL;
-	new_argv[1] = (char *) file;
-	while (argc > 1)
-	  {
-	    new_argv[argc] = argv[argc - 1];
-	    --argc;
-	  }
-
-	/* Execute the shell.  */
-	execv (new_argv[0], new_argv);
+	new_argv[argc] = argv[argc - 1];
+	--argc;
       }
-    }
+
+    /* Execute the shell.  */
+    execv (new_argv[0], new_argv);
+  }
 }
 
 
@@ -65,8 +59,6 @@ execvp (file, argv)
      const char *file;
      char *const argv[];
 {
-  int got_eacces = 0;
-
   if (*file == '\0')
     {
       /* We check the simple case first. */
@@ -75,10 +67,16 @@ execvp (file, argv)
     }
 
   if (strchr (file, '/') != NULL)
-    /* Don't search when it contains a slash.  */
-    execute (file, argv);
+    {
+      /* Don't search when it contains a slash.  */
+      execv (file, argv);
+
+      if (errno == ENOEXEC)
+	script_execute (file, argv);
+    }
   else
     {
+      int got_eacces = 0;
       char *path, *p, *name;
       size_t len;
 
@@ -100,9 +98,7 @@ execvp (file, argv)
       do
 	{
 	  path = p;
-	  p = strchr (path, ':');
-	  if (p == NULL)
-	    p = strchr (path, '\0');
+	  p = __strchrnul (path, ':');
 
 	  if (p == path)
 	    /* Two adjacent colons, or a colon at the beginning or the end
@@ -113,11 +109,14 @@ execvp (file, argv)
 	      /* Construct the pathname to try.  */
 	      char *tmp = __mempcpy (name, path, p - path);
 	      *tmp++ = '/';
-	      (void) __mempcpy (tmp, file, len);
+	      memcpy (tmp, file, len);
 	    }
 
 	  /* Try to execute this name.  If it works, execv will not return.  */
-	  execute (name, argv);
+	  execv (name, argv);
+
+	  if (errno == ENOEXEC)
+	    script_execute (name, argv);
 
 	  switch (errno)
 	    {
@@ -142,13 +141,13 @@ execvp (file, argv)
 	    }
 	}
       while (*p++ != '\0');
-    }
-
-  /* We tried every element and none of them worked.  */
 
-  if (got_eacces)
-    /* At least one failure was due to permissions, so report that error.  */
-    __set_errno (EACCES);
+      /* We tried every element and none of them worked.  */
+      if (got_eacces)
+	/* At least one failure was due to permissions, so report that
+           error.  */
+	__set_errno (EACCES);
+    }
 
   /* Return the error from the last attempt (probably ENOENT).  */
   return -1;
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index eb3f1cc2d4..9617d336f4 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -211,8 +211,7 @@ internal_fnmatch (const char *pattern, const char *string,
 	    {
 	      const char *endp;
 
-	      if (!(flags & FNM_FILE_NAME) || (endp = strchr (n, '/')) == NULL)
-		endp = strchr (n, '\0');
+	      endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
 
 	      if (c == '[')
 		{
diff --git a/posix/getopt.c b/posix/getopt.c
index 81cef23f9b..efd822358f 100644
--- a/posix/getopt.c
+++ b/posix/getopt.c
@@ -3,7 +3,7 @@
    "Keep this file name-space clean" means, talk to drepper@gnu.org
    before changing it!
 
-   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
    	Free Software Foundation, Inc.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -109,7 +109,7 @@
    Also, when `ordering' is RETURN_IN_ORDER,
    each non-option ARGV-element is returned here.  */
 
-char *optarg = NULL;
+char *optarg;
 
 /* Index in ARGV of the next element to be scanned.
    This is used for communication to and from the caller
@@ -130,7 +130,7 @@ int optind = 1;
    causes problems with re-calling getopt as programs generally don't
    know that. */
 
-int __getopt_initialized = 0;
+int __getopt_initialized;
 
 /* The next char to be scanned in the option-element
    in which the last option character we returned was found.
diff --git a/posix/regex.c b/posix/regex.c
index 74fcf9c45e..5cbc046c70 100644
--- a/posix/regex.c
+++ b/posix/regex.c
@@ -179,7 +179,7 @@ static void
 init_syntax_once ()
 {
    register int c;
-   static int done = 0;
+   static int done;
 
    if (done)
      return;
@@ -615,7 +615,7 @@ extract_number_and_incr (destination, source)
 /* It is useful to test things that ``must'' be true when debugging.  */
 # include <assert.h>
 
-static int debug = 0;
+static int debug;
 
 # define DEBUG_STATEMENT(e) e
 # define DEBUG_PRINT1(x) if (debug) printf (x)
@@ -1013,26 +1013,80 @@ 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[] =
   {
-    gettext_noop ("Success"),	/* REG_NOERROR */
-    gettext_noop ("No match"),	/* REG_NOMATCH */
-    gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
+#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 */
-    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 */
+    "\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 ("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
+  };
 
 /* Avoiding alloca during matching, to placate r_alloc.  */
 
@@ -3848,7 +3902,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
   fail_stack_type fail_stack;
 #endif
 #ifdef DEBUG
-  static unsigned failure_id = 0;
+  static unsigned failure_id;
   unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
 #endif
 
@@ -5489,7 +5543,7 @@ re_compile_pattern (pattern, length, bufp)
 
   if (!ret)
     return NULL;
-  return gettext (re_error_msgid[(int) ret]);
+  return gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
 }
 #ifdef _LIBC
 weak_alias (__re_compile_pattern, re_compile_pattern)
@@ -5526,12 +5580,14 @@ re_comp (s)
     {
       re_comp_buf.buffer = (unsigned char *) malloc (200);
       if (re_comp_buf.buffer == NULL)
-        return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
+        return (char *) gettext (re_error_msgid
+				 + re_error_msgid_idx[(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[(int) REG_ESPACE]);
+	return (char *) gettext (re_error_msgid
+				 + re_error_msgid_idx[(int) REG_ESPACE]);
     }
 
   /* Since `re_exec' always passes NULL for the `regs' argument, we
@@ -5546,7 +5602,7 @@ re_comp (s)
     return NULL;
 
   /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
-  return (char *) gettext (re_error_msgid[(int) ret]);
+  return (char *) gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
 }
 
 
@@ -5772,15 +5828,15 @@ regerror (errcode, preg, errbuf, errbuf_size)
   size_t msg_size;
 
   if (errcode < 0
-      || errcode >= (int) (sizeof (re_error_msgid)
-			   / sizeof (re_error_msgid[0])))
+      || errcode >= (int) (sizeof (re_error_msgid_idx)
+			   / sizeof (re_error_msgid_idx[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[errcode]);
+  msg = gettext (re_error_msgid + re_error_msgid_idx[errcode]);
 
   msg_size = strlen (msg) + 1; /* Includes the null.  */