1/* Fake setlocale - platform independent, for testing purposes. 2 Copyright (C) 2001-2002 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17#ifdef HAVE_CONFIG_H 18# include <config.h> 19#endif 20 21#include <stdlib.h> 22#include <locale.h> 23#include <string.h> 24 25/* Return string representation of locale CATEGORY. */ 26static const char * 27category_to_name (int category) 28{ 29 const char *retval; 30 31 switch (category) 32 { 33#ifdef LC_COLLATE 34 case LC_COLLATE: 35 retval = "LC_COLLATE"; 36 break; 37#endif 38#ifdef LC_CTYPE 39 case LC_CTYPE: 40 retval = "LC_CTYPE"; 41 break; 42#endif 43#ifdef LC_MONETARY 44 case LC_MONETARY: 45 retval = "LC_MONETARY"; 46 break; 47#endif 48#ifdef LC_NUMERIC 49 case LC_NUMERIC: 50 retval = "LC_NUMERIC"; 51 break; 52#endif 53#ifdef LC_TIME 54 case LC_TIME: 55 retval = "LC_TIME"; 56 break; 57#endif 58#ifdef LC_MESSAGES 59 case LC_MESSAGES: 60 retval = "LC_MESSAGES"; 61 break; 62#endif 63#ifdef LC_RESPONSE 64 case LC_RESPONSE: 65 retval = "LC_RESPONSE"; 66 break; 67#endif 68#ifdef LC_ALL 69 case LC_ALL: 70 /* This might not make sense but is perhaps better than any other 71 value. */ 72 retval = "LC_ALL"; 73 break; 74#endif 75 default: 76 /* If you have a better idea for a default value let me know. */ 77 retval = "LC_XXX"; 78 } 79 80 return retval; 81} 82 83/* An implementation of setlocale that always succeeds, but doesn't 84 actually change the behaviour of locale dependent functions. 85 Assumes setenv()/putenv() is not called. */ 86char * 87setlocale (int category, SETLOCALE_CONST char *locale) 88{ 89 static char C_string[] = "C"; 90 static char *current_locale = C_string; 91 struct list 92 { 93 int category; 94 char *current_locale; 95 struct list *next; 96 }; 97 static struct list *facets = NULL; 98 struct list *facetp; 99 char *retval; 100 101 if (locale != NULL) 102 { 103 char *copy; 104 105 copy = (char *) malloc (strlen (locale) + 1); 106 strcpy (copy, locale); 107 108 if (category == LC_ALL) 109 { 110 while ((facetp = facets) != NULL) 111 { 112 facets = facetp->next; 113 free (facetp->current_locale); 114 free (facetp); 115 } 116 if (current_locale != C_string) 117 free (current_locale); 118 current_locale = copy; 119 } 120 else 121 { 122 for (facetp = facets; facetp != NULL; facetp = facetp->next) 123 if (category == facetp->category) 124 { 125 free (facetp->current_locale); 126 facetp->current_locale = copy; 127 break; 128 } 129 if (facetp == NULL) 130 { 131 facetp = (struct list *) malloc (sizeof (struct list)); 132 facetp->category = category; 133 facetp->current_locale = copy; 134 facetp->next = facets; 135 facets = facetp; 136 } 137 } 138 } 139 140 retval = current_locale; 141 for (facetp = facets; facetp != NULL; facetp = facetp->next) 142 if (category == facetp->category) 143 { 144 retval = facetp->current_locale; 145 break; 146 } 147 148 if (retval[0] == '\0') 149 { 150 retval = getenv ("LC_ALL"); 151 if (retval == NULL || retval[0] == '\0') 152 { 153 retval = getenv (category_to_name (category)); 154 if (retval == NULL || retval[0] == '\0') 155 { 156 retval = getenv ("LANG"); 157 if (retval == NULL || retval[0] == '\0') 158 retval = "C"; 159 } 160 } 161 } 162 return retval; 163} 164