This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

gzipped charmap installation



The total size of the charmaps has grown from 3 MB to 11 MB in glibc-2.2.
Here are the total sizes of /usr/share/i18n/charmaps:

   glibc-2.1.3               3336 KB
   glibc-2.1.94             11696 KB

Since the charmaps are only ever used by "localedef" and "locale -m", i.e.
very rarely, here is a patch to install them in gzipped format. (Same as
what is done with man pages, info pages, X11 PCF fonts, etc.) The total
size then decreases to

   glibc-2.1.94 with gzip    2352 KB
   glibc-2.1.94 with bzip2   1812 KB

"localedef" continues to accept the same arguments as before, "locale -m"
produces the same output as before. But they are modified to look first
for an uncompressed charmap, then for a gzipped charmap, then (for the
sake of distributions, like Mandrake, which generally prefer bzip2 to
gzip) for a bzipped charmap. When reading the charmap, the decompressor
is called in a subprocess.

In order to avoid code duplication between locale.c and charmap.c, the
patch abstract the charmap directory handling routines into an extra file,
used by both "locale" and "localedef".

The patch furthermore
  - adds an include file include/spawn.h so I can use <spawn.h> inside
    glibc,
  - uses xstrdup instead of strdup in locale.c, for reliability,
  - makes the _DIRENT_HAVE_D_TYPE code consistent with the default code
    (The default code calls 'stat', not 'lstat', therefore the
    _DIRENT_HAVE_D_TYPE code should not treat symbolic links pointing
    to regular files as invalid.)
  - removes the obsolete repertoiremaps variables and installation rules
    from localedata/Makefile.


2000-09-30  Bruno Haible  <haible@clisp.cons.org>

	* locale/programs/charmap-dir.h: New file.
	* locale/programs/charmap-dir.c: New file.
	* locale/programs/linereader.h (lr_create): New declaration.
	* locale/programs/linereader.c (lr_create): New function, split out
	from lr_open.
	(lr_open): Tailcall lr_create.
	* locale/programs/locale.c: Include "charmap-dir.h". Don't include
	<unistd.h>.
	(xstrdup): New declaration.
	(more_help): Use xstrdup instead of strdup.
	(write_locales): Likewise. When encountering a symbolic link, call
	stat.
	(write_charmaps): Simplify using the charmap-dir.h functions.
	Use xstrdup instead of strdup.
	* locale/programs/charmap.c: Include "charmap-dir.h". Don't include
	<dirent.h> and <unistd.h>.
	(cmlr_open): New function.
	(charmap_read): Use cmlr_open instead of lr_open. Simplify using the
	charmap-dir.h functions.
	* locale/Makefile (distribute): Add charmap-dir.h.
	(lib-modules): Add charmap-dir.
	(CFLAGS-charmap-dir.c): Set to -Wno-write-strings, because posix_spawn
	wants a 'char **', not a 'const char **'.
	* include/spawn.h: New file.

2000-09-30  Bruno Haible  <haible@clisp.cons.org>

	* Makefile (repertoiremaps): Remove variable.
	(distribute): Remove repertoiremaps.
	(install-others): Likewise. Add .gz to charmaps.
	($(inst_i18ndir)/charmaps/%): Install in gzipped format.

*** glibc-20000928/locale/programs/charmap-dir.h.bak	Fri Sep 29 11:02:56 2000
--- glibc-20000928/locale/programs/charmap-dir.h	Sat Sep 30 20:47:50 2000
***************
*** 0 ****
--- 1,48 ----
+ /* Copyright (C) 2000 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
+    modify it under the terms of the GNU Library General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+ 
+    You should have received a copy of the GNU Library General Public
+    License along with the GNU C Library; see the file COPYING.LIB.  If not,
+    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #ifndef _CHARMAP_DIR_H
+ #define _CHARMAP_DIR_H 1
+ 
+ /* The data type of a charmap directory being traversed.  */
+ typedef struct charmap_dir CHARMAP_DIR;
+ 
+ /* Starts a charmap directory traversal.
+    Returns a CHARMAP_DIR, or NULL if the directory doesn't exist.  */
+ extern CHARMAP_DIR *charmap_opendir (const char *directory);
+ 
+ /* Reads the next directory entry.
+    Returns its charmap name, or NULL if past the last entry or upon error.
+    The storage returned may be overwritten by a later charmap_readdir
+    call on the same CHARMAP_DIR.  */
+ extern const char *charmap_readdir (CHARMAP_DIR *dir);
+ 
+ /* Finishes a charmap directory traversal, and frees the resources
+    attached to the CHARMAP_DIR.  */
+ extern int charmap_closedir (CHARMAP_DIR *dir);
+ 
+ /* Returns a NULL terminated list of alias names of a charmap.  */
+ extern char **charmap_aliases (const char *directory, const char *name);
+ 
+ /* Frees an alias list returned by charmap_aliases.  */
+ extern void charmap_free_aliases (char **aliases);
+ 
+ /* Opens a charmap for reading, given its name (not an alias name).  */
+ extern FILE *charmap_open (const char *directory, const char *name);
+ 
+ #endif /* _CHARMAP_DIR_H */
*** glibc-20000928/locale/programs/charmap-dir.c.bak	Fri Sep 29 11:02:59 2000
--- glibc-20000928/locale/programs/charmap-dir.c	Sat Sep 30 22:15:50 2000
***************
*** 0 ****
--- 1,312 ----
+ /* Copyright (C) 2000 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
+    modify it under the terms of the GNU Library General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+ 
+    You should have received a copy of the GNU Library General Public
+    License along with the GNU C Library; see the file COPYING.LIB.  If not,
+    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include <dirent.h>
+ #include <errno.h>
+ #include <error.h>
+ #include <fcntl.h>
+ #include <libintl.h>
+ #include <spawn.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/stat.h>
+ 
+ #include "charmap-dir.h"
+ 
+ extern void *xmalloc (size_t n);
+ extern void *xrealloc (void *p, size_t n);
+ 
+ /* The data type of a charmap directory being traversed.  */
+ struct charmap_dir
+ {
+   DIR *dir;
+   /* The directory pathname, ending in a slash.  */
+   char *directory;
+   size_t directory_len;
+   /* Scratch area used for returning pathnames.  */
+   char *pathname;
+   size_t pathname_size;
+ };
+ 
+ /* Starts a charmap directory traversal.
+    Returns a CHARMAP_DIR, or NULL if the directory doesn't exist.  */
+ CHARMAP_DIR *
+ charmap_opendir (const char *directory)
+ {
+   struct charmap_dir *cdir;
+   DIR *dir;
+   size_t len;
+   int add_slash;
+ 
+   dir = opendir (directory);
+   if (dir == NULL)
+     {
+       error (1, errno, gettext ("cannot read character map directory `%s'"),
+              directory);
+       return NULL;
+     }
+ 
+   cdir = (struct charmap_dir *) xmalloc (sizeof (struct charmap_dir));
+   cdir->dir = dir;
+ 
+   len = strlen (directory);
+   add_slash = (len == 0 || directory[len - 1] != '/');
+   cdir->directory = (char *) xmalloc (len + add_slash + 1);
+   memcpy (cdir->directory, directory, len);
+   if (add_slash)
+     cdir->directory[len] = '/';
+   cdir->directory[len + add_slash] = '\0';
+   cdir->directory_len = len + add_slash;
+ 
+   cdir->pathname = NULL;
+   cdir->pathname_size = 0;
+ 
+   return cdir;
+ }
+ 
+ /* Reads the next directory entry.
+    Returns its charmap name, or NULL if past the last entry or upon error.
+    The storage returned may be overwritten by a later charmap_readdir
+    call on the same CHARMAP_DIR.  */
+ const char *
+ charmap_readdir (CHARMAP_DIR *cdir)
+ {
+   for (;;)
+     {
+       struct dirent *dirent;
+       size_t len;
+       size_t size;
+       char *filename;
+       mode_t mode;
+ 
+       dirent = readdir (cdir->dir);
+       if (dirent == NULL)
+         return NULL;
+       if (strcmp (dirent->d_name, ".") == 0)
+         continue;
+       if (strcmp (dirent->d_name, "..") == 0)
+         continue;
+ 
+       len = strlen (dirent->d_name);
+ 
+       size = cdir->directory_len + len + 1;
+       if (size > cdir->pathname_size)
+         {
+           free (cdir->pathname);
+           if (size < 2 * cdir->pathname_size)
+             size = 2 * cdir->pathname_size;
+           cdir->pathname = (char *) xmalloc (size);
+           cdir->pathname_size = size;
+         }
+ 
+       stpcpy (stpcpy (cdir->pathname, cdir->directory), dirent->d_name);
+       filename = cdir->pathname + cdir->directory_len;
+ 
+ #ifdef _DIRENT_HAVE_D_TYPE
+       if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_LNK)
+         mode = DTTOIF (dirent->d_type);
+       else
+ #endif
+         {
+           struct stat statbuf;
+ 
+           if (stat (cdir->pathname, &statbuf) < 0)
+             continue;
+ 
+           mode = statbuf.st_mode;
+         }
+ 
+       if (!S_ISREG (mode))
+         continue;
+ 
+       /* For compressed charmaps, the canonical charmap name does not
+          include the extension.  */
+       if (len > 3 && memcmp (&filename[len - 3], ".gz", 3) == 0)
+         filename[len - 3] = '\0';
+       else if (len > 4 && memcmp (&filename[len - 4], ".bz2", 4) == 0)
+         filename[len - 4] = '\0';
+ 
+       return filename;
+     }
+ }
+ 
+ /* Finishes a charmap directory traversal, and frees the resources
+    attached to the CHARMAP_DIR.  */
+ int
+ charmap_closedir (CHARMAP_DIR *cdir)
+ {
+   DIR *dir = cdir->dir;
+ 
+   free (cdir->directory);
+   free (cdir->pathname);
+   free (cdir);
+   return closedir (dir);
+ }
+ 
+ /* Creates a subprocess decompressing the given pathname, and returns
+    a stream reading its output (the decompressed data).  */
+ static
+ FILE *
+ fopen_uncompressed (const char *pathname, char *compressor)
+ {
+   int pfd;
+ 
+   pfd = open (pathname, O_RDONLY);
+   if (pfd >= 0)
+     {
+       struct stat statbuf;
+       int fd[2];
+ 
+       if (fstat (pfd, &statbuf) >= 0
+           && S_ISREG (statbuf.st_mode)
+           && pipe (fd) >= 0)
+         {
+           char *argv[4] = { compressor, "-d", "-c", NULL };
+           posix_spawn_file_actions_t actions;
+ 
+           if (posix_spawn_file_actions_init (&actions) == 0)
+             {
+               if (posix_spawn_file_actions_adddup2 (&actions,
+                                                     fd[1], STDOUT_FILENO) == 0
+                   && posix_spawn_file_actions_addclose (&actions, fd[1]) == 0
+                   && posix_spawn_file_actions_addclose (&actions, fd[0]) == 0
+                   && posix_spawn_file_actions_adddup2 (&actions,
+                                                        pfd, STDIN_FILENO) == 0
+                   && posix_spawn_file_actions_addclose (&actions, pfd) == 0
+                   && posix_spawnp (NULL, compressor, &actions, NULL,
+                                    argv, environ) == 0)
+                 {
+                   posix_spawn_file_actions_destroy (&actions);
+                   close (fd[1]);
+                   close (pfd);
+                   return fdopen (fd[0], "r");
+                 }
+               posix_spawn_file_actions_destroy (&actions);
+             }
+           close (fd[1]);
+           close (fd[0]);
+         }
+       close (pfd);
+     }
+   return NULL;
+ }
+ 
+ /* Opens a charmap for reading, given its name (not an alias name).  */
+ FILE *
+ charmap_open (const char *directory, const char *name)
+ {
+   size_t dlen = strlen (directory);
+   int add_slash = (dlen == 0 || directory[dlen - 1] != '/');
+   size_t nlen = strlen (name);
+   char *pathname;
+   char *p;
+   FILE *stream;
+ 
+   pathname = alloca (dlen + add_slash + nlen + 5);
+   p = stpcpy (pathname, directory);
+   if (add_slash)
+     *p++ = '/';
+   p = stpcpy (p, name);
+ 
+   stream = fopen (pathname, "r");
+   if (stream != NULL)
+     return stream;
+ 
+   memcpy (p, ".gz", 4);
+   stream = fopen_uncompressed (pathname, "gzip");
+   if (stream != NULL)
+     return stream;
+ 
+   memcpy (p, ".bz2", 5);
+   stream = fopen_uncompressed (pathname, "bzip2");
+   if (stream != NULL)
+     return stream;
+ 
+   return NULL;
+ }
+ 
+ /* An empty alias list.  Avoids the need to return NULL from
+    charmap_aliases.  */
+ static char *empty[1];
+ 
+ /* Returns a NULL terminated list of alias names of a charmap.  */
+ char **
+ charmap_aliases (const char *directory, const char *name)
+ {
+   FILE *stream;
+   char **aliases;
+   size_t naliases;
+ 
+   stream = charmap_open (directory, name);
+   if (stream == NULL)
+     return empty;
+ 
+   aliases = NULL;
+   naliases = 0;
+ 
+   while (!feof (stream))
+     {
+       char *alias = NULL;
+       char junk[BUFSIZ];
+ 
+       if (fscanf (stream, " <code_set_name> %as", &alias) == 1
+           || fscanf (stream, "%% alias %as", &alias) == 1)
+         {
+           aliases = (char **) xrealloc (aliases,
+                                         (naliases + 2) * sizeof (char *));
+           aliases[naliases++] = alias;
+         }
+ 
+       /* Read the rest of the line.  */
+       if (fgets (junk, sizeof junk, stream) != NULL)
+         {
+           if (strstr (junk, "CHARMAP") != NULL)
+             /* We cannot expect more aliases from now on.  */
+             break;
+ 
+           while (strchr (junk, '\n') == NULL
+                  && fgets (junk, sizeof junk, stream) != NULL)
+             continue;
+         }
+     }
+ 
+   fclose (stream);
+ 
+   if (naliases == 0)
+     return empty;
+ 
+   aliases[naliases] = NULL;
+   return aliases;
+ }
+ 
+ /* Frees an alias list returned by charmap_aliases.  */
+ void
+ charmap_free_aliases (char **aliases)
+ {
+   if (aliases != empty)
+     {
+       char **p;
+ 
+       for (p = aliases; *p; p++)
+         free (*p);
+ 
+       free (aliases);
+     }
+ }
*** glibc-20000928/locale/programs/linereader.h.bak	Tue Sep  7 16:54:47 1999
--- glibc-20000928/locale/programs/linereader.h	Sat Sep 30 01:02:56 2000
***************
*** 1,4 ****
! /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Ulrich Drepper, <drepper@gnu.org>.
  
--- 1,4 ----
! /* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Ulrich Drepper, <drepper@gnu.org>.
  
***************
*** 85,90 ****
--- 85,91 ----
  
  /* Functions defined in linereader.c.  */
  extern struct linereader *lr_open (const char *fname, kw_hash_fct_t hf);
+ extern struct linereader *lr_create (FILE *fp, const char *fname, kw_hash_fct_t hf);
  extern int lr_eof (struct linereader *lr);
  extern void lr_close (struct linereader *lr);
  extern int lr_next (struct linereader *lr);
*** glibc-20000928/locale/programs/linereader.c.bak	Tue Aug 15 11:06:58 2000
--- glibc-20000928/locale/programs/linereader.c	Sat Sep 30 01:02:03 2000
***************
*** 47,69 ****
  lr_open (const char *fname, kw_hash_fct_t hf)
  {
    FILE *fp;
-   struct linereader *result;
-   int n;
  
    if (fname == NULL || strcmp (fname, "-") == 0
        || strcmp (fname, "/dev/stdin") == 0)
!     fp = stdin;
    else
      {
        fp = fopen (fname, "r");
        if (fp == NULL)
  	return NULL;
      }
  
    result = (struct linereader *) xmalloc (sizeof (*result));
  
    result->fp = fp;
!   result->fname = xstrdup (fname ? : "<stdin>");
    result->buf = NULL;
    result->bufsize = 0;
    result->lineno = 1;
--- 47,75 ----
  lr_open (const char *fname, kw_hash_fct_t hf)
  {
    FILE *fp;
  
    if (fname == NULL || strcmp (fname, "-") == 0
        || strcmp (fname, "/dev/stdin") == 0)
!     return lr_create (stdin, "<stdin>", hf);
    else
      {
        fp = fopen (fname, "r");
        if (fp == NULL)
  	return NULL;
+       return lr_create (fp, fname, hf);
      }
+ }
+ 
+ struct linereader *
+ lr_create (FILE *fp, const char *fname, kw_hash_fct_t hf)
+ {
+   struct linereader *result;
+   int n;
  
    result = (struct linereader *) xmalloc (sizeof (*result));
  
    result->fp = fp;
!   result->fname = xstrdup (fname);
    result->buf = NULL;
    result->bufsize = 0;
    result->lineno = 1;
*** glibc-20000928/locale/programs/locale.c.bak	Wed Jul 12 18:11:43 2000
--- glibc-20000928/locale/programs/locale.c	Sat Sep 30 21:45:44 2000
***************
*** 35,44 ****
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
- #include <unistd.h>
  #include <sys/stat.h>
  
  #include "localeinfo.h"
  
  
  /* If set print the name of the category.  */
--- 35,46 ----
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/stat.h>
  
  #include "localeinfo.h"
+ #include "charmap-dir.h"
+ 
+ extern char *xstrdup (const char *__str);
  
  
  /* If set print the name of the category.  */
***************
*** 251,257 ****
      {
      case ARGP_KEY_HELP_EXTRA:
        /* We print some extra information.  */
!       return strdup (gettext ("\
  Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"));
      default:
        break;
--- 253,259 ----
      {
      case ARGP_KEY_HELP_EXTRA:
        /* We print some extra information.  */
!       return xstrdup (gettext ("\
  Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"));
      default:
        break;
***************
*** 320,326 ****
        {
  	mode_t mode;
  #ifdef _DIRENT_HAVE_D_TYPE
! 	if (dirent->d_type != DT_UNKNOWN)
  	  mode = DTTOIF (dirent->d_type);
  	else
  #endif
--- 322,328 ----
        {
  	mode_t mode;
  #ifdef _DIRENT_HAVE_D_TYPE
! 	if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_LNK)
  	  mode = DTTOIF (dirent->d_type);
  	else
  #endif
***************
*** 348,354 ****
  		    "/LC_CTYPE");
  
  	    if (stat (buf, &st) == 0 && S_ISREG (st.st_mode))
! 	      PUT (strdup (dirent->d_name));
  	  }
        }
  
--- 350,356 ----
  		    "/LC_CTYPE");
  
  	    if (stat (buf, &st) == 0 && S_ISREG (st.st_mode))
! 	      PUT (xstrdup (dirent->d_name));
  	  }
        }
  
***************
*** 425,431 ****
  		    *cp++ = '\0';
  
  		  /* Add the alias.  */
! 		  PUT (strdup (alias));
  		}
  	    }
  
--- 427,433 ----
  		    *cp++ = '\0';
  
  		  /* Add the alias.  */
! 		  PUT (xstrdup (alias));
  		}
  	    }
  
***************
*** 453,536 ****
  write_charmaps (void)
  {
    void *all_data = NULL;
!   DIR *dir;
!   struct dirent *dirent;
  
!   dir = opendir (CHARMAP_PATH);
    if (dir == NULL)
!     {
!       error (1, errno, gettext ("cannot read character map directory `%s'"),
! 	     CHARMAP_PATH);
!       return;
!     }
! 
!   /* Now we can look for all files in the directory.  */
!   while ((dirent = readdir (dir)) != NULL)
!     if (strcmp (dirent->d_name, ".") != 0
! 	&& strcmp (dirent->d_name, "..") != 0)
!       {
! 	char *buf = NULL;
! 	mode_t mode;
! 
! #ifdef _DIRENT_HAVE_D_TYPE
! 	if (dirent->d_type != DT_UNKNOWN)
! 	  mode = DTTOIF (dirent->d_type);
! 	else
! #endif
! 	  {
! 	    struct stat st;
  
! 	    buf = alloca (sizeof (CHARMAP_PATH) + strlen (dirent->d_name) + 1);
! 
! 	    stpcpy (stpcpy (stpcpy (buf, CHARMAP_PATH), "/"), dirent->d_name);
  
! 	    if (stat (buf, &st) < 0)
! 	      continue;
! 	    mode = st.st_mode;
! 	  }
  
! 	if (S_ISREG (mode))
! 	  {
! 	    FILE *fp;
  
! 	    PUT (strdup (dirent->d_name));
  
! 	    /* Read the file and learn about the code set name.  */
! 	    if (buf == NULL)
! 	      {
! 		buf = alloca (sizeof (CHARMAP_PATH)
! 			      + strlen (dirent->d_name) + 1);
! 
! 		stpcpy (stpcpy (stpcpy (buf, CHARMAP_PATH), "/"),
! 			dirent->d_name);
! 	      }
! 
! 	    fp = fopen (buf, "r");
! 	    if (fp != NULL)
! 	      {
! 		char *name = NULL;
! 
! 		while (!feof (fp))
! 		  {
! 		    char junk[BUFSIZ];
! 
! 		    if (fscanf (fp, " <code_set_name> %as", &name) == 1)
! 		      break;
! 
! 		    while (fgets (junk, sizeof junk, fp) != NULL
! 			   && strchr (junk, '\n') == NULL)
! 		      continue;
! 		  }
! 
! 		fclose (fp);
! 
! 		if (name != NULL)
! 		  PUT (name);
! 	      }
! 	  }
!       }
  
!   closedir (dir);
  
    twalk (all_data, print_names);
  }
--- 455,492 ----
  write_charmaps (void)
  {
    void *all_data = NULL;
!   CHARMAP_DIR *dir;
!   const char *dirent;
  
!   /* Look for all files in the charmap directory.  */
!   dir = charmap_opendir (CHARMAP_PATH);
    if (dir == NULL)
!     return;
  
!   while ((dirent = charmap_readdir (dir)) != NULL)
!     {
!       char **aliases;
!       char **p;
  
!       PUT (xstrdup (dirent));
  
!       aliases = charmap_aliases (CHARMAP_PATH, dirent);
  
! #if 0
!       /* Add the code_set_name and the aliases.  */
!       for (p = aliases; *p; p++)
! 	PUT (xstrdup (*p));
! #else
!       /* Add the code_set_name only.  Most aliases are obsolete.  */
!       p = aliases;
!       if (*p)
! 	PUT (xstrdup (*p));
! #endif
  
!       charmap_free_aliases (aliases);
!     }
  
!   charmap_closedir (dir);
  
    twalk (all_data, print_names);
  }
*** glibc-20000928/locale/programs/charmap.c.bak	Sat Sep 30 00:52:16 2000
--- glibc-20000928/locale/programs/charmap.c	Sat Sep 30 22:05:22 2000
***************
*** 22,39 ****
  #endif
  
  #include <ctype.h>
- #include <dirent.h>
  #include <errno.h>
  #include <libintl.h>
  #include <limits.h>
  #include <obstack.h>
  #include <stdlib.h>
  #include <string.h>
- #include <unistd.h>
  
  #include "error.h"
  #include "linereader.h"
  #include "charmap.h"
  #include "locfile.h"
  #include "repertoire.h"
  
--- 22,38 ----
  #endif
  
  #include <ctype.h>
  #include <errno.h>
  #include <libintl.h>
  #include <limits.h>
  #include <obstack.h>
  #include <stdlib.h>
  #include <string.h>
  
  #include "error.h"
  #include "linereader.h"
  #include "charmap.h"
+ #include "charmap-dir.h"
  #include "locfile.h"
  #include "repertoire.h"
  
***************
*** 55,60 ****
--- 54,84 ----
  			      int nbytes, char *bytes, const char *from,
  			      const char *to, int decimal_ellipsis, int step);
  
+ static struct linereader *
+ cmlr_open (const char *directory, const char *name, kw_hash_fct_t hf)
+ {
+   FILE *fp;
+ 
+   fp = charmap_open (directory, name);
+   if (fp == NULL)
+     return NULL;
+   else
+     {
+       size_t dlen = strlen (directory);
+       int add_slash = (dlen == 0 || directory[dlen - 1] != '/');
+       size_t nlen = strlen (name);
+       char *pathname;
+       char *p;
+ 
+       pathname = alloca (dlen + add_slash + nlen + 1);
+       p = stpcpy (pathname, directory);
+       if (add_slash)
+ 	*p++ = '/';
+       stpcpy (p, name);
+ 
+       return lr_create (fp, pathname, hf);
+     }
+ }
  
  struct charmap_t *
  charmap_read (const char *filename)
***************
*** 76,101 ****
  	      char *i18npath = getenv ("I18NPATH");
  	      if (i18npath != NULL && *i18npath != '\0')
  		{
! 		  char path[strlen (filename) + 1 + strlen (i18npath)
! 			   + sizeof ("/charmaps/") - 1];
  		  char *next;
  		  i18npath = strdupa (i18npath);
  
- 
  		  while (cmfile == NULL
  			 && (next = strsep (&i18npath, ":")) != NULL)
  		    {
! 		      stpcpy (stpcpy (stpcpy (path, next), "/charmaps/"),
! 			      filename);
! 
! 		      cmfile = lr_open (path, charmap_hash);
  
  		      if (cmfile == NULL)
  			{
  			  /* Try without the "/charmaps" part.  */
! 			  stpcpy (stpcpy (path, next), filename);
! 
! 			  cmfile = lr_open (path, charmap_hash);
  			}
  		    }
  		}
--- 100,119 ----
  	      char *i18npath = getenv ("I18NPATH");
  	      if (i18npath != NULL && *i18npath != '\0')
  		{
! 		  char path[strlen (i18npath) + sizeof ("/charmaps")];
  		  char *next;
  		  i18npath = strdupa (i18npath);
  
  		  while (cmfile == NULL
  			 && (next = strsep (&i18npath, ":")) != NULL)
  		    {
! 		      stpcpy (stpcpy (path, next), "/charmaps");
! 		      cmfile = cmlr_open (path, filename, charmap_hash);
  
  		      if (cmfile == NULL)
  			{
  			  /* Try without the "/charmaps" part.  */
! 			  cmfile = cmlr_open (next, filename, charmap_hash);
  			}
  		    }
  		}
***************
*** 103,112 ****
  	      if (cmfile == NULL)
  		{
  		  /* Try the default directory.  */
! 		  char path[sizeof (CHARMAP_PATH) + strlen (filename) + 1];
! 
! 		  stpcpy (stpcpy (stpcpy (path, CHARMAP_PATH), "/"), filename);
! 		  cmfile = lr_open (path, charmap_hash);
  		}
  	    }
  	}
--- 121,127 ----
  	      if (cmfile == NULL)
  		{
  		  /* Try the default directory.  */
! 		  cmfile = cmlr_open (CHARMAP_PATH, filename, charmap_hash);
  		}
  	    }
  	}
***************
*** 125,197 ****
        /* OK, one more try.  We also accept the names given to the
  	 character sets in the files.  Sometimes they differ from the
  	 file name.  */
!       DIR *dir;
!       struct dirent *dirent;
  
!       dir = opendir (CHARMAP_PATH);
        if (dir != NULL)
  	{
! 	  while ((dirent = readdir (dir)) != NULL)
! 	    if (strcmp (dirent->d_name, ".") != 0
! 		&& strcmp (dirent->d_name, "..") != 0)
! 	      {
! 		char buf[sizeof (CHARMAP_PATH)
! 			+ strlen (dirent->d_name) + 1];
! 		FILE *fp;
! #ifdef _DIRENT_HAVE_D_TYPE
! 		if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_REG)
! 		  continue;
! #endif
! 		stpcpy (stpcpy (stpcpy (buf, CHARMAP_PATH), "/"),
! 			dirent->d_name);
  
! 		fp = fopen (buf, "r");
! 		if (fp != NULL)
  		  {
! 		    char *name = NULL;
  
! 		    while (!feof (fp))
! 		      {
! 			char junk[BUFSIZ];
! 
! 			if (fscanf (fp, " <code_set_name> %as", &name) == 1
! 			    || fscanf (fp, "%% alias %as", &name) == 1)
! 			  {
! 			    if (strcasecmp (name, filename) == 0)
! 			      break;
! 
! 			    free (name);
! 			    name = NULL;
! 			  }
! 
! 			if (fgets (junk, sizeof junk, fp) != NULL)
! 			  {
! 			    if (strstr (junk, "CHARMAP") != NULL)
! 			      /* We cannot expect more aliases from now on.  */
! 			      break;
! 
! 			    while (strchr (junk, '\n') == NULL
! 				   && fgets (junk, sizeof junk, fp) != NULL)
! 			      continue;
! 			  }
! 		      }
! 
! 		    fclose (fp);
! 
! 		    if (name != NULL)
! 		      {
! 			struct linereader *cmfile;
! 
! 			cmfile = lr_open (buf, charmap_hash);
! 			result = (cmfile == NULL
! 				  ? NULL : parse_charmap (cmfile));
  
! 			break;
! 		      }
! 		  }
! 	      }
  
! 	  closedir (dir);
  	}
      }
  
--- 140,181 ----
        /* OK, one more try.  We also accept the names given to the
  	 character sets in the files.  Sometimes they differ from the
  	 file name.  */
!       CHARMAP_DIR *dir;
  
!       dir = charmap_opendir (CHARMAP_PATH);
        if (dir != NULL)
  	{
! 	  const char *dirent;
  
! 	  while ((dirent = charmap_readdir (dir)) != NULL)
! 	    {
! 	      char **aliases;
! 	      char **p;
! 	      int found;
! 
! 	      aliases = charmap_aliases (CHARMAP_PATH, dirent);
! 	      found = 0;
! 	      for (p = aliases; *p; p++)
! 		if (strcasecmp (*p, filename) == 0)
  		  {
! 		    found = 1;
! 		    break;
! 		  }
! 	      charmap_free_aliases (aliases);
  
! 	      if (found)
! 		{
! 		  struct linereader *cmfile;
  
! 		  cmfile = cmlr_open (CHARMAP_PATH, dirent, charmap_hash);
! 		  if (cmfile != NULL)
! 		    result = parse_charmap (cmfile);
  
! 		  break;
! 		}
! 	    }
! 
! 	  charmap_closedir (dir);
  	}
      }
  
***************
*** 199,207 ****
      {
        struct linereader *cmfile;
  
!       cmfile = lr_open (CHARMAP_PATH "/" DEFAULT_CHARMAP, charmap_hash);
! 
!       result = cmfile == NULL ? NULL : parse_charmap (cmfile);
  
        if (result == NULL)
  	error (4, errno, _("default character map file `%s' not found"),
--- 183,191 ----
      {
        struct linereader *cmfile;
  
!       cmfile = cmlr_open (CHARMAP_PATH, DEFAULT_CHARMAP, charmap_hash);
!       if (cmfile != NULL)
! 	result = parse_charmap (cmfile);
  
        if (result == NULL)
  	error (4, errno, _("default character map file `%s' not found"),
*** glibc-20000928/locale/Makefile.bak	Tue Sep 26 14:39:55 2000
--- glibc-20000928/locale/Makefile	Sat Sep 30 17:47:23 2000
***************
*** 33,39 ****
  			      charmap-kw.gperf charmap-kw.h locfile-token.h \
  			      locfile-kw.gperf locfile-kw.h linereader.h \
  			      locfile.h charmap.h repertoire.h localedef.h \
! 			      3level.h)
  routines	= setlocale findlocale loadlocale localeconv nl_langinfo \
  		  nl_langinfo_l mb_cur_max codeset_name \
  		  newlocale duplocale freelocale
--- 33,39 ----
  			      charmap-kw.gperf charmap-kw.h locfile-token.h \
  			      locfile-kw.gperf locfile-kw.h linereader.h \
  			      locfile.h charmap.h repertoire.h localedef.h \
! 			      3level.h charmap-dir.h)
  routines	= setlocale findlocale loadlocale localeconv nl_langinfo \
  		  nl_langinfo_l mb_cur_max codeset_name \
  		  newlocale duplocale freelocale
***************
*** 59,65 ****
  localedef-modules	:= $(categories:%=ld-%) charmap linereader locfile \
  			   repertoire
  locale-modules		:= locale-spec
! lib-modules		:= simple-hash xmalloc xstrdup
  
  
  GPERF = gperf
--- 59,65 ----
  localedef-modules	:= $(categories:%=ld-%) charmap linereader locfile \
  			   repertoire
  locale-modules		:= locale-spec
! lib-modules		:= charmap-dir simple-hash xmalloc xstrdup
  
  
  GPERF = gperf
***************
*** 94,99 ****
--- 94,100 ----
  
  CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts
  CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-charmap-dir.c = -Wno-write-strings
  
  # Depend on libc.so so a DT_NEEDED is generated in the shared objects.
  # This ensures they will load libc.so for needed symbols if loaded by
*** glibc-20000928/include/spawn.h.bak	Sat Sep 30 17:40:55 2000
--- glibc-20000928/include/spawn.h	Sat Sep 30 17:41:59 2000
***************
*** 0 ****
--- 1 ----
+ #include <posix/spawn.h>
*** glibc-20000928/localedata/Makefile.bak	Tue Sep 26 14:39:55 2000
--- glibc-20000928/localedata/Makefile	Sat Sep 30 22:47:38 2000
***************
*** 31,40 ****
  locales := $(filter-out $(addprefix locales/, CVS RCS SCCS %~), \
  				    $(wildcard locales/*))
  
- # List of repertoire maps.
- repertoiremaps := $(filter-out $(addprefix repertoiremaps/, CVS RCS SCCS %~), \
- 					   $(wildcard repertoiremaps/*))
- 
  
  subdir-dirs = tests-mbwc
  vpath %.c tests-mbwc
--- 31,36 ----
***************
*** 64,70 ****
  		  $(addprefix tstfmon_,$(fmon-tests))			\
  
  distribute := CHECKSUMS README SUPPORTED ChangeLog			\
! 	      $(charmaps) $(locales) $(repertoiremaps)			\
  	      tst-rpmatch.sh tst-locale.sh tst-fmon.sh sort-test.sh	\
  	      tst-fmon.data $(test-input-data) $(ld-test-srcs)		\
  	      th_TH.in cs_CZ.in tst-mbswcs.sh tst-trans.sh tst-ctype.sh \
--- 60,66 ----
  		  $(addprefix tstfmon_,$(fmon-tests))			\
  
  distribute := CHECKSUMS README SUPPORTED ChangeLog			\
! 	      $(charmaps) $(locales)					\
  	      tst-rpmatch.sh tst-locale.sh tst-fmon.sh sort-test.sh	\
  	      tst-fmon.data $(test-input-data) $(ld-test-srcs)		\
  	      th_TH.in cs_CZ.in tst-mbswcs.sh tst-trans.sh tst-ctype.sh \
***************
*** 98,112 ****
  endif
  
  # Files to install.
! install-others := $(addprefix $(inst_i18ndir)/, $(charmaps) $(locales) \
! 						$(repertoiremaps))
  
  include ../Rules
  
! # Install the source files in the appropriate directories.
! $(inst_i18ndir)/charmaps/%: charmaps/% $(+force); $(do-install)
  $(inst_i18ndir)/locales/%: locales/% $(+force); $(do-install)
- $(inst_i18ndir)/repertoiremaps/%: repertoiremaps/% $(+force); $(do-install)
  
  # gcc does not know all the format specifiers we are using here.
  CFLAGS-tst-mbswcs1.c = -Wno-format
--- 94,114 ----
  endif
  
  # Files to install.
! install-others := $(addprefix $(inst_i18ndir)/, \
! 			      $(addsuffix .gz, $(charmaps)) \
! 			      $(locales))
  
  include ../Rules
  
! # Install the charmap files in gzipped format.
! $(inst_i18ndir)/charmaps/%.gz: charmaps/% $(+force)
! 	$(make-target-directory)
! 	rm -f $(@:.gz=) $@
! 	$(INSTALL_DATA) $< $(@:.gz=)
! 	gzip -9 $(@:.gz=)
! 
! # Install the locale source files in the appropriate directory.
  $(inst_i18ndir)/locales/%: locales/% $(+force); $(do-install)
  
  # gcc does not know all the format specifiers we are using here.
  CFLAGS-tst-mbswcs1.c = -Wno-format

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]