1 | #include "taichi/util/str.h" |
2 | |
3 | #include <sstream> |
4 | |
5 | #include "taichi/inc/constants.h" |
6 | |
7 | namespace taichi::lang { |
8 | |
9 | std::string c_quoted(std::string const &str) { |
10 | // https://zh.cppreference.com/w/cpp/language/escape |
11 | std::stringstream ss; |
12 | ss << '"'; |
13 | for (auto const &c : str) { |
14 | switch (c) { |
15 | #define REG_ESC(x, y) \ |
16 | case x: \ |
17 | ss << "\\" y; \ |
18 | break; |
19 | REG_ESC('\n', "n" ); |
20 | REG_ESC('\a', "a" ); |
21 | REG_ESC('\b', "b" ); |
22 | REG_ESC('\v', "v" ); |
23 | REG_ESC('\t', "t" ); |
24 | REG_ESC('\f', "f" ); |
25 | REG_ESC('\'', "'" ); |
26 | REG_ESC('\"', "\"" ); |
27 | REG_ESC('\\', "\\" ); |
28 | default: |
29 | ss << c; |
30 | } |
31 | } |
32 | #undef REG_ESC |
33 | ss << '"'; |
34 | return ss.str(); |
35 | } |
36 | |
37 | std::string format_error_message(const std::string &error_message_template, |
38 | const std::function<uint64(int)> &fetcher) { |
39 | std::string error_message_formatted; |
40 | int argument_id = 0; |
41 | for (int i = 0; i < (int)error_message_template.size(); i++) { |
42 | if (error_message_template[i] != '%') { |
43 | error_message_formatted += error_message_template[i]; |
44 | } else { |
45 | const auto dtype = error_message_template[i + 1]; |
46 | const auto argument = fetcher(argument_id); |
47 | if (dtype == 'd') { |
48 | error_message_formatted += fmt::format( |
49 | "{}" , taichi_union_cast_with_different_sizes<int32>(argument)); |
50 | } else if (dtype == 'f') { |
51 | error_message_formatted += fmt::format( |
52 | "{}" , taichi_union_cast_with_different_sizes<float32>(argument)); |
53 | } else { |
54 | TI_ERROR("Data type identifier %{} is not supported" , dtype); |
55 | } |
56 | argument_id += 1; |
57 | i++; // skip the dtype char |
58 | } |
59 | } |
60 | return error_message_formatted; |
61 | } |
62 | |
63 | } // namespace taichi::lang |
64 | |