#ifndef FY_PARSE_H
#define FY_PARSE_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <libfyaml.h>
#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;
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;
int flow_level;
bool required : 1;
bool implicit_complex : 1;
};
FY_PARSE_TYPE_DECL(simple_key);
struct fy_document_state;
enum fy_parser_state {
FYPS_NONE,
FYPS_STREAM_START,
FYPS_IMPLICIT_DOCUMENT_START,
FYPS_DOCUMENT_START,
FYPS_DOCUMENT_CONTENT,
FYPS_DOCUMENT_END,
FYPS_BLOCK_NODE,
FYPS_BLOCK_SEQUENCE_FIRST_ENTRY,
FYPS_BLOCK_SEQUENCE_ENTRY,
FYPS_INDENTLESS_SEQUENCE_ENTRY,
FYPS_BLOCK_MAPPING_FIRST_KEY,
FYPS_BLOCK_MAPPING_KEY,
FYPS_BLOCK_MAPPING_VALUE,
FYPS_FLOW_SEQUENCE_FIRST_ENTRY,
FYPS_FLOW_SEQUENCE_ENTRY,
FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_KEY,
FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE,
FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END,
FYPS_FLOW_MAPPING_FIRST_KEY,
FYPS_FLOW_MAPPING_KEY,
FYPS_FLOW_MAPPING_VALUE,
FYPS_FLOW_MAPPING_EMPTY_VALUE,
FYPS_SINGLE_DOCUMENT_END,
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_parser {
struct fy_parse_cfg cfg;
struct fy_input_list queued_inputs;
struct fy_reader builtin_reader;
struct fy_reader *reader;
struct fy_version default_version;
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;
bool stream_has_content : 1;
bool parse_flow_only : 1;
bool colon_follows_colon : 1;
bool had_directives : 1;
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;
struct fy_token *stream_end_token;
struct fy_token_list queued_tokens;
int token_activity_counter;
struct fy_atom last_comment;
struct fy_indent_list indent_stack;
int indent;
int parent_indent;
int indent_line;
struct fy_simple_key_list simple_keys;
enum fy_parser_state state;
struct fy_parse_state_log_list state_stack;
struct fy_document_state *current_document_state;
struct fy_document_state *default_document_state;
bool next_single_document;
enum fy_flow_type flow;
struct fy_flow_list flow_stack;
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_eventp_list recycled_eventp;
struct fy_token_list recycled_token;
struct fy_eventp_list *recycled_eventp_list;
struct fy_token_list *recycled_token_list;
struct fy_diag *diag;
int err_term_width;
int err_term_height;
struct fy_document_builder *fydb;
struct fy_composer *fyc;
fy_parse_composer_cb fyc_cb;
void *fyc_userdata;
struct fy_atom last_event_handle;
};
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_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_ptr_slow_path(struct fy_parser *fyp, size_t *leftp)
{
assert(fyp);
return fy_reader_ptr_slow_path(fyp->reader, leftp);
}
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);
}
static inline void
fy_get_mark(struct fy_parser *fyp, struct fy_mark *fym)
{
assert(fyp);
return 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);
}
static inline void
fy_advance_octets(struct fy_parser *fyp, size_t advance)
{
assert(fyp);
return fy_reader_advance_octets(fyp->reader, advance);
}
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(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_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(struct fy_parser *fyp, int pos)
{
assert(fyp);
return fy_reader_peek_at_internal(fyp->reader, pos, NULL);
}
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);
}
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 ? : &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;
}
#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);
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;
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, bool directive0);
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);
#endif