aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-05-18 09:00:09 +0000
committerRoland McGrath <roland@gnu.org>1995-05-18 09:00:09 +0000
commit2b83a2a4d978012cdf78b648337c31091e20526d (patch)
tree6a5130b031f6815b6edbbb6e2b084c79ece15b1d
parent4f6dc78a9237bb327a1d694635be9b0f50cc395e (diff)
downloadglibc-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--ChangeLog34
-rwxr-xr-xconfigure26
-rw-r--r--libintl.h1
-rw-r--r--locale/Makefile34
-rw-r--r--locale/categories.def4
-rw-r--r--locale/charmap.c524
-rw-r--r--locale/collate.c212
-rw-r--r--locale/config.h45
-rw-r--r--locale/ctype.c817
-rw-r--r--locale/ctypedump.c163
-rw-r--r--locale/hash.c254
-rw-r--r--locale/hash.h50
-rw-r--r--locale/iso-4217.def36
-rw-r--r--locale/keyword.gperf77
-rw-r--r--locale/keyword.h180
-rw-r--r--locale/langinfo.h4
-rw-r--r--locale/libintl.h77
-rw-r--r--locale/loadlocale.c9
-rw-r--r--locale/locale.c538
-rw-r--r--locale/localedef.c261
-rw-r--r--locale/localedef.h196
-rw-r--r--locale/locfile-lex.c533
-rw-r--r--locale/locfile-parse.c820
-rw-r--r--locale/messages.c76
-rw-r--r--locale/monetary.c132
-rw-r--r--locale/numeric.c62
-rw-r--r--locale/token.h54
-rw-r--r--posix/Makefile6
-rw-r--r--posix/regex.c5400
-rw-r--r--posix/regex.h495
-rw-r--r--regex.h1
31 files changed, 11096 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 4d55f3fa15..e0440179aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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*.
diff --git a/configure b/configure
index c543fb56fa..a543befe61 100755
--- a/configure
+++ b/configure
@@ -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] =