mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 02:40:08 +00:00
Update.
2000-10-01 Bruno Haible <haible@clisp.cons.org> * charmaps/BIG5: Add a width table. * charmaps/GB18030: Likewise. * charmaps/ISO-8859-6: Likewise. * charmaps/ISO-8859-8: Likewise. * charmaps/TIS-620: Likewise.
This commit is contained in:
parent
d77cd295eb
commit
3e07621988
1
include/spawn.h
Normal file
1
include/spawn.h
Normal file
@ -0,0 +1 @@
|
||||
#include <posix/spawn.h>
|
@ -33,7 +33,7 @@ distribute = localeinfo.h categories.def iso-639.def iso-3166.def \
|
||||
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)
|
||||
3level.h charmap-dir.h)
|
||||
routines = setlocale findlocale loadlocale localeconv nl_langinfo \
|
||||
nl_langinfo_l mb_cur_max codeset_name \
|
||||
newlocale duplocale freelocale
|
||||
@ -59,7 +59,7 @@ vpath %.gperf programs
|
||||
localedef-modules := $(categories:%=ld-%) charmap linereader locfile \
|
||||
repertoire
|
||||
locale-modules := locale-spec
|
||||
lib-modules := simple-hash xmalloc xstrdup
|
||||
lib-modules := charmap-dir simple-hash xmalloc xstrdup
|
||||
|
||||
|
||||
GPERF = gperf
|
||||
@ -94,6 +94,7 @@ locale-CPPFLAGS := -DLOCALE_PATH='$(localepath)' \
|
||||
|
||||
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
|
||||
|
312
locale/programs/charmap-dir.c
Normal file
312
locale/programs/charmap-dir.c
Normal file
@ -0,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);
|
||||
}
|
||||
}
|
48
locale/programs/charmap-dir.h
Normal file
48
locale/programs/charmap-dir.h
Normal file
@ -0,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 */
|
@ -22,18 +22,17 @@
|
||||
#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 "charmap-dir.h"
|
||||
#include "locfile.h"
|
||||
#include "repertoire.h"
|
||||
|
||||
@ -55,6 +54,31 @@ static void charmap_new_char (struct linereader *lr, struct charmap_t *cm,
|
||||
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,26 +100,20 @@ charmap_read (const char *filename)
|
||||
char *i18npath = getenv ("I18NPATH");
|
||||
if (i18npath != NULL && *i18npath != '\0')
|
||||
{
|
||||
char path[strlen (filename) + 1 + strlen (i18npath)
|
||||
+ sizeof ("/charmaps/") - 1];
|
||||
char path[strlen (i18npath) + sizeof ("/charmaps")];
|
||||
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);
|
||||
stpcpy (stpcpy (path, next), "/charmaps");
|
||||
cmfile = cmlr_open (path, filename, charmap_hash);
|
||||
|
||||
if (cmfile == NULL)
|
||||
{
|
||||
/* Try without the "/charmaps" part. */
|
||||
stpcpy (stpcpy (path, next), filename);
|
||||
|
||||
cmfile = lr_open (path, charmap_hash);
|
||||
cmfile = cmlr_open (next, filename, charmap_hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,10 +121,7 @@ charmap_read (const char *filename)
|
||||
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);
|
||||
cmfile = cmlr_open (CHARMAP_PATH, filename, charmap_hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,73 +140,42 @@ charmap_read (const char *filename)
|
||||
/* 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;
|
||||
CHARMAP_DIR *dir;
|
||||
|
||||
dir = opendir (CHARMAP_PATH);
|
||||
dir = charmap_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);
|
||||
const char *dirent;
|
||||
|
||||
fp = fopen (buf, "r");
|
||||
if (fp != NULL)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
charmap_free_aliases (aliases);
|
||||
|
||||
closedir (dir);
|
||||
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,9 +183,9 @@ charmap_read (const char *filename)
|
||||
{
|
||||
struct linereader *cmfile;
|
||||
|
||||
cmfile = lr_open (CHARMAP_PATH "/" DEFAULT_CHARMAP, charmap_hash);
|
||||
|
||||
result = cmfile == NULL ? NULL : parse_charmap (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"),
|
||||
|
@ -47,23 +47,29 @@ struct linereader *
|
||||
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;
|
||||
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 ? : "<stdin>");
|
||||
result->fname = xstrdup (fname);
|
||||
result->buf = NULL;
|
||||
result->bufsize = 0;
|
||||
result->lineno = 1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
/* 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,6 +85,7 @@ struct linereader
|
||||
|
||||
/* 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);
|
||||
|
@ -35,10 +35,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.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,7 +253,7 @@ more_help (int key, const char *text, void *input)
|
||||
{
|
||||
case ARGP_KEY_HELP_EXTRA:
|
||||
/* We print some extra information. */
|
||||
return strdup (gettext ("\
|
||||
return xstrdup (gettext ("\
|
||||
Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"));
|
||||
default:
|
||||
break;
|
||||
@ -320,7 +322,7 @@ write_locales (void)
|
||||
{
|
||||
mode_t mode;
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
if (dirent->d_type != DT_UNKNOWN)
|
||||
if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_LNK)
|
||||
mode = DTTOIF (dirent->d_type);
|
||||
else
|
||||
#endif
|
||||
@ -348,7 +350,7 @@ write_locales (void)
|
||||
"/LC_CTYPE");
|
||||
|
||||
if (stat (buf, &st) == 0 && S_ISREG (st.st_mode))
|
||||
PUT (strdup (dirent->d_name));
|
||||
PUT (xstrdup (dirent->d_name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,7 +427,7 @@ write_locales (void)
|
||||
*cp++ = '\0';
|
||||
|
||||
/* Add the alias. */
|
||||
PUT (strdup (alias));
|
||||
PUT (xstrdup (alias));
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,84 +455,38 @@ static void
|
||||
write_charmaps (void)
|
||||
{
|
||||
void *all_data = NULL;
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
CHARMAP_DIR *dir;
|
||||
const char *dirent;
|
||||
|
||||
dir = opendir (CHARMAP_PATH);
|
||||
/* Look for all files in the charmap directory. */
|
||||
dir = charmap_opendir (CHARMAP_PATH);
|
||||
if (dir == NULL)
|
||||
return;
|
||||
|
||||
while ((dirent = charmap_readdir (dir)) != NULL)
|
||||
{
|
||||
error (1, errno, gettext ("cannot read character map directory `%s'"),
|
||||
CHARMAP_PATH);
|
||||
return;
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
charmap_closedir (dir);
|
||||
|
||||
twalk (all_data, print_names);
|
||||
}
|
||||
|
@ -1,3 +1,11 @@
|
||||
2000-10-01 Bruno Haible <haible@clisp.cons.org>
|
||||
|
||||
* charmaps/BIG5: Add a width table.
|
||||
* charmaps/GB18030: Likewise.
|
||||
* charmaps/ISO-8859-6: Likewise.
|
||||
* charmaps/ISO-8859-8: Likewise.
|
||||
* charmaps/TIS-620: Likewise.
|
||||
|
||||
2000-09-30 Bruno Haible <haible@clisp.cons.org>
|
||||
|
||||
* Makefile (repertoiremaps): Remove variable.
|
||||
|
Loading…
Reference in New Issue
Block a user