Format.cpp 25 KB

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