📄 stdlib.c
字号:
? ((unsigned long)(-(1+LONG_MIN)))+1 : LONG_MAX); if (sflag && (number > tmp)) { number = tmp; SET_ERRNO(ERANGE); } } return negative ? (unsigned long)(-((long)number)) : number;}#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */#endif/**********************************************************************/#if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)#define L__stdlib_strto_ll#endif#if defined(L__stdlib_strto_ll) || defined(L__stdlib_strto_ll_l)#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)#if defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l)#define _stdlib_strto_ll _stdlib_wcsto_ll#define _stdlib_strto_ll_l _stdlib_wcsto_ll_l#define Wchar wchar_t#define Wuchar __uwchar_t#ifdef __UCLIBC_DO_XLOCALE#define ISSPACE(C) iswspace_l((C), locale_arg)#else#define ISSPACE(C) iswspace((C))#endif#else /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */#define Wchar char#define Wuchar unsigned char#ifdef __UCLIBC_DO_XLOCALE#define ISSPACE(C) isspace_l((C), locale_arg)#else#define ISSPACE(C) isspace((C))#endif#endif /* defined(L__stdlib_wcsto_ll) || defined(L__stdlib_wcsto_ll_l) */#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)unsigned long long _stdlib_strto_ll(register const Wchar * __restrict str, Wchar ** __restrict endptr, int base, int sflag){ return _stdlib_strto_ll_l(str, endptr, base, sflag, __UCLIBC_CURLOCALE);}#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) *//* This is the main work fuction which handles both strtoll (sflag = 1) and * strtoull (sflag = 0). */unsigned long long __XL_NPP(_stdlib_strto_ll)(register const Wchar * __restrict str, Wchar ** __restrict endptr, int base, int sflag __LOCALE_PARAM ){ unsigned long long number;#if _STRTO_ENDPTR const Wchar *fail_char;#define SET_FAIL(X) fail_char = (X)#else#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */#endif unsigned int n1; unsigned char negative, digit; assert(((unsigned int)sflag) <= 1); SET_FAIL(str); while (ISSPACE(*str)) { /* Skip leading whitespace. */ ++str; } /* Handle optional sign. */ negative = 0; switch(*str) { case '-': negative = 1; /* Fall through to increment str. */ case '+': ++str; } if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ base += 10; /* Default is 10 (26). */ if (*str == '0') { SET_FAIL(++str); base -= 2; /* Now base is 8 or 16 (24). */ if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */ ++str; base += base; /* Base is 16 (16 or 48). */ } } if (base > 16) { /* Adjust in case base wasn't dynamic. */ base = 16; } } number = 0; if (((unsigned)(base - 2)) < 35) { /* Legal base. */ do { digit = (((Wuchar)(*str - '0')) <= 9) ? (*str - '0') : ((*str >= 'A') ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */ : 40); if (digit >= base) { break; } SET_FAIL(++str);#if 1 /* Optional, but speeds things up in the usual case. */ if (number <= (ULLONG_MAX >> 6)) { number = number * base + digit; } else#endif { n1 = ((unsigned char) number) * base + digit; number = (number >> CHAR_BIT) * base; if (number + (n1 >> CHAR_BIT) <= (ULLONG_MAX >> CHAR_BIT)) { number = (number << CHAR_BIT) + n1; } else { /* Overflow. */ number = ULLONG_MAX; negative &= sflag; SET_ERRNO(ERANGE); } } } while (1); }#if _STRTO_ENDPTR if (endptr) { *endptr = (Wchar *) fail_char; }#endif { unsigned long long tmp = ((negative) ? ((unsigned long long)(-(1+LLONG_MIN)))+1 : LLONG_MAX); if (sflag && (number > tmp)) { number = tmp; SET_ERRNO(ERANGE); } } return negative ? (unsigned long long)(-((long long)number)) : number;}#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */#endif/**********************************************************************//* Made _Exit() an alias for _exit(), as per C99. *//* #ifdef L__Exit *//* void _Exit(int status) *//* { *//* _exit(status); *//* } *//* #endif *//**********************************************************************/#ifdef L_bsearchvoid *bsearch(const void *key, const void *base, size_t /* nmemb */ high, size_t size, int (*compar)(const void *, const void *)){ register char *p; size_t low; size_t mid; int r; if (size > 0) { /* TODO: change this to an assert?? */ low = 0; while (low < high) { mid = low + ((high - low) >> 1); /* Avoid possible overflow here. */ p = ((char *)base) + mid * size; /* Could overflow here... */ r = (*compar)(key, p); /* but that's an application problem! */ if (r > 0) { low = mid + 1; } else if (r < 0) { high = mid; } else { return p; } } } return NULL;}#endif/**********************************************************************/#ifdef L_qsort/* This code is derived from a public domain shell sort routine by * Ray Gardner and found in Bob Stout's snippets collection. The * original code is included below in an #if 0/#endif block. * * I modified it to avoid the possibility of overflow in the wgap * calculation, as well as to reduce the generated code size with * bcc and gcc. */void qsort (void *base, size_t nel, size_t width, int (*comp)(const void *, const void *)){ size_t wgap, i, j, k; char tmp; if ((nel > 1) && (width > 0)) { assert( nel <= ((size_t)(-1)) / width ); /* check for overflow */ wgap = 0; do { wgap = 3 * wgap + 1; } while (wgap < (nel-1)/3); /* From the above, we know that either wgap == 1 < nel or */ /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */ wgap *= width; /* So this can not overflow if wnel doesn't. */ nel *= width; /* Convert nel to 'wnel' */ do { i = wgap; do { j = i; do { register char *a; register char *b; j -= wgap; a = j + ((char *)base); b = a + wgap; if ( (*comp)(a, b) <= 0 ) { break; } k = width; do { tmp = *a; *a++ = *b; *b++ = tmp; } while ( --k ); } while (j >= wgap); i += width; } while (i < nel); wgap = (wgap - width)/3; } while (wgap); }}/* ---------- original snippets version below ---------- */#if 0/*** ssort() -- Fast, small, qsort()-compatible Shell sort**** by Ray Gardner, public domain 5/90*/#include <stddef.h>void ssort (void *base, size_t nel, size_t width, int (*comp)(const void *, const void *)){ size_t wnel, gap, wgap, i, j, k; char *a, *b, tmp; wnel = width * nel; for (gap = 0; ++gap < nel;) gap *= 3; while ( gap /= 3 ) { wgap = width * gap; for (i = wgap; i < wnel; i += width) { for (j = i - wgap; ;j -= wgap) { a = j + (char *)base; b = a + wgap; if ( (*comp)(a, b) <= 0 ) break; k = width; do { tmp = *a; *a++ = *b; *b++ = tmp; } while ( --k ); if (j < wgap) break; } } }}#endif#endif/**********************************************************************/#ifdef L__stdlib_mb_cur_maxsize_t _stdlib_mb_cur_max(void){#ifdef __CTYPE_HAS_UTF_8_LOCALES return __UCLIBC_CURLOCALE_DATA.mb_cur_max;#else#ifdef __CTYPE_HAS_8_BIT_LOCALES#ifdef __UCLIBC_MJN3_ONLY__#warning need to change this when/if transliteration is implemented#endif#endif return 1;#endif}#endif/**********************************************************************/#ifdef L_mblenint mblen(register const char *s, size_t n){ static mbstate_t state; size_t r; if (!s) { state.__mask = 0;#ifdef __CTYPE_HAS_UTF_8_LOCALES return ENCODING == __ctype_encoding_utf8;#else return 0;#endif } if ((r = mbrlen(s, n, &state)) == (size_t) -2) { /* TODO: Should we set an error state? */ state.__wc = 0xffffU; /* Make sure we're in an error state. */ return (size_t) -1; /* TODO: Change error code above? */ } return r;}#endif/**********************************************************************/#ifdef L_mbtowcint mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n){ static mbstate_t state; size_t r; if (!s) { state.__mask = 0;#ifdef __CTYPE_HAS_UTF_8_LOCALES return ENCODING == __ctype_encoding_utf8;#else return 0;#endif } if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) { /* TODO: Should we set an error state? */ state.__wc = 0xffffU; /* Make sure we're in an error state. */ return (size_t) -1; /* TODO: Change error code above? */ } return r;}#endif/**********************************************************************/#ifdef L_wctomb/* Note: We completely ignore state in all currently supported conversions. */int wctomb(register char *__restrict s, wchar_t swc){ return (!s) ?#ifdef __CTYPE_HAS_UTF_8_LOCALES (ENCODING == __ctype_encoding_utf8)#else 0 /* Encoding is stateless. */#endif : ((ssize_t) wcrtomb(s, swc, NULL));}#endif/**********************************************************************/#ifdef L_mbstowcssize_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n){ mbstate_t state; const char *e = s; /* Needed because of restrict. */ state.__mask = 0; /* Always start in initial shift state. */ return mbsrtowcs(pwcs, &e, n, &state);}#endif/**********************************************************************/#ifdef L_wcstombs/* Note: We completely ignore state in all currently supported conversions. */size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n){ const wchar_t *e = pwcs; /* Needed because of restrict. */ return wcsrtombs(s, &e, n, NULL);}#endif/**********************************************************************/#if defined(L_wcstol) || defined(L_wcstol_l)#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstol_l)strong_alias(wcstol,wcstoimax)#endif#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)strong_alias(__XL(wcstol),__XL(wcstoll))#endiflong __XL(wcstol)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ){ return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG );}__XL_ALIAS(wcstol)#endif/**********************************************************************/#if defined(L_wcstoll) || defined(L_wcstoll_l)#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)#if !defined(L_wcstoll_l)#if (ULLONG_MAX == UINTMAX_MAX)strong_alias(wcstoll,wcstoimax)#endifstrong_alias(wcstoll,wcstoq)#endiflong long __XL(wcstoll)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ){ return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1 __LOCALE_ARG );}__XL_ALIAS(wcstoll)#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */#endif/**********************************************************************/#if defined(L_wcstoul) || defined(L_wcstoul_l)#if (ULONG_MAX == UINTMAX_MAX) && !defined(L_wcstoul_l)strong_alias(wcstoul,wcstoumax)#endif#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)strong_alias(__XL(wcstoul),__XL(wcstoull))#endifunsigned long __XL(wcstoul)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ){ return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG );}__XL_ALIAS(wcstoul)#endif/**********************************************************************/#if defined(L_wcstoull) || defined(L_wcstoull_l)#if defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX)#if !defined(L_wcstoull_l)#if (ULLONG_MAX == UINTMAX_MAX)strong_alias(wcstoull,wcstoumax)#endifstrong_alias(wcstoull,wcstouq)#endifunsigned long long __XL(wcstoull)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base __LOCALE_PARAM ){ return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0 __LOCALE_ARG );}__XL_ALIAS(wcstoull)#endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */#endif/**********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -