/* Fake setlocale - platform independent, for testing purposes. Copyright (C) 2001-2002, 2015-2016 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include /* Return string representation of locale CATEGORY. */ static const char * category_to_name (int category) { const char *retval; switch (category) { #ifdef LC_COLLATE case LC_COLLATE: retval = "LC_COLLATE"; break; #endif #ifdef LC_CTYPE case LC_CTYPE: retval = "LC_CTYPE"; break; #endif #ifdef LC_MONETARY case LC_MONETARY: retval = "LC_MONETARY"; break; #endif #ifdef LC_NUMERIC case LC_NUMERIC: retval = "LC_NUMERIC"; break; #endif #ifdef LC_TIME case LC_TIME: retval = "LC_TIME"; break; #endif #ifdef LC_MESSAGES case LC_MESSAGES: retval = "LC_MESSAGES"; break; #endif #ifdef LC_RESPONSE case LC_RESPONSE: retval = "LC_RESPONSE"; break; #endif #ifdef LC_ALL case LC_ALL: /* This might not make sense but is perhaps better than any other value. */ retval = "LC_ALL"; break; #endif default: /* If you have a better idea for a default value let me know. */ retval = "LC_XXX"; } return retval; } /* An implementation of setlocale that always succeeds, but doesn't actually change the behaviour of locale dependent functions. Assumes setenv()/putenv() is not called. */ char * setlocale (int category, SETLOCALE_CONST char *locale) { static char C_string[] = "C"; static char *current_locale = C_string; struct list { int category; char *current_locale; struct list *next; }; static struct list *facets = NULL; struct list *facetp; char *retval; if (locale != NULL) { char *copy; copy = (char *) malloc (strlen (locale) + 1); strcpy (copy, locale); if (category == LC_ALL) { while ((facetp = facets) != NULL) { facets = facetp->next; free (facetp->current_locale); free (facetp); } if (current_locale != C_string) free (current_locale); current_locale = copy; } else { for (facetp = facets; facetp != NULL; facetp = facetp->next) if (category == facetp->category) { free (facetp->current_locale); facetp->current_locale = copy; break; } if (facetp == NULL) { facetp = (struct list *) malloc (sizeof (struct list)); facetp->category = category; facetp->current_locale = copy; facetp->next = facets; facets = facetp; } } } retval = current_locale; for (facetp = facets; facetp != NULL; facetp = facetp->next) if (category == facetp->category) { retval = facetp->current_locale; break; } if (retval[0] == '\0') { retval = getenv ("LC_ALL"); if (retval == NULL || retval[0] == '\0') { retval = getenv (category_to_name (category)); if (retval == NULL || retval[0] == '\0') { retval = getenv ("LANG"); if (retval == NULL || retval[0] == '\0') retval = "C"; } } } return retval; }