/* * fy-parse.h - YAML parser internal header file * * Copyright (c) 2019 Pantelis Antoniou * * SPDX-License-Identifier: MIT */ #ifndef FY_PARSE_H #define FY_PARSE_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "fy-ctype.h" #include "fy-utf8.h" #include "fy-list.h" #include "fy-typelist.h" #include "fy-types.h" #include "fy-diag.h" #include "fy-dump.h" #include "fy-atom.h" #include "fy-input.h" #include "fy-ctype.h" #include "fy-token.h" #include "fy-event.h" #include "fy-docstate.h" #include "fy-doc.h" #include "fy-docbuilder.h" #include "fy-emit.h" #include "fy-accel.h" #include "fy-emit-accum.h" #include "fy-path.h" #include "fy-composer.h" struct fy_parser; struct fy_input; /* for the event */ FY_PARSE_TYPE_DECL_ALLOC(eventp); enum fy_flow_type { FYFT_NONE, FYFT_MAP, FYFT_SEQUENCE, }; struct fy_flow { struct list_head node; enum fy_flow_type flow; int pending_complex_key_column; struct fy_mark pending_complex_key_mark; int parent_indent; }; FY_PARSE_TYPE_DECL(flow); struct fy_indent { struct list_head node; int indent; int indent_line; bool generated_block_map : 1; }; FY_PARSE_TYPE_DECL(indent); struct fy_token; struct fy_simple_key { struct list_head node; struct fy_mark mark; struct fy_mark end_mark; struct fy_token *token; /* associated token */ int flow_level; bool required : 1; bool implicit_complex : 1; }; FY_PARSE_TYPE_DECL(simple_key); struct fy_document_state; enum fy_parser_state { /** none state */ FYPS_NONE, /** Expect STREAM-START. */ FYPS_STREAM_START, /** Expect the beginning of an implicit document. */ FYPS_IMPLICIT_DOCUMENT_START, /** Expect DOCUMENT-START. */ FYPS_DOCUMENT_START, /** Expect the content of a document. */ FYPS_DOCUMENT_CONTENT, /** Expect DOCUMENT-END. */ FYPS_DOCUMENT_END, /** Expect a block node. */ FYPS_BLOCK_NODE, /** Expect the first entry of a block sequence. */ FYPS_BLOCK_SEQUENCE_FIRST_ENTRY, /** Expect an entry of a block sequence. */ FYPS_BLOCK_SEQUENCE_ENTRY, /** Expect an entry of an indentless sequence. */ FYPS_INDENTLESS_SEQUENCE_ENTRY, /** Expect the first key of a block mapping. */ FYPS_BLOCK_MAPPING_FIRST_KEY, /** Expect a block mapping key. */ FYPS_BLOCK_MAPPING_KEY, /** Expect a block mapping value. */ FYPS_BLOCK_MAPPING_VALUE, /** Expect the first entry of a flow sequence. */ FYPS_FLOW_SEQUENCE_FIRST_ENTRY, /** Expect an entry of a flow sequence. */ FYPS_FLOW_SEQUENCE_ENTRY, /** Expect a key of an ordered mapping. */ FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_KEY, /** Expect a value of an ordered mapping. */ FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE, /** Expect the and of an ordered mapping entry. */ FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END, /** Expect the first key of a flow mapping. */ FYPS_FLOW_MAPPING_FIRST_KEY, /** Expect a key of a flow mapping. */ FYPS_FLOW_MAPPING_KEY, /** Expect a value of a flow mapping. */ FYPS_FLOW_MAPPING_VALUE, /** Expect an empty value of a flow mapping. */ FYPS_FLOW_MAPPING_EMPTY_VALUE, /** Expect only stream end */ FYPS_SINGLE_DOCUMENT_END, /** Expect nothing. */ FYPS_END }; struct fy_parse_state_log { struct list_head node; enum fy_parser_state state; }; FY_PARSE_TYPE_DECL(parse_state_log); struct fy_streaming_alias { struct list_head node; struct fy_token *anchor; bool collecting; long mapping_nest; long sequence_nest; struct fy_eventp_list events; }; FY_PARSE_TYPE_DECL(streaming_alias); struct fy_streaming_alias_state { struct fy_streaming_alias *fysa; struct fy_eventp *next; }; /* 2 bits per collection tracking state * pos: * 2 * bit 0 - 0 map, 1 seq * bit 1 - 0 key, 1 val (if map) */ #define FYCTS_SCALAR 0 #define FYCTS_SEQ 1 #define FYCTS_MAP 2 #define FYCTS_MAP_KEY 2 #define FYCTS_MAP_VAL 3 #define FYCTS_MAP_TOGGLE 1 struct fy_parser { struct fy_parse_cfg cfg; struct fy_input_list queued_inputs; /* all the inputs queued */ struct fy_reader builtin_reader; /* the builtin reader */ struct fy_reader *reader; /* the external reader, or ptr to builtin_reader */ struct fy_version default_version; struct fy_version stream_version; /* last version set in stream */ union { struct { bool suppress_recycling : 1; bool stream_start_produced : 1; bool stream_end_produced : 1; bool stream_end_reached : 1; bool simple_key_allowed : 1; bool tab_used_for_ws : 1; bool stream_error : 1; bool generated_block_map : 1; bool last_was_comma : 1; bool document_has_content : 1; bool document_first_content_token : 1; bool bare_document_only : 1; /* no document start indicators allowed, no directives */ bool stream_has_content : 1; bool parse_flow_only : 1; /* document is in flow form, and stop parsing at the end */ bool parse_block_only : 1; /* document is in embedded block form, and stop parsing at the end */ bool colon_follows_colon : 1; /* "foo"::bar -> "foo": :bar */ bool had_directives : 1; /* document had directives */ bool is_checkpoint : 1; /* a parser checkpoint (not a real parser) */ }; unsigned int parser_bitflags; }; int flow_level; int pending_complex_key_column; struct fy_mark pending_complex_key_mark; int last_block_mapping_key_line; struct fy_mark last_comma_mark; struct fy_mark last_tab_used_for_ws_mark; /* copy of stream_end token */ struct fy_token *stream_end_token; /* produced tokens, but not yet consumed */ struct fy_token_list queued_tokens; int token_activity_counter; /* last comment */ struct fy_atom last_comment; /* next comment */ struct fy_atom override_comment; /* indent stack */ struct fy_indent_list indent_stack; int indent; int parent_indent; int indent_line; int starting_indent; /* simple key stack */ struct fy_simple_key_list simple_keys; /* state stack */ enum fy_parser_state state; struct fy_parse_state_log_list state_stack; /* current parse document */ struct fy_document_state *current_document_state; struct fy_document_state *default_document_state; bool next_single_document; /* flow stack */ enum fy_flow_type flow; struct fy_flow_list flow_stack; /* recycling lists */ struct fy_indent_list recycled_indent; struct fy_simple_key_list recycled_simple_key; struct fy_parse_state_log_list recycled_parse_state_log; struct fy_flow_list recycled_flow; struct fy_streaming_alias_list recycled_streaming_alias; struct fy_eventp_list recycled_eventp; struct fy_token_list recycled_token; struct fy_eventp_list *recycled_eventp_list; struct fy_token_list *recycled_token_list; /* the diagnostic object */ struct fy_diag *diag; int err_term_width; int err_term_height; /* for when using the built-in document builder */ struct fy_document_builder *fydb; /* when using the composer interface */ struct fy_composer *fyc; fy_parse_composer_cb fyc_cb; void *fyc_userdata; /* last generated event atom */ struct fy_atom last_event_handle; struct fy_streaming_alias_list streaming_aliases; /* streaming alias state */ struct { int alloc; int top; struct fy_streaming_alias_state *stack; struct fy_streaming_alias_state local[8]; } sas; /* collection tracking state */ struct { int alloc; int top; uint32_t *stack; uint32_t local[8]; /* 8 * 32 = 256 / 2 = 128 levels before needing dynamic allocation */ } cts; /* merge key state */ struct { bool active; struct fy_eventp_list args; struct fy_document *fyd; } mks; struct fy_eventp *fyep_peek; }; static inline struct fy_input * fyp_current_input(const struct fy_parser *fyp) { assert(fyp); return fy_reader_current_input(fyp->reader); } static inline uint64_t fyp_current_input_generation(const struct fy_parser *fyp) { assert(fyp); return fy_reader_current_input_generation(fyp->reader); } static inline int fyp_column(const struct fy_parser *fyp) { assert(fyp); return fy_reader_column(fyp->reader); } static inline int fyp_line(const struct fy_parser *fyp) { return fy_reader_line(fyp->reader); } static inline int fyp_tabsize(const struct fy_parser *fyp) { return fy_reader_tabsize(fyp->reader); } static inline bool fyp_json_mode(const struct fy_parser *fyp) { assert(fyp); return fy_reader_json_mode(fyp->reader); } static inline enum fy_lb_mode fyp_lb_mode(const struct fy_parser *fyp) { assert(fyp); return fy_reader_lb_mode(fyp->reader); } static inline enum fy_flow_ws_mode fyp_fws_mode(const struct fy_parser *fyp) { assert(fyp); return fy_reader_flow_ws_mode(fyp->reader); } static inline bool fyp_directive0_mode(const struct fy_parser *fyp) { assert(fyp); return fy_reader_directive0_mode(fyp->reader); } static inline bool fyp_block_mode(struct fy_parser *fyp) { return !fyp_json_mode(fyp) && !fyp->flow_level; } static inline bool fyp_is_lb(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_lb(fyp->reader, c); } static inline bool fyp_is_lbz(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_lbz(fyp->reader, c); } static inline bool fyp_is_blankz(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_blankz(fyp->reader, c); } static inline bool fyp_is_generic_lb(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_generic_lb(fyp->reader, c); } static inline bool fyp_is_generic_lbz(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_generic_lbz(fyp->reader, c); } static inline bool fyp_is_generic_blankz(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_generic_blankz(fyp->reader, c); } static inline bool fyp_is_flow_ws(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_flow_ws(fyp->reader, c); } static inline bool fyp_is_flow_blank(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_flow_blank(fyp->reader, c); } static inline bool fyp_is_flow_blankz(const struct fy_parser *fyp, int c) { assert(fyp); return fy_reader_is_flow_blankz(fyp->reader, c); } static inline const void * fy_ensure_lookahead_slow_path(struct fy_parser *fyp, size_t size, size_t *leftp) { assert(fyp); return fy_reader_ensure_lookahead_slow_path(fyp->reader, size, leftp); } /* only allowed if input does not update */ static inline void fy_get_mark(struct fy_parser *fyp, struct fy_mark *fym) { assert(fyp); fy_reader_get_mark(fyp->reader, fym); } static inline const void * fy_ptr(struct fy_parser *fyp, size_t *leftp) { assert(fyp); return fy_reader_ptr(fyp->reader, leftp); } static inline const void * fy_ensure_lookahead(struct fy_parser *fyp, size_t size, size_t *leftp) { assert(fyp); return fy_reader_ensure_lookahead(fyp->reader, size, leftp); } /* advance the given number of ascii characters, not utf8 */ static inline void fy_advance_octets(struct fy_parser *fyp, size_t advance) { assert(fyp); fy_reader_advance_octets(fyp->reader, advance); } /* compare string at the current point (n max) */ static inline int fy_parse_strncmp(struct fy_parser *fyp, const char *str, size_t n) { assert(fyp); return fy_reader_strncmp(fyp->reader, str, n); } static FY_ALWAYS_INLINE inline int fy_parse_peek_at_offset_width(struct fy_parser *fyp, size_t offset, int *wp) { assert(fyp); return fy_reader_peek_at_offset_width(fyp->reader, offset, wp); } static FY_ALWAYS_INLINE inline int fy_parse_peek_at_offset(struct fy_parser *fyp, size_t offset) { assert(fyp); return fy_reader_peek_at_offset(fyp->reader, offset); } static FY_ALWAYS_INLINE inline int fy_parse_peek_at_width_internal(struct fy_parser *fyp, int pos, ssize_t *offsetp, int *wp) { assert(fyp); return fy_reader_peek_at_width_internal(fyp->reader, pos, offsetp, wp); } static FY_ALWAYS_INLINE inline int fy_parse_peek_at_internal(struct fy_parser *fyp, int pos, ssize_t *offsetp) { assert(fyp); return fy_reader_peek_at_internal(fyp->reader, pos, offsetp); } static inline bool fy_is_blank_at_offset(struct fy_parser *fyp, size_t offset) { assert(fyp); return fy_is_blank(fy_reader_peek_at_offset(fyp->reader, offset)); } static inline bool fy_is_blankz_at_offset(struct fy_parser *fyp, size_t offset) { assert(fyp); return fy_reader_is_blankz(fyp->reader, fy_reader_peek_at_offset(fyp->reader, offset)); } static inline bool fy_is_generic_blankz_at_offset(struct fy_parser *fyp, size_t offset) { assert(fyp); return fy_reader_is_generic_blankz(fyp->reader, fy_reader_peek_at_offset(fyp->reader, offset)); } static FY_ALWAYS_INLINE inline int fy_parse_peek_at_width(struct fy_parser *fyp, int pos, int *wp) { assert(fyp); return fy_reader_peek_at_width(fyp->reader, pos, wp); } static FY_ALWAYS_INLINE inline int fy_parse_peek_at(struct fy_parser *fyp, int pos) { assert(fyp); return fy_reader_peek_at(fyp->reader, pos); } static FY_ALWAYS_INLINE inline int fy_parse_peek_width(struct fy_parser *fyp, int *wp) { assert(fyp); return fy_reader_peek_width(fyp->reader, wp); } static FY_ALWAYS_INLINE inline int fy_parse_peek(struct fy_parser *fyp) { assert(fyp); return fy_reader_peek(fyp->reader); } static FY_ALWAYS_INLINE inline void fy_advance(struct fy_parser *fyp, int c) { assert(fyp); fy_reader_advance(fyp->reader, c); } static FY_ALWAYS_INLINE inline void fy_advance_ws(struct fy_parser *fyp, int c) { assert(fyp); fy_reader_advance_ws(fyp->reader, c); } static FY_ALWAYS_INLINE inline void fy_advance_space(struct fy_parser *fyp) { assert(fyp); fy_reader_advance_space(fyp->reader); } static FY_ALWAYS_INLINE inline int fy_parse_get(struct fy_parser *fyp) { assert(fyp); return fy_reader_get(fyp->reader); } static FY_ALWAYS_INLINE inline int fy_advance_by(struct fy_parser *fyp, int count) { assert(fyp); return fy_reader_advance_by(fyp->reader, count); } /* compare string at the current point */ static inline bool fy_parse_strcmp(struct fy_parser *fyp, const char *str) { assert(fyp); return fy_reader_strcmp(fyp->reader, str); } static inline void fy_fill_atom_start(struct fy_parser *fyp, struct fy_atom *handle) { assert(fyp); fy_reader_fill_atom_start(fyp->reader, handle); } static inline void fy_fill_atom_end_at(struct fy_parser *fyp, struct fy_atom *handle, struct fy_mark *end_mark) { assert(fyp); fy_reader_fill_atom_end_at(fyp->reader, handle, end_mark); } static inline void fy_fill_atom_end(struct fy_parser *fyp, struct fy_atom *handle) { assert(fyp); fy_reader_fill_atom_end(fyp->reader, handle); } static inline struct fy_atom * fy_fill_atom(struct fy_parser *fyp, int advance, struct fy_atom *handle) { assert(fyp); return fy_reader_fill_atom(fyp->reader, advance, handle); } static inline struct fy_atom * fy_fill_atom_mark(struct fy_parser *fyp, const struct fy_mark *start_mark, const struct fy_mark *end_mark, struct fy_atom *handle) { assert(fyp); return fy_reader_fill_atom_mark(fyp->reader, start_mark, end_mark, handle); } static inline struct fy_atom * fy_fill_atom_at(struct fy_parser *fyp, int advance, int count, struct fy_atom *handle) { assert(fyp); return fy_reader_fill_atom_at(fyp->reader, advance, count, handle); } static inline void fy_parser_set_reader(struct fy_parser *fyp, struct fy_reader *fyr) { if (!fyp) return; fyp->reader = fyr ? fyr : &fyp->builtin_reader; } static inline void fy_parser_set_flow_only_mode(struct fy_parser *fyp, bool flow_only_mode) { fyp->parse_flow_only = flow_only_mode; } static inline void fy_parser_set_block_only_mode(struct fy_parser *fyp, bool block_only_mode) { fyp->parse_block_only = block_only_mode; } #define fy_fill_atom_a(_fyp, _advance) \ fy_fill_atom((_fyp), (_advance), alloca(sizeof(struct fy_atom))) struct fy_token *fy_token_vqueue(struct fy_parser *fyp, enum fy_token_type type, va_list ap); struct fy_token *fy_token_queue(struct fy_parser *fyp, enum fy_token_type type, ...); struct fy_token * fy_token_vqueue_internal(struct fy_parser *fyp, struct fy_token_list *fytl, enum fy_token_type type, va_list ap); struct fy_token * fy_token_queue_internal(struct fy_parser *fyp, struct fy_token_list *fytl, enum fy_token_type type, ...); int fy_parse_setup(struct fy_parser *fyp, const struct fy_parse_cfg *cfg); void fy_parse_cleanup(struct fy_parser *fyp); int fy_parse_input_append(struct fy_parser *fyp, const struct fy_input_cfg *fyic); ssize_t fy_parse_estimate_queued_input_size(struct fy_parser *fyp); struct fy_eventp *fy_parse_private(struct fy_parser *fyp); extern const char *fy_event_type_txt[]; enum fy_parse_cfg_flags fy_parser_get_cfg_flags(const struct fy_parser *fyp); extern const struct fy_tag * const fy_default_tags[]; extern const struct fy_version fy_default_version; /* usually highest stable */ bool fy_tag_handle_is_default(const char *handle, size_t handle_size); bool fy_tag_is_default_internal(const char *handle, size_t handle_size, const char *prefix, size_t prefix_size); bool fy_token_tag_directive_is_overridable(struct fy_token *fyt_td); int fy_parser_set_default_document_state(struct fy_parser *fyp, struct fy_document_state *fyds); void fy_parser_set_next_single_document(struct fy_parser *fyp); void *fy_alloc_default(void *userdata, size_t size); void fy_free_default(void *userdata, void *ptr); void *fy_realloc_default(void *userdata, void *ptr, size_t size); int fy_reader_fetch_flow_scalar_handle(struct fy_reader *fyr, int c, int indent, struct fy_atom *handle, bool sloppy_indent); int fy_reader_fetch_plain_scalar_handle(struct fy_reader *fyr, int c, int indent, int flow_level, struct fy_atom *handle); void fy_reader_skip_ws_cr_nl(struct fy_reader *fyr); void fy_reader_skip_ws(struct fy_reader *fyr); void fy_reader_skip_space(struct fy_reader *fyr); static inline int fy_document_state_version_compare(struct fy_document_state *fyds, const struct fy_version *vb) { return fy_version_compare(fy_document_state_version(fyds), vb); } int fy_parse_set_composer(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata); struct fy_streaming_alias * fy_parse_streaming_alias_create(struct fy_parser *fyp, struct fy_token *fyt_anchor); void fy_parse_streaming_alias_clean(struct fy_parser *fyp, struct fy_streaming_alias *fysa); void fy_parse_streaming_aliases_reset(struct fy_parser *fyp); struct fy_eventp *fy_parser_parse_resolve_prolog(struct fy_parser *fyp); struct fy_eventp *fy_parser_parse_resolve_epilog(struct fy_parser *fyp, struct fy_eventp *fyep); struct fy_parser_checkpoint { struct fy_parser fyp_checkpoint; int queued_token_count; struct fy_token **queued_tokens; int queued_input_count; struct fy_input **queued_inputs; bool diag_on_error; }; /* diagnostics */ static inline bool fyp_debug_log_level_is_enabled(struct fy_parser *fyp, enum fy_error_module module) { return fyp && fy_diag_log_level_is_enabled(fyp->diag, FYET_DEBUG, module); } int fy_parser_vdiag(struct fy_parser *fyp, unsigned int flags, const char *file, int line, const char *func, const char *fmt, va_list ap); int fy_parser_diag(struct fy_parser *fyp, unsigned int flags, const char *file, int line, const char *func, const char *fmt, ...) FY_FORMAT(printf, 6, 7); void fy_parser_diag_vreport(struct fy_parser *fyp, const struct fy_diag_report_ctx *fydrc, const char *fmt, va_list ap); void fy_parser_diag_report(struct fy_parser *fyp, const struct fy_diag_report_ctx *fydrc, const char *fmt, ...) FY_FORMAT(printf, 3, 4); #ifdef FY_DEVMODE #define fyp_debug(_fyp, _module, _fmt, ...) \ do { \ struct fy_parser *__fyp = (_fyp); \ enum fy_error_module __module = (_module); \ \ if (fyp_debug_log_level_is_enabled(__fyp, __module)) \ fy_parser_diag(__fyp, FYET_DEBUG | FYDF_MODULE(__module), \ __FILE__, __LINE__, __func__, \ (_fmt) , ## __VA_ARGS__); \ } while(0) #else #define fyp_debug(_fyp, _module, _fmt, ...) \ do { } while(0) #endif #define fyp_info(_fyp, _fmt, ...) \ fy_parser_diag((_fyp), FYET_INFO, __FILE__, __LINE__, __func__, \ (_fmt) , ## __VA_ARGS__) #define fyp_notice(_fyp, _fmt, ...) \ fy_parser_diag((_fyp), FYET_NOTICE, __FILE__, __LINE__, __func__, \ (_fmt) , ## __VA_ARGS__) #define fyp_warning(_fyp, _fmt, ...) \ fy_parser_diag((_fyp), FYET_WARNING, __FILE__, __LINE__, __func__, \ (_fmt) , ## __VA_ARGS__) #define fyp_error(_fyp, _fmt, ...) \ fy_parser_diag((_fyp), FYET_ERROR, __FILE__, __LINE__, __func__, \ (_fmt) , ## __VA_ARGS__) #define fyp_scan_debug(_fyp, _fmt, ...) \ fyp_debug((_fyp), FYEM_SCAN, (_fmt) , ## __VA_ARGS__) #define fyp_parse_debug(_fyp, _fmt, ...) \ fyp_debug((_fyp), FYEM_PARSE, (_fmt) , ## __VA_ARGS__) #define fyp_doc_debug(_fyp, _fmt, ...) \ fyp_debug((_fyp), FYEM_DOC, (_fmt) , ## __VA_ARGS__) #define fyp_error_check(_fyp, _cond, _label, _fmt, ...) \ do { \ if (!(_cond)) { \ fyp_error((_fyp), _fmt, ## __VA_ARGS__); \ goto _label ; \ } \ } while(0) #define _FYP_TOKEN_DIAG(_fyp, _fyt, _type, _module, _fmt, ...) \ do { \ struct fy_diag_report_ctx _drc; \ memset(&_drc, 0, sizeof(_drc)); \ _drc.type = (_type); \ _drc.module = (_module); \ _drc.fyt = (_fyt); \ fy_parser_diag_report((_fyp), &_drc, (_fmt) , ## __VA_ARGS__); \ } while(0) #define FYP_TOKEN_DIAG(_fyp, _fyt, _type, _module, _fmt, ...) \ _FYP_TOKEN_DIAG(_fyp, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__) #define FYP_PARSE_DIAG(_fyp, _adv, _cnt, _type, _module, _fmt, ...) \ _FYP_TOKEN_DIAG(_fyp, \ fy_token_create(FYTT_INPUT_MARKER, \ fy_fill_atom_at((_fyp), (_adv), (_cnt), \ alloca(sizeof(struct fy_atom)))), \ _type, _module, _fmt, ## __VA_ARGS__) #define FYP_MARK_DIAG(_fyp, _sm, _em, _type, _module, _fmt, ...) \ _FYP_TOKEN_DIAG(_fyp, \ fy_token_create(FYTT_INPUT_MARKER, \ fy_fill_atom_mark(((_fyp)), (_sm), (_em), \ alloca(sizeof(struct fy_atom)))), \ _type, _module, _fmt, ## __VA_ARGS__) #define FYP_NODE_DIAG(_fyp, _fyn, _type, _module, _fmt, ...) \ _FYP_TOKEN_DIAG(_fyp, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__) #define FYP_TOKEN_ERROR(_fyp, _fyt, _module, _fmt, ...) \ FYP_TOKEN_DIAG(_fyp, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) #define FYP_PARSE_ERROR(_fyp, _adv, _cnt, _module, _fmt, ...) \ FYP_PARSE_DIAG(_fyp, _adv, _cnt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) #define FYP_MARK_ERROR(_fyp, _sm, _em, _module, _fmt, ...) \ FYP_MARK_DIAG(_fyp, _sm, _em, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) #define FYP_NODE_ERROR(_fyp, _fyn, _module, _fmt, ...) \ FYP_NODE_DIAG(_fyp, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) #define FYP_TOKEN_ERROR_CHECK(_fyp, _fyt, _module, _cond, _label, _fmt, ...) \ do { \ if (!(_cond)) { \ FYP_TOKEN_ERROR(_fyp, _fyt, _module, _fmt, ## __VA_ARGS__); \ goto _label; \ } \ } while(0) #define FYP_PARSE_ERROR_CHECK(_fyp, _adv, _cnt, _module, _cond, _label, _fmt, ...) \ do { \ if (!(_cond)) { \ FYP_PARSE_ERROR(_fyp, _adv, _cnt, _module, _fmt, ## __VA_ARGS__); \ goto _label; \ } \ } while(0) #define FYP_MARK_ERROR_CHECK(_fyp, _sm, _em, _module, _cond, _label, _fmt, ...) \ do { \ if (!(_cond)) { \ FYP_MARK_ERROR(_fyp, _sm, _em, _module, _fmt, ## __VA_ARGS__); \ goto _label; \ } \ } while(0) #define FYP_NODE_ERROR_CHECK(_fyp, _fyn, _module, _cond, _label, _fmt, ...) \ do { \ if (!(_cond)) { \ FYP_NODE_ERROR(_fyp, _fyn, _module, _fmt, ## __VA_ARGS__); \ goto _label; \ } \ } while(0) #define FYP_TOKEN_WARNING(_fyp, _fyt, _module, _fmt, ...) \ FYP_TOKEN_DIAG(_fyp, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) #define FYP_PARSE_WARNING(_fyp, _adv, _cnt, _module, _fmt, ...) \ FYP_PARSE_DIAG(_fyp, _adv, _cnt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) #define FYP_MARK_WARNING(_fyp, _sm, _em, _module, _fmt, ...) \ FYP_MARK_DIAG(_fyp, _sm, _em, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) #define FYP_NODE_WARNING(_fyp, _fyn, _type, _module, _fmt, ...) \ FYP_NODE_DIAG(_fyp, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) #endif