diff options
author | Ulrich Drepper <drepper@redhat.com> | 1997-02-19 04:43:53 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1997-02-19 04:43:53 +0000 |
commit | 1fb05e3db1891142410bc58c320dfe281749fffe (patch) | |
tree | 46299dbecec282055e3493787910444e77099fe7 /locale | |
parent | c84142e8fe3cbcce43ae35ac957a74ac8216d11d (diff) | |
download | glibc-1fb05e3db1891142410bc58c320dfe281749fffe.tar glibc-1fb05e3db1891142410bc58c320dfe281749fffe.tar.gz glibc-1fb05e3db1891142410bc58c320dfe281749fffe.tar.bz2 glibc-1fb05e3db1891142410bc58c320dfe281749fffe.zip |
update from main archive 970218cvs/libc-970221cvs/libc-970220cvs/libc-970219
1997-02-19 03:28 Miles Bader <miles@gnu.ai.mit.edu>
* argp/argp-help.c: Add support for user provided filter of help
messages.
* argp/argp-parse.c: Likewise.
* argp/argp.h: Likewise.
* argp/argp-namefrob.h: Define __argp_input.
* argp/argp-test.c: Add example for filter.
1997-02-19 02:58 Ulrich Drepper <drepper@cygnus.com>
* argp.h: New file.
* locale/programs/locale.c: Switch to use argp.
* errno.h: Make it possible to get definition of error_t even
after having errno.h already.
* elf/dl-hash.h: New file. ELF hashing function. Extracted
from dl-lookup.c.
* elf/dl-lookup.c (_dl_elf_hash): Remove definition.
* elf/dl-load.c: Rename _dl_does_name_match_p to _dl_name_match_p.
* elf/dl-version.c: Likewise.
* elf/dl-lookup.c: Implement new versioning lookup scheme.
* elf/dl-version.c (_dl_check_map_versions): Initialize new field
in l_versions member.
* elf/dlvsym.c: Correct call of _dl_lookup_versioned_symbol_skip
and _dl_lookup_versioned_symbol.
* elf/link.h: Rename hash_name_pair to struct r_found_version.
* sysdeps/alpha/dl-machine.h: Likewise.
* sysdeps/i386/dl-machine.h: Likewise.
* sysdeps/m68k/dl-machine.h: Likewise.
* sysdeps/mips/dl-machine.h: Likewise.
* intl/l10nflist.c: (_nl_make_l10nflist): Fix bug in computation of
length of abs_filename.
* locale/Makefile (CPPFLAGS): Define LOCALE_ALIAS_PATH.
* locale/programs/ld-monetary.c (monetary_add): Allow value 0
in mon_grouping information. This means no more grouping.
* locale/programs/ld-numeric.c (numeric_add): Write value \377
when seein value 0 in grouping information.
* locale/programs/linereader.c (lr_close): Don't free fname since
it might be used in error messages.
* locale/programs/locale.c: Check whether output of `locale -a'
really is locale directory. Also print locale aliases.
* misc/search.h (__action_fn_t): Parameters VALUE and LEVEL cannot
be const.
1997-02-19 02:16 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/bsd/sun/sunos4/resourcebits.h: Correct #defin to
#define. Reported by Rick Flower <FLOWER@sdvax2.sdd.TRW.COM>.
1997-02-19 01:37 Erik Troan <ewt@redhat.com>
* shadow/sgetspent_r.c: Accept empty third, fourth and fifth fields.
1997-02-19 01:02 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/mman/syscalls.list: msync takes 3 arguments.
Reported by Andreas Jaeger <aj@arthur.pfalz.de>.
* sysdeps/stub/msync.c (msync): Add missing third parameter.
1997-02-19 00:29 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/bsd/sigsuspend.c: Call __sigpause with needed
additional argument.
1997-02-18 22:13 Ulrich Drepper <drepper@cygnus.com>
* inet/net/ethernet.h: New file.
* sysdeps/unix/sysv/linux/netinet/if_ether.c: Add BSD compatibility.
* sysdeps/unix/sysv/linux/net/if_slip.h: New file.
Contributed by a sun <asun@zoology.washington.edu>.
* sysdeps/unix/sysv/linux/net/if_arp.h: Include <sys/socket.h>.
* sunrpc/rpc/rpc_msg.h: Include <rpc/clnt.h>.
Reported by a sun <asun@zoology.washington.edu>.
1997-02-16 14:25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* Makerules ((common-objpfx)distinfo-$(subdir)): Depend on sysdep
makefiles which may change the distinfo variables.
1997-02-16 14:03 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers)
[$(subdir)=misc]: Add sys/quota.h.
(sysdep_headers) [$(subdir)=inet]: Add netinet/udp.h.
1997-02-17 13:12 aleph1@dfw.net
* sunrpc/clnt_simp.c (callrpc): Prevent buffer overflow by using
strncpy.
1997-02-18 03:28 Ulrich Drepper <drepper@cygnus.com>
* stdio-common/bug10.c (main): Correct parameter.
1997-02-17 02:51 Ulrich Drepper <drepper@cygnus.com>
* malloc/obstack.h: Add `extern "C"' protection.
* posix/regex.h: Likewise.
* io/ftw.h: Likewise.
* misc/libgen.h: Likewise.
* login/utmp.h: Likewise.
* sysdeps/unix/sysv/linux/sys/reboot.h: Likewise.
* sysdeps/unix/sysv/linux/netinet/in.h: Likewise.
* sunrpc/rpc/pmap_rmt.h: Likewise.
* sunrpc/rpc/auth_des.h: Likewise.
* elf/link.h: Likewise.
Reported by HJ Lu.
1997-02-17 01:45 a sun <asun@zoology.washington.edu>
Linux specific network headers.
* sysdeps/unix/sysv/linux/netinet/if_fddi.h: New file.
* sysdeps/unix/sysv/linux/netinet/if_tr.h: New file.
* sysdeps/unix/sysv/linux/netinet/ip_icmp.h: New file.
* sysdeps/unix/sysv/linux/netinet/ip_fw.h: New file.
* sysdeps/unix/sysv/linux/netinet/igmp.h: New file.
* sysdeps/unix/sysv/linux/netinet/icmp.h: New file.
* sysdeps/unix/sysv/linux/netinet/ip.h: New file.
* sysdeps/unix/sysv/linux/netinet/tcp.h: New file.
* sysdeps/unix/sysv/linux/netipx/ipx.h: New file.
* sysdeps/unix/sysv/linux/netatalk/atalk.h: New file.
* sysdeps/unix/sysv/linux/Dist: Add new network headers.
* sysdeps/unix/sysv/linux/Makefile [$(subdir)=misc] (sysdep_headers):
Add sys/quota.h.
[$(subdir)=inet] (sysdep_headers): Add new network header.
* sysdeps/unix/sysv/linux/netinet/udp.h: Add Linux specific changes.
* inet/netinet/ip.h: Move to sysdeps/generic.
* inet/netinet/tcp.h: Likewise.
* sysdeps/generic/netinet/ip.h: Moved to here from inet/netinet.
* sysdeps/generic/netinet/tcp.h: Likewise.
1997-02-17 01:18 Ulrich Drepper <drepper@cygnus.com>
* misc/sys/syslog.h (prioritynames): Correct definition to use
braces where necessary.
(facilitynames): Likewise.
Patch by Ronald F. Guilmette <rfg@monkeys.com>.
Comment and beautify declarations.
1997-02-16 19:54 1997 Philip Blundell <Philip.Blundell@pobox.com>
* inet/Makefile (routines): Add in6_addr, getnameinfo.
* inet/getnameinfo.c: New file. Implementation of getnameinfo()
by Craig Metz.
* inet/in6_addr.c: New file. IPv6 addressing constants.
* posix/Makefile (routines): Add gai_strerror.
* resolv/netdb.h: Add more constants for IPv6 basic API.
* sysdeps/posix/gai_strerror.c: New file.
* sysdeps/stub/gai_strerror.c New file.
* sysdeps/unix/sysv/linux/netinet/in.h: Add definitions for IPv6
basic API.
* sysdeps/posix/getaddrinfo.c: Update from latest version by
Craig Metz and use reentrant getXXbyYY functions.
1997-02-15 14:32 Andreas Jaeger <aj@arthur.pfalz.de>
* argp/argp.h: Declare argp_program_version as const char.
* argp/argp-test.c: Likewise
* stdlib/testrand.c (main): Declare main prototype.
* stdlib/testdiv.c (main): Likewise.
* string/testcopy.c (main): Likewise.
* string/test-ffs.c (main): Likewise.
* time/test_time.c (main): Likewise.
* locale/duplocale.c (__duplocale): Return result.
1997-02-16 03:54 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/netinet/in.h: Declare bindresvport.
Reported by fabsoft@fabserver1.zarm.uni-bremen.de.
* nss/nss.h: Remove declaration of __nss_shlib_revision.
* nss/nsswitch.c: Don't use NSS_SHLIB_VERSION macro.
1997-02-16 03:48 Thorsten Kukuk <kukuk@weber.uni-paderborn.de>
* nis/nss_nis/nis-ethers.c (_nss_nis_getethernam_r): Rename to
_nss_nis_gethostton_r.
(_nss_nis_getetherbyaddr_r): Rename to _nss_nis_getntohost_r.
1997-02-15 22:37 Andy Berkheimer <andy@tho.org>
* resolv/gethnamaddr.c (gethostbyname2): Test for ':' in name before
trying to resolv name as numeric IPv6 address.
* nss/digits_dots.c: Likewise.
Sat Feb 15 04:51:08 1997 Ulrich Drepper <drepper@cygnus.com>
* locale/setlocale.c (setlocale): Don't try to be clever about
unused locales. When the existence of the locale files isn't
tested the result of setlocale might be different.
1997-02-15 03:34 Ulrich Drepper <drepper@cygnus.com>
* locale/setlocale.c (setlocale): Don't increment usage_count of
new locale if it already has the value MAX_USAGE_COUNT (it might
be the C locale data which is read-only).
Diffstat (limited to 'locale')
-rw-r--r-- | locale/Makefile | 1 | ||||
-rw-r--r-- | locale/duplocale.c | 2 | ||||
-rw-r--r-- | locale/programs/ld-monetary.c | 8 | ||||
-rw-r--r-- | locale/programs/ld-numeric.c | 5 | ||||
-rw-r--r-- | locale/programs/linereader.c | 1 | ||||
-rw-r--r-- | locale/programs/locale.c | 353 | ||||
-rw-r--r-- | locale/setlocale.c | 33 |
7 files changed, 283 insertions, 120 deletions
diff --git a/locale/Makefile b/locale/Makefile index dcf469f689..7acef573d6 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -74,6 +74,7 @@ localepath = "$(localedir):$(i18ndir)" CPPFLAGS := -DLOCALE_PATH='$(localepath)' \ -DLOCALEDIR='"$(localedir)"' \ + -DLOCALE_ALIAS_PATH='"$(localedir):$(i18ndir)"' \ -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \ -DLOCSRCDIR='"$(i18ndir)/locales"' -DHAVE_CONFIG_H \ -Iprograms $(CPPFLAGS) diff --git a/locale/duplocale.c b/locale/duplocale.c index 494c2ec829..f22c4dee95 100644 --- a/locale/duplocale.c +++ b/locale/duplocale.c @@ -52,4 +52,6 @@ __duplocale (__locale_t dataset) /* It's done. */ __libc_lock_unlock (__libc_setlocale_lock); + + return result; } diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c index ce83b18dba..cd30125a5a 100644 --- a/locale/programs/ld-monetary.c +++ b/locale/programs/ld-monetary.c @@ -364,9 +364,11 @@ field `%s' in category `%s' declared more than once"), \ if (code->tok == tok_minus1) monetary->mon_grouping[monetary->mon_grouping_act++] = '\177'; else if (code->val.num == 0) - lr_error (lr, _("\ -values for field `%s' in category `%s' must not be zero"), - "mon_grouping", "LC_MONETARY"); + /* A value of 0 disables grouping from here on but we must + not store a NUL character since this terminates the + string. Use something different which must not be used + otherwise. */ + monetary->mon_grouping[monetary->mon_grouping_act++] = '\377'; else if (code->val.num > 126) lr_error (lr, _("\ values for field `%s' in category `%s' must be smaller than 127"), diff --git a/locale/programs/ld-numeric.c b/locale/programs/ld-numeric.c index 375635aafc..2454281a4d 100644 --- a/locale/programs/ld-numeric.c +++ b/locale/programs/ld-numeric.c @@ -195,6 +195,11 @@ field `%s' in category `%s' declared more than once"), \ if (code->tok == tok_minus1) numeric->grouping[numeric->grouping_act++] = '\177'; + else if (code->val.num == 0) + /* A value of 0 disables grouping from here on but we must + not store a NUL character since this terminates the string. + Use something different which must not be used otherwise. */ + numeric->grouping[numeric->grouping_act++] = '\377'; else if (code->val.num > 126) lr_error (lr, _("\ values for field `%s' in category `%s' must be smaller than 127"), diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c index edb5a51f5c..83679b7655 100644 --- a/locale/programs/linereader.c +++ b/locale/programs/linereader.c @@ -108,7 +108,6 @@ void lr_close (struct linereader *lr) { fclose (lr->fp); - free ((char *) lr->fname); free (lr->buf); free (lr); } diff --git a/locale/programs/locale.c b/locale/programs/locale.c index 8587345bf2..5a68c562ef 100644 --- a/locale/programs/locale.c +++ b/locale/programs/locale.c @@ -1,4 +1,4 @@ -/* locale - Implementation of the locale program according to POSIX 1003.2 +/* Implementation of the locale program according to POSIX 1003.2. Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. @@ -22,18 +22,21 @@ # include <config.h> #endif +#include <argp.h> +#include <argz.h> #include <dirent.h> +#include <errno.h> #include <error.h> -#include <getopt.h> #include <langinfo.h> #include <libintl.h> #include <limits.h> #include <locale.h> +#include <search.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> -#include <errno.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h> #include "localeinfo.h" @@ -44,16 +47,44 @@ static int show_category_name; /* If set print the name of the item. */ static int show_keyword_name; -/* Long options. */ -static const struct option long_options[] = +/* Print names of all available locales. */ +static int do_all; + +/* Print names of all available character maps. */ +static int do_charmaps = 0; + +/* Name and version of program. */ +static void print_version (FILE *stream, struct argp_state *state); +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +/* Definitions of arguments for argp functions. */ +static struct argp_option options[] = { - { "all-locales", no_argument, NULL, 'a' }, - { "category-name", no_argument, &show_category_name, 1 }, - { "charmaps", no_argument, NULL, 'm' }, - { "help", no_argument, NULL, 'h' }, - { "keyword-name", no_argument, &show_keyword_name, 1 }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 } + { NULL, 0, NULL, 0, "System information:" }, + { "all-locales", 'a', NULL, 0, "Write names of available locales" }, + { "charmaps", 'm', NULL, 0, "Write names of available charmaps" }, + { NULL, 0, NULL, 0, "Modify output format:" }, + { "category-name", 'c', NULL, 0, "Write names of selected categories" }, + { "keyword-name", 'k', NULL, 0, "Write names of selected keywords" }, + { NULL, 0, NULL, 0, NULL } +}; + +/* Short description of program. */ +static const char doc[] = "Get locale-specific information."; + +/* Strings for arguments in help texts. */ +static const char args_doc[] = "NAME\n[-a|-m]"; + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Function to print some extra text in the help message. */ +static char *more_help (int key, const char *text, void *input); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, args_doc, doc, NULL, more_help }; @@ -124,7 +155,6 @@ extern void locale_special (const char *name, int show_category_name, int show_keyword_name); /* Prototypes for local functions. */ -static void usage (int status) __attribute__ ((noreturn)); static void write_locales (void); static void write_charmaps (void); static void show_locale_vars (void); @@ -134,12 +164,6 @@ static void show_info (const char *name); int main (int argc, char *argv[]) { - int optchar; - int do_all = 0; - int do_help = 0; - int do_version = 0; - int do_charmaps = 0; - /* Set initial values for global variables. */ show_category_name = 0; show_keyword_name = 0; @@ -152,55 +176,13 @@ main (int argc, char *argv[]) /* Initialize the message catalog. */ textdomain (PACKAGE); - while ((optchar = getopt_long (argc, argv, "achkmV", long_options, NULL)) - != -1) - switch (optchar) - { - case '\0': /* Long option. */ - break; - case 'a': - do_all = 1; - break; - case 'c': - show_category_name = 1; - break; - case 'h': - do_help = 1; - break; - case 'k': - show_keyword_name = 1; - break; - case 'm': - do_charmaps = 1; - break; - case 'V': - do_version = 1; - break; - default: - usage (EXIT_FAILURE); - } - - /* Version information is requested. */ - if (do_version) - { - printf ("locale (GNU %s) %s\n", PACKAGE, VERSION); - printf (_("\ -Copyright (C) %s Free Software Foundation, Inc.\n\ -This is free software; see the source for copying conditions. There is NO\n\ -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ -"), "1995, 1996, 1997"); - printf (_("Written by %s.\n"), "Ulrich Drepper"); - - exit (EXIT_SUCCESS); - } - - /* Help is requested. */ - if (do_help) - usage (EXIT_SUCCESS); + /* Parse and process arguments. */ + argp_parse (&argp, argc, argv, 0, 0, NULL); /* `-a' requests the names of all available locales. */ if (do_all != 0) { + setlocale (LC_COLLATE, ""); write_locales (); exit (EXIT_SUCCESS); } @@ -233,61 +215,219 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ } -/* Display usage information and exit. */ -static void -usage (int status) +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) { - if (status != EXIT_SUCCESS) - fprintf (stderr, gettext ("Try `%s --help' for more information.\n"), - __progname); - else + switch (key) { - printf (gettext ("\ -Usage: %s [OPTION]... name\n\ -Mandatory arguments to long options are mandatory for short options too.\n\ - -h, --help display this help and exit\n\ - -V, --version output version information and exit\n\ -\n\ - -a, --all-locales write names of available locales\n\ - -m, --charmaps write names of available charmaps\n\ -\n\ - -c, --category-name write names of selected categories\n\ - -k, --keyword-name write names of selected keywords\n"), - __progname); - fputs (gettext ("\ -Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"), - stdout); + case 'a': + do_all = 1; + break; + case 'c': + show_category_name = 1; + break; + case 'm': + do_charmaps = 1; + break; + case 'k': + show_keyword_name = 1; + break; + default: + return ARGP_ERR_UNKNOWN; } + return 0; +} + + +static char * +more_help (int key, const char *text, void *input) +{ + switch (key) + { + case ARGP_KEY_HELP_EXTRA: + /* We print some extra information. */ + return strdup (gettext ("\ +Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n")); + default: + break; + } + return (char *) text; +} + +/* Print the version information. */ +static void +print_version (FILE *stream, struct argp_state *state) +{ + fprintf (stream, "locale (GNU %s) %s\n", PACKAGE, VERSION); + fprintf (stream, gettext ("\ +Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), "1995, 1996, 1997"); + fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); +} - exit (status); + +/* Simple action function which prints arguments as strings. */ +static void +print_names (const void *nodep, VISIT value, int level) +{ + if (value == postorder || value == leaf) + puts (*(char **) nodep); } -/* Write the names of all available locales to stdout. */ +/* Write the names of all available locales to stdout. We have some + sources of the information: the contents of the locale directory + and the locale.alias file. To avoid duplicates and print the + result is a reasonable order we put all entries is a search tree + and print them afterwards. */ static void write_locales (void) { + void *all_data = NULL; DIR *dir; struct dirent *dirent; + char *alias_path; + size_t alias_path_len; + char *entry; - /* `POSIX' locale is always available (POSIX.2 4.34.3). */ - puts ("POSIX"); +#define PUT(name) tsearch ((name), &all_data, \ + (int (*) (const void *, const void *)) strcoll) - dir = opendir (LOCALE_PATH); + dir = opendir (LOCALEDIR); if (dir == NULL) { error (1, errno, gettext ("cannot read locale directory `%s'"), - LOCALE_PATH); + LOCALEDIR); return; } + /* `POSIX' locale is always available (POSIX.2 4.34.3). */ + PUT ("POSIX"); + /* And so is the "C" locale. */ + PUT ("C"); + /* 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) - puts (dirent->d_name); + { + mode_t mode; +#ifdef _DIRENT_HAVE_D_TYPE + if (dirent->d_type != DT_UNKNOWN) + mode = DTTOIF (dirent->d_type); + else +#endif + { + struct stat st; + char buf[sizeof (LOCALEDIR) + strlen (dirent->d_name) + 1]; + + stpcpy (stpcpy (stpcpy (buf, LOCALEDIR), "/"), dirent->d_name); + + if (stat (buf, &st) < 0) + continue; + mode = st.st_mode; + } + + if (S_ISDIR (mode)) + PUT (strdup (dirent->d_name)); + } closedir (dir); + + /* Now read the locale.alias files. */ + if (argz_create_sep (LOCALE_ALIAS_PATH, ':', &alias_path, &alias_path_len)) + error (1, errno, gettext ("while preparing output")); + + entry = NULL; + while ((entry = argz_next (alias_path, alias_path_len, entry))) + { + static const char aliasfile[] = "/locale.alias"; + FILE *fp; + char full_name[strlen (entry) + sizeof aliasfile]; + + stpcpy (stpcpy (full_name, entry), aliasfile); + fp = fopen (full_name, "r"); + if (fp == NULL) + /* Ignore non-existing files. */ + continue; + + while (! feof (fp)) + { + /* It is a reasonable approach to use a fix buffer here + because + a) we are only interested in the first two fields + b) these fields must be usable as file names and so must + not be that long */ + char buf[BUFSIZ]; + char *alias; + char *value; + char *cp; + + if (fgets (buf, BUFSIZ, fp) == NULL) + /* EOF reached. */ + break; + + cp = buf; + /* Ignore leading white space. */ + while (isspace (cp[0])) + ++cp; + + /* A leading '#' signals a comment line. */ + if (cp[0] != '\0' && cp[0] != '#') + { + alias = cp++; + while (cp[0] != '\0' && !isspace (cp[0])) + ++cp; + /* Terminate alias name. */ + if (cp[0] != '\0') + *cp++ = '\0'; + + /* Now look for the beginning of the value. */ + while (isspace (cp[0])) + ++cp; + + if (cp[0] != '\0') + { + value = cp++; + while (cp[0] != '\0' && !isspace (cp[0])) + ++cp; + /* Terminate value. */ + if (cp[0] == '\n') + { + /* This has to be done to make the following + test for the end of line possible. We are + looking for the terminating '\n' which do not + overwrite here. */ + *cp++ = '\0'; + *cp = '\n'; + } + else if (cp[0] != '\0') + *cp++ = '\0'; + + /* Add the alias. */ + PUT (strdup (alias)); + } + } + + /* Possibly not the whole line fits into the buffer. + Ignore the rest of the line. */ + while (strchr (cp, '\n') == NULL) + { + cp = buf; + if (fgets (buf, BUFSIZ, fp) == NULL) + /* Make sure the inner loop will be left. The outer + loop will exit at the `feof' test. */ + *cp = '\n'; + } + } + + fclose (fp); + } + + twalk (all_data, print_names); } @@ -295,6 +435,7 @@ write_locales (void) static void write_charmaps (void) { + void *all_data = NULL; DIR *dir; struct dirent *dirent; @@ -310,9 +451,31 @@ write_charmaps (void) while ((dirent = readdir (dir)) != NULL) if (strcmp (dirent->d_name, ".") != 0 && strcmp (dirent->d_name, "..") != 0) - puts (dirent->d_name); + { + mode_t mode; +#ifdef _DIRENT_HAVE_D_TYPE + if (dirent->d_type != DT_UNKNOWN) + mode = DTTOIF (dirent->d_type); + else +#endif + { + struct stat st; + char buf[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)) + PUT (strdup (dirent->d_name)); + } closedir (dir); + + twalk (all_data, print_names); } diff --git a/locale/setlocale.c b/locale/setlocale.c index 368027f743..12e6569384 100644 --- a/locale/setlocale.c +++ b/locale/setlocale.c @@ -314,28 +314,19 @@ setlocale (int category, const char *locale) /* Load the new data for each category. */ while (category-- > 0) - /* Only actually load the data if anything will use it. */ - if (_nl_current[category] != NULL) - { - newdata[category] = _nl_find_locale (locale_path, locale_path_len, - category, - &newnames[category]); - - if (newdata[category] == NULL) - break; - - /* We must not simply free a global locale since we have - no control over the usage. So we mark it as - un-deletable. */ + { + newdata[category] = _nl_find_locale (locale_path, locale_path_len, + category, + &newnames[category]); + + if (newdata[category] == NULL) + break; + + /* We must not simply free a global locale since we have no + control over the usage. So we mark it as un-deletable. */ + if (newdata[category]->usage_count != MAX_USAGE_COUNT) newdata[category]->usage_count = MAX_USAGE_COUNT; - } - else - { - /* The data is never used; just change the name. */ - newnames[category] = clever_copy (newnames[category]); - if (newnames[category] == NULL) - break; - } + } /* Create new composite name. */ if (category >= 0 |