Format.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/CharacterTypes.h>
  7. #include <AK/Format.h>
  8. #include <AK/GenericLexer.h>
  9. #include <AK/IntegralMath.h>
  10. #include <AK/StringBuilder.h>
  11. #include <AK/kstdio.h>
  12. #if defined(AK_OS_SERENITY) && !defined(KERNEL)
  13. # include <serenity.h>
  14. #endif
  15. #ifdef KERNEL
  16. # include <Kernel/Process.h>
  17. # include <Kernel/Thread.h>
  18. #else
  19. # include <math.h>
  20. # include <stdio.h>
  21. # include <string.h>
  22. #endif
  23. namespace AK {
  24. class FormatParser : public GenericLexer {
  25. public:
  26. struct FormatSpecifier {
  27. StringView flags;
  28. size_t index;
  29. };
  30. explicit FormatParser(StringView input);
  31. StringView consume_literal();
  32. bool consume_number(size_t& value);
  33. bool consume_specifier(FormatSpecifier& specifier);
  34. bool consume_replacement_field(size_t& index);
  35. };
  36. namespace {
  37. static constexpr size_t use_next_index = NumericLimits<size_t>::max();
  38. // The worst case is that we have the largest 64-bit value formatted as binary number, this would take
  39. // 65 bytes. Choosing a larger power of two won't hurt and is a bit of mitigation against out-of-bounds accesses.
  40. static constexpr size_t convert_unsigned_to_string(u64 value, Array<u8, 128>& buffer, u8 base, bool upper_case)
  41. {
  42. VERIFY(base >= 2 && base <= 16);
  43. constexpr char const* lowercase_lookup = "0123456789abcdef";
  44. constexpr char const* uppercase_lookup = "0123456789ABCDEF";
  45. if (value == 0) {
  46. buffer[0] = '0';
  47. return 1;
  48. }
  49. size_t used = 0;
  50. while (value > 0) {
  51. if (upper_case)
  52. buffer[used++] = uppercase_lookup[value % base];
  53. else
  54. buffer[used++] = lowercase_lookup[value % base];
  55. value /= base;
  56. }
  57. for (size_t i = 0; i < used / 2; ++i)
  58. swap(buffer[i], buffer[used - i - 1]);
  59. return used;
  60. }
  61. ErrorOr<void> vformat_impl(TypeErasedFormatParams& params, FormatBuilder& builder, FormatParser& parser)
  62. {
  63. auto const literal = parser.consume_literal();
  64. TRY(builder.put_literal(literal));
  65. FormatParser::FormatSpecifier specifier;
  66. if (!parser.consume_specifier(specifier)) {
  67. VERIFY(parser.is_eof());
  68. return {};
  69. }
  70. if (specifier.index == use_next_index)
  71. specifier.index = params.take_next_index();
  72. auto& parameter = params.parameters().at(specifier.index);
  73. FormatParser argparser { specifier.flags };
  74. TRY(parameter.formatter(params, builder, argparser, parameter.value));
  75. TRY(vformat_impl(params, builder, parser));
  76. return {};
  77. }
  78. } // namespace AK::{anonymous}
  79. FormatParser::FormatParser(StringView input)
  80. : GenericLexer(input)
  81. {
  82. }
  83. StringView FormatParser::consume_literal()
  84. {
  85. auto const begin = tell();
  86. while (!is_eof()) {
  87. if (consume_specific("{{"))
  88. continue;
  89. if (consume_specific("}}"))
  90. continue;
  91. if (next_is(is_any_of("{}"sv)))
  92. return m_input.substring_view(begin, tell() - begin);
  93. consume();
  94. }
  95. return m_input.substring_view(begin);
  96. }
  97. bool FormatParser::consume_number(size_t& value)
  98. {
  99. value = 0;
  100. bool consumed_at_least_one = false;
  101. while (next_is(is_ascii_digit)) {
  102. value *= 10;
  103. value += parse_ascii_digit(consume());
  104. consumed_at_least_one = true;
  105. }
  106. return consumed_at_least_one;
  107. }
  108. bool FormatParser::consume_specifier(FormatSpecifier& specifier)
  109. {
  110. VERIFY(!next_is('}'));
  111. if (!consume_specific('{'))
  112. return false;
  113. if (!consume_number(specifier.index))
  114. specifier.index = use_next_index;
  115. if (consume_specific(':')) {
  116. auto const begin = tell();
  117. size_t level = 1;
  118. while (level > 0) {
  119. VERIFY(!is_eof());
  120. if (consume_specific('{')) {
  121. ++level;
  122. continue;
  123. }
  124. if (consume_specific('}')) {
  125. --level;
  126. continue;
  127. }
  128. consume();
  129. }
  130. specifier.flags = m_input.substring_view(begin, tell() - begin - 1);
  131. } else {
  132. if (!consume_specific('}'))
  133. VERIFY_NOT_REACHED();
  134. specifier.flags = ""sv;
  135. }
  136. return true;
  137. }
  138. bool FormatParser::consume_replacement_field(size_t& index)
  139. {
  140. if (!consume_specific('{'))
  141. return false;
  142. if (!consume_number(index))
  143. index = use_next_index;
  144. if (!consume_specific('}'))
  145. VERIFY_NOT_REACHED();
  146. return true;
  147. }
  148. ErrorOr<void> FormatBuilder::put_padding(char fill, size_t amount)
  149. {
  150. for (size_t i = 0; i < amount; ++i)
  151. TRY(m_builder.try_append(fill));
  152. return {};
  153. }
  154. ErrorOr<void> FormatBuilder::put_literal(StringView value)
  155. {
  156. for (size_t i = 0; i < value.length(); ++i) {
  157. TRY(m_builder.try_append(value[i]));
  158. if (value[i] == '{' || value[i] == '}')
  159. ++i;
  160. }
  161. return {};
  162. }
  163. ErrorOr<void> FormatBuilder::put_string(
  164. StringView value,
  165. Align align,
  166. size_t min_width,
  167. size_t max_width,
  168. char fill)
  169. {
  170. auto const used_by_string = min(max_width, value.length());
  171. auto const used_by_padding = max(min_width, used_by_string) - used_by_string;
  172. if (used_by_string < value.length())
  173. value = value.substring_view(0, used_by_string);
  174. if (align == Align::Left || align == Align::Default) {
  175. TRY(m_builder.try_append(value));
  176. TRY(put_padding(fill, used_by_padding));
  177. } else if (align == Align::Center) {
  178. auto const used_by_left_padding = used_by_padding / 2;
  179. auto const used_by_right_padding = ceil_div<size_t, size_t>(used_by_padding, 2);
  180. TRY(put_padding(fill, used_by_left_padding));
  181. TRY(m_builder.try_append(value));
  182. TRY(put_padding(fill, used_by_right_padding));
  183. } else if (align == Align::Right) {
  184. TRY(put_padding(fill, used_by_padding));
  185. TRY(m_builder.try_append(value));
  186. }
  187. return {};
  188. }
  189. ErrorOr<void> FormatBuilder::put_u64(
  190. u64 value,
  191. u8 base,
  192. bool prefix,
  193. bool upper_case,
  194. bool zero_pad,
  195. Align align,
  196. size_t min_width,
  197. char fill,
  198. SignMode sign_mode,
  199. bool is_negative)
  200. {
  201. if (align == Align::Default)
  202. align = Align::Right;
  203. Array<u8, 128> buffer;
  204. auto const used_by_digits = convert_unsigned_to_string(value, buffer, base, upper_case);
  205. size_t used_by_prefix = 0;
  206. if (align == Align::Right && zero_pad) {
  207. // We want String::formatted("{:#08x}", 32) to produce '0x00000020' instead of '0x000020'. This
  208. // behavior differs from both fmtlib and printf, but is more intuitive.
  209. used_by_prefix = 0;
  210. } else {
  211. if (is_negative || sign_mode != SignMode::OnlyIfNeeded)
  212. used_by_prefix += 1;
  213. if (prefix) {
  214. if (base == 8)
  215. used_by_prefix += 1;
  216. else if (base == 16)
  217. used_by_prefix += 2;
  218. else if (base == 2)
  219. used_by_prefix += 2;
  220. }
  221. }
  222. auto const used_by_field = used_by_prefix + used_by_digits;
  223. auto const used_by_padding = max(used_by_field, min_width) - used_by_field;
  224. auto const put_prefix = [&]() -> ErrorOr<void> {
  225. if (is_negative)
  226. TRY(m_builder.try_append('-'));
  227. else if (sign_mode == SignMode::Always)
  228. TRY(m_builder.try_append('+'));
  229. else if (sign_mode == SignMode::Reserved)
  230. TRY(m_builder.try_append(' '));
  231. if (prefix) {
  232. if (base == 2) {
  233. if (upper_case)
  234. TRY(m_builder.try_append("0B"sv));
  235. else
  236. TRY(m_builder.try_append("0b"sv));
  237. } else if (base == 8) {
  238. TRY(m_builder.try_append("0"sv));
  239. } else if (base == 16) {
  240. if (upper_case)
  241. TRY(m_builder.try_append("0X"sv));
  242. else
  243. TRY(m_builder.try_append("0x"sv));
  244. }
  245. }
  246. return {};
  247. };
  248. auto const put_digits = [&]() -> ErrorOr<void> {
  249. for (size_t i = 0; i < used_by_digits; ++i)
  250. TRY(m_builder.try_append(buffer[i]));
  251. return {};
  252. };
  253. if (align == Align::Left) {
  254. auto const used_by_right_padding = used_by_padding;
  255. TRY(put_prefix());
  256. TRY(put_digits());
  257. TRY(put_padding(fill, used_by_right_padding));
  258. } else if (align == Align::Center) {
  259. auto const used_by_left_padding = used_by_padding / 2;
  260. auto const used_by_right_padding = ceil_div<size_t, size_t>(used_by_padding, 2);
  261. TRY(put_padding(fill, used_by_left_padding));
  262. TRY(put_prefix());
  263. TRY(put_digits());
  264. TRY(put_padding(fill, used_by_right_padding));
  265. } else if (align == Align::Right) {
  266. auto const used_by_left_padding = used_by_padding;
  267. if (zero_pad) {
  268. TRY(put_prefix());
  269. TRY(put_padding('0', used_by_left_padding));
  270. TRY(put_digits());
  271. } else {
  272. TRY(put_padding(fill, used_by_left_padding));
  273. TRY(put_prefix());
  274. TRY(put_digits());
  275. }
  276. }
  277. return {};
  278. }
  279. ErrorOr<void> FormatBuilder::put_i64(
  280. i64 value,
  281. u8 base,
  282. bool prefix,
  283. bool upper_case,
  284. bool zero_pad,
  285. Align align,
  286. size_t min_width,
  287. char fill,
  288. SignMode sign_mode)
  289. {
  290. auto const is_negative = value < 0;
  291. value = is_negative ? -value : value;
  292. TRY(put_u64(static_cast<u64>(value), base, prefix, upper_case, zero_pad, align, min_width, fill, sign_mode, is_negative));
  293. return {};
  294. }
  295. ErrorOr<void> FormatBuilder::put_fixed_point(
  296. i64 integer_value,
  297. u64 fraction_value,
  298. u64 fraction_one,
  299. u8 base,
  300. bool upper_case,
  301. bool zero_pad,
  302. Align align,
  303. size_t min_width,
  304. size_t precision,
  305. char fill,
  306. SignMode sign_mode)
  307. {
  308. StringBuilder string_builder;
  309. FormatBuilder format_builder { string_builder };
  310. bool is_negative = integer_value < 0;
  311. if (is_negative)
  312. integer_value = -integer_value;
  313. TRY(format_builder.put_u64(static_cast<u64>(integer_value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode, is_negative));
  314. if (precision > 0) {
  315. // FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good
  316. // place to start would be the following video from CppCon 2019:
  317. // https://youtu.be/4P_kbF0EbZM (Stephan T. Lavavej “Floating-Point <charconv>: Making Your Code 10x Faster With C++17's Final Boss”)
  318. u64 scale = pow<u64>(10, precision);
  319. auto fraction = (scale * fraction_value) / fraction_one; // TODO: overflows
  320. if (is_negative)
  321. fraction = scale - fraction;
  322. while (fraction != 0 && fraction % 10 == 0)
  323. fraction /= 10;
  324. size_t visible_precision = 0;
  325. {
  326. auto fraction_tmp = fraction;
  327. for (; visible_precision < precision; ++visible_precision) {
  328. if (fraction_tmp == 0)
  329. break;
  330. fraction_tmp /= 10;
  331. }
  332. }
  333. if (zero_pad || visible_precision > 0)
  334. TRY(string_builder.try_append('.'));
  335. if (visible_precision > 0)
  336. TRY(format_builder.put_u64(fraction, base, false, upper_case, true, Align::Right, visible_precision));
  337. if (zero_pad && (precision - visible_precision) > 0)
  338. TRY(format_builder.put_u64(0, base, false, false, true, Align::Right, precision - visible_precision));
  339. }
  340. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  341. return {};
  342. }
  343. #ifndef KERNEL
  344. ErrorOr<void> FormatBuilder::put_f64(
  345. double value,
  346. u8 base,
  347. bool upper_case,
  348. bool zero_pad,
  349. Align align,
  350. size_t min_width,
  351. size_t precision,
  352. char fill,
  353. SignMode sign_mode)
  354. {
  355. StringBuilder string_builder;
  356. FormatBuilder format_builder { string_builder };
  357. if (isnan(value) || isinf(value)) [[unlikely]] {
  358. if (value < 0.0)
  359. TRY(string_builder.try_append('-'));
  360. else if (sign_mode == SignMode::Always)
  361. TRY(string_builder.try_append('+'));
  362. else if (sign_mode == SignMode::Reserved)
  363. TRY(string_builder.try_append(' '));
  364. if (isnan(value))
  365. TRY(string_builder.try_append(upper_case ? "NAN"sv : "nan"sv));
  366. else
  367. TRY(string_builder.try_append(upper_case ? "INF"sv : "inf"sv));
  368. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  369. return {};
  370. }
  371. bool is_negative = value < 0.0;
  372. if (is_negative)
  373. value = -value;
  374. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode, is_negative));
  375. if (precision > 0) {
  376. // FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good
  377. // place to start would be the following video from CppCon 2019:
  378. // https://youtu.be/4P_kbF0EbZM (Stephan T. Lavavej “Floating-Point <charconv>: Making Your Code 10x Faster With C++17's Final Boss”)
  379. value -= static_cast<i64>(value);
  380. double epsilon = 0.5;
  381. for (size_t i = 0; i < precision; ++i)
  382. epsilon /= 10.0;
  383. size_t visible_precision = 0;
  384. for (; visible_precision < precision; ++visible_precision) {
  385. if (value - static_cast<i64>(value) < epsilon)
  386. break;
  387. value *= 10.0;
  388. epsilon *= 10.0;
  389. }
  390. if (zero_pad || visible_precision > 0)
  391. TRY(string_builder.try_append('.'));
  392. if (visible_precision > 0)
  393. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, true, Align::Right, visible_precision));
  394. if (zero_pad && (precision - visible_precision) > 0)
  395. TRY(format_builder.put_u64(0, base, false, false, true, Align::Right, precision - visible_precision));
  396. }
  397. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  398. return {};
  399. }
  400. ErrorOr<void> FormatBuilder::put_f80(
  401. long double value,
  402. u8 base,
  403. bool upper_case,
  404. Align align,
  405. size_t min_width,
  406. size_t precision,
  407. char fill,
  408. SignMode sign_mode)
  409. {
  410. StringBuilder string_builder;
  411. FormatBuilder format_builder { string_builder };
  412. if (isnan(value) || isinf(value)) [[unlikely]] {
  413. if (value < 0.0l)
  414. TRY(string_builder.try_append('-'));
  415. else if (sign_mode == SignMode::Always)
  416. TRY(string_builder.try_append('+'));
  417. else if (sign_mode == SignMode::Reserved)
  418. TRY(string_builder.try_append(' '));
  419. if (isnan(value))
  420. TRY(string_builder.try_append(upper_case ? "NAN"sv : "nan"sv));
  421. else
  422. TRY(string_builder.try_append(upper_case ? "INF"sv : "inf"sv));
  423. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  424. return {};
  425. }
  426. bool is_negative = value < 0.0l;
  427. if (is_negative)
  428. value = -value;
  429. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode, is_negative));
  430. if (precision > 0) {
  431. // FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good
  432. // place to start would be the following video from CppCon 2019:
  433. // https://youtu.be/4P_kbF0EbZM (Stephan T. Lavavej “Floating-Point <charconv>: Making Your Code 10x Faster With C++17's Final Boss”)
  434. value -= static_cast<i64>(value);
  435. long double epsilon = 0.5l;
  436. for (size_t i = 0; i < precision; ++i)
  437. epsilon /= 10.0l;
  438. size_t visible_precision = 0;
  439. for (; visible_precision < precision; ++visible_precision) {
  440. if (value - static_cast<i64>(value) < epsilon)
  441. break;
  442. value *= 10.0l;
  443. epsilon *= 10.0l;
  444. }
  445. if (visible_precision > 0) {
  446. string_builder.append('.');
  447. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, true, Align::Right, visible_precision));
  448. }
  449. }
  450. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  451. return {};
  452. }
  453. #endif
  454. ErrorOr<void> FormatBuilder::put_hexdump(ReadonlyBytes bytes, size_t width, char fill)
  455. {
  456. auto put_char_view = [&](auto i) -> ErrorOr<void> {
  457. TRY(put_padding(fill, 4));
  458. for (size_t j = i - width; j < i; ++j) {
  459. auto ch = bytes[j];
  460. TRY(m_builder.try_append(ch >= 32 && ch <= 127 ? ch : '.')); // silly hack
  461. }
  462. return {};
  463. };
  464. for (size_t i = 0; i < bytes.size(); ++i) {
  465. if (width > 0) {
  466. if (i % width == 0 && i) {
  467. TRY(put_char_view(i));
  468. TRY(put_literal("\n"sv));
  469. }
  470. }
  471. TRY(put_u64(bytes[i], 16, false, false, true, Align::Right, 2));
  472. }
  473. if (width > 0 && bytes.size() && bytes.size() % width == 0)
  474. TRY(put_char_view(bytes.size()));
  475. return {};
  476. }
  477. ErrorOr<void> vformat(StringBuilder& builder, StringView fmtstr, TypeErasedFormatParams& params)
  478. {
  479. FormatBuilder fmtbuilder { builder };
  480. FormatParser parser { fmtstr };
  481. TRY(vformat_impl(params, fmtbuilder, parser));
  482. return {};
  483. }
  484. void StandardFormatter::parse(TypeErasedFormatParams& params, FormatParser& parser)
  485. {
  486. if ("<^>"sv.contains(parser.peek(1))) {
  487. VERIFY(!parser.next_is(is_any_of("{}"sv)));
  488. m_fill = parser.consume();
  489. }
  490. if (parser.consume_specific('<'))
  491. m_align = FormatBuilder::Align::Left;
  492. else if (parser.consume_specific('^'))
  493. m_align = FormatBuilder::Align::Center;
  494. else if (parser.consume_specific('>'))
  495. m_align = FormatBuilder::Align::Right;
  496. if (parser.consume_specific('-'))
  497. m_sign_mode = FormatBuilder::SignMode::OnlyIfNeeded;
  498. else if (parser.consume_specific('+'))
  499. m_sign_mode = FormatBuilder::SignMode::Always;
  500. else if (parser.consume_specific(' '))
  501. m_sign_mode = FormatBuilder::SignMode::Reserved;
  502. if (parser.consume_specific('#'))
  503. m_alternative_form = true;
  504. if (parser.consume_specific('0'))
  505. m_zero_pad = true;
  506. if (size_t index = 0; parser.consume_replacement_field(index)) {
  507. if (index == use_next_index)
  508. index = params.take_next_index();
  509. m_width = params.parameters().at(index).to_size();
  510. } else if (size_t width = 0; parser.consume_number(width)) {
  511. m_width = width;
  512. }
  513. if (parser.consume_specific('.')) {
  514. if (size_t index = 0; parser.consume_replacement_field(index)) {
  515. if (index == use_next_index)
  516. index = params.take_next_index();
  517. m_precision = params.parameters().at(index).to_size();
  518. } else if (size_t precision = 0; parser.consume_number(precision)) {
  519. m_precision = precision;
  520. }
  521. }
  522. if (parser.consume_specific('b'))
  523. m_mode = Mode::Binary;
  524. else if (parser.consume_specific('B'))
  525. m_mode = Mode::BinaryUppercase;
  526. else if (parser.consume_specific('d'))
  527. m_mode = Mode::Decimal;
  528. else if (parser.consume_specific('o'))
  529. m_mode = Mode::Octal;
  530. else if (parser.consume_specific('x'))
  531. m_mode = Mode::Hexadecimal;
  532. else if (parser.consume_specific('X'))
  533. m_mode = Mode::HexadecimalUppercase;
  534. else if (parser.consume_specific('c'))
  535. m_mode = Mode::Character;
  536. else if (parser.consume_specific('s'))
  537. m_mode = Mode::String;
  538. else if (parser.consume_specific('p'))
  539. m_mode = Mode::Pointer;
  540. else if (parser.consume_specific('f'))
  541. m_mode = Mode::Float;
  542. else if (parser.consume_specific('a'))
  543. m_mode = Mode::Hexfloat;
  544. else if (parser.consume_specific('A'))
  545. m_mode = Mode::HexfloatUppercase;
  546. else if (parser.consume_specific("hex-dump"))
  547. m_mode = Mode::HexDump;
  548. if (!parser.is_eof())
  549. dbgln("{} did not consume '{}'", __PRETTY_FUNCTION__, parser.remaining());
  550. VERIFY(parser.is_eof());
  551. }
  552. ErrorOr<void> Formatter<StringView>::format(FormatBuilder& builder, StringView value)
  553. {
  554. if (m_sign_mode != FormatBuilder::SignMode::Default)
  555. VERIFY_NOT_REACHED();
  556. if (m_alternative_form)
  557. VERIFY_NOT_REACHED();
  558. if (m_zero_pad)
  559. VERIFY_NOT_REACHED();
  560. if (m_mode != Mode::Default && m_mode != Mode::String && m_mode != Mode::Character && m_mode != Mode::HexDump)
  561. VERIFY_NOT_REACHED();
  562. m_width = m_width.value_or(0);
  563. m_precision = m_precision.value_or(NumericLimits<size_t>::max());
  564. if (m_mode == Mode::HexDump)
  565. return builder.put_hexdump(value.bytes(), m_width.value(), m_fill);
  566. return builder.put_string(value, m_align, m_width.value(), m_precision.value(), m_fill);
  567. }
  568. ErrorOr<void> Formatter<FormatString>::vformat(FormatBuilder& builder, StringView fmtstr, TypeErasedFormatParams& params)
  569. {
  570. StringBuilder string_builder;
  571. TRY(AK::vformat(string_builder, fmtstr, params));
  572. TRY(Formatter<StringView>::format(builder, string_builder.string_view()));
  573. return {};
  574. }
  575. template<Integral T>
  576. ErrorOr<void> Formatter<T>::format(FormatBuilder& builder, T value)
  577. {
  578. if (m_mode == Mode::Character) {
  579. // FIXME: We just support ASCII for now, in the future maybe unicode?
  580. VERIFY(value >= 0 && value <= 127);
  581. m_mode = Mode::String;
  582. Formatter<StringView> formatter { *this };
  583. return formatter.format(builder, StringView { reinterpret_cast<char const*>(&value), 1 });
  584. }
  585. if (m_precision.has_value())
  586. VERIFY_NOT_REACHED();
  587. if (m_mode == Mode::Pointer) {
  588. if (m_sign_mode != FormatBuilder::SignMode::Default)
  589. VERIFY_NOT_REACHED();
  590. if (m_align != FormatBuilder::Align::Default)
  591. VERIFY_NOT_REACHED();
  592. if (m_alternative_form)
  593. VERIFY_NOT_REACHED();
  594. if (m_width.has_value())
  595. VERIFY_NOT_REACHED();
  596. m_mode = Mode::Hexadecimal;
  597. m_alternative_form = true;
  598. m_width = 2 * sizeof(void*);
  599. m_zero_pad = true;
  600. }
  601. u8 base = 0;
  602. bool upper_case = false;
  603. if (m_mode == Mode::Binary) {
  604. base = 2;
  605. } else if (m_mode == Mode::BinaryUppercase) {
  606. base = 2;
  607. upper_case = true;
  608. } else if (m_mode == Mode::Octal) {
  609. base = 8;
  610. } else if (m_mode == Mode::Decimal || m_mode == Mode::Default) {
  611. base = 10;
  612. } else if (m_mode == Mode::Hexadecimal) {
  613. base = 16;
  614. } else if (m_mode == Mode::HexadecimalUppercase) {
  615. base = 16;
  616. upper_case = true;
  617. } else if (m_mode == Mode::HexDump) {
  618. m_width = m_width.value_or(32);
  619. return builder.put_hexdump({ &value, sizeof(value) }, m_width.value(), m_fill);
  620. } else {
  621. VERIFY_NOT_REACHED();
  622. }
  623. m_width = m_width.value_or(0);
  624. if constexpr (IsSame<MakeUnsigned<T>, T>)
  625. return builder.put_u64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
  626. else
  627. return builder.put_i64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
  628. }
  629. ErrorOr<void> Formatter<char>::format(FormatBuilder& builder, char value)
  630. {
  631. if (m_mode == Mode::Binary || m_mode == Mode::BinaryUppercase || m_mode == Mode::Decimal || m_mode == Mode::Octal || m_mode == Mode::Hexadecimal || m_mode == Mode::HexadecimalUppercase) {
  632. // Trick: signed char != char. (Sometimes weird features are actually helpful.)
  633. Formatter<signed char> formatter { *this };
  634. return formatter.format(builder, static_cast<signed char>(value));
  635. } else {
  636. Formatter<StringView> formatter { *this };
  637. return formatter.format(builder, { &value, 1 });
  638. }
  639. }
  640. ErrorOr<void> Formatter<wchar_t>::format(FormatBuilder& builder, wchar_t value)
  641. {
  642. if (m_mode == Mode::Binary || m_mode == Mode::BinaryUppercase || m_mode == Mode::Decimal || m_mode == Mode::Octal || m_mode == Mode::Hexadecimal || m_mode == Mode::HexadecimalUppercase) {
  643. Formatter<u32> formatter { *this };
  644. return formatter.format(builder, static_cast<u32>(value));
  645. } else {
  646. StringBuilder codepoint;
  647. codepoint.append_code_point(value);
  648. Formatter<StringView> formatter { *this };
  649. return formatter.format(builder, codepoint.string_view());
  650. }
  651. }
  652. ErrorOr<void> Formatter<bool>::format(FormatBuilder& builder, bool value)
  653. {
  654. if (m_mode == Mode::Binary || m_mode == Mode::BinaryUppercase || m_mode == Mode::Decimal || m_mode == Mode::Octal || m_mode == Mode::Hexadecimal || m_mode == Mode::HexadecimalUppercase) {
  655. Formatter<u8> formatter { *this };
  656. return formatter.format(builder, static_cast<u8>(value));
  657. } else if (m_mode == Mode::HexDump) {
  658. return builder.put_hexdump({ &value, sizeof(value) }, m_width.value_or(32), m_fill);
  659. } else {
  660. Formatter<StringView> formatter { *this };
  661. return formatter.format(builder, value ? "true"sv : "false"sv);
  662. }
  663. }
  664. #ifndef KERNEL
  665. ErrorOr<void> Formatter<long double>::format(FormatBuilder& builder, long double value)
  666. {
  667. u8 base;
  668. bool upper_case;
  669. if (m_mode == Mode::Default || m_mode == Mode::Float) {
  670. base = 10;
  671. upper_case = false;
  672. } else if (m_mode == Mode::Hexfloat) {
  673. base = 16;
  674. upper_case = false;
  675. } else if (m_mode == Mode::HexfloatUppercase) {
  676. base = 16;
  677. upper_case = true;
  678. } else {
  679. VERIFY_NOT_REACHED();
  680. }
  681. m_width = m_width.value_or(0);
  682. m_precision = m_precision.value_or(6);
  683. return builder.put_f80(value, base, upper_case, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode);
  684. }
  685. ErrorOr<void> Formatter<double>::format(FormatBuilder& builder, double value)
  686. {
  687. u8 base;
  688. bool upper_case;
  689. if (m_mode == Mode::Default || m_mode == Mode::Float) {
  690. base = 10;
  691. upper_case = false;
  692. } else if (m_mode == Mode::Hexfloat) {
  693. base = 16;
  694. upper_case = false;
  695. } else if (m_mode == Mode::HexfloatUppercase) {
  696. base = 16;
  697. upper_case = true;
  698. } else {
  699. VERIFY_NOT_REACHED();
  700. }
  701. m_width = m_width.value_or(0);
  702. m_precision = m_precision.value_or(6);
  703. return builder.put_f64(value, base, upper_case, m_zero_pad, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode);
  704. }
  705. ErrorOr<void> Formatter<float>::format(FormatBuilder& builder, float value)
  706. {
  707. Formatter<double> formatter { *this };
  708. return formatter.format(builder, value);
  709. }
  710. #endif
  711. #ifndef KERNEL
  712. void vout(FILE* file, StringView fmtstr, TypeErasedFormatParams& params, bool newline)
  713. {
  714. StringBuilder builder;
  715. MUST(vformat(builder, fmtstr, params));
  716. if (newline)
  717. builder.append('\n');
  718. auto const string = builder.string_view();
  719. auto const retval = ::fwrite(string.characters_without_null_termination(), 1, string.length(), file);
  720. if (static_cast<size_t>(retval) != string.length()) {
  721. auto error = ferror(file);
  722. dbgln("vout() failed ({} written out of {}), error was {} ({})", retval, string.length(), error, strerror(error));
  723. }
  724. }
  725. #endif
  726. static bool is_debug_enabled = true;
  727. void set_debug_enabled(bool value)
  728. {
  729. is_debug_enabled = value;
  730. }
  731. void vdbgln(StringView fmtstr, TypeErasedFormatParams& params)
  732. {
  733. if (!is_debug_enabled)
  734. return;
  735. StringBuilder builder;
  736. #ifdef AK_OS_SERENITY
  737. # ifdef KERNEL
  738. if (Kernel::Processor::is_initialized()) {
  739. struct timespec ts = {};
  740. if (TimeManagement::is_initialized())
  741. ts = TimeManagement::the().monotonic_time(TimePrecision::Coarse).to_timespec();
  742. if (Kernel::Thread::current()) {
  743. auto& thread = *Kernel::Thread::current();
  744. builder.appendff("{}.{:03} \033[34;1m[#{} {}({}:{})]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, Kernel::Processor::current_id(), thread.process().name(), thread.pid().value(), thread.tid().value());
  745. } else {
  746. builder.appendff("{}.{:03} \033[34;1m[#{} Kernel]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, Kernel::Processor::current_id());
  747. }
  748. } else {
  749. builder.appendff("\033[34;1m[Kernel]\033[0m: ");
  750. }
  751. # else
  752. static TriState got_process_name = TriState::Unknown;
  753. static char process_name_buffer[256];
  754. if (got_process_name == TriState::Unknown) {
  755. if (get_process_name(process_name_buffer, sizeof(process_name_buffer)) == 0)
  756. got_process_name = TriState::True;
  757. else
  758. got_process_name = TriState::False;
  759. }
  760. struct timespec ts;
  761. clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
  762. if (got_process_name == TriState::True)
  763. builder.appendff("{}.{:03} \033[33;1m{}({}:{})\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, process_name_buffer, getpid(), gettid());
  764. # endif
  765. #endif
  766. MUST(vformat(builder, fmtstr, params));
  767. builder.append('\n');
  768. auto const string = builder.string_view();
  769. #ifdef AK_OS_SERENITY
  770. # ifdef KERNEL
  771. if (!Kernel::Processor::is_initialized()) {
  772. kernelearlyputstr(string.characters_without_null_termination(), string.length());
  773. return;
  774. }
  775. # endif
  776. #endif
  777. dbgputstr(string.characters_without_null_termination(), string.length());
  778. }
  779. #ifdef KERNEL
  780. void vdmesgln(StringView fmtstr, TypeErasedFormatParams& params)
  781. {
  782. StringBuilder builder;
  783. # ifdef AK_OS_SERENITY
  784. struct timespec ts = {};
  785. if (TimeManagement::is_initialized())
  786. ts = TimeManagement::the().monotonic_time(TimePrecision::Coarse).to_timespec();
  787. if (Kernel::Processor::is_initialized() && Kernel::Thread::current()) {
  788. auto& thread = *Kernel::Thread::current();
  789. builder.appendff("{}.{:03} \033[34;1m[{}({}:{})]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, thread.process().name(), thread.pid().value(), thread.tid().value());
  790. } else {
  791. builder.appendff("{}.{:03} \033[34;1m[Kernel]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000);
  792. }
  793. # endif
  794. MUST(vformat(builder, fmtstr, params));
  795. builder.append('\n');
  796. auto const string = builder.string_view();
  797. kernelputstr(string.characters_without_null_termination(), string.length());
  798. }
  799. void v_critical_dmesgln(StringView fmtstr, TypeErasedFormatParams& params)
  800. {
  801. // FIXME: Try to avoid memory allocations further to prevent faulting
  802. // at OOM conditions.
  803. StringBuilder builder;
  804. # ifdef AK_OS_SERENITY
  805. if (Kernel::Processor::is_initialized() && Kernel::Thread::current()) {
  806. auto& thread = *Kernel::Thread::current();
  807. builder.appendff("[{}({}:{})]: ", thread.process().name(), thread.pid().value(), thread.tid().value());
  808. } else {
  809. builder.appendff("[Kernel]: ");
  810. }
  811. # endif
  812. MUST(vformat(builder, fmtstr, params));
  813. builder.append('\n');
  814. auto const string = builder.string_view();
  815. kernelcriticalputstr(string.characters_without_null_termination(), string.length());
  816. }
  817. #endif
  818. template struct Formatter<unsigned char, void>;
  819. template struct Formatter<unsigned short, void>;
  820. template struct Formatter<unsigned int, void>;
  821. template struct Formatter<unsigned long, void>;
  822. template struct Formatter<unsigned long long, void>;
  823. template struct Formatter<short, void>;
  824. template struct Formatter<int, void>;
  825. template struct Formatter<long, void>;
  826. template struct Formatter<long long, void>;
  827. template struct Formatter<signed char, void>;
  828. } // namespace AK