rapidyaml  0.13.0
parse and emit YAML, and do it fast
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 More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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 More...
 
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. More...
 
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 More...
 
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. More...
 
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. More...
 
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 More...
 
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. More...
 
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 More...
 
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. More...
 
template<class CharContainer >
void c4::yml::format_exc (CharContainer *out, ExceptionBasic const &exc)
 Format a basic exception to an existing char container. More...
 
template<class CharContainer >
void c4::yml::format_exc (CharContainer *out, ExceptionParse const &exc)
 Format a parse exception to an existing char container. More...
 
template<class CharContainer >
void c4::yml::format_exc (CharContainer *out, ExceptionVisit const &exc)
 Format a visit exception to an existing char container. More...
 
template<class CharContainer , class ExceptionT >
CharContainer c4::yml::format_exc (ExceptionT const &exc)
 Format a parse exception, and return a newly-created char container. More...
 

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:

{c++}
/// to output to std::cerr:
location_format([&s](csubstr s){
std::cerr.write(s.str, s.len);
}, loc);
/// to build a string:
std::string msg;
location_format([&s](csubstr s){
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

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 }
@ npos
a null string position
Definition: common.hpp:258

◆ 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:

{c++}
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,

{c++}
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

◆ 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:

{c++}
/// to output to cerr:
err_basic_format([](csubstr s){
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: error.def.hpp:318

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(substr s) noexcept
neutral version for use in generic code
Definition: substr.hpp:2204

◆ 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(Callbacks const &callbacks, ErrorDataBasic const &errdata, const char *msg_)
trigger a basic error to its respective handler, with a non-formatted error message.
Definition: common.cpp:201

◆ 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 }
void err_basic(ErrorDataBasic const &errdata, const char *fmt, Args const &...args)
trigger a basic error to its respective handler, with a formatted error message.
Definition: error.hpp:338

◆ 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:

{c++}
/// to output to cerr:
/// this is what err_parse_print() does
err_parse_format([](csubstr s){
std::cerr.write(s.str, s.len);
}, errmsg, errdata);
/// to build a string:
std::string msg;
err_parse_format([](csubstr s){
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.
Definition: error.def.hpp:331
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(Callbacks const &callbacks, ErrorDataParse const &errdata, const char *msg_)
trigger a parse error to its respective handler, with a non-formatted error message
Definition: common.cpp:215

◆ 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 }
void err_parse(ErrorDataParse const &errdata, const char *fmt, Args const &...args)
trigger a parse error to its respective handler, with a formatted error message.
Definition: error.hpp:397

◆ 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:

{c++}
/// to output to cerr:
err_visit_format([](csubstr s){
std::cerr.write(s.str, s.len);
}, errmsg, errdata);
/// to build a string:
std::string msg;
err_visit_format([&msg](csubstr s){
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.
Definition: error.def.hpp:350
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
@ YAML
yaml directive: \YAML <version>

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:251

◆ 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(Callbacks const &callbacks, ErrorDataVisit const &errdata, const char *msg_)
trigger a visit error to its respective handler, with a non-formatted error message
Definition: common.cpp:233

◆ 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 }
void err_visit(ErrorDataVisit const &errdata, const char *fmt, Args const &...args)
trigger a visit error to its respective handler, with a formatted error message.
Definition: error.hpp:459

◆ 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 }
CharContainer format_exc(ExceptionT const &exc)
Format a parse exception, and return a newly-created char container.
Definition: error.hpp:566