OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc2/] [newlib/] [libc/] [locale/] [locale.c] - Blame information for rev 520

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/*
2
FUNCTION
3
<<setlocale>>, <<localeconv>>---select or query locale
4
 
5
INDEX
6
        setlocale
7
INDEX
8
        localeconv
9
INDEX
10
        _setlocale_r
11
INDEX
12
        _localeconv_r
13
 
14
ANSI_SYNOPSIS
15
        #include <locale.h>
16
        char *setlocale(int <[category]>, const char *<[locale]>);
17
        lconv *localeconv(void);
18
 
19
        char *_setlocale_r(void *<[reent]>,
20
                        int <[category]>, const char *<[locale]>);
21
        lconv *_localeconv_r(void *<[reent]>);
22
 
23
TRAD_SYNOPSIS
24
        #include <locale.h>
25
        char *setlocale(<[category]>, <[locale]>)
26
        int <[category]>;
27
        char *<[locale]>;
28
 
29
        lconv *localeconv();
30
 
31
        char *_setlocale_r(<[reent]>, <[category]>, <[locale]>)
32
        char *<[reent]>;
33
        int <[category]>;
34
        char *<[locale]>;
35
 
36
        lconv *_localeconv_r(<[reent]>);
37
        char *<[reent]>;
38
 
39
DESCRIPTION
40
<<setlocale>> is the facility defined by ANSI C to condition the
41
execution environment for international collating and formatting
42
information; <<localeconv>> reports on the settings of the current
43
locale.
44
 
45
This is a minimal implementation, supporting only the required <<"POSIX">>
46
and <<"C">> values for <[locale]>; strings representing other locales are not
47
honored unless _MB_CAPABLE is defined.
48
 
49
If _MB_CAPABLE is defined, POSIX locale strings are allowed, following
50
the form
51
 
52
  language[_TERRITORY][.charset][@@modifier]
53
 
54
<<"language">> is a two character string per ISO 639.  <<"TERRITORY">> is a
55
country code per ISO 3166.  For <<"charset">> and <<"modifier">> see below.
56
 
57
Additionally to the POSIX specifier, seven extensions are supported for
58
backward compatibility with older implementations using newlib:
59
<<"C-UTF-8">>, <<"C-JIS">>, <<"C-eucJP">>, <<"C-SJIS">>, <<C-KOI8-R>>,
60
<<C-KOI8-U>>, <<"C-ISO-8859-x">> with 1 <= x <= 15, or <<"C-CPxxx">> with
61
xxx in [437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866, 874, 1125,
62
1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258].
63
 
64
Instead of <<"C-">>, you can specify also <<"C.">>.  Both variations allow
65
to specify language neutral locales while using other charsets than ASCII,
66
for instance <<"C.UTF-8">>, which keeps all settings as in the C locale,
67
but uses the UTF-8 charset.
68
 
69
Even when using POSIX locale strings, the only charsets allowed are
70
<<"UTF-8">>, <<"JIS">>, <<"EUCJP">>, <<"SJIS">>, <<KOI8-R>>, <<KOI8-U>>,
71
<<"ISO-8859-x">> with 1 <= x <= 15, or <<"CPxxx">> with xxx in
72
[437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866, 874, 1125, 1250,
73
1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258].
74
Charsets are case insensitive.  For instance, <<"EUCJP">> and <<"eucJP">>
75
are equivalent.  <<"UTF-8">> can also be written without dash, as in
76
<<"UTF8">> or <<"utf8">>.
77
 
78
(<<"">> is also accepted; if given, the settings are read from the
79
corresponding LC_* environment variables and $LANG according to POSIX rules.
80
 
81
Under Cygwin, this implementation additionally supports the charsets
82
<<"GBK">>, <<"eucKR">>, and <<"Big5">>.
83
 
84
This implementation also supports a single modifier, <<"cjknarrow">>.
85
Any other modifier is ignored.  <<"cjknarrow">>, in conjunction with one
86
of the language specifiers <<"ja">>, <<"ko">>, and <<"zh">> specifies
87
how the functions <<wcwidth>> and <<wcswidth>> handle characters from
88
the "CJK Ambiguous Width" character class described in
89
http://www.unicode.org/unicode/reports/tr11/.  Usually these characters
90
have a width of 1, unless you specify one of the aforementioned
91
languages, in which case these characters have a width of 2.  By
92
specifying the <<"cjknarrow">> modifier, these characters will have a
93
width of one in the languages <<"ja">>, <<"ko">>, and <<"zh">> as well.
94
 
95
If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns a
96
pointer to the string representing the current locale.  The acceptable
97
values for <[category]> are defined in `<<locale.h>>' as macros
98
beginning with <<"LC_">>.
99
 
100
<<localeconv>> returns a pointer to a structure (also defined in
101
`<<locale.h>>') describing the locale-specific conventions currently
102
in effect.
103
 
104
<<_localeconv_r>> and <<_setlocale_r>> are reentrant versions of
105
<<localeconv>> and <<setlocale>> respectively.  The extra argument
106
<[reent]> is a pointer to a reentrancy structure.
107
 
108
RETURNS
109
A successful call to <<setlocale>> returns a pointer to a string
110
associated with the specified category for the new locale.  The string
111
returned by <<setlocale>> is such that a subsequent call using that
112
string will restore that category (or all categories in case of LC_ALL),
113
to that state.  The application shall not modify the string returned
114
which may be overwritten by a subsequent call to <<setlocale>>.
115
On error, <<setlocale>> returns <<NULL>>.
116
 
117
<<localeconv>> returns a pointer to a structure of type <<lconv>>,
118
which describes the formatting and collating conventions in effect (in
119
this implementation, always those of the C locale).
120
 
121
PORTABILITY
122
ANSI C requires <<setlocale>>, but the only locale required across all
123
implementations is the C locale.
124
 
125
NOTES
126
There is no ISO-8859-12 codepage.  It's also refused by this implementation.
127
 
128
No supporting OS subroutines are required.
129
*/
130
 
131
/* Parts of this code are originally taken from FreeBSD. */
132
/*
133
 * Copyright (c) 1996 - 2002 FreeBSD Project
134
 * Copyright (c) 1991, 1993
135
 *      The Regents of the University of California.  All rights reserved.
136
 *
137
 * This code is derived from software contributed to Berkeley by
138
 * Paul Borman at Krystal Technologies.
139
 *
140
 * Redistribution and use in source and binary forms, with or without
141
 * modification, are permitted provided that the following conditions
142
 * are met:
143
 * 1. Redistributions of source code must retain the above copyright
144
 *    notice, this list of conditions and the following disclaimer.
145
 * 2. Redistributions in binary form must reproduce the above copyright
146
 *    notice, this list of conditions and the following disclaimer in the
147
 *    documentation and/or other materials provided with the distribution.
148
 * 4. Neither the name of the University nor the names of its contributors
149
 *    may be used to endorse or promote products derived from this software
150
 *    without specific prior written permission.
151
 *
152
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
153
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
154
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
155
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
156
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
157
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
158
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
159
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
160
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
161
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
162
 * SUCH DAMAGE.
163
 */
164
 
165
#include <newlib.h>
166
#include <errno.h>
167
#include <locale.h>
168
#include <string.h>
169
#include <limits.h>
170
#include <reent.h>
171
#include <stdlib.h>
172
#include <wchar.h>
173
#include "../stdlib/local.h"
174
 
175
#define _LC_LAST      7
176
#define ENCODING_LEN 31
177
 
178
int __EXPORT __mb_cur_max = 1;
179
 
180
int __nlocale_changed = 0;
181
int __mlocale_changed = 0;
182
char *_PathLocale = NULL;
183
 
184
static _CONST struct lconv lconv =
185
{
186
  ".", "", "", "", "", "", "", "", "", "",
187
  CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
188
  CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
189
  CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
190
  CHAR_MAX, CHAR_MAX
191
};
192
 
193
#ifdef _MB_CAPABLE
194
/*
195
 * Category names for getenv()
196
 */
197
static char *categories[_LC_LAST] = {
198
  "LC_ALL",
199
  "LC_COLLATE",
200
  "LC_CTYPE",
201
  "LC_MONETARY",
202
  "LC_NUMERIC",
203
  "LC_TIME",
204
  "LC_MESSAGES",
205
};
206
 
207
/*
208
 * Default locale per POSIX.  Can be overridden on a per-target base.
209
 */
210
#ifndef DEFAULT_LOCALE
211
#define DEFAULT_LOCALE  "C"
212
#endif
213
/*
214
 * This variable can be changed by any outside mechanism.  This allows,
215
 * for instance, to load the default locale from a file.
216
 */
217
char __default_locale[ENCODING_LEN + 1] = DEFAULT_LOCALE;
218
 
219
/*
220
 * Current locales for each category
221
 */
222
static char current_categories[_LC_LAST][ENCODING_LEN + 1] = {
223
    "C",
224
    "C",
225
    "C",
226
    "C",
227
    "C",
228
    "C",
229
    "C",
230
};
231
 
232
/*
233
 * The locales we are going to try and load
234
 */
235
static char new_categories[_LC_LAST][ENCODING_LEN + 1];
236
static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
237
 
238
static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)];
239
static char *currentlocale(void);
240
static char *loadlocale(struct _reent *, int);
241
static const char *__get_locale_env(struct _reent *, int);
242
 
243
#endif
244
 
245
#ifdef __CYGWIN__
246
static char lc_ctype_charset[ENCODING_LEN + 1] = "UTF-8";
247
static char lc_message_charset[ENCODING_LEN + 1] = "UTF-8";
248
#else
249
static char lc_ctype_charset[ENCODING_LEN + 1] = "ASCII";
250
static char lc_message_charset[ENCODING_LEN + 1] = "ASCII";
251
#endif
252
static int lc_ctype_cjk_lang = 0;
253
 
254
char *
255
_DEFUN(_setlocale_r, (p, category, locale),
256
       struct _reent *p _AND
257
       int category _AND
258
       _CONST char *locale)
259
{
260
#ifndef _MB_CAPABLE
261
  if (locale)
262
    {
263
      if (strcmp (locale, "POSIX") && strcmp (locale, "C")
264
          && strcmp (locale, ""))
265
        return NULL;
266
    }
267
  return "C";
268
#else
269
  int i, j, len, saverr;
270
  const char *env, *r;
271
 
272
  if (category < LC_ALL || category >= _LC_LAST)
273
    {
274
      p->_errno = EINVAL;
275
      return NULL;
276
    }
277
 
278
  if (locale == NULL)
279
    return category != LC_ALL ? current_categories[category] : currentlocale();
280
 
281
  /*
282
   * Default to the current locale for everything.
283
   */
284
  for (i = 1; i < _LC_LAST; ++i)
285
    strcpy (new_categories[i], current_categories[i]);
286
 
287
  /*
288
   * Now go fill up new_categories from the locale argument
289
   */
290
  if (!*locale)
291
    {
292
      if (category == LC_ALL)
293
        {
294
          for (i = 1; i < _LC_LAST; ++i)
295
            {
296
              env = __get_locale_env (p, i);
297
              if (strlen (env) > ENCODING_LEN)
298
                {
299
                  p->_errno = EINVAL;
300
                  return NULL;
301
                }
302
              strcpy (new_categories[i], env);
303
            }
304
        }
305
      else
306
        {
307
          env = __get_locale_env (p, category);
308
          if (strlen (env) > ENCODING_LEN)
309
            {
310
              p->_errno = EINVAL;
311
              return NULL;
312
            }
313
          strcpy (new_categories[category], env);
314
        }
315
    }
316
  else if (category != LC_ALL)
317
    {
318
      if (strlen (locale) > ENCODING_LEN)
319
        {
320
          p->_errno = EINVAL;
321
          return NULL;
322
        }
323
      strcpy (new_categories[category], locale);
324
    }
325
  else
326
    {
327
      if ((r = strchr (locale, '/')) == NULL)
328
        {
329
          if (strlen (locale) > ENCODING_LEN)
330
            {
331
              p->_errno = EINVAL;
332
              return NULL;
333
            }
334
          for (i = 1; i < _LC_LAST; ++i)
335
            strcpy (new_categories[i], locale);
336
        }
337
      else
338
        {
339
          for (i = 1; r[1] == '/'; ++r)
340
            ;
341
          if (!r[1])
342
            {
343
              p->_errno = EINVAL;
344
              return NULL;  /* Hmm, just slashes... */
345
            }
346
          do
347
            {
348
              if (i == _LC_LAST)
349
                break;  /* Too many slashes... */
350
              if ((len = r - locale) > ENCODING_LEN)
351
                {
352
                  p->_errno = EINVAL;
353
                  return NULL;
354
                }
355
              strlcpy (new_categories[i], locale, len + 1);
356
              i++;
357
              while (*r == '/')
358
                r++;
359
              locale = r;
360
              while (*r && *r != '/')
361
                r++;
362
            }
363
          while (*locale);
364
          while (i < _LC_LAST)
365
            {
366
              strcpy (new_categories[i], new_categories[i-1]);
367
              i++;
368
            }
369
        }
370
    }
371
 
372
  if (category != LC_ALL)
373
    return loadlocale (p, category);
374
 
375
  for (i = 1; i < _LC_LAST; ++i)
376
    {
377
      strcpy (saved_categories[i], current_categories[i]);
378
      if (loadlocale (p, i) == NULL)
379
        {
380
          saverr = p->_errno;
381
          for (j = 1; j < i; j++)
382
            {
383
              strcpy (new_categories[j], saved_categories[j]);
384
              if (loadlocale (p, j) == NULL)
385
                {
386
                  strcpy (new_categories[j], "C");
387
                  loadlocale (p, j);
388
                }
389
            }
390
          p->_errno = saverr;
391
          return NULL;
392
        }
393
    }
394
  return currentlocale ();
395
#endif
396
}
397
 
398
#ifdef _MB_CAPABLE
399
static char *
400
currentlocale()
401
{
402
        int i;
403
 
404
        (void)strcpy(current_locale_string, current_categories[1]);
405
 
406
        for (i = 2; i < _LC_LAST; ++i)
407
                if (strcmp(current_categories[1], current_categories[i])) {
408
                        for (i = 2; i < _LC_LAST; ++i) {
409
                                (void)strcat(current_locale_string, "/");
410
                                (void)strcat(current_locale_string,
411
                                             current_categories[i]);
412
                        }
413
                        break;
414
                }
415
        return (current_locale_string);
416
}
417
#endif
418
 
419
#ifdef _MB_CAPABLE
420
#ifdef __CYGWIN__
421
extern void *__set_charset_from_codepage (unsigned int, char *charset);
422
#endif /* __CYGWIN__ */
423
 
424
extern void __set_ctype (const char *charset);
425
 
426
static char *
427
loadlocale(struct _reent *p, int category)
428
{
429
  /* At this point a full-featured system would just load the locale
430
     specific data from the locale files.
431
     What we do here for now is to check the incoming string for correctness.
432
     The string must be in one of the allowed locale strings, either
433
     one in POSIX-style, or one in the old newlib style to maintain
434
     backward compatibility.  If the local string is correct, the charset
435
     is extracted and stored in lc_ctype_charset or lc_message_charset
436
     dependent on the cateogry. */
437
  char *locale = new_categories[category];
438
  char charset[ENCODING_LEN + 1];
439
  unsigned long val;
440
  char *end;
441
  int mbc_max;
442
  int (*l_wctomb) (struct _reent *, char *, wchar_t, const char *, mbstate_t *);
443
  int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t,
444
                   const char *, mbstate_t *);
445
#ifdef _MB_CAPABLE
446
  int cjknarrow = 0;
447
#endif
448
 
449
  /* "POSIX" is translated to "C", as on Linux. */
450
  if (!strcmp (locale, "POSIX"))
451
    strcpy (locale, "C");
452
  if (!strcmp (locale, "C"))                            /* Default "C" locale */
453
#ifdef __CYGWIN__
454
    strcpy (charset, "UTF-8");
455
#else
456
    strcpy (charset, "ASCII");
457
#endif
458
  else if (locale[0] == 'C'
459
           && (locale[1] == '-'         /* Old newlib style */
460
               || locale[1] == '.'))    /* Extension for the C locale to allow
461
                                           specifying different charsets while
462
                                           sticking to the C locale in terms
463
                                           of sort order, etc.  Proposed in
464
                                           the Debian project. */
465
    strcpy (charset, locale + 2);
466
  else                                                  /* POSIX style */
467
    {
468
      char *c = locale;
469
 
470
      /* Don't use ctype macros here, they might be localized. */
471
      /* Language */
472
      if (c[0] < 'a' || c[0] > 'z'
473
          || c[1] < 'a' || c[1] > 'z')
474
        return NULL;
475
      c += 2;
476
      if (c[0] == '_')
477
        {
478
          /* Territory */
479
          ++c;
480
          if (c[0] < 'A' || c[0] > 'Z'
481
              || c[1] < 'A' || c[1] > 'Z')
482
            return NULL;
483
          c += 2;
484
        }
485
      if (c[0] == '.')
486
        {
487
          /* Charset */
488
          char *chp;
489
 
490
          ++c;
491
          strcpy (charset, c);
492
          if ((chp = strchr (charset, '@')))
493
            /* Strip off modifier */
494
            *chp = '\0';
495
          c += strlen (charset);
496
        }
497
      else if (c[0] == '\0' || c[0] == '@')
498
        /* End of string or just a modifier */
499
#ifdef __CYGWIN__
500
        __set_charset_from_codepage (0, charset);
501
#else
502
        strcpy (charset, "ISO-8859-1");
503
#endif
504
      else
505
        /* Invalid string */
506
        return NULL;
507
#ifdef _MB_CAPABLE
508
      if (c[0] == '@')
509
        {
510
          /* Modifier */
511
          /* Only one modifier is recognized right now.  "cjknarrow" is used
512
             to modify the behaviour of wcwidth() for East Asian languages.
513
             For details see the comment at the end of this function. */
514
          if (!strcmp (c + 1, "cjknarrow"))
515
            cjknarrow = 1;
516
        }
517
#endif
518
    }
519
  /* We only support this subset of charsets. */
520
  switch (charset[0])
521
    {
522
    case 'U':
523
    case 'u':
524
      if (strcasecmp (charset, "UTF-8") && strcasecmp (charset, "UTF8"))
525
        return NULL;
526
      strcpy (charset, "UTF-8");
527
      mbc_max = 6;
528
#ifdef _MB_CAPABLE
529
      l_wctomb = __utf8_wctomb;
530
      l_mbtowc = __utf8_mbtowc;
531
#endif
532
    break;
533
    case 'J':
534
    case 'j':
535
      if (strcasecmp (charset, "JIS"))
536
        return NULL;
537
      strcpy (charset, "JIS");
538
      mbc_max = 8;
539
#ifdef _MB_CAPABLE
540
      l_wctomb = __jis_wctomb;
541
      l_mbtowc = __jis_mbtowc;
542
#endif
543
    break;
544
    case 'E':
545
    case 'e':
546
      if (!strcasecmp (charset, "EUCJP"))
547
        {
548
          strcpy (charset, "EUCJP");
549
          mbc_max = 3;
550
#ifdef _MB_CAPABLE
551
          l_wctomb = __eucjp_wctomb;
552
          l_mbtowc = __eucjp_mbtowc;
553
#endif
554
        }
555
#ifdef __CYGWIN__
556
      else if (!strcasecmp (charset, "EUCKR"))
557
        {
558
          strcpy (charset, "EUCKR");
559
          mbc_max = 2;
560
#ifdef _MB_CAPABLE
561
          l_wctomb = __kr_wctomb;
562
          l_mbtowc = __kr_mbtowc;
563
#endif
564
        }
565
#endif
566
      else
567
        return NULL;
568
    break;
569
    case 'S':
570
    case 's':
571
      if (strcasecmp (charset, "SJIS"))
572
        return NULL;
573
      strcpy (charset, "SJIS");
574
      mbc_max = 2;
575
#ifdef _MB_CAPABLE
576
      l_wctomb = __sjis_wctomb;
577
      l_mbtowc = __sjis_mbtowc;
578
#endif
579
    break;
580
    case 'I':
581
    case 'i':
582
      /* Must be exactly one of ISO-8859-1, [...] ISO-8859-16, except for
583
         ISO-8859-12. */
584
      if (strncasecmp (charset, "ISO-8859-", 9))
585
        return NULL;
586
      strncpy (charset, "ISO", 3);
587
      val = _strtol_r (p, charset + 9, &end, 10);
588
      if (val < 1 || val > 16 || val == 12 || *end)
589
        return NULL;
590
      mbc_max = 1;
591
#ifdef _MB_CAPABLE
592
#ifdef _MB_EXTENDED_CHARSETS_ISO
593
      l_wctomb = __iso_wctomb;
594
      l_mbtowc = __iso_mbtowc;
595
#else /* !_MB_EXTENDED_CHARSETS_ISO */
596
      l_wctomb = __ascii_wctomb;
597
      l_mbtowc = __ascii_mbtowc;
598
#endif /* _MB_EXTENDED_CHARSETS_ISO */
599
#endif
600
    break;
601
    case 'C':
602
    case 'c':
603
      if (charset[1] != 'P' && charset[1] != 'p')
604
        return NULL;
605
      strncpy (charset, "CP", 2);
606
      val = _strtol_r (p, charset + 2, &end, 10);
607
      if (*end)
608
        return NULL;
609
      switch (val)
610
        {
611
        case 437:
612
        case 720:
613
        case 737:
614
        case 775:
615
        case 850:
616
        case 852:
617
        case 855:
618
        case 857:
619
        case 858:
620
        case 862:
621
        case 866:
622
        case 874:
623
        case 1125:
624
        case 1250:
625
        case 1251:
626
        case 1252:
627
        case 1253:
628
        case 1254:
629
        case 1255:
630
        case 1256:
631
        case 1257:
632
        case 1258:
633
          mbc_max = 1;
634
#ifdef _MB_CAPABLE
635
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
636
          l_wctomb = __cp_wctomb;
637
          l_mbtowc = __cp_mbtowc;
638
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
639
          l_wctomb = __ascii_wctomb;
640
          l_mbtowc = __ascii_mbtowc;
641
#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
642
#endif
643
          break;
644
        default:
645
          return NULL;
646
        }
647
    break;
648
    case 'K':
649
    case 'k':
650
      if (!strcasecmp (charset, "KOI8-R"))
651
        strcpy (charset, "CP20866");
652
      else if (!strcasecmp (charset, "KOI8-U"))
653
        strcpy (charset, "CP21866");
654
      else
655
        return NULL;
656
      mbc_max = 1;
657
#ifdef _MB_CAPABLE
658
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
659
      l_wctomb = __cp_wctomb;
660
      l_mbtowc = __cp_mbtowc;
661
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
662
      l_wctomb = __ascii_wctomb;
663
      l_mbtowc = __ascii_mbtowc;
664
#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
665
#endif
666
      break;
667
    case 'A':
668
    case 'a':
669
      if (strcasecmp (charset, "ASCII"))
670
        return NULL;
671
      strcpy (charset, "ASCII");
672
      mbc_max = 1;
673
#ifdef _MB_CAPABLE
674
      l_wctomb = __ascii_wctomb;
675
      l_mbtowc = __ascii_mbtowc;
676
#endif
677
      break;
678
#ifdef __CYGWIN__
679
    case 'G':
680
    case 'g':
681
      if (strcasecmp (charset, "GBK"))
682
        return NULL;
683
      strcpy (charset, "GBK");
684
      mbc_max = 2;
685
#ifdef _MB_CAPABLE
686
      l_wctomb = __gbk_wctomb;
687
      l_mbtowc = __gbk_mbtowc;
688
#endif
689
      break;
690
    case 'B':
691
    case 'b':
692
      if (strcasecmp (charset, "BIG5"))
693
        return NULL;
694
      strcpy (charset, "BIG5");
695
      mbc_max = 2;
696
#ifdef _MB_CAPABLE
697
      l_wctomb = __big5_wctomb;
698
      l_mbtowc = __big5_mbtowc;
699
#endif
700
      break;
701
#endif /* __CYGWIN__ */
702
    default:
703
      return NULL;
704
    }
705
  if (category == LC_CTYPE)
706
    {
707
      strcpy (lc_ctype_charset, charset);
708
      __mb_cur_max = mbc_max;
709
#ifdef _MB_CAPABLE
710
      __wctomb = l_wctomb;
711
      __mbtowc = l_mbtowc;
712
      __set_ctype (charset);
713
      /* Check for the language part of the locale specifier.  In case
714
         of "ja", "ko", or "zh", assume the use of CJK fonts, unless the
715
         "@cjknarrow" modifier has been specifed.
716
         The result is stored in lc_ctype_cjk_lang and tested in wcwidth()
717
         to figure out the width to return (1 or 2) for the "CJK Ambiguous
718
         Width" category of characters. */
719
      lc_ctype_cjk_lang = !cjknarrow
720
                          && ((strncmp (locale, "ja", 2) == 0
721
                              || strncmp (locale, "ko", 2) == 0
722
                              || strncmp (locale, "zh", 2) == 0));
723
#endif
724
    }
725
  else if (category == LC_MESSAGES)
726
    strcpy (lc_message_charset, charset);
727
  return strcpy(current_categories[category], new_categories[category]);
728
}
729
 
730
static const char *
731
__get_locale_env(struct _reent *p, int category)
732
{
733
  const char *env;
734
 
735
  /* 1. check LC_ALL. */
736
  env = _getenv_r (p, categories[0]);
737
 
738
  /* 2. check LC_* */
739
  if (env == NULL || !*env)
740
    env = _getenv_r (p, categories[category]);
741
 
742
  /* 3. check LANG */
743
  if (env == NULL || !*env)
744
    env = _getenv_r (p, "LANG");
745
 
746
  /* 4. if none is set, fall to default locale */
747
  if (env == NULL || !*env)
748
    env = __default_locale;
749
 
750
  return env;
751
}
752
#endif
753
 
754
char *
755
_DEFUN_VOID(__locale_charset)
756
{
757
  return lc_ctype_charset;
758
}
759
 
760
char *
761
_DEFUN_VOID(__locale_msgcharset)
762
{
763
  return lc_message_charset;
764
}
765
 
766
int
767
_DEFUN_VOID(__locale_cjk_lang)
768
{
769
  return lc_ctype_cjk_lang;
770
}
771
 
772
struct lconv *
773
_DEFUN(_localeconv_r, (data),
774
      struct _reent *data)
775
{
776
  return (struct lconv *) &lconv;
777
}
778
 
779
#ifndef _REENT_ONLY
780
 
781
#ifndef __CYGWIN__
782
char *
783
_DEFUN(setlocale, (category, locale),
784
       int category _AND
785
       _CONST char *locale)
786
{
787
  return _setlocale_r (_REENT, category, locale);
788
}
789
#endif
790
 
791
struct lconv *
792
_DEFUN_VOID(localeconv)
793
{
794
  return _localeconv_r (_REENT);
795
}
796
 
797
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.