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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libc/] [i18n/] [v2_0/] [src/] [locale.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//========================================================================
2
//
3
//      locale.cxx
4
//
5
//      Implementation of ISO C internationalisation (i18n) locales
6
//
7
//========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    jlarmour
44
// Contributors: jjohnstn
45
// Date:         2000-04-18
46
// Purpose:     
47
// Description: 
48
// Usage:       
49
//
50
//####DESCRIPTIONEND####
51
//
52
//========================================================================
53
 
54
// CONFIGURATION
55
 
56
#include <pkgconf/libc_i18n.h>     // Configuration header
57
 
58
// INCLUDES
59
 
60
#include <cyg/infra/cyg_type.h>    // Common type definitions and support
61
#include <cyg/infra/cyg_trac.h>    // Common tracing support
62
#include <cyg/infra/cyg_ass.h>     // Common assertion support
63
#include <locale.h>                // struct lconv
64
#include <string.h>                // several string functions
65
#include <limits.h>                // CHAR_MAX
66
#include "internal.h"              // locale type definitions
67
 
68
// CONSTANTS
69
 
70
// define the "C" locale
71
static const Cyg_libc_locale_t
72
C_locale = {
73
  "C",
74
  { ".", "", "", "", "", "", "", "", "", "",
75
    CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
76
    CHAR_MAX, CHAR_MAX
77
  },
78
  1,
79
  NULL,
80
  NULL,
81
};
82
 
83
// define the "C-EUCJP" locale (C locale with Japanese EUCJP mb support)
84
#ifdef CYGFUN_LIBC_I18N_LOCALE_C_EUCJP
85
static const Cyg_libc_locale_t
86
C_EUCJP_locale = {
87
  "C-EUCJP",
88
  { ".", "", "", "", "", "", "", "", "", "",
89
    CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
90
    CHAR_MAX, CHAR_MAX
91
  },
92
  2,
93
  &__mbtowc_jp,
94
  &__wctomb_jp,
95
};
96
#endif
97
 
98
// define the "C-SJIS" locale (C locale with Japanese SJIS mb support)
99
#ifdef CYGFUN_LIBC_I18N_LOCALE_C_SJIS
100
static const Cyg_libc_locale_t
101
C_SJIS_locale = {
102
  "C-SJIS",
103
  { ".", "", "", "", "", "", "", "", "", "",
104
    CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
105
    CHAR_MAX, CHAR_MAX
106
  },
107
  2,
108
  &__mbtowc_jp,
109
  &__wctomb_jp,
110
};
111
#endif
112
 
113
// define the "C-JIS" locale (C locale with Japanese JIS mb support)
114
#ifdef CYGFUN_LIBC_I18N_LOCALE_C_JIS
115
static const Cyg_libc_locale_t
116
C_JIS_locale = {
117
  "C-JIS",
118
  { ".", "", "", "", "", "", "", "", "", "",
119
    CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
120
    CHAR_MAX, CHAR_MAX
121
  },
122
  8,
123
  &__mbtowc_jp,
124
  &__wctomb_jp,
125
};
126
#endif
127
 
128
// only one locale now, but leave room for expansion
129
static const Cyg_libc_locale_t *all_locales[] = { &C_locale,
130
#ifdef CYGFUN_LIBC_I18N_LOCALE_C_EUCJP
131
                                                  &C_EUCJP_locale,
132
#endif
133
#ifdef CYGFUN_LIBC_I18N_LOCALE_C_SJIS
134
                                                  &C_SJIS_locale,
135
#endif
136
#ifdef CYGFUN_LIBC_I18N_LOCALE_C_JIS
137
                                                  &C_JIS_locale,
138
#endif
139
};
140
 
141
// GLOBALS
142
 
143
// the maximum size of a multibyte character including state info
144
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
145
int __mb_cur_max = 1;
146
#endif
147
 
148
// the current locales. Our default is the C locale
149
static const Cyg_libc_locale_t *current_collate_locale  = &C_locale;
150
const        Cyg_libc_locale_t *__current_ctype_locale  = &C_locale;
151
static const Cyg_libc_locale_t *current_monetary_locale = &C_locale;
152
static const Cyg_libc_locale_t *current_numeric_locale  = &C_locale;
153
static const Cyg_libc_locale_t *current_time_locale     = &C_locale;
154
 
155
// FUNCTIONS
156
 
157
static const Cyg_libc_locale_t *
158
find_locale_data( const char *locale_str, cyg_ucount32 checklen )
159
{
160
    CYG_REPORT_FUNCNAMETYPE( "find_locale_data", "returning %08x" );
161
    CYG_REPORT_FUNCARG1( "locale_str=%s", locale_str );
162
 
163
    const Cyg_libc_locale_t *temp_locale, *curr_locale=NULL;
164
    cyg_ucount32 i;
165
 
166
    // is it "" i.e. use the default?
167
    if (*locale_str=='\0') {
168
        curr_locale = &C_locale;
169
        CYG_REPORT_RETVAL( curr_locale );
170
        return curr_locale;
171
    } // if
172
 
173
    for (i=0; i<sizeof(all_locales)/sizeof(Cyg_libc_locale_t *); i++ ) {
174
 
175
        temp_locale = all_locales[i];
176
 
177
        if ( !strncmp(temp_locale->name, locale_str, checklen) )
178
            curr_locale = temp_locale;
179
    } // for
180
 
181
    CYG_REPORT_RETVAL( curr_locale );
182
    return curr_locale;
183
} // find_locale_data()
184
 
185
typedef int (*mbtowc_fn_type)(wchar_t *, const char *, size_t, int *);
186
// routine used to export mbtowc function to I/O routines
187
externC mbtowc_fn_type
188
__get_current_locale_mbtowc_fn ()
189
{
190
    if (__current_ctype_locale->mbtowc_fn)
191
      return __current_ctype_locale->mbtowc_fn;
192
    return &__mbtowc_c;
193
}
194
 
195
externC char *
196
setlocale( int category, const char *locale )
197
{
198
    CYG_REPORT_FUNCNAMETYPE("setlocale", "returning %08x");
199
    CYG_REPORT_FUNCARG2( "category=%d, locale=%s", category, locale );
200
 
201
    if (locale != NULL)
202
        CYG_CHECK_DATA_PTR( locale, "locale pointer is invalid!" );
203
 
204
    const char *str;
205
 
206
    // special case if locale==NULL, return current locale name
207
    if (locale==NULL) {
208
 
209
        CYG_TRACE0( true, "Getting current locale value" );
210
 
211
        switch (category) {
212
 
213
        case LC_COLLATE:
214
            str = current_collate_locale->name;
215
            break;
216
        case LC_CTYPE:
217
            str = __current_ctype_locale->name;
218
            break;
219
        case LC_MONETARY:
220
            str = current_monetary_locale->name;
221
            break;
222
        case LC_NUMERIC:
223
            str = current_numeric_locale->name;
224
            break;
225
        case LC_TIME:
226
            str = current_time_locale->name;
227
            break;
228
        case LC_ALL:
229
 
230
            // create static string to give a constructed string back
231
            // to the user. The size is the number of categories other
232
            // than LC_ALL times the maximum name size, and add a constant
233
            // for the delimiting octothorpes
234
            static char my_str[ CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE*5+10 ];
235
 
236
            strcpy( my_str, "#" );
237
            strcat( my_str, current_collate_locale->name );
238
            strcat( my_str, "#" );
239
            strcat( my_str, __current_ctype_locale->name );
240
            strcat( my_str, "#" );
241
            strcat( my_str, current_monetary_locale->name );
242
            strcat( my_str, "#" );
243
            strcat( my_str, current_numeric_locale->name );
244
            strcat( my_str, "#" );
245
            strcat( my_str, current_time_locale->name );
246
            strcat( my_str, "#" );
247
 
248
            str = &my_str[0];
249
            break;
250
        default:
251
            str=NULL;
252
            CYG_FAIL("setlocale() passed bad category!" );
253
            break;
254
 
255
        } // switch
256
 
257
        CYG_REPORT_RETVAL( (char *)str);
258
        return (char *)str;
259
    } // if
260
 
261
    // we only get here if locale is non-NULL, i.e. we want to set it
262
 
263
    const Cyg_libc_locale_t *loc;
264
    cyg_bool default_locale = (*locale=='\0');
265
 
266
    CYG_TRACE0( true, "Setting current locale value" );
267
 
268
    switch( category ) {
269
    case LC_COLLATE:
270
        loc = find_locale_data( locale, CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE );
271
        if (loc != NULL)      // found it
272
            current_collate_locale=loc;
273
        break;
274
 
275
    case LC_CTYPE:
276
        loc = find_locale_data( locale, CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE );
277
        if (loc != NULL)      // found it
278
          {
279
            __current_ctype_locale=loc;
280
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
281
            __mb_cur_max = loc->mb_cur_max;
282
#endif
283
          }
284
        break;
285
 
286
    case LC_MONETARY:
287
        loc = find_locale_data( locale, CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE );
288
        if (loc != NULL)      // found it
289
            current_monetary_locale=loc;
290
        break;
291
 
292
    case LC_NUMERIC:
293
        loc = find_locale_data( locale, CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE );
294
        if (loc != NULL)      // found it
295
            current_numeric_locale=loc;
296
        break;
297
 
298
    case LC_TIME:
299
        loc = find_locale_data( locale, CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE );
300
        if (loc != NULL)      // found it
301
            current_time_locale=loc;
302
        break;
303
 
304
    case LC_ALL:
305
        // first try and match it exactly
306
        loc = find_locale_data( locale, CYGNUM_LIBC_I18N_MAX_LOCALE_NAME_SIZE );
307
        if (loc != NULL) {     // found it
308
 
309
            CYG_TRACE0(true, "Matched locale string exactly");
310
            current_collate_locale = __current_ctype_locale = loc;
311
            current_monetary_locale = current_numeric_locale = loc;
312
            current_time_locale = loc;
313
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
314
            __mb_cur_max = loc->mb_cur_max;
315
#endif
316
        } // if
317
        else {
318
            CYG_TRACE0( true, "Attempting to parse string previously "
319
                        "returned from setlocale()" );
320
            // now try and see if it is a compound string returned
321
            // earlier by setlocale( LC_ALL, NULL );
322
 
323
            // Note we don't do much checking here. This could be
324
            // much more rigorous (but at the expense of speed/size?)
325
 
326
            const Cyg_libc_locale_t *temp_collate_locale,
327
                *temp_ctype_locale, *temp_monetary_locale,
328
                *temp_numeric_locale, *temp_time_locale;
329
 
330
            cyg_ucount32 token_len;
331
 
332
            str = &locale[0];
333
            if ( *str=='#' ) {
334
                ++str;
335
                token_len = strcspn( str, "#" );
336
                loc = find_locale_data( str, token_len );
337
 
338
                if (loc!=NULL) {
339
                    temp_collate_locale=loc;
340
                    str += token_len+1;
341
                    token_len = strcspn( str, "#" );
342
                    loc = find_locale_data( str, token_len );
343
 
344
                    if (loc!=NULL) {
345
                        temp_ctype_locale=loc;
346
                        str += token_len+1;
347
                        token_len = strcspn( str, "#" );
348
                        loc = find_locale_data( str, token_len );
349
 
350
                        if (loc!=NULL) {
351
                            temp_monetary_locale=loc;
352
                            str += token_len+1;
353
                            token_len = strcspn( str, "#" );
354
                            loc = find_locale_data( str, token_len );
355
 
356
                            if (loc!=NULL) {
357
                                temp_numeric_locale=loc;
358
                                str += token_len+1;
359
                                token_len = strcspn( str, "#" );
360
                                loc = find_locale_data( str, token_len );
361
 
362
                                if (loc!=NULL) {
363
                                    temp_time_locale=loc;
364
                                    str += token_len+1;
365
                                    token_len = strcspn( str, "#" );
366
                                    loc = find_locale_data( str, token_len );
367
 
368
                                    if (loc!=NULL) {
369
                      // if we've got this far and loc still isn't NULL,
370
                      // then everything's fine, and we've matched everything
371
 
372
                      current_collate_locale = temp_collate_locale;
373
                      __current_ctype_locale = temp_ctype_locale;
374
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
375
                      __mb_cur_max = temp_ctype_locale->mb_cur_max;
376
#endif
377
                      current_monetary_locale = temp_monetary_locale;
378
                      current_numeric_locale = temp_numeric_locale;
379
                      current_time_locale = temp_time_locale;
380
 
381
                                    } // if
382
                                } // if
383
                            } // if
384
                        } // if
385
                    } // if
386
                } // if
387
            } // if
388
 
389
        } // else
390
        break; // case LC_ALL
391
 
392
    default:
393
            CYG_FAIL("setlocale() passed bad category!" );
394
            loc=NULL;
395
            break;
396
    } // switch
397
 
398
    if (loc==NULL) {
399
        CYG_REPORT_RETVAL( NULL );
400
        return NULL;
401
    } // if
402
    else if (default_locale==true) {
403
        CYG_REPORT_RETVAL(C_locale.name);
404
        return (char *)C_locale.name;
405
    } // else if
406
    else {
407
        CYG_REPORT_RETVAL(locale);
408
        return (char *)locale;
409
    } // else
410
} // setlocale()
411
 
412
externC struct lconv *
413
localeconv( void )
414
{
415
    CYG_REPORT_FUNCNAMETYPE( "localeconv", "returning %08x" );
416
    CYG_REPORT_FUNCARGVOID();
417
 
418
    static struct lconv static_lconv;
419
 
420
    static_lconv.decimal_point =
421
        current_numeric_locale->numdata.decimal_point;
422
 
423
    static_lconv.thousands_sep =
424
        current_numeric_locale->numdata.thousands_sep;
425
 
426
    static_lconv.grouping =
427
        current_numeric_locale->numdata.grouping;
428
 
429
    // we cheat a bit, but it should be worth it - a lot of these are
430
    // constants which optimise nicely
431
    cyg_ucount32 size_used;
432
    size_used = (char *)&static_lconv.int_curr_symbol -
433
                (char *)&static_lconv;
434
 
435
    memcpy( &(static_lconv.int_curr_symbol),
436
            &(current_monetary_locale->numdata.int_curr_symbol),
437
            sizeof(struct lconv) - size_used );
438
 
439
 
440
    CYG_REPORT_RETVAL( &static_lconv );
441
    return &static_lconv;
442
} // localeconv()
443
 
444
// EOF locale.cxx

powered by: WebSVN 2.1.0

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