(root)/
gettext-0.22.4/
gettext-tools/
tests/
setlocale.c
       1  /* Fake setlocale - platform independent, for testing purposes.
       2     Copyright (C) 2001-2002, 2019-2020 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 <https://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  /* Make this override available independently of possible overrides in
      26     libgnuintl.h or locale.h.
      27     Note: On platforms where _nl_locale_name_posix invokes setlocale_null, this
      28     override *must* be called 'setlocale'.  */
      29  #undef setlocale
      30  /* Avoid a link error on MSVC.  */
      31  #if defined _WIN32 && !defined __CYGWIN__
      32  # define setlocale fake_setlocale
      33  #endif
      34  
      35  /* Return string representation of locale CATEGORY.  */
      36  static const char *
      37  category_to_name (int category)
      38  {
      39    const char *retval;
      40  
      41    switch (category)
      42    {
      43  #ifdef LC_COLLATE
      44    case LC_COLLATE:
      45      retval = "LC_COLLATE";
      46      break;
      47  #endif
      48  #ifdef LC_CTYPE
      49    case LC_CTYPE:
      50      retval = "LC_CTYPE";
      51      break;
      52  #endif
      53  #ifdef LC_MONETARY
      54    case LC_MONETARY:
      55      retval = "LC_MONETARY";
      56      break;
      57  #endif
      58  #ifdef LC_NUMERIC
      59    case LC_NUMERIC:
      60      retval = "LC_NUMERIC";
      61      break;
      62  #endif
      63  #ifdef LC_TIME
      64    case LC_TIME:
      65      retval = "LC_TIME";
      66      break;
      67  #endif
      68  #ifdef LC_MESSAGES
      69    case LC_MESSAGES:
      70      retval = "LC_MESSAGES";
      71      break;
      72  #endif
      73  #ifdef LC_RESPONSE
      74    case LC_RESPONSE:
      75      retval = "LC_RESPONSE";
      76      break;
      77  #endif
      78  #ifdef LC_ALL
      79    case LC_ALL:
      80      /* This might not make sense but is perhaps better than any other
      81         value.  */
      82      retval = "LC_ALL";
      83      break;
      84  #endif
      85    default:
      86      /* If you have a better idea for a default value let me know.  */
      87      retval = "LC_XXX";
      88    }
      89  
      90    return retval;
      91  }
      92  
      93  /* An implementation of setlocale that always succeeds, but doesn't
      94     actually change the behaviour of locale dependent functions.
      95     Assumes setenv()/putenv() is not called.  */
      96  char *
      97  setlocale (int category, const char *locale)
      98  {
      99    static char C_string[] = "C";
     100    static char *current_locale = C_string;
     101    struct list
     102    {
     103      int category;
     104      char *current_locale;
     105      struct list *next;
     106    };
     107    static struct list *facets = NULL;
     108    struct list *facetp;
     109    char *retval;
     110  
     111    if (locale != NULL)
     112      {
     113        char *copy;
     114  
     115        copy = (char *) malloc (strlen (locale) + 1);
     116        strcpy (copy, locale);
     117  
     118        if (category == LC_ALL)
     119          {
     120            while ((facetp = facets) != NULL)
     121              {
     122                facets = facetp->next;
     123                free (facetp->current_locale);
     124                free (facetp);
     125              }
     126            if (current_locale != C_string)
     127              free (current_locale);
     128            current_locale = copy;
     129          }
     130        else
     131          {
     132            for (facetp = facets; facetp != NULL; facetp = facetp->next)
     133              if (category == facetp->category)
     134                {
     135                  free (facetp->current_locale);
     136                  facetp->current_locale = copy;
     137                  break;
     138                }
     139            if (facetp == NULL)
     140              {
     141                facetp = (struct list *) malloc (sizeof (struct list));
     142                facetp->category = category;
     143                facetp->current_locale = copy;
     144                facetp->next = facets;
     145                facets = facetp;
     146              }
     147          }
     148      }
     149  
     150    retval = current_locale;
     151    for (facetp = facets; facetp != NULL; facetp = facetp->next)
     152      if (category == facetp->category)
     153        {
     154          retval = facetp->current_locale;
     155          break;
     156        }
     157  
     158    if (retval[0] == '\0')
     159      {
     160        retval = getenv ("LC_ALL");
     161        if (retval == NULL || retval[0] == '\0')
     162          {
     163            retval = getenv (category_to_name (category));
     164            if (retval == NULL || retval[0] == '\0')
     165              {
     166                retval = getenv ("LANG");
     167                if (retval == NULL || retval[0] == '\0')
     168                  retval = "C";
     169              }
     170          }
     171      }
     172    return retval;
     173  }