strconv.odin 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. package strconv
  2. import "core:unicode/utf8"
  3. parse_bool :: proc(s: string, n: ^int = nil) -> (result: bool = false, ok: bool) {
  4. switch s {
  5. case "1", "t", "T", "true", "TRUE", "True":
  6. if n != nil { n^ = len(s) }
  7. return true, true
  8. case "0", "f", "F", "false", "FALSE", "False":
  9. if n != nil { n^ = len(s) }
  10. return false, true
  11. }
  12. return
  13. }
  14. _digit_value :: proc(r: rune) -> int {
  15. ri := int(r)
  16. v: int = 16
  17. switch r {
  18. case '0'..='9': v = ri-'0'
  19. case 'a'..='z': v = ri-'a'+10
  20. case 'A'..='Z': v = ri-'A'+10
  21. }
  22. return v
  23. }
  24. // Parses an integer value from a string, in the given base, without a prefix.
  25. //
  26. // Returns ok=false if no numeric value of the appropriate base could be found,
  27. // or if the input string contained more than just the number.
  28. //
  29. // ```
  30. // n, ok := strconv.parse_i64_of_base("-1234eeee", 10);
  31. // assert(n == -1234 && ok);
  32. // ```
  33. parse_i64_of_base :: proc(str: string, base: int, n: ^int = nil) -> (value: i64, ok: bool) {
  34. assert(base <= 16, "base must be 1-16")
  35. s := str
  36. defer if n != nil { n^ = len(str)-len(s) }
  37. if s == "" {
  38. return
  39. }
  40. neg := false
  41. if len(s) > 1 {
  42. switch s[0] {
  43. case '-':
  44. neg = true
  45. s = s[1:]
  46. case '+':
  47. s = s[1:]
  48. }
  49. }
  50. i := 0
  51. for r in s {
  52. if r == '_' {
  53. i += 1
  54. continue
  55. }
  56. v := i64(_digit_value(r))
  57. if v >= i64(base) {
  58. break
  59. }
  60. value *= i64(base)
  61. value += v
  62. i += 1
  63. }
  64. s = s[i:]
  65. if neg {
  66. value = -value
  67. }
  68. ok = len(s) == 0
  69. return
  70. }
  71. // Parses a integer value from a string, in base 10, unless there's a prefix.
  72. //
  73. // Returns ok=false if a valid integer could not be found,
  74. // or if the input string contained more than just the number.
  75. //
  76. // ```
  77. // n, ok := strconv.parse_i64_maybe_prefixed("1234");
  78. // assert(n == 1234 && ok);
  79. //
  80. // n, ok = strconv.parse_i64_maybe_prefixed("0xeeee");
  81. // assert(n == 0xeeee && ok);
  82. // ```
  83. parse_i64_maybe_prefixed :: proc(str: string, n: ^int = nil) -> (value: i64, ok: bool) {
  84. s := str
  85. defer if n != nil { n^ = len(str)-len(s) }
  86. if s == "" {
  87. return
  88. }
  89. neg := false
  90. if len(s) > 1 {
  91. switch s[0] {
  92. case '-':
  93. neg = true
  94. s = s[1:]
  95. case '+':
  96. s = s[1:]
  97. }
  98. }
  99. base: i64 = 10
  100. if len(s) > 2 && s[0] == '0' {
  101. switch s[1] {
  102. case 'b': base = 2; s = s[2:]
  103. case 'o': base = 8; s = s[2:]
  104. case 'd': base = 10; s = s[2:]
  105. case 'z': base = 12; s = s[2:]
  106. case 'x': base = 16; s = s[2:]
  107. }
  108. }
  109. i := 0
  110. for r in s {
  111. if r == '_' {
  112. i += 1
  113. continue
  114. }
  115. v := i64(_digit_value(r))
  116. if v >= base {
  117. break
  118. }
  119. value *= base
  120. value += v
  121. i += 1
  122. }
  123. s = s[i:]
  124. if neg {
  125. value = -value
  126. }
  127. ok = len(s) == 0
  128. return
  129. }
  130. parse_i64 :: proc{parse_i64_maybe_prefixed, parse_i64_of_base}
  131. // Parses an unsigned integer value from a string, in the given base, and
  132. // without a prefix.
  133. //
  134. // Returns ok=false if no numeric value of the appropriate base could be found,
  135. // or if the input string contained more than just the number.
  136. //
  137. // ```
  138. // n, ok := strconv.parse_u64_of_base("1234eeee", 10);
  139. // assert(n == 1234 && ok);
  140. //
  141. // n, ok = strconv.parse_u64_of_base("5678eeee", 16);
  142. // assert(n == 0x5678eeee && ok);
  143. // ```
  144. parse_u64_of_base :: proc(str: string, base: int, n: ^int = nil) -> (value: u64, ok: bool) {
  145. assert(base <= 16, "base must be 1-16")
  146. s := str
  147. defer if n != nil { n^ = len(str)-len(s) }
  148. if s == "" {
  149. return
  150. }
  151. if len(s) > 1 && s[0] == '+' {
  152. s = s[1:]
  153. }
  154. i := 0
  155. for r in s {
  156. if r == '_' {
  157. i += 1
  158. continue
  159. }
  160. v := u64(_digit_value(r))
  161. if v >= u64(base) {
  162. break
  163. }
  164. value *= u64(base)
  165. value += v
  166. i += 1
  167. }
  168. s = s[i:]
  169. ok = len(s) == 0
  170. return
  171. }
  172. // Parses an unsigned integer value from a string in base 10, unless there's a prefix.
  173. //
  174. // Returns ok=false if a valid integer could not be found, if the value was negative,
  175. // or if the input string contained more than just the number.
  176. //
  177. // ```
  178. // n, ok := strconv.parse_u64_maybe_prefixed("1234");
  179. // assert(n == 1234 && ok);
  180. //
  181. // n, ok = strconv.parse_u64_maybe_prefixed("0xeeee");
  182. // assert(n == 0xeeee && ok);
  183. // ```
  184. parse_u64_maybe_prefixed :: proc(str: string, n: ^int = nil) -> (value: u64, ok: bool) {
  185. s := str
  186. defer if n != nil { n^ = len(str)-len(s) }
  187. if s == "" {
  188. return
  189. }
  190. if len(s) > 1 && s[0] == '+' {
  191. s = s[1:]
  192. }
  193. base := u64(10)
  194. if len(s) > 2 && s[0] == '0' {
  195. switch s[1] {
  196. case 'b': base = 2; s = s[2:]
  197. case 'o': base = 8; s = s[2:]
  198. case 'd': base = 10; s = s[2:]
  199. case 'z': base = 12; s = s[2:]
  200. case 'x': base = 16; s = s[2:]
  201. }
  202. }
  203. i := 0
  204. for r in s {
  205. if r == '_' {
  206. i += 1
  207. continue
  208. }
  209. v := u64(_digit_value(r))
  210. if v >= base {
  211. break
  212. }
  213. value *= base
  214. value += v
  215. i += 1
  216. }
  217. s = s[i:]
  218. ok = len(s) == 0
  219. return
  220. }
  221. parse_u64 :: proc{parse_u64_maybe_prefixed, parse_u64_of_base}
  222. // Parses an integer value from a string in the given base, or
  223. // - if the string has a prefix (e.g: '0x') then that will determine the base;
  224. // - otherwise, assumes base 10.
  225. //
  226. // Returns ok=false if no appropriate value could be found, or if the input string
  227. // contained more than just the number.
  228. //
  229. // ```
  230. // n, ok := strconv.parse_int("1234"); // without prefix, inferred base 10
  231. // assert(n == 1234 && ok);
  232. //
  233. // n, ok = strconv.parse_int("ffff", 16); // without prefix, explicit base
  234. // assert(n == 0xffff && ok);
  235. //
  236. // n, ok = strconv.parse_int("0xffff"); // with prefix and inferred base
  237. // assert(n == 0xffff && ok);
  238. // ```
  239. parse_int :: proc(s: string, base := 0, n: ^int = nil) -> (value: int, ok: bool) {
  240. v: i64 = ---
  241. switch base {
  242. case 0: v, ok = parse_i64_maybe_prefixed(s, n)
  243. case: v, ok = parse_i64_of_base(s, base, n)
  244. }
  245. value = int(v)
  246. return
  247. }
  248. // Parses an unsigned integer value from a string in the given base, or
  249. // - if the string has a prefix (e.g: '0x') then that will determine the base;
  250. // - otherwise, assumes base 10.
  251. //
  252. // Returns ok=false if:
  253. // - no appropriate value could be found; or
  254. // - the value was negative.
  255. // - the input string contained more than just the number.
  256. //
  257. // ```
  258. // n, ok := strconv.parse_uint("1234"); // without prefix, inferred base 10
  259. // assert(n == 1234 && ok);
  260. //
  261. // n, ok = strconv.parse_uint("ffff", 16); // without prefix, explicit base
  262. // assert(n == 0xffff && ok);
  263. //
  264. // n, ok = strconv.parse_uint("0xffff"); // with prefix and inferred base
  265. // assert(n == 0xffff && ok);
  266. // ```
  267. parse_uint :: proc(s: string, base := 0, n: ^int = nil) -> (value: uint, ok: bool) {
  268. v: u64 = ---
  269. switch base {
  270. case 0: v, ok = parse_u64_maybe_prefixed(s, n)
  271. case: v, ok = parse_u64_of_base(s, base, n)
  272. }
  273. value = uint(v)
  274. return
  275. }
  276. // Parses an integer value from a string, in the given base, without a prefix.
  277. //
  278. // Returns ok=false if no numeric value of the appropriate base could be found,
  279. // or if the input string contained more than just the number.
  280. //
  281. // ```
  282. // n, ok := strconv.parse_i128_of_base("-1234eeee", 10);
  283. // assert(n == -1234 && ok);
  284. // ```
  285. parse_i128_of_base :: proc(str: string, base: int, n: ^int = nil) -> (value: i128, ok: bool) {
  286. assert(base <= 16, "base must be 1-16")
  287. s := str
  288. defer if n != nil { n^ = len(str)-len(s) }
  289. if s == "" {
  290. return
  291. }
  292. neg := false
  293. if len(s) > 1 {
  294. switch s[0] {
  295. case '-':
  296. neg = true
  297. s = s[1:]
  298. case '+':
  299. s = s[1:]
  300. }
  301. }
  302. i := 0
  303. for r in s {
  304. if r == '_' {
  305. i += 1
  306. continue
  307. }
  308. v := i128(_digit_value(r))
  309. if v >= i128(base) {
  310. break
  311. }
  312. value *= i128(base)
  313. value += v
  314. i += 1
  315. }
  316. s = s[i:]
  317. if neg {
  318. value = -value
  319. }
  320. ok = len(s) == 0
  321. return
  322. }
  323. // Parses a integer value from a string, in base 10, unless there's a prefix.
  324. //
  325. // Returns ok=false if a valid integer could not be found,
  326. // or if the input string contained more than just the number.
  327. //
  328. // ```
  329. // n, ok := strconv.parse_i128_maybe_prefixed("1234");
  330. // assert(n == 1234 && ok);
  331. //
  332. // n, ok = strconv.parse_i128_maybe_prefixed("0xeeee");
  333. // assert(n == 0xeeee && ok);
  334. // ```
  335. parse_i128_maybe_prefixed :: proc(str: string, n: ^int = nil) -> (value: i128, ok: bool) {
  336. s := str
  337. defer if n != nil { n^ = len(str)-len(s) }
  338. if s == "" {
  339. return
  340. }
  341. neg := false
  342. if len(s) > 1 {
  343. switch s[0] {
  344. case '-':
  345. neg = true
  346. s = s[1:]
  347. case '+':
  348. s = s[1:]
  349. }
  350. }
  351. base: i128 = 10
  352. if len(s) > 2 && s[0] == '0' {
  353. switch s[1] {
  354. case 'b': base = 2; s = s[2:]
  355. case 'o': base = 8; s = s[2:]
  356. case 'd': base = 10; s = s[2:]
  357. case 'z': base = 12; s = s[2:]
  358. case 'x': base = 16; s = s[2:]
  359. }
  360. }
  361. i := 0
  362. for r in s {
  363. if r == '_' {
  364. i += 1
  365. continue
  366. }
  367. v := i128(_digit_value(r))
  368. if v >= base {
  369. break
  370. }
  371. value *= base
  372. value += v
  373. i += 1
  374. }
  375. s = s[i:]
  376. if neg {
  377. value = -value
  378. }
  379. ok = len(s) == 0
  380. return
  381. }
  382. parse_i128 :: proc{parse_i128_maybe_prefixed, parse_i128_of_base}
  383. // Parses an unsigned integer value from a string, in the given base, and
  384. // without a prefix.
  385. //
  386. // Returns ok=false if no numeric value of the appropriate base could be found,
  387. // or if the input string contained more than just the number.
  388. //
  389. // ```
  390. // n, ok := strconv.parse_u128_of_base("1234eeee", 10);
  391. // assert(n == 1234 && ok);
  392. //
  393. // n, ok = strconv.parse_u128_of_base("5678eeee", 16);
  394. // assert(n == 0x5678eeee && ok);
  395. // ```
  396. parse_u128_of_base :: proc(str: string, base: int, n: ^int = nil) -> (value: u128, ok: bool) {
  397. assert(base <= 16, "base must be 1-16")
  398. s := str
  399. defer if n != nil { n^ = len(str)-len(s) }
  400. if s == "" {
  401. return
  402. }
  403. if len(s) > 1 && s[0] == '+' {
  404. s = s[1:]
  405. }
  406. i := 0
  407. for r in s {
  408. if r == '_' {
  409. i += 1
  410. continue
  411. }
  412. v := u128(_digit_value(r))
  413. if v >= u128(base) {
  414. break
  415. }
  416. value *= u128(base)
  417. value += v
  418. i += 1
  419. }
  420. s = s[i:]
  421. ok = len(s) == 0
  422. return
  423. }
  424. // Parses an unsigned integer value from a string in base 10, unless there's a prefix.
  425. //
  426. // Returns ok=false if a valid integer could not be found, if the value was negative,
  427. // or if the input string contained more than just the number.
  428. //
  429. // ```
  430. // n, ok := strconv.parse_u128_maybe_prefixed("1234");
  431. // assert(n == 1234 && ok);
  432. //
  433. // n, ok = strconv.parse_u128_maybe_prefixed("0xeeee");
  434. // assert(n == 0xeeee && ok);
  435. // ```
  436. parse_u128_maybe_prefixed :: proc(str: string, n: ^int = nil) -> (value: u128, ok: bool) {
  437. s := str
  438. defer if n != nil { n^ = len(str)-len(s) }
  439. if s == "" {
  440. return
  441. }
  442. if len(s) > 1 && s[0] == '+' {
  443. s = s[1:]
  444. }
  445. base := u128(10)
  446. if len(s) > 2 && s[0] == '0' {
  447. switch s[1] {
  448. case 'b': base = 2; s = s[2:]
  449. case 'o': base = 8; s = s[2:]
  450. case 'd': base = 10; s = s[2:]
  451. case 'z': base = 12; s = s[2:]
  452. case 'x': base = 16; s = s[2:]
  453. }
  454. }
  455. i := 0
  456. for r in s {
  457. if r == '_' {
  458. i += 1
  459. continue
  460. }
  461. v := u128(_digit_value(r))
  462. if v >= base {
  463. break
  464. }
  465. value *= base
  466. value += v
  467. i += 1
  468. }
  469. s = s[i:]
  470. ok = len(s) == 0
  471. return
  472. }
  473. parse_u128 :: proc{parse_u128_maybe_prefixed, parse_u128_of_base}
  474. // Parses a 32-bit floating point number from a string.
  475. //
  476. // Returns ok=false if a base 10 float could not be found,
  477. // or if the input string contained more than just the number.
  478. //
  479. // ```
  480. // n, ok := strconv.parse_f32("12.34eee");
  481. // assert(n == 12.34 && ok);
  482. //
  483. // n, ok = strconv.parse_f32("12.34");
  484. // assert(n == 12.34 && ok);
  485. // ```
  486. parse_f32 :: proc(s: string, n: ^int = nil) -> (value: f32, ok: bool) {
  487. v: f64 = ---
  488. v, ok = parse_f64(s, n)
  489. return f32(v), ok
  490. }
  491. // Parses a 64-bit floating point number from a string.
  492. //
  493. // Returns ok=false if a base 10 float could not be found,
  494. // or if the input string contained more than just the number.
  495. //
  496. // ```
  497. // n, ok := strconv.parse_f32("12.34eee");
  498. // assert(n == 12.34 && ok);
  499. //
  500. // n, ok = strconv.parse_f32("12.34");
  501. // assert(n == 12.34 && ok);
  502. // ```
  503. parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
  504. s := str
  505. defer if n != nil { n^ = len(str)-len(s) }
  506. if s == "" {
  507. return
  508. }
  509. i := 0
  510. sign: f64 = 1
  511. switch s[i] {
  512. case '-': i += 1; sign = -1
  513. case '+': i += 1
  514. }
  515. for ; i < len(s); i += 1 {
  516. r := rune(s[i])
  517. if r == '_' {
  518. continue
  519. }
  520. v := _digit_value(r)
  521. if v >= 10 {
  522. break
  523. }
  524. value *= 10
  525. value += f64(v)
  526. }
  527. if i < len(s) && s[i] == '.' {
  528. pow10: f64 = 10
  529. i += 1
  530. for ; i < len(s); i += 1 {
  531. r := rune(s[i])
  532. if r == '_' {
  533. continue
  534. }
  535. v := _digit_value(r)
  536. if v >= 10 {
  537. break
  538. }
  539. value += f64(v)/pow10
  540. pow10 *= 10
  541. }
  542. }
  543. frac := false
  544. scale: f64 = 1
  545. if i < len(s) && (s[i] == 'e' || s[i] == 'E') {
  546. i += 1
  547. if i < len(s) {
  548. switch s[i] {
  549. case '-': i += 1; frac = true
  550. case '+': i += 1
  551. }
  552. exp: u32 = 0
  553. for ; i < len(s); i += 1 {
  554. r := rune(s[i])
  555. if r == '_' {
  556. continue
  557. }
  558. d := u32(_digit_value(r))
  559. if d >= 10 {
  560. break
  561. }
  562. exp = exp * 10 + d
  563. }
  564. if exp > 308 { exp = 308 }
  565. for exp >= 50 { scale *= 1e50; exp -= 50 }
  566. for exp >= 8 { scale *= 1e8; exp -= 8 }
  567. for exp > 0 { scale *= 10; exp -= 1 }
  568. }
  569. }
  570. s = s[i:]
  571. if frac {
  572. value = sign * (value/scale)
  573. } else {
  574. value = sign * (value*scale)
  575. }
  576. ok = len(s) == 0
  577. return
  578. }
  579. append_bool :: proc(buf: []byte, b: bool) -> string {
  580. n := 0
  581. if b {
  582. n = copy(buf, "true")
  583. } else {
  584. n = copy(buf, "false")
  585. }
  586. return string(buf[:n])
  587. }
  588. append_uint :: proc(buf: []byte, u: u64, base: int) -> string {
  589. return append_bits(buf, u, base, false, 8*size_of(uint), digits, nil)
  590. }
  591. append_int :: proc(buf: []byte, i: i64, base: int) -> string {
  592. return append_bits(buf, u64(i), base, true, 8*size_of(int), digits, nil)
  593. }
  594. itoa :: proc(buf: []byte, i: int) -> string {
  595. return append_int(buf, i64(i), 10)
  596. }
  597. atoi :: proc(s: string) -> int {
  598. v, _ := parse_int(s)
  599. return v
  600. }
  601. atof :: proc(s: string) -> f64 {
  602. v, _ := parse_f64(s)
  603. return v
  604. }
  605. ftoa :: append_float
  606. append_float :: proc(buf: []byte, f: f64, fmt: byte, prec, bit_size: int) -> string {
  607. return string(generic_ftoa(buf, f, fmt, prec, bit_size))
  608. }
  609. quote :: proc(buf: []byte, str: string) -> string {
  610. write_byte :: proc(buf: []byte, i: ^int, bytes: ..byte) {
  611. if i^ >= len(buf) {
  612. return
  613. }
  614. n := copy(buf[i^:], bytes[:])
  615. i^ += n
  616. }
  617. if buf == nil {
  618. return ""
  619. }
  620. c :: '"'
  621. i := 0
  622. s := str
  623. write_byte(buf, &i, c)
  624. for width := 0; len(s) > 0; s = s[width:] {
  625. r := rune(s[0])
  626. width = 1
  627. if r >= utf8.RUNE_SELF {
  628. r, width = utf8.decode_rune_in_string(s)
  629. }
  630. if width == 1 && r == utf8.RUNE_ERROR {
  631. write_byte(buf, &i, '\\', 'x')
  632. write_byte(buf, &i, digits[s[0]>>4])
  633. write_byte(buf, &i, digits[s[0]&0xf])
  634. }
  635. if i < len(buf) {
  636. x := quote_rune(buf[i:], r)
  637. i += len(x)
  638. }
  639. }
  640. write_byte(buf, &i, c)
  641. return string(buf[:i])
  642. }
  643. quote_rune :: proc(buf: []byte, r: rune) -> string {
  644. write_byte :: proc(buf: []byte, i: ^int, bytes: ..byte) {
  645. if i^ < len(buf) {
  646. n := copy(buf[i^:], bytes[:])
  647. i^ += n
  648. }
  649. }
  650. write_string :: proc(buf: []byte, i: ^int, s: string) {
  651. if i^ < len(buf) {
  652. n := copy(buf[i^:], s)
  653. i^ += n
  654. }
  655. }
  656. write_rune :: proc(buf: []byte, i: ^int, r: rune) {
  657. if i^ < len(buf) {
  658. b, w := utf8.encode_rune(r)
  659. n := copy(buf[i^:], b[:w])
  660. i^ += n
  661. }
  662. }
  663. if buf == nil {
  664. return ""
  665. }
  666. i := 0
  667. write_byte(buf, &i, '\'')
  668. switch r {
  669. case '\a': write_string(buf, &i, "\\a")
  670. case '\b': write_string(buf, &i, "\\b")
  671. case '\e': write_string(buf, &i, "\\e")
  672. case '\f': write_string(buf, &i, "\\f")
  673. case '\n': write_string(buf, &i, "\\n")
  674. case '\r': write_string(buf, &i, "\\r")
  675. case '\t': write_string(buf, &i, "\\t")
  676. case '\v': write_string(buf, &i, "\\v")
  677. case:
  678. if r < 32 {
  679. write_string(buf, &i, "\\x")
  680. b: [2]byte
  681. s := append_bits(b[:], u64(r), 16, true, 64, digits, nil)
  682. switch len(s) {
  683. case 0: write_string(buf, &i, "00")
  684. case 1: write_rune(buf, &i, '0')
  685. case 2: write_string(buf, &i, s)
  686. }
  687. } else {
  688. write_rune(buf, &i, r)
  689. }
  690. }
  691. write_byte(buf, &i, '\'')
  692. return string(buf[:i])
  693. }
  694. unquote_char :: proc(str: string, quote: byte) -> (r: rune, multiple_bytes: bool, tail_string: string, success: bool) {
  695. hex_to_int :: proc(c: byte) -> int {
  696. switch c {
  697. case '0'..='9': return int(c-'0')
  698. case 'a'..='f': return int(c-'a')+10
  699. case 'A'..='F': return int(c-'A')+10
  700. }
  701. return -1
  702. }
  703. w: int
  704. if str[0] == quote && quote == '"' {
  705. return
  706. } else if str[0] >= 0x80 {
  707. r, w = utf8.decode_rune_in_string(str)
  708. return r, true, str[w:], true
  709. } else if str[0] != '\\' {
  710. return rune(str[0]), false, str[1:], true
  711. }
  712. if len(str) <= 1 {
  713. return
  714. }
  715. s := str
  716. c := s[1]
  717. s = s[2:]
  718. switch c {
  719. case:
  720. return
  721. case 'a': r = '\a'
  722. case 'b': r = '\b'
  723. case 'f': r = '\f'
  724. case 'n': r = '\n'
  725. case 'r': r = '\r'
  726. case 't': r = '\t'
  727. case 'v': r = '\v'
  728. case '\\': r = '\\'
  729. case '"': r = '"'
  730. case '\'': r = '\''
  731. case '0'..='7':
  732. v := int(c-'0')
  733. if len(s) < 2 {
  734. return
  735. }
  736. for i in 0..<len(s) {
  737. d := int(s[i]-'0')
  738. if d < 0 || d > 7 {
  739. return
  740. }
  741. v = (v<<3) | d
  742. }
  743. s = s[2:]
  744. if v > 0xff {
  745. return
  746. }
  747. r = rune(v)
  748. case 'x', 'u', 'U':
  749. count: int
  750. switch c {
  751. case 'x': count = 2
  752. case 'u': count = 4
  753. case 'U': count = 8
  754. }
  755. if len(s) < count {
  756. return
  757. }
  758. for i in 0..<count {
  759. d := hex_to_int(s[i])
  760. if d < 0 {
  761. return
  762. }
  763. r = (r<<4) | rune(d)
  764. }
  765. s = s[count:]
  766. if c == 'x' {
  767. break
  768. }
  769. if r > utf8.MAX_RUNE {
  770. return
  771. }
  772. multiple_bytes = true
  773. }
  774. success = true
  775. tail_string = s
  776. return
  777. }
  778. unquote_string :: proc(lit: string, allocator := context.allocator) -> (res: string, allocated, success: bool) {
  779. contains_rune :: proc(s: string, r: rune) -> int {
  780. for c, offset in s {
  781. if c == r {
  782. return offset
  783. }
  784. }
  785. return -1
  786. }
  787. if len(lit) < 2 {
  788. return
  789. }
  790. if lit[0] == '`' {
  791. return lit[1:len(lit)-1], false, true
  792. }
  793. s := lit
  794. quote := '"'
  795. if s == `""` {
  796. return "", false, true
  797. }
  798. s = s[1:len(s)-1]
  799. if contains_rune(s, '\n') >= 0 {
  800. return s, false, false
  801. }
  802. if contains_rune(s, '\\') < 0 && contains_rune(s, quote) < 0 {
  803. if quote == '"' {
  804. return s, false, true
  805. }
  806. }
  807. context.allocator = allocator
  808. buf_len := 3*len(s) / 2
  809. buf := make([]byte, buf_len)
  810. offset := 0
  811. for len(s) > 0 {
  812. r, multiple_bytes, tail_string, ok := unquote_char(s, byte(quote))
  813. if !ok {
  814. delete(buf)
  815. return s, false, false
  816. }
  817. s = tail_string
  818. if r < 0x80 || !multiple_bytes {
  819. buf[offset] = byte(r)
  820. offset += 1
  821. } else {
  822. b, w := utf8.encode_rune(r)
  823. copy(buf[offset:], b[:w])
  824. offset += w
  825. }
  826. }
  827. new_string := string(buf[:offset])
  828. return new_string, true, true
  829. }