strconv.odin 17 KB

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