diff options
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/Makefile | 6 | ||||
-rw-r--r-- | stdlib/fmtmsg.c | 358 | ||||
-rw-r--r-- | stdlib/fmtmsg.h | 107 | ||||
-rw-r--r-- | stdlib/stdlib.h | 47 | ||||
-rw-r--r-- | stdlib/strtod.c | 107 | ||||
-rw-r--r-- | stdlib/strtod_l.c | 25 | ||||
-rw-r--r-- | stdlib/strtof.c | 6 | ||||
-rw-r--r-- | stdlib/strtof_l.c | 25 | ||||
-rw-r--r-- | stdlib/strtol.c | 121 | ||||
-rw-r--r-- | stdlib/strtol_l.c | 26 | ||||
-rw-r--r-- | stdlib/strtold.c | 6 | ||||
-rw-r--r-- | stdlib/strtold_l.c | 26 | ||||
-rw-r--r-- | stdlib/strtoll_l.c | 26 | ||||
-rw-r--r-- | stdlib/strtoul_l.c | 26 | ||||
-rw-r--r-- | stdlib/strtoull_l.c | 26 |
15 files changed, 878 insertions, 60 deletions
diff --git a/stdlib/Makefile b/stdlib/Makefile index 7e70e5a1bb..b5a38bd965 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -21,7 +21,7 @@ # subdir := stdlib -headers := stdlib.h alloca.h monetary.h inttypes.h +headers := stdlib.h alloca.h monetary.h inttypes.h fmtmsg.h routines := \ atof atoi atol atoll \ @@ -39,10 +39,12 @@ routines := \ srand48_r seed48_r lcong48_r \ drand48-iter \ strtol strtoul strtoll strtoull \ + strtol_l strtoul_l strtoll_l strtoull_l \ strtof strtod strtold \ + strtof_l strtod_l strtold_l \ system canonicalize \ a64l l64a \ - rpmatch strfmon strfmon_l getsubopt xpg_basename + rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg distribute := exit.h grouping.h abort-instr.h tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ diff --git a/stdlib/fmtmsg.c b/stdlib/fmtmsg.c new file mode 100644 index 0000000000..9ce492bdc4 --- /dev/null +++ b/stdlib/fmtmsg.c @@ -0,0 +1,358 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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 <fmtmsg.h> +#include <libc-lock.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/syslog.h> + + +/* We have global data, protect the modification. */ +__libc_lock_define_initialized (static, lock) + + +enum +{ + label_mask = 0x01, + severity_mask = 0x02, + text_mask = 0x04, + action_mask = 0x08, + tag_mask = 0x10, + all_mask = label_mask | severity_mask | text_mask | action_mask | tag_mask +}; + +static struct +{ + const char *name; + size_t len; +} keywords[] = + { + { "label", 5 }, + { "severity", 8 }, + { "text", 4 }, + { "action", 6}, + { "tag", 3 } + }; +#define NKEYWORDS (sizeof( keywords) / sizeof (keywords[0])) + + +struct severity_info +{ + int severity; + const char *string; + struct severity_info *next; +}; + + +/* List of known severities. */ +static const struct severity_info nosev = +{ + MM_NOSEV, "", NULL +}; +static const struct severity_info haltsev = +{ + MM_HALT, "HALT", (struct severity_info *) &nosev +}; +static const struct severity_info errorsev = +{ + MM_ERROR, "ERROR", (struct severity_info *) &haltsev +}; +static const struct severity_info warningsev = +{ + MM_WARNING, "WARNING", (struct severity_info *) &errorsev +}; +static const struct severity_info infosev = +{ + MM_INFO, "INFO", (struct severity_info *) &warningsev +}; + +/* Start of the list. */ +static struct severity_info *severity_list = (struct severity_info *) &infosev; + + +/* Prototypes for local functions. */ +static int internal_addseverity (int severity, const char *string); + + +int +fmtmsg (long int classification, const char *label, int severity, + const char *text, const char *action, const char *tag) +{ + static int print = -1; + int result = MM_OK; + struct severity_info *severity_rec; + + if (print == -1) + { + __libc_lock_lock (lock); + + if (print == -1) + { + const char *msgverb_var = getenv ("MSGVERB"); + const char *sevlevel_var = getenv ("SEV_LEVEL"); + + if (msgverb_var != NULL && msgverb_var[0] != '\0') + { + /* Using this extra variable allows us to work without + locking. */ + print = 0; + + do + { + size_t cnt; + + for (cnt = 0; cnt < NKEYWORDS; ++cnt) + if (memcmp (msgverb_var, + keywords[cnt].name, keywords[cnt].len) == 0 + && (msgverb_var[keywords[cnt].len] == ':' + || msgverb_var[keywords[cnt].len] == '\0')) + break; + + if (cnt < NKEYWORDS) + { + print |= 1 << cnt; + + msgverb_var += keywords[cnt].len; + if (msgverb_var[0] == ':') + ++msgverb_var; + } + else + { + /* We found an illegal keyword in the + environment variable. The specifications say + that we print all fields. */ + print = all_mask; + break; + } + } + while (msgverb_var[0] != '\0'); + } + else + print = all_mask; + + + if (sevlevel_var != NULL) + while (sevlevel_var[0] != '\0') + { + const char *end = strchr (sevlevel_var, ':'); + int level; + + if (end == NULL) + end = strchr (sevlevel_var, '\0'); + + /* First field: keyword. This is not used here but it + must be present. */ + while (sevlevel_var < end) + if (*sevlevel_var++ == ',') + break; + + if (sevlevel_var < end) + { + /* Second field: severity level, a number. */ + char *cp; + + level = strtol (sevlevel_var, &cp, 0); + if (cp != sevlevel_var && cp < end && *cp++ == ',' + && level > MM_INFO) + { + const char *new_string; + + new_string = __strndup (cp, end - cp); + + if (new_string != NULL + && (internal_addseverity (level, new_string) + != MM_OK)) + free ((char *) new_string); + } + } + + sevlevel_var = end + (*end == ':' ? 1 : 0); + } + } + + __libc_lock_unlock (lock); + } + + /* Start the real work. First check whether the input is ok. */ + if (label != MM_NULLLBL) + { + /* Must be two fields, separated by a colon. */ + const char *cp = strchr (label, ':'); + if (cp == NULL) + return MM_NOTOK; + + /* The first field must not contain more then 10 bytes. */ + if (cp - label > 10 + /* The second field must not have more then 14 bytes. */ + || strlen (cp + 1) > 14) + return MM_NOTOK; + } + + for (severity_rec = severity_list; severity_rec != NULL; + severity_rec = severity_rec->next) + if (severity == severity_rec->severity) + /* Bingo. */ + break; + + /* If we don't know anything about the severity level return an error. */ + if (severity_rec == NULL) + return MM_NOTOK; + + + /* Now we can print. */ + if (classification & MM_PRINT) + { + int do_label = (print & label_mask) && label != MM_NULLLBL; + int do_severity = (print & severity_mask) && severity != MM_NULLSEV; + int do_text = (print & text_mask) && text != MM_NULLTXT; + int do_action = (print & action_mask) && action != MM_NULLACT; + int do_tag = (print & tag_mask) && tag != MM_NULLTAG; + + if (fprintf (stderr, "%s%s%s%s%s%s%s%s%s%s\n", + do_label ? label : "", + do_label && (do_severity | do_text) ? ": " : "", + do_severity ? severity_rec->string : "", + do_severity && do_text ? ": " : "", + do_text ? text : "", + (do_label | do_severity | do_text) && (do_action | do_tag) + ? "\n" : "", + do_action ? "TO FIX: " : "", + do_action ? action : "", + do_action && do_tag ? " " : "", + do_tag ? tag : "") == EOF) + /* Oh, oh. An error occured during the output. */ + result = MM_NOMSG; + } + + if (classification & MM_CONSOLE) + { + int do_label = label != MM_NULLLBL; + int do_severity = severity != MM_NULLSEV; + int do_text = text != MM_NULLTXT; + int do_action = action != MM_NULLACT; + int do_tag = tag != MM_NULLTAG; + + syslog (LOG_ERR, "%s%s%s%s%s%s%s%s%s%s\n", + do_label ? label : "", + do_label && (do_severity | do_text) ? ": " : "", + do_severity ? severity_rec->string : "", + do_severity && do_text ? ": " : "", + do_text ? text : "", + (do_label | do_severity | do_text) && (do_action | do_tag) + ? "\n" : "", + do_action ? "TO FIX: " : "", + do_action ? action : "", + do_action && do_tag ? " " : "", + do_tag ? tag : ""); + } + + return result; +} + + +/* Add the new entry to the list. */ +static int +internal_addseverity (int severity, const char *string) +{ + struct severity_info *runp, *lastp; + int result = MM_OK; + + /* First see if there is already a record for the severity level. */ + for (runp = severity_list, lastp = NULL; runp != NULL; runp = runp-> next) + if (runp->severity == severity) + break; + else + lastp = runp; + + if (runp != NULL) + { + /* Release old string. */ + free ((char *) runp->string); + + if (string != NULL) + /* Change the string. */ + runp->string = string; + else + { + /* Remove the severity class. */ + if (lastp == NULL) + severity_list = runp->next; + else + lastp->next = runp->next; + + free (runp); + } + } + else if (string != NULL) + { + runp = malloc (sizeof (*runp)); + if (runp == NULL) + result = MM_NOTOK; + else + { + runp->severity = severity; + runp->next = severity_list; + runp->string = string; + severity_list = runp; + } + } + else + /* We tried to remove a non-existing severity class. */ + result = MM_NOTOK; + + return result; +} + + +/* Add new severity level or remove old one. */ +int +addseverity (int severity, const char *string) +{ + int result; + const char *new_string; + + if (string == NULL) + /* We want to remove the severity class. */ + new_string = NULL; + else + { + new_string = __strdup (string); + + if (new_string == NULL || severity <= MM_INFO) + /* Allocation failed or illegal value. */ + return MM_NOTOK; + } + + /* Protect the global data. */ + __libc_lock_lock (lock); + + /* Do the real work. */ + result = internal_addseverity (severity, string); + + if (result != MM_OK) + /* Free the allocated string. */ + free ((char *) new_string); + + /* Release the lock. */ + __libc_lock_unlock (lock); + + return result; +} diff --git a/stdlib/fmtmsg.h b/stdlib/fmtmsg.h new file mode 100644 index 0000000000..07fa98aa43 --- /dev/null +++ b/stdlib/fmtmsg.h @@ -0,0 +1,107 @@ +/* Message display handling. + Copyright (C) 1997 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 __FMTMSG_H + +#define __FMTMSG_H 1 +#include <features.h> + +#define __need_NULL +#include <stddef.h> + + +__BEGIN_DECLS + +/* Values to control `fmtmsg' function. */ +enum +{ + MM_HARD = 0x001, /* Source of the condition is hardware. */ +#define MM_HARD MM_HARD + MM_SOFT = 0x002, /* Source of the condition is software. */ +#define MM_SOFT MM_SOFT + MM_FIRM = 0x004, /* Source of the condition is firmware. */ +#define MM_FIRM MM_FIRM + MM_APPL = 0x008, /* Condition detected by application. */ +#define MM_APPL MM_APPL + MM_UTIL = 0x010, /* Condition detected by utility. */ +#define MM_UTIL MM_UTIL + MM_OPSYS = 0x020, /* Condition detected by operating system. */ +#define MM_OPSYS MM_OPSYS + MM_RECOVER = 0x040, /* Recoverable error. */ +#define MM_RECOVER MM_RECOVER + MM_NRECOV = 0x080, /* Non-recoverable error. */ +#define MM_NRECOV MM_NRECOV + MM_PRINT = 0x100, /* Display message in standard error. */ +#define MM_PRINT MM_PRINT + MM_CONSOLE = 0x200 /* Display message on system console. */ +#define MM_CONSOLE MM_CONSOLE +}; + +/* Values to be for SEVERITY parameter of `fmtmsg'. */ +enum +{ + MM_NOSEV = 0, /* No severity level provided for the message. */ +#define MM_NOSEV MM_NOSEV + MM_HALT, /* Error causing application to halt. */ +#define MM_HALT MM_HALT + MM_ERROR, /* Application has encountered a non-fatal fault. */ +#define MM_ERROR MM_ERROR + MM_WARNING, /* Application has detected unusual non-error + condition. */ +#define MM_WARNING MM_WARNING + MM_INFO /* Informative message. */ +#define MM_INFO MM_INFO +}; + + +/* Macros which can be used as null values for the arguments of `fmtmsg'. */ +#define MM_NULLLBL NULL +#define MM_NULLSEV 0 +#define MM_NULLMC ((long int) 0) +#define MM_NULLTXT NULL +#define MM_NULLACT NULL +#define MM_NULLTAG NULL + + +/* Possible return values of `fmtmsg'. */ +enum +{ + MM_NOTOK = -1, +#define MM_NOTOK MM_NOTOK + MM_OK = 0, +#define MM_OK MM_OK + MM_NOMSG = 1, +#define MM_NOMSG MM_NOMSG + MM_NOCON = 4 +#define MM_NOCON MM_NOCON +}; + + +/* Print message with given CLASSIFICATION, LABEL, SEVERITY, TEXT, ACTION + and TAG to console or standard error. */ +extern int fmtmsg __P ((long int __classification, __const char *__label, + int __severity, __const char *__text, + __const char *__action, __const char *__tag)); + +/* Add or remove severity level. */ +extern int addseverity __P ((int __severity, __const char *__string)); + +__END_DECLS + +#endif /* fmtmsg.h */ diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h index 98ed88986b..40c24eb8f0 100644 --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h @@ -128,6 +128,53 @@ extern unsigned long long int strtoull __P ((__const char *__restrict __nptr, #endif /* ISO C 9X or GCC and use MISC. */ +#ifdef __USE_GNU +/* The concept of one static locale per category is not very well + thought out. Many applications will need to process its data using + information from several different locales. Another application is + the implementation of the internationalization handling in the + upcoming ISO C++ standard library. To support this another set of + the functions using locale data exist which have an additional + argument. + + Attention: all these functions are *not* standardized in any form. + This is a proof-of-concept implementation. */ + +/* Structure for reentrant locale using functions. This is an + (almost) opaque type for the user level programs. */ +# include <xlocale.h> + +/* Special versions of the functions above which take the locale to + use as an additional parameter. */ +extern long int __strtol_l __P ((__const char *__restrict __nptr, + char **__restrict __endptr, int __base, + __locale_t __loc)); + +extern unsigned long int __strtoul_l __P ((__const char *__restrict __nptr, + char **__restrict __endptr, + int __base, __locale_t __loc)); + +extern long long int __strtoll_l __P ((__const char *__restrict __nptr, + char **__restrict __endptr, int __base, + __locale_t __loc)); + +extern unsigned long long int __strtoull_l __P ((__const char *__restrict + __nptr, + char **__restrict __endptr, + int __base, + __locale_t __loc)); + +extern double __strtod_l __P ((__const char *__restrict __nptr, + char **__restrict __endptr, __locale_t __loc)); + +extern float __strtof_l __P ((__const char *__restrict __nptr, + char **__restrict __endptr, __locale_t __loc)); + +extern __long_double_t __strtold_l __P ((__const char *__restrict __nptr, + char **__restrict __endptr, + __locale_t __loc)); +#endif /* GNU */ + /* The internal entry points for `strtoX' take an extra flag argument saying whether or not to parse locale-dependent number grouping. */ diff --git a/stdlib/strtod.c b/stdlib/strtod.c index e0c9b08031..5ddb956081 100644 --- a/stdlib/strtod.c +++ b/stdlib/strtod.c @@ -25,9 +25,17 @@ # define FLOAT double # define FLT DBL # ifdef USE_WIDE_CHAR -# define STRTOF wcstod +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define STRTOF __wcstod_l +# else +# define STRTOF wcstod +# endif # else -# define STRTOF strtod +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define STRTOF __strtod_l +# else +# define STRTOF strtod +# endif # endif # define MPN2FLOAT __mpn_construct_double # define FLOAT_HUGE_VAL HUGE_VAL @@ -40,30 +48,6 @@ u.ieee.mantissa1 = (mant) & 0xffffffff; \ } while (0) #endif - -#ifdef USE_WIDE_CHAR -# include <wctype.h> -# include <wchar.h> -# define STRING_TYPE wchar_t -# define CHAR_TYPE wint_t -# define L_(Ch) L##Ch -# define ISSPACE(Ch) iswspace (Ch) -# define ISDIGIT(Ch) iswdigit (Ch) -# define ISXDIGIT(Ch) iswxdigit (Ch) -# define TOLOWER(Ch) towlower (Ch) -# define STRNCASECMP(S1, S2, N) __wcsncasecmp ((S1), (S2), (N)) -# define STRTOULL(S, E, B) wcstoull ((S), (E), (B)) -#else -# define STRING_TYPE char -# define CHAR_TYPE char -# define L_(Ch) Ch -# define ISSPACE(Ch) isspace (Ch) -# define ISDIGIT(Ch) isdigit (Ch) -# define ISXDIGIT(Ch) isxdigit (Ch) -# define TOLOWER(Ch) tolower (Ch) -# define STRNCASECMP(S1, S2, N) __strncasecmp ((S1), (S2), (N)) -# define STRTOULL(S, E, B) strtoull ((S), (E), (B)) -#endif /* End of configuration part. */ #include <ctype.h> @@ -88,6 +72,65 @@ #include <assert.h> +/* We use this code also for the extended locale handling where the + function gets as an additional argument the locale which has to be + used. To access the values we have to redefine the _NL_CURRENT + macro. */ +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# undef _NL_CURRENT +# define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +# define LOCALE_PARAM , loc +# define LOCALE_PARAM_DECL __locale_t loc; +#else +# define LOCALE_PARAM +# define LOCALE_PARAM_DECL +#endif + + +#ifdef USE_WIDE_CHAR +# include <wctype.h> +# include <wchar.h> +# define STRING_TYPE wchar_t +# define CHAR_TYPE wint_t +# define L_(Ch) L##Ch +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define ISSPACE(Ch) __iswspace_l ((Ch), loc) +# define ISDIGIT(Ch) __iswdigit_l ((Ch), loc) +# define ISXDIGIT(Ch) __iswxdigit_l ((Ch), loc) +# define TOLOWER(Ch) __towlower_l ((Ch), loc) +# define STRNCASECMP(S1, S2, N) __wcsncasecmp_l ((S1), (S2), (N), loc) +# define STRTOULL(S, E, B) __wcstoull_l ((S), (E), (B), loc) +# else +# define ISSPACE(Ch) iswspace (Ch) +# define ISDIGIT(Ch) iswdigit (Ch) +# define ISXDIGIT(Ch) iswxdigit (Ch) +# define TOLOWER(Ch) towlower (Ch) +# define STRNCASECMP(S1, S2, N) __wcsncasecmp ((S1), (S2), (N)) +# define STRTOULL(S, E, B) wcstoull ((S), (E), (B)) +# endif +#else +# define STRING_TYPE char +# define CHAR_TYPE char +# define L_(Ch) Ch +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define ISSPACE(Ch) __isspace_l ((Ch), loc) +# define ISDIGIT(Ch) __isdigit_l ((Ch), loc) +# define ISXDIGIT(Ch) __isxdigit_l ((Ch), loc) +# define TOLOWER(Ch) __tolower_l ((Ch), loc) +# define STRNCASECMP(S1, S2, N) __strncasecmp_l ((S1), (S2), (N), loc) +# define STRTOULL(S, E, B) __strtoull_l ((S), (E), (B), loc) +# else +# define ISSPACE(Ch) isspace (Ch) +# define ISDIGIT(Ch) isdigit (Ch) +# define ISXDIGIT(Ch) isxdigit (Ch) +# define TOLOWER(Ch) tolower (Ch) +# define STRNCASECMP(S1, S2, N) __strncasecmp ((S1), (S2), (N)) +# define STRTOULL(S, E, B) strtoull ((S), (E), (B)) +# endif +#endif + + /* Constants we need from float.h; select the set for the FLOAT precision. */ #define MANT_DIG PASTE(FLT,_MANT_DIG) #define DIG PASTE(FLT,_DIG) @@ -354,10 +397,11 @@ __mpn_lshift_1 (mp_limb_t *ptr, mp_size_t size, unsigned int count, return 0.0. If the number is too big to be represented, set `errno' to ERANGE and return HUGE_VAL with the appropriate sign. */ FLOAT -INTERNAL (STRTOF) (nptr, endptr, group) +INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM) const STRING_TYPE *nptr; STRING_TYPE **endptr; int group; + LOCALE_PARAM_DECL { int negative; /* The sign of the number. */ MPN_VAR (num); /* MP representation of the number. */ @@ -400,6 +444,10 @@ INTERNAL (STRTOF) (nptr, endptr, group) in the format described in <locale.h>. */ const char *grouping; +#ifdef USE_IN_EXTENDED_LOCALE_MODEL + struct locale_data *current = loc->__locales[LC_NUMERIC]; +#endif + if (group) { grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); @@ -1352,9 +1400,10 @@ FLOAT #ifdef weak_function weak_function #endif -STRTOF (nptr, endptr) +STRTOF (nptr, endptr LOCALE_PARAM) const STRING_TYPE *nptr; STRING_TYPE **endptr; + LOCALE_PARAM_DECL { - return INTERNAL (STRTOF) (nptr, endptr, 0); + return INTERNAL (STRTOF) (nptr, endptr, 0 LOCALE_PARAM); } diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c new file mode 100644 index 0000000000..c2f08233a1 --- /dev/null +++ b/stdlib/strtod_l.c @@ -0,0 +1,25 @@ +/* Convert string representing a number to float value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern double ____strtod_l_internal (const char *, char **, int, __locale_t); + +#include <strtod.c> diff --git a/stdlib/strtof.c b/stdlib/strtof.c index 026b5eead3..9d070279f8 100644 --- a/stdlib/strtof.c +++ b/stdlib/strtof.c @@ -3,7 +3,11 @@ #define FLOAT float #define FLT FLT -#define STRTOF strtof +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define STRTOF __strtof_l +#else +# define STRTOF strtof +#endif #define MPN2FLOAT __mpn_construct_float #define FLOAT_HUGE_VAL HUGE_VALF #define SET_MANTISSA(flt, mant) \ diff --git a/stdlib/strtof_l.c b/stdlib/strtof_l.c new file mode 100644 index 0000000000..262c5e063b --- /dev/null +++ b/stdlib/strtof_l.c @@ -0,0 +1,25 @@ +/* Convert string representing a number to float value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern float ____strtof_l_internal (const char *, char **, int, __locale_t); + +#include <strtof.c> diff --git a/stdlib/strtol.c b/stdlib/strtol.c index 6ec096daf6..97ad23453b 100644 --- a/stdlib/strtol.c +++ b/stdlib/strtol.c @@ -64,30 +64,62 @@ extern int errno; #endif /* Determine the name. */ -#if UNSIGNED -# ifdef USE_WIDE_CHAR -# ifdef QUAD -# define strtol wcstoull +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# if UNSIGNED +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol __wcstoull_l +# else +# define strtol __wcstoul_l +# endif # else -# define strtol wcstoul +# ifdef QUAD +# define strtol __strtoull_l +# else +# define strtol __strtoul_l +# endif # endif # else -# ifdef QUAD -# define strtol strtoull +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol __wcstoll_l +# else +# define strtol __wcstol_l +# endif # else -# define strtol strtoul +# ifdef QUAD +# define strtol __strtoll_l +# else +# define strtol __strtol_l +# endif # endif # endif #else -# ifdef USE_WIDE_CHAR -# ifdef QUAD -# define strtol wcstoll +# if UNSIGNED +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol wcstoull +# else +# define strtol wcstoul +# endif # else -# define strtol wcstol +# ifdef QUAD +# define strtol strtoull +# else +# define strtol strtoul +# endif # endif # else -# ifdef QUAD -# define strtol strtoll +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol wcstoll +# else +# define strtol wcstol +# endif +# else +# ifdef QUAD +# define strtol strtoll +# endif # endif # endif #endif @@ -119,22 +151,51 @@ extern int errno; #endif #endif + +/* We use this code also for the extended locale handling where the + function gets as an additional argument the locale which has to be + used. To access the values we have to redefine the _NL_CURRENT + macro. */ +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# undef _NL_CURRENT +# define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +# define LOCALE_PARAM , loc +# define LOCALE_PARAM_DECL __locale_t loc; +#else +# define LOCALE_PARAM +# define LOCALE_PARAM_DECL +#endif + + #ifdef USE_WIDE_CHAR # include <wchar.h> # include <wctype.h> # define L_(Ch) L##Ch # define UCHAR_TYPE wint_t # define STRING_TYPE wchar_t -# define ISSPACE(Ch) iswspace (Ch) -# define ISALPHA(Ch) iswalpha (Ch) -# define TOUPPER(Ch) towupper (Ch) -#else -# define L_(Ch) Ch -# define UCHAR_TYPE unsigned char -# define STRING_TYPE char -# define ISSPACE(Ch) isspace (Ch) -# define ISALPHA(Ch) isalpha (Ch) -# define TOUPPER(Ch) toupper (Ch) +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define ISSPACE(Ch) __iswspace_l ((Ch), loc) +# define ISALPHA(Ch) __iswalpha_l ((Ch), loc) +# define TOUPPER(Ch) __towupper_l ((Ch), loc) +# else +# define ISSPACE(Ch) iswspace (Ch) +# define ISALPHA(Ch) iswalpha (Ch) +# define TOUPPER(Ch) towupper (Ch) +# endif +# else +# define L_(Ch) Ch +# define UCHAR_TYPE unsigned char +# define STRING_TYPE char +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define ISSPACE(Ch) __isspace_l ((Ch), loc) +# define ISALPHA(Ch) __isalpha_l ((Ch), loc) +# define TOUPPER(Ch) __toupper_l ((Ch), loc) +# else +# define ISSPACE(Ch) isspace (Ch) +# define ISALPHA(Ch) isalpha (Ch) +# define TOUPPER(Ch) toupper (Ch) +# endif #endif #ifdef __STDC__ @@ -151,6 +212,7 @@ extern int errno; #endif + /* Convert NPTR to an `unsigned long int' or `long int' in base BASE. If BASE is 0 the base is determined by the presence of a leading zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. @@ -159,11 +221,12 @@ extern int errno; one converted is stored in *ENDPTR. */ INT -INTERNAL (strtol) (nptr, endptr, base, group) +INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM) const STRING_TYPE *nptr; STRING_TYPE **endptr; int base; int group; + LOCALE_PARAM_DECL { int negative; register unsigned LONG int cutoff; @@ -175,6 +238,9 @@ INTERNAL (strtol) (nptr, endptr, base, group) int overflow; #ifdef USE_NUMBER_GROUPING +# ifdef USE_IN_EXTENDED_LOCALE_MODEL + struct locale_data *current = loc->__locales[LC_NUMERIC]; +# endif /* The thousands character of the current locale. */ wchar_t thousands; /* The numeric grouping specification of the current locale, @@ -362,10 +428,11 @@ INT #ifdef weak_function weak_function #endif -strtol (nptr, endptr, base) +strtol (nptr, endptr, base LOCALE_PARAM) const STRING_TYPE *nptr; STRING_TYPE **endptr; int base; + LOCALE_PARAM_DECL { - return INTERNAL (strtol) (nptr, endptr, base, 0); + return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM); } diff --git a/stdlib/strtol_l.c b/stdlib/strtol_l.c new file mode 100644 index 0000000000..38f7555de2 --- /dev/null +++ b/stdlib/strtol_l.c @@ -0,0 +1,26 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern long int ____strtol_l_internal (const char *, char **, int, int, + __locale_t); + +#include <strtol.c> diff --git a/stdlib/strtold.c b/stdlib/strtold.c index 9747232ef2..32e7e90943 100644 --- a/stdlib/strtold.c +++ b/stdlib/strtold.c @@ -3,7 +3,11 @@ #define FLOAT long double #define FLT LDBL -#define STRTOF strtold +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define STRTOF __strtold_l +#else +# define STRTOF strtold +#endif #define MPN2FLOAT __mpn_construct_long_double #define FLOAT_HUGE_VAL HUGE_VALL #define SET_MANTISSA(flt, mant) \ diff --git a/stdlib/strtold_l.c b/stdlib/strtold_l.c new file mode 100644 index 0000000000..fb36ef7164 --- /dev/null +++ b/stdlib/strtold_l.c @@ -0,0 +1,26 @@ +/* Convert string representing a number to float value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern long double ____strtold_l_internal (const char *, char **, int, + __locale_t); + +#include <strtold.c> diff --git a/stdlib/strtoll_l.c b/stdlib/strtoll_l.c new file mode 100644 index 0000000000..7611887a9d --- /dev/null +++ b/stdlib/strtoll_l.c @@ -0,0 +1,26 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern long long int ____strtoll_l_internal (const char *, char **, int, int, + __locale_t); + +#include <strtoll.c> diff --git a/stdlib/strtoul_l.c b/stdlib/strtoul_l.c new file mode 100644 index 0000000000..c26e234769 --- /dev/null +++ b/stdlib/strtoul_l.c @@ -0,0 +1,26 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern unsigned long int ____strtoul_l_internal (const char *, char **, int, + int, __locale_t); + +#include <strtoul.c> diff --git a/stdlib/strtoull_l.c b/stdlib/strtoull_l.c new file mode 100644 index 0000000000..2d8058fac3 --- /dev/null +++ b/stdlib/strtoull_l.c @@ -0,0 +1,26 @@ +/* Convert string representing a number to integer value, using given locale. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + 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. */ + +#define USE_IN_EXTENDED_LOCALE_MODEL 1 + +extern unsigned long long int ____strtoull_l_internal (const char *, char **, + int, int, __locale_t); + +#include <strtoull.c> |