fmt.odin 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207
  1. #import "os.odin";
  2. #import "mem.odin";
  3. #import "utf8.odin";
  4. #import "types.odin";
  5. #import "strconv.odin";
  6. #import "raw.odin";
  7. _BUFFER_SIZE :: 1<<12;
  8. StringBuffer :: union {
  9. Static {buf: []u8},
  10. Dynamic{buf: [dynamic]u8},
  11. }
  12. FmtInfo :: struct {
  13. minus: bool,
  14. plus: bool,
  15. space: bool,
  16. zero: bool,
  17. hash: bool,
  18. width_set: bool,
  19. prec_set: bool,
  20. width: int,
  21. prec: int,
  22. reordered: bool,
  23. good_arg_index: bool,
  24. buf: ^StringBuffer,
  25. arg: any, // Temporary
  26. }
  27. make_string_buffer_from_slice :: proc(b: []u8) -> StringBuffer {
  28. return StringBuffer.Static{b};
  29. }
  30. make_string_dynamic_buffer :: proc() -> StringBuffer {
  31. return StringBuffer.Dynamic{make([dynamic]u8)};
  32. }
  33. string_buffer_data :: proc(buf: ^StringBuffer) -> []u8 {
  34. match b in buf {
  35. case StringBuffer.Static:
  36. return b.buf[..];
  37. case StringBuffer.Dynamic:
  38. return b.buf[..];
  39. }
  40. return nil;
  41. }
  42. string_buffer_data :: proc(buf: StringBuffer) -> []u8 {
  43. match b in buf {
  44. case StringBuffer.Static:
  45. return b.buf[..];
  46. case StringBuffer.Dynamic:
  47. return b.buf[..];
  48. }
  49. return nil;
  50. }
  51. to_string :: proc(buf: StringBuffer) -> string {
  52. return string(string_buffer_data(buf));
  53. }
  54. write_string :: proc(buf: ^StringBuffer, s: string) {
  55. write_bytes(buf, []u8(s));
  56. }
  57. write_bytes :: proc(buf: ^StringBuffer, data: []u8) {
  58. match b in buf {
  59. case StringBuffer.Static:
  60. append(b.buf, ..data);
  61. case StringBuffer.Dynamic:
  62. append(b.buf, ..data);
  63. }
  64. }
  65. write_byte :: proc(buf: ^StringBuffer, data: u8) {
  66. match b in buf {
  67. case StringBuffer.Static:
  68. append(b.buf, data);
  69. case StringBuffer.Dynamic:
  70. append(b.buf, data);
  71. }
  72. }
  73. write_rune :: proc(buf: ^StringBuffer, r: rune) {
  74. if r < utf8.RUNE_SELF {
  75. write_byte(buf, u8(r));
  76. return;
  77. }
  78. b, n := utf8.encode_rune(r);
  79. write_bytes(buf, b[0..<n]);
  80. }
  81. write_int :: proc(buf: ^StringBuffer, i: i128, base: int) {
  82. b: [129]u8;
  83. s := strconv.append_bits(b[0..<0], u128(i), base, true, 128, strconv.digits, 0);
  84. write_string(buf, s);
  85. }
  86. write_int :: proc(buf: ^StringBuffer, i: i64, base: int) {
  87. b: [129]u8;
  88. s := strconv.append_bits(b[0..<0], u128(i), base, true, 64, strconv.digits, 0);
  89. write_string(buf, s);
  90. }
  91. fprint :: proc(fd: os.Handle, args: ..any) -> int {
  92. data: [_BUFFER_SIZE]u8;
  93. buf := make_string_buffer_from_slice(data[0..<0]);
  94. sbprint(&buf, ..args);
  95. res := string_buffer_data(buf);
  96. os.write(fd, res);
  97. return len(res);
  98. }
  99. fprintln :: proc(fd: os.Handle, args: ..any) -> int {
  100. data: [_BUFFER_SIZE]u8;
  101. buf := make_string_buffer_from_slice(data[0..<0]);
  102. sbprintln(&buf, ..args);
  103. res := string_buffer_data(buf);
  104. os.write(fd, res);
  105. return len(res);
  106. }
  107. fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
  108. data: [_BUFFER_SIZE]u8;
  109. buf := make_string_buffer_from_slice(data[0..<0]);
  110. sbprintf(&buf, fmt, ..args);
  111. res := string_buffer_data(buf);
  112. os.write(fd, res);
  113. return len(res);
  114. }
  115. // print* procedures return the number of bytes written
  116. print :: proc(args: ..any) -> int { return fprint(os.stdout, ..args); }
  117. print_err :: proc(args: ..any) -> int { return fprint(os.stderr, ..args); }
  118. println :: proc(args: ..any) -> int { return fprintln(os.stdout, ..args); }
  119. println_err :: proc(args: ..any) -> int { return fprintln(os.stderr, ..args); }
  120. printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args); }
  121. printf_err :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args); }
  122. // aprint* procedures return a string that was allocated with the current context
  123. // They must be freed accordingly
  124. aprint :: proc(args: ..any) -> string {
  125. buf := make_string_dynamic_buffer();
  126. sbprint(&buf, ..args);
  127. return to_string(buf);
  128. }
  129. aprintln :: proc(args: ..any) -> string {
  130. buf := make_string_dynamic_buffer();
  131. sbprintln(&buf, ..args);
  132. return to_string(buf);
  133. }
  134. aprintf :: proc(fmt: string, args: ..any) -> string {
  135. buf := make_string_dynamic_buffer();
  136. sbprintf(&buf, fmt, ..args);
  137. return to_string(buf);
  138. }
  139. // bprint* procedures return a string that was allocated with the current context
  140. // They must be freed accordingly
  141. bprint :: proc(buf: []u8, args: ..any) -> string {
  142. sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
  143. return sbprint(&sb, ..args);
  144. }
  145. bprintln :: proc(buf: []u8, args: ..any) -> string {
  146. sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
  147. return sbprintln(&sb, ..args);
  148. }
  149. bprintf :: proc(buf: []u8, fmt: string, args: ..any) -> string {
  150. sb := make_string_buffer_from_slice(buf[0..<0..<len(buf)]);
  151. return sbprintf(&sb, fmt, ..args);
  152. }
  153. fprint_type :: proc(fd: os.Handle, info: ^TypeInfo) {
  154. data: [_BUFFER_SIZE]u8;
  155. buf := make_string_buffer_from_slice(data[0..<0]);
  156. write_type(&buf, info);
  157. os.write(fd, string_buffer_data(buf));
  158. }
  159. write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) {
  160. if ti == nil {
  161. return;
  162. }
  163. using TypeInfo;
  164. match info in ti {
  165. case Named:
  166. write_string(buf, info.name);
  167. case Integer:
  168. match {
  169. case ti == type_info(int): write_string(buf, "int");
  170. case ti == type_info(uint): write_string(buf, "uint");
  171. case:
  172. write_string(buf, info.signed ? "i" : "u");
  173. write_int(buf, i64(8*info.size), 10);
  174. }
  175. case Rune:
  176. write_string(buf, "rune");
  177. case Float:
  178. match info.size {
  179. case 2: write_string(buf, "f16");
  180. case 4: write_string(buf, "f32");
  181. case 8: write_string(buf, "f64");
  182. }
  183. case Complex:
  184. match info.size {
  185. case 4: write_string(buf, "complex32");
  186. case 8: write_string(buf, "complex64");
  187. case 16: write_string(buf, "complex128");
  188. }
  189. case String: write_string(buf, "string");
  190. case Boolean: write_string(buf, "bool");
  191. case Any:
  192. write_string(buf, "any");
  193. case Atomic:
  194. write_string(buf, "atomic ");
  195. write_type(buf, info.elem);
  196. case Pointer:
  197. if info.elem == nil {
  198. write_string(buf, "rawptr");
  199. } else {
  200. write_string(buf, "^");
  201. write_type(buf, info.elem);
  202. }
  203. case Procedure:
  204. write_string(buf, "proc");
  205. if info.params == nil {
  206. write_string(buf, "()");
  207. } else {
  208. t := info.params.(^Tuple);
  209. write_string(buf, "(");
  210. for type, i in t.types {
  211. if i > 0 { write_string(buf, ", "); }
  212. write_type(buf, type);
  213. }
  214. write_string(buf, ")");
  215. }
  216. if info.results != nil {
  217. write_string(buf, " -> ");
  218. write_type(buf, info.results);
  219. }
  220. case Tuple:
  221. count := len(info.names);
  222. if count != 1 { write_string(buf, "("); }
  223. for name, i in info.names {
  224. if i > 0 { write_string(buf, ", "); }
  225. type := info.types[i];
  226. if len(name) > 0 {
  227. write_string(buf, name);
  228. write_string(buf, ": ");
  229. }
  230. write_type(buf, type);
  231. }
  232. if count != 1 { write_string(buf, ")"); }
  233. case Array:
  234. write_string(buf, "[");
  235. fi := FmtInfo{buf = buf};
  236. write_int(buf, i64(info.count), 10);
  237. write_string(buf, "]");
  238. write_type(buf, info.elem);
  239. case DynamicArray:
  240. write_string(buf, "[dynamic]");
  241. write_type(buf, info.elem);
  242. case Slice:
  243. write_string(buf, "[]");
  244. write_type(buf, info.elem);
  245. case Vector:
  246. write_string(buf, "[vector ");
  247. write_int(buf, i64(info.count), 10);
  248. write_string(buf, "]");
  249. write_type(buf, info.elem);
  250. case Map:
  251. write_string(buf, "map[");
  252. write_type(buf, info.key);
  253. write_byte(buf, ']');
  254. write_type(buf, info.value);
  255. case Struct:
  256. write_string(buf, "struct ");
  257. if info.packed { write_string(buf, "#packed "); }
  258. if info.ordered { write_string(buf, "#ordered "); }
  259. if info.custom_align {
  260. write_string(buf, "#align ");
  261. write_int(buf, i64(info.align), 10);
  262. write_byte(buf, ' ');
  263. }
  264. write_byte(buf, '{');
  265. for name, i in info.names {
  266. if i > 0 {
  267. write_string(buf, ", ");
  268. }
  269. write_string(buf, name);
  270. write_string(buf, ": ");
  271. write_type(buf, info.types[i]);
  272. }
  273. write_byte(buf, '}');
  274. case Union:
  275. write_string(buf, "union {");
  276. cf := info.common_fields;
  277. total_count := 0;
  278. for name, i in cf.names {
  279. if i > 0 {
  280. write_string(buf, ", ");
  281. }
  282. write_string(buf, name);
  283. write_string(buf, ": ");
  284. write_type(buf, cf.types[i]);
  285. total_count++;
  286. }
  287. for name, i in info.variant_names {
  288. if total_count > 0 || i > 0 {
  289. write_string(buf, ", ");
  290. }
  291. write_string(buf, name);
  292. write_byte(buf, '{');
  293. defer write_byte(buf, '}');
  294. variant_type := type_info_base(info.variant_types[i]);
  295. variant := variant_type.(^Struct);
  296. vc := len(variant.names)-len(cf.names);
  297. for j in 0..vc {
  298. if j > 0 {
  299. write_string(buf, ", ");
  300. }
  301. index := j + len(cf.names);
  302. write_string(buf, variant.names[index]);
  303. write_string(buf, ": ");
  304. write_type(buf, variant.types[index]);
  305. }
  306. }
  307. write_string(buf, "}");
  308. case RawUnion:
  309. write_string(buf, "raw_union {");
  310. for name, i in info.names {
  311. if i > 0 {
  312. write_string(buf, ", ");
  313. }
  314. write_string(buf, name);
  315. write_string(buf, ": ");
  316. write_type(buf, info.types[i]);
  317. }
  318. write_string(buf, "}");
  319. case Enum:
  320. write_string(buf, "enum ");
  321. write_type(buf, info.base);
  322. write_string(buf, " {");
  323. for name, i in info.names {
  324. if i > 0 {
  325. write_string(buf, ", ");
  326. }
  327. write_string(buf, name);
  328. }
  329. write_string(buf, "}");
  330. case BitField:
  331. write_string(buf, "bit_field ");
  332. if info.align != 1 {
  333. write_string(buf, "#align ");
  334. write_int(buf, i64(info.align), 10);
  335. write_rune(buf, ' ');
  336. }
  337. write_string(buf, " {");
  338. for name, i in info.names {
  339. if i > 0 {
  340. write_string(buf, ", ");
  341. }
  342. write_string(buf, name);
  343. write_string(buf, ": ");
  344. write_int(buf, i64(info.bits[i]), 10);
  345. }
  346. write_string(buf, "}");
  347. }
  348. }
  349. _parse_int :: proc(s: string, offset: int) -> (result: int, offset: int, ok: bool) {
  350. is_digit :: proc(r: rune) -> bool #inline {
  351. return '0' <= r && r <= '9';
  352. }
  353. result := 0;
  354. ok := true;
  355. i := 0;
  356. for i < len(s[offset..]) {
  357. c := rune(s[offset+i]);
  358. if !is_digit(c) {
  359. break;
  360. }
  361. i++;
  362. result *= 10;
  363. result += int(c)-'0';
  364. }
  365. return result, offset+i, i != 0;
  366. }
  367. _arg_number :: proc(fi: ^FmtInfo, arg_index: int, format: string, offset, arg_count: int) -> (index, offset: int, ok: bool) {
  368. parse_arg_number :: proc(format: string) -> (int, int, bool) {
  369. if len(format) < 3 {
  370. return 0, 1, false;
  371. }
  372. for i in 1..len(format) {
  373. if format[i] == ']' {
  374. width, new_index, ok := _parse_int(format, 1);
  375. if !ok || new_index != i {
  376. return 0, i+1, false;
  377. }
  378. return width-1, i+1, true;
  379. }
  380. }
  381. return 0, 1, false;
  382. }
  383. if len(format) <= offset || format[offset] != '[' {
  384. return arg_index, offset, false;
  385. }
  386. fi.reordered = true;
  387. index, width, ok := parse_arg_number(format[offset..]);
  388. if ok && 0 <= index && index < arg_count {
  389. return index, offset+width, true;
  390. }
  391. fi.good_arg_index = false;
  392. return arg_index, offset+width, false;
  393. }
  394. int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
  395. num := 0;
  396. new_arg_index := arg_index;
  397. ok := true;
  398. if arg_index < len(args) {
  399. arg := args[arg_index];
  400. arg.type_info = type_info_base(arg.type_info);
  401. match i in arg {
  402. case int: num = i;
  403. case i8: num = int(i);
  404. case i16: num = int(i);
  405. case i32: num = int(i);
  406. case i64: num = int(i);
  407. case u8: num = int(i);
  408. case u16: num = int(i);
  409. case u32: num = int(i);
  410. case u64: num = int(i);
  411. case:
  412. ok = false;
  413. }
  414. }
  415. return num, new_arg_index, ok;
  416. }
  417. fmt_bad_verb :: proc(using fi: ^FmtInfo, verb: rune) {
  418. assert(verb != 'v');
  419. write_string(buf, "%!");
  420. write_rune(buf, verb);
  421. write_byte(buf, '(');
  422. if arg.type_info != nil {
  423. write_type(buf, arg.type_info);
  424. write_byte(buf, '=');
  425. fmt_value(fi, arg, 'v');
  426. } else {
  427. write_string(buf, "<nil>");
  428. }
  429. write_byte(buf, ')');
  430. }
  431. fmt_bool :: proc(using fi: ^FmtInfo, b: bool, verb: rune) {
  432. match verb {
  433. case 't', 'v':
  434. write_string(buf, b ? "true" : "false");
  435. case:
  436. fmt_bad_verb(fi, verb);
  437. }
  438. }
  439. fmt_write_padding :: proc(fi: ^FmtInfo, width: int) {
  440. if width <= 0 {
  441. return;
  442. }
  443. pad_byte: u8 = '0';
  444. if fi.space {
  445. pad_byte = ' ';
  446. }
  447. data := string_buffer_data(fi.buf^);
  448. count := min(width, cap(data)-len(data));
  449. for _ in 0..<count {
  450. write_byte(fi.buf, pad_byte);
  451. }
  452. }
  453. _fmt_int :: proc(fi: ^FmtInfo, u: u128, base: int, is_signed: bool, bit_size: int, digits: string) {
  454. _, neg := strconv.is_integer_negative(u128(u), is_signed, bit_size);
  455. BUF_SIZE :: 256;
  456. if fi.width_set || fi.prec_set {
  457. width := fi.width + fi.prec + 3; // 3 extra bytes for sign and prefix
  458. if width > BUF_SIZE {
  459. // TODO(bill):????
  460. panic("_fmt_int: buffer overrun. Width and precision too big");
  461. }
  462. }
  463. prec := 0;
  464. if fi.prec_set {
  465. prec = fi.prec;
  466. if prec == 0 && u == 0 {
  467. prev_zero := fi.zero;
  468. fi.zero = false;
  469. fmt_write_padding(fi, fi.width);
  470. fi.zero = prev_zero;
  471. return;
  472. }
  473. } else if fi.zero && fi.width_set {
  474. prec = fi.width;
  475. if neg || fi.plus || fi.space {
  476. // There needs to be space for the "sign"
  477. prec--;
  478. }
  479. }
  480. match base {
  481. case 2, 8, 10, 12, 16:
  482. break;
  483. case:
  484. panic("_fmt_int: unknown base, whoops");
  485. }
  486. buf: [256]u8;
  487. start := 0;
  488. flags: strconv.IntFlag;
  489. if fi.hash && !fi.zero { flags |= strconv.IntFlag.Prefix; }
  490. if fi.plus { flags |= strconv.IntFlag.Plus; }
  491. if fi.space { flags |= strconv.IntFlag.Space; }
  492. s := strconv.append_bits(buf[start..<start], u128(u), base, is_signed, bit_size, digits, flags);
  493. if fi.hash && fi.zero {
  494. c: u8;
  495. match base {
  496. case 2: c = 'b';
  497. case 8: c = 'o';
  498. case 10: c = 'd';
  499. case 12: c = 'z';
  500. case 16: c = 'x';
  501. }
  502. if c != 0 {
  503. write_byte(fi.buf, '0');
  504. write_byte(fi.buf, c);
  505. }
  506. }
  507. prev_zero := fi.zero;
  508. defer fi.zero = prev_zero;
  509. fi.zero = false;
  510. _pad(fi, s);
  511. }
  512. immutable __DIGITS_LOWER := "0123456789abcdefx";
  513. immutable __DIGITS_UPPER := "0123456789ABCDEFX";
  514. fmt_rune :: proc(fi: ^FmtInfo, r: rune, verb: rune) {
  515. match verb {
  516. case 'c', 'r', 'v':
  517. write_rune(fi.buf, r);
  518. case:
  519. fmt_bad_verb(fi, verb);
  520. }
  521. }
  522. fmt_int :: proc(fi: ^FmtInfo, u: u128, is_signed: bool, bit_size: int, verb: rune) {
  523. match verb {
  524. case 'v': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER);
  525. case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER);
  526. case 'o': _fmt_int(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER);
  527. case 'd': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER);
  528. case 'x': _fmt_int(fi, u, 16, is_signed, bit_size, __DIGITS_LOWER);
  529. case 'X': _fmt_int(fi, u, 16, is_signed, bit_size, __DIGITS_UPPER);
  530. case 'c', 'r':
  531. fmt_rune(fi, rune(u), verb);
  532. case 'U':
  533. r := rune(u);
  534. if r < 0 || r > utf8.MAX_RUNE {
  535. fmt_bad_verb(fi, verb);
  536. } else {
  537. write_string(fi.buf, "U+");
  538. _fmt_int(fi, u, 16, false, bit_size, __DIGITS_UPPER);
  539. }
  540. case:
  541. fmt_bad_verb(fi, verb);
  542. }
  543. }
  544. _pad :: proc(fi: ^FmtInfo, s: string) {
  545. if !fi.width_set {
  546. write_string(fi.buf, s);
  547. return;
  548. }
  549. width := fi.width - utf8.rune_count(s);
  550. if fi.minus { // right pad
  551. write_string(fi.buf, s);
  552. fmt_write_padding(fi, width);
  553. } else { // left pad
  554. fmt_write_padding(fi, width);
  555. write_string(fi.buf, s);
  556. }
  557. }
  558. fmt_float :: proc(fi: ^FmtInfo, v: f64, bit_size: int, verb: rune) {
  559. match verb {
  560. // case 'e', 'E', 'f', 'F', 'g', 'G', 'v':
  561. // case 'f', 'F', 'v':
  562. case 'f', 'F', 'v':
  563. prec: int = 3;
  564. if fi.prec_set {
  565. prec = fi.prec;
  566. }
  567. buf: [386]u8;
  568. str := strconv.append_float(buf[1..<1], v, 'f', prec, bit_size);
  569. str = string(buf[0..len(str)]);
  570. if str[1] == '+' || str[1] == '-' {
  571. str = str[1..];
  572. } else {
  573. str[0] = '+';
  574. }
  575. if fi.space && !fi.plus && str[0] == '+' {
  576. str[0] = ' ';
  577. }
  578. if len(str) > 1 && str[1] == 'N' && str[1] == 'I' {
  579. write_string(fi.buf, str);
  580. return;
  581. }
  582. if fi.plus || str[0] != '+' {
  583. if fi.zero && fi.width_set && fi.width > len(str) {
  584. write_byte(fi.buf, str[0]);
  585. fmt_write_padding(fi, fi.width - len(str));
  586. write_string(fi.buf, str[1..]);
  587. } else {
  588. _pad(fi, str);
  589. }
  590. } else {
  591. _pad(fi, str[1..]);
  592. }
  593. case:
  594. fmt_bad_verb(fi, verb);
  595. }
  596. }
  597. fmt_string :: proc(fi: ^FmtInfo, s: string, verb: rune) {
  598. match verb {
  599. case 's', 'v':
  600. write_string(fi.buf, s);
  601. case 'x', 'X':
  602. space := fi.space;
  603. fi.space = false;
  604. defer fi.space = space;
  605. for i in 0..<len(s) {
  606. if i > 0 && space {
  607. write_byte(fi.buf, ' ');
  608. }
  609. _fmt_int(fi, u128(s[i]), 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
  610. }
  611. case:
  612. fmt_bad_verb(fi, verb);
  613. }
  614. }
  615. fmt_pointer :: proc(fi: ^FmtInfo, p: rawptr, verb: rune) {
  616. match verb {
  617. case 'p', 'v':
  618. // Okay
  619. case:
  620. fmt_bad_verb(fi, verb);
  621. return;
  622. }
  623. u := u128(uint(p));
  624. if !fi.hash || verb == 'v' {
  625. write_string(fi.buf, "0x");
  626. }
  627. _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER);
  628. }
  629. fmt_enum :: proc(fi: ^FmtInfo, v: any, verb: rune) {
  630. if v.type_info == nil || v.data == nil {
  631. write_string(fi.buf, "<nil>");
  632. return;
  633. }
  634. using TypeInfo;
  635. match e in v.type_info {
  636. case:
  637. fmt_bad_verb(fi, verb);
  638. return;
  639. case Enum:
  640. match verb {
  641. case 'd', 'f':
  642. fmt_arg(fi, any{v.data, type_info_base(e.base)}, verb);
  643. case 's', 'v':
  644. i: i128;
  645. f: f64;
  646. ok := false;
  647. a := any{v.data, type_info_base(e.base)};
  648. match v in a {
  649. case rune: i = i128(v);
  650. case i8: i = i128(v);
  651. case i16: i = i128(v);
  652. case i32: i = i128(v);
  653. case i64: i = i128(v);
  654. case i128: i = i128(v);
  655. case int: i = i128(v);
  656. case u8: i = i128(v);
  657. case u16: i = i128(v);
  658. case u32: i = i128(v);
  659. case u64: i = i128(v);
  660. case u128: i = i128(v);
  661. case uint: i = i128(v);
  662. case f32: f = f64(v); i = i128(transmute(i64, f));
  663. case f64: f = f64(v); i = i128(transmute(i64, f));
  664. }
  665. if types.is_string(e.base) {
  666. for val, idx in e.values {
  667. if val.i == i {
  668. write_string(fi.buf, e.names[idx]);
  669. ok = true;
  670. break;
  671. }
  672. }
  673. } else if len(e.values) == 0 {
  674. write_string(fi.buf, "");
  675. ok = true;
  676. } else {
  677. for val, idx in e.values {
  678. if val.i == i {
  679. write_string(fi.buf, e.names[idx]);
  680. ok = true;
  681. break;
  682. }
  683. }
  684. }
  685. if !ok {
  686. write_string(fi.buf, "!%(BAD ENUM VALUE)");
  687. }
  688. case:
  689. fmt_bad_verb(fi, verb);
  690. return;
  691. }
  692. }
  693. }
  694. fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) {
  695. if v.data == nil || v.type_info == nil {
  696. write_string(fi.buf, "<nil>");
  697. return;
  698. }
  699. using TypeInfo;
  700. match info in v.type_info {
  701. case Named:
  702. match b in info.base {
  703. case Struct:
  704. if verb != 'v' {
  705. fmt_bad_verb(fi, verb);
  706. return;
  707. }
  708. write_string(fi.buf, info.name);
  709. write_byte(fi.buf, '{');
  710. for _, i in b.names {
  711. if i > 0 {
  712. write_string(fi.buf, ", ");
  713. }
  714. write_string(fi.buf, b.names[i]);
  715. write_string(fi.buf, " = ");
  716. data := ^u8(v.data) + b.offsets[i];
  717. fmt_arg(fi, any{rawptr(data), b.types[i]}, 'v');
  718. }
  719. write_byte(fi.buf, '}');
  720. case:
  721. fmt_value(fi, any{v.data, info.base}, verb);
  722. }
  723. case Boolean: fmt_arg(fi, v, verb);
  724. case Integer: fmt_arg(fi, v, verb);
  725. case Rune: fmt_arg(fi, v, verb);
  726. case Float: fmt_arg(fi, v, verb);
  727. case Complex: fmt_arg(fi, v, verb);
  728. case String: fmt_arg(fi, v, verb);
  729. case Pointer:
  730. if v.type_info == type_info(^TypeInfo) {
  731. write_type(fi.buf, ^^TypeInfo(v.data)^);
  732. } else {
  733. fmt_pointer(fi, ^rawptr(v.data)^, verb);
  734. }
  735. case Atomic:
  736. fmt_arg(fi, any{v.data, info.elem}, verb);
  737. case Array:
  738. write_byte(fi.buf, '[');
  739. defer write_byte(fi.buf, ']');
  740. for i in 0..<info.count {
  741. if i > 0 {
  742. write_string(fi.buf, ", ");
  743. }
  744. data := ^u8(v.data) + i*info.elem_size;
  745. fmt_arg(fi, any{rawptr(data), info.elem}, verb);
  746. }
  747. case DynamicArray:
  748. write_byte(fi.buf, '[');
  749. defer write_byte(fi.buf, ']');
  750. array := ^raw.DynamicArray(v.data);
  751. for i in 0..<array.len {
  752. if i > 0 {
  753. write_string(fi.buf, ", ");
  754. }
  755. data := ^u8(array.data) + i*info.elem_size;
  756. fmt_arg(fi, any{rawptr(data), info.elem}, verb);
  757. }
  758. case Slice:
  759. write_byte(fi.buf, '[');
  760. defer write_byte(fi.buf, ']');
  761. slice := ^[]u8(v.data);
  762. for _, i in slice {
  763. if i > 0 {
  764. write_string(fi.buf, ", ");
  765. }
  766. data := &slice[0] + i*info.elem_size;
  767. fmt_arg(fi, any{rawptr(data), info.elem}, verb);
  768. }
  769. case Vector:
  770. write_byte(fi.buf, '<');
  771. defer write_byte(fi.buf, '>');
  772. for i in 0..<info.count {
  773. if i > 0 {
  774. write_string(fi.buf, ", ");
  775. }
  776. data := ^u8(v.data) + i*info.elem_size;
  777. fmt_value(fi, any{rawptr(data), info.elem}, verb);
  778. }
  779. case Map:
  780. if verb != 'v' {
  781. fmt_bad_verb(fi, verb);
  782. return;
  783. }
  784. write_string(fi.buf, "map[");
  785. defer write_byte(fi.buf, ']');
  786. entries := &(^raw.DynamicMap(v.data).entries);
  787. gs := type_info_base(info.generated_struct).(^Struct);
  788. ed := type_info_base(gs.types[1]).(^DynamicArray);
  789. entry_type := ed.elem.(^Struct);
  790. entry_size := ed.elem_size;
  791. for i in 0..<entries.len {
  792. if i > 0 {
  793. write_string(fi.buf, ", ");
  794. }
  795. data := ^u8(entries.data) + i*entry_size;
  796. header := ^__MapEntryHeader(data);
  797. if types.is_string(info.key) {
  798. write_string(fi.buf, header.key.str);
  799. } else {
  800. fi := FmtInfo{buf = fi.buf};
  801. fmt_arg(&fi, any{rawptr(&header.key.hash), info.key}, 'v');
  802. }
  803. write_string(fi.buf, "=");
  804. value := data + entry_type.offsets[2];
  805. fmt_arg(fi, any{rawptr(value), info.value}, 'v');
  806. }
  807. case Struct:
  808. write_byte(fi.buf, '{');
  809. defer write_byte(fi.buf, '}');
  810. for _, i in info.names {
  811. if i > 0 {
  812. write_string(fi.buf, ", ");
  813. }
  814. write_string(fi.buf, info.names[i]);
  815. write_string(fi.buf, " = ");
  816. data := ^u8(v.data) + info.offsets[i];
  817. fmt_value(fi, any{rawptr(data), info.types[i]}, 'v');
  818. }
  819. case Union:
  820. write_byte(fi.buf, '{');
  821. defer write_byte(fi.buf, '}');
  822. cf := info.common_fields;
  823. for _, i in cf.names {
  824. if i > 0 {
  825. write_string(fi.buf, ", ");
  826. }
  827. write_string(fi.buf, cf.names[i]);
  828. write_string(fi.buf, " = ");
  829. data := ^u8(v.data) + cf.offsets[i];
  830. fmt_value(fi, any{rawptr(data), cf.types[i]}, 'v');
  831. }
  832. case RawUnion:
  833. write_string(fi.buf, "(raw_union)");
  834. case Enum:
  835. fmt_enum(fi, v, verb);
  836. case Procedure:
  837. write_type(fi.buf, v.type_info);
  838. write_string(fi.buf, " @ ");
  839. fmt_pointer(fi, ^rawptr(v.data)^, 'p');
  840. }
  841. }
  842. fmt_complex :: proc(fi: ^FmtInfo, c: complex128, bits: int, verb: rune) {
  843. match verb {
  844. case 'f', 'F', 'v':
  845. r := real(c);
  846. i := imag(c);
  847. fmt_float(fi, r, bits/2, verb);
  848. if !fi.plus && i >= 0 {
  849. write_rune(fi.buf, '+');
  850. }
  851. fmt_float(fi, i, bits/2, verb);
  852. write_rune(fi.buf, 'i');
  853. case:
  854. fmt_bad_verb(fi, verb);
  855. return;
  856. }
  857. }
  858. _u128_to_lo_hi :: proc(a: u128) -> (lo, hi: u64) { return u64(a), u64(a>>64); }
  859. _i128_to_lo_hi :: proc(a: u128) -> (lo: u64 hi: i64) { return u64(a), i64(a>>64); }
  860. do_foo :: proc(fi: ^FmtInfo, f: f64) {
  861. fmt_string(fi, "Hellope$%!", 'v');
  862. }
  863. fmt_arg :: proc(fi: ^FmtInfo, arg: any, verb: rune) {
  864. if arg == nil {
  865. write_string(fi.buf, "<nil>");
  866. return;
  867. }
  868. fi.arg = arg;
  869. if verb == 'T' {
  870. ti := arg.type_info;
  871. match a in arg {
  872. case ^TypeInfo: ti = a;
  873. }
  874. write_type(fi.buf, ti);
  875. return;
  876. }
  877. base_arg := arg;
  878. base_arg.type_info = type_info_base(base_arg.type_info);
  879. match a in base_arg {
  880. case any: fmt_arg(fi, a, verb);
  881. case bool: fmt_bool(fi, a, verb);
  882. case rune: fmt_rune(fi, a, verb);
  883. case f32: fmt_float(fi, f64(a), 32, verb);
  884. case f64: fmt_float(fi, a, 64, verb);
  885. case complex64: fmt_complex(fi, complex128(a), 64, verb);
  886. case complex128: fmt_complex(fi, a, 128, verb);
  887. case int: fmt_int(fi, u128(a), true, 8*size_of(int), verb);
  888. case i8: fmt_int(fi, u128(a), true, 8, verb);
  889. case i16: fmt_int(fi, u128(a), true, 16, verb);
  890. case i32: fmt_int(fi, u128(a), true, 32, verb);
  891. case i64: fmt_int(fi, u128(a), true, 64, verb);
  892. case i128: fmt_int(fi, u128(a), true, 128, verb);
  893. case uint: fmt_int(fi, u128(a), false, 8*size_of(uint), verb);
  894. case u8: fmt_int(fi, u128(a), false, 8, verb);
  895. case u16: fmt_int(fi, u128(a), false, 16, verb);
  896. case u32: fmt_int(fi, u128(a), false, 32, verb);
  897. case u64: fmt_int(fi, u128(a), false, 64, verb);
  898. case u128: fmt_int(fi, u128(a), false, 128, verb);
  899. case string: fmt_string(fi, a, verb);
  900. case: fmt_value(fi, arg, verb);
  901. }
  902. }
  903. sbprint :: proc(buf: ^StringBuffer, args: ..any) -> string {
  904. fi: FmtInfo;
  905. fi.buf = buf;
  906. prev_string := false;
  907. for arg, i in args {
  908. is_string := arg != nil && types.is_string(arg.type_info);
  909. if i > 0 && !is_string && !prev_string {
  910. write_byte(buf, ' ');
  911. }
  912. fmt_value(&fi, args[i], 'v');
  913. prev_string = is_string;
  914. }
  915. return to_string(buf^);
  916. }
  917. sbprintln :: proc(buf: ^StringBuffer, args: ..any) -> string {
  918. fi: FmtInfo;
  919. fi.buf = buf;
  920. for arg, i in args {
  921. if i > 0 {
  922. write_byte(buf, ' ');
  923. }
  924. fmt_value(&fi, args[i], 'v');
  925. }
  926. write_byte(buf, '\n');
  927. return to_string(buf^);
  928. }
  929. sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string {
  930. fi := FmtInfo{};
  931. end := len(fmt);
  932. arg_index := 0;
  933. was_prev_index := false;
  934. for i := 0; i < end; /**/ {
  935. fi = FmtInfo{buf = b, good_arg_index = true};
  936. prev_i := i;
  937. for i < end && fmt[i] != '%' {
  938. i++;
  939. }
  940. if i > prev_i {
  941. write_string(b, fmt[prev_i..<i]);
  942. }
  943. if i >= end {
  944. break;
  945. }
  946. // Process a "verb"
  947. i++;
  948. prefix_loop:
  949. for ; i < end; i++ {
  950. match fmt[i] {
  951. case '+':
  952. fi.plus = true;
  953. case '-':
  954. fi.minus = true;
  955. fi.zero = false;
  956. case ' ':
  957. fi.space = true;
  958. case '#':
  959. fi.hash = true;
  960. case '0':
  961. fi.zero = !fi.minus;
  962. case:
  963. break prefix_loop;
  964. }
  965. }
  966. arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args));
  967. // Width
  968. if i < end && fmt[i] == '*' {
  969. i++;
  970. fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index);
  971. if !fi.width_set {
  972. write_string(b, "%!(BAD WIDTH)");
  973. }
  974. if fi.width < 0 {
  975. fi.width = -fi.width;
  976. fi.minus = true;
  977. fi.zero = false;
  978. }
  979. was_prev_index = false;
  980. } else {
  981. fi.width, i, fi.width_set = _parse_int(fmt, i);
  982. if was_prev_index && fi.width_set { // %[6]2d
  983. fi.good_arg_index = false;
  984. }
  985. }
  986. // Precision
  987. if i < end && fmt[i] == '.' {
  988. i++;
  989. if was_prev_index { // %[6].2d
  990. fi.good_arg_index = false;
  991. }
  992. if i < end && fmt[i] == '*' {
  993. arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args));
  994. i++;
  995. fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index);
  996. if fi.prec < 0 {
  997. fi.prec = 0;
  998. fi.prec_set = false;
  999. }
  1000. if !fi.prec_set {
  1001. write_string(fi.buf, "%!(BAD PRECISION)");
  1002. }
  1003. was_prev_index = false;
  1004. } else {
  1005. fi.prec, i, fi.prec_set = _parse_int(fmt, i);
  1006. if !fi.prec_set {
  1007. // fi.prec_set = true;
  1008. // fi.prec = 0;
  1009. }
  1010. }
  1011. }
  1012. if !was_prev_index {
  1013. arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args));
  1014. }
  1015. if i >= end {
  1016. write_string(b, "%!(NO VERB)");
  1017. break;
  1018. }
  1019. verb, w := utf8.decode_rune(fmt[i..]);
  1020. i += w;
  1021. if verb == '%' {
  1022. write_byte(b, '%');
  1023. } else if !fi.good_arg_index {
  1024. write_string(b, "%!(BAD ARGUMENT NUMBER)");
  1025. } else if arg_index >= len(args) {
  1026. write_string(b, "%!(MISSING ARGUMENT)");
  1027. } else {
  1028. fmt_arg(&fi, args[arg_index], verb);
  1029. arg_index++;
  1030. }
  1031. }
  1032. if !fi.reordered && arg_index < len(args) {
  1033. write_string(b, "%!(EXTRA ");
  1034. for arg, index in args[arg_index..] {
  1035. if index > 0 {
  1036. write_string(b, ", ");
  1037. }
  1038. if arg == nil {
  1039. write_string(b, "<nil>");
  1040. } else {
  1041. fmt_arg(&fi, args[index], 'v');
  1042. }
  1043. }
  1044. write_string(b, ")");
  1045. }
  1046. return to_string(b^);
  1047. }