lj_strscan.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*
  2. ** String scanning.
  3. ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
  4. */
  5. #include <math.h>
  6. #define lj_strscan_c
  7. #define LUA_CORE
  8. #include "lj_obj.h"
  9. #include "lj_char.h"
  10. #include "lj_strscan.h"
  11. /* -- Scanning numbers ---------------------------------------------------- */
  12. /*
  13. ** Rationale for the builtin string to number conversion library:
  14. **
  15. ** It removes a dependency on libc's strtod(), which is a true portability
  16. ** nightmare. Mainly due to the plethora of supported OS and toolchain
  17. ** combinations. Sadly, the various implementations
  18. ** a) are often buggy, incomplete (no hex floats) and/or imprecise,
  19. ** b) sometimes crash or hang on certain inputs,
  20. ** c) return non-standard NaNs that need to be filtered out, and
  21. ** d) fail if the locale-specific decimal separator is not a dot,
  22. ** which can only be fixed with atrocious workarounds.
  23. **
  24. ** Also, most of the strtod() implementations are hopelessly bloated,
  25. ** which is not just an I-cache hog, but a problem for static linkage
  26. ** on embedded systems, too.
  27. **
  28. ** OTOH the builtin conversion function is very compact. Even though it
  29. ** does a lot more, like parsing long longs, octal or imaginary numbers
  30. ** and returning the result in different formats:
  31. ** a) It needs less than 3 KB (!) of machine code (on x64 with -Os),
  32. ** b) it doesn't perform any dynamic allocation and,
  33. ** c) it needs only around 600 bytes of stack space.
  34. **
  35. ** The builtin function is faster than strtod() for typical inputs, e.g.
  36. ** "123", "1.5" or "1e6". Arguably, it's slower for very large exponents,
  37. ** which are not very common (this could be fixed, if needed).
  38. **
  39. ** And most importantly, the builtin function is equally precise on all
  40. ** platforms. It correctly converts and rounds any input to a double.
  41. ** If this is not the case, please send a bug report -- but PLEASE verify
  42. ** that the implementation you're comparing to is not the culprit!
  43. **
  44. ** The implementation quickly pre-scans the entire string first and
  45. ** handles simple integers on-the-fly. Otherwise, it dispatches to the
  46. ** base-specific parser. Hex and octal is straightforward.
  47. **
  48. ** Decimal to binary conversion uses a fixed-length circular buffer in
  49. ** base 100. Some simple cases are handled directly. For other cases, the
  50. ** number in the buffer is up-scaled or down-scaled until the integer part
  51. ** is in the proper range. Then the integer part is rounded and converted
  52. ** to a double which is finally rescaled to the result. Denormals need
  53. ** special treatment to prevent incorrect 'double rounding'.
  54. */
  55. /* Definitions for circular decimal digit buffer (base 100 = 2 digits/byte). */
  56. #define STRSCAN_DIG 1024
  57. #define STRSCAN_MAXDIG 800 /* 772 + extra are sufficient. */
  58. #define STRSCAN_DDIG (STRSCAN_DIG/2)
  59. #define STRSCAN_DMASK (STRSCAN_DDIG-1)
  60. #define STRSCAN_MAXEXP (1 << 20)
  61. /* Helpers for circular buffer. */
  62. #define DNEXT(a) (((a)+1) & STRSCAN_DMASK)
  63. #define DPREV(a) (((a)-1) & STRSCAN_DMASK)
  64. #define DLEN(lo, hi) ((int32_t)(((lo)-(hi)) & STRSCAN_DMASK))
  65. #define casecmp(c, k) (((c) | 0x20) == k)
  66. /* Final conversion to double. */
  67. static void strscan_double(uint64_t x, TValue *o, int32_t ex2, int32_t neg)
  68. {
  69. double n;
  70. /* Avoid double rounding for denormals. */
  71. if (LJ_UNLIKELY(ex2 <= -1075 && x != 0)) {
  72. /* NYI: all of this generates way too much code on 32 bit CPUs. */
  73. #if (defined(__GNUC__) || defined(__clang__)) && LJ_64
  74. int32_t b = (int32_t)(__builtin_clzll(x)^63);
  75. #else
  76. int32_t b = (x>>32) ? 32+(int32_t)lj_fls((uint32_t)(x>>32)) :
  77. (int32_t)lj_fls((uint32_t)x);
  78. #endif
  79. if ((int32_t)b + ex2 <= -1023 && (int32_t)b + ex2 >= -1075) {
  80. uint64_t rb = (uint64_t)1 << (-1075-ex2);
  81. if ((x & rb) && ((x & (rb+rb+rb-1)))) x += rb+rb;
  82. x = (x & ~(rb+rb-1));
  83. }
  84. }
  85. /* Convert to double using a signed int64_t conversion, then rescale. */
  86. lj_assertX((int64_t)x >= 0, "bad double conversion");
  87. n = (double)(int64_t)x;
  88. if (neg) n = -n;
  89. if (ex2) n = ldexp(n, ex2);
  90. o->n = n;
  91. }
  92. /* Parse hexadecimal number. */
  93. static StrScanFmt strscan_hex(const uint8_t *p, TValue *o,
  94. StrScanFmt fmt, uint32_t opt,
  95. int32_t ex2, int32_t neg, uint32_t dig)
  96. {
  97. uint64_t x = 0;
  98. uint32_t i;
  99. /* Scan hex digits. */
  100. for (i = dig > 16 ? 16 : dig ; i; i--, p++) {
  101. uint32_t d = (*p != '.' ? *p : *++p); if (d > '9') d += 9;
  102. x = (x << 4) + (d & 15);
  103. }
  104. /* Summarize rounding-effect of excess digits. */
  105. for (i = 16; i < dig; i++, p++)
  106. x |= ((*p != '.' ? *p : *++p) != '0'), ex2 += 4;
  107. /* Format-specific handling. */
  108. switch (fmt) {
  109. case STRSCAN_INT:
  110. if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg &&
  111. !(x == 0 && neg)) {
  112. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  113. return STRSCAN_INT; /* Fast path for 32 bit integers. */
  114. }
  115. if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; }
  116. /* fallthrough */
  117. case STRSCAN_U32:
  118. if (dig > 8) return STRSCAN_ERROR;
  119. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  120. return STRSCAN_U32;
  121. case STRSCAN_I64:
  122. case STRSCAN_U64:
  123. if (dig > 16) return STRSCAN_ERROR;
  124. o->u64 = neg ? ~x+1u : x;
  125. return fmt;
  126. default:
  127. break;
  128. }
  129. /* Reduce range, then convert to double. */
  130. if ((x & U64x(c0000000,0000000))) { x = (x >> 2) | (x & 3); ex2 += 2; }
  131. strscan_double(x, o, ex2, neg);
  132. return fmt;
  133. }
  134. /* Parse octal number. */
  135. static StrScanFmt strscan_oct(const uint8_t *p, TValue *o,
  136. StrScanFmt fmt, int32_t neg, uint32_t dig)
  137. {
  138. uint64_t x = 0;
  139. /* Scan octal digits. */
  140. if (dig > 22 || (dig == 22 && *p > '1')) return STRSCAN_ERROR;
  141. while (dig-- > 0) {
  142. if (!(*p >= '0' && *p <= '7')) return STRSCAN_ERROR;
  143. x = (x << 3) + (*p++ & 7);
  144. }
  145. /* Format-specific handling. */
  146. switch (fmt) {
  147. case STRSCAN_INT:
  148. if (x >= 0x80000000u+neg) fmt = STRSCAN_U32;
  149. /* fallthrough */
  150. case STRSCAN_U32:
  151. if ((x >> 32)) return STRSCAN_ERROR;
  152. o->i = neg ? (int32_t)(~(uint32_t)x+1u) : (int32_t)x;
  153. break;
  154. default:
  155. case STRSCAN_I64:
  156. case STRSCAN_U64:
  157. o->u64 = neg ? ~x+1u : x;
  158. break;
  159. }
  160. return fmt;
  161. }
  162. /* Parse decimal number. */
  163. static StrScanFmt strscan_dec(const uint8_t *p, TValue *o,
  164. StrScanFmt fmt, uint32_t opt,
  165. int32_t ex10, int32_t neg, uint32_t dig)
  166. {
  167. uint8_t xi[STRSCAN_DDIG], *xip = xi;
  168. if (dig) {
  169. uint32_t i = dig;
  170. if (i > STRSCAN_MAXDIG) {
  171. ex10 += (int32_t)(i - STRSCAN_MAXDIG);
  172. i = STRSCAN_MAXDIG;
  173. }
  174. /* Scan unaligned leading digit. */
  175. if (((ex10^i) & 1))
  176. *xip++ = ((*p != '.' ? *p : *++p) & 15), i--, p++;
  177. /* Scan aligned double-digits. */
  178. for ( ; i > 1; i -= 2) {
  179. uint32_t d = 10 * ((*p != '.' ? *p : *++p) & 15); p++;
  180. *xip++ = d + ((*p != '.' ? *p : *++p) & 15); p++;
  181. }
  182. /* Scan and realign trailing digit. */
  183. if (i) *xip++ = 10 * ((*p != '.' ? *p : *++p) & 15), ex10--, dig++, p++;
  184. /* Summarize rounding-effect of excess digits. */
  185. if (dig > STRSCAN_MAXDIG) {
  186. do {
  187. if ((*p != '.' ? *p : *++p) != '0') { xip[-1] |= 1; break; }
  188. p++;
  189. } while (--dig > STRSCAN_MAXDIG);
  190. dig = STRSCAN_MAXDIG;
  191. } else { /* Simplify exponent. */
  192. while (ex10 > 0 && dig <= 18) *xip++ = 0, ex10 -= 2, dig += 2;
  193. }
  194. } else { /* Only got zeros. */
  195. ex10 = 0;
  196. xi[0] = 0;
  197. }
  198. /* Fast path for numbers in integer format (but handles e.g. 1e6, too). */
  199. if (dig <= 20 && ex10 == 0) {
  200. uint8_t *xis;
  201. uint64_t x = xi[0];
  202. double n;
  203. for (xis = xi+1; xis < xip; xis++) x = x * 100 + *xis;
  204. if (!(dig == 20 && (xi[0] > 18 || (int64_t)x >= 0))) { /* No overflow? */
  205. /* Format-specific handling. */
  206. switch (fmt) {
  207. case STRSCAN_INT:
  208. if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) {
  209. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  210. return STRSCAN_INT; /* Fast path for 32 bit integers. */
  211. }
  212. if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; }
  213. /* fallthrough */
  214. case STRSCAN_U32:
  215. if ((x >> 32) != 0) return STRSCAN_ERROR;
  216. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  217. return STRSCAN_U32;
  218. case STRSCAN_I64:
  219. case STRSCAN_U64:
  220. o->u64 = neg ? ~x+1u : x;
  221. return fmt;
  222. default:
  223. plainnumber: /* Fast path for plain numbers < 2^63. */
  224. if ((int64_t)x < 0) break;
  225. n = (double)(int64_t)x;
  226. if (neg) n = -n;
  227. o->n = n;
  228. return fmt;
  229. }
  230. }
  231. }
  232. /* Slow non-integer path. */
  233. if (fmt == STRSCAN_INT) {
  234. if ((opt & STRSCAN_OPT_C)) return STRSCAN_ERROR;
  235. fmt = STRSCAN_NUM;
  236. } else if (fmt > STRSCAN_INT) {
  237. return STRSCAN_ERROR;
  238. }
  239. {
  240. uint32_t hi = 0, lo = (uint32_t)(xip-xi);
  241. int32_t ex2 = 0, idig = (int32_t)lo + (ex10 >> 1);
  242. lj_assertX(lo > 0 && (ex10 & 1) == 0, "bad lo %d ex10 %d", lo, ex10);
  243. /* Handle simple overflow/underflow. */
  244. if (idig > 310/2) { if (neg) setminfV(o); else setpinfV(o); return fmt; }
  245. else if (idig < -326/2) { o->n = neg ? -0.0 : 0.0; return fmt; }
  246. /* Scale up until we have at least 17 or 18 integer part digits. */
  247. while (idig < 9 && idig < DLEN(lo, hi)) {
  248. uint32_t i, cy = 0;
  249. ex2 -= 6;
  250. for (i = DPREV(lo); ; i = DPREV(i)) {
  251. uint32_t d = (xi[i] << 6) + cy;
  252. cy = (((d >> 2) * 5243) >> 17); d = d - cy * 100; /* Div/mod 100. */
  253. xi[i] = (uint8_t)d;
  254. if (i == hi) break;
  255. if (d == 0 && i == DPREV(lo)) lo = i;
  256. }
  257. if (cy) {
  258. hi = DPREV(hi);
  259. if (xi[DPREV(lo)] == 0) lo = DPREV(lo);
  260. else if (hi == lo) { lo = DPREV(lo); xi[DPREV(lo)] |= xi[lo]; }
  261. xi[hi] = (uint8_t)cy; idig++;
  262. }
  263. }
  264. /* Scale down until no more than 17 or 18 integer part digits remain. */
  265. while (idig > 9) {
  266. uint32_t i = hi, cy = 0;
  267. ex2 += 6;
  268. do {
  269. cy += xi[i];
  270. xi[i] = (cy >> 6);
  271. cy = 100 * (cy & 0x3f);
  272. if (xi[i] == 0 && i == hi) hi = DNEXT(hi), idig--;
  273. i = DNEXT(i);
  274. } while (i != lo);
  275. while (cy) {
  276. if (hi == lo) { xi[DPREV(lo)] |= 1; break; }
  277. xi[lo] = (cy >> 6); lo = DNEXT(lo);
  278. cy = 100 * (cy & 0x3f);
  279. }
  280. }
  281. /* Collect integer part digits and convert to rescaled double. */
  282. {
  283. uint64_t x = xi[hi];
  284. uint32_t i;
  285. for (i = DNEXT(hi); --idig > 0 && i != lo; i = DNEXT(i))
  286. x = x * 100 + xi[i];
  287. if (i == lo) {
  288. while (--idig >= 0) x = x * 100;
  289. } else { /* Gather round bit from remaining digits. */
  290. x <<= 1; ex2--;
  291. do {
  292. if (xi[i]) { x |= 1; break; }
  293. i = DNEXT(i);
  294. } while (i != lo);
  295. }
  296. strscan_double(x, o, ex2, neg);
  297. }
  298. }
  299. return fmt;
  300. }
  301. /* Parse binary number. */
  302. static StrScanFmt strscan_bin(const uint8_t *p, TValue *o,
  303. StrScanFmt fmt, uint32_t opt,
  304. int32_t ex2, int32_t neg, uint32_t dig)
  305. {
  306. uint64_t x = 0;
  307. uint32_t i;
  308. if (ex2 || dig > 64) return STRSCAN_ERROR;
  309. /* Scan binary digits. */
  310. for (i = dig; i; i--, p++) {
  311. if ((*p & ~1) != '0') return STRSCAN_ERROR;
  312. x = (x << 1) | (*p & 1);
  313. }
  314. /* Format-specific handling. */
  315. switch (fmt) {
  316. case STRSCAN_INT:
  317. if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) {
  318. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  319. return STRSCAN_INT; /* Fast path for 32 bit integers. */
  320. }
  321. if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; }
  322. /* fallthrough */
  323. case STRSCAN_U32:
  324. if (dig > 32) return STRSCAN_ERROR;
  325. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  326. return STRSCAN_U32;
  327. case STRSCAN_I64:
  328. case STRSCAN_U64:
  329. o->u64 = neg ? ~x+1u : x;
  330. return fmt;
  331. default:
  332. break;
  333. }
  334. /* Reduce range, then convert to double. */
  335. if ((x & U64x(c0000000,0000000))) { x = (x >> 2) | (x & 3); ex2 += 2; }
  336. strscan_double(x, o, ex2, neg);
  337. return fmt;
  338. }
  339. /* Scan string containing a number. Returns format. Returns value in o. */
  340. StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o,
  341. uint32_t opt)
  342. {
  343. int32_t neg = 0;
  344. const uint8_t *pe = p + len;
  345. /* Remove leading space, parse sign and non-numbers. */
  346. if (LJ_UNLIKELY(!lj_char_isdigit(*p))) {
  347. while (lj_char_isspace(*p)) p++;
  348. if (*p == '+' || *p == '-') neg = (*p++ == '-');
  349. if (LJ_UNLIKELY(*p >= 'A')) { /* Parse "inf", "infinity" or "nan". */
  350. TValue tmp;
  351. setnanV(&tmp);
  352. if (casecmp(p[0],'i') && casecmp(p[1],'n') && casecmp(p[2],'f')) {
  353. if (neg) setminfV(&tmp); else setpinfV(&tmp);
  354. p += 3;
  355. if (casecmp(p[0],'i') && casecmp(p[1],'n') && casecmp(p[2],'i') &&
  356. casecmp(p[3],'t') && casecmp(p[4],'y')) p += 5;
  357. } else if (casecmp(p[0],'n') && casecmp(p[1],'a') && casecmp(p[2],'n')) {
  358. p += 3;
  359. }
  360. while (lj_char_isspace(*p)) p++;
  361. if (*p || p < pe) return STRSCAN_ERROR;
  362. o->u64 = tmp.u64;
  363. return STRSCAN_NUM;
  364. }
  365. }
  366. /* Parse regular number. */
  367. {
  368. StrScanFmt fmt = STRSCAN_INT;
  369. int cmask = LJ_CHAR_DIGIT;
  370. int base = (opt & STRSCAN_OPT_C) && *p == '0' ? 0 : 10;
  371. const uint8_t *sp, *dp = NULL;
  372. uint32_t dig = 0, hasdig = 0, x = 0;
  373. int32_t ex = 0;
  374. /* Determine base and skip leading zeros. */
  375. if (LJ_UNLIKELY(*p <= '0')) {
  376. if (*p == '0') {
  377. if (casecmp(p[1], 'x'))
  378. base = 16, cmask = LJ_CHAR_XDIGIT, p += 2;
  379. else if (casecmp(p[1], 'b'))
  380. base = 2, cmask = LJ_CHAR_DIGIT, p += 2;
  381. }
  382. for ( ; ; p++) {
  383. if (*p == '0') {
  384. hasdig = 1;
  385. } else if (*p == '.') {
  386. if (dp) return STRSCAN_ERROR;
  387. dp = p;
  388. } else {
  389. break;
  390. }
  391. }
  392. }
  393. /* Preliminary digit and decimal point scan. */
  394. for (sp = p; ; p++) {
  395. if (LJ_LIKELY(lj_char_isa(*p, cmask))) {
  396. x = x * 10 + (*p & 15); /* For fast path below. */
  397. dig++;
  398. } else if (*p == '.') {
  399. if (dp) return STRSCAN_ERROR;
  400. dp = p;
  401. } else {
  402. break;
  403. }
  404. }
  405. if (!(hasdig | dig)) return STRSCAN_ERROR;
  406. /* Handle decimal point. */
  407. if (dp) {
  408. if (base == 2) return STRSCAN_ERROR;
  409. fmt = STRSCAN_NUM;
  410. if (dig) {
  411. ex = (int32_t)(dp-(p-1)); dp = p-1;
  412. while (ex < 0 && *dp-- == '0') ex++, dig--; /* Skip trailing zeros. */
  413. if (ex <= -STRSCAN_MAXEXP) return STRSCAN_ERROR;
  414. if (base == 16) ex *= 4;
  415. }
  416. }
  417. /* Parse exponent. */
  418. if (base >= 10 && casecmp(*p, (uint32_t)(base == 16 ? 'p' : 'e'))) {
  419. uint32_t xx;
  420. int negx = 0;
  421. fmt = STRSCAN_NUM; p++;
  422. if (*p == '+' || *p == '-') negx = (*p++ == '-');
  423. if (!lj_char_isdigit(*p)) return STRSCAN_ERROR;
  424. xx = (*p++ & 15);
  425. while (lj_char_isdigit(*p)) {
  426. xx = xx * 10 + (*p & 15);
  427. if (xx >= STRSCAN_MAXEXP) return STRSCAN_ERROR;
  428. p++;
  429. }
  430. ex += negx ? (int32_t)(~xx+1u) : (int32_t)xx;
  431. }
  432. /* Parse suffix. */
  433. if (*p) {
  434. /* I (IMAG), U (U32), LL (I64), ULL/LLU (U64), L (long), UL/LU (ulong). */
  435. /* NYI: f (float). Not needed until cp_number() handles non-integers. */
  436. if (casecmp(*p, 'i')) {
  437. if (!(opt & STRSCAN_OPT_IMAG)) return STRSCAN_ERROR;
  438. p++; fmt = STRSCAN_IMAG;
  439. } else if (fmt == STRSCAN_INT) {
  440. if (casecmp(*p, 'u')) p++, fmt = STRSCAN_U32;
  441. if (casecmp(*p, 'l')) {
  442. p++;
  443. if (casecmp(*p, 'l')) p++, fmt += STRSCAN_I64 - STRSCAN_INT;
  444. else if (!(opt & STRSCAN_OPT_C)) return STRSCAN_ERROR;
  445. else if (sizeof(long) == 8) fmt += STRSCAN_I64 - STRSCAN_INT;
  446. }
  447. if (casecmp(*p, 'u') && (fmt == STRSCAN_INT || fmt == STRSCAN_I64))
  448. p++, fmt += STRSCAN_U32 - STRSCAN_INT;
  449. if ((fmt == STRSCAN_U32 && !(opt & STRSCAN_OPT_C)) ||
  450. (fmt >= STRSCAN_I64 && !(opt & STRSCAN_OPT_LL)))
  451. return STRSCAN_ERROR;
  452. }
  453. while (lj_char_isspace(*p)) p++;
  454. if (*p) return STRSCAN_ERROR;
  455. }
  456. if (p < pe) return STRSCAN_ERROR;
  457. /* Fast path for decimal 32 bit integers. */
  458. if (fmt == STRSCAN_INT && base == 10 &&
  459. (dig < 10 || (dig == 10 && *sp <= '2' && x < 0x80000000u+neg))) {
  460. if ((opt & STRSCAN_OPT_TONUM)) {
  461. o->n = neg ? -(double)x : (double)x;
  462. return STRSCAN_NUM;
  463. } else if (x == 0 && neg) {
  464. o->n = -0.0;
  465. return STRSCAN_NUM;
  466. } else {
  467. o->i = neg ? (int32_t)(~x+1u) : (int32_t)x;
  468. return STRSCAN_INT;
  469. }
  470. }
  471. /* Dispatch to base-specific parser. */
  472. if (base == 0 && !(fmt == STRSCAN_NUM || fmt == STRSCAN_IMAG))
  473. return strscan_oct(sp, o, fmt, neg, dig);
  474. if (base == 16)
  475. fmt = strscan_hex(sp, o, fmt, opt, ex, neg, dig);
  476. else if (base == 2)
  477. fmt = strscan_bin(sp, o, fmt, opt, ex, neg, dig);
  478. else
  479. fmt = strscan_dec(sp, o, fmt, opt, ex, neg, dig);
  480. /* Try to convert number to integer, if requested. */
  481. if (fmt == STRSCAN_NUM && (opt & STRSCAN_OPT_TOINT) && !tvismzero(o)) {
  482. double n = o->n;
  483. int32_t i = lj_num2int(n);
  484. if (n == (lua_Number)i) { o->i = i; return STRSCAN_INT; }
  485. }
  486. return fmt;
  487. }
  488. }
  489. int LJ_FASTCALL lj_strscan_num(GCstr *str, TValue *o)
  490. {
  491. StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), str->len, o,
  492. STRSCAN_OPT_TONUM);
  493. lj_assertX(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM, "bad scan format");
  494. return (fmt != STRSCAN_ERROR);
  495. }
  496. #if LJ_DUALNUM
  497. int LJ_FASTCALL lj_strscan_number(GCstr *str, TValue *o)
  498. {
  499. StrScanFmt fmt = lj_strscan_scan((const uint8_t *)strdata(str), str->len, o,
  500. STRSCAN_OPT_TOINT);
  501. lj_assertX(fmt == STRSCAN_ERROR || fmt == STRSCAN_NUM || fmt == STRSCAN_INT,
  502. "bad scan format");
  503. if (fmt == STRSCAN_INT) setitype(o, LJ_TISNUM);
  504. return (fmt != STRSCAN_ERROR);
  505. }
  506. #endif
  507. #undef DNEXT
  508. #undef DPREV
  509. #undef DLEN