From b85697f61d8aeeaeb8b91d50ab2c668b7fcbbd8a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 18 Dec 1999 19:45:25 +0000 Subject: Update. 1999-12-17 Ulrich Drepper * string/bits/string2.h (__strtok_r_1c): Help gcc optimizing string access. * locale/programs/ld-collate.c: Implement handling of absolute ellipsis. Parsing of file and constructing the internal data structures should now be complete. (collate_finish): Start adding support to generate the data structures which are written out to the file. * intl/dcgettext.c: Rewrite to handle caching of previous results here instead of in the dcgettext macro. * intl/libintl.h (dcgettext): Don't define for systems using this glibc or systems with tsearch. * sysdeps/generic/mathdef.h: Protect definitions for math.h against double inclusion. * sysdeps/alpha/fpu/bits/mathdef.h: Likewise. * sysdeps/i386/fpu/bits/mathdef.h: Likewise. * sysdeps/m68k/fpu/bits/mathdef.h: Likewise. * sysdeps/powerpc/fpu/bits/mathdef.h: Likewise. * sysdeps/i386/fpu/libm-test-ulps: Add more deltas (are mobile PIIs that different?). 1999-12-17 Andreas Jaeger * rt/aio.h (struct aiocb64): Add member __next_prio to sync the struct with aiocb. * rt/Makefile (tests): Added tst-aio64. Added dependency rules for tst-aio64. * rt/tst-aio64.c: New file, copied from tst-aio.c and changed for 64bit tests. 1999-12-15 Thorsten Kukuk * sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c: Removed. * sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c: Removed. * sysdeps/unix/sysv/linux/bits/resource.h: Change RLIM_INFINITY back to old value (signed long). * sysdeps/unix/sysv/linux/i386/bits/resource.h: New, with unsigned long RLIM_INFINITY. * sysdeps/unix/sysv/linux/getrlimit.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/getrlimit.c: ... here. * sysdeps/unix/sysv/linux/getrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/getrlimit64.c: ... here. * sysdeps/unix/sysv/linux/oldgetrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c: ... here. * sysdeps/unix/sysv/linux/oldsetrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/oldsetrlimit64.c: ... here. * sysdeps/unix/sysv/linux/setrlimit.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/setrlimit.c: ... here. * sysdeps/unix/sysv/linux/setrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/setrlimit64.c: ... here. * sysdeps/unix/sysv/linux/sparc/bits/resource.h: New. * sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c: Removed. * sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c: Removed. 1999-12-17 Andreas Jaeger * elf/ldconfig.c: Add new option -l to manualy link shared libraries. (options): Added option. (parse_opt): Set option. (main): Handle option. (manual_link): New function. 1999-12-17 Thorsten Kukuk * string/bits/string2.h: Fix patch from 1999-12-07. 1999-12-16 Ulrich Drepper * sysdeps/generic/strsep.c: If delim string has only one character don't run over end of string. * locale/programs/ld-collate.c (insert_weights): Also update next pointer of last cursor element. (insert_value): Return nonzero value if nothing got inserted. (handle_ellipsis): Don't do anything if to-value cannot be inserted. 1999-12-10 Jakub Jelinek * stdlib/longlong.h (__sparc_v9__): Use %rDIGIT instead of %DIGIT where appropriate. 1999-12-10 Jakub Jelinek * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c (__sigaction): Copy sa_flags into kernel sigaction structure. 1999-12-14 Andreas Jaeger * string/tester.c (test_strsep): More tests for access beyond the final NUL. The first two tests come from PR libc/1486 by martinea@iro.umontreal.ca. 1999-12-14 Thorsten Kukuk * nis/ypclnt.c: Correct handling of cached client handles. (__xdr_ypresp_all): Call callback function for errors, too, like Solaris does. * nis/nss_compat/compat-grp.c: Make sure errno is always set correct. * nis/nss_compat/compat-initgroups.c: Likewise. * nis/nss_compat/compat-spwd.c: Likewise. * nis/nss_nis/nis-alias.c: Likewise. * nis/nss_nis/nis-ethers.c: Likewise. * nis/nss_nis/nis-grp.c: Likewise. * nis/nss_nis/nis-hosts.c: Likewise. * nis/nss_nis/nis-netgrp.c: Likewise. * nis/nss_nis/nis-publickey.c: Likewise. * nis/nss_nis/nis-service.c: Likewise. Also use services.byservicename Map if available, optimize query if name/port and protocol is known. --- intl/dcgettext.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 155 insertions(+), 20 deletions(-) (limited to 'intl/dcgettext.c') diff --git a/intl/dcgettext.c b/intl/dcgettext.c index d482da39b8..8e51970495 100644 --- a/intl/dcgettext.c +++ b/intl/dcgettext.c @@ -121,6 +121,9 @@ char *getcwd (); # ifndef HAVE_STPCPY static char *stpcpy PARAMS ((char *dest, const char *src)); # endif +# ifndef HAVE_MEMPCPY +static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); +# endif #endif /* Amount to increase buffer size by in each try. */ @@ -130,7 +133,7 @@ static char *stpcpy PARAMS ((char *dest, const char *src)); /* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define PATH_MAX but might cause redefinition warnings when sys/param.h is later included (as on MORE/BSD 4.3). */ -#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__)) +#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__) # include #endif @@ -138,16 +141,16 @@ static char *stpcpy PARAMS ((char *dest, const char *src)); # define _POSIX_PATH_MAX 255 #endif -#if !defined(PATH_MAX) && defined(_PC_PATH_MAX) +#if !defined PATH_MAX && defined _PC_PATH_MAX # define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) #endif /* Don't include sys/param.h if it already has been. */ -#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN) +#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN # include #endif -#if !defined(PATH_MAX) && defined(MAXPATHLEN) +#if !defined PATH_MAX && defined MAXPATHLEN # define PATH_MAX MAXPATHLEN #endif @@ -165,6 +168,68 @@ static char *stpcpy PARAMS ((char *dest, const char *src)); # define HAVE_LOCALE_NULL #endif +/* We want to allocate a string at the end of the struct. gcc makes + this easy. */ +#ifdef __GNUC__ +# define ZERO 0 +#else +# define ZERO 1 +#endif + +/* This is the type used for the search tree where known translations + are stored. */ +struct known_translation_t +{ + /* Domain in which to search. */ + char *domain; + + /* The category. */ + int category; + + /* State of the catalog counter at the point the string was found. */ + int counter; + + /* And finally the translation. */ + const char *translation; + + /* Pointer to the string in question. */ + char msgid[ZERO]; +}; + +/* Root of the search tree with known translations. We can use this + only if the system provides the `tsearch' function family. */ +#if defined HAVE_TSEARCH || defined _LIBC +# include + +static void *root; + +# ifdef _LIBC +# define tsearch __tsearch +# endif + +/* Function to compare two entries in the table of known translations. */ +static int +transcmp (const void *p1, const void *p2) +{ + struct known_translation_t *s1 = (struct known_translation_t *) p1; + struct known_translation_t *s2 = (struct known_translation_t *) p2; + int result; + + result = strcmp (s1->msgid, s2->msgid); + if (result == 0) + { + result = strcmp (s1->msgid, s2->msgid); + if (result == 0) + /* We compare the category last (though this is the cheapest + operation) since it is hopefully always the same (namely + LC_MESSAGES). */ + result = s1->category - s2->category; + } + + return result; +} +#endif + /* Name of the default domain used for gettext(3) prior any call to textdomain(3). The default value for this is "messages". */ const char _nl_default_default_domain[] = "messages"; @@ -268,12 +333,34 @@ DCGETTEXT (domainname, msgid, category) char *dirname, *xdomainname; char *single_locale; char *retval; - int saved_errno = errno; + int saved_errno; +#if defined HAVE_TSEARCH || defined _LIBC + struct known_translation_t *search; + struct known_translation_t **foundp; + size_t msgid_len = strlen (msgid) + 1; +#endif + size_t domainname_len; /* If no real MSGID is given return NULL. */ if (msgid == NULL) return NULL; +#if defined HAVE_TSEARCH || defined _LIBC + /* Try to find the translation among those which we found at some time. */ + search = (struct known_translation_t *) alloca (sizeof (*search) + + msgid_len); + memcpy (search->msgid, msgid, msgid_len); + search->domain = (char *) domainname; + search->category = category; + + foundp = (struct known_translation_t **) tfind (search, &root, transcmp); + if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr) + return (char *) (*foundp)->translation; +#endif + + /* Preserve the `errno' value. */ + saved_errno = errno; + /* See whether this is a SUID binary or not. */ DETERMINE_SECURE; @@ -340,12 +427,13 @@ DCGETTEXT (domainname, msgid, category) categoryname = category_to_name (category); categoryvalue = guess_category_value (category, categoryname); + domainname_len = strlen (domainname); xdomainname = (char *) alloca (strlen (categoryname) - + strlen (domainname) + 5); + + domainname_len + 5); ADD_BLOCK (block_list, xdomainname); - stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), - domainname), + stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), + domainname, domainname_len), ".mo"); /* Creating working area. */ @@ -422,6 +510,38 @@ DCGETTEXT (domainname, msgid, category) { FREE_BLOCKS (block_list); __set_errno (saved_errno); +#if defined HAVE_TSEARCH || defined _LIBC + if (foundp == NULL) + { + /* Create a new entry and add it to the search tree. */ + struct known_translation_t *newp; + + newp = (struct known_translation_t *) + malloc (sizeof (*newp) + msgid_len + + domainname_len + 1 - ZERO); + if (newp != NULL) + { + newp->domain = mempcpy (newp->msgid, msgid, msgid_len); + memcpy (newp->domain, domainname, domainname_len + 1); + newp->category = category; + newp->counter = _nl_msg_cat_cntr; + newp->translation = retval; + + /* Insert the entry in the search tree. */ + foundp = (struct known_translation_t **) + tsearch (newp, &root, transcmp); + if (&newp != foundp) + /* The insert failed. */ + free (newp); + } + } + else + { + /* We can update the existing entry. */ + (*foundp)->counter = _nl_msg_cat_cntr; + (*foundp)->translation = retval; + } +#endif return retval; } } @@ -571,12 +691,13 @@ _nl_find_msg (domain_file, msgid) return NULL; if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len - && strcmp (msgid, - domain->data + W (domain->must_swap, - domain->orig_tab[nstr - 1].offset)) - == 0) - return (char *) domain->data - + W (domain->must_swap, domain->trans_tab[nstr - 1].offset); + && (strcmp (msgid, + domain->data + W (domain->must_swap, + domain->orig_tab[nstr - 1].offset)) + == 0)) + return ((char *) domain->data + + W (domain->must_swap, + domain->trans_tab[nstr - 1].offset)); } /* NOTREACHED */ } @@ -590,9 +711,9 @@ _nl_find_msg (domain_file, msgid) int cmp_val; act = (bottom + top) / 2; - cmp_val = strcmp (msgid, domain->data - + W (domain->must_swap, - domain->orig_tab[act].offset)); + cmp_val = strcmp (msgid, (domain->data + + W (domain->must_swap, + domain->orig_tab[act].offset))); if (cmp_val < 0) top = act; else if (cmp_val > 0) @@ -602,9 +723,9 @@ _nl_find_msg (domain_file, msgid) } /* If an translation is found return this. */ - return bottom >= top ? NULL : (char *) domain->data - + W (domain->must_swap, - domain->trans_tab[act].offset); + return bottom >= top ? NULL : ((char *) domain->data + + W (domain->must_swap, + domain->trans_tab[act].offset)); } @@ -728,6 +849,17 @@ stpcpy (dest, src) } #endif +#if !_LIBC && !HAVE_MEMPCPY +static void * +mempcpy (dest, src, n) + void *dest; + const void *src; + size_t n; +{ + return (void *) ((char *) memcpy (dst, src, n) + n); +} +#endif + #ifdef _LIBC /* If we want to free all resources we have to do some work at @@ -748,6 +880,9 @@ free_mem (void) if (_nl_current_default_domain != _nl_default_default_domain) /* Yes, again a pointer comparison. */ free ((char *) _nl_current_default_domain); + + /* Remove the search tree with the know translations. */ + __tdestroy (root, free); } text_set_element (__libc_subfreeres, free_mem); -- cgit v1.2.3