Path: blob/master/dep/rapidyaml/include/c4/yml/parse.hpp
4264 views
#ifndef _C4_YML_PARSE_HPP_1#define _C4_YML_PARSE_HPP_23#ifndef _C4_YML_TREE_HPP_4#include "c4/yml/tree.hpp"5#endif67#ifndef _C4_YML_NODE_HPP_8#include "c4/yml/node.hpp"9#endif1011#ifndef _C4_YML_DETAIL_STACK_HPP_12#include "c4/yml/detail/stack.hpp"13#endif1415#include <stdarg.h>1617#if defined(_MSC_VER)18# pragma warning(push)19# pragma warning(disable: 4251/*needs to have dll-interface to be used by clients of struct*/)20#endif2122namespace c4 {23namespace yml {2425struct RYML_EXPORT ParserOptions26{27private:2829typedef enum : uint32_t {30LOCATIONS = (1 << 0),31DEFAULTS = 0,32} Flags_e;3334uint32_t flags = DEFAULTS;35public:36ParserOptions() = default;3738/** @name source location tracking */39/** @{ */4041/** enable/disable source location tracking */42ParserOptions& locations(bool enabled)43{44if(enabled)45flags |= LOCATIONS;46else47flags &= ~LOCATIONS;48return *this;49}50bool locations() const { return (flags & LOCATIONS) != 0u; }5152/** @} */53};545556//-----------------------------------------------------------------------------57//-----------------------------------------------------------------------------58//-----------------------------------------------------------------------------59class RYML_EXPORT Parser60{61public:6263/** @name construction and assignment */64/** @{ */6566Parser(Callbacks const& cb, ParserOptions opts={});67Parser(ParserOptions opts={}) : Parser(get_callbacks(), opts) {}68~Parser();6970Parser(Parser &&);71Parser(Parser const&);72Parser& operator=(Parser &&);73Parser& operator=(Parser const&);7475/** @} */7677public:7879/** @name modifiers */80/** @{ */8182/** Reserve a certain capacity for the parsing stack.83* This should be larger than the expected depth of the parsed84* YAML tree.85*86* The parsing stack is the only (potential) heap memory used by87* the parser.88*89* If the requested capacity is below the default90* stack size of 16, the memory is used directly in the parser91* object; otherwise it will be allocated from the heap.92*93* @note this reserves memory only for the parser itself; all the94* allocations for the parsed tree will go through the tree's95* allocator.96*97* @note the tree and the arena can (and should) also be reserved. */98void reserve_stack(size_t capacity)99{100m_stack.reserve(capacity);101}102103/** Reserve a certain capacity for the array used to track node104* locations in the source buffer. */105void reserve_locations(size_t num_source_lines)106{107_resize_locations(num_source_lines);108}109110/** Reserve a certain capacity for the character arena used to111* filter scalars. */112void reserve_filter_arena(size_t num_characters)113{114_resize_filter_arena(num_characters);115}116117/** @} */118119public:120121/** @name getters and modifiers */122/** @{ */123124/** Get the current callbacks in the parser. */125Callbacks callbacks() const { return m_stack.m_callbacks; }126127/** Get the name of the latest file parsed by this object. */128csubstr filename() const { return m_file; }129130/** Get the latest YAML buffer parsed by this object. */131csubstr source() const { return m_buf; }132133size_t stack_capacity() const { return m_stack.capacity(); }134size_t locations_capacity() const { return m_newline_offsets_capacity; }135size_t filter_arena_capacity() const { return m_filter_arena.len; }136137ParserOptions const& options() const { return m_options; }138139/** @} */140141public:142143/** @name parse_in_place */144/** @{ */145146/** Create a new tree and parse into its root.147* The tree is created with the callbacks currently in the parser. */148Tree parse_in_place(csubstr filename, substr src)149{150Tree t(callbacks());151t.reserve(_estimate_capacity(src));152this->parse_in_place(filename, src, &t, t.root_id());153return t;154}155156/** Parse into an existing tree, starting at its root node.157* The callbacks in the tree are kept, and used to allocate158* the tree members, if any allocation is required. */159void parse_in_place(csubstr filename, substr src, Tree *t)160{161this->parse_in_place(filename, src, t, t->root_id());162}163164/** Parse into an existing node.165* The callbacks in the tree are kept, and used to allocate166* the tree members, if any allocation is required. */167void parse_in_place(csubstr filename, substr src, Tree *t, size_t node_id);168// ^^^^^^^^^^^^^ this is the workhorse overload; everything else is syntactic candy169170/** Parse into an existing node.171* The callbacks in the tree are kept, and used to allocate172* the tree members, if any allocation is required. */173void parse_in_place(csubstr filename, substr src, NodeRef node)174{175this->parse_in_place(filename, src, node.tree(), node.id());176}177178RYML_DEPRECATED("use parse_in_place() instead") Tree parse(csubstr filename, substr src) { return parse_in_place(filename, src); }179RYML_DEPRECATED("use parse_in_place() instead") void parse(csubstr filename, substr src, Tree *t) { parse_in_place(filename, src, t); }180RYML_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); }181RYML_DEPRECATED("use parse_in_place() instead") void parse(csubstr filename, substr src, NodeRef node) { parse_in_place(filename, src, node); }182183/** @} */184185public:186187/** @name parse_in_arena: copy the YAML source buffer to the188* tree's arena, then parse the copy in situ189*190* @note overloads receiving a substr YAML buffer are intentionally191* left undefined, such that calling parse_in_arena() with a substr192* will cause a linker error. This is to prevent an accidental193* copy of the source buffer to the tree's arena, because substr194* is implicitly convertible to csubstr. If you really intend to parse195* a mutable buffer in the tree's arena, convert it first to immutable196* by assigning the substr to a csubstr prior to calling parse_in_arena().197* This is not needed for parse_in_place() because csubstr is not198* implicitly convertible to substr. */199/** @{ */200201// READ THE NOTE ABOVE!202#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."203RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) Tree parse_in_arena(csubstr filename, substr csrc);204RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr csrc, Tree *t);205RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr csrc, Tree *t, size_t node_id);206RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr csrc, NodeRef node);207208/** Create a new tree and parse into its root.209* The immutable YAML source is first copied to the tree's arena,210* and parsed from there.211* The callbacks in the tree are kept, and used to allocate212* the tree members, if any allocation is required. */213Tree parse_in_arena(csubstr filename, csubstr csrc)214{215Tree t(callbacks());216substr src = t.copy_to_arena(csrc);217t.reserve(_estimate_capacity(csrc));218this->parse_in_place(filename, src, &t, t.root_id());219return t;220}221222/** Parse into an existing tree, starting at its root node.223* The immutable YAML source is first copied to the tree's arena,224* and parsed from there.225* The callbacks in the tree are kept, and used to allocate226* the tree members, if any allocation is required. */227void parse_in_arena(csubstr filename, csubstr csrc, Tree *t)228{229substr src = t->copy_to_arena(csrc);230this->parse_in_place(filename, src, t, t->root_id());231}232233/** Parse into a specific node in an existing tree.234* The immutable YAML source is first copied to the tree's arena,235* and parsed from there.236* The callbacks in the tree are kept, and used to allocate237* the tree members, if any allocation is required. */238void parse_in_arena(csubstr filename, csubstr csrc, Tree *t, size_t node_id)239{240substr src = t->copy_to_arena(csrc);241this->parse_in_place(filename, src, t, node_id);242}243244/** Parse into a specific node in an existing tree.245* The immutable YAML source is first copied to the tree's arena,246* and parsed from there.247* The callbacks in the tree are kept, and used to allocate248* the tree members, if any allocation is required. */249void parse_in_arena(csubstr filename, csubstr csrc, NodeRef node)250{251substr src = node.tree()->copy_to_arena(csrc);252this->parse_in_place(filename, src, node.tree(), node.id());253}254255RYML_DEPRECATED("use parse_in_arena() instead") Tree parse(csubstr filename, csubstr csrc) { return parse_in_arena(filename, csrc); }256RYML_DEPRECATED("use parse_in_arena() instead") void parse(csubstr filename, csubstr csrc, Tree *t) { parse_in_arena(filename, csrc, t); }257RYML_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); }258RYML_DEPRECATED("use parse_in_arena() instead") void parse(csubstr filename, csubstr csrc, NodeRef node) { parse_in_arena(filename, csrc, node); }259260/** @} */261262public:263264/** @name locations */265/** @{ */266267/** Get the location of a node of the last tree to be parsed by this parser. */268Location location(Tree const& tree, size_t node_id) const;269/** Get the location of a node of the last tree to be parsed by this parser. */270Location location(ConstNodeRef node) const;271/** Get the string starting at a particular location, to the end272* of the parsed source buffer. */273csubstr location_contents(Location const& loc) const;274/** Given a pointer to a buffer position, get the location. @p val275* must be pointing to somewhere in the source buffer that was276* last parsed by this object. */277Location val_location(const char *val) const;278279/** @} */280281private:282283typedef enum {284BLOCK_LITERAL, //!< keep newlines (|)285BLOCK_FOLD //!< replace newline with single space (>)286} BlockStyle_e;287288typedef enum {289CHOMP_CLIP, //!< single newline at end (default)290CHOMP_STRIP, //!< no newline at end (-)291CHOMP_KEEP //!< all newlines from end (+)292} BlockChomp_e;293294private:295296using flag_t = int;297298static size_t _estimate_capacity(csubstr src) { size_t c = _count_nlines(src); c = c >= 16 ? c : 16; return c; }299300void _reset();301302bool _finished_file() const;303bool _finished_line() const;304305csubstr _peek_next_line(size_t pos=npos) const;306bool _advance_to_peeked();307void _scan_line();308309csubstr _slurp_doc_scalar();310311/**312* @param [out] quoted313* Will only be written to if this method returns true.314* Will be set to true if the scanned scalar was quoted, by '', "", > or |.315*/316bool _scan_scalar_seq_blck(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);317bool _scan_scalar_map_blck(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);318bool _scan_scalar_seq_flow(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);319bool _scan_scalar_map_flow(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);320bool _scan_scalar_unk(csubstr *C4_RESTRICT scalar, bool *C4_RESTRICT quoted);321322csubstr _scan_comment();323csubstr _scan_squot_scalar();324csubstr _scan_dquot_scalar();325csubstr _scan_block();326substr _scan_plain_scalar_blck(csubstr currscalar, csubstr peeked_line, size_t indentation);327substr _scan_plain_scalar_flow(csubstr currscalar, csubstr peeked_line);328substr _scan_complex_key(csubstr currscalar, csubstr peeked_line);329csubstr _scan_to_next_nonempty_line(size_t indentation);330csubstr _extend_scanned_scalar(csubstr currscalar);331332csubstr _filter_squot_scalar(const substr s);333csubstr _filter_dquot_scalar(substr s);334csubstr _filter_plain_scalar(substr s, size_t indentation);335csubstr _filter_block_scalar(substr s, BlockStyle_e style, BlockChomp_e chomp, size_t indentation);336template<bool backslash_is_escape, bool keep_trailing_whitespace>337bool _filter_nl(substr scalar, size_t *C4_RESTRICT pos, size_t *C4_RESTRICT filter_arena_pos, size_t indentation);338template<bool keep_trailing_whitespace>339void _filter_ws(substr scalar, size_t *C4_RESTRICT pos, size_t *C4_RESTRICT filter_arena_pos);340bool _apply_chomp(substr buf, size_t *C4_RESTRICT pos, BlockChomp_e chomp);341342void _handle_finished_file();343void _handle_line();344345bool _handle_indentation();346347bool _handle_unk();348bool _handle_map_flow();349bool _handle_map_blck();350bool _handle_seq_flow();351bool _handle_seq_blck();352bool _handle_top();353bool _handle_types();354bool _handle_key_anchors_and_refs();355bool _handle_val_anchors_and_refs();356void _move_val_tag_to_key_tag();357void _move_key_tag_to_val_tag();358void _move_key_tag2_to_key_tag();359void _move_val_anchor_to_key_anchor();360void _move_key_anchor_to_val_anchor();361362void _push_level(bool explicit_flow_chars = false);363void _pop_level();364365void _start_unk(bool as_child=true);366367void _start_map(bool as_child=true);368void _start_map_unk(bool as_child);369void _stop_map();370371void _start_seq(bool as_child=true);372void _stop_seq();373374void _start_seqimap();375void _stop_seqimap();376377void _start_doc(bool as_child=true);378void _stop_doc();379void _start_new_doc(csubstr rem);380void _end_stream();381382NodeData* _append_val(csubstr val, flag_t quoted=false);383NodeData* _append_key_val(csubstr val, flag_t val_quoted=false);384bool _rval_dash_start_or_continue_seq();385386void _store_scalar(csubstr s, flag_t is_quoted);387csubstr _consume_scalar();388void _move_scalar_from_top();389390inline 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)}); }391inline 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)}); }392inline 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); }393394void _set_indentation(size_t behind);395void _save_indentation(size_t behind=0);396bool _maybe_set_indentation_from_anchor_or_tag();397398void _write_key_anchor(size_t node_id);399void _write_val_anchor(size_t node_id);400401void _handle_directive(csubstr directive);402403void _skipchars(char c);404template<size_t N>405void _skipchars(const char (&chars)[N]);406407private:408409static size_t _count_nlines(csubstr src);410411private:412413typedef enum : flag_t {414RTOP = 0x01 << 0, ///< reading at top level415RUNK = 0x01 << 1, ///< reading an unknown: must determine whether scalar, map or seq416RMAP = 0x01 << 2, ///< reading a map417RSEQ = 0x01 << 3, ///< reading a seq418FLOW = 0x01 << 4, ///< reading is inside explicit flow chars: [] or {}419QMRK = 0x01 << 5, ///< reading an explicit key (`? key`)420RKEY = 0x01 << 6, ///< reading a scalar as key421RVAL = 0x01 << 7, ///< reading a scalar as val422RNXT = 0x01 << 8, ///< read next val or keyval423SSCL = 0x01 << 9, ///< there's a stored scalar424QSCL = 0x01 << 10, ///< stored scalar was quoted425RSET = 0x01 << 11, ///< the (implicit) map being read is a !!set. @see https://yaml.org/type/set.html426NDOC = 0x01 << 12, ///< no document mode. a document has ended and another has not started yet.427//! reading an implicit map nested in an explicit seq.428//! eg, {key: [key2: value2, key3: value3]}429//! is parsed as {key: [{key2: value2}, {key3: value3}]}430RSEQIMAP = 0x01 << 13,431} State_e;432433struct LineContents434{435csubstr full; ///< the full line, including newlines on the right436csubstr stripped; ///< the stripped line, excluding newlines on the right437csubstr rem; ///< the stripped line remainder; initially starts at the first non-space character438size_t indentation; ///< the number of spaces on the beginning of the line439440LineContents() : full(), stripped(), rem(), indentation() {}441442void reset_with_next_line(csubstr buf, size_t pos);443444void reset(csubstr full_, csubstr stripped_)445{446full = full_;447stripped = stripped_;448rem = stripped_;449// find the first column where the character is not a space450indentation = full.first_not_of(' ');451}452453size_t current_col() const454{455return current_col(rem);456}457458size_t current_col(csubstr s) const459{460RYML_ASSERT(s.str >= full.str);461RYML_ASSERT(full.is_super(s));462size_t col = static_cast<size_t>(s.str - full.str);463return col;464}465};466467struct State468{469flag_t flags;470size_t level;471size_t node_id; // don't hold a pointer to the node as it will be relocated during tree resizes472csubstr scalar;473size_t scalar_col; // the column where the scalar (or its quotes) begin474475Location pos;476LineContents line_contents;477size_t indref;478479State() : flags(), level(), node_id(), scalar(), scalar_col(), pos(), line_contents(), indref() {}480481void reset(const char *file, size_t node_id_)482{483flags = RUNK|RTOP;484level = 0;485pos.name = to_csubstr(file);486pos.offset = 0;487pos.line = 1;488pos.col = 1;489node_id = node_id_;490scalar_col = 0;491scalar.clear();492indref = 0;493}494};495496void _line_progressed(size_t ahead);497void _line_ended();498void _line_ended_undo();499500void _prepare_pop()501{502RYML_ASSERT(m_stack.size() > 1);503State const& curr = m_stack.top();504State & next = m_stack.top(1);505next.pos = curr.pos;506next.line_contents = curr.line_contents;507next.scalar = curr.scalar;508}509510inline bool _at_line_begin() const511{512return m_state->line_contents.rem.begin() == m_state->line_contents.full.begin();513}514inline bool _at_line_end() const515{516csubstr r = m_state->line_contents.rem;517return r.empty() || r.begins_with(' ', r.len);518}519inline bool _token_is_from_this_line(csubstr token) const520{521return token.is_sub(m_state->line_contents.full);522}523524inline NodeData * node(State const* s) const { return m_tree->get(s->node_id); }525inline NodeData * node(State const& s) const { return m_tree->get(s .node_id); }526inline NodeData * node(size_t node_id) const { return m_tree->get( node_id); }527528inline bool has_all(flag_t f) const { return (m_state->flags & f) == f; }529inline bool has_any(flag_t f) const { return (m_state->flags & f) != 0; }530inline bool has_none(flag_t f) const { return (m_state->flags & f) == 0; }531532static inline bool has_all(flag_t f, State const* s) { return (s->flags & f) == f; }533static inline bool has_any(flag_t f, State const* s) { return (s->flags & f) != 0; }534static inline bool has_none(flag_t f, State const* s) { return (s->flags & f) == 0; }535536inline void set_flags(flag_t f) { set_flags(f, m_state); }537inline void add_flags(flag_t on) { add_flags(on, m_state); }538inline void addrem_flags(flag_t on, flag_t off) { addrem_flags(on, off, m_state); }539inline void rem_flags(flag_t off) { rem_flags(off, m_state); }540541void set_flags(flag_t f, State * s);542void add_flags(flag_t on, State * s);543void addrem_flags(flag_t on, flag_t off, State * s);544void rem_flags(flag_t off, State * s);545546void _resize_filter_arena(size_t num_characters);547void _grow_filter_arena(size_t num_characters);548substr _finish_filter_arena(substr dst, size_t pos);549550void _prepare_locations();551void _resize_locations(size_t sz);552bool _locations_dirty() const;553554bool _location_from_cont(Tree const& tree, size_t node, Location *C4_RESTRICT loc) const;555bool _location_from_node(Tree const& tree, size_t node, Location *C4_RESTRICT loc, size_t level) const;556557private:558559void _free();560void _clr();561void _cp(Parser const* that);562void _mv(Parser *that);563564#ifdef RYML_DBG565template<class ...Args> void _dbg(csubstr fmt, Args const& C4_RESTRICT ...args) const;566#endif567template<class ...Args> void _err(csubstr fmt, Args const& C4_RESTRICT ...args) const;568template<class DumpFn> void _fmt_msg(DumpFn &&dumpfn) const;569static csubstr _prfl(substr buf, flag_t v);570571private:572573ParserOptions m_options;574575csubstr m_file;576substr m_buf;577578size_t m_root_id;579Tree * m_tree;580581detail::stack<State> m_stack;582State * m_state;583584size_t m_key_tag_indentation;585size_t m_key_tag2_indentation;586csubstr m_key_tag;587csubstr m_key_tag2;588size_t m_val_tag_indentation;589csubstr m_val_tag;590591bool m_key_anchor_was_before;592size_t m_key_anchor_indentation;593csubstr m_key_anchor;594size_t m_val_anchor_indentation;595csubstr m_val_anchor;596597substr m_filter_arena;598599size_t *m_newline_offsets;600size_t m_newline_offsets_size;601size_t m_newline_offsets_capacity;602csubstr m_newline_offsets_buf;603};604605606//-----------------------------------------------------------------------------607//-----------------------------------------------------------------------------608//-----------------------------------------------------------------------------609610/** @name parse_in_place611*612* @desc parse a mutable YAML source buffer.613*614* @note These freestanding functions use a temporary parser object,615* and are convenience functions to easily parse YAML without the need616* to instantiate a separate parser. Note that some properties617* (notably node locations in the original source code) are only618* available through the parser object after it has parsed the619* code. If you need access to any of these properties, use620* Parser::parse_in_place() */621/** @{ */622623inline Tree parse_in_place( substr yaml ) { Parser np; return np.parse_in_place({} , yaml); } //!< parse in-situ a modifiable YAML source buffer.624inline 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.625inline 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 buffer626inline 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.627inline 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 buffer628inline 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.629inline 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 buffer630inline 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.631632RYML_DEPRECATED("use parse_in_place() instead") inline Tree parse( substr yaml ) { Parser np; return np.parse_in_place({} , yaml); }633RYML_DEPRECATED("use parse_in_place() instead") inline Tree parse(csubstr filename, substr yaml ) { Parser np; return np.parse_in_place(filename, yaml); }634RYML_DEPRECATED("use parse_in_place() instead") inline void parse( substr yaml, Tree *t ) { Parser np; np.parse_in_place({} , yaml, t); }635RYML_DEPRECATED("use parse_in_place() instead") inline void parse(csubstr filename, substr yaml, Tree *t ) { Parser np; np.parse_in_place(filename, yaml, t); }636RYML_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); }637RYML_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); }638RYML_DEPRECATED("use parse_in_place() instead") inline void parse( substr yaml, NodeRef node ) { Parser np; np.parse_in_place({} , yaml, node); }639RYML_DEPRECATED("use parse_in_place() instead") inline void parse(csubstr filename, substr yaml, NodeRef node ) { Parser np; np.parse_in_place(filename, yaml, node); }640641/** @} */642643644//-----------------------------------------------------------------------------645646/** @name parse_in_arena647* @desc parse a read-only YAML source buffer, copying it first to the tree's arena.648*649* @note These freestanding functions use a temporary parser object,650* and are convenience functions to easily parse YAML without the need651* to instantiate a separate parser. Note that some properties652* (notably node locations in the original source code) are only653* available through the parser object after it has parsed the654* code. If you need access to any of these properties, use655* Parser::parse_in_arena().656*657* @note overloads receiving a substr YAML buffer are intentionally658* left undefined, such that calling parse_in_arena() with a substr659* will cause a linker error. This is to prevent an accidental660* copy of the source buffer to the tree's arena, because substr661* is implicitly convertible to csubstr. If you really intend to parse662* a mutable buffer in the tree's arena, convert it first to immutable663* by assigning the substr to a csubstr prior to calling parse_in_arena().664* This is not needed for parse_in_place() because csubstr is not665* implicitly convertible to substr. */666/** @{ */667668/* READ THE NOTE ABOVE! */669RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) Tree parse_in_arena( substr yaml );670RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) Tree parse_in_arena(csubstr filename, substr yaml );671RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena( substr yaml, Tree *t );672RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr yaml, Tree *t );673RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena( substr yaml, Tree *t, size_t node_id);674RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr yaml, Tree *t, size_t node_id);675RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena( substr yaml, NodeRef node );676RYML_DEPRECATED(RYML_DONT_PARSE_SUBSTR_IN_ARENA) void parse_in_arena(csubstr filename, substr yaml, NodeRef node );677678inline 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.679inline 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.680inline 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.681inline 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.682inline 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.683inline 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.684inline 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.685inline 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.686687RYML_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.688RYML_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.689RYML_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.690RYML_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.691RYML_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.692RYML_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.693RYML_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.694RYML_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.695696/** @} */697698} // namespace yml699} // namespace c4700701#if defined(_MSC_VER)702# pragma warning(pop)703#endif704705#endif /* _C4_YML_PARSE_HPP_ */706707708