"Fossies" - the Fresh Open Source Software Archive

Member "gnuastro-0.8/bootstrapped/lib/nl_langinfo.c" (28 Dec 2018, 10386 Bytes) of package /linux/privat/gnuastro-0.8.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nl_langinfo.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.5_vs_0.6.

    1 /* nl_langinfo() replacement: query locale dependent information.
    2 
    3    Copyright (C) 2007-2018 Free Software Foundation, Inc.
    4 
    5    This program is free software: you can redistribute it and/or modify
    6    it under the terms of the GNU General Public License as published by
    7    the Free Software Foundation; either version 3 of the License, or
    8    (at your option) any later version.
    9 
   10    This program is distributed in the hope that it will be useful,
   11    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13    GNU General Public License for more details.
   14 
   15    You should have received a copy of the GNU General Public License
   16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
   17 
   18 #include <config.h>
   19 
   20 /* Specification.  */
   21 #include <langinfo.h>
   22 
   23 #include <locale.h>
   24 #include <string.h>
   25 #if defined _WIN32 && ! defined __CYGWIN__
   26 # define WIN32_LEAN_AND_MEAN  /* avoid including junk */
   27 # include <windows.h>
   28 # include <stdio.h>
   29 #endif
   30 
   31 #if !REPLACE_NL_LANGINFO || GNULIB_defined_CODESET
   32 /* Return the codeset of the current locale, if this is easily deducible.
   33    Otherwise, return "".  */
   34 static char *
   35 ctype_codeset (void)
   36 {
   37   static char buf[2 + 10 + 1];
   38   char const *locale = setlocale (LC_CTYPE, NULL);
   39   char *codeset = buf;
   40   size_t codesetlen;
   41   codeset[0] = '\0';
   42 
   43   if (locale && locale[0])
   44     {
   45       /* If the locale name contains an encoding after the dot, return it.  */
   46       char *dot = strchr (locale, '.');
   47 
   48       if (dot)
   49         {
   50           /* Look for the possible @... trailer and remove it, if any.  */
   51           char *codeset_start = dot + 1;
   52           char const *modifier = strchr (codeset_start, '@');
   53 
   54           if (! modifier)
   55             codeset = codeset_start;
   56           else
   57             {
   58               codesetlen = modifier - codeset_start;
   59               if (codesetlen < sizeof buf)
   60                 {
   61                   codeset = memcpy (buf, codeset_start, codesetlen);
   62                   codeset[codesetlen] = '\0';
   63                 }
   64             }
   65         }
   66     }
   67 
   68 # if defined _WIN32 && ! defined __CYGWIN__
   69   /* If setlocale is successful, it returns the number of the
   70      codepage, as a string.  Otherwise, fall back on Windows API
   71      GetACP, which returns the locale's codepage as a number (although
   72      this doesn't change according to what the 'setlocale' call specified).
   73      Either way, prepend "CP" to make it a valid codeset name.  */
   74   codesetlen = strlen (codeset);
   75   if (0 < codesetlen && codesetlen < sizeof buf - 2)
   76     memmove (buf + 2, codeset, codesetlen + 1);
   77   else
   78     sprintf (buf + 2, "%u", GetACP ());
   79   codeset = memcpy (buf, "CP", 2);
   80 # endif
   81   return codeset;
   82 }
   83 #endif
   84 
   85 
   86 #if REPLACE_NL_LANGINFO
   87 
   88 /* Override nl_langinfo with support for added nl_item values.  */
   89 
   90 # undef nl_langinfo
   91 
   92 char *
   93 rpl_nl_langinfo (nl_item item)
   94 {
   95   switch (item)
   96     {
   97 # if GNULIB_defined_CODESET
   98     case CODESET:
   99       return ctype_codeset ();
  100 # endif
  101 # if GNULIB_defined_T_FMT_AMPM
  102     case T_FMT_AMPM:
  103       return (char *) "%I:%M:%S %p";
  104 # endif
  105 # if GNULIB_defined_ALTMON
  106     case ALTMON_1:
  107     case ALTMON_2:
  108     case ALTMON_3:
  109     case ALTMON_4:
  110     case ALTMON_5:
  111     case ALTMON_6:
  112     case ALTMON_7:
  113     case ALTMON_8:
  114     case ALTMON_9:
  115     case ALTMON_10:
  116     case ALTMON_11:
  117     case ALTMON_12:
  118       /* We don't ship the appropriate localizations with gnulib.  Therefore,
  119          treat ALTMON_i like MON_i.  */
  120       item = item - ALTMON_1 + MON_1;
  121       break;
  122 # endif
  123 # if GNULIB_defined_ERA
  124     case ERA:
  125       /* The format is not standardized.  In glibc it is a sequence of strings
  126          of the form "direction:offset:start_date:end_date:era_name:era_format"
  127          with an empty string at the end.  */
  128       return (char *) "";
  129     case ERA_D_FMT:
  130       /* The %Ex conversion in strftime behaves like %x if the locale does not
  131          have an alternative time format.  */
  132       item = D_FMT;
  133       break;
  134     case ERA_D_T_FMT:
  135       /* The %Ec conversion in strftime behaves like %c if the locale does not
  136          have an alternative time format.  */
  137       item = D_T_FMT;
  138       break;
  139     case ERA_T_FMT:
  140       /* The %EX conversion in strftime behaves like %X if the locale does not
  141          have an alternative time format.  */
  142       item = T_FMT;
  143       break;
  144     case ALT_DIGITS:
  145       /* The format is not standardized.  In glibc it is a sequence of 10
  146          strings, appended in memory.  */
  147       return (char *) "\0\0\0\0\0\0\0\0\0\0";
  148 # endif
  149 # if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS
  150     case YESEXPR:
  151       return (char *) "^[yY]";
  152     case NOEXPR:
  153       return (char *) "^[nN]";
  154 # endif
  155     default:
  156       break;
  157     }
  158   return nl_langinfo (item);
  159 }
  160 
  161 #else
  162 
  163 /* Provide nl_langinfo from scratch, either for native MS-Windows, or
  164    for old Unix platforms without locales, such as Linux libc5 or
  165    BeOS.  */
  166 
  167 # include <time.h>
  168 
  169 char *
  170 nl_langinfo (nl_item item)
  171 {
  172   static char nlbuf[100];
  173   struct tm tmm = { 0 };
  174 
  175   switch (item)
  176     {
  177     /* nl_langinfo items of the LC_CTYPE category */
  178     case CODESET:
  179       {
  180         char *codeset = ctype_codeset ();
  181         if (*codeset)
  182           return codeset;
  183       }
  184 # ifdef __BEOS__
  185       return (char *) "UTF-8";
  186 # else
  187       return (char *) "ISO-8859-1";
  188 # endif
  189     /* nl_langinfo items of the LC_NUMERIC category */
  190     case RADIXCHAR:
  191       return localeconv () ->decimal_point;
  192     case THOUSEP:
  193       return localeconv () ->thousands_sep;
  194 # ifdef GROUPING
  195     case GROUPING:
  196       return localeconv () ->grouping;
  197 # endif
  198     /* nl_langinfo items of the LC_TIME category.
  199        TODO: Really use the locale.  */
  200     case D_T_FMT:
  201     case ERA_D_T_FMT:
  202       return (char *) "%a %b %e %H:%M:%S %Y";
  203     case D_FMT:
  204     case ERA_D_FMT:
  205       return (char *) "%m/%d/%y";
  206     case T_FMT:
  207     case ERA_T_FMT:
  208       return (char *) "%H:%M:%S";
  209     case T_FMT_AMPM:
  210       return (char *) "%I:%M:%S %p";
  211     case AM_STR:
  212       if (!strftime (nlbuf, sizeof nlbuf, "%p", &tmm))
  213         return (char *) "AM";
  214       return nlbuf;
  215     case PM_STR:
  216       tmm.tm_hour = 12;
  217       if (!strftime (nlbuf, sizeof nlbuf, "%p", &tmm))
  218         return (char *) "PM";
  219       return nlbuf;
  220     case DAY_1:
  221     case DAY_2:
  222     case DAY_3:
  223     case DAY_4:
  224     case DAY_5:
  225     case DAY_6:
  226     case DAY_7:
  227       {
  228         static char const days[][sizeof "Wednesday"] = {
  229           "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
  230           "Friday", "Saturday"
  231         };
  232         tmm.tm_wday = item - DAY_1;
  233         if (!strftime (nlbuf, sizeof nlbuf, "%A", &tmm))
  234           return (char *) days[item - DAY_1];
  235         return nlbuf;
  236       }
  237     case ABDAY_1:
  238     case ABDAY_2:
  239     case ABDAY_3:
  240     case ABDAY_4:
  241     case ABDAY_5:
  242     case ABDAY_6:
  243     case ABDAY_7:
  244       {
  245         static char const abdays[][sizeof "Sun"] = {
  246           "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  247         };
  248         tmm.tm_wday = item - ABDAY_1;
  249         if (!strftime (nlbuf, sizeof nlbuf, "%a", &tmm))
  250           return (char *) abdays[item - ABDAY_1];
  251         return nlbuf;
  252       }
  253     {
  254       static char const months[][sizeof "September"] = {
  255         "January", "February", "March", "April", "May", "June", "July",
  256         "September", "October", "November", "December"
  257       };
  258       case MON_1:
  259       case MON_2:
  260       case MON_3:
  261       case MON_4:
  262       case MON_5:
  263       case MON_6:
  264       case MON_7:
  265       case MON_8:
  266       case MON_9:
  267       case MON_10:
  268       case MON_11:
  269       case MON_12:
  270         tmm.tm_mon = item - MON_1;
  271         if (!strftime (nlbuf, sizeof nlbuf, "%B", &tmm))
  272           return (char *) months[item - MON_1];
  273         return nlbuf;
  274       case ALTMON_1:
  275       case ALTMON_2:
  276       case ALTMON_3:
  277       case ALTMON_4:
  278       case ALTMON_5:
  279       case ALTMON_6:
  280       case ALTMON_7:
  281       case ALTMON_8:
  282       case ALTMON_9:
  283       case ALTMON_10:
  284       case ALTMON_11:
  285       case ALTMON_12:
  286         tmm.tm_mon = item - ALTMON_1;
  287         /* The platforms without nl_langinfo() don't support strftime with %OB.
  288            We don't even need to try.  */
  289         #if 0
  290         if (!strftime (nlbuf, sizeof nlbuf, "%OB", &tmm))
  291         #endif
  292           if (!strftime (nlbuf, sizeof nlbuf, "%B", &tmm))
  293             return (char *) months[item - ALTMON_1];
  294         return nlbuf;
  295     }
  296     case ABMON_1:
  297     case ABMON_2:
  298     case ABMON_3:
  299     case ABMON_4:
  300     case ABMON_5:
  301     case ABMON_6:
  302     case ABMON_7:
  303     case ABMON_8:
  304     case ABMON_9:
  305     case ABMON_10:
  306     case ABMON_11:
  307     case ABMON_12:
  308       {
  309         static char const abmonths[][sizeof "Jan"] = {
  310           "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
  311           "Sep", "Oct", "Nov", "Dec"
  312         };
  313         tmm.tm_mon = item - ABMON_1;
  314         if (!strftime (nlbuf, sizeof nlbuf, "%b", &tmm))
  315           return (char *) abmonths[item - ABMON_1];
  316         return nlbuf;
  317       }
  318     case ERA:
  319       return (char *) "";
  320     case ALT_DIGITS:
  321       return (char *) "\0\0\0\0\0\0\0\0\0\0";
  322     /* nl_langinfo items of the LC_MONETARY category.  */
  323     case CRNCYSTR:
  324       return localeconv () ->currency_symbol;
  325 # ifdef INT_CURR_SYMBOL
  326     case INT_CURR_SYMBOL:
  327       return localeconv () ->int_curr_symbol;
  328     case MON_DECIMAL_POINT:
  329       return localeconv () ->mon_decimal_point;
  330     case MON_THOUSANDS_SEP:
  331       return localeconv () ->mon_thousands_sep;
  332     case MON_GROUPING:
  333       return localeconv () ->mon_grouping;
  334     case POSITIVE_SIGN:
  335       return localeconv () ->positive_sign;
  336     case NEGATIVE_SIGN:
  337       return localeconv () ->negative_sign;
  338     case FRAC_DIGITS:
  339       return & localeconv () ->frac_digits;
  340     case INT_FRAC_DIGITS:
  341       return & localeconv () ->int_frac_digits;
  342     case P_CS_PRECEDES:
  343       return & localeconv () ->p_cs_precedes;
  344     case N_CS_PRECEDES:
  345       return & localeconv () ->n_cs_precedes;
  346     case P_SEP_BY_SPACE:
  347       return & localeconv () ->p_sep_by_space;
  348     case N_SEP_BY_SPACE:
  349       return & localeconv () ->n_sep_by_space;
  350     case P_SIGN_POSN:
  351       return & localeconv () ->p_sign_posn;
  352     case N_SIGN_POSN:
  353       return & localeconv () ->n_sign_posn;
  354 # endif
  355     /* nl_langinfo items of the LC_MESSAGES category
  356        TODO: Really use the locale. */
  357     case YESEXPR:
  358       return (char *) "^[yY]";
  359     case NOEXPR:
  360       return (char *) "^[nN]";
  361     default:
  362       return (char *) "";
  363     }
  364 }
  365 
  366 #endif