rapidyaml  0.7.2
parse and emit YAML, and do it fast
common.hpp
Go to the documentation of this file.
1 #ifndef _C4_YML_COMMON_HPP_
2 #define _C4_YML_COMMON_HPP_
3 
4 /** @file common.hpp Common utilities and infrastructure used by ryml. */
5 
6 #include <cstddef>
7 #include <c4/substr.hpp>
8 #include <c4/dump.hpp>
9 #include <c4/yml/export.hpp>
10 
11 #if defined(C4_MSVC) || defined(C4_MINGW)
12 #include <malloc.h>
13 #else
14 #include <alloca.h>
15 #endif
16 
17 
18 
19 //-----------------------------------------------------------------------------
20 
21 #ifndef RYML_ERRMSG_SIZE
22 /// size for the error message buffer
23 #define RYML_ERRMSG_SIZE (1024)
24 #endif
25 
26 #ifndef RYML_LOGBUF_SIZE
27 /// size for the buffer used to format individual values to string
28 /// while preparing an error message. This is only used for formatting
29 /// individual values in the message; final messages will be larger
30 /// than this value (see @ref RYML_ERRMSG_SIZE). This is also used for
31 /// the detailed debug log messages when RYML_DBG is defined.
32 #define RYML_LOGBUF_SIZE (256)
33 #endif
34 
35 #ifndef RYML_LOGBUF_SIZE_MAX
36 /// size for the fallback larger log buffer. When @ref
37 /// RYML_LOGBUF_SIZE is not large enough to convert a value to string,
38 /// then temporary stack memory is allocated up to
39 /// RYML_LOGBUF_SIZE_MAX. This limit is in place to prevent a stack
40 /// overflow. If the printed value requires more than
41 /// RYML_LOGBUF_SIZE_MAX, the value is silently skipped.
42 #define RYML_LOGBUF_SIZE_MAX (1024)
43 #endif
44 
45 #ifndef RYML_LOCATIONS_SMALL_THRESHOLD
46 /// threshold at which a location search will revert from linear to
47 /// binary search.
48 #define RYML_LOCATIONS_SMALL_THRESHOLD (30)
49 #endif
50 
51 
52 //-----------------------------------------------------------------------------
53 // Specify groups to have a predefined topic order in doxygen:
54 
55 /** @defgroup doc_quickstart Quickstart
56  *
57  * Example code for every feature.
58  */
59 
60 /** @defgroup doc_parse Parse utilities
61  * @see sample::sample_parse_in_place
62  * @see sample::sample_parse_in_arena
63  * @see sample::sample_parse_file
64  * @see sample::sample_parse_reuse_tree
65  * @see sample::sample_parse_reuse_parser
66  * @see sample::sample_parse_reuse_tree_and_parser
67  * @see sample::sample_location_tracking
68  */
69 
70 /** @defgroup doc_emit Emit utilities
71  *
72  * Utilities to emit YAML and JSON, either to a memory buffer or to a
73  * file or ostream-like class.
74  *
75  * @see sample::sample_emit_to_container
76  * @see sample::sample_emit_to_stream
77  * @see sample::sample_emit_to_file
78  * @see sample::sample_emit_nested_node
79  * @see sample::sample_emit_style
80  */
81 
82 /** @defgroup doc_node_type Node types
83  */
84 
85 /** @defgroup doc_tree Tree utilities
86  * @see sample::sample_quick_overview
87  * @see sample::sample_iterate_trees
88  * @see sample::sample_create_trees
89  * @see sample::sample_tree_arena
90  *
91  * @see sample::sample_static_trees
92  * @see sample::sample_location_tracking
93  *
94  * @see sample::sample_docs
95  * @see sample::sample_anchors_and_aliases
96  * @see sample::sample_tags
97  */
98 
99 /** @defgroup doc_node_classes Node classes
100  *
101  * High-level node classes.
102  *
103  * @see sample::sample_quick_overview
104  * @see sample::sample_iterate_trees
105  * @see sample::sample_create_trees
106  * @see sample::sample_tree_arena
107  */
108 
109 /** @defgroup doc_callbacks Callbacks for errors and allocation
110  *
111  * Functions called by ryml to allocate/free memory and to report
112  * errors.
113  *
114  * @see sample::sample_error_handler
115  * @see sample::sample_global_allocator
116  * @see sample::sample_per_tree_allocator
117  */
118 
119 /** @defgroup doc_serialization Serialization/deserialization
120  *
121  * Contains information on how to serialize and deserialize
122  * fundamental types, user scalar types, user container types and
123  * interop with std scalar/container types.
124  *
125  */
126 
127 /** @defgroup doc_ref_utils Anchor/Reference utilities
128  *
129  * @see sample::sample_anchors_and_aliases
130  * */
131 
132 /** @defgroup doc_tag_utils Tag utilities
133  * @see sample::sample_tags
134  */
135 
136 /** @defgroup doc_preprocessors Preprocessors
137  *
138  * Functions for preprocessing YAML prior to parsing.
139  */
140 
141 
142 //-----------------------------------------------------------------------------
143 
144 // document macros for doxygen
145 #ifdef __DOXYGEN__ // defined in Doxyfile::PREDEFINED
146 
147 /** define this macro with a boolean value to enable/disable
148  * assertions to check preconditions and assumptions throughout the
149  * codebase; this causes a slowdown of the code, and larger code
150  * size. By default, this macro is defined unless NDEBUG is defined
151  * (see C4_USE_ASSERT); as a result, by default this macro is truthy
152  * only in debug builds. */
153 # define RYML_USE_ASSERT
154 
155 /** (Undefined by default) Define this macro to disable ryml's default
156  * implementation of the callback functions; see @ref c4::yml::Callbacks */
157 # define RYML_NO_DEFAULT_CALLBACKS
158 
159 /** (Undefined by default) When this macro is defined (and
160  * @ref RYML_NO_DEFAULT_CALLBACKS is not defined), the default error
161  * handler will throw C++ exceptions of type `std::runtime_error`. */
162 # define RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS
163 
164 /** Conditionally expands to `noexcept` when @ref RYML_USE_ASSERT is 0 and
165  * is empty otherwise. The user is unable to override this macro. */
166 # define RYML_NOEXCEPT
167 
168 #endif
169 
170 
171 //-----------------------------------------------------------------------------
172 
173 
174 /** @cond dev*/
175 #ifndef RYML_USE_ASSERT
176 # define RYML_USE_ASSERT C4_USE_ASSERT
177 #endif
178 
179 #if RYML_USE_ASSERT
180 # define RYML_ASSERT(cond) RYML_CHECK(cond)
181 # define RYML_ASSERT_MSG(cond, msg) RYML_CHECK_MSG(cond, msg)
182 # define _RYML_CB_ASSERT(cb, cond) _RYML_CB_CHECK((cb), (cond))
183 # define _RYML_CB_ASSERT_(cb, cond, loc) _RYML_CB_CHECK((cb), (cond), (loc))
184 # define RYML_NOEXCEPT
185 #else
186 # define RYML_ASSERT(cond)
187 # define RYML_ASSERT_MSG(cond, msg)
188 # define _RYML_CB_ASSERT(cb, cond)
189 # define _RYML_CB_ASSERT_(cb, cond, loc)
190 # define RYML_NOEXCEPT noexcept
191 #endif
192 
193 #define RYML_DEPRECATED(msg) C4_DEPRECATED(msg)
194 
195 #define RYML_CHECK(cond) \
196  do { \
197  if(C4_UNLIKELY(!(cond))) \
198  { \
199  RYML_DEBUG_BREAK(); \
200  c4::yml::error("check failed: " #cond, c4::yml::Location(__FILE__, __LINE__, 0)); \
201  C4_UNREACHABLE_AFTER_ERR(); \
202  } \
203  } while(0)
204 
205 #define RYML_CHECK_MSG(cond, msg) \
206  do \
207  { \
208  if(C4_UNLIKELY(!(cond))) \
209  { \
210  RYML_DEBUG_BREAK(); \
211  c4::yml::error(msg ": check failed: " #cond, c4::yml::Location(__FILE__, __LINE__, 0)); \
212  C4_UNREACHABLE_AFTER_ERR(); \
213  } \
214  } while(0)
215 
216 #if defined(RYML_DBG) && !defined(NDEBUG) && !defined(C4_NO_DEBUG_BREAK)
217 # define RYML_DEBUG_BREAK() \
218  do { \
219  if(c4::get_error_flags() & c4::ON_ERROR_DEBUGBREAK) \
220  { \
221  C4_DEBUG_BREAK(); \
222  } \
223  } while(0)
224 #else
225 # define RYML_DEBUG_BREAK()
226 #endif
227 
228 /** @endcond */
229 
230 
231 //-----------------------------------------------------------------------------
232 //-----------------------------------------------------------------------------
233 //-----------------------------------------------------------------------------
234 
235 namespace c4 {
236 namespace yml {
237 
238 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
239 
240 
241 #ifndef RYML_ID_TYPE
242 /** The type of a node id in the YAML tree. In the future, the default
243  * will likely change to int32_t, which was observed to be faster.
244  * @see id_type */
245 #define RYML_ID_TYPE size_t
246 #endif
247 
248 
249 /** The type of a node id in the YAML tree; to override the default
250  * type, define the macro @ref RYML_ID_TYPE to a suitable integer
251  * type. */
253 static_assert(std::is_integral<id_type>::value, "id_type must be an integer type");
254 
255 
256 C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wuseless-cast")
257 enum : id_type {
258  /** an index to none */
259  NONE = id_type(-1),
260 };
261 C4_SUPPRESS_WARNING_GCC_CLANG_POP
262 
263 
264 enum : size_t {
265  /** a null string position */
266  npos = size_t(-1)
267 };
268 
269 
270 //-----------------------------------------------------------------------------
271 //-----------------------------------------------------------------------------
272 //-----------------------------------------------------------------------------
273 
274 //! holds a position into a source buffer
276 {
277  //! number of bytes from the beginning of the source buffer
278  size_t offset;
279  //! line
280  size_t line;
281  //! column
282  size_t col;
283 
284  LineCol() = default;
285  //! construct from line and column
286  LineCol(size_t l, size_t c) : offset(0), line(l), col(c) {}
287  //! construct from offset, line and column
288  LineCol(size_t o, size_t l, size_t c) : offset(o), line(l), col(c) {}
289 };
290 static_assert(std::is_trivial<LineCol>::value, "LineCol not trivial");
291 static_assert(std::is_standard_layout<LineCol>::value, "Location not trivial");
292 
293 
294 //! a source file position
296 {
297  //! number of bytes from the beginning of the source buffer
298  size_t offset;
299  //! line
300  size_t line;
301  //! column
302  size_t col;
303  //! file name
304  csubstr name;
305 
306  operator bool () const { return !name.empty() || line != 0 || offset != 0 || col != 0; }
307  operator LineCol const& () const { return reinterpret_cast<LineCol const&>(*this); }
308 
309  Location() = default;
310  Location( size_t l, size_t c) : offset( ), line(l), col(c), name( ) {}
311  Location( size_t b, size_t l, size_t c) : offset(b), line(l), col(c), name( ) {}
312  Location( csubstr n, size_t l, size_t c) : offset( ), line(l), col(c), name(n) {}
313  Location( csubstr n, size_t b, size_t l, size_t c) : offset(b), line(l), col(c), name(n) {}
314  Location(const char *n, size_t l, size_t c) : offset( ), line(l), col(c), name(to_csubstr(n)) {}
315  Location(const char *n, size_t b, size_t l, size_t c) : offset(b), line(l), col(c), name(to_csubstr(n)) {}
316 };
317 static_assert(std::is_standard_layout<Location>::value, "Location not trivial");
318 
319 
320 //-----------------------------------------------------------------------------
321 
322 /** @addtogroup doc_callbacks
323  *
324  * @{ */
325 
326 struct Callbacks;
327 
328 
329 /** set the global callbacks for the library; after a call to this
330  * function, these callbacks will be used by newly created objects
331  * (unless they are copying older objects with different
332  * callbacks). If @ref RYML_NO_DEFAULT_CALLBACKS is defined, it is
333  * mandatory to call this function prior to using any other library
334  * facility.
335  *
336  * @warning This function is NOT thread-safe.
337  *
338  * @warning the error callback must never return: see @ref pfn_error
339  * for more details */
340 RYML_EXPORT void set_callbacks(Callbacks const& c);
341 
342 /** get the global callbacks
343  * @warning This function is not thread-safe. */
344 RYML_EXPORT Callbacks const& get_callbacks();
345 
346 /** set the global callbacks back to their defaults ()
347  * @warning This function is not thread-safe. */
349 
350 
351 /** the type of the function used to report errors
352  *
353  * @warning When given by the user, this function MUST interrupt
354  * execution, typically by either throwing an exception, or using
355  * `std::longjmp()` ([see
356  * documentation](https://en.cppreference.com/w/cpp/utility/program/setjmp))
357  * or by calling `std::abort()`. If the function returned, the parser
358  * would enter into an infinite loop, or the program may crash. */
359 using pfn_error = void (*) (const char* msg, size_t msg_len, Location location, void *user_data);
360 
361 
362 /** the type of the function used to allocate memory; ryml will only
363  * allocate memory through this callback. */
364 using pfn_allocate = void* (*)(size_t len, void* hint, void *user_data);
365 
366 
367 /** the type of the function used to free memory; ryml will only free
368  * memory through this callback. */
369 using pfn_free = void (*)(void* mem, size_t size, void *user_data);
370 
371 
372 /** a c-style callbacks class. Can be used globally by the library
373  * and/or locally by @ref Tree and @ref Parser objects. */
375 {
376  void * m_user_data;
380 
381  /** Construct an object with the default callbacks. If
382  * @ref RYML_NO_DEFAULT_CALLBACKS is defined, the object will have null
383  * members.*/
384  Callbacks();
385 
386  /** Construct an object with the given callbacks.
387  *
388  * @param user_data Data to be forwarded in every call to a callback.
389  *
390  * @param alloc A pointer to an allocate function. Unless
391  * @ref RYML_NO_DEFAULT_CALLBACKS is defined, when this
392  * parameter is null, will fall back to ryml's default
393  * alloc implementation.
394  *
395  * @param free A pointer to a free function. Unless
396  * @ref RYML_NO_DEFAULT_CALLBACKS is defined, when this
397  * parameter is null, will fall back to ryml's default free
398  * implementation.
399  *
400  * @param error A pointer to an error function, which must never
401  * return (see @ref pfn_error). Unless
402  * @ref RYML_NO_DEFAULT_CALLBACKS is defined, when this
403  * parameter is null, will fall back to ryml's default
404  * error implementation.
405  */
406  Callbacks(void *user_data, pfn_allocate alloc, pfn_free free, pfn_error error);
407 
408  bool operator!= (Callbacks const& that) const { return !operator==(that); }
409  bool operator== (Callbacks const& that) const
410  {
411  return (m_user_data == that.m_user_data &&
412  m_allocate == that.m_allocate &&
413  m_free == that.m_free &&
414  m_error == that.m_error);
415  }
416 };
417 
418 
419 /** @} */
420 
421 
422 //-----------------------------------------------------------------------------
423 //-----------------------------------------------------------------------------
424 //-----------------------------------------------------------------------------
425 
426 /// @cond dev
427 
428 // BEWARE! MSVC requires that [[noreturn]] appears before RYML_EXPORT
429 [[noreturn]] RYML_EXPORT void error(Callbacks const& cb, const char *msg, size_t msg_len, Location loc);
430 [[noreturn]] RYML_EXPORT void error(const char *msg, size_t msg_len, Location loc);
431 
432 [[noreturn]] inline void error(const char *msg, size_t msg_len)
433 {
434  error(msg, msg_len, Location{});
435 }
436 template<size_t N>
437 [[noreturn]] inline void error(const char (&msg)[N], Location loc)
438 {
439  error(msg, N-1, loc);
440 }
441 template<size_t N>
442 [[noreturn]] inline void error(const char (&msg)[N])
443 {
444  error(msg, N-1, Location{});
445 }
446 
447 #define _RYML_CB_ERR(cb, msg_literal) \
448  _RYML_CB_ERR_(cb, msg_literal, c4::yml::Location(__FILE__, 0, __LINE__, 0))
449 #define _RYML_CB_CHECK(cb, cond) \
450  _RYML_CB_CHECK_(cb, cond, c4::yml::Location(__FILE__, 0, __LINE__, 0))
451 #define _RYML_CB_ERR_(cb, msg_literal, loc) \
452 do \
453 { \
454  const char msg[] = msg_literal; \
455  RYML_DEBUG_BREAK(); \
456  c4::yml::error((cb), msg, sizeof(msg)-1, loc); \
457  C4_UNREACHABLE_AFTER_ERR(); \
458 } while(0)
459 #define _RYML_CB_CHECK_(cb, cond, loc) \
460  do \
461  { \
462  if(C4_UNLIKELY(!(cond))) \
463  { \
464  const char msg[] = "check failed: " #cond; \
465  RYML_DEBUG_BREAK(); \
466  c4::yml::error((cb), msg, sizeof(msg)-1, loc); \
467  C4_UNREACHABLE_AFTER_ERR(); \
468  } \
469  } while(0)
470 #define _RYML_CB_ALLOC_HINT(cb, T, num, hint) (T*) (cb).m_allocate((num) * sizeof(T), (hint), (cb).m_user_data)
471 #define _RYML_CB_ALLOC(cb, T, num) _RYML_CB_ALLOC_HINT((cb), T, (num), nullptr)
472 #define _RYML_CB_FREE(cb, buf, T, num) \
473  do { \
474  (cb).m_free((buf), (num) * sizeof(T), (cb).m_user_data); \
475  (buf) = nullptr; \
476  } while(0)
477 
478 
479 
480 //-----------------------------------------------------------------------------
481 //-----------------------------------------------------------------------------
482 //-----------------------------------------------------------------------------
483 
484 typedef enum {
485  BLOCK_LITERAL, //!< keep newlines (|)
486  BLOCK_FOLD //!< replace newline with single space (>)
487 } BlockStyle_e;
488 
489 typedef enum {
490  CHOMP_CLIP, //!< single newline at end (default)
491  CHOMP_STRIP, //!< no newline at end (-)
492  CHOMP_KEEP //!< all newlines from end (+)
493 } BlockChomp_e;
494 
495 
496 /** Abstracts the fact that a scalar filter result may not fit in the
497  * intended memory. */
498 struct FilterResult
499 {
500  C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
501  C4_ALWAYS_INLINE size_t required_len() const noexcept { return str.len; }
502  C4_ALWAYS_INLINE csubstr get() { RYML_ASSERT(valid()); return str; }
503  csubstr str;
504 };
505 /** Abstracts the fact that a scalar filter result may not fit in the
506  * intended memory. */
507 struct FilterResultExtending
508 {
509  C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
510  C4_ALWAYS_INLINE size_t required_len() const noexcept { return reqlen; }
511  C4_ALWAYS_INLINE csubstr get() { RYML_ASSERT(valid()); return str; }
512  csubstr str;
513  size_t reqlen;
514 };
515 
516 
517 //-----------------------------------------------------------------------------
518 //-----------------------------------------------------------------------------
519 //-----------------------------------------------------------------------------
520 
521 
522 namespace detail {
523 // is there a better way to do this?
524 template<int8_t signedval, uint8_t unsignedval>
525 struct _charconstant_t
526  : public std::conditional<std::is_signed<char>::value,
527  std::integral_constant<int8_t, signedval>,
528  std::integral_constant<uint8_t, unsignedval>>::type
529 {};
530 #define _RYML_CHCONST(signedval, unsignedval) ::c4::yml::detail::_charconstant_t<INT8_C(signedval), UINT8_C(unsignedval)>::value
531 } // namespace detail
532 
533 
534 namespace detail {
535 struct _SubstrWriter
536 {
537  substr buf;
538  size_t pos;
539  _SubstrWriter(substr buf_, size_t pos_=0) : buf(buf_), pos(pos_) { C4_ASSERT(buf.str); }
540  void append(csubstr s)
541  {
542  C4_ASSERT(!s.overlaps(buf));
543  C4_ASSERT(s.str || !s.len);
544  if(s.len && pos + s.len <= buf.len)
545  {
546  C4_ASSERT(s.str);
547  memcpy(buf.str + pos, s.str, s.len);
548  }
549  pos += s.len;
550  }
551  void append(char c)
552  {
553  C4_ASSERT(buf.str);
554  if(pos < buf.len)
555  buf.str[pos] = c;
556  ++pos;
557  }
558  void append_n(char c, size_t numtimes)
559  {
560  C4_ASSERT(buf.str);
561  if(numtimes && pos + numtimes < buf.len)
562  memset(buf.str + pos, c, numtimes);
563  pos += numtimes;
564  }
565  size_t slack() const { return pos <= buf.len ? buf.len - pos : 0; }
566  size_t excess() const { return pos > buf.len ? pos - buf.len : 0; }
567  //! get the part written so far
568  csubstr curr() const { return pos <= buf.len ? buf.first(pos) : buf; }
569  //! get the part that is still free to write to (the remainder)
570  substr rem() { return pos < buf.len ? buf.sub(pos) : buf.last(0); }
571 
572  size_t advance(size_t more) { pos += more; return pos; }
573 };
574 } // namespace detail
575 
576 
577 namespace detail {
578 // dumpfn is a function abstracting prints to terminal (or to string).
579 template<class DumpFn, class ...Args>
580 C4_NO_INLINE void _dump(DumpFn &&dumpfn, csubstr fmt, Args&& ...args)
581 {
582  DumpResults results;
583  // try writing everything:
584  {
585  // buffer for converting individual arguments. it is defined
586  // in a child scope to free it in case the buffer is too small
587  // for any of the arguments.
588  char writebuf[RYML_LOGBUF_SIZE];
589  results = format_dump_resume(std::forward<DumpFn>(dumpfn), writebuf, fmt, std::forward<Args>(args)...);
590  }
591  // if any of the arguments failed to fit the buffer, allocate a
592  // larger buffer (up to a limit) and resume writing.
593  //
594  // results.bufsize is set to the size of the largest element
595  // serialized. Eg int(1) will require 1 byte.
596  if(C4_UNLIKELY(results.bufsize > RYML_LOGBUF_SIZE))
597  {
598  const size_t bufsize = results.bufsize <= RYML_LOGBUF_SIZE_MAX ? results.bufsize : RYML_LOGBUF_SIZE_MAX;
599  #ifdef C4_MSVC
600  substr largerbuf = {static_cast<char*>(_alloca(bufsize)), bufsize};
601  #else
602  substr largerbuf = {static_cast<char*>(alloca(bufsize)), bufsize};
603  #endif
604  results = format_dump_resume(std::forward<DumpFn>(dumpfn), results, largerbuf, fmt, std::forward<Args>(args)...);
605  }
606 }
607 template<class ...Args>
608 C4_NORETURN C4_NO_INLINE void _report_err(Callbacks const& C4_RESTRICT callbacks, csubstr fmt, Args const& C4_RESTRICT ...args)
609 {
610  char errmsg[RYML_ERRMSG_SIZE] = {0};
611  detail::_SubstrWriter writer(errmsg);
612  auto dumpfn = [&writer](csubstr s){ writer.append(s); };
613  _dump(dumpfn, fmt, args...);
614  writer.append('\n');
615  const size_t len = writer.pos < RYML_ERRMSG_SIZE ? writer.pos : RYML_ERRMSG_SIZE;
616  callbacks.m_error(errmsg, len, {}, callbacks.m_user_data);
617  C4_UNREACHABLE_AFTER_ERR();
618 }
619 } // namespace detail
620 
621 
622 inline csubstr _c4prc(const char &C4_RESTRICT c) // pass by reference!
623 {
624  switch(c)
625  {
626  case '\n': return csubstr("\\n");
627  case '\t': return csubstr("\\t");
628  case '\0': return csubstr("\\0");
629  case '\r': return csubstr("\\r");
630  case '\f': return csubstr("\\f");
631  case '\b': return csubstr("\\b");
632  case '\v': return csubstr("\\v");
633  case '\a': return csubstr("\\a");
634  default: return csubstr(&c, 1);
635  }
636 }
637 
638 /// @endcond
639 
640 C4_SUPPRESS_WARNING_GCC_POP
641 
642 } // namespace yml
643 } // namespace c4
644 
645 #endif /* _C4_YML_COMMON_HPP_ */
#define RYML_ID_TYPE
The type of a node id in the YAML tree.
Definition: common.hpp:245
#define RYML_ERRMSG_SIZE
size for the error message buffer
Definition: common.hpp:23
#define RYML_LOGBUF_SIZE
size for the buffer used to format individual values to string while preparing an error message....
Definition: common.hpp:32
#define RYML_LOGBUF_SIZE_MAX
size for the fallback larger log buffer. When RYML_LOGBUF_SIZE is not large enough to convert a value...
Definition: common.hpp:42
#define RYML_EXPORT
Definition: export.hpp:15
void reset_callbacks()
set the global callbacks back to their defaults ()
Definition: common.cpp:123
void(*)(const char *msg, size_t msg_len, Location location, void *user_data) pfn_error
the type of the function used to report errors
Definition: common.hpp:359
void set_callbacks(Callbacks const &c)
set the global callbacks for the library; after a call to this function, these callbacks will be used...
Definition: common.cpp:113
void *(*)(size_t len, void *hint, void *user_data) pfn_allocate
the type of the function used to allocate memory; ryml will only allocate memory through this callbac...
Definition: common.hpp:364
Callbacks const & get_callbacks()
get the global callbacks
Definition: common.cpp:118
void(*)(void *mem, size_t size, void *user_data) pfn_free
the type of the function used to free memory; ryml will only free memory through this callback.
Definition: common.hpp:369
csubstr to_csubstr(substr s) noexcept
neutral version for use in generic code
Definition: substr.hpp:2189
bool operator!=(const char(&s)[N], basic_substring< C > const that) noexcept
Definition: substr.hpp:2227
bool operator==(const char(&s)[N], basic_substring< C > const that) noexcept
Definition: substr.hpp:2226
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
Definition: common.hpp:252
@ npos
a null string position
Definition: common.hpp:266
void error(Callbacks const &cb, const char *msg, size_t msg_len, Location loc)
Definition: common.cpp:130
@ NONE
an index to none
Definition: common.hpp:259
Definition: common.cpp:12
a c-style callbacks class.
Definition: common.hpp:375
void * m_user_data
Definition: common.hpp:376
pfn_allocate m_allocate
Definition: common.hpp:377
pfn_free m_free
Definition: common.hpp:378
pfn_error m_error
Definition: common.hpp:379
holds a position into a source buffer
Definition: common.hpp:276
size_t line
line
Definition: common.hpp:280
LineCol(size_t o, size_t l, size_t c)
construct from offset, line and column
Definition: common.hpp:288
size_t offset
number of bytes from the beginning of the source buffer
Definition: common.hpp:278
LineCol(size_t l, size_t c)
construct from line and column
Definition: common.hpp:286
LineCol()=default
size_t col
column
Definition: common.hpp:282
a source file position
Definition: common.hpp:296
Location(csubstr n, size_t b, size_t l, size_t c)
Definition: common.hpp:313
size_t col
column
Definition: common.hpp:302
Location()=default
size_t line
line
Definition: common.hpp:300
Location(const char *n, size_t l, size_t c)
Definition: common.hpp:314
size_t offset
number of bytes from the beginning of the source buffer
Definition: common.hpp:298
Location(size_t l, size_t c)
Definition: common.hpp:310
Location(csubstr n, size_t l, size_t c)
Definition: common.hpp:312
csubstr name
file name
Definition: common.hpp:304
Location(const char *n, size_t b, size_t l, size_t c)
Definition: common.hpp:315
Location(size_t b, size_t l, size_t c)
Definition: common.hpp:311
read+write string views