format_providers.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/diagnostics/format_providers.h"
  5. #include "common/check.h"
  6. #include "llvm/ADT/StringExtras.h"
  7. auto llvm::format_provider<Carbon::BoolAsSelect>::format(
  8. const Carbon::BoolAsSelect& wrapper, raw_ostream& out, StringRef style)
  9. -> void {
  10. if (style.empty()) {
  11. llvm::format_provider<bool>::format(wrapper.value, out, style);
  12. return;
  13. }
  14. // Remove wrapping quotes if present.
  15. if (style.starts_with('\'') && style.ends_with('\'')) {
  16. style = style.drop_front().drop_back();
  17. }
  18. auto sep = style.find('|');
  19. CARBON_CHECK(
  20. sep != llvm::StringRef::npos,
  21. "BoolAsSelect requires a `|` separating true and false results: `{0}`",
  22. style);
  23. CARBON_CHECK(style.find('|', sep + 1) == llvm::StringRef::npos,
  24. "BoolAsSelect only allows one `|`: `{0}`", style);
  25. if (wrapper.value) {
  26. out << style.take_front(sep);
  27. } else {
  28. out << style.drop_front(sep + 1);
  29. }
  30. }
  31. auto llvm::format_provider<Carbon::IntAsSelect>::format(
  32. const Carbon::IntAsSelect& wrapper, raw_ostream& out, StringRef style)
  33. -> void {
  34. if (style == "s") {
  35. if (wrapper.value != 1) {
  36. out << "s";
  37. }
  38. return;
  39. } else if (style.empty()) {
  40. llvm::format_provider<int>::format(wrapper.value, out, style);
  41. return;
  42. }
  43. // Remove wrapping quotes if present.
  44. if (style.starts_with('\'') && style.ends_with('\'')) {
  45. style = style.drop_front().drop_back();
  46. }
  47. auto cursor = style;
  48. while (!cursor.empty()) {
  49. auto case_sep = cursor.find("|");
  50. auto token = cursor.substr(0, case_sep);
  51. if (case_sep == llvm::StringRef::npos) {
  52. cursor = llvm::StringRef();
  53. } else {
  54. cursor = cursor.drop_front(case_sep + 1);
  55. }
  56. auto pair_sep = token.find(':');
  57. CARBON_CHECK(pair_sep != llvm::StringRef::npos,
  58. "IntAsSelect requires a `:` separating each comparison and "
  59. "output string: `{0}`",
  60. style);
  61. auto comp = token.take_front(pair_sep);
  62. auto output_string = token.drop_front(pair_sep + 1);
  63. if (comp.empty()) {
  64. // Default case.
  65. CARBON_CHECK(cursor.empty(),
  66. "IntAsSelect requires the default case be last: `{0}`",
  67. style);
  68. out << output_string;
  69. return;
  70. } else if (comp.consume_front("=")) {
  71. // Equality comparison.
  72. int value;
  73. CARBON_CHECK(to_integer(comp, value),
  74. "IntAsSelect has invalid value in comparison: `{0}`", style);
  75. if (value == wrapper.value) {
  76. out << output_string;
  77. return;
  78. }
  79. } else {
  80. CARBON_FATAL("IntAsSelect has unrecognized comparison: `{0}`", style);
  81. }
  82. }
  83. CARBON_FATAL("IntAsSelect doesn't handle `{0}`: `{1}`", wrapper.value, style);
  84. }