Format.cpp 26 KB

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