Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rapidyaml/include/c4/yml/parse.hpp
4264 views
1
#ifndef _C4_YML_PARSE_HPP_
2
#define _C4_YML_PARSE_HPP_
3
4
#ifndef _C4_YML_TREE_HPP_
5
#include "c4/yml/tree.hpp"
6
#endif
7
8
#ifndef _C4_YML_NODE_HPP_
9
#include "c4/yml/node.hpp"
10
#endif
11
12
#ifndef _C4_YML_DETAIL_STACK_HPP_
13
#include "c4/yml/detail/stack.hpp"
14
#endif
15
16
#include <stdarg.h>
17
18
#if defined(_MSC_VER)
19
# pragma warning(push)
20
# pragma warning(disable: 4251/*needs to have dll-interface to be used by clients of struct*/)
21
#endif
22
23
namespace c4 {
24
namespace yml {
25
26
struct RYML_EXPORT ParserOptions
27
{
28
private:
29
30
typedef enum : uint32_t {
31
LOCATIONS = (1 << 0),
32
DEFAULTS = 0,
33
} Flags_e;
34
35
uint32_t flags = DEFAULTS;
36
public:
37
ParserOptions() = default;
38
39
/** @name source location tracking */
40
/** @{ */
41
42
/** enable/disable source location tracking */
43
ParserOptions& locations(bool enabled)
44
{
45
if(enabled)
46
flags |= LOCATIONS;
47
else
48
flags &= ~LOCATIONS;
49
return *this;
50
}
51
bool locations() const { return (flags & LOCATIONS) != 0u; }
52
53
/** @} */
54
};
55
56
57
//-----------------------------------------------------------------------------
58
//-----------------------------------------------------------------------------
59
//-----------------------------------------------------------------------------
60
class RYML_EXPORT Parser
61
{
62
public:
63
64
/** @name construction and assignment */
65
/** @{ */
66
67
Parser(Callbacks const& cb, ParserOptions opts={});
68
Parser(ParserOptions opts={}) : Parser(get_callbacks(), opts) {}
69
~Parser();
70
71
Parser(Parser &&);
72
Parser(Parser const&);
73
Parser& operator=(Parser &&);
74
Parser& operator=(Parser const&);
75
76
/** @} */
77
78
public:
79
80
/** @name modifiers */
81
/** @{ */
82
83
/** Reserve a certain capacity for the parsing stack.
84
* This should be larger than the expected depth of the parsed
85
* YAML tree.
86
*
87
* The parsing stack is the only (potential) heap memory used by
88
* the parser.
89
*
90
* If the requested capacity is below the default
91
* stack size of 16, the memory is used directly in the parser
92
* object; otherwise it will be allocated from the heap.
93
*
94
* @note this reserves memory only for the parser itself; all the
95
* allocations for the parsed tree will go through the tree's
96
* allocator.
97
*
98
* @note the tree and the arena can (and should) also be reserved. */
99
void reserve_stack(size_t capacity)
100
{
101
m_stack.reserve(capacity);
102
}
103
104
/** Reserve a certain capacity for the array used to track node
105
* locations in the source buffer. */
106
void reserve_locations(size_t num_source_lines)
107
{
108
_resize_locations(num_source_lines);
109
}
110
111
/** Reserve a certain capacity for the character arena used to
112
* filter scalars. */
113
void reserve_filter_arena(size_t num_characters)
114
{
115
_resize_filter_arena(num_characters);
116
}
117
118
/** @} */
119
120
public:
121
122
/** @name getters and modifiers */
123
/** @{ */
124
125
/** Get the current callbacks in the parser. */
126
Callbacks callbacks() const { return m_stack.m_callbacks; }
127
128
/** Get the name of the latest file parsed by this object. */
129
csubstr filename() const { return m_file; }
130
131
/** Get the latest YAML buffer parsed by this object. */
132
csubstr source() const { return m_buf; }
133
134
size_t stack_capacity() const { return m_stack.capacity(); }
135
size_t locations_capacity() const { return m_newline_offsets_capacity; }
136
size_t filter_arena_capacity() const { return m_filter_arena.len; }
137
138
ParserOptions const& options() const { return m_options; }
139
140
/** @} */
141
142
public:
143
144
/** @name parse_in_place */
145
/** @{ */
146
147
/** Create a new tree and parse into its root.
148
* The tree is created with the callbacks currently in the parser. */
149
Tree parse_in_place(csubstr filename, substr src)
150
{
151
Tree t(callbacks());
152
t.reserve(_estimate_capacity(src));
153
this->parse_in_place(filename, src, &t, t.root_id());
154
return t;
155
}
156
157
/** Parse into an existing tree, starting at its root node.
158
* The callbacks in the tree are kept, and used to allocate
159
* the tree members, if any allocation is required. */
160
void parse_in_place(csubstr filename, substr src, Tree *t)
161
{
162
this->parse_in_place(filename, src, t, t->root_id());
163
}
164
165
/** Parse into an existing node.
166
* The callbacks in the tree are kept, and used to allocate
167
* the tree members, if any allocation is required. */
168
void parse_in_place(csubstr filename, substr src, Tree *t, size_t node_id);
169
// ^^^^^^^^^^^^^ this is the workhorse overload; everything else is syntactic candy
170
171
/** Parse into an existing node.
172
* The callbacks in the tree are kept, and used to allocate
173
* the tree members, if any allocation is required. */
174
void parse_in_place(csubstr filename, substr src, NodeRef node)
175
{
176
this->parse_in_place(filename, src, node.tree(), node.id());
177
}
178
179
RYML_DEPRECATED("use parse_in_place() instead") Tree parse(csubstr filename, substr src) { return parse_in_place(filename, src); }
180
RYML_DEPRECATED("use parse_in_place() instead") void parse(csubstr filename, substr src, Tree *t) { parse_in_place(filename, src, t); }
181
RYML_DEPRECATED("use parse_in_place() instead") void parse(csubstr filename, substr src, Tree *t, size_t node_id) { parse_in_place(filename, src, t, node_id); }
182
RYML_DEPRECATED("use parse_in_place() instead") void parse(csubstr filename, substr src, NodeRef node) { parse_in_place(filename, src, node); }
183
184
/** @} */
185
186
public:
187
188
/** @name parse_in_arena: copy the YAML source buffer to the
189
* tree's arena, then parse the copy in situ
190
*
191
* @note overloads receiving a substr YAML buffer are intentionally
192
* left undefined, such that calling parse_in_arena() with a substr
193
* will cause a linker error. This is to prevent an accidental
194
* copy of the source buffer to the tree's arena, because substr
195
* is implicitly convertible to csubstr. If you really intend to parse
196
* a mutable buffer in the tree's arena, convert it first to immutable
197
* by assigning the substr to a csubstr prior to calling parse_in_arena().
198
* This is not needed for parse_in_place() because csubstr is not
199
* implicitly convertible to substr. */
200
/** @{ */
201
202
// READ THE NOTE ABOVE!
203
#define RYML_DONT_PARSE_SUBSTR_IN_ARENA "Do not pass a (mutable) substr to parse_in_arena(); if you have a substr, it should be parsed in place. Consider using parse_in_place() instead, or convert the buffer to csubstr prior to calling. This function is deliberately left undefined and will cause a linker error."
204
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) Tree parse_in_arena(csubstr filename, substr csrc);
205
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr csrc, Tree *t);
206
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr csrc, Tree *t, size_t node_id);
207
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr csrc, NodeRef node);
208
209
/** Create a new tree and parse into its root.
210
* The immutable YAML source is first copied to the tree's arena,
211
* and parsed from there.
212
* The callbacks in the tree are kept, and used to allocate
213
* the tree members, if any allocation is required. */
214
Tree parse_in_arena(csubstr filename, csubstr csrc)
215
{
216
Tree t(callbacks());
217
substr src = t.copy_to_arena(csrc);
218
t.reserve(_estimate_capacity(csrc));
219
this->parse_in_place(filename, src, &t, t.root_id());
220
return t;
221
}
222
223
/** Parse into an existing tree, starting at its root node.
224
* The immutable YAML source is first copied to the tree's arena,
225
* and parsed from there.
226
* The callbacks in the tree are kept, and used to allocate
227
* the tree members, if any allocation is required. */
228
void parse_in_arena(csubstr filename, csubstr csrc, Tree *t)
229
{
230
substr src = t->copy_to_arena(csrc);
231
this->parse_in_place(filename, src, t, t->root_id());
232
}
233
234
/** Parse into a specific node in an existing tree.
235
* The immutable YAML source is first copied to the tree's arena,
236
* and parsed from there.
237
* The callbacks in the tree are kept, and used to allocate
238
* the tree members, if any allocation is required. */
239
void parse_in_arena(csubstr filename, csubstr csrc, Tree *t, size_t node_id)
240
{
241
substr src = t->copy_to_arena(csrc);
242
this->parse_in_place(filename, src, t, node_id);
243
}
244
245
/** Parse into a specific node in an existing tree.
246
* The immutable YAML source is first copied to the tree's arena,
247
* and parsed from there.
248
* The callbacks in the tree are kept, and used to allocate
249
* the tree members, if any allocation is required. */
250
void parse_in_arena(csubstr filename, csubstr csrc, NodeRef node)
251
{
252
substr src = node.tree()->copy_to_arena(csrc);
253
this->parse_in_place(filename, src, node.tree(), node.id());
254
}
255
256
RYML_DEPRECATED("use parse_in_arena() instead") Tree parse(csubstr filename, csubstr csrc) { return parse_in_arena(filename, csrc); }
257
RYML_DEPRECATED("use parse_in_arena() instead") void parse(csubstr filename, csubstr csrc, Tree *t) { parse_in_arena(filename, csrc, t); }
258
RYML_DEPRECATED("use parse_in_arena() instead") void parse(csubstr filename, csubstr csrc, Tree *t, size_t node_id) { parse_in_arena(filename, csrc, t, node_id); }
259
RYML_DEPRECATED("use parse_in_arena() instead") void parse(csubstr filename, csubstr csrc, NodeRef node) { parse_in_arena(filename, csrc, node); }
260
261
/** @} */
262
263
public:
264
265
/** @name locations */
266
/** @{ */
267
268
/** Get the location of a node of the last tree to be parsed by this parser. */
269
Location location(Tree const& tree, size_t node_id) const;
270
/** Get the location of a node of the last tree to be parsed by this parser. */
271
Location location(ConstNodeRef node) const;
272
/** Get the string starting at a particular location, to the end
273
* of the parsed source buffer. */
274
csubstr location_contents(Location const& loc) const;
275
/** Given a pointer to a buffer position, get the location. @p val
276
* must be pointing to somewhere in the source buffer that was
277
* last parsed by this object. */
278
Location val_location(const char *val) const;
279
280
/** @} */
281
282
private:
283
284
typedef enum {
285
BLOCK_LITERAL, //!< keep newlines (|)
286
BLOCK_FOLD //!< replace newline with single space (>)
287
} BlockStyle_e;
288
289
typedef enum {
290
CHOMP_CLIP, //!< single newline at end (default)
291
CHOMP_STRIP, //!< no newline at end (-)
292
CHOMP_KEEP //!< all newlines from end (+)
293
} BlockChomp_e;
294
295
private:
296
297
using flag_t = int;
298
299
static size_t _estimate_capacity(csubstr src) { size_t c = _count_nlines(src); c = c >= 16 ? c : 16; return c; }
300
301
void _reset();
302
303
bool _finished_file() const;
304
bool _finished_line() const;
305
306
csubstr _peek_next_line(size_t pos=npos) const;
307
bool _advance_to_peeked();
308
void _scan_line();
309
310
csubstr _slurp_doc_scalar();
311
312
/**
313
* @param [out] quoted
314
* Will only be written to if this method returns true.
315
* Will be set to true if the scanned scalar was quoted, by '', "", > or |.
316
*/
317
bool _scan_scalar_seq_blck(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);
318
bool _scan_scalar_map_blck(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);
319
bool _scan_scalar_seq_flow(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);
320
bool _scan_scalar_map_flow(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);
321
bool _scan_scalar_unk(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);
322
323
csubstr _scan_comment();
324
csubstr _scan_squot_scalar();
325
csubstr _scan_dquot_scalar();
326
csubstr _scan_block();
327
substr _scan_plain_scalar_blck(csubstr currscalar, csubstr peeked_line, size_t indentation);
328
substr _scan_plain_scalar_flow(csubstr currscalar, csubstr peeked_line);
329
substr _scan_complex_key(csubstr currscalar, csubstr peeked_line);
330
csubstr _scan_to_next_nonempty_line(size_t indentation);
331
csubstr _extend_scanned_scalar(csubstr currscalar);
332
333
csubstr _filter_squot_scalar(const substr s);
334
csubstr _filter_dquot_scalar(substr s);
335
csubstr _filter_plain_scalar(substr s, size_t indentation);
336
csubstr _filter_block_scalar(substr s, BlockStyle_e style, BlockChomp_e chomp, size_t indentation);
337
template<bool backslash_is_escape, bool keep_trailing_whitespace>
338
bool _filter_nl(substr scalar, size_t *C4_RESTRICT pos, size_t *C4_RESTRICT filter_arena_pos, size_t indentation);
339
template<bool keep_trailing_whitespace>
340
void _filter_ws(substr scalar, size_t *C4_RESTRICT pos, size_t *C4_RESTRICT filter_arena_pos);
341
bool _apply_chomp(substr buf, size_t *C4_RESTRICT pos, BlockChomp_e chomp);
342
343
void _handle_finished_file();
344
void _handle_line();
345
346
bool _handle_indentation();
347
348
bool _handle_unk();
349
bool _handle_map_flow();
350
bool _handle_map_blck();
351
bool _handle_seq_flow();
352
bool _handle_seq_blck();
353
bool _handle_top();
354
bool _handle_types();
355
bool _handle_key_anchors_and_refs();
356
bool _handle_val_anchors_and_refs();
357
void _move_val_tag_to_key_tag();
358
void _move_key_tag_to_val_tag();
359
void _move_key_tag2_to_key_tag();
360
void _move_val_anchor_to_key_anchor();
361
void _move_key_anchor_to_val_anchor();
362
363
void _push_level(bool explicit_flow_chars = false);
364
void _pop_level();
365
366
void _start_unk(bool as_child=true);
367
368
void _start_map(bool as_child=true);
369
void _start_map_unk(bool as_child);
370
void _stop_map();
371
372
void _start_seq(bool as_child=true);
373
void _stop_seq();
374
375
void _start_seqimap();
376
void _stop_seqimap();
377
378
void _start_doc(bool as_child=true);
379
void _stop_doc();
380
void _start_new_doc(csubstr rem);
381
void _end_stream();
382
383
NodeData* _append_val(csubstr val, flag_t quoted=false);
384
NodeData* _append_key_val(csubstr val, flag_t val_quoted=false);
385
bool _rval_dash_start_or_continue_seq();
386
387
void _store_scalar(csubstr s, flag_t is_quoted);
388
csubstr _consume_scalar();
389
void _move_scalar_from_top();
390
391
inline NodeData* _append_val_null(const char *str) { _RYML_CB_ASSERT(m_stack.m_callbacks, str >= m_buf.begin() && str <= m_buf.end()); return _append_val({nullptr, size_t(0)}); }
392
inline NodeData* _append_key_val_null(const char *str) { _RYML_CB_ASSERT(m_stack.m_callbacks, str >= m_buf.begin() && str <= m_buf.end()); return _append_key_val({nullptr, size_t(0)}); }
393
inline void _store_scalar_null(const char *str) { _RYML_CB_ASSERT(m_stack.m_callbacks, str >= m_buf.begin() && str <= m_buf.end()); _store_scalar({nullptr, size_t(0)}, false); }
394
395
void _set_indentation(size_t behind);
396
void _save_indentation(size_t behind=0);
397
bool _maybe_set_indentation_from_anchor_or_tag();
398
399
void _write_key_anchor(size_t node_id);
400
void _write_val_anchor(size_t node_id);
401
402
void _handle_directive(csubstr directive);
403
404
void _skipchars(char c);
405
template<size_t N>
406
void _skipchars(const char (&chars)[N]);
407
408
private:
409
410
static size_t _count_nlines(csubstr src);
411
412
private:
413
414
typedef enum : flag_t {
415
RTOP = 0x01 << 0, ///< reading at top level
416
RUNK = 0x01 << 1, ///< reading an unknown: must determine whether scalar, map or seq
417
RMAP = 0x01 << 2, ///< reading a map
418
RSEQ = 0x01 << 3, ///< reading a seq
419
FLOW = 0x01 << 4, ///< reading is inside explicit flow chars: [] or {}
420
QMRK = 0x01 << 5, ///< reading an explicit key (`? key`)
421
RKEY = 0x01 << 6, ///< reading a scalar as key
422
RVAL = 0x01 << 7, ///< reading a scalar as val
423
RNXT = 0x01 << 8, ///< read next val or keyval
424
SSCL = 0x01 << 9, ///< there's a stored scalar
425
QSCL = 0x01 << 10, ///< stored scalar was quoted
426
RSET = 0x01 << 11, ///< the (implicit) map being read is a !!set. @see https://yaml.org/type/set.html
427
NDOC = 0x01 << 12, ///< no document mode. a document has ended and another has not started yet.
428
//! reading an implicit map nested in an explicit seq.
429
//! eg, {key: [key2: value2, key3: value3]}
430
//! is parsed as {key: [{key2: value2}, {key3: value3}]}
431
RSEQIMAP = 0x01 << 13,
432
} State_e;
433
434
struct LineContents
435
{
436
csubstr full; ///< the full line, including newlines on the right
437
csubstr stripped; ///< the stripped line, excluding newlines on the right
438
csubstr rem; ///< the stripped line remainder; initially starts at the first non-space character
439
size_t indentation; ///< the number of spaces on the beginning of the line
440
441
LineContents() : full(), stripped(), rem(), indentation() {}
442
443
void reset_with_next_line(csubstr buf, size_t pos);
444
445
void reset(csubstr full_, csubstr stripped_)
446
{
447
full = full_;
448
stripped = stripped_;
449
rem = stripped_;
450
// find the first column where the character is not a space
451
indentation = full.first_not_of(' ');
452
}
453
454
size_t current_col() const
455
{
456
return current_col(rem);
457
}
458
459
size_t current_col(csubstr s) const
460
{
461
RYML_ASSERT(s.str >= full.str);
462
RYML_ASSERT(full.is_super(s));
463
size_t col = static_cast<size_t>(s.str - full.str);
464
return col;
465
}
466
};
467
468
struct State
469
{
470
flag_t flags;
471
size_t level;
472
size_t node_id; // don't hold a pointer to the node as it will be relocated during tree resizes
473
csubstr scalar;
474
size_t scalar_col; // the column where the scalar (or its quotes) begin
475
476
Location pos;
477
LineContents line_contents;
478
size_t indref;
479
480
State() : flags(), level(), node_id(), scalar(), scalar_col(), pos(), line_contents(), indref() {}
481
482
void reset(const char *file, size_t node_id_)
483
{
484
flags = RUNK|RTOP;
485
level = 0;
486
pos.name = to_csubstr(file);
487
pos.offset = 0;
488
pos.line = 1;
489
pos.col = 1;
490
node_id = node_id_;
491
scalar_col = 0;
492
scalar.clear();
493
indref = 0;
494
}
495
};
496
497
void _line_progressed(size_t ahead);
498
void _line_ended();
499
void _line_ended_undo();
500
501
void _prepare_pop()
502
{
503
RYML_ASSERT(m_stack.size() > 1);
504
State const& curr = m_stack.top();
505
State & next = m_stack.top(1);
506
next.pos = curr.pos;
507
next.line_contents = curr.line_contents;
508
next.scalar = curr.scalar;
509
}
510
511
inline bool _at_line_begin() const
512
{
513
return m_state->line_contents.rem.begin() == m_state->line_contents.full.begin();
514
}
515
inline bool _at_line_end() const
516
{
517
csubstr r = m_state->line_contents.rem;
518
return r.empty() || r.begins_with(' ', r.len);
519
}
520
inline bool _token_is_from_this_line(csubstr token) const
521
{
522
return token.is_sub(m_state->line_contents.full);
523
}
524
525
inline NodeData * node(State const* s) const { return m_tree->get(s->node_id); }
526
inline NodeData * node(State const& s) const { return m_tree->get(s .node_id); }
527
inline NodeData * node(size_t node_id) const { return m_tree->get( node_id); }
528
529
inline bool has_all(flag_t f) const { return (m_state->flags & f) == f; }
530
inline bool has_any(flag_t f) const { return (m_state->flags & f) != 0; }
531
inline bool has_none(flag_t f) const { return (m_state->flags & f) == 0; }
532
533
static inline bool has_all(flag_t f, State const* s) { return (s->flags & f) == f; }
534
static inline bool has_any(flag_t f, State const* s) { return (s->flags & f) != 0; }
535
static inline bool has_none(flag_t f, State const* s) { return (s->flags & f) == 0; }
536
537
inline void set_flags(flag_t f) { set_flags(f, m_state); }
538
inline void add_flags(flag_t on) { add_flags(on, m_state); }
539
inline void addrem_flags(flag_t on, flag_t off) { addrem_flags(on, off, m_state); }
540
inline void rem_flags(flag_t off) { rem_flags(off, m_state); }
541
542
void set_flags(flag_t f, State * s);
543
void add_flags(flag_t on, State * s);
544
void addrem_flags(flag_t on, flag_t off, State * s);
545
void rem_flags(flag_t off, State * s);
546
547
void _resize_filter_arena(size_t num_characters);
548
void _grow_filter_arena(size_t num_characters);
549
substr _finish_filter_arena(substr dst, size_t pos);
550
551
void _prepare_locations();
552
void _resize_locations(size_t sz);
553
bool _locations_dirty() const;
554
555
bool _location_from_cont(Tree const& tree, size_t node, Location *C4_RESTRICT loc) const;
556
bool _location_from_node(Tree const& tree, size_t node, Location *C4_RESTRICT loc, size_t level) const;
557
558
private:
559
560
void _free();
561
void _clr();
562
void _cp(Parser const* that);
563
void _mv(Parser *that);
564
565
#ifdef RYML_DBG
566
template<class ...Args> void _dbg(csubstr fmt, Args const& C4_RESTRICT ...args) const;
567
#endif
568
template<class ...Args> void _err(csubstr fmt, Args const& C4_RESTRICT ...args) const;
569
template<class DumpFn> void _fmt_msg(DumpFn &&dumpfn) const;
570
static csubstr _prfl(substr buf, flag_t v);
571
572
private:
573
574
ParserOptions m_options;
575
576
csubstr m_file;
577
substr m_buf;
578
579
size_t m_root_id;
580
Tree * m_tree;
581
582
detail::stack<State> m_stack;
583
State * m_state;
584
585
size_t m_key_tag_indentation;
586
size_t m_key_tag2_indentation;
587
csubstr m_key_tag;
588
csubstr m_key_tag2;
589
size_t m_val_tag_indentation;
590
csubstr m_val_tag;
591
592
bool m_key_anchor_was_before;
593
size_t m_key_anchor_indentation;
594
csubstr m_key_anchor;
595
size_t m_val_anchor_indentation;
596
csubstr m_val_anchor;
597
598
substr m_filter_arena;
599
600
size_t *m_newline_offsets;
601
size_t m_newline_offsets_size;
602
size_t m_newline_offsets_capacity;
603
csubstr m_newline_offsets_buf;
604
};
605
606
607
//-----------------------------------------------------------------------------
608
//-----------------------------------------------------------------------------
609
//-----------------------------------------------------------------------------
610
611
/** @name parse_in_place
612
*
613
* @desc parse a mutable YAML source buffer.
614
*
615
* @note These freestanding functions use a temporary parser object,
616
* and are convenience functions to easily parse YAML without the need
617
* to instantiate a separate parser. Note that some properties
618
* (notably node locations in the original source code) are only
619
* available through the parser object after it has parsed the
620
* code. If you need access to any of these properties, use
621
* Parser::parse_in_place() */
622
/** @{ */
623
624
inline Tree parse_in_place( substr yaml ) { Parser np; return np.parse_in_place({} , yaml); } //!< parse in-situ a modifiable YAML source buffer.
625
inline Tree parse_in_place(csubstr filename, substr yaml ) { Parser np; return np.parse_in_place(filename, yaml); } //!< parse in-situ a modifiable YAML source buffer, providing a filename for error messages.
626
inline void parse_in_place( substr yaml, Tree *t ) { Parser np; np.parse_in_place({} , yaml, t); } //!< reusing the YAML tree, parse in-situ a modifiable YAML source buffer
627
inline void parse_in_place(csubstr filename, substr yaml, Tree *t ) { Parser np; np.parse_in_place(filename, yaml, t); } //!< reusing the YAML tree, parse in-situ a modifiable YAML source buffer, providing a filename for error messages.
628
inline void parse_in_place( substr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_place({} , yaml, t, node_id); } //!< reusing the YAML tree, parse in-situ a modifiable YAML source buffer
629
inline void parse_in_place(csubstr filename, substr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_place(filename, yaml, t, node_id); } //!< reusing the YAML tree, parse in-situ a modifiable YAML source buffer, providing a filename for error messages.
630
inline void parse_in_place( substr yaml, NodeRef node ) { Parser np; np.parse_in_place({} , yaml, node); } //!< reusing the YAML tree, parse in-situ a modifiable YAML source buffer
631
inline void parse_in_place(csubstr filename, substr yaml, NodeRef node ) { Parser np; np.parse_in_place(filename, yaml, node); } //!< reusing the YAML tree, parse in-situ a modifiable YAML source buffer, providing a filename for error messages.
632
633
RYML_DEPRECATED("use parse_in_place() instead") inline Tree parse( substr yaml ) { Parser np; return np.parse_in_place({} , yaml); }
634
RYML_DEPRECATED("use parse_in_place() instead") inline Tree parse(csubstr filename, substr yaml ) { Parser np; return np.parse_in_place(filename, yaml); }
635
RYML_DEPRECATED("use parse_in_place() instead") inline void parse( substr yaml, Tree *t ) { Parser np; np.parse_in_place({} , yaml, t); }
636
RYML_DEPRECATED("use parse_in_place() instead") inline void parse(csubstr filename, substr yaml, Tree *t ) { Parser np; np.parse_in_place(filename, yaml, t); }
637
RYML_DEPRECATED("use parse_in_place() instead") inline void parse( substr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_place({} , yaml, t, node_id); }
638
RYML_DEPRECATED("use parse_in_place() instead") inline void parse(csubstr filename, substr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_place(filename, yaml, t, node_id); }
639
RYML_DEPRECATED("use parse_in_place() instead") inline void parse( substr yaml, NodeRef node ) { Parser np; np.parse_in_place({} , yaml, node); }
640
RYML_DEPRECATED("use parse_in_place() instead") inline void parse(csubstr filename, substr yaml, NodeRef node ) { Parser np; np.parse_in_place(filename, yaml, node); }
641
642
/** @} */
643
644
645
//-----------------------------------------------------------------------------
646
647
/** @name parse_in_arena
648
* @desc parse a read-only YAML source buffer, copying it first to the tree's arena.
649
*
650
* @note These freestanding functions use a temporary parser object,
651
* and are convenience functions to easily parse YAML without the need
652
* to instantiate a separate parser. Note that some properties
653
* (notably node locations in the original source code) are only
654
* available through the parser object after it has parsed the
655
* code. If you need access to any of these properties, use
656
* Parser::parse_in_arena().
657
*
658
* @note overloads receiving a substr YAML buffer are intentionally
659
* left undefined, such that calling parse_in_arena() with a substr
660
* will cause a linker error. This is to prevent an accidental
661
* copy of the source buffer to the tree's arena, because substr
662
* is implicitly convertible to csubstr. If you really intend to parse
663
* a mutable buffer in the tree's arena, convert it first to immutable
664
* by assigning the substr to a csubstr prior to calling parse_in_arena().
665
* This is not needed for parse_in_place() because csubstr is not
666
* implicitly convertible to substr. */
667
/** @{ */
668
669
/* READ THE NOTE ABOVE! */
670
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) Tree parse_in_arena( substr yaml );
671
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) Tree parse_in_arena(csubstr filename, substr yaml );
672
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena( substr yaml, Tree *t );
673
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr yaml, Tree *t );
674
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena( substr yaml, Tree *t, size_t node_id);
675
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr yaml, Tree *t, size_t node_id);
676
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena( substr yaml, NodeRef node );
677
RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr yaml, NodeRef node );
678
679
inline Tree parse_in_arena( csubstr yaml ) { Parser np; return np.parse_in_arena({} , yaml); } //!< parse a read-only YAML source buffer, copying it first to the tree's source arena.
680
inline Tree parse_in_arena(csubstr filename, csubstr yaml ) { Parser np; return np.parse_in_arena(filename, yaml); } //!< parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
681
inline void parse_in_arena( csubstr yaml, Tree *t ) { Parser np; np.parse_in_arena({} , yaml, t); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena.
682
inline void parse_in_arena(csubstr filename, csubstr yaml, Tree *t ) { Parser np; np.parse_in_arena(filename, yaml, t); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
683
inline void parse_in_arena( csubstr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_arena({} , yaml, t, node_id); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena.
684
inline void parse_in_arena(csubstr filename, csubstr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_arena(filename, yaml, t, node_id); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
685
inline void parse_in_arena( csubstr yaml, NodeRef node ) { Parser np; np.parse_in_arena({} , yaml, node); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena.
686
inline void parse_in_arena(csubstr filename, csubstr yaml, NodeRef node ) { Parser np; np.parse_in_arena(filename, yaml, node); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
687
688
RYML_DEPRECATED("use parse_in_arena() instead") inline Tree parse( csubstr yaml ) { Parser np; return np.parse_in_arena({} , yaml); } //!< parse a read-only YAML source buffer, copying it first to the tree's source arena.
689
RYML_DEPRECATED("use parse_in_arena() instead") inline Tree parse(csubstr filename, csubstr yaml ) { Parser np; return np.parse_in_arena(filename, yaml); } //!< parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
690
RYML_DEPRECATED("use parse_in_arena() instead") inline void parse( csubstr yaml, Tree *t ) { Parser np; np.parse_in_arena({} , yaml, t); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena.
691
RYML_DEPRECATED("use parse_in_arena() instead") inline void parse(csubstr filename, csubstr yaml, Tree *t ) { Parser np; np.parse_in_arena(filename, yaml, t); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
692
RYML_DEPRECATED("use parse_in_arena() instead") inline void parse( csubstr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_arena({} , yaml, t, node_id); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena.
693
RYML_DEPRECATED("use parse_in_arena() instead") inline void parse(csubstr filename, csubstr yaml, Tree *t, size_t node_id) { Parser np; np.parse_in_arena(filename, yaml, t, node_id); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
694
RYML_DEPRECATED("use parse_in_arena() instead") inline void parse( csubstr yaml, NodeRef node ) { Parser np; np.parse_in_arena({} , yaml, node); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena.
695
RYML_DEPRECATED("use parse_in_arena() instead") inline void parse(csubstr filename, csubstr yaml, NodeRef node ) { Parser np; np.parse_in_arena(filename, yaml, node); } //!< reusing the YAML tree, parse a read-only YAML source buffer, copying it first to the tree's source arena, providing a filename for error messages.
696
697
/** @} */
698
699
} // namespace yml
700
} // namespace c4
701
702
#if defined(_MSC_VER)
703
# pragma warning(pop)
704
#endif
705
706
#endif /* _C4_YML_PARSE_HPP_ */
707
708