diff options
| author | Roland McGrath <roland@gnu.org> | 1995-05-18 09:00:09 +0000 |
|---|---|---|
| committer | Roland McGrath <roland@gnu.org> | 1995-05-18 09:00:09 +0000 |
| commit | 2b83a2a4d978012cdf78b648337c31091e20526d (patch) | |
| tree | 6a5130b031f6815b6edbbb6e2b084c79ece15b1d | |
| parent | 4f6dc78a9237bb327a1d694635be9b0f50cc395e (diff) | |
| download | glibc-2b83a2a4d978012cdf78b648337c31091e20526d.tar.xz glibc-2b83a2a4d978012cdf78b648337c31091e20526d.zip | |
Wed May 17 16:50:21 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
Merged 1003.2 locale and localedef programs by Ulrich Drepper.
* locale/charmap.c: New file.
* locale/collate.c: New file.
* locale/config.h: New file.
* locale/ctype.c: New file.
* locale/ctypedump.c: New file.
* locale/hash.c: New file.
* locale/hash.h: New file.
* locale/iso-4217.def: New file.
* locale/keyword.gperf: New file.
* locale/keyword.h: New file.
* locale/libintl.h: New file.
* locale/locale.c: New file.
* locale/localedef.c: New file.
* locale/localedef.h: New file.
* locale/locfile-lex.c: New file.
* locale/locfile-parse.c: New file.
* locale/messages.c: New file.
* locale/monetary.c: New file.
* locale/numeric.c: New file.
* locale/token.h: New file.
* posix/regex.c, posix/regex.h: New files, incorporated from GNU regex.
* posix/Makefile (headers): Add regex.h.
(routines): Add regex.
(gpl2lgpl): Add regex.c and regex.h.
Tue May 16 17:35:07 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* locale/loadlocale.c: Expect macro LOCALE_PATH to be defined,
instead of hard-coding "/share/locale".
| -rw-r--r-- | ChangeLog | 34 | ||||
| -rwxr-xr-x | configure | 26 | ||||
| -rw-r--r-- | libintl.h | 1 | ||||
| -rw-r--r-- | locale/Makefile | 34 | ||||
| -rw-r--r-- | locale/categories.def | 4 | ||||
| -rw-r--r-- | locale/charmap.c | 524 | ||||
| -rw-r--r-- | locale/collate.c | 212 | ||||
| -rw-r--r-- | locale/config.h | 45 | ||||
| -rw-r--r-- | locale/ctype.c | 817 | ||||
| -rw-r--r-- | locale/ctypedump.c | 163 | ||||
| -rw-r--r-- | locale/hash.c | 254 | ||||
| -rw-r--r-- | locale/hash.h | 50 | ||||
| -rw-r--r-- | locale/iso-4217.def | 36 | ||||
| -rw-r--r-- | locale/keyword.gperf | 77 | ||||
| -rw-r--r-- | locale/keyword.h | 180 | ||||
| -rw-r--r-- | locale/langinfo.h | 4 | ||||
| -rw-r--r-- | locale/libintl.h | 77 | ||||
| -rw-r--r-- | locale/loadlocale.c | 9 | ||||
| -rw-r--r-- | locale/locale.c | 538 | ||||
| -rw-r--r-- | locale/localedef.c | 261 | ||||
| -rw-r--r-- | locale/localedef.h | 196 | ||||
| -rw-r--r-- | locale/locfile-lex.c | 533 | ||||
| -rw-r--r-- | locale/locfile-parse.c | 820 | ||||
| -rw-r--r-- | locale/messages.c | 76 | ||||
| -rw-r--r-- | locale/monetary.c | 132 | ||||
| -rw-r--r-- | locale/numeric.c | 62 | ||||
| -rw-r--r-- | locale/token.h | 54 | ||||
| -rw-r--r-- | posix/Makefile | 6 | ||||
| -rw-r--r-- | posix/regex.c | 5400 | ||||
| -rw-r--r-- | posix/regex.h | 495 | ||||
| -rw-r--r-- | regex.h | 1 |
31 files changed, 11096 insertions, 25 deletions
@@ -1,3 +1,37 @@ +Wed May 17 16:50:21 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + Merged 1003.2 locale and localedef programs by Ulrich Drepper. + * locale/charmap.c: New file. + * locale/collate.c: New file. + * locale/config.h: New file. + * locale/ctype.c: New file. + * locale/ctypedump.c: New file. + * locale/hash.c: New file. + * locale/hash.h: New file. + * locale/iso-4217.def: New file. + * locale/keyword.gperf: New file. + * locale/keyword.h: New file. + * locale/libintl.h: New file. + * locale/locale.c: New file. + * locale/localedef.c: New file. + * locale/localedef.h: New file. + * locale/locfile-lex.c: New file. + * locale/locfile-parse.c: New file. + * locale/messages.c: New file. + * locale/monetary.c: New file. + * locale/numeric.c: New file. + * locale/token.h: New file. + + * posix/regex.c, posix/regex.h: New files, incorporated from GNU regex. + * posix/Makefile (headers): Add regex.h. + (routines): Add regex. + (gpl2lgpl): Add regex.c and regex.h. + +Tue May 16 17:35:07 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * locale/loadlocale.c: Expect macro LOCALE_PATH to be defined, + instead of hard-coding "/share/locale". + Sat May 13 02:16:42 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * configure.in (os=gnu*): Always set elf=yes, not just for os=gnu*elf*. @@ -571,6 +571,19 @@ echo "$ac_t""$host" 1>&4 # $machine, $vendor, and $os, and changes them whenever convenient. config_machine=$host_cpu config_vendor=$host_vendor config_os=$host_os +# Some configurations imply other options. +case "$host_os" in +gnu* | linux* | bsd4.4* | netbsd* | freebsd*) + # These systems always use GNU tools. + gnu_ld=yes gnu_as=yes +esac +case "$host_os" in +gnu* | linux* | sysv4* | solaris2*) + # These systems always use the ELF format. + elf=yes +esac + +# Compute the list of sysdep directories for this configuration. sysdep_dir=$srcdir/sysdeps echo $ac_n "checking sysdep dirs""... $ac_c" 1>&4 if eval "test \"`echo '$''{'libc_cv_sysdirs'+set}'`\" = set"; then @@ -621,19 +634,6 @@ none) base_os='' ;; esac -# Some configurations imply other options. -case "$os" in -gnu* | linux* | bsd4.4* | netbsd* | freebsd*) - # These systems always use GNU tools. - gnu_ld=yes gnu_as=yes -esac -case "$os" in -gnu* | linux* | sysv4* | solaris2*) - # These systems always use the ELF format. - elf=yes -esac - - # For sunos4.1.1, try sunos4.1.1, then sunos4.1, then sunos4, then sunos. tail=$os ostry=$os diff --git a/libintl.h b/libintl.h new file mode 100644 index 0000000000..38a33d232b --- /dev/null +++ b/libintl.h @@ -0,0 +1 @@ +#include <locale/libintl.h> diff --git a/locale/Makefile b/locale/Makefile index 87a6706e05..c3abc2c62e 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -21,10 +21,36 @@ # subdir := locale -headers := locale.h -distribute := localeinfo.h categories.def -routines := setlocale loadlocale localeconv -categories := ctype messages monetary numeric time collate +headers = locale.h +distribute = localeinfo.h categories.def \ + $(localedef-modules:=.c) $(locale-modules:=.c) \ + $(lib-modules:=.c) config.h hash.h iso-4217.def \ + keyword.gperf keyword.h localedef.h token.h +routines = setlocale loadlocale localeconv nl_langinfo +categories = ctype messages monetary numeric time collate aux = $(categories:%=lc-%) $(categories:%=C-%) +others = localedef locale +install-bin = localedef locale +extra-objs = $(localedef-modules:=.o) $(locale-modules:=.o) \ + $(lib-modules:=.o) + +localedef-modules := charmap locfile-lex locfile-parse ctype \ + monetary messages collate numeric +locale-modules := ctypedump +lib-modules := error hash xmalloc + + +GPERF = gperf +GPERFFLAGS = -acCgopt -k1,2,5,$$ include ../Rules + +keyword.h: keyword.gperf + $(GPERF) $(GPERFFLAGS) $< > $@.new + mv -f $@.new $@ + +$(objpfx)localedef: $(localedef-modules:%=$(objpfx)%.o) +$(objpfx)locale: $(locale-modules:%=$(objpfx)%.o) +$(objpfx)localedef $(objpfx)locale: $(lib-modules:%=$(objpfx)%.o) + +CPPFLAGS += -DLOCALE_PATH='"$(localedir)"' -DCHARMAP_PATH='"$(nlsdir)/charmap"' diff --git a/locale/categories.def b/locale/categories.def index 6bdad35e17..be3c6bc549 100644 --- a/locale/categories.def +++ b/locale/categories.def @@ -101,6 +101,10 @@ DEFINE_CATEGORY (LC_TIME, "LC_TIME", { D_FMT, "d_fmt", std, string }, { T_FMT, "t_fmt", std, string }, { T_FMT_AMPM, "t_fmt_ampm", std, string }, + { ERA, "era", opt, string }, + { ERA_YEAR, "era_year", opt, string }, + { ERA_D_FMT, "era_d_fmt", opt, string }, + { ALT_DIGITS, "alt_digits", opt, stringarray, 0, 100 }, { 0 } ), NO_POSTLOAD, NULL, NULL, NULL ) diff --git a/locale/charmap.c b/locale/charmap.c new file mode 100644 index 0000000000..ad1075e5bc --- /dev/null +++ b/locale/charmap.c @@ -0,0 +1,524 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ctype.h> +#include <errno.h> +#include <libintl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "localedef.h" +#include "hash.h" + +/* Data structure for representing charmap database. */ +struct charmap charmap_data; + +/* Line number in charmap file. */ +static unsigned int line_no; + +/* Prototypes for local functions. */ +static void read_prolog (FILE *infile); +static unsigned long read_body (FILE *infile); + + +/* Read complete table of symbolic names for character set from file. If + this file does not exist or is not readable a default file is tried. + If this also is not readable no character map is defined. */ +void +charmap_read (const char *filename) +{ + unsigned long max_char; + long path_max = pathconf (".", _PC_PATH_MAX); + char buf[path_max]; + FILE *infile = NULL; + + /* Initialize charmap data. */ + charmap_data.codeset_name = NULL; + charmap_data.mb_cur_max = -1; + charmap_data.mb_cur_min = -1; + charmap_data.escape_char = '\\'; + charmap_data.comment_char = '#'; + + if (filename != NULL) + { + strcpy (buf, filename); + infile = fopen (filename, "r"); + if (infile == NULL && filename[0] != '/') + { + snprintf (buf, path_max, "%s/%s", CHARMAP_PATH, filename); + infile = fopen (buf, "r"); + } + } + if (infile == NULL) + { + if (filename != NULL) + error (0, errno, gettext ("input file `%s' not found"), filename); + + snprintf (buf, path_max, "%s/%s", CHARMAP_PATH, DEFAULT_CHARMAP); + infile = fopen (buf, "r"); + + if (infile == NULL) + error (4, errno, gettext ("input file `%s' not found"), filename); + } + + charmap_data.filename = buf; + init_hash (&charmap_data.table, 500); + line_no = 0; + + /* Read the prolog of the charmap file. */ + read_prolog (infile); + + /* Last works on the charmap tables global data. */ + if (charmap_data.mb_cur_max == -1) + charmap_data.mb_cur_max = 1; + if (charmap_data.mb_cur_min == -1) + charmap_data.mb_cur_min = charmap_data.mb_cur_max; + + if ((size_t) charmap_data.mb_cur_max > sizeof (long)) + { + error (2, 0, gettext ("program limitation: for now only upto %Zu " + "bytes per character are allowed"), sizeof (long)); + } + + /* Now process all entries. */ + max_char = read_body (infile); + + /* We don't need the file anymore. */ + fclose (infile); + + + /* Determine the optimal table size when using the simple modulo hashing + function. */ + if (max_char >= 256) + { + int size; + /* Current best values, initialized to some never reached high value. */ + int best_count = 10000; + int best_size = 10000; + int best_product = best_count * best_size; + + /* Give warning. */ + error (-1, 0, gettext ("computing character table size: this may take " + "a while")); + + for (size = 256; size <= best_product; ++size) + { + /* Array with slot counters. */ + int cnt[size]; + /* Current character. */ + int ch; + /* Maximal number of characters in any slot. */ + int maxcnt = 0; + /* Product of current size and maximal count. */ + int product = 0; + /* Iteration pointer through hashing table. */ + char *ptr = NULL; + + /* Initializes counters to zero. */ + memset(cnt, 0, size * sizeof (int)); + + /* Iterate through whole hashing table. */ + while (product < best_product + && iterate_table (&charmap_data.table, (void **) &ptr, + (void **) &ch)) + { + /* Increment slot counter. */ + ++cnt[ch % size]; + /* Test for current maximum. */ + if (cnt[ch % size] > maxcnt) + { + maxcnt = cnt[ch % size]; + product = maxcnt * size; + } + } + + if (product < best_product) + { + best_count = maxcnt; + best_size = size; + best_product = best_count * best_size; + } + } + + charmap_data.hash_size = best_size; + charmap_data.hash_layers = best_count; + } + else + { + charmap_data.hash_size = 256; + charmap_data.hash_layers = 1; + } +} + + +#define SYNTAX_ERROR \ + do { error (0, 0, gettext ("%s:%u: syntax error in charmap file"), \ + charmap_data.filename, line_no); \ + goto end_of_loop; } while (0) + +/* Read the prolog of the charmap file until the line containing `CHARMAP'. + All possible entries are processed. */ +static void +read_prolog (FILE *infile) +{ + size_t bufsize = sysconf (_SC_LINE_MAX); + char buf[bufsize]; + + while (1) + { + char *cp = buf; + char len; + + /* Read the next line. */ + fgets (buf, bufsize, infile); + len = strlen (buf); + + /* On EOF simply return. */ + if (len == 0 || buf[len - 1] != '\n') + error (4, 0, gettext ("%s: unexpected end of file in charmap"), + charmap_data.filename); + + /* This is the next line. */ + ++line_no; + + /* Comments and empty lines are ignored. */ + if (len == 1 || buf[0] == charmap_data.comment_char) + continue; + + buf[len - 1] = '\0'; + + /* Throw away leading white spaces. This is not defined in POSIX.2 + so don't do it if conformance is requested. */ + if (!posix_conformance) + while (isspace (*cp)) + ++cp; + + /* If `CHARMAP' is read the prolog is over. */ + if (strncmp (cp, "CHARMAP", 7) == 0 + && (!posix_conformance || cp[7] == '\0')) + return; + + /* Now it can be only one of special symbols defining the charmap + parameters. All are beginning with '<'. */ + if (*cp != '<') + SYNTAX_ERROR; + + ++cp; + if (strncmp (cp, "code_set_name>", 14) == 0) + { + char *startp; + +#define cp_to_arg(no,pred) \ + cp += no; \ + while (isspace (*cp)) \ + ++cp; \ + if (*cp == '\0' || !pred (*cp)) \ + SYNTAX_ERROR; + + cp_to_arg (14,isgraph) + + if (charmap_data.codeset_name != NULL) + { + error (0, 0, gettext ("%s:%u: duplicate code set name " + "specification"), + charmap_data.filename, line_no); + free (charmap_data.codeset_name); + } + + startp = cp; + while (*cp != '\0' && isgraph (*cp) && !isspace (*cp)) + ++cp; + + charmap_data.codeset_name = (char *) xmalloc (cp - startp + 1); + strncpy (startp, startp, cp - startp); + } + else if (strncmp (cp, "mb_cur_max>", 11) == 0) + { + int new_val; + cp_to_arg (11,isdigit) + + if (charmap_data.mb_cur_max != -1) + error (0, 0, + gettext ("%s:%u: duplicate definition of mb_cur_max"), + charmap_data.filename, line_no); + + new_val = (int) strtol (cp, &cp, posix_conformance ? 10 : 0); + if (new_val < 1) + error (0, 0, gettext ("%s:%u: illegal value for mb_cur_max: %d"), + charmap_data.filename, line_no, new_val); + else + charmap_data.mb_cur_max = new_val; + } + else if (strncmp (cp, "mb_cur_min>", 11) == 0) + { + int new_val; + cp_to_arg (11,isdigit) + + if (charmap_data.mb_cur_max != -1) + error (0, 0, + gettext ("%s:%u: duplicate definition of mb_cur_min"), + charmap_data.filename, line_no); + + new_val = (int) strtol (cp, &cp, posix_conformance ? 10 : 0); + if (new_val < 1) + error (0, 0, gettext ("%s:%u: illegal value for mb_cur_min: %d"), + charmap_data.filename, line_no, new_val); + else + charmap_data.mb_cur_min = new_val; + } + else if (strncmp (cp, "escape_char>", 12) == 0) + { + cp_to_arg (12, isgraph) + charmap_data.escape_char = *cp; + } + else if (strncmp (cp, "comment_char>", 13) == 0) + { + cp_to_arg (13, isgraph) + charmap_data.comment_char = *cp; + } + else + SYNTAX_ERROR; + end_of_loop: + } +} +#undef cp_to_arg + + +static unsigned long +read_body (FILE *infile) +{ + unsigned long max_char = 0; + size_t bufsize = sysconf (_SC_LINE_MAX); + char buf[bufsize]; + char name_str[bufsize / 2]; + char code_str[bufsize / 2]; + + while (1) + { + char *cp = buf; + size_t len; + + /* Read the next line. */ + fgets (buf, bufsize, infile); + len = strlen (buf); + + /* On EOF simply return. */ + if (len == 0) + error (0, 0, gettext ("%s: `END CHARMAP' is missing"), + charmap_data.filename); + + /* This is the next line. */ + ++line_no; + + if (len == bufsize - 1) + { + error (0, 0, gettext ("%s:%u: line too long; use `getconf " + "LINE_MAX' to get the current maximum line" + "length"), charmap_data.filename, line_no); + do + { + fgets (buf, bufsize, infile); + len = strlen (buf); + } + while (len == bufsize - 1); + continue; + } + + /* Comments and empty lines are ignored. */ + if (len == 1 || buf[0] == charmap_data.comment_char) + continue; + + buf[len - 1] = |
