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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [stdlib/] [stdlib.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*  Copyright (C) 2002     Manuel Novoa III
2
 *  From my (incomplete) stdlib library for linux and (soon) elks.
3
 *
4
 *  This library is free software; you can redistribute it and/or
5
 *  modify it under the terms of the GNU Library General Public
6
 *  License as published by the Free Software Foundation; either
7
 *  version 2 of the License, or (at your option) any later version.
8
 *
9
 *  This library 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 GNU
12
 *  Library General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU Library General Public
15
 *  License along with this library; if not, write to the Free
16
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
 */
18
 
19
/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
20
 *
21
 *  This code is currently under development.  Also, I plan to port
22
 *  it to elks which is a 16-bit environment with a fairly limited
23
 *  compiler.  Therefore, please refrain from modifying this code
24
 *  and, instead, pass any bug-fixes, etc. to me.  Thanks.  Manuel
25
 *
26
 *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
27
 
28
/* Oct 29, 2002
29
 * Fix a couple of 'restrict' bugs in mbstowcs and wcstombs.
30
 *
31
 * Nov 21, 2002
32
 * Add wscto{inttype} functions.
33
 */
34
 
35
#define _ISOC99_SOURCE                  /* for ULLONG primarily... */
36
#define _GNU_SOURCE
37
#include <limits.h>
38
#include <stdint.h>
39
#include <inttypes.h>
40
#include <ctype.h>
41
#include <errno.h>
42
#include <assert.h>
43
#include <unistd.h>
44
 
45
/* Work around gcc's refusal to create aliases.
46
 * TODO: Add in a define to disable the aliases? */
47
 
48
#if UINT_MAX == ULONG_MAX
49
#define atoi __ignore_atoi
50
#define abs __ignore_abs
51
#endif
52
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
53
#define llabs __ignore_llabs
54
#define atoll __ignore_atoll
55
#define strtoll __ignore_strtoll
56
#define strtoull __ignore_strtoull
57
#define wcstoll __ignore_wcstoll
58
#define wcstoull __ignore_wcstoull
59
#define strtoll_l __ignore_strtoll_l
60
#define strtoull_l __ignore_strtoull_l
61
#define wcstoll_l __ignore_wcstoll_l
62
#define wcstoull_l __ignore_wcstoull_l
63
#endif
64
 
65
#include <stdlib.h>
66
#include <locale.h>
67
 
68
#ifdef __UCLIBC_HAS_WCHAR__
69
 
70
#include <wchar.h>
71
#include <wctype.h>
72
#include <bits/uClibc_uwchar.h>
73
 
74
#ifdef __UCLIBC_HAS_XLOCALE__
75
#include <xlocale.h>
76
#endif /* __UCLIBC_HAS_XLOCALE__ */
77
 
78
/* TODO: clean up the following... */
79
 
80
#if WCHAR_MAX > 0xffffUL
81
#define UTF_8_MAX_LEN 6
82
#else
83
#define UTF_8_MAX_LEN 3
84
#endif
85
 
86
#ifdef __UCLIBC_HAS_LOCALE__
87
 
88
#define ENCODING                ((__UCLIBC_CURLOCALE_DATA).encoding)
89
#ifndef __CTYPE_HAS_UTF_8_LOCALES
90
#ifdef L_mblen
91
/* emit only once */
92
#warning __CTYPE_HAS_UTF_8_LOCALES not set!
93
#endif
94
#endif
95
 
96
#else  /* __UCLIBC_HAS_LOCALE__ */
97
 
98
#ifdef __UCLIBC_MJN3_ONLY__
99
#ifdef L_mblen
100
/* emit only once */
101
#warning devel checks
102
#endif
103
#endif
104
#ifdef __CTYPE_HAS_8_BIT_LOCALES
105
#error __CTYPE_HAS_8_BIT_LOCALES is defined!
106
#endif
107
#ifdef __CTYPE_HAS_UTF_8_LOCALES
108
#error __CTYPE_HAS_UTF_8_LOCALES is defined!
109
#endif
110
#endif
111
 
112
#endif /* __UCLIBC_HAS_LOCALE__ */
113
 
114
#if UINT_MAX == ULONG_MAX
115
#undef atoi
116
#undef abs
117
#endif
118
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
119
#undef llabs
120
#undef atoll
121
#undef strtoll
122
#undef strtoull
123
#undef wcstoll
124
#undef wcstoull
125
#undef strtoll_l
126
#undef strtoull_l
127
#undef wcstoll_l
128
#undef wcstoull_l
129
#endif /* __UCLIBC_HAS_WCHAR__ */
130
 
131
/**********************************************************************/
132
#ifdef __UCLIBC_HAS_XLOCALE__
133
 
134
extern unsigned long
135
_stdlib_strto_l_l(register const char * __restrict str,
136
                                  char ** __restrict endptr, int base, int sflag,
137
                                  __locale_t locale_arg);
138
 
139
#if defined(ULLONG_MAX)
140
extern unsigned long long
141
_stdlib_strto_ll_l(register const char * __restrict str,
142
                                   char ** __restrict endptr, int base, int sflag,
143
                                  __locale_t locale_arg);
144
#endif
145
 
146
#ifdef __UCLIBC_HAS_WCHAR__
147
extern unsigned long
148
_stdlib_wcsto_l_l(register const wchar_t * __restrict str,
149
                                  wchar_t ** __restrict endptr, int base, int sflag,
150
                                  __locale_t locale_arg);
151
 
152
#if defined(ULLONG_MAX)
153
extern unsigned long long
154
_stdlib_wcsto_ll_l(register const wchar_t * __restrict str,
155
                                   wchar_t ** __restrict endptr, int base, int sflag,
156
                                  __locale_t locale_arg);
157
#endif
158
#endif /* __UCLIBC_HAS_WCHAR__ */
159
 
160
#endif /* __UCLIBC_HAS_XLOCALE__ */
161
 
162
 
163
 
164
extern unsigned long
165
_stdlib_strto_l(register const char * __restrict str,
166
                                char ** __restrict endptr, int base, int sflag);
167
 
168
#if defined(ULLONG_MAX)
169
extern unsigned long long
170
_stdlib_strto_ll(register const char * __restrict str,
171
                                 char ** __restrict endptr, int base, int sflag);
172
#endif
173
 
174
#ifdef __UCLIBC_HAS_WCHAR__
175
extern unsigned long
176
_stdlib_wcsto_l(register const wchar_t * __restrict str,
177
                                wchar_t ** __restrict endptr, int base, int sflag);
178
 
179
#if defined(ULLONG_MAX)
180
extern unsigned long long
181
_stdlib_wcsto_ll(register const wchar_t * __restrict str,
182
                                 wchar_t ** __restrict endptr, int base, int sflag);
183
#endif
184
#endif /* __UCLIBC_HAS_WCHAR__ */
185
/**********************************************************************/
186
#ifdef L_atof
187
 
188
double atof(const char *nptr)
189
{
190
        return strtod(nptr, (char **) NULL);
191
}
192
 
193
#endif
194
/**********************************************************************/
195
#ifdef L_abs
196
 
197
#if INT_MAX < LONG_MAX
198
 
199
int abs(int j)
200
{
201
        return (j >= 0) ? j : -j;
202
}
203
 
204
#endif /* INT_MAX < LONG_MAX */
205
 
206
#endif
207
/**********************************************************************/
208
#ifdef L_labs
209
 
210
#if UINT_MAX == ULONG_MAX
211
strong_alias(labs,abs)
212
#endif
213
 
214
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
215
strong_alias(labs,llabs)
216
#endif
217
 
218
#if ULONG_MAX == UINTMAX_MAX
219
strong_alias(labs,imaxabs)
220
#endif
221
 
222
long int labs(long int j)
223
{
224
        return (j >= 0) ? j : -j;
225
}
226
 
227
#endif
228
/**********************************************************************/
229
#ifdef L_llabs
230
 
231
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
232
 
233
#if (ULLONG_MAX == UINTMAX_MAX)
234
strong_alias(llabs,imaxabs)
235
#endif
236
 
237
long long int llabs(long long int j)
238
{
239
        return (j >= 0) ? j : -j;
240
}
241
 
242
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
243
 
244
#endif
245
/**********************************************************************/
246
#ifdef L_atoi
247
 
248
#if INT_MAX < LONG_MAX 
249
 
250
int atoi(const char *nptr)
251
{
252
        return (int) strtol(nptr, (char **) NULL, 10);
253
}
254
 
255
#endif /* INT_MAX < LONG_MAX  */
256
 
257
#endif
258
/**********************************************************************/
259
#ifdef L_atol
260
 
261
#if UINT_MAX == ULONG_MAX
262
strong_alias(atol,atoi)
263
#endif
264
 
265
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
266
strong_alias(atol,atoll)
267
#endif
268
 
269
long atol(const char *nptr)
270
{
271
        return strtol(nptr, (char **) NULL, 10);
272
}
273
 
274
#endif
275
/**********************************************************************/
276
#ifdef L_atoll
277
 
278
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
279
 
280
long long atoll(const char *nptr)
281
{
282
        return strtoll(nptr, (char **) NULL, 10);
283
}
284
 
285
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
286
 
287
#endif
288
/**********************************************************************/
289
#if defined(L_strtol) || defined(L_strtol_l)
290
 
291
#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtol_l)
292
strong_alias(strtol,strtoimax)
293
#endif
294
 
295
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
296
strong_alias(__XL(strtol),__XL(strtoll))
297
#endif
298
 
299
long __XL(strtol)(const char * __restrict str, char ** __restrict endptr,
300
                                  int base   __LOCALE_PARAM )
301
{
302
    return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1   __LOCALE_ARG );
303
}
304
 
305
__XL_ALIAS(strtol)
306
 
307
#endif
308
/**********************************************************************/
309
#if defined(L_strtoll) || defined(L_strtoll_l)
310
 
311
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
312
 
313
#if !defined(L_strtoll_l)
314
#if (ULLONG_MAX == UINTMAX_MAX)
315
strong_alias(strtoll,strtoimax)
316
#endif
317
strong_alias(strtoll,strtoq)
318
#endif
319
 
320
long long __XL(strtoll)(const char * __restrict str,
321
                                                char ** __restrict endptr, int base
322
                                                __LOCALE_PARAM )
323
{
324
    return (long long) __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 1
325
                                                                                                  __LOCALE_ARG );
326
}
327
 
328
__XL_ALIAS(strtoll)
329
 
330
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
331
 
332
#endif
333
/**********************************************************************/
334
#if defined(L_strtoul) || defined(L_strtoul_l)
335
 
336
#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_strtoul_l)
337
strong_alias(strtoul,strtoumax)
338
#endif
339
 
340
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
341
strong_alias(__XL(strtoul),__XL(strtoull))
342
#endif
343
 
344
unsigned long __XL(strtoul)(const char * __restrict str,
345
                                                        char ** __restrict endptr, int base
346
                                                        __LOCALE_PARAM )
347
{
348
    return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0   __LOCALE_ARG );
349
}
350
 
351
__XL_ALIAS(strtoul)
352
 
353
#endif
354
/**********************************************************************/
355
#if defined(L_strtoull) || defined(L_strtoull_l)
356
 
357
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
358
 
359
#if !defined(L_strtoull_l)
360
#if (ULLONG_MAX == UINTMAX_MAX)
361
strong_alias(strtoull,strtoumax)
362
#endif
363
strong_alias(strtoull,strtouq)
364
#endif
365
 
366
unsigned long long __XL(strtoull)(const char * __restrict str,
367
                                                                  char ** __restrict endptr, int base
368
                                                                  __LOCALE_PARAM )
369
{
370
    return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0   __LOCALE_ARG );
371
}
372
 
373
__XL_ALIAS(strtoull)
374
 
375
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
376
 
377
#endif
378
/**********************************************************************/
379
/* Support routines follow */
380
/**********************************************************************/
381
/* Set if we want errno set appropriately. */
382
/* NOTE: Implies _STRTO_ENDPTR below */
383
#define _STRTO_ERRNO            1
384
 
385
/* Set if we want support for the endptr arg. */
386
/* Implied by _STRTO_ERRNO. */
387
#define _STRTO_ENDPTR           1
388
 
389
#if _STRTO_ERRNO
390
#undef _STRTO_ENDPTR
391
#define _STRTO_ENDPTR           1
392
#define SET_ERRNO(X)            __set_errno(X)
393
#else
394
#define SET_ERRNO(X)            ((void)(X))     /* keep side effects */
395
#endif
396
 
397
/**********************************************************************/
398
#if defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l)
399
#define L__stdlib_strto_l
400
#endif
401
 
402
#if defined(L__stdlib_strto_l) || defined(L__stdlib_strto_l_l)
403
 
404
#if defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l)
405
 
406
#define _stdlib_strto_l _stdlib_wcsto_l
407
#define _stdlib_strto_l_l _stdlib_wcsto_l_l
408
#define Wchar wchar_t
409
#define Wuchar __uwchar_t
410
#ifdef __UCLIBC_DO_XLOCALE
411
#define ISSPACE(C) iswspace_l((C), locale_arg)
412
#else
413
#define ISSPACE(C) iswspace((C))
414
#endif
415
 
416
#else  /* defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l) */
417
 
418
#define Wchar char
419
#define Wuchar unsigned char
420
#ifdef __UCLIBC_DO_XLOCALE
421
#define ISSPACE(C) isspace_l((C), locale_arg)
422
#else
423
#define ISSPACE(C) isspace((C))
424
#endif
425
 
426
#endif /* defined(L__stdlib_wcsto_l) || defined(L__stdlib_wcsto_l_l) */
427
 
428
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
429
 
430
unsigned long _stdlib_strto_l(register const Wchar * __restrict str,
431
                                                          Wchar ** __restrict endptr, int base,
432
                                                          int sflag)
433
{
434
        return _stdlib_strto_l_l(str, endptr, base, sflag, __UCLIBC_CURLOCALE);
435
}
436
 
437
 
438
#else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
439
 
440
/* This is the main work fuction which handles both strtol (sflag = 1) and
441
 * strtoul (sflag = 0). */
442
 
443
unsigned long __XL_NPP(_stdlib_strto_l)(register const Wchar * __restrict str,
444
                                                                                Wchar ** __restrict endptr, int base,
445
                                                                                int sflag   __LOCALE_PARAM )
446
{
447
    unsigned long number, cutoff;
448
#if _STRTO_ENDPTR
449
    const Wchar *fail_char;
450
#define SET_FAIL(X)       fail_char = (X)
451
#else
452
#define SET_FAIL(X)       ((void)(X)) /* Keep side effects. */
453
#endif
454
    unsigned char negative, digit, cutoff_digit;
455
 
456
        assert(((unsigned int)sflag) <= 1);
457
 
458
        SET_FAIL(str);
459
 
460
    while (ISSPACE(*str)) { /* Skip leading whitespace. */
461
                ++str;
462
    }
463
 
464
    /* Handle optional sign. */
465
    negative = 0;
466
    switch(*str) {
467
                case '-': negative = 1; /* Fall through to increment str. */
468
                case '+': ++str;
469
    }
470
 
471
    if (!(base & ~0x10)) {              /* Either dynamic (base = 0) or base 16. */
472
                base += 10;                             /* Default is 10 (26). */
473
                if (*str == '0') {
474
                        SET_FAIL(++str);
475
                        base -= 2;                      /* Now base is 8 or 16 (24). */
476
                        if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
477
                                ++str;
478
                                base += base;   /* Base is 16 (16 or 48). */
479
                        }
480
                }
481
 
482
                if (base > 16) {                /* Adjust in case base wasn't dynamic. */
483
                        base = 16;
484
                }
485
    }
486
 
487
        number = 0;
488
 
489
    if (((unsigned)(base - 2)) < 35) { /* Legal base. */
490
                cutoff_digit = ULONG_MAX % base;
491
                cutoff = ULONG_MAX / base;
492
                do {
493
                        digit = (((Wuchar)(*str - '0')) <= 9)
494
                                ? (*str - '0')
495
                                : ((*str >= 'A')
496
                                   ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
497
                                          : 40);
498
 
499
                        if (digit >= base) {
500
                                break;
501
                        }
502
 
503
                        SET_FAIL(++str);
504
 
505
                        if ((number > cutoff)
506
                                || ((number == cutoff) && (digit > cutoff_digit))) {
507
                                number = ULONG_MAX;
508
                                negative &= sflag;
509
                                SET_ERRNO(ERANGE);
510
                        } else {
511
                                number = number * base + digit;
512
                        }
513
                } while (1);
514
        }
515
 
516
#if _STRTO_ENDPTR
517
    if (endptr) {
518
                *endptr = (Wchar *) fail_char;
519
    }
520
#endif
521
 
522
        {
523
                unsigned long tmp = ((negative)
524
                                                         ? ((unsigned long)(-(1+LONG_MIN)))+1
525
                                                         : LONG_MAX);
526
                if (sflag && (number > tmp)) {
527
                        number = tmp;
528
                        SET_ERRNO(ERANGE);
529
                }
530
        }
531
 
532
        return negative ? (unsigned long)(-((long)number)) : number;
533
}
534
 
535
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
536
 
537
 
538
#endif
539
/**********************************************************************/
540
#if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)
541
#define L__stdlib_strto_ll
542
#endif
543
 
544
#if defined(L__stdlib_strto_ll) || defined(L__stdlib_strto_ll_l)
545
 
546
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
547
 
548
#if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)
549
#define _stdlib_strto_ll _stdlib_wcsto_ll
550
#define _stdlib_strto_ll_l _stdlib_wcsto_ll_l
551
#define Wchar wchar_t
552
#define Wuchar __uwchar_t
553
#ifdef __UCLIBC_DO_XLOCALE
554
#define ISSPACE(C) iswspace_l((C), locale_arg)
555
#else
556
#define ISSPACE(C) iswspace((C))
557
#endif
558
 
559
#else  /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */
560
 
561
#define Wchar char
562
#define Wuchar unsigned char
563
#ifdef __UCLIBC_DO_XLOCALE
564
#define ISSPACE(C) isspace_l((C), locale_arg)
565
#else
566
#define ISSPACE(C) isspace((C))
567
#endif
568
 
569
#endif /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */
570
 
571
#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
572
 
573
unsigned long long _stdlib_strto_ll(register const Wchar * __restrict str,
574
                                                                        Wchar ** __restrict endptr, int base,
575
                                                                        int sflag)
576
{
577
        return _stdlib_strto_ll_l(str, endptr, base, sflag, __UCLIBC_CURLOCALE);
578
}
579
 
580
 
581
#else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
582
 
583
/* This is the main work fuction which handles both strtoll (sflag = 1) and
584
 * strtoull (sflag = 0). */
585
 
586
unsigned long long __XL_NPP(_stdlib_strto_ll)(register const Wchar * __restrict str,
587
                                                                                          Wchar ** __restrict endptr, int base,
588
                                                                                          int sflag   __LOCALE_PARAM )
589
{
590
    unsigned long long number;
591
#if _STRTO_ENDPTR
592
    const Wchar *fail_char;
593
#define SET_FAIL(X)       fail_char = (X)
594
#else
595
#define SET_FAIL(X)       ((void)(X)) /* Keep side effects. */
596
#endif
597
        unsigned int n1;
598
    unsigned char negative, digit;
599
 
600
        assert(((unsigned int)sflag) <= 1);
601
 
602
        SET_FAIL(str);
603
 
604
    while (ISSPACE(*str)) {             /* Skip leading whitespace. */
605
                ++str;
606
    }
607
 
608
    /* Handle optional sign. */
609
    negative = 0;
610
    switch(*str) {
611
                case '-': negative = 1; /* Fall through to increment str. */
612
                case '+': ++str;
613
    }
614
 
615
    if (!(base & ~0x10)) {              /* Either dynamic (base = 0) or base 16. */
616
                base += 10;                             /* Default is 10 (26). */
617
                if (*str == '0') {
618
                        SET_FAIL(++str);
619
                        base -= 2;                      /* Now base is 8 or 16 (24). */
620
                        if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
621
                                ++str;
622
                                base += base;   /* Base is 16 (16 or 48). */
623
                        }
624
                }
625
 
626
                if (base > 16) {                /* Adjust in case base wasn't dynamic. */
627
                        base = 16;
628
                }
629
    }
630
 
631
        number = 0;
632
 
633
    if (((unsigned)(base - 2)) < 35) { /* Legal base. */
634
                do {
635
                        digit = (((Wuchar)(*str - '0')) <= 9)
636
                                ? (*str - '0')
637
                                : ((*str >= 'A')
638
                                   ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
639
                                          : 40);
640
 
641
                        if (digit >= base) {
642
                                break;
643
                        }
644
 
645
                        SET_FAIL(++str);
646
 
647
#if 1
648
                        /* Optional, but speeds things up in the usual case. */
649
                        if (number <= (ULLONG_MAX >> 6)) {
650
                                number = number * base + digit;
651
                        } else
652
#endif
653
                        {
654
                                n1 = ((unsigned char) number) * base + digit;
655
                                number = (number >> CHAR_BIT) * base;
656
 
657
                                if (number + (n1 >> CHAR_BIT) <= (ULLONG_MAX >> CHAR_BIT)) {
658
                                        number = (number << CHAR_BIT) + n1;
659
                                } else {                /* Overflow. */
660
                                        number = ULLONG_MAX;
661
                                        negative &= sflag;
662
                                        SET_ERRNO(ERANGE);
663
                                }
664
                        }
665
 
666
                } while (1);
667
        }
668
 
669
#if _STRTO_ENDPTR
670
    if (endptr) {
671
                *endptr = (Wchar *) fail_char;
672
    }
673
#endif
674
 
675
        {
676
                unsigned long long tmp = ((negative)
677
                                                                  ? ((unsigned long long)(-(1+LLONG_MIN)))+1
678
                                                                  : LLONG_MAX);
679
                if (sflag && (number > tmp)) {
680
                        number = tmp;
681
                        SET_ERRNO(ERANGE);
682
                }
683
        }
684
 
685
        return negative ? (unsigned long long)(-((long long)number)) : number;
686
}
687
 
688
#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
689
 
690
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
691
 
692
#endif
693
/**********************************************************************/
694
/* Made _Exit() an alias for _exit(), as per C99. */
695
/*  #ifdef L__Exit */
696
 
697
/*  void _Exit(int status) */
698
/*  { */
699
/*      _exit(status); */
700
/*  } */
701
 
702
/*  #endif */
703
/**********************************************************************/
704
#ifdef L_bsearch
705
 
706
void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
707
                          size_t size, int (*compar)(const void *, const void *))
708
{
709
        register char *p;
710
        size_t low;
711
        size_t mid;
712
        int r;
713
 
714
        if (size > 0) {                          /* TODO: change this to an assert?? */
715
                low = 0;
716
                while (low < high) {
717
                        mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */
718
                        p = ((char *)base) + mid * size; /* Could overflow here... */
719
                        r = (*compar)(key, p); /* but that's an application problem! */
720
                        if (r > 0) {
721
                                low = mid + 1;
722
                        } else if (r < 0) {
723
                                high = mid;
724
                        } else {
725
                                return p;
726
                        }
727
                }
728
        }
729
        return NULL;
730
}
731
 
732
#endif
733
/**********************************************************************/
734
#ifdef L_qsort
735
 
736
/* This code is derived from a public domain shell sort routine by
737
 * Ray Gardner and found in Bob Stout's snippets collection.  The
738
 * original code is included below in an #if 0/#endif block.
739
 *
740
 * I modified it to avoid the possibility of overflow in the wgap
741
 * calculation, as well as to reduce the generated code size with
742
 * bcc and gcc. */
743
 
744
void qsort (void  *base,
745
            size_t nel,
746
            size_t width,
747
            int (*comp)(const void *, const void *))
748
{
749
        size_t wgap, i, j, k;
750
        char tmp;
751
 
752
        if ((nel > 1) && (width > 0)) {
753
                assert( nel <= ((size_t)(-1)) / width ); /* check for overflow */
754
                wgap = 0;
755
                do {
756
                        wgap = 3 * wgap + 1;
757
                } while (wgap < (nel-1)/3);
758
                /* From the above, we know that either wgap == 1 < nel or */
759
                /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap <  nel. */
760
                wgap *= width;                  /* So this can not overflow if wnel doesn't. */
761
                nel *= width;                   /* Convert nel to 'wnel' */
762
                do {
763
                        i = wgap;
764
                        do {
765
                                j = i;
766
                                do {
767
                                        register char *a;
768
                                        register char *b;
769
 
770
                                        j -= wgap;
771
                                        a = j + ((char *)base);
772
                                        b = a + wgap;
773
                                        if ( (*comp)(a, b) <= 0 ) {
774
                                                break;
775
                                        }
776
                                        k = width;
777
                                        do {
778
                                                tmp = *a;
779
                                                *a++ = *b;
780
                                                *b++ = tmp;
781
                                        } while ( --k );
782
                                } while (j >= wgap);
783
                                i += width;
784
                        } while (i < nel);
785
                        wgap = (wgap - width)/3;
786
                } while (wgap);
787
        }
788
}
789
 
790
/* ---------- original snippets version below ---------- */
791
 
792
#if 0
793
/*
794
**  ssort()  --  Fast, small, qsort()-compatible Shell sort
795
**
796
**  by Ray Gardner,  public domain   5/90
797
*/
798
 
799
#include <stddef.h>
800
 
801
void ssort (void  *base,
802
            size_t nel,
803
            size_t width,
804
            int (*comp)(const void *, const void *))
805
{
806
      size_t wnel, gap, wgap, i, j, k;
807
      char *a, *b, tmp;
808
 
809
      wnel = width * nel;
810
      for (gap = 0; ++gap < nel;)
811
            gap *= 3;
812
      while ( gap /= 3 )
813
      {
814
            wgap = width * gap;
815
            for (i = wgap; i < wnel; i += width)
816
            {
817
                  for (j = i - wgap; ;j -= wgap)
818
                  {
819
                        a = j + (char *)base;
820
                        b = a + wgap;
821
                        if ( (*comp)(a, b) <= 0 )
822
                              break;
823
                        k = width;
824
                        do
825
                        {
826
                              tmp = *a;
827
                              *a++ = *b;
828
                              *b++ = tmp;
829
                        } while ( --k );
830
                        if (j < wgap)
831
                              break;
832
                  }
833
            }
834
      }
835
}
836
#endif
837
 
838
#endif
839
/**********************************************************************/
840
#ifdef L__stdlib_mb_cur_max
841
 
842
size_t _stdlib_mb_cur_max(void)
843
{
844
#ifdef __CTYPE_HAS_UTF_8_LOCALES
845
        return __UCLIBC_CURLOCALE_DATA.mb_cur_max;
846
#else
847
#ifdef __CTYPE_HAS_8_BIT_LOCALES
848
#ifdef __UCLIBC_MJN3_ONLY__
849
#warning need to change this when/if transliteration is implemented
850
#endif
851
#endif
852
        return 1;
853
#endif
854
}
855
 
856
#endif
857
/**********************************************************************/
858
#ifdef L_mblen
859
 
860
int mblen(register const char *s, size_t n)
861
{
862
        static mbstate_t state;
863
        size_t r;
864
 
865
        if (!s) {
866
                state.mask = 0;
867
#ifdef __CTYPE_HAS_UTF_8_LOCALES
868
                return ENCODING == __ctype_encoding_utf8;
869
#else
870
                return 0;
871
#endif
872
        }
873
 
874
        if ((r = mbrlen(s, n, &state)) == (size_t) -2) {
875
                /* TODO: Should we set an error state? */
876
                state.wc = 0xffffU;             /* Make sure we're in an error state. */
877
                return (size_t) -1;             /* TODO: Change error code above? */
878
        }
879
        return r;
880
}
881
 
882
#endif
883
/**********************************************************************/
884
#ifdef L_mbtowc
885
 
886
int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n)
887
{
888
        static mbstate_t state;
889
        size_t r;
890
 
891
        if (!s) {
892
                state.mask = 0;
893
#ifdef __CTYPE_HAS_UTF_8_LOCALES
894
                return ENCODING == __ctype_encoding_utf8;
895
#else
896
                return 0;
897
#endif
898
        }
899
 
900
        if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) {
901
                /* TODO: Should we set an error state? */
902
                state.wc = 0xffffU;             /* Make sure we're in an error state. */
903
                return (size_t) -1;             /* TODO: Change error code above? */
904
        }
905
        return r;
906
}
907
 
908
#endif
909
/**********************************************************************/
910
#ifdef L_wctomb
911
 
912
/* Note: We completely ignore state in all currently supported conversions. */
913
 
914
int wctomb(register char *__restrict s, wchar_t swc)
915
{
916
        return (!s)
917
                ?
918
#ifdef __CTYPE_HAS_UTF_8_LOCALES
919
                (ENCODING == __ctype_encoding_utf8)
920
#else
921
 
922
#endif
923
                : ((ssize_t) wcrtomb(s, swc, NULL));
924
}
925
 
926
#endif
927
/**********************************************************************/
928
#ifdef L_mbstowcs
929
 
930
size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
931
{
932
        mbstate_t state;
933
        const char *e = s;                      /* Needed because of restrict. */
934
 
935
        state.mask = 0;                          /* Always start in initial shift state. */
936
        return mbsrtowcs(pwcs, &e, n, &state);
937
}
938
 
939
#endif
940
/**********************************************************************/
941
#ifdef L_wcstombs
942
 
943
/* Note: We completely ignore state in all currently supported conversions. */
944
 
945
size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
946
{
947
        const wchar_t *e = pwcs;        /* Needed because of restrict. */
948
 
949
        return wcsrtombs(s, &e, n, NULL);
950
}
951
 
952
#endif
953
/**********************************************************************/
954
#if defined(L_wcstol) || defined(L_wcstol_l)
955
 
956
#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstol_l)
957
strong_alias(wcstol,wcstoimax)
958
#endif
959
 
960
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
961
strong_alias(__XL(wcstol),__XL(wcstoll))
962
#endif
963
 
964
long __XL(wcstol)(const wchar_t * __restrict str,
965
                                  wchar_t ** __restrict endptr, int base   __LOCALE_PARAM )
966
{
967
    return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1   __LOCALE_ARG );
968
}
969
 
970
__XL_ALIAS(wcstol)
971
 
972
#endif
973
/**********************************************************************/
974
#if defined(L_wcstoll) || defined(L_wcstoll_l)
975
 
976
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
977
 
978
#if !defined(L_wcstoll_l)
979
#if (ULLONG_MAX == UINTMAX_MAX)
980
strong_alias(wcstoll,wcstoimax)
981
#endif
982
strong_alias(wcstoll,wcstoq)
983
#endif
984
 
985
long long __XL(wcstoll)(const wchar_t * __restrict str,
986
                                                wchar_t ** __restrict endptr, int base
987
                                                __LOCALE_PARAM )
988
{
989
    return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1
990
                                                                                                  __LOCALE_ARG );
991
}
992
 
993
__XL_ALIAS(wcstoll)
994
 
995
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
996
 
997
#endif
998
/**********************************************************************/
999
#if defined(L_wcstoul) || defined(L_wcstoul_l)
1000
 
1001
#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstoul_l)
1002
strong_alias(wcstoul,wcstoumax)
1003
#endif
1004
 
1005
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
1006
strong_alias(__XL(wcstoul),__XL(wcstoull))
1007
#endif
1008
 
1009
unsigned long __XL(wcstoul)(const wchar_t * __restrict str,
1010
                                                        wchar_t ** __restrict endptr, int base
1011
                                                        __LOCALE_PARAM )
1012
{
1013
    return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0   __LOCALE_ARG );
1014
}
1015
 
1016
__XL_ALIAS(wcstoul)
1017
 
1018
#endif
1019
/**********************************************************************/
1020
#if defined(L_wcstoull) || defined(L_wcstoull_l)
1021
 
1022
#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)
1023
 
1024
#if !defined(L_wcstoull_l)
1025
#if (ULLONG_MAX == UINTMAX_MAX)
1026
strong_alias(wcstoull,wcstoumax)
1027
#endif
1028
strong_alias(wcstoull,wcstouq)
1029
#endif
1030
 
1031
unsigned long long __XL(wcstoull)(const wchar_t * __restrict str,
1032
                                                                  wchar_t ** __restrict endptr, int base
1033
                                                                  __LOCALE_PARAM )
1034
{
1035
    return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0   __LOCALE_ARG );
1036
}
1037
 
1038
__XL_ALIAS(wcstoull)
1039
 
1040
#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
1041
 
1042
#endif
1043
/**********************************************************************/
1044
 

powered by: WebSVN 2.1.0

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