format_providers.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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::Diagnostics::BoolAsSelect>::format(
  8. const Carbon::Diagnostics::BoolAsSelect& wrapper, raw_ostream& out,
  9. StringRef style) -> void {
  10. if (style.empty()) {
  11. llvm::format_provider<bool>::format(wrapper.value, out, style);
  12. return;
  13. }
  14. auto sep = style.find('|');
  15. CARBON_CHECK(
  16. sep != llvm::StringRef::npos,
  17. "BoolAsSelect requires a `|` separating true and false results: `{0}`",
  18. style);
  19. CARBON_CHECK(style.find('|', sep + 1) == llvm::StringRef::npos,
  20. "BoolAsSelect only allows one `|`: `{0}`", style);
  21. if (wrapper.value) {
  22. out << style.take_front(sep);
  23. } else {
  24. out << style.drop_front(sep + 1);
  25. }
  26. }
  27. auto llvm::format_provider<Carbon::Diagnostics::IntAsSelect>::format(
  28. const Carbon::Diagnostics::IntAsSelect& wrapper, raw_ostream& out,
  29. StringRef style) -> void {
  30. if (style == "s") {
  31. if (wrapper.value != 1) {
  32. out << "s";
  33. }
  34. return;
  35. } else if (style.empty()) {
  36. llvm::format_provider<int>::format(wrapper.value, out, style);
  37. return;
  38. }
  39. auto cursor = style;
  40. while (!cursor.empty()) {
  41. auto case_sep = cursor.find("|");
  42. auto token = cursor.substr(0, case_sep);
  43. if (case_sep == llvm::StringRef::npos) {
  44. cursor = llvm::StringRef();
  45. } else {
  46. cursor = cursor.drop_front(case_sep + 1);
  47. }
  48. auto pair_sep = token.find(':');
  49. CARBON_CHECK(pair_sep != llvm::StringRef::npos,
  50. "IntAsSelect requires a `:` separating each comparison and "
  51. "output string: `{0}`",
  52. style);
  53. auto comp = token.take_front(pair_sep);
  54. auto output_string = token.drop_front(pair_sep + 1);
  55. if (comp.empty()) {
  56. // Default case.
  57. CARBON_CHECK(cursor.empty(),
  58. "IntAsSelect requires the default case be last: `{0}`",
  59. style);
  60. out << output_string;
  61. return;
  62. } else if (comp.consume_front("=")) {
  63. // Equality comparison.
  64. int value;
  65. CARBON_CHECK(to_integer(comp, value),
  66. "IntAsSelect has invalid value in comparison: `{0}`", style);
  67. if (value == wrapper.value) {
  68. out << output_string;
  69. return;
  70. }
  71. } else {
  72. CARBON_FATAL("IntAsSelect has unrecognized comparison: `{0}`", style);
  73. }
  74. }
  75. CARBON_FATAL("IntAsSelect doesn't handle `{0}`: `{1}`", wrapper.value, style);
  76. }