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 2, or (at your option) 7 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, write to the Free Software Foundation, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18#ifdef HAVE_CONFIG_H 19# include <config.h> 20#endif 21 22#include <stdlib.h> 23#include <locale.h> 24#include <string.h> 25 26/* Return string representation of locale CATEGORY. */ 27static const char * 28category_to_name (int category) 29{ 30 const char *retval; 31 32 switch (category) 33 { 34#ifdef LC_COLLATE 35 case LC_COLLATE: 36 retval = "LC_COLLATE"; 37 break; 38#endif 39#ifdef LC_CTYPE 40 case LC_CTYPE: 41 retval = "LC_CTYPE"; 42 break; 43#endif 44#ifdef LC_MONETARY 45 case LC_MONETARY: 46 retval = "LC_MONETARY"; 47 break; 48#endif 49#ifdef LC_NUMERIC 50 case LC_NUMERIC: 51 retval = "LC_NUMERIC"; 52 break; 53#endif 54#ifdef LC_TIME 55 case LC_TIME: 56 retval = "LC_TIME"; 57 break; 58#endif 59#ifdef LC_MESSAGES 60 case LC_MESSAGES: 61 retval = "LC_MESSAGES"; 62 break; 63#endif 64#ifdef LC_RESPONSE 65 case LC_RESPONSE: 66 retval = "LC_RESPONSE"; 67 break; 68#endif 69#ifdef LC_ALL 70 case LC_ALL: 71 /* This might not make sense but is perhaps better than any other 72 value. */ 73 retval = "LC_ALL"; 74 break; 75#endif 76 default: 77 /* If you have a better idea for a default value let me know. */ 78 retval = "LC_XXX"; 79 } 80 81 return retval; 82} 83 84/* An implementation of setlocale that always succeeds, but doesn't 85 actually change the behaviour of locale dependent functions. 86 Assumes setenv()/putenv() is not called. */ 87char * 88setlocale (int category, SETLOCALE_CONST char *locale) 89{ 90 static char C_string[] = "C"; 91 static char *current_locale = C_string; 92 struct list 93 { 94 int category; 95 char *current_locale; 96 struct list *next; 97 }; 98 static struct list *facets = NULL; 99 struct list *facetp; 100 char *retval; 101 102 if (locale != NULL) 103 { 104 char *copy; 105 106 copy = (char *) malloc (strlen (locale) + 1); 107 strcpy (copy, locale); 108 109 if (category == LC_ALL) 110 { 111 while ((facetp = facets) != NULL) 112 { 113 facets = facetp->next; 114 free (facetp->current_locale); 115 free (facetp); 116 } 117 if (current_locale != C_string) 118 free (current_locale); 119 current_locale = copy; 120 } 121 else 122 { 123 for (facetp = facets; facetp != NULL; facetp = facetp->next) 124 if (category == facetp->category) 125 { 126 free (facetp->current_locale); 127 facetp->current_locale = copy; 128 break; 129 } 130 if (facetp == NULL) 131 { 132 facetp = (struct list *) malloc (sizeof (struct list)); 133 facetp->category = category; 134 facetp->current_locale = copy; 135 facetp->next = facets; 136 facets = facetp; 137 } 138 } 139 } 140 141 retval = current_locale; 142 for (facetp = facets; facetp != NULL; facetp = facetp->next) 143 if (category == facetp->category) 144 { 145 retval = facetp->current_locale; 146 break; 147 } 148 149 if (retval[0] == '\0') 150 { 151 retval = getenv ("LC_ALL"); 152 if (retval == NULL || retval[0] == '\0') 153 { 154 retval = getenv (category_to_name (category)); 155 if (retval == NULL || retval[0] == '\0') 156 { 157 retval = getenv ("LANG"); 158 if (retval == NULL || retval[0] == '\0') 159 retval = "C"; 160 } 161 } 162 } 163 return retval; 164} 165