fmt.odin 28 KB

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