rapidyaml 0.14.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
Error handling

Utilities to report handle errors, and to build and report error messages. More...

Classes

struct  c4::yml::Location
 holds a source or yaml file position, for example when an error is detected; See also location_format() and location_format_with_context(). More...
struct  c4::yml::ErrorDataBasic
 Data for a basic error. More...
struct  c4::yml::ErrorDataParse
 Data for a parse error. More...
struct  c4::yml::ErrorDataVisit
 Data for a visit error. More...
struct  c4::yml::ExceptionBasic
 Exception thrown by the default basic error implementation. More...
struct  c4::yml::ExceptionParse
 Exception thrown by the default parse error implementation. More...
struct  c4::yml::ExceptionVisit
 Exception thrown by the default visit error implementation. More...

Functions

template<class DumpFn>
size_t c4::yml::location_format (DumpFn &&dumpfn, Location const &loc)
 generic formatting of a location
template<class DumpFn>
void c4::yml::location_format_with_context (DumpFn &&dumpfn, Location const &location, csubstr source_buffer, csubstr call="", size_t num_lines_before=3, size_t num_lines_after=0, size_t first_col_highlight=0, size_t last_col_highlight=0, size_t maxlen=80u)
 Generic formatting of a location, printing the source code buffer region around the location.
template<class DumpFn>
void c4::yml::err_basic_format (DumpFn &&dumpfn, csubstr msg, ErrorDataBasic const &errdata)
 Given an error message and associated basic error data, format it fully as a basic error message.
void c4::yml::err_basic (Callbacks const &callbacks, ErrorDataBasic const &errdata, const char *msg_)
 trigger a basic error to its respective handler, with a non-formatted error message.
void c4::yml::err_basic (ErrorDataBasic const &errdata, const char *msg)
 trigger a basic error to its respective handler, with a non-formatted error message.
template<class ... Args>
void c4::yml::err_basic (Callbacks const &callbacks, ErrorDataBasic const &errdata, const char *fmt, Args const &...args)
 trigger a basic error to its respective handler, with a formatted error message.
template<class ... Args>
void c4::yml::err_basic (ErrorDataBasic const &errdata, const char *fmt, Args const &...args)
 trigger a basic error to its respective handler, with a formatted error message.
template<class DumpFn>
void c4::yml::err_parse_format (DumpFn &&dumpfn, csubstr msg, ErrorDataParse const &errdata)
 Given an error message and associated parse error data, format it fully as a parse error message.
void c4::yml::err_parse (Callbacks const &callbacks, ErrorDataParse const &errdata, const char *msg)
 trigger a parse error to its respective handler, with a non-formatted error message
void c4::yml::err_parse (ErrorDataParse const &errdata, const char *msg)
 trigger a parse error to its respective handler, with a non-formatted error message.
template<class ... Args>
void c4::yml::err_parse (Callbacks const &callbacks, ErrorDataParse const &errdata, const char *fmt, Args const &...args)
 trigger a parse error to its respective handler, with a formatted error message
template<class ... Args>
void c4::yml::err_parse (ErrorDataParse const &errdata, const char *fmt, Args const &...args)
 trigger a parse error to its respective handler, with a formatted error message.
template<class DumpFn>
void c4::yml::err_visit_format (DumpFn &&dumpfn, csubstr msg, ErrorDataVisit const &errdata)
 Given an error message and associated visit error data, format it fully as a visit error message.
void c4::yml::err_visit (Callbacks const &callbacks, ErrorDataVisit const &errdata, const char *msg)
 trigger a visit error to its respective handler, with a non-formatted error message
void c4::yml::err_visit (ErrorDataVisit const &errdata, const char *msg)
 trigger a visit error to its respective handler, with a non-formatted error message.
template<class ... Args>
void c4::yml::err_visit (Callbacks const &callbacks, ErrorDataVisit const &errdata, const char *fmt, Args const &...args)
 trigger a visit error to its respective handler, with a formatted error message
template<class ... Args>
void c4::yml::err_visit (ErrorDataVisit const &errdata, const char *fmt, Args const &...args)
 trigger a visit error to its respective handler, with a formatted error message.
template<class CharContainer>
void c4::yml::format_exc (CharContainer *out, ExceptionBasic const &exc)
 Format a basic exception to an existing char container.
template<class CharContainer>
void c4::yml::format_exc (CharContainer *out, ExceptionParse const &exc)
 Format a parse exception to an existing char container.
template<class CharContainer>
void c4::yml::format_exc (CharContainer *out, ExceptionVisit const &exc)
 Format a visit exception to an existing char container.
template<class CharContainer, class ExceptionT>
CharContainer c4::yml::format_exc (ExceptionT const &exc)
 Format a parse exception, and return a newly-created char container.

Detailed Description

Utilities to report handle errors, and to build and report error messages.

See also
sample::sample_error_handler

Function Documentation

◆ location_format()

template<class DumpFn>
size_t c4::yml::location_format ( DumpFn && dumpfn,
Location const & loc )

generic formatting of a location

Parameters
dumpfnfunction taking a csubstr and abstracting a string concatenation operation, such as appending to a std::string or printing to terminal.
locthe location to be formatted

For example:

/// to output to std::cerr:
std::cerr.write(s.str, s.len);
}, loc);
/// to build a string:
std::string msg;
msg.append(s.str, s.len);
}, loc);
size_t location_format(DumpFn &&dumpfn, Location const &loc)
generic formatting of a location
Definition error.def.hpp:18
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2357
size_t len
the length of the substring
Definition substr.hpp:218
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

Definition at line 18 of file error.def.hpp.

19{
20 if(!loc)
21 return 0;
22 char buf_[32];
23 substr buf(buf_);
24 size_t count = 0;
25 if(!loc.name.empty())
26 {
27 std::forward<DumpFn>(dumpfn)(loc.name);
28 std::forward<DumpFn>(dumpfn)(":");
29 count += loc.name.len + 1;
30 }
31 if(loc.line != npos)
32 {
33 csubstr val = detail::_to_chars_limited(buf, loc.line);
34 if(loc.name.empty())
35 {
36 std::forward<DumpFn>(dumpfn)("line=");
37 std::forward<DumpFn>(dumpfn)(val);
38 if(loc.col == npos)
39 {
40 std::forward<DumpFn>(dumpfn)(":");
41 ++count;
42 }
43 count += val.len + 5;
44 }
45 else
46 {
47 std::forward<DumpFn>(dumpfn)(val);
48 std::forward<DumpFn>(dumpfn)(":");
49 count += val.len + 1;
50 }
51 }
52 if(loc.col != npos)
53 {
54 csubstr val = detail::_to_chars_limited(buf, loc.col);
55 if(loc.line != npos || !loc.name.empty())
56 {
57 std::forward<DumpFn>(dumpfn)(" ");
58 ++count;
59 }
60 std::forward<DumpFn>(dumpfn)("col=");
61 std::forward<DumpFn>(dumpfn)(val);
62 count += val.len + 4;
63 if(loc.offset == npos)
64 {
65 std::forward<DumpFn>(dumpfn)(":");
66 ++count;
67 }
68 }
69 if(loc.offset != npos)
70 {
71 csubstr val = detail::_to_chars_limited(buf, loc.offset);
72 if(loc.line != npos || loc.col != npos || !loc.name.empty())
73 {
74 std::forward<DumpFn>(dumpfn)(" ");
75 ++count;
76 }
77 std::forward<DumpFn>(dumpfn)("(");
78 std::forward<DumpFn>(dumpfn)(val);
79 std::forward<DumpFn>(dumpfn)("B):");
80 count += val.len + 5;
81 }
82 return count;
83}
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2356
@ npos
a null string position
Definition common.hpp:263

◆ location_format_with_context()

template<class DumpFn>
void c4::yml::location_format_with_context ( DumpFn && dumpfn,
Location const & location,
csubstr source_buffer,
csubstr call = "",
size_t num_lines_before = 3,
size_t num_lines_after = 0,
size_t first_col_highlight = 0,
size_t last_col_highlight = 0,
size_t maxlen = 80u )

Generic formatting of a location, printing the source code buffer region around the location.

Parameters
dumpfnfunction taking a csubstr and abstracting a string concatenation operation, such as appending to a std::string or printing to terminal.
locationthe location
source_bufferthe source buffer
calla string with a call of attention to print in the message (see examples below)
num_lines_beforehow many source buffer lines to print before the location line
num_lines_afterhow many source buffer lines to print after the location line
first_col_highlightthe first column to highlight around the location line
last_col_highlightthe last column to highlight around the location line
maxlenthe maximum number of columns to show in the error message; source buffer lines will have at most this number of columns shown; if the line is longer than this, the line will be trimmed as needed at the end and/or beginning, and only the relevant columns around the location are shown

For example:

std::string out;
auto dumpfn = [&out](csubstr s){ out.append(s.str, s.len); };
format_location_with_context(dumpfn, location, source, "error");

will result in this string:

file.yaml:3: col=3 (11B): error:
error:
error: ccc
error: |
error: (here)
error:
error: see region:
error:
error: aaa
error: bbb
error: ccc
error: |
error: (here)

If an empty string is passed for the call of attention,

format_location_with_context(dumpfn, location, source);

the returned string becomes:

file.yaml:3: col=3 (11B): ccc
|
(here)
file.yaml:3: col=3 (11B): see region:
aaa
bbb
ccc
|
(here)

Definition at line 86 of file error.def.hpp.

95{
96 if(!location)
97 return;
98 char buf_[32];
99 substr buf(buf_);
100 auto pr = [&](csubstr s){ std::forward<DumpFn>(dumpfn)(s); };
101 auto prn = [&](csubstr s, size_t num_times){
102 for(size_t i = 0; i < num_times; ++i)
103 std::forward<DumpFn>(dumpfn)(s);
104 };
105 csubstr line = detail::_get_text_region(source_buffer, location.offset, 0, 0);
106 size_t target_col = location.col != npos ? location.col : (last_col_highlight > first_col_highlight ? first_col_highlight : npos);
107 size_t first_col_to_show = 0;
108 if(target_col != npos && target_col > maxlen)
109 first_col_to_show = target_col - maxlen + 1;
110 auto print_line_maybe_truncated = [&](csubstr contents){
111 if(contents.len <= maxlen)
112 {
113 if(first_col_to_show == 0)
114 {
115 pr(contents);
116 }
117 else if(first_col_to_show < contents.len)
118 {
119 csubstr show = contents.sub(first_col_to_show);
120 pr("[...]");
121 pr(show);
122 if(maxlen > show.len)
123 prn(" ", maxlen - show.len + 5);
124 pr(" (showing columns ");
125 pr(detail::_to_chars_limited(buf, first_col_to_show));
126 pr("-");
127 pr(detail::_to_chars_limited(buf, contents.len));
128 pr("/");
129 pr(detail::_to_chars_limited(buf, contents.len));
130 pr(")");
131 }
132 else
133 {
134 pr("[...]");
135 prn(" ", maxlen + 5);
136 pr(" (not showing, columns=");
137 pr(detail::_to_chars_limited(buf, contents.len));
138 pr(")");
139 }
140 }
141 else
142 {
143 if(first_col_to_show == 0)
144 {
145 csubstr show = contents.first(maxlen);
146 pr(show);
147 pr("[...] (showing columns 0-");
148 pr(detail::_to_chars_limited(buf, show.len));
149 pr("/");
150 pr(detail::_to_chars_limited(buf, contents.len));
151 pr(")");
152 }
153 else if(first_col_to_show < contents.len && first_col_to_show + maxlen <= contents.len)
154 {
155 csubstr show = contents.sub(first_col_to_show, maxlen);
156 pr("[...]");
157 pr(show);
158 pr("[...] (showing columns ");
159 pr(detail::_to_chars_limited(buf, first_col_to_show));
160 pr("-");
161 pr(detail::_to_chars_limited(buf, first_col_to_show + maxlen));
162 pr("/");
163 pr(detail::_to_chars_limited(buf, contents.len));
164 pr(")");
165 }
166 else if(first_col_to_show < contents.len)
167 {
168 csubstr show = contents.sub(first_col_to_show);
169 pr("[...]");
170 pr(show);
171 if(maxlen > show.len)
172 prn(" ", maxlen - show.len + 5);
173 pr(" (showing columns ");
174 pr(detail::_to_chars_limited(buf, first_col_to_show));
175 pr("-");
176 pr(detail::_to_chars_limited(buf, contents.len));
177 pr("/");
178 pr(detail::_to_chars_limited(buf, contents.len));
179 pr(")");
180 }
181 else
182 {
183 pr("[...]");
184 prn(" ", maxlen + 5);
185 pr(" (not showing, columns=");
186 pr(detail::_to_chars_limited(buf, contents.len));
187 pr(")");
188 }
189 }
190 };
191 // print the location, and compute how many cols it took
192 size_t locsize = location_format(pr, location);
193 // print line
194 if(locsize)
195 {
196 pr(" ");
197 //++locsize;
198 }
199 auto print_call = [&](csubstr after){
200 pr(call);
201 pr(":");
202 if(after.len)
203 pr(after);
204 };
205 size_t jump;
206 if(call.empty())
207 {
208 print_line_maybe_truncated(line);
209 pr("\n");
210 jump = locsize + location.col - first_col_to_show;
211 }
212 else
213 {
214 print_call("\n");
215 print_call("\n");
216 print_call(" ");
217 pr(" ");
218 print_line_maybe_truncated(line);
219 pr("\n");
220 jump = call.len + 2;
221 }
222 // when skipping to the first col, add 5 to adjust for the [...]
223 // leading the line as shown
224 const size_t first_col_jump = first_col_to_show == 0 ? 0 : 5;
225 // print a cursor pointing at the column on the previous printed line
226 auto print_cursor = [&](size_t nocall_jump){
227 if(location.offset == npos)
228 return;
229 if(call.empty())
230 {
231 if(nocall_jump != npos)
232 {
233 prn(" ", nocall_jump + first_col_jump);
234 pr("|\n");
235 prn(" ", nocall_jump + first_col_jump);
236 pr("(here)\n");
237 }
238 }
239 else if(location.col != npos)
240 {
241 print_call(" ");
242 pr(" ");
243 prn(" ", location.col - first_col_to_show + first_col_jump);
244 pr("|\n");
245 print_call(" ");
246 pr(" ");
247 prn(" ", location.col - first_col_to_show + first_col_jump);
248 pr("(here)\n");
249 }
250 };
251 // maybe highlighted zone
252 size_t firstcol = first_col_highlight < line.len ? first_col_highlight : line.len;
253 size_t lastcol = last_col_highlight < line.len ? last_col_highlight : line.len;
254 firstcol = firstcol < maxlen ? firstcol : maxlen;
255 lastcol = lastcol < maxlen ? lastcol : maxlen;
256 if(firstcol < lastcol)
257 {
258 if(!call.empty())
259 {
260 print_call(" ");
261 pr(" ");
262 }
263 else
264 {
265 for(size_t i = 0; i < locsize + firstcol; ++i)
266 pr(" ");
267 }
268 for(size_t i = locsize + firstcol; i < locsize + lastcol; ++i)
269 pr("~");
270 pr(" (cols ");
271 pr(detail::_to_chars_limited(buf, firstcol));
272 pr("-");
273 pr(detail::_to_chars_limited(buf, lastcol));
274 pr("/");
275 pr(detail::_to_chars_limited(buf, line.len));
276 pr(")\n");
277 }
278 if(location.col != npos)
279 {
280 print_cursor(jump);
281 }
282 // maybe print the region
283 if(num_lines_before || num_lines_after)
284 {
285 if(!call.empty())
286 {
287 print_call("\n");
288 print_call(" ");
289 pr("see region:\n");
290 print_call("\n");
291 }
292 else
293 {
294 if(location)
295 {
296 location_format(pr, location);
297 pr(" ");
298 }
299 pr("see region:\n");
300 }
301 csubstr region = detail::_get_text_region(source_buffer, location.offset, num_lines_before, num_lines_after);
302 for(csubstr contents : region.split('\n'))
303 {
304 if(!call.empty())
305 {
306 print_call(" ");
307 }
308 print_line_maybe_truncated(contents);
309 pr("\n");
310 }
311 assert(location.col == npos || location.col >= first_col_to_show);
312 print_cursor(location.col - first_col_to_show);
313 }
314}
csubstr _get_text_region(csubstr text, size_t pos, size_t num_lines_before, size_t num_lines_after)
Definition common.cpp:283
split_proxy split(C sep, size_t start_pos=0) const
a view into the splits
Definition substr.hpp:1913
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
Definition substr.hpp:530
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:503
bool empty() const noexcept
Definition substr.hpp:356

◆ err_basic_format()

template<class DumpFn>
void c4::yml::err_basic_format ( DumpFn && dumpfn,
csubstr msg,
ErrorDataBasic const & errdata )

Given an error message and associated basic error data, format it fully as a basic error message.

Parameters
dumpfnfunction taking a csubstr and abstracting a string concatenation operation, such as appending to a std::string or printing to terminal.
msgthe error message
errdatathe error data

For example:

/// to output to cerr:
std::cerr.write(s.str, s.len);
}, errmsg, errdata);
/// to build a string:
std::string msg;
error_basic_format([&msg](csubstr s){
msg.append(s.str, s.len);
}, errmsg, errdata);
void err_basic_format(DumpFn &&dumpfn, csubstr msg, ErrorDataBasic const &errdata)
Given an error message and associated basic error data, format it fully as a basic error message.

Definition at line 318 of file error.def.hpp.

319{
320 if(errdata.location)
321 {
322 location_format(dumpfn, errdata.location);
323 std::forward<DumpFn>(dumpfn)(" ");
324 }
325 std::forward<DumpFn>(dumpfn)("ERROR: [basic] ");
326 std::forward<DumpFn>(dumpfn)(msg);
327}

◆ err_basic() [1/4]

void c4::yml::err_basic ( Callbacks const & callbacks,
ErrorDataBasic const & errdata,
const char * msg_ )

trigger a basic error to its respective handler, with a non-formatted error message.

Definition at line 201 of file common.cpp.

202{
203 csubstr msg = to_csubstr(msg_);
204 callbacks.m_error_basic(msg, errdata, callbacks.m_user_data);
205 abort(); // the call above should not return, so force it here in case it does // LCOV_EXCL_LINE
206 C4_UNREACHABLE_AFTER_ERR();
207}
csubstr to_csubstr(const char(&s)[N]) noexcept
Definition substr.hpp:2381

◆ err_basic() [2/4]

void c4::yml::err_basic ( ErrorDataBasic const & errdata,
const char * msg )

trigger a basic error to its respective handler, with a non-formatted error message.

Like (1), but use the current global callbacks.

Definition at line 196 of file common.cpp.

197{
198 err_basic(get_callbacks(), errdata, msg);
199 C4_UNREACHABLE_AFTER_ERR();
200}
Callbacks const & get_callbacks()
get the global callbacks
Definition common.cpp:94
void err_basic(ErrorDataBasic const &errdata, const char *msg)
trigger a basic error to its respective handler, with a non-formatted error message.
Definition common.cpp:196

◆ err_basic() [3/4]

template<class ... Args>
void c4::yml::err_basic ( Callbacks const & callbacks,
ErrorDataBasic const & errdata,
const char * fmt,
Args const &... args )

trigger a basic error to its respective handler, with a formatted error message.

Definition at line 328 of file error.hpp.

329{
330 char errbuf[RYML_ERRMSG_SIZE];
331 csubstr msg = detail::_mk_err_msg(errbuf, to_csubstr(fmt), args...);
332 callbacks.m_error_basic(msg, errdata, callbacks.m_user_data);
333 std::abort(); // the call above should not return, but force it here in case it does // LCOV_EXCL_LINE
334 C4_UNREACHABLE_AFTER_ERR();
335}
#define RYML_ERRMSG_SIZE
size for the error message buffer
Definition common.hpp:34

◆ err_basic() [4/4]

template<class ... Args>
void c4::yml::err_basic ( ErrorDataBasic const & errdata,
const char * fmt,
Args const &... args )

trigger a basic error to its respective handler, with a formatted error message.

Like (1), but use the current global callbacks.

Definition at line 338 of file error.hpp.

339{
340 err_basic(get_callbacks(), errdata, fmt, args...);
341 C4_UNREACHABLE_AFTER_ERR();
342}

◆ err_parse_format()

template<class DumpFn>
void c4::yml::err_parse_format ( DumpFn && dumpfn,
csubstr msg,
ErrorDataParse const & errdata )

Given an error message and associated parse error data, format it fully as a parse error message.

Parameters
dumpfnfunction taking a csubstr and abstracting a string concatenation operation, such as appending to a std::string or printing to terminal.
msgthe error message
errdatathe error data

For example:

/// to output to cerr:
/// this is what err_parse_print() does
std::cerr.write(s.str, s.len);
}, errmsg, errdata);
/// to build a string:
std::string msg;
s.append(s.str, s.len);
}, errmsg, errdata);
void err_parse_format(DumpFn &&dumpfn, csubstr msg, ErrorDataParse const &errdata)
Given an error message and associated parse error data, format it fully as a parse error message.
Note
if the (preferably original) source buffer is kept, location_format_with_context() can be used to also an additional rich error message showing the YAML source buffer region around that location.

Definition at line 331 of file error.def.hpp.

332{
333 if(errdata.ymlloc)
334 {
335 location_format(std::forward<DumpFn>(dumpfn), errdata.ymlloc);
336 std::forward<DumpFn>(dumpfn)(" ");
337 }
338 std::forward<DumpFn>(dumpfn)("ERROR: [parse] ");
339 std::forward<DumpFn>(dumpfn)(msg);
340 if(errdata.cpploc)
341 {
342 std::forward<DumpFn>(dumpfn)("\n");
343 location_format(std::forward<DumpFn>(dumpfn), errdata.cpploc);
344 std::forward<DumpFn>(dumpfn)(" (detected here)");
345 }
346}

◆ err_parse() [1/4]

void c4::yml::err_parse ( Callbacks const & callbacks,
ErrorDataParse const & errdata,
const char * msg_ )

trigger a parse error to its respective handler, with a non-formatted error message

Definition at line 215 of file common.cpp.

216{
217 csubstr msg = to_csubstr(msg_);
218 if(callbacks.m_error_parse)
219 callbacks.m_error_parse(msg, errdata, callbacks.m_user_data);
220 // fall to basic error if there is no parse handler set
221 else if(callbacks.m_error_basic)
222 callbacks.m_error_basic(msg, errdata.ymlloc, callbacks.m_user_data);
223 abort(); // the call above should not return, so force it here in case it does // LCOV_EXCL_LINE
224 C4_UNREACHABLE_AFTER_ERR();
225}

◆ err_parse() [2/4]

void c4::yml::err_parse ( ErrorDataParse const & errdata,
const char * msg )

trigger a parse error to its respective handler, with a non-formatted error message.

Like (1), but use the current global callbacks.

Definition at line 210 of file common.cpp.

211{
212 err_parse(get_callbacks(), errdata, msg);
213 C4_UNREACHABLE_AFTER_ERR();
214}
void err_parse(ErrorDataParse const &errdata, const char *msg)
trigger a parse error to its respective handler, with a non-formatted error message.
Definition common.cpp:210

◆ err_parse() [3/4]

template<class ... Args>
void c4::yml::err_parse ( Callbacks const & callbacks,
ErrorDataParse const & errdata,
const char * fmt,
Args const &... args )

trigger a parse error to its respective handler, with a formatted error message

Definition at line 383 of file error.hpp.

384{
385 char errbuf[RYML_ERRMSG_SIZE];
386 csubstr msg = detail::_mk_err_msg(errbuf, to_csubstr(fmt), args...);
387 if(callbacks.m_error_parse)
388 callbacks.m_error_parse(msg, errdata, callbacks.m_user_data);
389 // fall to basic error if there is no parse handler set, but use errdata.ymlloc instead of errdata.cpploc
390 else if(callbacks.m_error_basic)
391 callbacks.m_error_basic(msg, errdata.ymlloc, callbacks.m_user_data);
392 std::abort(); // the call above should not return, so force it here in case it does // LCOV_EXCL_LINE
393 C4_UNREACHABLE_AFTER_ERR();
394}

◆ err_parse() [4/4]

template<class ... Args>
void c4::yml::err_parse ( ErrorDataParse const & errdata,
const char * fmt,
Args const &... args )

trigger a parse error to its respective handler, with a formatted error message.

Like (1), but use the current global callbacks.

Definition at line 397 of file error.hpp.

398{
399 err_parse(get_callbacks(), errdata, fmt, args...);
400 C4_UNREACHABLE_AFTER_ERR();
401}

◆ err_visit_format()

template<class DumpFn>
void c4::yml::err_visit_format ( DumpFn && dumpfn,
csubstr msg,
ErrorDataVisit const & errdata )

Given an error message and associated visit error data, format it fully as a visit error message.

Parameters
dumpfnfunction taking a csubstr and abstracting a string concatenation operation, such as appending to a std::string or printing to terminal.
msgthe error message
errdatathe error data

For example:

/// to output to cerr:
std::cerr.write(s.str, s.len);
}, errmsg, errdata);
/// to build a string:
std::string msg;
msg.append(s.str, s.len);
}, errmsg, errdata);
@note under certain conditions, it is possible to obtain an
associated location, and subsequently use @ref
location_format_with_context() to also create a rich error message
showing the YAML source buffer region around that location. This is
possible if the (preferably original) source buffer is kept, and
the node location can be retrieved from the parser.
void err_visit_format(DumpFn &&dumpfn, csubstr msg, ErrorDataVisit const &errdata)
Given an error message and associated visit error data, format it fully as a visit error message.
void location_format_with_context(DumpFn &&dumpfn, Location const &location, csubstr source_buffer, csubstr call, size_t num_lines_before, size_t num_lines_after, size_t first_col_highlight, size_t last_col_highlight, size_t maxlen)
Generic formatting of a location, printing the source code buffer region around the location.
Definition error.def.hpp:86

Definition at line 350 of file error.def.hpp.

351{
352 char buf_[32];
353 substr buf(buf_);
354 if(errdata.cpploc)
355 {
356 location_format(dumpfn, errdata.cpploc);
357 std::forward<DumpFn>(dumpfn)(" ");
358 }
359 std::forward<DumpFn>(dumpfn)("ERROR: [visit] ");
360 std::forward<DumpFn>(dumpfn)(msg);
361 if(errdata.node != NONE && errdata.tree != nullptr)
362 {
363 if(errdata.cpploc)
364 {
365 std::forward<DumpFn>(dumpfn)("\n");
366 location_format(dumpfn, errdata.cpploc);
367 std::forward<DumpFn>(dumpfn)(" ");
368 }
369 std::forward<DumpFn>(dumpfn)("ERROR: (");
370 if(errdata.node != NONE)
371 {
372 std::forward<DumpFn>(dumpfn)("node=");
373 std::forward<DumpFn>(dumpfn)(detail::_to_chars_limited(buf, errdata.node));
374 if(errdata.tree != nullptr)
375 std::forward<DumpFn>(dumpfn)(" ");
376 }
377 if(errdata.tree != nullptr)
378 {
379 std::forward<DumpFn>(dumpfn)("tree=");
380 std::forward<DumpFn>(dumpfn)(detail::_to_chars_limited(buf, static_cast<void const*>(errdata.tree)));
381 }
382 std::forward<DumpFn>(dumpfn)(")");
383 }
384}
@ NONE
an index to none
Definition common.hpp:256

◆ err_visit() [1/4]

void c4::yml::err_visit ( Callbacks const & callbacks,
ErrorDataVisit const & errdata,
const char * msg_ )

trigger a visit error to its respective handler, with a non-formatted error message

Definition at line 233 of file common.cpp.

234{
235 csubstr msg = to_csubstr(msg_);
236 if(callbacks.m_error_visit)
237 callbacks.m_error_visit(msg, errdata, callbacks.m_user_data);
238 // fall to basic error if there is no visit handler set
239 else if(callbacks.m_error_basic)
240 callbacks.m_error_basic(msg, errdata.cpploc, callbacks.m_user_data);
241 abort(); // the call above should not return, so force it here in case it does // LCOV_EXCL_LINE
242 C4_UNREACHABLE_AFTER_ERR();
243}

◆ err_visit() [2/4]

void c4::yml::err_visit ( ErrorDataVisit const & errdata,
const char * msg )

trigger a visit error to its respective handler, with a non-formatted error message.

Like (1), but uses the current global callbacks.

Definition at line 228 of file common.cpp.

229{
230 err_visit(get_callbacks(), errdata, msg);
231 C4_UNREACHABLE_AFTER_ERR();
232}
void err_visit(ErrorDataVisit const &errdata, const char *msg)
trigger a visit error to its respective handler, with a non-formatted error message.
Definition common.cpp:228

◆ err_visit() [3/4]

template<class ... Args>
void c4::yml::err_visit ( Callbacks const & callbacks,
ErrorDataVisit const & errdata,
const char * fmt,
Args const &... args )

trigger a visit error to its respective handler, with a formatted error message

Definition at line 445 of file error.hpp.

446{
447 char errbuf[RYML_ERRMSG_SIZE];
448 csubstr msg = detail::_mk_err_msg(errbuf, to_csubstr(fmt), args...);
449 if(callbacks.m_error_visit)
450 callbacks.m_error_visit(msg, errdata, callbacks.m_user_data);
451 // fall to basic error if there is no visit handler set
452 else if(callbacks.m_error_basic)
453 callbacks.m_error_basic(msg, errdata.cpploc, callbacks.m_user_data);
454 std::abort(); // the call above should not return, so force it here in case it does // LCOV_EXCL_LINE
455 C4_UNREACHABLE_AFTER_ERR();
456}

◆ err_visit() [4/4]

template<class ... Args>
void c4::yml::err_visit ( ErrorDataVisit const & errdata,
const char * fmt,
Args const &... args )

trigger a visit error to its respective handler, with a formatted error message.

Like (1), but use the current global callbacks.

Definition at line 459 of file error.hpp.

460{
461 err_visit(get_callbacks(), errdata, fmt, args...);
462 C4_UNREACHABLE_AFTER_ERR();
463}

◆ format_exc() [1/4]

template<class CharContainer>
void c4::yml::format_exc ( CharContainer * out,
ExceptionBasic const & exc )

Format a basic exception to an existing char container.

Note
Available only if RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS is defined, and RYML_NO_DEFAULT_CALLBACKS is NOT defined.

Definition at line 526 of file error.hpp.

527{
528 out->clear();
529 err_basic_format([out](csubstr s){
530 out->append(s.str, s.len);
531 }, csubstr{exc.msg, strlen(exc.msg)}, exc.errdata_basic);
532}

◆ format_exc() [2/4]

template<class CharContainer>
void c4::yml::format_exc ( CharContainer * out,
ExceptionParse const & exc )

Format a parse exception to an existing char container.

Note
Available only if RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS is defined, and RYML_NO_DEFAULT_CALLBACKS is NOT defined.

Definition at line 539 of file error.hpp.

540{
541 out->clear();
542 err_parse_format([out](csubstr s){
543 out->append(s.str, s.len);
544 }, csubstr{exc.msg, strlen(exc.msg)}, exc.errdata_parse);
545}

◆ format_exc() [3/4]

template<class CharContainer>
void c4::yml::format_exc ( CharContainer * out,
ExceptionVisit const & exc )

Format a visit exception to an existing char container.

Note
Available only if RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS is defined, and RYML_NO_DEFAULT_CALLBACKS is NOT defined.

Definition at line 552 of file error.hpp.

553{
554 out->clear();
555 err_visit_format([out](csubstr s){
556 out->append(s.str, s.len);
557 }, csubstr{exc.msg, strlen(exc.msg)}, exc.errdata_visit);
558}

◆ format_exc() [4/4]

template<class CharContainer, class ExceptionT>
CharContainer c4::yml::format_exc ( ExceptionT const & exc)

Format a parse exception, and return a newly-created char container.

Note
Available only if RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS is defined, and RYML_NO_DEFAULT_CALLBACKS is NOT defined.

Definition at line 566 of file error.hpp.

567{
568 CharContainer str;
569 format_exc(&str, exc);
570 return str;
571}
void format_exc(CharContainer *out, ExceptionBasic const &exc)
Format a basic exception to an existing char container.
Definition error.hpp:526