github.com/kidsbmilk/gofronted_all@v0.0.0-20220701224323-6479d5976c5d/go/go-diagnostics.cc (about) 1 // go-diagnostics.cc -- Go error/warning diagnostics utilities. 2 3 // Copyright 2016 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 #include "go-diagnostics.h" 8 9 static std::string 10 mformat_value() 11 { 12 return std::string(xstrerror(errno)); 13 } 14 15 // Rewrite a format string to expand any extensions not 16 // supported by sprintf(). See comments in go-diagnostics.h 17 // for list of supported format specifiers. 18 19 static std::string 20 expand_format(const char* fmt) 21 { 22 std::stringstream ss; 23 for (const char* c = fmt; *c; ++c) 24 { 25 if (*c != '%') 26 { 27 ss << *c; 28 continue; 29 } 30 c++; 31 switch (*c) 32 { 33 case '\0': 34 { 35 // malformed format string 36 go_unreachable(); 37 } 38 case '%': 39 { 40 ss << "%"; 41 break; 42 } 43 case 'm': 44 { 45 ss << mformat_value(); 46 break; 47 } 48 case '<': 49 { 50 ss << go_open_quote(); 51 break; 52 } 53 case '>': 54 { 55 ss << go_close_quote(); 56 break; 57 } 58 case 'q': 59 { 60 ss << go_open_quote(); 61 c++; 62 if (*c == 'm') 63 { 64 ss << mformat_value(); 65 } 66 else 67 { 68 ss << "%" << *c; 69 } 70 ss << go_close_quote(); 71 break; 72 } 73 default: 74 { 75 ss << "%" << *c; 76 } 77 } 78 } 79 return ss.str(); 80 } 81 82 // Expand message format specifiers, using a combination of 83 // expand_format above to handle extensions (ex: %m, %q) and vasprintf() 84 // to handle regular printf-style formatting. A pragma is being used here to 85 // suppress this warning: 86 // 87 // warning: function ‘std::__cxx11::string expand_message(const char*, __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format] 88 // 89 // What appears to be happening here is that the checker is deciding that 90 // because of the call to vasprintf() (which has attribute gnu_printf), the 91 // calling function must need to have attribute gnu_printf as well, even 92 // though there is already an attribute declaration for it. 93 94 static std::string 95 expand_message(const char* fmt, va_list ap) GO_ATTRIBUTE_GCC_DIAG(1,0); 96 97 #pragma GCC diagnostic push 98 #pragma GCC diagnostic ignored "-Wsuggest-attribute=format" 99 100 static std::string 101 expand_message(const char* fmt, va_list ap) 102 { 103 char* mbuf = 0; 104 std::string expanded_fmt = expand_format(fmt); 105 int nwr = vasprintf(&mbuf, expanded_fmt.c_str(), ap); 106 if (nwr == -1) 107 { 108 // memory allocation failed 109 go_be_error_at(Linemap::unknown_location(), 110 "memory allocation failed in vasprintf"); 111 go_assert(0); 112 } 113 std::string rval = std::string(mbuf); 114 free(mbuf); 115 return rval; 116 } 117 118 #pragma GCC diagnostic pop 119 120 static const char* cached_open_quote = NULL; 121 static const char* cached_close_quote = NULL; 122 123 const char* 124 go_open_quote() 125 { 126 if (cached_open_quote == NULL) 127 go_be_get_quotechars(&cached_open_quote, &cached_close_quote); 128 return cached_open_quote; 129 } 130 131 const char* 132 go_close_quote() 133 { 134 if (cached_close_quote == NULL) 135 go_be_get_quotechars(&cached_open_quote, &cached_close_quote); 136 return cached_close_quote; 137 } 138 139 void 140 go_error_at(const Location location, const char* fmt, ...) 141 { 142 va_list ap; 143 144 va_start(ap, fmt); 145 go_be_error_at(location, expand_message(fmt, ap)); 146 va_end(ap); 147 } 148 149 void 150 go_warning_at(const Location location, int opt, const char* fmt, ...) 151 { 152 va_list ap; 153 154 va_start(ap, fmt); 155 go_be_warning_at(location, opt, expand_message(fmt, ap)); 156 va_end(ap); 157 } 158 159 void 160 go_fatal_error(const Location location, const char* fmt, ...) 161 { 162 va_list ap; 163 164 va_start(ap, fmt); 165 go_be_fatal_error(location, expand_message(fmt, ap)); 166 va_end(ap); 167 } 168 169 void 170 go_inform(const Location location, const char* fmt, ...) 171 { 172 va_list ap; 173 174 va_start(ap, fmt); 175 go_be_inform(location, expand_message(fmt, ap)); 176 va_end(ap); 177 } 178 179 // go_debug uses normal printf formatting, not GCC diagnostic formatting. 180 181 void 182 go_debug(const Location location, const char* fmt, ...) 183 { 184 va_list ap; 185 186 va_start(ap, fmt); 187 char* mbuf = NULL; 188 int nwr = vasprintf(&mbuf, fmt, ap); 189 va_end(ap); 190 if (nwr == -1) 191 { 192 go_be_error_at(Linemap::unknown_location(), 193 "memory allocation failed in vasprintf"); 194 go_assert(0); 195 } 196 std::string rval = std::string(mbuf); 197 free(mbuf); 198 go_be_inform(location, rval); 199 }