diff options
author | Bruno Haible <bruno@clisp.org> | 2019-12-18 10:49:44 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2019-12-18 10:49:44 +0100 |
commit | e144ded4615b8d7a77bd4f5a3f8bc309f46a78a5 (patch) | |
tree | a01471ada7762060fdd34e91ddb9796b8f3f4c64 /lib/setlocale_null.c | |
parent | 2d1b7501b00dce53481b58b3808313f264c720ea (diff) | |
download | gnulib-e144ded4615b8d7a77bd4f5a3f8bc309f46a78a5.tar.gz |
setlocale-null: Handle NULL result from setlocale.
* lib/locale.in.h (setlocale_null): Document EINVAL return value.
* lib/setlocale_null.c (setlocale_null_unlocked): Handle NULL result
from setlocale or _wsetlocale.
Diffstat (limited to 'lib/setlocale_null.c')
-rw-r--r-- | lib/setlocale_null.c | 105 |
1 files changed, 78 insertions, 27 deletions
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c index 350eca7299..8072a4560e 100644 --- a/lib/setlocale_null.c +++ b/lib/setlocale_null.c @@ -63,52 +63,103 @@ setlocale_null_unlocked (int category, char *buf, size_t bufsize) on _wsetlocale() and uses malloc() for the result. We are better off using _wsetlocale() directly. */ const wchar_t *result = _wsetlocale (category, NULL); - size_t length = wcslen (result); - if (length < bufsize) - { - size_t i; - - /* Convert wchar_t[] -> char[], assuming plain ASCII. */ - for (i = 0; i <= length; i++) - buf[i] = result[i]; - return 0; + if (result == NULL) + { + /* CATEGORY is invalid. */ + if (bufsize > 0) + /* Return an empty string in BUF. + This is a convenience for callers that don't want to write explicit + code for handling EINVAL. */ + buf[0] = '\0'; + return EINVAL; } else { - if (bufsize > 0) + size_t length = wcslen (result); + if (length < bufsize) { - /* Return a truncated result in BUF. - This is a convenience for callers that don't want to write - explicit code for handling ERANGE. */ size_t i; /* Convert wchar_t[] -> char[], assuming plain ASCII. */ - for (i = 0; i < bufsize; i++) + for (i = 0; i <= length; i++) buf[i] = result[i]; - buf[bufsize - 1] = '\0'; + + return 0; + } + else + { + if (bufsize > 0) + { + /* Return a truncated result in BUF. + This is a convenience for callers that don't want to write + explicit code for handling ERANGE. */ + size_t i; + + /* Convert wchar_t[] -> char[], assuming plain ASCII. */ + for (i = 0; i < bufsize; i++) + buf[i] = result[i]; + buf[bufsize - 1] = '\0'; + } + return ERANGE; } - return ERANGE; } #else const char *result = setlocale (category, NULL); - size_t length = strlen (result); - if (length < bufsize) + +# ifdef __ANDROID__ + if (result == NULL) + switch (category) + { + case LC_CTYPE: + case LC_NUMERIC: + case LC_TIME: + case LC_COLLATE: + case LC_MONETARY: + case LC_MESSAGES: + case LC_ALL: + case LC_PAPER: + case LC_NAME: + case LC_ADDRESS: + case LC_TELEPHONE: + case LC_MEASUREMENT: + result = "C"; + break; + default: + break; + } +# endif + + if (result == NULL) { - memcpy (buf, result, length + 1); - return 0; + /* CATEGORY is invalid. */ + if (bufsize > 0) + /* Return an empty string in BUF. + This is a convenience for callers that don't want to write explicit + code for handling EINVAL. */ + buf[0] = '\0'; + return EINVAL; } else { - if (bufsize > 0) + size_t length = strlen (result); + if (length < bufsize) + { + memcpy (buf, result, length + 1); + return 0; + } + else { - /* Return a truncated result in BUF. - This is a convenience for callers that don't want to write - explicit code for handling ERANGE. */ - memcpy (buf, result, bufsize - 1); - buf[bufsize - 1] = '\0'; + if (bufsize > 0) + { + /* Return a truncated result in BUF. + This is a convenience for callers that don't want to write + explicit code for handling ERANGE. */ + memcpy (buf, result, bufsize - 1); + buf[bufsize - 1] = '\0'; + } + return ERANGE; } - return ERANGE; } #endif } |