ctype.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* Copyright (C) 2002 Manuel Novoa III
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Library General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Library General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Library General Public
  14. * License along with this library; if not, write to the Free
  15. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
  18. *
  19. * Besides uClibc, I'm using this code in my libc for elks, which is
  20. * a 16-bit environment with a fairly limited compiler. It would make
  21. * things much easier for me if this file isn't modified unnecessarily.
  22. * In particular, please put any new or replacement functions somewhere
  23. * else, and modify the makefile to use your version instead.
  24. * Thanks. Manuel
  25. *
  26. * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
  27. #define _GNU_SOURCE
  28. #define __NO_CTYPE
  29. #include <ctype.h>
  30. #include <stdio.h>
  31. #include <limits.h>
  32. #include <assert.h>
  33. #include <locale.h>
  34. /**********************************************************************/
  35. extern int __isctype_loc(int c, int ct);
  36. /* Some macros used throughout the file. */
  37. #define U ((unsigned char)c)
  38. /* #define LCT (__cur_locale->ctype) */
  39. #define LCT (&__global_locale)
  40. /**********************************************************************/
  41. #ifndef __PASTE
  42. #define __PASTE(X,Y) X ## Y
  43. #endif
  44. #define C_MACRO(X) __PASTE(__C_,X)(c)
  45. #define CT_MACRO(X) __PASTE(__ctype_,X)(c)
  46. /**********************************************************************/
  47. #ifndef __CTYPE_HAS_8_BIT_LOCALES
  48. #define IS_FUNC_BODY(NAME) \
  49. int NAME (int c) \
  50. { \
  51. return C_MACRO(NAME); \
  52. }
  53. #else
  54. /* It may be worth defining __isctype_loc over the whole range of char. */
  55. /* #define IS_FUNC_BODY(NAME) \ */
  56. /* int NAME (int c) \ */
  57. /* { \ */
  58. /* return __isctype_loc(c, __PASTE(_CTYPE_,NAME)); \ */
  59. /* } */
  60. #define IS_FUNC_BODY(NAME) \
  61. int NAME (int c) \
  62. { \
  63. if (((unsigned int) c) <= 0x7f) { \
  64. return C_MACRO(NAME); \
  65. } \
  66. return __isctype_loc(c, __PASTE(_CTYPE_,NAME)); \
  67. }
  68. #endif /* __CTYPE_HAS_8_BIT_LOCALES */
  69. /**********************************************************************/
  70. #ifdef L_isalnum
  71. IS_FUNC_BODY(isalnum);
  72. #endif
  73. /**********************************************************************/
  74. #ifdef L_isalpha
  75. IS_FUNC_BODY(isalpha);
  76. #endif
  77. /**********************************************************************/
  78. #ifdef L_isblank
  79. /* Warning!!! This is correct for all the currently supported 8-bit locales.
  80. * If any are added though, this will need to be verified. */
  81. int isblank(int c)
  82. {
  83. return __isblank(c);
  84. }
  85. #endif
  86. /**********************************************************************/
  87. #ifdef L_iscntrl
  88. IS_FUNC_BODY(iscntrl);
  89. #endif
  90. /**********************************************************************/
  91. #ifdef L_isdigit
  92. int isdigit(int c)
  93. {
  94. return __isdigit(c);
  95. }
  96. #endif
  97. /**********************************************************************/
  98. #ifdef L_isgraph
  99. IS_FUNC_BODY(isgraph);
  100. #endif
  101. /**********************************************************************/
  102. #ifdef L_islower
  103. IS_FUNC_BODY(islower);
  104. #endif
  105. /**********************************************************************/
  106. #ifdef L_isprint
  107. IS_FUNC_BODY(isprint);
  108. #endif
  109. /**********************************************************************/
  110. #ifdef L_ispunct
  111. IS_FUNC_BODY(ispunct);
  112. #endif
  113. /**********************************************************************/
  114. #ifdef L_isspace
  115. /* Warning!!! This is correct for all the currently supported 8-bit locales.
  116. * If any are added though, this will need to be verified. */
  117. int isspace(int c)
  118. {
  119. return __isspace(c);
  120. }
  121. #endif
  122. /**********************************************************************/
  123. #ifdef L_isupper
  124. IS_FUNC_BODY(isupper);
  125. #endif
  126. /**********************************************************************/
  127. #ifdef L_isxdigit
  128. int isxdigit(int c)
  129. {
  130. return __isxdigit(c);
  131. }
  132. #endif
  133. /**********************************************************************/
  134. #ifdef L_tolower
  135. #ifdef __CTYPE_HAS_8_BIT_LOCALES
  136. int tolower(int c)
  137. {
  138. return ((((unsigned int) c) <= 0x7f)
  139. || (LCT->encoding != __ctype_encoding_8_bit))
  140. ? __C_tolower(c)
  141. : ( __isctype_loc(c, _CTYPE_isupper)
  142. ? (unsigned char)
  143. ( U - LCT->tbl8uplow[ ((int)
  144. (LCT->idx8uplow[(U & 0x7f)
  145. >> Cuplow_IDX_SHIFT])
  146. << Cuplow_IDX_SHIFT)
  147. + (U & ((1 << Cuplow_IDX_SHIFT) - 1)) ])
  148. : c );
  149. }
  150. #else /* __CTYPE_HAS_8_BIT_LOCALES */
  151. int tolower(int c)
  152. {
  153. return __C_tolower(c);
  154. }
  155. #endif /* __CTYPE_HAS_8_BIT_LOCALES */
  156. #endif
  157. /**********************************************************************/
  158. #ifdef L_toupper
  159. #ifdef __CTYPE_HAS_8_BIT_LOCALES
  160. int toupper(int c)
  161. {
  162. return ((((unsigned int) c) <= 0x7f)
  163. || (LCT->encoding != __ctype_encoding_8_bit))
  164. ? __C_toupper(c)
  165. : ( __isctype_loc(c, _CTYPE_islower)
  166. ? (unsigned char)
  167. ( U + LCT->tbl8uplow[ ((int)
  168. (LCT->idx8uplow[(U & 0x7f)
  169. >> Cuplow_IDX_SHIFT])
  170. << Cuplow_IDX_SHIFT)
  171. + (U & ((1 << Cuplow_IDX_SHIFT) - 1)) ])
  172. : c );
  173. }
  174. #else /* __CTYPE_HAS_8_BIT_LOCALES */
  175. int toupper(int c)
  176. {
  177. return __C_toupper(c);
  178. }
  179. #endif /* __CTYPE_HAS_8_BIT_LOCALES */
  180. #endif
  181. /**********************************************************************/
  182. #ifdef L_isascii
  183. int isascii(int c)
  184. {
  185. return __isascii(c);
  186. }
  187. #endif
  188. /**********************************************************************/
  189. #ifdef L_toascii
  190. int toascii(int c)
  191. {
  192. return __toascii(c);
  193. }
  194. #endif
  195. /**********************************************************************/
  196. #ifdef L_isxlower
  197. int isxlower(int c)
  198. {
  199. return __isxlower(c);
  200. }
  201. #endif
  202. /**********************************************************************/
  203. #ifdef L_isxupper
  204. int isxupper(int c)
  205. {
  206. return __isxupper(c);
  207. }
  208. #endif
  209. /**********************************************************************/
  210. #ifdef L___isctype_loc
  211. #ifdef __CTYPE_HAS_8_BIT_LOCALES
  212. /* This internal routine is similar to iswctype(), but it doesn't
  213. * work for any non-standard types, itdoesn't work for "xdigit"s,
  214. * and it doesn't work for chars between 0 and 0x7f (although that
  215. * may change). */
  216. static const char ctype_range[] = {
  217. __CTYPE_RANGES
  218. };
  219. int __isctype_loc(int c, int ct)
  220. {
  221. unsigned char d;
  222. assert(((unsigned int)ct) < _CTYPE_isxdigit);
  223. assert(((unsigned int)c) > 0x7f);
  224. #if (CHAR_MIN == 0) /* We don't have signed chars... */
  225. if ((LCT->encoding != __ctype_encoding_8_bit)
  226. || (((unsigned int) c) > UCHAR_MAX)
  227. ) {
  228. return 0;
  229. }
  230. #else
  231. /* Allow non-EOF negative char values for glibc compatiblity. */
  232. if ((LCT->encoding != __ctype_encoding_8_bit) || (c == EOF)
  233. || ( ((unsigned int)(c - CHAR_MIN)) > (UCHAR_MAX - CHAR_MIN))
  234. ) {
  235. return 0;
  236. }
  237. #endif
  238. /* TODO - test assumptions??? 8-bit chars -- or ensure in generator. */
  239. #define Cctype_TBL_MASK ((1 << Cctype_IDX_SHIFT) - 1)
  240. #define Cctype_IDX_OFFSET (128 >> Cctype_IDX_SHIFT)
  241. c &= 0x7f;
  242. #ifdef Cctype_PACKED
  243. d = LCT->tbl8ctype[ ((int)(LCT->idx8ctype[(U >> Cctype_IDX_SHIFT) ])
  244. << (Cctype_IDX_SHIFT - 1))
  245. + ((U & Cctype_TBL_MASK) >> 1)];
  246. d = (U & 1) ? (d >> 4) : (d & 0xf);
  247. #else
  248. d = LCT->tbl8ctype[ ((int)(LCT->idx8ctype[(U >> Cctype_IDX_SHIFT) ])
  249. << Cctype_IDX_SHIFT)
  250. + (U & Cctype_TBL_MASK) ];
  251. #endif
  252. return ( ((unsigned char)(d - ctype_range[2*ct])) <= ctype_range[2*ct+1] );
  253. }
  254. #endif /* __CTYPE_HAS_8_BIT_LOCALES */
  255. #endif
  256. /**********************************************************************/