Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

371 lines
9.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. /*
  9. *
  10. * Copyright (c) 1998-9
  11. * Dr John Maddock
  12. *
  13. * Permission to use, copy, modify, distribute and sell this software
  14. * and its documentation for any purpose is hereby granted without fee,
  15. * provided that the above copyright notice appear in all copies and
  16. * that both that copyright notice and this permission notice appear
  17. * in supporting documentation. Dr John Maddock makes no representations
  18. * about the suitability of this software for any purpose.
  19. * It is provided "as is" without express or implied warranty.
  20. *
  21. */
  22. /*
  23. * FILE re_nls.h
  24. * VERSION 2.12
  25. * This is an internal header file, do not include directly
  26. */
  27. #ifndef RE_NLS_H
  28. #define RE_NLS_H
  29. #ifndef JM_CFG_H
  30. #include <jm/jm_cfg.h>
  31. #endif
  32. #ifdef RE_LOCALE_CPP
  33. #include <jm/regfac.h>
  34. #endif
  35. #include <limits.h>
  36. JM_NAMESPACE(__JM)
  37. enum char_class_type
  38. {
  39. #ifdef RE_LOCALE_CPP
  40. char_class_none = 0,
  41. char_class_alnum = __JM_STD::ctype_base::alnum,
  42. char_class_alpha = __JM_STD::ctype_base::alpha,
  43. char_class_cntrl = __JM_STD::ctype_base::cntrl,
  44. char_class_digit = __JM_STD::ctype_base::digit,
  45. char_class_graph = __JM_STD::ctype_base::graph,
  46. char_class_lower = __JM_STD::ctype_base::lower,
  47. char_class_print = __JM_STD::ctype_base::print,
  48. char_class_punct = __JM_STD::ctype_base::punct,
  49. char_class_space = __JM_STD::ctype_base::space,
  50. char_class_upper = __JM_STD::ctype_base::upper,
  51. char_class_xdigit = __JM_STD::ctype_base::xdigit,
  52. char_class_blank = 1<<12,
  53. char_class_underscore = 1<<13,
  54. char_class_word = __JM_STD::ctype_base::alnum | char_class_underscore,
  55. char_class_unicode = 1<<14,
  56. char_class_all_base = char_class_alnum | char_class_alpha | char_class_cntrl
  57. | char_class_digit | char_class_graph | char_class_lower
  58. | char_class_print | char_class_punct | char_class_space
  59. | char_class_upper | char_class_xdigit
  60. #elif defined(RE_LOCALE_W32)
  61. char_class_none = 0,
  62. char_class_alnum = C1_ALPHA | C1_DIGIT,
  63. char_class_alpha = C1_ALPHA,
  64. char_class_cntrl = C1_CNTRL,
  65. char_class_digit = C1_DIGIT,
  66. char_class_graph = C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_ALPHA,
  67. char_class_lower = C1_LOWER,
  68. char_class_print = C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_BLANK | C1_ALPHA,
  69. char_class_punct = C1_PUNCT,
  70. char_class_space = C1_SPACE,
  71. char_class_upper = C1_UPPER,
  72. char_class_xdigit = C1_XDIGIT,
  73. char_class_blank = C1_BLANK,
  74. char_class_underscore = 0x0200,
  75. char_class_word = C1_ALPHA | C1_DIGIT | char_class_underscore,
  76. char_class_unicode = 0x0400
  77. #else
  78. char_class_none = 0,
  79. char_class_alpha = 1,
  80. char_class_cntrl = char_class_alpha << 1,
  81. char_class_digit = char_class_cntrl << 1,
  82. char_class_lower = char_class_digit << 1,
  83. char_class_punct = char_class_lower << 1,
  84. char_class_space = char_class_punct << 1,
  85. char_class_upper = char_class_space << 1,
  86. char_class_xdigit = char_class_upper << 1,
  87. char_class_blank = char_class_xdigit << 1,
  88. char_class_unicode = char_class_blank << 1,
  89. char_class_underscore = char_class_unicode << 1,
  90. char_class_alnum = char_class_alpha | char_class_digit,
  91. char_class_graph = char_class_alpha | char_class_digit | char_class_punct | char_class_underscore,
  92. char_class_print = char_class_alpha | char_class_digit | char_class_punct | char_class_underscore | char_class_blank,
  93. char_class_word = char_class_alpha | char_class_digit | char_class_underscore
  94. #endif
  95. };
  96. //
  97. // declare our initialise class and functions:
  98. //
  99. template <class charT>
  100. class re_initialiser
  101. {
  102. public:
  103. void update();
  104. };
  105. JM_IX_DECL void RE_CALL re_init();
  106. JM_IX_DECL void RE_CALL re_update();
  107. JM_IX_DECL void RE_CALL re_free();
  108. JM_IX_DECL void RE_CALL re_init_w();
  109. JM_IX_DECL void RE_CALL re_update_w();
  110. JM_IX_DECL void RE_CALL re_free_w();
  111. JM_TEMPLATE_SPECIALISE
  112. class re_initialiser<char>
  113. {
  114. public:
  115. re_initialiser() { re_init(); }
  116. ~re_initialiser() { re_free(); }
  117. void RE_CALL update() { re_update(); }
  118. };
  119. #ifndef JM_NO_WCSTRING
  120. JM_TEMPLATE_SPECIALISE
  121. class re_initialiser<wchar_t>
  122. {
  123. public:
  124. re_initialiser() { re_init_w(); }
  125. ~re_initialiser() { re_free_w(); }
  126. void RE_CALL update() { re_update_w(); }
  127. };
  128. #endif
  129. //
  130. // start by declaring externals for RE_LOCALE_C
  131. // and RE_LOCALE_W32:
  132. //
  133. JM_IX_DECL extern unsigned char re_syntax_map[];
  134. JM_IX_DECL extern unsigned short re_class_map[];
  135. JM_IX_DECL extern char re_lower_case_map[];
  136. JM_IX_DECL extern char re_zero;
  137. JM_IX_DECL extern char re_ten;
  138. #ifndef JM_NO_WCSTRING
  139. JM_IX_DECL extern unsigned short re_unicode_classes[];
  140. JM_IX_DECL extern const wchar_t* re_lower_case_map_w;
  141. JM_IX_DECL extern wchar_t re_zero_w;
  142. JM_IX_DECL extern wchar_t re_ten_w;
  143. JM_IX_DECL wchar_t RE_CALL re_wtolower(wchar_t c);
  144. JM_IX_DECL bool RE_CALL re_iswclass(wchar_t c, jm_uintfast32_t f);
  145. #endif
  146. JM_IX_DECL const char* RE_CALL re_get_error_str(unsigned int id);
  147. JM_IX_DECL unsigned int RE_CALL re_get_syntax_type(wchar_t c);
  148. #ifdef RE_LOCALE_CPP
  149. __JM_STD::string RE_CALL re_get_error_str(unsigned int id, const __JM_STD::locale&);
  150. #endif
  151. //
  152. // add some API's for character manipulation:
  153. //
  154. inline char RE_CALL re_tolower(char c
  155. #ifdef RE_LOCALE_CPP
  156. , const __JM_STD::locale& l
  157. #endif
  158. )
  159. {
  160. #ifdef RE_LOCALE_CPP
  161. return JM_USE_FACET(l, __JM_STD::ctype<char>).tolower(c);
  162. #else
  163. return re_lower_case_map[(unsigned char)c];
  164. #endif
  165. }
  166. #ifndef JM_NO_WCSTRING
  167. inline wchar_t RE_CALL re_tolower(wchar_t c
  168. #ifdef RE_LOCALE_CPP
  169. , const __JM_STD::locale& l
  170. #endif
  171. )
  172. {
  173. #ifdef RE_LOCALE_CPP
  174. return JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).tolower(c);
  175. #else
  176. return c < 256 ? re_lower_case_map_w[c] : re_wtolower(c);
  177. #endif
  178. }
  179. #endif
  180. inline bool RE_CALL re_istype(char c, jm_uintfast32_t f
  181. #ifdef RE_LOCALE_CPP
  182. , const __JM_STD::locale& l
  183. #endif
  184. )
  185. {
  186. #ifdef RE_LOCALE_CPP
  187. if(JM_USE_FACET(l, __JM_STD::ctype<char>).is((__JM_STD::ctype<char>::mask)(f & char_class_all_base), c))
  188. return true;
  189. if((f & char_class_underscore) && (c == '_'))
  190. return true;
  191. if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
  192. return true;
  193. return false;
  194. #else
  195. return re_class_map[(unsigned char)c] & f;
  196. #endif
  197. }
  198. #ifndef JM_NO_WCSTRING
  199. inline bool RE_CALL re_istype(wchar_t c, jm_uintfast32_t f
  200. #ifdef RE_LOCALE_CPP
  201. , const __JM_STD::locale& l
  202. #endif
  203. )
  204. {
  205. #ifdef RE_LOCALE_CPP
  206. if(JM_USE_FACET(l, __JM_STD::ctype<wchar_t>).is((__JM_STD::ctype<wchar_t>::mask)(f & char_class_all_base), c))
  207. return true;
  208. if((f & char_class_underscore) && (c == '_'))
  209. return true;
  210. if((f & char_class_blank) && ((c == ' ') || (c == '\t')))
  211. return true;
  212. return false;
  213. #else
  214. return c < 256 ? re_unicode_classes[c] & f : re_iswclass(c, f);
  215. #endif
  216. }
  217. #endif
  218. inline char RE_CALL re_get_zero(char
  219. #ifdef RE_LOCALE_CPP
  220. , const __JM_STD::locale& l
  221. #endif
  222. )
  223. {
  224. #ifdef RE_LOCALE_CPP
  225. return JM_USE_FACET(l, regfacet<char>).zero();
  226. #else
  227. return re_zero;
  228. #endif
  229. }
  230. #ifndef JM_NO_WCSTRING
  231. inline wchar_t RE_CALL re_get_zero(wchar_t
  232. #ifdef RE_LOCALE_CPP
  233. , const __JM_STD::locale& l
  234. #endif
  235. )
  236. {
  237. #ifdef RE_LOCALE_CPP
  238. return JM_USE_FACET(l, regfacet<wchar_t>).zero();
  239. #else
  240. return re_zero_w;
  241. #endif
  242. }
  243. #endif
  244. inline char RE_CALL re_get_ten(char
  245. #ifdef RE_LOCALE_CPP
  246. , const __JM_STD::locale& l
  247. #endif
  248. )
  249. {
  250. #ifdef RE_LOCALE_CPP
  251. return JM_USE_FACET(l, regfacet<char>).ten();
  252. #else
  253. return re_ten;
  254. #endif
  255. }
  256. #ifndef JM_NO_WCSTRING
  257. inline wchar_t RE_CALL re_get_ten(wchar_t
  258. #ifdef RE_LOCALE_CPP
  259. , const __JM_STD::locale& l
  260. #endif
  261. )
  262. {
  263. #ifdef RE_LOCALE_CPP
  264. return JM_USE_FACET(l, regfacet<wchar_t>).ten();
  265. #else
  266. return re_ten_w;
  267. #endif
  268. }
  269. #endif
  270. //
  271. // re_toi:
  272. // convert a single character to the int it represents:
  273. //
  274. template <class charT>
  275. unsigned int RE_CALL re_toi(charT c
  276. #ifdef RE_LOCALE_CPP
  277. , const __JM_STD::locale& l
  278. #endif
  279. )
  280. {
  281. if(re_istype(c, char_class_digit MAYBE_PASS_LOCALE(l)))
  282. return c - re_get_zero(c MAYBE_PASS_LOCALE(l));
  283. if(re_istype(c, char_class_xdigit MAYBE_PASS_LOCALE(l)))
  284. return 10 + re_tolower(c MAYBE_PASS_LOCALE(l)) - re_tolower(re_get_ten(c MAYBE_PASS_LOCALE(l)) MAYBE_PASS_LOCALE(l));
  285. return -1; // error!!
  286. }
  287. //
  288. // re_toi:
  289. // parse an int from the input string
  290. // update first to point to end of int
  291. // on exit.
  292. //
  293. template <class charT>
  294. unsigned int RE_CALL re_toi(const charT*& first, const charT*const last, int radix
  295. #ifdef RE_LOCALE_CPP
  296. , const __JM_STD::locale& l
  297. #endif
  298. )
  299. {
  300. unsigned int maxval;
  301. if(radix < 0)
  302. {
  303. // if radix is less than zero, then restrict
  304. // return value to charT. NB assumes sizeof(charT) <= sizeof(int)
  305. radix *= -1;
  306. maxval = 1 << (sizeof(charT) * CHAR_BIT - 1);
  307. maxval /= radix;
  308. maxval *= 2;
  309. maxval -= 1;
  310. }
  311. else
  312. {
  313. maxval = (unsigned int)-1;
  314. maxval /= radix;
  315. }
  316. unsigned int result = 0;
  317. unsigned int type = (radix > 10) ? char_class_xdigit : char_class_digit;
  318. while((first != last) && re_istype(*first, type MAYBE_PASS_LOCALE(l)) && (result <= maxval))
  319. {
  320. result *= radix;
  321. result += re_toi(*first MAYBE_PASS_LOCALE(l));
  322. ++first;
  323. }
  324. return result;
  325. }
  326. #ifndef JM_NO_WCSTRING
  327. JM_IX_DECL bool RE_CALL re_is_combining(wchar_t c);
  328. #endif
  329. extern const char* regex_message_catalogue;
  330. JM_IX_DECL const char* RE_CALL get_global_locale_name(int);
  331. JM_END_NAMESPACE
  332. #endif