Format.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  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/String.h>
  10. #include <AK/StringBuilder.h>
  11. #include <AK/kstdio.h>
  12. #if defined(__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 const char* lowercase_lookup = "0123456789abcdef";
  44. constexpr const char* 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. const auto 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. const auto 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("{}")))
  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. const auto 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 = "";
  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. const auto used_by_string = min(max_width, value.length());
  171. const auto 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. const auto used_by_left_padding = used_by_padding / 2;
  179. const auto 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. const auto 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. const auto used_by_field = used_by_prefix + used_by_digits;
  223. const auto used_by_padding = max(used_by_field, min_width) - used_by_field;
  224. const auto 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"));
  235. else
  236. TRY(m_builder.try_append("0b"));
  237. } else if (base == 8) {
  238. TRY(m_builder.try_append("0"));
  239. } else if (base == 16) {
  240. if (upper_case)
  241. TRY(m_builder.try_append("0X"));
  242. else
  243. TRY(m_builder.try_append("0x"));
  244. }
  245. }
  246. return {};
  247. };
  248. const auto 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. const auto 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. const auto used_by_left_padding = used_by_padding / 2;
  260. const auto 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. const auto 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. const auto 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. #ifndef KERNEL
  296. ErrorOr<void> FormatBuilder::put_f64(
  297. double value,
  298. u8 base,
  299. bool upper_case,
  300. bool zero_pad,
  301. Align align,
  302. size_t min_width,
  303. size_t precision,
  304. char fill,
  305. SignMode sign_mode)
  306. {
  307. StringBuilder string_builder;
  308. FormatBuilder format_builder { string_builder };
  309. if (isnan(value) || isinf(value)) [[unlikely]] {
  310. if (value < 0.0)
  311. TRY(string_builder.try_append('-'));
  312. else if (sign_mode == SignMode::Always)
  313. TRY(string_builder.try_append('+'));
  314. else if (sign_mode == SignMode::Reserved)
  315. TRY(string_builder.try_append(' '));
  316. if (isnan(value))
  317. TRY(string_builder.try_append(upper_case ? "NAN"sv : "nan"sv));
  318. else
  319. TRY(string_builder.try_append(upper_case ? "INF"sv : "inf"sv));
  320. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  321. return {};
  322. }
  323. bool is_negative = value < 0.0;
  324. if (is_negative)
  325. value = -value;
  326. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode, is_negative));
  327. if (precision > 0) {
  328. // FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good
  329. // place to start would be the following video from CppCon 2019:
  330. // https://youtu.be/4P_kbF0EbZM (Stephan T. Lavavej “Floating-Point <charconv>: Making Your Code 10x Faster With C++17's Final Boss”)
  331. value -= static_cast<i64>(value);
  332. double epsilon = 0.5;
  333. for (size_t i = 0; i < precision; ++i)
  334. epsilon /= 10.0;
  335. size_t visible_precision = 0;
  336. for (; visible_precision < precision; ++visible_precision) {
  337. if (value - static_cast<i64>(value) < epsilon)
  338. break;
  339. value *= 10.0;
  340. epsilon *= 10.0;
  341. }
  342. if (zero_pad || visible_precision > 0)
  343. TRY(string_builder.try_append('.'));
  344. if (visible_precision > 0)
  345. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, true, Align::Right, visible_precision));
  346. if (zero_pad && (precision - visible_precision) > 0)
  347. TRY(format_builder.put_u64(0, base, false, false, true, Align::Right, precision - visible_precision));
  348. }
  349. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  350. return {};
  351. }
  352. ErrorOr<void> FormatBuilder::put_f80(
  353. long double value,
  354. u8 base,
  355. bool upper_case,
  356. Align align,
  357. size_t min_width,
  358. size_t precision,
  359. char fill,
  360. SignMode sign_mode)
  361. {
  362. StringBuilder string_builder;
  363. FormatBuilder format_builder { string_builder };
  364. if (isnan(value) || isinf(value)) [[unlikely]] {
  365. if (value < 0.0l)
  366. TRY(string_builder.try_append('-'));
  367. else if (sign_mode == SignMode::Always)
  368. TRY(string_builder.try_append('+'));
  369. else if (sign_mode == SignMode::Reserved)
  370. TRY(string_builder.try_append(' '));
  371. if (isnan(value))
  372. TRY(string_builder.try_append(upper_case ? "NAN"sv : "nan"sv));
  373. else
  374. TRY(string_builder.try_append(upper_case ? "INF"sv : "inf"sv));
  375. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  376. return {};
  377. }
  378. bool is_negative = value < 0.0l;
  379. if (is_negative)
  380. value = -value;
  381. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, false, Align::Right, 0, ' ', sign_mode, is_negative));
  382. if (precision > 0) {
  383. // FIXME: This is a terrible approximation but doing it properly would be a lot of work. If someone is up for that, a good
  384. // place to start would be the following video from CppCon 2019:
  385. // https://youtu.be/4P_kbF0EbZM (Stephan T. Lavavej “Floating-Point <charconv>: Making Your Code 10x Faster With C++17's Final Boss”)
  386. value -= static_cast<i64>(value);
  387. long double epsilon = 0.5l;
  388. for (size_t i = 0; i < precision; ++i)
  389. epsilon /= 10.0l;
  390. size_t visible_precision = 0;
  391. for (; visible_precision < precision; ++visible_precision) {
  392. if (value - static_cast<i64>(value) < epsilon)
  393. break;
  394. value *= 10.0l;
  395. epsilon *= 10.0l;
  396. }
  397. if (visible_precision > 0) {
  398. string_builder.append('.');
  399. TRY(format_builder.put_u64(static_cast<u64>(value), base, false, upper_case, true, Align::Right, visible_precision));
  400. }
  401. }
  402. TRY(put_string(string_builder.string_view(), align, min_width, NumericLimits<size_t>::max(), fill));
  403. return {};
  404. }
  405. #endif
  406. ErrorOr<void> FormatBuilder::put_hexdump(ReadonlyBytes bytes, size_t width, char fill)
  407. {
  408. auto put_char_view = [&](auto i) -> ErrorOr<void> {
  409. TRY(put_padding(fill, 4));
  410. for (size_t j = i - width; j < i; ++j) {
  411. auto ch = bytes[j];
  412. TRY(m_builder.try_append(ch >= 32 && ch <= 127 ? ch : '.')); // silly hack
  413. }
  414. return {};
  415. };
  416. for (size_t i = 0; i < bytes.size(); ++i) {
  417. if (width > 0) {
  418. if (i % width == 0 && i) {
  419. TRY(put_char_view(i));
  420. TRY(put_literal("\n"sv));
  421. }
  422. }
  423. TRY(put_u64(bytes[i], 16, false, false, true, Align::Right, 2));
  424. }
  425. if (width > 0 && bytes.size() && bytes.size() % width == 0)
  426. TRY(put_char_view(bytes.size()));
  427. return {};
  428. }
  429. ErrorOr<void> vformat(StringBuilder& builder, StringView fmtstr, TypeErasedFormatParams& params)
  430. {
  431. FormatBuilder fmtbuilder { builder };
  432. FormatParser parser { fmtstr };
  433. TRY(vformat_impl(params, fmtbuilder, parser));
  434. return {};
  435. }
  436. void StandardFormatter::parse(TypeErasedFormatParams& params, FormatParser& parser)
  437. {
  438. if (StringView { "<^>" }.contains(parser.peek(1))) {
  439. VERIFY(!parser.next_is(is_any_of("{}")));
  440. m_fill = parser.consume();
  441. }
  442. if (parser.consume_specific('<'))
  443. m_align = FormatBuilder::Align::Left;
  444. else if (parser.consume_specific('^'))
  445. m_align = FormatBuilder::Align::Center;
  446. else if (parser.consume_specific('>'))
  447. m_align = FormatBuilder::Align::Right;
  448. if (parser.consume_specific('-'))
  449. m_sign_mode = FormatBuilder::SignMode::OnlyIfNeeded;
  450. else if (parser.consume_specific('+'))
  451. m_sign_mode = FormatBuilder::SignMode::Always;
  452. else if (parser.consume_specific(' '))
  453. m_sign_mode = FormatBuilder::SignMode::Reserved;
  454. if (parser.consume_specific('#'))
  455. m_alternative_form = true;
  456. if (parser.consume_specific('0'))
  457. m_zero_pad = true;
  458. if (size_t index = 0; parser.consume_replacement_field(index)) {
  459. if (index == use_next_index)
  460. index = params.take_next_index();
  461. m_width = params.parameters().at(index).to_size();
  462. } else if (size_t width = 0; parser.consume_number(width)) {
  463. m_width = width;
  464. }
  465. if (parser.consume_specific('.')) {
  466. if (size_t index = 0; parser.consume_replacement_field(index)) {
  467. if (index == use_next_index)
  468. index = params.take_next_index();
  469. m_precision = params.parameters().at(index).to_size();
  470. } else if (size_t precision = 0; parser.consume_number(precision)) {
  471. m_precision = precision;
  472. }
  473. }
  474. if (parser.consume_specific('b'))
  475. m_mode = Mode::Binary;
  476. else if (parser.consume_specific('B'))
  477. m_mode = Mode::BinaryUppercase;
  478. else if (parser.consume_specific('d'))
  479. m_mode = Mode::Decimal;
  480. else if (parser.consume_specific('o'))
  481. m_mode = Mode::Octal;
  482. else if (parser.consume_specific('x'))
  483. m_mode = Mode::Hexadecimal;
  484. else if (parser.consume_specific('X'))
  485. m_mode = Mode::HexadecimalUppercase;
  486. else if (parser.consume_specific('c'))
  487. m_mode = Mode::Character;
  488. else if (parser.consume_specific('s'))
  489. m_mode = Mode::String;
  490. else if (parser.consume_specific('p'))
  491. m_mode = Mode::Pointer;
  492. else if (parser.consume_specific('f'))
  493. m_mode = Mode::Float;
  494. else if (parser.consume_specific('a'))
  495. m_mode = Mode::Hexfloat;
  496. else if (parser.consume_specific('A'))
  497. m_mode = Mode::HexfloatUppercase;
  498. else if (parser.consume_specific("hex-dump"))
  499. m_mode = Mode::HexDump;
  500. if (!parser.is_eof())
  501. dbgln("{} did not consume '{}'", __PRETTY_FUNCTION__, parser.remaining());
  502. VERIFY(parser.is_eof());
  503. }
  504. ErrorOr<void> Formatter<StringView>::format(FormatBuilder& builder, StringView value)
  505. {
  506. if (m_sign_mode != FormatBuilder::SignMode::Default)
  507. VERIFY_NOT_REACHED();
  508. if (m_alternative_form)
  509. VERIFY_NOT_REACHED();
  510. if (m_zero_pad)
  511. VERIFY_NOT_REACHED();
  512. if (m_mode != Mode::Default && m_mode != Mode::String && m_mode != Mode::Character && m_mode != Mode::HexDump)
  513. VERIFY_NOT_REACHED();
  514. m_width = m_width.value_or(0);
  515. m_precision = m_precision.value_or(NumericLimits<size_t>::max());
  516. if (m_mode == Mode::HexDump)
  517. return builder.put_hexdump(value.bytes(), m_width.value(), m_fill);
  518. return builder.put_string(value, m_align, m_width.value(), m_precision.value(), m_fill);
  519. }
  520. ErrorOr<void> Formatter<FormatString>::vformat(FormatBuilder& builder, StringView fmtstr, TypeErasedFormatParams& params)
  521. {
  522. StringBuilder string_builder;
  523. TRY(AK::vformat(string_builder, fmtstr, params));
  524. TRY(Formatter<StringView>::format(builder, string_builder.string_view()));
  525. return {};
  526. }
  527. template<typename T>
  528. ErrorOr<void> Formatter<T, typename EnableIf<IsIntegral<T>>::Type>::format(FormatBuilder& builder, T value)
  529. {
  530. if (m_mode == Mode::Character) {
  531. // FIXME: We just support ASCII for now, in the future maybe unicode?
  532. VERIFY(value >= 0 && value <= 127);
  533. m_mode = Mode::String;
  534. Formatter<StringView> formatter { *this };
  535. return formatter.format(builder, StringView { reinterpret_cast<const char*>(&value), 1 });
  536. }
  537. if (m_precision.has_value())
  538. VERIFY_NOT_REACHED();
  539. if (m_mode == Mode::Pointer) {
  540. if (m_sign_mode != FormatBuilder::SignMode::Default)
  541. VERIFY_NOT_REACHED();
  542. if (m_align != FormatBuilder::Align::Default)
  543. VERIFY_NOT_REACHED();
  544. if (m_alternative_form)
  545. VERIFY_NOT_REACHED();
  546. if (m_width.has_value())
  547. VERIFY_NOT_REACHED();
  548. m_mode = Mode::Hexadecimal;
  549. m_alternative_form = true;
  550. m_width = 2 * sizeof(void*);
  551. m_zero_pad = true;
  552. }
  553. u8 base = 0;
  554. bool upper_case = false;
  555. if (m_mode == Mode::Binary) {
  556. base = 2;
  557. } else if (m_mode == Mode::BinaryUppercase) {
  558. base = 2;
  559. upper_case = true;
  560. } else if (m_mode == Mode::Octal) {
  561. base = 8;
  562. } else if (m_mode == Mode::Decimal || m_mode == Mode::Default) {
  563. base = 10;
  564. } else if (m_mode == Mode::Hexadecimal) {
  565. base = 16;
  566. } else if (m_mode == Mode::HexadecimalUppercase) {
  567. base = 16;
  568. upper_case = true;
  569. } else if (m_mode == Mode::HexDump) {
  570. m_width = m_width.value_or(32);
  571. return builder.put_hexdump({ &value, sizeof(value) }, m_width.value(), m_fill);
  572. } else {
  573. VERIFY_NOT_REACHED();
  574. }
  575. m_width = m_width.value_or(0);
  576. if constexpr (IsSame<MakeUnsigned<T>, T>)
  577. return builder.put_u64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
  578. else
  579. return builder.put_i64(value, base, m_alternative_form, upper_case, m_zero_pad, m_align, m_width.value(), m_fill, m_sign_mode);
  580. }
  581. ErrorOr<void> Formatter<char>::format(FormatBuilder& builder, char value)
  582. {
  583. 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) {
  584. // Trick: signed char != char. (Sometimes weird features are actually helpful.)
  585. Formatter<signed char> formatter { *this };
  586. return formatter.format(builder, static_cast<signed char>(value));
  587. } else {
  588. Formatter<StringView> formatter { *this };
  589. return formatter.format(builder, { &value, 1 });
  590. }
  591. }
  592. ErrorOr<void> Formatter<wchar_t>::format(FormatBuilder& builder, wchar_t value)
  593. {
  594. 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) {
  595. Formatter<u32> formatter { *this };
  596. return formatter.format(builder, static_cast<u32>(value));
  597. } else {
  598. StringBuilder codepoint;
  599. codepoint.append_code_point(value);
  600. Formatter<StringView> formatter { *this };
  601. return formatter.format(builder, codepoint.to_string());
  602. }
  603. }
  604. ErrorOr<void> Formatter<bool>::format(FormatBuilder& builder, bool value)
  605. {
  606. 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) {
  607. Formatter<u8> formatter { *this };
  608. return formatter.format(builder, static_cast<u8>(value));
  609. } else if (m_mode == Mode::HexDump) {
  610. return builder.put_hexdump({ &value, sizeof(value) }, m_width.value_or(32), m_fill);
  611. } else {
  612. Formatter<StringView> formatter { *this };
  613. return formatter.format(builder, value ? "true" : "false");
  614. }
  615. }
  616. #ifndef KERNEL
  617. ErrorOr<void> Formatter<long double>::format(FormatBuilder& builder, long double value)
  618. {
  619. u8 base;
  620. bool upper_case;
  621. if (m_mode == Mode::Default || m_mode == Mode::Float) {
  622. base = 10;
  623. upper_case = false;
  624. } else if (m_mode == Mode::Hexfloat) {
  625. base = 16;
  626. upper_case = false;
  627. } else if (m_mode == Mode::HexfloatUppercase) {
  628. base = 16;
  629. upper_case = true;
  630. } else {
  631. VERIFY_NOT_REACHED();
  632. }
  633. m_width = m_width.value_or(0);
  634. m_precision = m_precision.value_or(6);
  635. return builder.put_f80(value, base, upper_case, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode);
  636. }
  637. ErrorOr<void> Formatter<double>::format(FormatBuilder& builder, double value)
  638. {
  639. u8 base;
  640. bool upper_case;
  641. if (m_mode == Mode::Default || m_mode == Mode::Float) {
  642. base = 10;
  643. upper_case = false;
  644. } else if (m_mode == Mode::Hexfloat) {
  645. base = 16;
  646. upper_case = false;
  647. } else if (m_mode == Mode::HexfloatUppercase) {
  648. base = 16;
  649. upper_case = true;
  650. } else {
  651. VERIFY_NOT_REACHED();
  652. }
  653. m_width = m_width.value_or(0);
  654. m_precision = m_precision.value_or(6);
  655. return builder.put_f64(value, base, upper_case, m_zero_pad, m_align, m_width.value(), m_precision.value(), m_fill, m_sign_mode);
  656. }
  657. ErrorOr<void> Formatter<float>::format(FormatBuilder& builder, float value)
  658. {
  659. Formatter<double> formatter { *this };
  660. return formatter.format(builder, value);
  661. }
  662. #endif
  663. #ifndef KERNEL
  664. void vout(FILE* file, StringView fmtstr, TypeErasedFormatParams& params, bool newline)
  665. {
  666. StringBuilder builder;
  667. MUST(vformat(builder, fmtstr, params));
  668. if (newline)
  669. builder.append('\n');
  670. const auto string = builder.string_view();
  671. const auto retval = ::fwrite(string.characters_without_null_termination(), 1, string.length(), file);
  672. if (static_cast<size_t>(retval) != string.length()) {
  673. auto error = ferror(file);
  674. dbgln("vout() failed ({} written out of {}), error was {} ({})", retval, string.length(), error, strerror(error));
  675. }
  676. }
  677. #endif
  678. static bool is_debug_enabled = true;
  679. void set_debug_enabled(bool value)
  680. {
  681. is_debug_enabled = value;
  682. }
  683. void vdbgln(StringView fmtstr, TypeErasedFormatParams& params)
  684. {
  685. if (!is_debug_enabled)
  686. return;
  687. StringBuilder builder;
  688. #ifdef __serenity__
  689. # ifdef KERNEL
  690. if (Kernel::Processor::is_initialized()) {
  691. struct timespec ts = {};
  692. if (TimeManagement::is_initialized())
  693. ts = TimeManagement::the().monotonic_time(TimePrecision::Coarse).to_timespec();
  694. if (Kernel::Thread::current()) {
  695. auto& thread = *Kernel::Thread::current();
  696. 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());
  697. } else {
  698. builder.appendff("{}.{:03} \033[34;1m[#{} Kernel]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, Kernel::Processor::current_id());
  699. }
  700. } else {
  701. builder.appendff("\033[34;1m[Kernel]\033[0m: ");
  702. }
  703. # else
  704. static TriState got_process_name = TriState::Unknown;
  705. static char process_name_buffer[256];
  706. if (got_process_name == TriState::Unknown) {
  707. if (get_process_name(process_name_buffer, sizeof(process_name_buffer)) == 0)
  708. got_process_name = TriState::True;
  709. else
  710. got_process_name = TriState::False;
  711. }
  712. struct timespec ts;
  713. clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
  714. if (got_process_name == TriState::True)
  715. builder.appendff("{}.{:03} \033[33;1m{}({}:{})\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, process_name_buffer, getpid(), gettid());
  716. # endif
  717. #endif
  718. MUST(vformat(builder, fmtstr, params));
  719. builder.append('\n');
  720. const auto string = builder.string_view();
  721. #ifdef __serenity__
  722. # ifdef KERNEL
  723. if (!Kernel::Processor::is_initialized()) {
  724. kernelearlyputstr(string.characters_without_null_termination(), string.length());
  725. return;
  726. }
  727. # endif
  728. #endif
  729. dbgputstr(string.characters_without_null_termination(), string.length());
  730. }
  731. #ifdef KERNEL
  732. void vdmesgln(StringView fmtstr, TypeErasedFormatParams& params)
  733. {
  734. StringBuilder builder;
  735. # ifdef __serenity__
  736. struct timespec ts = {};
  737. # if !ARCH(AARCH64)
  738. if (TimeManagement::is_initialized())
  739. ts = TimeManagement::the().monotonic_time(TimePrecision::Coarse).to_timespec();
  740. # endif
  741. if (Kernel::Processor::is_initialized() && Kernel::Thread::current()) {
  742. auto& thread = *Kernel::Thread::current();
  743. builder.appendff("{}.{:03} \033[34;1m[{}({}:{})]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000, thread.process().name(), thread.pid().value(), thread.tid().value());
  744. } else {
  745. builder.appendff("{}.{:03} \033[34;1m[Kernel]\033[0m: ", ts.tv_sec, ts.tv_nsec / 1000000);
  746. }
  747. # endif
  748. MUST(vformat(builder, fmtstr, params));
  749. builder.append('\n');
  750. const auto string = builder.string_view();
  751. kernelputstr(string.characters_without_null_termination(), string.length());
  752. }
  753. void v_critical_dmesgln(StringView fmtstr, TypeErasedFormatParams& params)
  754. {
  755. // FIXME: Try to avoid memory allocations further to prevent faulting
  756. // at OOM conditions.
  757. StringBuilder builder;
  758. # ifdef __serenity__
  759. if (Kernel::Processor::is_initialized() && Kernel::Thread::current()) {
  760. auto& thread = *Kernel::Thread::current();
  761. builder.appendff("[{}({}:{})]: ", thread.process().name(), thread.pid().value(), thread.tid().value());
  762. } else {
  763. builder.appendff("[Kernel]: ");
  764. }
  765. # endif
  766. MUST(vformat(builder, fmtstr, params));
  767. builder.append('\n');
  768. const auto string = builder.string_view();
  769. kernelcriticalputstr(string.characters_without_null_termination(), string.length());
  770. }
  771. #endif
  772. template struct Formatter<unsigned char, void>;
  773. template struct Formatter<unsigned short, void>;
  774. template struct Formatter<unsigned int, void>;
  775. template struct Formatter<unsigned long, void>;
  776. template struct Formatter<unsigned long long, void>;
  777. template struct Formatter<short, void>;
  778. template struct Formatter<int, void>;
  779. template struct Formatter<long, void>;
  780. template struct Formatter<long long, void>;
  781. template struct Formatter<signed char, void>;
  782. } // namespace AK