$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/shave.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/shave.m4 $(top_srcdir)/.libtool-version \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEBVERSION = @DEBVERSION@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
+LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIBYAML_CFLAGS = @LIBYAML_CFLAGS@
LIBYAML_LIBS = @LIBYAML_LIBS@
LIPO = @LIPO@
```c
if (argc == 1)
- fyd = fy_document_build_from_string(NULL, yaml);
+ fyd = fy_document_build_from_string(NULL, yaml, FY_NT);
else
fyd = fy_document_build_from_file(NULL, argv[1]);
if (!fyd) {
```c
rc =
/* set increased invoice number (modify existing node) */
- fy_document_insert_at(fyd, "/invoice",
+ fy_document_insert_at(fyd, "/invoice", FY_NT,
fy_node_buildf(fyd, "%u", invoice_nr + 1)) ||
/* add spouse (create new mapping pair) */
- fy_document_insert_at(fyd, "/bill-to",
+ fy_document_insert_at(fyd, "/bill-to", FY_NT,
fy_node_buildf(fyd, "spouse: %s", "Doris")) ||
/* add a second address */
- fy_document_insert_at(fyd, "/bill-to",
+ fy_document_insert_at(fyd, "/bill-to", FY_NT,
fy_node_buildf(fyd, "delivery-address:\n"
" lines: |\n"
" 1226 Windward Ave.\n"));
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libfyaml 0.7.3.
+# Generated by GNU Autoconf 2.69 for libfyaml 0.7.11.
#
# Report bugs to <pantelis.antoniou@konsulko.com>.
#
# Identity of this package.
PACKAGE_NAME='libfyaml'
PACKAGE_TARNAME='libfyaml'
-PACKAGE_VERSION='0.7.3'
-PACKAGE_STRING='libfyaml 0.7.3'
+PACKAGE_VERSION='0.7.11'
+PACKAGE_STRING='libfyaml 0.7.11'
PACKAGE_BUGREPORT='pantelis.antoniou@konsulko.com'
PACKAGE_URL=''
LDFLAGS
CFLAGS
CC
-DEBVERSION
+LIBTOOL_VERSION
EXTRA
PATCH
MINOR
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libfyaml 0.7.3 to adapt to many kinds of systems.
+\`configure' configures libfyaml 0.7.11 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libfyaml 0.7.3:";;
+ short | recursive ) echo "Configuration of libfyaml 0.7.11:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libfyaml configure 0.7.3
+libfyaml configure 0.7.11
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libfyaml $as_me 0.7.3, which was
+It was created by libfyaml $as_me 0.7.11, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='libfyaml'
- VERSION='0.7.3'
+ VERSION='0.7.11'
cat >>confdefs.h <<_ACEOF
PATCH=`echo $VERSION | cut -d. -f3- | cut -d- -f1`
-EXTRA=`echo $VERSION | cut -d- -f2-`
+EXTRA=`echo $VERSION | cut -d- -f2- -s`
-DEBVERSION="$MAJOR.$MINOR"
+# libtool version is of the following format <current>:<revision>:<age>
+# and it is the library ABI version
+#
+# - Increase current when an interface has been added removed or changed
+# - Increase revision every time a release is made
+# - Increase age when changes are backwards compatible
+#
+# examples of semantic versioning progression mapping to libtool abi versions
+#
+# v0.7.4 -> v0.7.5 - patch number changes, backwards compatible (1)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v0.7.5 -> v0.8.0 - minor number changes, backwards compatible (same as (1)) (2)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v0.8.0 -> v0.9.0 - minor number changes, but breaks backwards compatibility - should not happen (3)
+# with semantic versioning for major version number >= 1, allowed for major == 0
+# increase revision, increase current, age reset to 0
+#
+# v0.9.0 -> v1.0.0 - major number changes, first public release (4)
+# increase current, set revision and age to 0
+#
+# v1.0.0 -> v1.0.1 - patch number changes, _must_ be backwards compatible (same as (1)) (5)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v1.0.1 -> v1.1.0 - minor number changes, backwards compatible (same as (5)) (6)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v1.1.0 -> v1.2.0 - minor number changes, breaking backwards compatibility (7)
+# XXX illegal in semantic versioning and should not happen
+#
+# v1.1.0 -> v2.0.0 - major number changes, breaking backwards compatibility (same as (4)) (8)
+# increase current, set revision and age to 0
+
+
+LIBTOOL_VERSION=1:1:0
_ACEOF
-for flag in -Wall -Wsign-compare; do
+for flag in -Wall -Wsign-compare -Wno-stringop-overflow; do
as_CACHEVAR=`$as_echo "ax_cv_check_cflags_-pedantic -Werror_$flag" | $as_tr_sh`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
$as_echo_n "checking whether C compiler accepts $flag... " >&6; }
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libfyaml $as_me 0.7.3, which was
+This file was extended by libfyaml $as_me 0.7.11, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-libfyaml config.status 0.7.3
+libfyaml config.status 0.7.11
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
MAJOR.MINOR: ${MAJOR}.${MINOR}
PATCH: ${PATCH}
EXTRA: ${EXTRA}
+ LIBTOOL_VERSION: ${LIBTOOL_VERSION}
prefix: ${prefix}
C compiler: ${CC}
CFLAGS: ${CFLAGS}
m4_define(fyaml_major, `echo $VERSION | cut -d. -f1 | cut -d- -f1`)
m4_define(fyaml_minor, `echo $VERSION | cut -d. -f2 | cut -d- -f1`)
m4_define(fyaml_patch, `echo $VERSION | cut -d. -f3- | cut -d- -f1`)
-m4_define(fyaml_extra, `echo $VERSION | cut -d- -f2-`)
+m4_define(fyaml_extra, `echo $VERSION | cut -d- -f2- -s`)
AC_SUBST(MAJOR, fyaml_major)
AC_SUBST(MINOR, fyaml_minor)
AC_SUBST(PATCH, fyaml_patch)
AC_SUBST(EXTRA, fyaml_extra)
-AC_SUBST(DEBVERSION, "$MAJOR.$MINOR")
+# libtool version is of the following format <current>:<revision>:<age>
+# and it is the library ABI version
+#
+# - Increase current when an interface has been added removed or changed
+# - Increase revision every time a release is made
+# - Increase age when changes are backwards compatible
+#
+# examples of semantic versioning progression mapping to libtool abi versions
+#
+# v0.7.4 -> v0.7.5 - patch number changes, backwards compatible (1)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v0.7.5 -> v0.8.0 - minor number changes, backwards compatible (same as (1)) (2)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v0.8.0 -> v0.9.0 - minor number changes, but breaks backwards compatibility - should not happen (3)
+# with semantic versioning for major version number >= 1, allowed for major == 0
+# increase revision, increase current, age reset to 0
+#
+# v0.9.0 -> v1.0.0 - major number changes, first public release (4)
+# increase current, set revision and age to 0
+#
+# v1.0.0 -> v1.0.1 - patch number changes, _must_ be backwards compatible (same as (1)) (5)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v1.0.1 -> v1.1.0 - minor number changes, backwards compatible (same as (5)) (6)
+# increase revision, increase age (age must be <= current), current unchanged
+#
+# v1.1.0 -> v1.2.0 - minor number changes, breaking backwards compatibility (7)
+# XXX illegal in semantic versioning and should not happen
+#
+# v1.1.0 -> v2.0.0 - major number changes, breaking backwards compatibility (same as (4)) (8)
+# increase current, set revision and age to 0
+
+m4_define(fyaml_libtool_version, m4_normalize(m4_include([.libtool-version])))
+AC_SUBST(LIBTOOL_VERSION, fyaml_libtool_version)
dnl AX_* requires 2.64
m4_version_prereq(2.64, [AX_CHECK_ENABLE_DEBUG()], [true])
dnl for old autoconf version AX_APPEND_COMPILE_FLAGS does not work
m4_version_prereq(2.64,
- [AX_APPEND_COMPILE_FLAGS([-Wall -Wsign-compare],
+ [AX_APPEND_COMPILE_FLAGS([-Wall -Wsign-compare -Wno-stringop-overflow],
[CFLAGS], [-pedantic -Werror])],
[CFLAGS="$CFLAGS -Wall -Wsign-compare"])
MAJOR.MINOR: ${MAJOR}.${MINOR}
PATCH: ${PATCH}
EXTRA: ${EXTRA}
+ LIBTOOL_VERSION: ${LIBTOOL_VERSION}
prefix: ${prefix}
C compiler: ${CC}
CFLAGS: ${CFLAGS}
doc-%:
srctree=@top_srcdir@ @SPHINX@ -M `echo $@ | sed -s 's/^doc-//g'` "@srcdir@" "$(BUILDDIR)"
+# if we have sphinx generate the manpages
$(MANPAGES1): doc-man
+else
+
+# otherwise, install the canned ones
+MANPAGES1 = $(srcdir)/canned-man/fy-tool.1
+
+endif
+
install-data-hook: $(MANPAGES1)
$(MKDIR_P) "$(DESTDIR)$(mandir)/man1"
@for i in "$(MANPAGES1)"; do \
(cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-filter.1)
(cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-testsuite.1)
(cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-join.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-ypath.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-compose.1)
uninstall-hook:
@for i in "$(MANPAGES1)"; do \
rm -f "$(DESTDIR)$(mandir)/man1/`basename $$i`"; \
done
- (cd "$(DESTDIR)$(mandir)/man1" && rm -f fy-dump.1 fy-filter.1 fy-testsuite.1 fy-join.1)
-
-endif
+ (cd "$(DESTDIR)$(mandir)/man1" && \
+ rm -f fy-dump.1 fy-filter.1 fy-testsuite.1 fy-join.1 fy-ypath.1 fy-compose.1)
clean-local:
@rm -rf "$(BUILDDIR)"
index.rst \
intro.rst \
libfyaml.rst \
- man/fy-tool.rst
+ man/fy-tool.rst \
+ canned-man/fy-tool.1
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/shave.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/shave.m4 $(top_srcdir)/.libtool-version \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEBVERSION = @DEBVERSION@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
+LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIBYAML_CFLAGS = @LIBYAML_CFLAGS@
LIBYAML_LIBS = @LIBYAML_LIBS@
LIPO = @LIPO@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
BUILDDIR = _build
+
+# otherwise, install the canned ones
+@HAVE_SPHINX_FALSE@MANPAGES1 = $(srcdir)/canned-man/fy-tool.1
@HAVE_SPHINX_TRUE@MANPAGES1 = $(BUILDDIR)/man/fy-tool.1
EXTRA_DIST = \
conf.py \
index.rst \
intro.rst \
libfyaml.rst \
- man/fy-tool.rst
+ man/fy-tool.rst \
+ canned-man/fy-tool.1
all: all-am
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-@HAVE_SPHINX_FALSE@install-data-hook:
-@HAVE_SPHINX_FALSE@uninstall-hook:
clean: clean-am
clean-am: clean-generic clean-libtool clean-local mostlyclean-am
@HAVE_SPHINX_TRUE@doc-%:
@HAVE_SPHINX_TRUE@ srctree=@top_srcdir@ @SPHINX@ -M `echo $@ | sed -s 's/^doc-//g'` "@srcdir@" "$(BUILDDIR)"
+# if we have sphinx generate the manpages
@HAVE_SPHINX_TRUE@$(MANPAGES1): doc-man
-@HAVE_SPHINX_TRUE@install-data-hook: $(MANPAGES1)
-@HAVE_SPHINX_TRUE@ $(MKDIR_P) "$(DESTDIR)$(mandir)/man1"
-@HAVE_SPHINX_TRUE@ @for i in "$(MANPAGES1)"; do \
-@HAVE_SPHINX_TRUE@ $(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/man1"; \
-@HAVE_SPHINX_TRUE@ done
-@HAVE_SPHINX_TRUE@ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-dump.1)
-@HAVE_SPHINX_TRUE@ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-filter.1)
-@HAVE_SPHINX_TRUE@ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-testsuite.1)
-@HAVE_SPHINX_TRUE@ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-join.1)
-
-@HAVE_SPHINX_TRUE@uninstall-hook:
-@HAVE_SPHINX_TRUE@ @for i in "$(MANPAGES1)"; do \
-@HAVE_SPHINX_TRUE@ rm -f "$(DESTDIR)$(mandir)/man1/`basename $$i`"; \
-@HAVE_SPHINX_TRUE@ done
-@HAVE_SPHINX_TRUE@ (cd "$(DESTDIR)$(mandir)/man1" && rm -f fy-dump.1 fy-filter.1 fy-testsuite.1 fy-join.1)
+install-data-hook: $(MANPAGES1)
+ $(MKDIR_P) "$(DESTDIR)$(mandir)/man1"
+ @for i in "$(MANPAGES1)"; do \
+ $(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/man1"; \
+ done
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-dump.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-filter.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-testsuite.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-join.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-ypath.1)
+ (cd "$(DESTDIR)$(mandir)/man1" && $(LN_S) -f fy-tool.1 fy-compose.1)
+
+uninstall-hook:
+ @for i in "$(MANPAGES1)"; do \
+ rm -f "$(DESTDIR)$(mandir)/man1/`basename $$i`"; \
+ done
+ (cd "$(DESTDIR)$(mandir)/man1" && \
+ rm -f fy-dump.1 fy-filter.1 fy-testsuite.1 fy-join.1 fy-ypath.1 fy-compose.1)
clean-local:
@rm -rf "$(BUILDDIR)"
--- /dev/null
+.\" Man page generated from reStructuredText.
+.
+.TH "FY-TOOL" "1" "Jan 14, 2022" "" "libfyaml"
+.SH NAME
+fy-tool \- fy-tool documentation
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fBfy\-tool\fP [\fIOPTIONS\fP] [<\fIfile\fP> ...]
+.sp
+\fBfy\-dump\fP [\fIOPTIONS\fP] [<\fIfile\fP> ...]
+.sp
+\fBfy\-testsuite\fP [\fIOPTIONS\fP] <\fIfile\fP>
+.sp
+\fBfy\-filter\fP [\fIOPTIONS\fP] [\-f*FILE*] [<\fIpath\fP> ...]
+.sp
+\fBfy\-join\fP [\fIOPTIONS\fP] [\-T*PATH*] [\-F*PATH*] [\-t*PATH*] [<\fIfile\fP> ...]
+.sp
+\fBfy\-ypath\fP [\fIOPTIONS\fP] <\fIypath\-expression> [<*file\fP> ...]
+.sp
+\fBfy\-compose\fP [\fIOPTIONS\fP] [<\fIfile\fP> ...]
+.SH DESCRIPTION
+.sp
+\fBfy\-tool\fP is a general YAML/JSON manipulation tool using \fIlibfyaml\fP\&.
+Its operation is different depending on how it\(aqs called, either via aliases
+named \fIfy\-dump\fP, \fIfy\-testsuite\fP, \fIfy\-filter\fP, \fIfy\-join\fP, or via the
+\fI\-\-dump\fP, \fI\-\-testsuite\fP, \fI\-\-filter\fP, \fI\-\-join\fP, \fI\-\-ypath\fP and \fI\-\-compose\fP options.
+.INDENT 0.0
+.IP \(bu 2
+In \fIdump\fP mode it will parse YAML/JSON input files and output YAML/JSON
+according to the output format options.
+.IP \(bu 2
+In \fItestsuite\fP mode it will parse a single YAML input file and output
+yaml testsuite reference output.
+.IP \(bu 2
+In \fIfilter\fP mode it will parse YAML/JSON files and output YAML/JSON
+output filtered according to the given option.
+.IP \(bu 2
+In \fIjoin\fP mode it will parse YAML/JSON files and join them into a single
+YAML/JSON document according to the given command line options.
+.IP \(bu 2
+In \fIypath\fP mode it will parse YAML/JSON files and execute a ypath query
+which will output a document stream according to the results. This is
+an experimental mode under development, where the syntax is not yet
+decided completely.
+.IP \(bu 2
+In \fIcompose\fP mode, it operates similarly to dump, but the document tree
+is created using the built\-in composer API.
+.UNINDENT
+.SH OPTIONS
+.sp
+A number of options are common for all the different modes of operation
+and they are as follows:
+Common options.INDENT 0.0
+.TP
+.B \-q, \-\-quiet
+Quiet operation, does not output informational messages at all.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-h, \-\-help
+Display usage information.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-v, \-\-version
+Display version information.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-I DIR, \-\-include=DIR
+Add the \fIDIR\fP directory to the search path which will be used to locate a YAML/JSON file.
+The default path is set to ""
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-d LEVEL, \-\-debug\-level=LEVEL
+Set the minimum numeric debug level value of the library to \fILEVEL\fP\&.
+The numeric value must be in the range of 0 to 4 and their meaning is as follows:
+.INDENT 7.0
+.IP \(bu 2
+\fB0\fP (\fIDEBUG\fP)
+.sp
+Internal library debugging messages. No output is produced when the
+library was compiled with \fI\-\-disable\-debug\fP
+.IP \(bu 2
+\fB1\fP (\fIINFO\fP)
+.sp
+Informational messages about the internal operation of the library.
+.IP \(bu 2
+\fB2\fP (\fINOTICE\fP)
+.sp
+Messsages that could require attention.
+.IP \(bu 2
+\fB3\fP (\fIWARNING\fP)
+.sp
+A warning message, something is wrong, but operation can continue.
+This is the default value.
+.IP \(bu 2
+\fB4\fP (\fIERROR\fP)
+.sp
+A fatal error occured, it is impossible to continue.
+.UNINDENT
+.sp
+The default level is 3 (\fIWARNING\fP), which means that messages
+with level 3 and higher will be displayed.
+.UNINDENT
+Parser Options.INDENT 0.0
+.TP
+.B \-j JSONOPT, \-\-json=JSONOPT
+Marks the input files as JSON or YAML accordingly to:
+.INDENT 7.0
+.IP \(bu 2
+\fBno\fP
+.sp
+The input files are always in YAML mode.
+.IP \(bu 2
+\fBforce\fP
+.sp
+The input files are always set to JSON mode.
+.IP \(bu 2
+\fBauto\fP
+.sp
+The input files are set to JSON mode automatically when the
+file\(aqs extension is \fI\&.json\fP\&. This is the default.
+.UNINDENT
+.sp
+JSON support is complete so all valid JSON files are parsed according
+to JSON rules, even where those differ with YAML rules.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-yaml\-1.1
+Force YAML 1.1 rules, when input does not specify a version via a directive.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-yaml\-1.2
+Force YAML 1.2 rules, when input does not specify a version via a directive.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-yaml\-1.3
+Force YAML 1.3 rules, when input does not specify a version via a directive.
+This option is experimental since the 1.3 spec is not yet released.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-disable\-accel
+Disable use of acceleration features; use less memory but potentially more CPU.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-disable\-buffering
+Disable use stdio bufferring, reads will be performed via unix fd reads. This
+may reduce latency when reading from a network file descriptor, or similar.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-disable\-depth\-limit
+Disable the object depth limit, which is usually set to a value near 60.
+Using this option is is possible to process even pathological inputs when
+using the default non\-recursive build mode.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-prefer\-recursive
+Prefer recursive build methods, instead of iterative. This field is merely here
+for evaluation purposes and will be removed in a future version.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-sloppy\-flow\-indentation
+Use sloppy flow indentation, where indentation is not taken into account in flow
+mode, even when the input is invalid YAML according to the spec.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-ypath\-aliases
+Process aliases using ypaths. Experimental option.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-streaming
+Only valid when in \fBdump\fP mode, enables streaming mode. This means
+that no in\-memory graph tree is constructed, so indefinite and arbitrary
+large YAML input streams can be processed.
+.sp
+Note that in streaming mode:
+.INDENT 7.0
+.IP \(bu 2
+Key duplication checks are disabled.
+.IP \(bu 2
+No reording of key order is possible when emitting (i.e. \fI\-\-sort\fP is not available).
+.IP \(bu 2
+Alias resolution is not available (i.e. \fI\-\-resolve\fP).
+.UNINDENT
+.UNINDENT
+Resolver Options.INDENT 0.0
+.TP
+.B \-r, \-\-resolve
+Perform anchor and merge key resolution. By default this option is disabled.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-l, \-\-follow
+Follow aliases when performing path traversal. By default this option is disabled.
+.UNINDENT
+Testsuite Options.INDENT 0.0
+.TP
+.B \-\-disable\-flow\-markers
+Do not output flow\-markers for the testsuite output.
+.UNINDENT
+Emitter Options.INDENT 0.0
+.TP
+.B \-i INDENT, \-\-indent=INDENT
+Sets the emitter indent (in spaces). Default is \fB2\fP\&.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-w WIDTH, \-\-width=WIDTH
+Sets the preferred output width of the emitter. It is generally impossible
+to strictly adhere to this limit so this is treated as a hint at best.
+It not valid in any oneline output modes (i.e. \fIflow\-oneline\fP or \fIjson\-oneline\fP).
+Default value is 80.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-m MODE, \-\-mode=MODE
+Sets the output mode of the YAML emitted. Possible values are:
+.INDENT 7.0
+.IP \(bu 2
+\fBoriginal\fP
+.sp
+The original formatting used in the input. This is default mode.
+.IP \(bu 2
+\fBblock\fP
+.sp
+The output is forced to be in block mode. All flow constructs will
+be converted to block mode.
+.IP \(bu 2
+\fBflow\fP
+.sp
+The output is forced to be in flow mode. All block constructs will
+be converted to flow mode.
+.IP \(bu 2
+\fBflow\-oneline\fP
+.sp
+The output is forced to be in flow mode, but no newlines will be
+emitted; the output is going to be a (potentially very) long line.
+.IP \(bu 2
+\fBjson\fP
+.sp
+The output is forced to be in JSON mode. Note that it is impossible
+to output an arbitrary YAML file as JSON, so this may fail.
+.IP \(bu 2
+\fBjson\-oneline\fP
+.sp
+The output is forced to be in JSON mode and in a single line.
+.IP \(bu 2
+\fBdejson\fP
+.sp
+Output is in block YAML mode but with special care to convert
+JSON quoted strings in as non\-idiomatic YAML as possible.
+For example \fI{ foo: "this is a test" }\fP will be emitted as
+\fIfoo: this is a test\fP\&. YAML can handle scalars without using
+excessive quoting.
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-C MODE, \-\-color=MODE
+It is possible to colorize output using ANSI color escape sequences,
+and the mode can be one of:
+.INDENT 7.0
+.IP \(bu 2
+\fBoff\fP
+.sp
+Never colorize output.
+.IP \(bu 2
+\fBon\fP
+.sp
+Always colorize output.
+.IP \(bu 2
+\fBauto\fP
+.sp
+Automatically colorize output when the output is a terminal.
+This is the default.
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-V, \-\-visible
+Make all whitespace (spaces, unicode spaces and linebreaks) visible.
+Note that this is performed using UTF8 characters so it will not work
+on non\-UTF8 terminals, or a non\-UTF8 complete font.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-s, \-\-sort
+Sort keys on output. This option is disabled by default.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-c, \-\-comment
+Experimental output comments option. Enabled output while preserving comments.
+Disabled by default.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-strip\-labels
+Strip labels on output. Disabled by default.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-strip\-tags
+Strip tags on output. Disabled by default.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-strip\-doc
+Strip document indicators on output. Disabled by default.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-null\-output
+Do not generate any output, useful for profiling the parser.
+.UNINDENT
+YPATH options.INDENT 0.0
+.TP
+.B \-\-dump\-pathexpr
+Dump the produced path expression for debugging.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-no\-exec
+Do not execute the expression. Useful when used with \fI\-\-dump\-pathexpr\fP
+.UNINDENT
+Compose options.INDENT 0.0
+.TP
+.B \-\-dump\-path
+Dump the path while composing.
+.UNINDENT
+Tool mode select options.INDENT 0.0
+.TP
+.B \-\-dump
+Select \fIdump\fP mode of operation. This is the default.
+This mode is also enabled when the called binary is aliased to
+\fIfy\-dump\fP\&.
+.sp
+In this mode, all files provided in the command line will be dumped
+in one continuous stream, to the standard output, using document start
+indicators to mark the start of end new file.
+.sp
+If the file provided is \fI\-\fP then the input is the standard input.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-testsuite
+Select \fItestsuite\fP mode of operation.
+This mode is also enabled when the called binary is aliased to \fIfy\-testsuite\fP\&.
+.sp
+In this mode, a single YAML file is read and an event stream is
+generated which is the format used for \fIyaml\-testsuite\fP compliance.
+.sp
+If the file provided is \fI\-\fP then the input is the standard input.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-filter
+Select \fIfilter\fP mode of operation.
+This mode is also enabled when the called binary is aliased to \fIfy\-filter\fP\&.
+.sp
+In this mode, a single YAML file is read from the standard input for each path
+that is provided in the command line a document will be produced to the
+standard output.
+To use file instead of standard input use the \fI\-f/\-\-file\fP option.
+.sp
+If the file provided is \fI\-\fP then the input is the standard input.
+.INDENT 7.0
+.TP
+.B \-f FILE, \-\-file=FILE
+Use the given file as input instead of standard input.
+.sp
+If first character of \fIFILE\fP is \fB>\fP the the input is the content of the option
+that follows.
+For example \-\-file ">foo: bar" is as \-\-file file.yaml with file.yaml "foo: bar"
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-join
+Select \fIjoin\fP mode of operation.
+This mode is also enabled when the called binary is aliased to \fIfy\-join\fP\&.
+.sp
+In this mode, multiple YAML files are joined into a single document, emitted
+to the standard output.
+.sp
+If the file provided is \fI\-\fP then the input is the standard input.
+.INDENT 7.0
+.TP
+.B \-T PATH, \-\-to=PATH
+The target path of the join. By default this is the root \fB/\fP\&.
+.sp
+If first character of \fIFILE\fP is \fB>\fP the the input is the content of the option
+that follows.
+.UNINDENT
+.INDENT 7.0
+.TP
+.B \-F PATH, \-\-from=PATH
+The origin path of the join (for each input). By default this is the root \fB/\fP\&.
+.sp
+If first character of \fIFILE\fP is \fB>\fP the the input is the content of the option
+that follows.
+.UNINDENT
+.INDENT 7.0
+.TP
+.B \-t PATH, \-\-trim=PATH
+Trim path of the output of the join. By default this is the root \fB/\fP\&.
+.sp
+If first character of \fIFILE\fP is \fB>\fP the the input is the content of the option
+that follows.
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-ypath
+Process files and output query results using ypath.
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-\-compose
+Use the composer API to build the document instead of direct events.
+.UNINDENT
+.SH EXAMPLES
+Example input files
+.sp
+We\(aqre going to be using a couple of YAML files in our examples.
+.sp
+invoice.yaml
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+# invoice.yaml
+invoice: 34843
+date : !!str 2001\-01\-23
+bill\-to: &id001
+given : Chris
+family : Dumars
+address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+simple\-anchors.yaml
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+# simple\-anchors.yaml
+foo: &label { bar: frooz }
+baz: *label
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+mergekeyspec.yaml
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+\-\-\-
+\- &CENTER { x: 1, y: 2 }
+\- &LEFT { x: 0, y: 2 }
+\- &BIG { r: 10 }
+\- &SMALL { r: 1 }
+
+# All the following maps are equal:
+
+\- # Explicit keys
+ x: 1
+ y: 2
+ r: 10
+ label: center/big
+
+\- # Merge one map
+ << : *CENTER
+ r: 10
+ label: center/big
+
+\- # Merge multiple maps
+ << : [ *CENTER, *BIG ]
+ label: center/big
+
+\- # Override
+ << : [ *BIG, *LEFT, *SMALL ]
+ x: 1
+ label: center/big
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+bomb.yaml
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
+b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
+c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
+d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
+e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
+f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
+g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+fy\-dump examples.
+.sp
+Parse and dump generated YAML document tree in the original YAML form
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump invoice.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+invoice: 34843
+date: !!str 2001\-01\-23
+bill\-to: &id001
+given: Chris
+family: Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Parse and dump generated YAML document tree in flow YAML form
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump \-mflow invoice.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ invoice: 34843,
+ date: !!str 2001\-01\-23,
+ bill\-to: &id001 {
+ given: Chris,
+ family: Dumars,
+ address: {
+ lines: "458 Walkman Dr.\enSuite #292\en"
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Parse and dump generated YAML document from the input string
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump \-mjson ">foo: bar"
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "foo": "bar"
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Using the resolve option on the \fIsimple\-anchors.yaml\fP
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump \-r simple\-anchor.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+foo: &label {
+ bar: frooz
+ }
+baz: {
+ bar: frooz
+ }
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Stripping the labels too:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump \-r \-\-strip\-label simple\-anchor.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+foo: {
+ bar: frooz
+ }
+baz: {
+ bar: frooz
+ }
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Merge key support:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump \-r \-\-strip\-label mergekeyspec.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+\-\-\-
+\- {
+ x: 1,
+ y: 2
+ }
+\- {
+ x: 0,
+ y: 2
+ }
+\- {
+ r: 10
+ }
+\- {
+ r: 1
+ }
+\- x: 1
+ y: 2
+ r: 10
+ label: center/big
+\- y: 2
+ x: 1
+ r: 10
+ label: center/big
+\- r: 10
+ y: 2
+ x: 1
+ label: center/big
+\- y: 2
+ r: 10
+ x: 1
+ label: center/big
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Sorting option:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-dump \-s invoice.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+bill\-to: &id001
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ family: Dumars
+ given: Chris
+date: !!str 2001\-01\-23
+invoice: 34843
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+fy\-testsuite example.
+.sp
+An example using the testsuite mode generates the following
+event stream from \fIinvoice.yaml\fP
+.sp
+Parse and dump test\-suite event format
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-testsuite invoice.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+fy\-filter examples.
+.sp
+Filter out from the \fI/bill\-to\fP path of \fIinvoice.yaml\fP
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ cat invoice.yaml | fy\-filter /bill\-to
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+&id001
+given: Chris
+family: Dumars
+address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Filter example with arrays (and use the \-\-file option)
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-filter \-\-file=mergekeyspec.yaml /5
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+\-\-\-
+<<: *CENTER
+r: 10
+label: center/big
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Follow anchors example
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-filter \-\-file=simple\-anchors.yaml /baz/bar
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+frooz
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Handle YAML bombs (if you can spare the memory and cpu time)
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-filter \-\-file=bomb.yaml \-r / | wc \-l
+6726047
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+You don\(aqt have to, you can just follow links to retrieve data.
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-filter \-\-file=stuff/bomb.yaml \-l \-\-strip\-label /g/0/1/2/3/4/5/6
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+"lol"
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Following links works with merge keys too:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-filter \-\-file=mergekeyspec.yaml \-l \-\-strip\-label /5/x
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+\-\-\- 1
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+fy\-join examples.
+.sp
+Joining two YAML files that have root mappings.
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-join simple\-anchors.yaml invoice.yaml
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+foo: &label {
+ bar: frooz
+ }
+baz: *label
+invoice: 34843
+date: !!str 2001\-01\-23
+bill\-to: &id001
+ given: Chris
+ family: Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Join two files with sequences at root:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ fy\-join \-mblock ">[ foo, bar ]" ">[ baz ]"
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+\- foo
+\- bar
+\- baz
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.SH AUTHOR
+.sp
+Pantelis Antoniou <\fI\%pantelis.antoniou@konsulko.com\fP>
+.SH BUGS
+.INDENT 0.0
+.IP \(bu 2
+The only supported input and output character encoding is UTF8.
+.IP \(bu 2
+Sorting does not respect language settings.
+.IP \(bu 2
+There is no way for the user to specific a different coloring scheme.
+.UNINDENT
+.SH SEE ALSO
+.sp
+\fBlibfyaml(1)\fP
+.SH COPYRIGHT
+2019, Pantelis Antoniou
+.\" Generated by docutils manpage writer.
+.
**fy-join** [*OPTIONS*] [-T*PATH*] [-F*PATH*] [-t*PATH*] [<*file*> ...]
+**fy-ypath** [*OPTIONS*] <*ypath-expression> [<*file*> ...]
+
+**fy-compose** [*OPTIONS*] [<*file*> ...]
+
Description
-----------
:program:`fy-tool` is a general YAML/JSON manipulation tool using `libfyaml`.
Its operation is different depending on how it's called, either via aliases
named `fy-dump`, `fy-testsuite`, `fy-filter`, `fy-join`, or via the
-`--dump`, `--testsuite`, `--filter`, `--join` options.
+`--dump`, `--testsuite`, `--filter`, `--join`, `--ypath` and `--compose` options.
* In `dump` mode it will parse YAML/JSON input files and output YAML/JSON
according to the output format options.
* In `join` mode it will parse YAML/JSON files and join them into a single
YAML/JSON document according to the given command line options.
+* In `ypath` mode it will parse YAML/JSON files and execute a ypath query
+ which will output a document stream according to the results. This is
+ an experimental mode under development, where the syntax is not yet
+ decided completely.
+
+* In `compose` mode, it operates similarly to dump, but the document tree
+ is created using the built-in composer API.
+
Options
-------
The input files are always in YAML mode.
- - **yes**
+ - **force**
The input files are always set to JSON mode.
The input files are set to JSON mode automatically when the
file's extension is `.json`. This is the default.
- Note that although libfyaml's YAML 1.2 support is complete, that simply
- means that a valid JSON file will parse as YAML 1.2. However there
- are instances where one requires strict JSON spec adherence, and
- for invalid JSON to be rejected even when it's valid YAML 1.2.
+ JSON support is complete so all valid JSON files are parsed according
+ to JSON rules, even where those differ with YAML rules.
+
+.. option:: --yaml-1.1
+
+ Force YAML 1.1 rules, when input does not specify a version via a directive.
+
+.. option:: --yaml-1.2
+
+ Force YAML 1.2 rules, when input does not specify a version via a directive.
+
+.. option:: --yaml-1.3
+
+ Force YAML 1.3 rules, when input does not specify a version via a directive.
+ This option is experimental since the 1.3 spec is not yet released.
+
+.. option:: --disable-accel
+
+ Disable use of acceleration features; use less memory but potentially more CPU.
+
+.. option:: --disable-buffering
+
+ Disable use stdio bufferring, reads will be performed via unix fd reads. This
+ may reduce latency when reading from a network file descriptor, or similar.
+
+.. option:: --disable-depth-limit
+
+ Disable the object depth limit, which is usually set to a value near 60.
+ Using this option is is possible to process even pathological inputs when
+ using the default non-recursive build mode.
+
+.. option:: --prefer-recursive
+
+ Prefer recursive build methods, instead of iterative. This field is merely here
+ for evaluation purposes and will be removed in a future version.
+
+.. option:: --sloppy-flow-indentation
+
+ Use sloppy flow indentation, where indentation is not taken into account in flow
+ mode, even when the input is invalid YAML according to the spec.
+
+.. option:: --ypath-aliases
+
+ Process aliases using ypaths. Experimental option.
.. option:: --streaming
Follow aliases when performing path traversal. By default this option is disabled.
+.. rubric:: Testsuite Options
+
+.. option:: --disable-flow-markers
+
+ Do not output flow-markers for the testsuite output.
+
.. rubric:: Emitter Options
.. option:: -i INDENT, --indent=INDENT
Strip document indicators on output. Disabled by default.
+.. option:: --null-output
+
+ Do not generate any output, useful for profiling the parser.
+
+.. rubric:: YPATH options
+
+.. option:: --dump-pathexpr
+
+ Dump the produced path expression for debugging.
+
+.. option:: --no-exec
+
+ Do not execute the expression. Useful when used with `--dump-pathexpr`
+
+.. rubric:: Compose options
+
+.. option:: --dump-path
+
+ Dump the path while composing.
+
.. rubric:: Tool mode select options
.. option:: --dump
If first character of `FILE` is **>** the the input is the content of the option
that follows.
+.. option:: --ypath
+
+ Process files and output query results using ypath.
+
+.. option:: --compose
+
+ Use the composer API to build the document instead of direct events.
+
Examples
--------
/*
* libfyaml.h - Main header file of the public interface
*
- * Copyright (c) 2019 Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+ * Copyright (c) 2019-2021 Pantelis Antoniou <pantelis.antoniou@konsulko.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
struct fy_path_exec;
struct fy_path_component;
struct fy_path;
+struct fy_document_iterator;
#ifndef FY_BIT
* @FYPCF_JSON_NONE: Never enable JSON input mode
* @FYPCF_JSON_FORCE: Force JSON mode always
* @FYPCF_YPATH_ALIASES: Enable YPATH aliases mode
+ * @FYPCF_ALLOW_DUPLICATE_KEYS: Allow duplicate keys on mappings
*/
enum fy_parse_cfg_flags {
FYPCF_QUIET = FY_BIT(0),
FYPCF_JSON_NONE = FYPCF_JSON(1),
FYPCF_JSON_FORCE = FYPCF_JSON(2),
FYPCF_YPATH_ALIASES = FY_BIT(18),
+ FYPCF_ALLOW_DUPLICATE_KEYS = FY_BIT(19),
};
#define FYPCF_DEFAULT_PARSE (0)
FYSS_MAX,
};
+/**
+ * struct fy_event_stream_start_data - stream start event data
+ *
+ * @stream_start: The token that started the stream
+ */
+struct fy_event_stream_start_data {
+ struct fy_token *stream_start;
+};
+
+/*
+ * struct fy_event_stream_end_data - stream end event data
+ *
+ * @stream_end: The token that ended the stream
+ */
+struct fy_event_stream_end_data {
+ struct fy_token *stream_end;
+};
+
+/*
+ * struct fy_event_document_start_data - doument start event data
+ *
+ * @document_start: The token that started the document, or NULL if
+ * the document was implicitly started.
+ * @document_state: The state of the document (i.e. information about
+ * the YAML version and configured tags)
+ * @implicit: True if the document started implicitly
+ */
+struct fy_event_document_start_data {
+ struct fy_token *document_start;
+ struct fy_document_state *document_state;
+ bool implicit;
+};
+
+/*
+ * struct fy_event_document_end_data - doument end event data
+ *
+ * @document_end: The token that ended the document, or NULL if the
+ * document was implicitly ended
+ * @implicit: True if the document ended implicitly
+ */
+struct fy_event_document_end_data {
+ struct fy_token *document_end;
+ bool implicit;
+};
+
+/*
+ * struct fy_event_alias_data - alias event data
+ *
+ * @anchor: The anchor token definining this alias.
+ */
+struct fy_event_alias_data {
+ struct fy_token *anchor;
+};
+
+/*
+ * struct fy_event_scalar_data - scalar event data
+ *
+ * @.anchor: anchor token or NULL
+ * @tag: tag token or NULL
+ * @value: scalar value token (cannot be NULL)
+ * @tag_implicit: true if the tag was implicit or explicit
+ */
+struct fy_event_scalar_data {
+ struct fy_token *anchor;
+ struct fy_token *tag;
+ struct fy_token *value;
+ bool tag_implicit;
+};
+
+/*
+ * struct fy_event_sequence_start_data - sequence start event data
+ *
+ * @anchor: anchor token or NULL
+ * @tag: tag token or NULL
+ * @sequence_start: sequence start value token or NULL if the sequence
+ * was started implicitly
+ */
+struct fy_event_sequence_start_data {
+ struct fy_token *anchor;
+ struct fy_token *tag;
+ struct fy_token *sequence_start;
+};
+
+/*
+ * struct fy_event_sequence_end_data - sequence end event data
+ *
+ * @sequence_end: The token that ended the sequence, or NULL if
+ * the sequence was implicitly ended
+ */
+struct fy_event_sequence_end_data {
+ struct fy_token *sequence_end;
+};
+
+/*
+ * struct fy_event_mapping_start_data - mapping start event data
+ *
+ * @anchor: anchor token or NULL
+ * @tag: tag token or NULL
+ * @mapping_start: mapping start value token or NULL if the mapping
+ * was started implicitly
+ */
+struct fy_event_mapping_start_data {
+ struct fy_token *anchor;
+ struct fy_token *tag;
+ struct fy_token *mapping_start;
+};
+
+/*
+ * struct fy_event_mapping_end_data - mapping end event data
+ *
+ * @mapping_end: The token that ended the mapping, or NULL if
+ * the mapping was implicitly ended
+ */
+struct fy_event_mapping_end_data {
+ struct fy_token *mapping_end;
+};
+
/**
* struct fy_event - Event generated by the parser
*
*
* @stream_start: Stream start information, it is valid when
* &fy_event->type is &enum FYET_STREAM_START
- * @stream_start.stream_start: The token that started the stream
- * @stream_end:Stream end information, it is valid when
- * &fy_event->type is &enum FYET_STREAM_END
- * @stream_end.stream_end: The token that ended the stream
- *
+ * @stream_end: Stream end information, it is valid when
+ * &fy_event->type is &enum FYET_STREAM_END
* @document_start: Document start information, it is valid when
* &fy_event->type is &enum FYET_DOCUMENT_START
- * @document_start.document_start: The token that started the document, or
- * NULL if the document was implicitly
- * started
- * @document_start.document_state: The state of the document (i.e. information
- * about the YAML version and configured tags)
- * @document_start.implicit: True if the document started implicitly
- *
* @document_end: Document end information, it is valid when
* &fy_event->type is &enum FYET_DOCUMENT_END
- * @document_end.document_end: The token that ended the document, or
- * NULL if the document was implicitly ended
- * @document_end.implicit: True if the document ended implicitly
- *
* @alias: Alias information, it is valid when
* &fy_event->type is &enum FYET_ALIAS
- * @alias.anchor: The anchor token definining this alias.
- *
* @scalar: Scalar information, it is valid when
* &fy_event->type is &enum FYET_SCALAR
- * @scalar.anchor: anchor token or NULL
- * @scalar.tag: tag token or NULL
- * @scalar.value: scalar value token (cannot be NULL)
- * @scalar.tag_implicit: true if the tag was implicit or explicit
- *
* @sequence_start: Sequence start information, it is valid when
* &fy_event->type is &enum FYET_SEQUENCE_START
- * @sequence_start.anchor: anchor token or NULL
- * @sequence_start.tag: tag token or NULL
- * @sequence_start.sequence_start: sequence start value token or NULL if
- * the sequence was started implicitly
* @sequence_end: Sequence end information, it is valid when
* &fy_event->type is &enum FYET_SEQUENCE_END
- * @sequence_end.sequence_end: The token that ended the sequence, or
- * NULL if the sequence was implicitly ended
- *
* @mapping_start: Mapping start information, it is valid when
* &fy_event->type is &enum FYET_MAPPING_START
- * @mapping_start.anchor: anchor token or NULL
- * @mapping_start.tag: tag token or NULL
- * @mapping_start.mapping_start: mapping start value token or NULL if
- * the mapping was started implicitly
* @mapping_end: Mapping end information, it is valid when
* &fy_event->type is &enum FYET_MAPPING_END
- * @mapping_end.mapping_end: The token that ended the mapping, or
- * NULL if the mapping was implicitly ended
*/
struct fy_event {
enum fy_event_type type;
/* anonymous union */
union {
- struct {
- struct fy_token *stream_start;
- } stream_start;
-
- struct {
- struct fy_token *stream_end;
- } stream_end;
-
- struct {
- struct fy_token *document_start;
- struct fy_document_state *document_state;
- bool implicit;
- } document_start;
-
- struct {
- struct fy_token *document_end;
- bool implicit;
- } document_end;
-
- struct {
- struct fy_token *anchor;
- } alias;
-
- struct {
- struct fy_token *anchor;
- struct fy_token *tag;
- struct fy_token *value;
- bool tag_implicit;
- } scalar;
-
- struct {
- struct fy_token *anchor;
- struct fy_token *tag;
- struct fy_token *sequence_start;
- } sequence_start;
-
- struct {
- struct fy_token *sequence_end;
- } sequence_end;
-
- struct {
- struct fy_token *anchor;
- struct fy_token *tag;
- struct fy_token *mapping_start;
- } mapping_start;
-
- struct {
- struct fy_token *mapping_end;
- } mapping_end;
+ struct fy_event_stream_start_data stream_start;
+ struct fy_event_stream_end_data stream_end;
+ struct fy_event_document_start_data document_start;
+ struct fy_event_document_end_data document_end;
+ struct fy_event_alias_data alias;
+ struct fy_event_scalar_data scalar;
+ struct fy_event_sequence_start_data sequence_start;
+ struct fy_event_sequence_end_data sequence_end;
+ struct fy_event_mapping_start_data mapping_start;
+ struct fy_event_mapping_end_data mapping_end;
};
};
+/**
+ * fy_event_data() - Get a pointer to the event data
+ *
+ * Some languages *cough*golang*cough* really don't like
+ * unions, and anonymous unions in particular.
+ *
+ * You should not have to use this in other language bindings.
+ *
+ * @fye: The event
+ *
+ * Returns:
+ * A pointer to the event data structure, or NULL if the
+ * event is invalid
+ */
+static inline void *
+fy_event_data(struct fy_event *fye)
+{
+ if (!fye)
+ return NULL;
+
+ /* note that the unions should all be laid out
+ * at the same address, but play it straight and
+ * hope the optimizer will figure this is all
+ * the same...
+ */
+ switch (fye->type) {
+ case FYET_STREAM_START:
+ return &fye->stream_start;
+ case FYET_STREAM_END:
+ return &fye->stream_end;
+ case FYET_DOCUMENT_START:
+ return &fye->document_start;
+ case FYET_DOCUMENT_END:
+ return &fye->document_end;
+ case FYET_ALIAS:
+ return &fye->alias;
+ case FYET_SCALAR:
+ return &fye->scalar;
+ case FYET_SEQUENCE_START:
+ return &fye->sequence_start;
+ case FYET_SEQUENCE_END:
+ return &fye->sequence_end;
+ case FYET_MAPPING_START:
+ return &fye->mapping_start;
+ case FYET_MAPPING_END:
+ return &fye->mapping_end;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
/**
* fy_library_version() - Return the library version string
*
ssize_t (*callback)(void *user, void *buf, size_t count))
FY_EXPORT;
+/**
+ * fy_parser_set_input_db() - Set the parser to process the given file descriptor
+ *
+ * Point the parser to use @fd for processing.
+ *
+ * @fyp: The parser
+ * @fd: The file descriptor to use
+ *
+ * Returns:
+ * zero on success, -1 on error
+ */
+int
+fy_parser_set_input_fd(struct fy_parser *fyp, int fd)
+ FY_EXPORT;
+
/**
* fy_parser_parse() - Parse and return the next event.
*
* fy_token_get_comment() - Get zero terminated comment of a token
*
* @fyt: The token out of which the comment text will be returned.
+ * @buf: The buffer to be filled with the contents of the token
+ * @maxsz: The maximum size of the comment buffer
+ * @which: The comment placement
*
* Returns:
* A pointer to a zero terminated text representation of the token comment.
* @FYECF_STRIP_TAGS: Strip tags when emitting
* @FYECF_STRIP_DOC: Strip document tags and markers when emitting
* @FYECF_NO_ENDING_NEWLINE: Do not output ending new line (useful for single line mode)
+ * @FYECF_STRIP_EMPTY_KV: Remove all keys with empty values from the output (not available in streaming mode)
* @FYECF_INDENT_DEFAULT: Default emit output indent
* @FYECF_INDENT_1: Output indent is 1
* @FYECF_INDENT_2: Output indent is 2
* @FYECF_MODE_JSON_TP: Emit using JSON mode (type preserving)
* @FYECF_MODE_JSON_ONELINE: Emit using JSON mode (non type preserving, one line)
* @FYECF_MODE_DEJSON: Emit YAML trying to pretify JSON
+ * @FYECF_MODE_PRETTY: Emit YAML that tries to look good
* @FYECF_DOC_START_MARK_AUTO: Automatically generate document start markers if required
* @FYECF_DOC_START_MARK_OFF: Do not generate document start markers
* @FYECF_DOC_START_MARK_ON: Always generate document start markers
FYECF_STRIP_TAGS = FY_BIT(3),
FYECF_STRIP_DOC = FY_BIT(4),
FYECF_NO_ENDING_NEWLINE = FY_BIT(5),
+ FYECF_STRIP_EMPTY_KV = FY_BIT(6),
FYECF_INDENT_DEFAULT = FYECF_INDENT(0),
FYECF_INDENT_1 = FYECF_INDENT(1),
FYECF_INDENT_2 = FYECF_INDENT(2),
FYECF_MODE_JSON_TP = FYECF_MODE(5),
FYECF_MODE_JSON_ONELINE = FYECF_MODE(6),
FYECF_MODE_DEJSON = FYECF_MODE(7),
+ FYECF_MODE_PRETTY = FYECF_MODE(8),
FYECF_DOC_START_MARK_AUTO = FYECF_DOC_START_MARK(0),
FYECF_DOC_START_MARK_OFF = FYECF_DOC_START_MARK(1),
FYECF_DOC_START_MARK_ON = FYECF_DOC_START_MARK(2),
fy_emitter_set_diag(struct fy_emitter *emit, struct fy_diag *diag)
FY_EXPORT;
+/**
+ * fy_emitter_set_finalizer() - Set emitter finalizer
+ *
+ * Set a method callback to be called when the emitter
+ * is disposed of. If finalizer is NULL, then the method
+ * is removed.
+ *
+ * @emit: The emitter to replace the diagnostic object
+ * @finalizer: The finalizer callback
+ */
+void
+fy_emitter_set_finalizer(struct fy_emitter *emit,
+ void (*finalizer)(struct fy_emitter *emit))
+ FY_EXPORT;
+
/**
* struct fy_emitter_default_output_data - emitter default output configuration
*
const char *filename)
FY_EXPORT;
+/**
+ * fy_emit_document_to_fd() - Emit a document to a file descriptor
+ *
+ * Emits a document from the root to the given file descriptor
+ *
+ * @fyd: The document to emit
+ * @flags: The emitter flags to use
+ * @fd: The file descriptor to output to
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ */
+int
+fy_emit_document_to_fd(struct fy_document *fyd,
+ enum fy_emitter_cfg_flags flags, int fd)
+ FY_EXPORT;
+
/**
* fy_emit_document_to_buffer() - Emit a document to a buffer
*
int
fy_emit_document_to_buffer(struct fy_document *fyd,
enum fy_emitter_cfg_flags flags,
- char *buf, int size)
+ char *buf, size_t size)
FY_EXPORT;
/**
*/
int
fy_emit_node_to_buffer(struct fy_node *fyn, enum fy_emitter_cfg_flags flags,
- char *buf, int size)
+ char *buf, size_t size)
FY_EXPORT;
/**
#define fy_emit_node_to_string_alloca(_fyn, _flags) \
FY_ALLOCA_COPY_FREE(fy_emit_node_to_string((_fyn), (_flags)), FY_NT)
+/**
+ * fy_emit_to_buffer() - Create an emitter for buffer output.
+ *
+ * Creates a special purpose emitter for buffer output.
+ * Calls to fy_emit_event() populate the buffer.
+ * The contents are retreived by a call to fy_emit_to_buffer_collect()
+ *
+ * @flags: The emitter flags to use
+ * @buf: Pointer to the buffer area to fill
+ * @size: Size of the buffer
+ *
+ * Returns:
+ * The newly created emitter or NULL on error.
+ */
+struct fy_emitter *
+fy_emit_to_buffer(enum fy_emitter_cfg_flags flags, char *buf, size_t size)
+ FY_EXPORT;
+
+/**
+ * fy_emit_to_buffer_collect() - Collect the buffer emitter output
+ *
+ * Collects the output of the emitter which was created by
+ * fy_emit_to_buffer() and populated using fy_emit_event() calls.
+ * The NULL terminated returned buffer is the same as the one used in the
+ * fy_emit_to_buffer() call and the sizep argument will be filled with
+ * the size of the buffer.
+ *
+ * @emit: The emitter
+ * @sizep: Pointer to the size to be filled
+ *
+ * Returns:
+ * The buffer or NULL in case of an error.
+ */
+char *
+fy_emit_to_buffer_collect(struct fy_emitter *emit, size_t *sizep)
+ FY_EXPORT;
+
+/**
+ * fy_emit_to_string() - Create an emitter to create a dynamically
+ * allocated string.
+ *
+ * Creates a special purpose emitter for output to a dynamically
+ * allocated string.
+ * Calls to fy_emit_event() populate the buffer.
+ * The contents are retreived by a call to fy_emit_to_string_collect()
+ *
+ * @flags: The emitter flags to use
+ *
+ * Returns:
+ * The newly created emitter or NULL on error.
+ */
+struct fy_emitter *
+fy_emit_to_string(enum fy_emitter_cfg_flags flags)
+ FY_EXPORT;
+
+/**
+ * fy_emit_to_string_collect() - Collect the string emitter output
+ *
+ * Collects the output of the emitter which was created by
+ * fy_emit_to_string() and populated using fy_emit_event() calls.
+ * The NULL terminated returned buffer is dynamically allocated
+ * and must be freed via a call to free().
+ * The sizep argument will be filled with the size of the buffer.
+ *
+ * @emit: The emitter
+ * @sizep: Pointer to the size to be filled
+ *
+ * Returns:
+ * The dynamically allocated string or NULL in case of an error.
+ */
+char *
+fy_emit_to_string_collect(struct fy_emitter *emit, size_t *sizep)
+ FY_EXPORT;
+
/**
* fy_node_copy() - Copy a node, associating the new node with the given document
*
* If no such parent is found then returns the absolute path
* from the start of the document.
*
- * --- &foo
- * foo: &bar
- * bar
- * baz
+ * --- &foo
+ * foo: &bar
+ * bar
+ * baz
*
* - The short path of /foo is \*foo
* - The short path of /foo/bar is \*bar
int module_width;
};
+/**
+ * struct fy_diag_error - A collected diagnostic error
+ *
+ * @type: Error type
+ * @module: The module
+ * @fyt: The token (may be NULL)
+ * @msg: The message to be output alongside
+ * @file: The file which contained the input
+ * @line: The line at the error
+ * @column: The column at the error
+ *
+ * This structure contains information about an error
+ * being collected by the diagnostic object.
+ */
+struct fy_diag_error {
+ enum fy_error_type type;
+ enum fy_error_module module;
+ struct fy_token *fyt;
+ const char *msg;
+ const char *file;
+ int line;
+ int column;
+};
+
/**
* fy_diag_create() - Create a diagnostic object
*
fy_diag_reset_error(struct fy_diag *diag)
FY_EXPORT;
+/**
+ * fy_diag_set_collect_errors() - Collect errors instead of outputting
+ *
+ * Set the collect errors mode. When true instead of outputting to
+ * the diagnostic interface, errors are collected for later
+ * retrieval.
+ *
+ * @diag: The diagnostic object
+ * @collect_errors: The collect errors mode
+ */
+void
+fy_diag_set_collect_errors(struct fy_diag *diag, bool collect_errors)
+ FY_EXPORT;
+
/**
* fy_diag_cfg_default() - Fill in the configuration structure
* with defaults
__attribute__((format(printf, 7, 8)))
FY_EXPORT;
+/**
+ * fy_diag_errors_iterate() - Iterate over the errors of a diagnostic object
+ *
+ * This method iterates over all the errors collected on the diagnostic object.
+ * The start of the iteration is signalled by a NULL in \*prevp.
+ *
+ * @diag: The diagnostic object
+ * @prevp: The previous result iterator
+ *
+ * Returns:
+ * The next errors or NULL when there are not any more.
+ */
+struct fy_diag_error *
+fy_diag_errors_iterate(struct fy_diag *diag, void **prevp)
+ FY_EXPORT;
+
/**
* enum fy_path_parse_cfg_flags - Path parse configuration flags
*
* @FYTT_PE_GT: Greater than operator
* @FYTT_PE_LTE: Less or equal than operator
* @FYTT_PE_GTE: Greater or equal than operator
- * @FYTT_PE_PLUS: Plus operator
- * @FYTT_PE_MINUS: Minus operator
- * @FYTT_PE_MULT: Multiply operator
- * @FYTT_PE_DIV: Divide operator
+ * @FYTT_SE_PLUS: Plus operator
+ * @FYTT_SE_MINUS: Minus operator
+ * @FYTT_SE_MULT: Multiply operator
+ * @FYTT_SE_DIV: Divide operator
* @FYTT_PE_METHOD: Path expression method (chained)
* @FYTT_SE_METHOD: Scalar expression method (non chained)
*/
fy_document_state_end_implicit(struct fy_document_state *fyds)
FY_EXPORT;
+/**
+ * fy_document_state_json_mode() - Input was JSON?
+ *
+ * Find out if a document state object's document was
+ * created by a JSON input.
+ * Note that for synthetic documents this method returns false.
+ *
+ * @fyds: The document state object
+ *
+ * Returns:
+ * true if document was created in JSON mode, false otherwise
+ */
+bool
+fy_document_state_json_mode(struct fy_document_state *fyds)
+ FY_EXPORT;
+
/**
* fy_document_state_tag_directive_iterate() - Iterate over the tag
* directives of a document state
fy_path_component_mapping_get_scalar_key(struct fy_path_component *fypc)
FY_EXPORT;
+/**
+ * fy_path_component_mapping_get_scalar_key_tag() - Get the scalar key's tag of a mapping
+ *
+ * @fypc: The mapping path component to return it's scalar key's tag
+ *
+ * Returns:
+ * a non NULL tag token if the mapping contains a scalar key with a tag or
+ * NULL in case of an error, or if the component has a complex key
+ */
+struct fy_token *
+fy_path_component_mapping_get_scalar_key_tag(struct fy_path_component *fypc)
+ FY_EXPORT;
+
/**
* fy_path_component_mapping_get_complex_key() - Get the complex key of a mapping
*
fy_path_component_mapping_get_complex_key(struct fy_path_component *fypc)
FY_EXPORT;
+/**
+ * fy_path_component_get_text() - Get the textual representation of a path component
+ *
+ * Given a path component, return a malloc'ed string which contains
+ * the textual representation of it.
+ *
+ * Note that this method will only return fully completed components and not
+ * ones that are in the building process.
+ *
+ * @fypc: The path component to get it's textual representation
+ *
+ * Returns:
+ * The textual representation of the path component, NULL on error, or
+ * if the component has not been completely built during the composition
+ * of a complex key.
+ * The string must be free'ed using free.
+ */
+char *
+fy_path_component_get_text(struct fy_path_component *fypc)
+ FY_EXPORT;
+
+#define fy_path_component_get_text_alloca(_fypc) \
+ FY_ALLOCA_COPY_FREE(fy_path_component_get_text((_fypc)), FY_NT)
/**
* fy_path_depth() - Get the depth of a path
*
FY_EXPORT;
/**
- * fy_path_in_mapping_key() - Check if the path is in a mapping value state
+ * fy_path_in_mapping_value() - Check if the path is in a mapping value state
*
* @fypp: The path
*
* true if the path is located within a collectin root state
*/
bool
-fy_path_is_collection_root(struct fy_path *fypp)
+fy_path_in_collection_root(struct fy_path *fypp)
+ FY_EXPORT;
+
+/**
+ * fy_path_get_root_user_data() - Return the userdata associated with the path root
+ *
+ * @fypp: The path
+ *
+ * Returns:
+ * The user data associated with the root of the path, or NULL if no path
+ */
+void *
+fy_path_get_root_user_data(struct fy_path *fypp)
+ FY_EXPORT;
+
+/**
+ * fy_path_set_root_user_data() - Set the user data associated with the root
+ *
+ * Note, no error condition if not a path
+ *
+ * @fypp: The path
+ * @data: The data to set as root data
+ */
+void
+fy_path_set_root_user_data(struct fy_path *fypp, void *data)
FY_EXPORT;
/**
FY_EXPORT;
/**
- * fy_path_component_get_sequence_data() - Return the userdata associated with the sequence
+ * fy_path_component_get_sequence_user_data() - Return the userdata associated with the sequence
*
* @fypc: The path component
*
fy_path_last_not_collection_root_component(struct fy_path *fypp)
FY_EXPORT;
+/**
+ * fy_document_iterator_create() - Create a document iterator
+ *
+ * Creates a document iterator, that can trawl through a document
+ * without using recursion.
+ *
+ * Returns:
+ * The newly created document iterator or NULL on error
+ */
+struct fy_document_iterator *
+fy_document_iterator_create(void)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_destroy() - Destroy the given document iterator
+ *
+ * Destroy a document iterator created earlier via fy_document_iterator_create().
+ *
+ * @fydi: The document iterator to destroy
+ */
+void
+fy_document_iterator_destroy(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_event_free() - Free an event that was created by a document iterator
+ *
+ * Free (possibly recycling) an event that was created by a document iterator.
+ *
+ * @fydi: The document iterator that created the event
+ * @fye: The event
+ */
+void
+fy_document_iterator_event_free(struct fy_document_iterator *fydi, struct fy_event *fye)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_stream_start() - Create a stream start event using the iterator
+ *
+ * Creates a stream start event on the document iterator and advances the internal state
+ * of it accordingly.
+ *
+ * @fydi: The document iterator to create the event
+ *
+ * Returns:
+ * The newly created stream start event, or NULL on error.
+ */
+struct fy_event *
+fy_document_iterator_stream_start(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_stream_end() - Create a stream end event using the iterator
+ *
+ * Creates a stream end event on the document iterator and advances the internal state
+ * of it accordingly.
+ *
+ * @fydi: The document iterator to create the event
+ *
+ * Returns:
+ * The newly created stream end event, or NULL on error.
+ */
+struct fy_event *
+fy_document_iterator_stream_end(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_document_start() - Create a document start event using the iterator
+ *
+ * Creates a document start event on the document iterator and advances the internal state
+ * of it accordingly. The document must not be released until an error, cleanup or a call
+ * to fy_document_iterator_document_end().
+ *
+ * @fydi: The document iterator to create the event
+ * @fyd: The document containing the document state that is used in the event
+ *
+ * Returns:
+ * The newly created document start event, or NULL on error.
+ */
+struct fy_event *
+fy_document_iterator_document_start(struct fy_document_iterator *fydi, struct fy_document *fyd)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_document_end() - Create a document end event using the iterator
+ *
+ * Creates a document end event on the document iterator and advances the internal state
+ * of it accordingly. The document that was used earlier in the call of
+ * fy_document_iterator_document_start() can now be released.
+ *
+ * @fydi: The document iterator to create the event
+ *
+ * Returns:
+ * The newly created document end event, or NULL on error.
+ */
+struct fy_event *
+fy_document_iterator_document_end(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_body_next() - Create document body events until the end
+ *
+ * Creates the next document body, depth first until the end of the document.
+ * The events are created depth first and are in same exact sequence that the
+ * original events that created the document.
+ *
+ * That means that the finite event stream that generated the document is losslesly
+ * preserved in such a way that the document tree representation is functionally
+ * equivalent.
+ *
+ * Repeated calls to this function will generate a stream of SCALAR, ALIAS, SEQUENCE
+ * START, SEQUENCE END, MAPPING START and MAPPING END events, returning NULL at the
+ * end of the body event stream.
+ *
+ * @fydi: The document iterator to create the event
+ *
+ * Returns:
+ * The newly created document body event or NULL at an error, or an end of the
+ * event stream. Use fy_document_iterator_get_error() to check if an error occured.
+ */
+struct fy_event *
+fy_document_iterator_body_next(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_node_start() - Start a document node iteration run using a starting point
+ *
+ * Starts an iteration run starting at the given node.
+ *
+ * @fydi: The document iterator to run with
+ * @fyn: The iterator root for the iteration
+ */
+void
+fy_document_iterator_node_start(struct fy_document_iterator *fydi, struct fy_node *fyn)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_node_next() - Return the next node in the iteration sequence
+ *
+ * Returns a pointer to the next node iterating using as a start the node given
+ * at fy_document_iterator_node_start(). The first node returned will be that,
+ * followed by all the remaing nodes in the subtree.
+ *
+ * @fydi: The document iterator to use for the iteration
+ *
+ * Returns:
+ * The next node in the iteration sequence or NULL at the end, or if an error occured.
+ */
+struct fy_node *
+fy_document_iterator_node_next(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
+/**
+ * fy_document_iterator_get_error() - Get the error state of the document iterator
+ *
+ * Returns the error state of the iterator. If it's in error state, return true
+ * and reset the iterator to the state just after creation.
+ *
+ * @fydi: The document iterator to use for checking it's error state.
+ *
+ * Returns:
+ * true if it was in an error state, false otherwise.
+ */
+bool
+fy_document_iterator_get_error(struct fy_document_iterator *fydi)
+ FY_EXPORT;
+
#ifdef __cplusplus
}
#endif
Name: libfyaml
Description: Fancy YAML 1.3 parser library
Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lfyaml-@MAJOR@.@MINOR@ @PTHREAD_LIBS@
+Libs: -L${libdir} -lfyaml @PTHREAD_LIBS@
Cflags: -I${includedir} @PTHREAD_CFLAGS@
-I$(top_srcdir)/include
AM_CFLAGS =
-lib_LTLIBRARIES = libfyaml-@MAJOR@.@MINOR@.la
-libfyaml_@MAJOR@_@MINOR@_la_SOURCES = \
+lib_LTLIBRARIES = libfyaml.la
+libfyaml_la_SOURCES = \
lib/fy-parse.c lib/fy-parse.h \
lib/fy-utf8.c lib/fy-utf8.h \
lib/fy-types.c lib/fy-types.h \
lib/fy-input.c lib/fy-input.h \
lib/fy-docstate.c lib/fy-docstate.h \
lib/fy-doc.c lib/fy-doc.h \
+ lib/fy-docbuilder.c lib/fy-docbuilder.h \
lib/fy-emit.c lib/fy-emit.h lib/fy-emit-accum.h \
lib/fy-utils.c lib/fy-utils.h \
lib/fy-event.h lib/fy-event.c \
lib/fy-path.c lib/fy-path.h \
lib/fy-composer.c lib/fy-composer.h
-libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS = $(AM_CPPFLAGS) \
+libfyaml_la_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/xxhash
-libfyaml_@MAJOR@_@MINOR@_la_CFLAGS = $(AM_CFLAGS)
-libfyaml_@MAJOR@_@MINOR@_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) \
- $(VERSIONING_LDFLAGS) \
- -version-info 0:0:0
+libfyaml_la_CFLAGS = $(AM_CFLAGS)
+libfyaml_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) \
+ -version $(LIBTOOL_VERSION)
bin_PROGRAMS =
noinst_PROGRAMS =
-I$(top_srcdir)/src/valgrind \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/xxhash
-libfyaml_parser_LDADD = $(AM_LDADD) $(LIBYAML_LIBS) libfyaml-@MAJOR@.@MINOR@.la
+libfyaml_parser_LDADD = $(AM_LDADD) $(LIBYAML_LIBS) libfyaml.la
libfyaml_parser_CFLAGS = $(AM_CFLAGS) $(LIBYAML_CFLAGS)
libfyaml_parser_LDFLAGS = $(AM_LDFLAGS)
valgrind/fy-valgrind.h
fy_tool_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/valgrind
-fy_tool_LDADD = $(AM_LDADD) libfyaml-@MAJOR@.@MINOR@.la
+fy_tool_LDADD = $(AM_LDADD) libfyaml.la
fy_tool_CFLAGS = $(AM_CFLAGS)
fy_tool_LDFLAGS = $(AM_LDFLAGS)
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/shave.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/shave.m4 $(top_srcdir)/.libtool-version \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
-libfyaml_@MAJOR@_@MINOR@_la_LIBADD =
+libfyaml_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
-am_libfyaml_@MAJOR@_@MINOR@_la_OBJECTS = \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo \
- xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo \
- lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo
-libfyaml_@MAJOR@_@MINOR@_la_OBJECTS = \
- $(am_libfyaml_@MAJOR@_@MINOR@_la_OBJECTS)
+am_libfyaml_la_OBJECTS = lib/libfyaml_la-fy-parse.lo \
+ lib/libfyaml_la-fy-utf8.lo lib/libfyaml_la-fy-types.lo \
+ lib/libfyaml_la-fy-diag.lo lib/libfyaml_la-fy-dump.lo \
+ lib/libfyaml_la-fy-atom.lo lib/libfyaml_la-fy-ctype.lo \
+ lib/libfyaml_la-fy-token.lo lib/libfyaml_la-fy-input.lo \
+ lib/libfyaml_la-fy-docstate.lo lib/libfyaml_la-fy-doc.lo \
+ lib/libfyaml_la-fy-docbuilder.lo lib/libfyaml_la-fy-emit.lo \
+ lib/libfyaml_la-fy-utils.lo lib/libfyaml_la-fy-event.lo \
+ xxhash/libfyaml_la-xxhash.lo lib/libfyaml_la-fy-accel.lo \
+ lib/libfyaml_la-fy-walk.lo lib/libfyaml_la-fy-path.lo \
+ lib/libfyaml_la-fy-composer.lo
+libfyaml_la_OBJECTS = $(am_libfyaml_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
-libfyaml_@MAJOR@_@MINOR@_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) \
- $(libfyaml_@MAJOR@_@MINOR@_la_LDFLAGS) $(LDFLAGS) -o $@
+libfyaml_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libfyaml_la_CFLAGS) \
+ $(CFLAGS) $(libfyaml_la_LDFLAGS) $(LDFLAGS) -o $@
@HAVE_LIBYAML_TRUE@am__EXEEXT_1 = libfyaml-parser$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am_fy_tool_OBJECTS = tool/fy_tool-fy-tool.$(OBJEXT)
fy_tool_OBJECTS = $(am_fy_tool_OBJECTS)
-fy_tool_DEPENDENCIES = libfyaml-@MAJOR@.@MINOR@.la
+fy_tool_DEPENDENCIES = libfyaml.la
fy_tool_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(fy_tool_CFLAGS) \
$(CFLAGS) $(fy_tool_LDFLAGS) $(LDFLAGS) -o $@
libfyaml_parser_OBJECTS = $(am_libfyaml_parser_OBJECTS)
am__DEPENDENCIES_1 =
@HAVE_LIBYAML_TRUE@libfyaml_parser_DEPENDENCIES = \
-@HAVE_LIBYAML_TRUE@ $(am__DEPENDENCIES_1) \
-@HAVE_LIBYAML_TRUE@ libfyaml-@MAJOR@.@MINOR@.la
+@HAVE_LIBYAML_TRUE@ $(am__DEPENDENCIES_1) libfyaml.la
libfyaml_parser_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(libfyaml_parser_CFLAGS) $(CFLAGS) $(libfyaml_parser_LDFLAGS) \
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(libfyaml_@MAJOR@_@MINOR@_la_SOURCES) $(fy_tool_SOURCES) \
+SOURCES = $(libfyaml_la_SOURCES) $(fy_tool_SOURCES) \
$(libfyaml_parser_SOURCES)
-DIST_SOURCES = $(libfyaml_@MAJOR@_@MINOR@_la_SOURCES) \
- $(fy_tool_SOURCES) $(am__libfyaml_parser_SOURCES_DIST)
+DIST_SOURCES = $(libfyaml_la_SOURCES) $(fy_tool_SOURCES) \
+ $(am__libfyaml_parser_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEBVERSION = @DEBVERSION@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
+LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIBYAML_CFLAGS = @LIBYAML_CFLAGS@
LIBYAML_LIBS = @LIBYAML_LIBS@
LIPO = @LIPO@
-I$(top_srcdir)/include
AM_CFLAGS =
-lib_LTLIBRARIES = libfyaml-@MAJOR@.@MINOR@.la
-libfyaml_@MAJOR@_@MINOR@_la_SOURCES = \
+lib_LTLIBRARIES = libfyaml.la
+libfyaml_la_SOURCES = \
lib/fy-parse.c lib/fy-parse.h \
lib/fy-utf8.c lib/fy-utf8.h \
lib/fy-types.c lib/fy-types.h \
lib/fy-input.c lib/fy-input.h \
lib/fy-docstate.c lib/fy-docstate.h \
lib/fy-doc.c lib/fy-doc.h \
+ lib/fy-docbuilder.c lib/fy-docbuilder.h \
lib/fy-emit.c lib/fy-emit.h lib/fy-emit-accum.h \
lib/fy-utils.c lib/fy-utils.h \
lib/fy-event.h lib/fy-event.c \
lib/fy-path.c lib/fy-path.h \
lib/fy-composer.c lib/fy-composer.h
-libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS = $(AM_CPPFLAGS) \
+libfyaml_la_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/xxhash
-libfyaml_@MAJOR@_@MINOR@_la_CFLAGS = $(AM_CFLAGS)
-libfyaml_@MAJOR@_@MINOR@_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) \
- $(VERSIONING_LDFLAGS) \
- -version-info 0:0:0
+libfyaml_la_CFLAGS = $(AM_CFLAGS)
+libfyaml_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) \
+ -version $(LIBTOOL_VERSION)
@HAVE_LIBYAML_TRUE@libfyaml_parser_SOURCES = \
@HAVE_LIBYAML_TRUE@ internal/libfyaml-parser.c \
@HAVE_LIBYAML_TRUE@ -I$(top_srcdir)/src/lib \
@HAVE_LIBYAML_TRUE@ -I$(top_srcdir)/src/xxhash
-@HAVE_LIBYAML_TRUE@libfyaml_parser_LDADD = $(AM_LDADD) $(LIBYAML_LIBS) libfyaml-@MAJOR@.@MINOR@.la
+@HAVE_LIBYAML_TRUE@libfyaml_parser_LDADD = $(AM_LDADD) $(LIBYAML_LIBS) libfyaml.la
@HAVE_LIBYAML_TRUE@libfyaml_parser_CFLAGS = $(AM_CFLAGS) $(LIBYAML_CFLAGS)
@HAVE_LIBYAML_TRUE@libfyaml_parser_LDFLAGS = $(AM_LDFLAGS)
fy_tool_SOURCES = \
valgrind/fy-valgrind.h
fy_tool_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/valgrind
-fy_tool_LDADD = $(AM_LDADD) libfyaml-@MAJOR@.@MINOR@.la
+fy_tool_LDADD = $(AM_LDADD) libfyaml.la
fy_tool_CFLAGS = $(AM_CFLAGS)
fy_tool_LDFLAGS = $(AM_LDFLAGS)
include_HEADERS = \
lib/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) lib/$(DEPDIR)
@: > lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-parse.lo: lib/$(am__dirstamp) \
+ lib/$(DEPDIR)/$(am__dirstamp)
+lib/libfyaml_la-fy-utf8.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-types.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-diag.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-dump.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-atom.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-ctype.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-token.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-input.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-docstate.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-doc.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-docbuilder.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-emit.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-utils.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-event.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
xxhash/$(am__dirstamp):
@$(MKDIR_P) xxhash
xxhash/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) xxhash/$(DEPDIR)
@: > xxhash/$(DEPDIR)/$(am__dirstamp)
-xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo: xxhash/$(am__dirstamp) \
+xxhash/libfyaml_la-xxhash.lo: xxhash/$(am__dirstamp) \
xxhash/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-accel.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-walk.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-path.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo: lib/$(am__dirstamp) \
+lib/libfyaml_la-fy-composer.lo: lib/$(am__dirstamp) \
lib/$(DEPDIR)/$(am__dirstamp)
-libfyaml-@MAJOR@.@MINOR@.la: $(libfyaml_@MAJOR@_@MINOR@_la_OBJECTS) $(libfyaml_@MAJOR@_@MINOR@_la_DEPENDENCIES) $(EXTRA_libfyaml_@MAJOR@_@MINOR@_la_DEPENDENCIES)
- $(AM_V_CCLD)$(libfyaml_@MAJOR@_@MINOR@_la_LINK) -rpath $(libdir) $(libfyaml_@MAJOR@_@MINOR@_la_OBJECTS) $(libfyaml_@MAJOR@_@MINOR@_la_LIBADD) $(LIBS)
+libfyaml.la: $(libfyaml_la_OBJECTS) $(libfyaml_la_DEPENDENCIES) $(EXTRA_libfyaml_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libfyaml_la_LINK) -rpath $(libdir) $(libfyaml_la_OBJECTS) $(libfyaml_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-event.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-input.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-path.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-token.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-types.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-accel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-atom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-composer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-ctype.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-diag.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-doc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-docbuilder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-docstate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-dump.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-emit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-event.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-input.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-parse.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-path.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-types.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-utf8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libfyaml_la-fy-walk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tool/$(DEPDIR)/fy_tool-fy-tool.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@xxhash/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-xxhash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@xxhash/$(DEPDIR)/libfyaml_la-xxhash.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo: lib/fy-parse.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo `test -f 'lib/fy-parse.c' || echo '$(srcdir)/'`lib/fy-parse.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-parse.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-parse.lo: lib/fy-parse.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-parse.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-parse.Tpo -c -o lib/libfyaml_la-fy-parse.lo `test -f 'lib/fy-parse.c' || echo '$(srcdir)/'`lib/fy-parse.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-parse.Tpo lib/$(DEPDIR)/libfyaml_la-fy-parse.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-parse.c' object='lib/libfyaml_la-fy-parse.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-parse.lo `test -f 'lib/fy-parse.c' || echo '$(srcdir)/'`lib/fy-parse.c
+
+lib/libfyaml_la-fy-utf8.lo: lib/fy-utf8.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-utf8.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-utf8.Tpo -c -o lib/libfyaml_la-fy-utf8.lo `test -f 'lib/fy-utf8.c' || echo '$(srcdir)/'`lib/fy-utf8.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-utf8.Tpo lib/$(DEPDIR)/libfyaml_la-fy-utf8.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-utf8.c' object='lib/libfyaml_la-fy-utf8.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo `test -f 'lib/fy-parse.c' || echo '$(srcdir)/'`lib/fy-parse.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-utf8.lo `test -f 'lib/fy-utf8.c' || echo '$(srcdir)/'`lib/fy-utf8.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo: lib/fy-utf8.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo `test -f 'lib/fy-utf8.c' || echo '$(srcdir)/'`lib/fy-utf8.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-utf8.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-types.lo: lib/fy-types.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-types.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-types.Tpo -c -o lib/libfyaml_la-fy-types.lo `test -f 'lib/fy-types.c' || echo '$(srcdir)/'`lib/fy-types.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-types.Tpo lib/$(DEPDIR)/libfyaml_la-fy-types.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-types.c' object='lib/libfyaml_la-fy-types.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo `test -f 'lib/fy-utf8.c' || echo '$(srcdir)/'`lib/fy-utf8.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-types.lo `test -f 'lib/fy-types.c' || echo '$(srcdir)/'`lib/fy-types.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo: lib/fy-types.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-types.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo `test -f 'lib/fy-types.c' || echo '$(srcdir)/'`lib/fy-types.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-types.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-types.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-types.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-diag.lo: lib/fy-diag.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-diag.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-diag.Tpo -c -o lib/libfyaml_la-fy-diag.lo `test -f 'lib/fy-diag.c' || echo '$(srcdir)/'`lib/fy-diag.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-diag.Tpo lib/$(DEPDIR)/libfyaml_la-fy-diag.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-diag.c' object='lib/libfyaml_la-fy-diag.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo `test -f 'lib/fy-types.c' || echo '$(srcdir)/'`lib/fy-types.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-diag.lo `test -f 'lib/fy-diag.c' || echo '$(srcdir)/'`lib/fy-diag.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo: lib/fy-diag.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo `test -f 'lib/fy-diag.c' || echo '$(srcdir)/'`lib/fy-diag.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-diag.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-dump.lo: lib/fy-dump.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-dump.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-dump.Tpo -c -o lib/libfyaml_la-fy-dump.lo `test -f 'lib/fy-dump.c' || echo '$(srcdir)/'`lib/fy-dump.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-dump.Tpo lib/$(DEPDIR)/libfyaml_la-fy-dump.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-dump.c' object='lib/libfyaml_la-fy-dump.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo `test -f 'lib/fy-diag.c' || echo '$(srcdir)/'`lib/fy-diag.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-dump.lo `test -f 'lib/fy-dump.c' || echo '$(srcdir)/'`lib/fy-dump.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo: lib/fy-dump.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo `test -f 'lib/fy-dump.c' || echo '$(srcdir)/'`lib/fy-dump.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-dump.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-atom.lo: lib/fy-atom.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-atom.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-atom.Tpo -c -o lib/libfyaml_la-fy-atom.lo `test -f 'lib/fy-atom.c' || echo '$(srcdir)/'`lib/fy-atom.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-atom.Tpo lib/$(DEPDIR)/libfyaml_la-fy-atom.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-atom.c' object='lib/libfyaml_la-fy-atom.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo `test -f 'lib/fy-dump.c' || echo '$(srcdir)/'`lib/fy-dump.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-atom.lo `test -f 'lib/fy-atom.c' || echo '$(srcdir)/'`lib/fy-atom.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo: lib/fy-atom.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo `test -f 'lib/fy-atom.c' || echo '$(srcdir)/'`lib/fy-atom.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-atom.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-ctype.lo: lib/fy-ctype.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-ctype.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-ctype.Tpo -c -o lib/libfyaml_la-fy-ctype.lo `test -f 'lib/fy-ctype.c' || echo '$(srcdir)/'`lib/fy-ctype.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-ctype.Tpo lib/$(DEPDIR)/libfyaml_la-fy-ctype.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-ctype.c' object='lib/libfyaml_la-fy-ctype.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo `test -f 'lib/fy-atom.c' || echo '$(srcdir)/'`lib/fy-atom.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-ctype.lo `test -f 'lib/fy-ctype.c' || echo '$(srcdir)/'`lib/fy-ctype.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo: lib/fy-ctype.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo `test -f 'lib/fy-ctype.c' || echo '$(srcdir)/'`lib/fy-ctype.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-ctype.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-token.lo: lib/fy-token.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-token.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-token.Tpo -c -o lib/libfyaml_la-fy-token.lo `test -f 'lib/fy-token.c' || echo '$(srcdir)/'`lib/fy-token.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-token.Tpo lib/$(DEPDIR)/libfyaml_la-fy-token.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-token.c' object='lib/libfyaml_la-fy-token.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo `test -f 'lib/fy-ctype.c' || echo '$(srcdir)/'`lib/fy-ctype.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-token.lo `test -f 'lib/fy-token.c' || echo '$(srcdir)/'`lib/fy-token.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo: lib/fy-token.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-token.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo `test -f 'lib/fy-token.c' || echo '$(srcdir)/'`lib/fy-token.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-token.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-token.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-token.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-input.lo: lib/fy-input.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-input.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-input.Tpo -c -o lib/libfyaml_la-fy-input.lo `test -f 'lib/fy-input.c' || echo '$(srcdir)/'`lib/fy-input.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-input.Tpo lib/$(DEPDIR)/libfyaml_la-fy-input.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-input.c' object='lib/libfyaml_la-fy-input.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo `test -f 'lib/fy-token.c' || echo '$(srcdir)/'`lib/fy-token.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-input.lo `test -f 'lib/fy-input.c' || echo '$(srcdir)/'`lib/fy-input.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo: lib/fy-input.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-input.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo `test -f 'lib/fy-input.c' || echo '$(srcdir)/'`lib/fy-input.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-input.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-input.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-input.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-docstate.lo: lib/fy-docstate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-docstate.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-docstate.Tpo -c -o lib/libfyaml_la-fy-docstate.lo `test -f 'lib/fy-docstate.c' || echo '$(srcdir)/'`lib/fy-docstate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-docstate.Tpo lib/$(DEPDIR)/libfyaml_la-fy-docstate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-docstate.c' object='lib/libfyaml_la-fy-docstate.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo `test -f 'lib/fy-input.c' || echo '$(srcdir)/'`lib/fy-input.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-docstate.lo `test -f 'lib/fy-docstate.c' || echo '$(srcdir)/'`lib/fy-docstate.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo: lib/fy-docstate.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo `test -f 'lib/fy-docstate.c' || echo '$(srcdir)/'`lib/fy-docstate.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-docstate.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-doc.lo: lib/fy-doc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-doc.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-doc.Tpo -c -o lib/libfyaml_la-fy-doc.lo `test -f 'lib/fy-doc.c' || echo '$(srcdir)/'`lib/fy-doc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-doc.Tpo lib/$(DEPDIR)/libfyaml_la-fy-doc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-doc.c' object='lib/libfyaml_la-fy-doc.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo `test -f 'lib/fy-docstate.c' || echo '$(srcdir)/'`lib/fy-docstate.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-doc.lo `test -f 'lib/fy-doc.c' || echo '$(srcdir)/'`lib/fy-doc.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo: lib/fy-doc.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo `test -f 'lib/fy-doc.c' || echo '$(srcdir)/'`lib/fy-doc.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-doc.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-docbuilder.lo: lib/fy-docbuilder.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-docbuilder.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-docbuilder.Tpo -c -o lib/libfyaml_la-fy-docbuilder.lo `test -f 'lib/fy-docbuilder.c' || echo '$(srcdir)/'`lib/fy-docbuilder.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-docbuilder.Tpo lib/$(DEPDIR)/libfyaml_la-fy-docbuilder.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-docbuilder.c' object='lib/libfyaml_la-fy-docbuilder.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo `test -f 'lib/fy-doc.c' || echo '$(srcdir)/'`lib/fy-doc.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-docbuilder.lo `test -f 'lib/fy-docbuilder.c' || echo '$(srcdir)/'`lib/fy-docbuilder.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo: lib/fy-emit.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo `test -f 'lib/fy-emit.c' || echo '$(srcdir)/'`lib/fy-emit.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-emit.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-emit.lo: lib/fy-emit.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-emit.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-emit.Tpo -c -o lib/libfyaml_la-fy-emit.lo `test -f 'lib/fy-emit.c' || echo '$(srcdir)/'`lib/fy-emit.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-emit.Tpo lib/$(DEPDIR)/libfyaml_la-fy-emit.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-emit.c' object='lib/libfyaml_la-fy-emit.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo `test -f 'lib/fy-emit.c' || echo '$(srcdir)/'`lib/fy-emit.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-emit.lo `test -f 'lib/fy-emit.c' || echo '$(srcdir)/'`lib/fy-emit.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo: lib/fy-utils.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo `test -f 'lib/fy-utils.c' || echo '$(srcdir)/'`lib/fy-utils.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-utils.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-utils.lo: lib/fy-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-utils.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-utils.Tpo -c -o lib/libfyaml_la-fy-utils.lo `test -f 'lib/fy-utils.c' || echo '$(srcdir)/'`lib/fy-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-utils.Tpo lib/$(DEPDIR)/libfyaml_la-fy-utils.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-utils.c' object='lib/libfyaml_la-fy-utils.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo `test -f 'lib/fy-utils.c' || echo '$(srcdir)/'`lib/fy-utils.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-utils.lo `test -f 'lib/fy-utils.c' || echo '$(srcdir)/'`lib/fy-utils.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo: lib/fy-event.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-event.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo `test -f 'lib/fy-event.c' || echo '$(srcdir)/'`lib/fy-event.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-event.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-event.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-event.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-event.lo: lib/fy-event.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-event.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-event.Tpo -c -o lib/libfyaml_la-fy-event.lo `test -f 'lib/fy-event.c' || echo '$(srcdir)/'`lib/fy-event.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-event.Tpo lib/$(DEPDIR)/libfyaml_la-fy-event.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-event.c' object='lib/libfyaml_la-fy-event.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo `test -f 'lib/fy-event.c' || echo '$(srcdir)/'`lib/fy-event.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-event.lo `test -f 'lib/fy-event.c' || echo '$(srcdir)/'`lib/fy-event.c
-xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo: xxhash/xxhash.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo -MD -MP -MF xxhash/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-xxhash.Tpo -c -o xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo `test -f 'xxhash/xxhash.c' || echo '$(srcdir)/'`xxhash/xxhash.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xxhash/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-xxhash.Tpo xxhash/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-xxhash.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xxhash/xxhash.c' object='xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo' libtool=yes @AMDEPBACKSLASH@
+xxhash/libfyaml_la-xxhash.lo: xxhash/xxhash.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT xxhash/libfyaml_la-xxhash.lo -MD -MP -MF xxhash/$(DEPDIR)/libfyaml_la-xxhash.Tpo -c -o xxhash/libfyaml_la-xxhash.lo `test -f 'xxhash/xxhash.c' || echo '$(srcdir)/'`xxhash/xxhash.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) xxhash/$(DEPDIR)/libfyaml_la-xxhash.Tpo xxhash/$(DEPDIR)/libfyaml_la-xxhash.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xxhash/xxhash.c' object='xxhash/libfyaml_la-xxhash.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo `test -f 'xxhash/xxhash.c' || echo '$(srcdir)/'`xxhash/xxhash.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o xxhash/libfyaml_la-xxhash.lo `test -f 'xxhash/xxhash.c' || echo '$(srcdir)/'`xxhash/xxhash.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo: lib/fy-accel.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo `test -f 'lib/fy-accel.c' || echo '$(srcdir)/'`lib/fy-accel.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-accel.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-accel.lo: lib/fy-accel.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-accel.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-accel.Tpo -c -o lib/libfyaml_la-fy-accel.lo `test -f 'lib/fy-accel.c' || echo '$(srcdir)/'`lib/fy-accel.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-accel.Tpo lib/$(DEPDIR)/libfyaml_la-fy-accel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-accel.c' object='lib/libfyaml_la-fy-accel.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo `test -f 'lib/fy-accel.c' || echo '$(srcdir)/'`lib/fy-accel.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-accel.lo `test -f 'lib/fy-accel.c' || echo '$(srcdir)/'`lib/fy-accel.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo: lib/fy-walk.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo `test -f 'lib/fy-walk.c' || echo '$(srcdir)/'`lib/fy-walk.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-walk.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-walk.lo: lib/fy-walk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-walk.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-walk.Tpo -c -o lib/libfyaml_la-fy-walk.lo `test -f 'lib/fy-walk.c' || echo '$(srcdir)/'`lib/fy-walk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-walk.Tpo lib/$(DEPDIR)/libfyaml_la-fy-walk.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-walk.c' object='lib/libfyaml_la-fy-walk.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo `test -f 'lib/fy-walk.c' || echo '$(srcdir)/'`lib/fy-walk.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-walk.lo `test -f 'lib/fy-walk.c' || echo '$(srcdir)/'`lib/fy-walk.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo: lib/fy-path.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-path.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo `test -f 'lib/fy-path.c' || echo '$(srcdir)/'`lib/fy-path.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-path.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-path.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-path.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-path.lo: lib/fy-path.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-path.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-path.Tpo -c -o lib/libfyaml_la-fy-path.lo `test -f 'lib/fy-path.c' || echo '$(srcdir)/'`lib/fy-path.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-path.Tpo lib/$(DEPDIR)/libfyaml_la-fy-path.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-path.c' object='lib/libfyaml_la-fy-path.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo `test -f 'lib/fy-path.c' || echo '$(srcdir)/'`lib/fy-path.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-path.lo `test -f 'lib/fy-path.c' || echo '$(srcdir)/'`lib/fy-path.c
-lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo: lib/fy-composer.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.Tpo -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo `test -f 'lib/fy-composer.c' || echo '$(srcdir)/'`lib/fy-composer.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.Tpo lib/$(DEPDIR)/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-composer.c' object='lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo' libtool=yes @AMDEPBACKSLASH@
+lib/libfyaml_la-fy-composer.lo: lib/fy-composer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -MT lib/libfyaml_la-fy-composer.lo -MD -MP -MF lib/$(DEPDIR)/libfyaml_la-fy-composer.Tpo -c -o lib/libfyaml_la-fy-composer.lo `test -f 'lib/fy-composer.c' || echo '$(srcdir)/'`lib/fy-composer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) lib/$(DEPDIR)/libfyaml_la-fy-composer.Tpo lib/$(DEPDIR)/libfyaml_la-fy-composer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib/fy-composer.c' object='lib/libfyaml_la-fy-composer.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_@MAJOR@_@MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_@MAJOR@_@MINOR@_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_@MAJOR@_@MINOR@_la-fy-composer.lo `test -f 'lib/fy-composer.c' || echo '$(srcdir)/'`lib/fy-composer.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_la_CPPFLAGS) $(CPPFLAGS) $(libfyaml_la_CFLAGS) $(CFLAGS) -c -o lib/libfyaml_la-fy-composer.lo `test -f 'lib/fy-composer.c' || echo '$(srcdir)/'`lib/fy-composer.c
tool/fy_tool-fy-tool.o: tool/fy-tool.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fy_tool_CPPFLAGS) $(CPPFLAGS) $(fy_tool_CFLAGS) $(CFLAGS) -MT tool/fy_tool-fy-tool.o -MD -MP -MF tool/$(DEPDIR)/fy_tool-fy-tool.Tpo -c -o tool/fy_tool-fy-tool.o `test -f 'tool/fy-tool.c' || echo '$(srcdir)/'`tool/fy-tool.c
{
struct fy_document *fyd;
struct fy_document_builder *fydb;
+ struct fy_document_builder_cfg cfg;
unsigned int flags;
int rc, count;
flags |= FYECF_SORT_KEYS;
flags |= FYECF_INDENT(indent) | FYECF_WIDTH(width);
- fydb = fy_document_builder_create(&fyp->cfg);
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.parse_cfg = fyp->cfg;
+ cfg.diag = fy_diag_ref(fyp->diag);
+
+ fydb = fy_document_builder_create(&cfg);
assert(fydb);
count = 0;
fy_path_in_mapping(path) ? 'M' : '-',
fy_path_in_mapping_key(path) ? 'K' :
fy_path_in_mapping_value(path) ? 'V' : '-',
- fy_path_is_collection_root(path) ? '/' : '-',
+ fy_path_in_collection_root(path) ? '/' : '-',
fy_path_depth(path),
fy_path_get_text_alloca(path),
fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf)));
int do_compose(struct fy_parser *fyp, int indent, int width, bool resolve, bool sort, bool null_output)
{
struct composer_data cd;
- unsigned int flags;
int rc;
- flags = 0;
- if (sort)
- flags |= FYECF_SORT_KEYS;
- flags |= FYECF_INDENT(indent) | FYECF_WIDTH(width);
-
memset(&cd, 0, sizeof(cd));
cd.null_output = null_output;
cd.single_document = true;
int do_iterate(struct fy_parser *fyp)
{
- enum fy_node_iterator_flags flags;
struct fy_document *fyd;
+ struct fy_document_iterator *fydi;
int count;
struct fy_node *fyn;
- struct fy_node_iterator ni;
- enum fy_node_iterator_result res;
char *path;
size_t len;
const char *text;
char textbuf[16];
bool belongs_to_key;
- memset(&ni, 0, sizeof(ni));
-
- flags = FYNIF_DEPTH_FIRST;
- fy_node_iterator_setup(&ni, flags | FYNIF_FOLLOW_KEYS | FYNIF_FOLLOW_LINKS);
+ fydi = fy_document_iterator_create();
+ assert(fydi);
count = 0;
while ((fyd = fy_parse_load_document(fyp)) != NULL) {
fprintf(stderr, "> Start\n");
- fy_node_iterator_start(&ni, fy_document_root(fyd));
+ fy_document_iterator_node_start(fydi, fy_document_root(fyd));
+
fyn = NULL;
- while ((fyn = fy_node_iterator_next(&ni, fyn)) != NULL) {
+ while ((fyn = fy_document_iterator_node_next(fydi)) != NULL) {
belongs_to_key = fy_node_belongs_to_key(fyd, fyn);
path = fy_node_get_path(fyn);
free(path);
}
- res = fy_node_iterator_end(&ni);
-
fprintf(stderr, "> End\n");
fy_parse_document_destroy(fyp, fyd);
- if (res != FYNIR_OK) {
- fprintf(stderr, "> Iterator error %d\n", (int)res);
- break;
- }
-
count++;
}
- fy_node_iterator_cleanup(&ni);
+ fy_document_iterator_destroy(fydi);
return count > 0 ? 0 : -1;
}
int do_comment(struct fy_parser *fyp)
{
- enum fy_node_iterator_flags flags;
struct fy_document *fyd;
int count;
struct fy_node *fyn;
- struct fy_node_iterator ni;
- enum fy_node_iterator_result res;
+ struct fy_document_iterator *fydi;
char *path;
struct fy_token *fyt;
struct fy_atom *handle;
static const char *placement_txt[] = { "top", "right", "bottom" };
char buf[1024];
- memset(&ni, 0, sizeof(ni));
-
- flags = FYNIF_DEPTH_FIRST;
- fy_node_iterator_setup(&ni, flags | FYNIF_FOLLOW_KEYS | FYNIF_FOLLOW_LINKS);
+ fydi = fy_document_iterator_create();
+ assert(fydi);
count = 0;
while ((fyd = fy_parse_load_document(fyp)) != NULL) {
- fy_node_iterator_start(&ni, fy_document_root(fyd));
+ fy_document_iterator_node_start(fydi, fy_document_root(fyd));
fyn = NULL;
- while ((fyn = fy_node_iterator_next(&ni, fyn)) != NULL) {
+ while ((fyn = fy_document_iterator_node_next(fydi)) != NULL) {
if (!fy_node_is_scalar(fyn))
continue;
free(path);
}
- res = fy_node_iterator_end(&ni);
-
fy_parse_document_destroy(fyp, fyd);
- if (res != FYNIR_OK) {
- break;
- }
-
count++;
}
- fy_node_iterator_cleanup(&ni);
+ fy_document_iterator_destroy(fydi);
return count > 0 ? 0 : -1;
}
char keybuf[16], valbuf[16];
const char *key;
+ /* supress warnings about unused functions */
+ (void)fy_kv_list_push;
+ (void)fy_kv_list_push_tail;
+ (void)fy_kv_list_is_singular;
+ (void)fy_kv_list_insert_after;
+ (void)fy_kv_list_insert_before;
+ (void)fy_kv_list_last;
+ (void)fy_kv_list_pop_tail;
+ (void)fy_kv_prev;
+ (void)fy_kv_lists_splice;
+ (void)fy_kv_list_splice_after;
+ (void)fy_kv_list_splice_before;
+
seed = 0; /* we don't care much about seed practices right now */
rc = fy_kv_store_setup(&kvs, 8);
assert(!rc);
if (!fyn) {
fprintf(stderr, "exec: did not find node for %s\n", pathstr);
} else {
- fprintf(stderr, "exec: path %s - return %s\n", pathstr, fy_node_get_path_a(fyn));
+ fprintf(stderr, "exec: path %s - return %s\n", pathstr, fy_node_get_path_alloca(fyn));
}
fyn = node_find(fyd, fy_document_root(fyd), &path);
if (!fyn) {
fprintf(stderr, "norm: did not find node for %s\n", pathstr);
} else {
- fprintf(stderr, "norm: path %s - return %s\n", pathstr, fy_node_get_path_a(fyn));
+ fprintf(stderr, "norm: path %s - return %s\n", pathstr, fy_node_get_path_alloca(fyn));
}
fy_parse_document_destroy(fyp, fyd);
fyic->type = fyit_stream;
fyic->stream.name = "stdin";
fyic->stream.fp = stdin;
- fyic->stream.chunk = chunk;
+ fyic->chunk = chunk;
} else {
fyic->type = fyit_callback;
fyic->userdata = stdin;
fyic->type = fyit_stream;
fyic->stream.name = "stdin";
fyic->stream.fp = stdin;
- fyic->stream.chunk = chunk;
+ fyic->chunk = chunk;
} else {
fyic->type = fyit_callback;
fyic->userdata = stdin;
#include "fy-parse.h"
#include "fy-doc.h"
-void fy_reader_fill_atom_start(struct fy_reader *fyr, struct fy_atom *handle)
-{
- memset(handle, 0, sizeof(*handle));
-
- /* start mark */
- fy_reader_get_mark(fyr, &handle->start_mark);
- handle->end_mark = handle->start_mark;
- handle->fyi = fy_reader_current_input(fyr);
- handle->fyi_generation = fy_reader_current_input_generation(fyr);
-
- /* note that handle->data may be zero for empty input */
-}
-
-void fy_reader_fill_atom_end_at(struct fy_reader *fyr, struct fy_atom *handle,
- struct fy_mark *end_mark)
-{
- if (end_mark)
- handle->end_mark = *end_mark;
- else
- fy_reader_get_mark(fyr, &handle->end_mark);
-
- /* default is plain, modify at return */
- handle->style = FYAS_PLAIN;
- handle->chomp = FYAC_CLIP;
- /* by default we don't do storage hints, it's the job of the caller */
- handle->storage_hint = 0;
- handle->storage_hint_valid = false;
- handle->tabsize = fy_reader_tabsize(fyr);
- handle->json_mode = fy_reader_json_mode(fyr);
- handle->lb_mode = fy_reader_lb_mode(fyr);
- handle->fws_mode = fy_reader_flow_ws_mode(fyr);
-}
-
-void fy_reader_fill_atom_end(struct fy_reader *fyr, struct fy_atom *handle)
-{
- fy_reader_fill_atom_end_at(fyr, handle, NULL);
-}
-
struct fy_atom *fy_reader_fill_atom(struct fy_reader *fyr, int advance, struct fy_atom *handle)
{
/* start mark */
const char *s, *e, *ss;
int col, c, w, ts, cws, advws;
bool last_was_ws, is_block;
+ int lastc;
s = line_start;
e = line_start + len;
/* consecutive whitespace */
cws = 0;
+ lastc = -1;
li->s_tb = s;
for (col = 0, ss = s; (c = fy_utf8_get(ss, (e - ss), &w)) >= 0; ss += w) {
+ lastc = c;
+
/* mark start of chomp */
if (is_block && !li->chomp_start && (unsigned int)col >= iter->chomp) {
li->chomp_start = ss;
* then we're indented
*/
li->indented = fy_is_ws(c);
+
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d chomp_start=%d\n", __FILE__, __LINE__, (int)(li->chomp_start - li->start));
+#endif
+
}
if (fy_is_lb_m(c, atom->lb_mode)) {
}
/* no chomp point hit, use whatever we have here */
- if (is_block && !li->chomp_start)
+ if (is_block && !li->chomp_start) {
li->chomp_start = ss;
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d chomp_start=%d\n", __FILE__, __LINE__, (int)(li->chomp_start - li->start));
+#endif
+
+ }
if (!last_was_ws) {
cws = 0;
last_was_ws = true;
}
- } else if (fy_is_ws(c)) {
+ } else if (fy_is_space(c)) {
- advws = fy_is_space(c) ? 1 : (ts - (col % ts));
+ col++;
+ cws++;
+
+ if (!last_was_ws) {
+ li->nws_end = ss;
+ last_was_ws = true;
+ }
+
+ } else if (fy_is_tab(c)) {
+
+ bool can_be_nws_end;
+
+ advws = ts - (col % ts);
col += advws;
+
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d tab col=%d chomp=%d\n", __FILE__, __LINE__, col, (int)(li->chomp_start - li->start));
+#endif
+
+ if (fy_atom_style_is_block(atom->style) && col >= (int)(li->chomp_start - li->start)) {
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d tab col=%d chomp=%d\n", __FILE__, __LINE__, col, (int)(li->chomp_start - li->start));
+#endif
+ goto do_nws;
+ }
+
cws += advws;
- if (!last_was_ws) {
+ can_be_nws_end = true;
+ if (atom->style == FYAS_DOUBLE_QUOTED && ss > li->start && ss[-1] == '\\') {
+ can_be_nws_end = false;
+#ifdef DEBUG_CHUNK
+ fprintf(stderr, "%s:%d backslashed tab\n", __FILE__, __LINE__);
+#endif
+ }
+
+ if (can_be_nws_end && !last_was_ws) {
li->nws_end = ss;
last_was_ws = true;
}
} else {
+
+ col++;
+do_nws:
/* mark start of non whitespace */
if (!li->nws_start)
li->nws_start = ss;
last_was_ws = false;
cws = 0;
-
- col++;
}
/* if we got both break */
}
li->e_tb = ss;
- li->final = c == -1;
+ li->final = c < 0;
+
+ if (li->final && atom->ends_with_eof) {
+
+ /* mark start of chomp */
+ if (is_block && !li->chomp_start && (unsigned int)col >= iter->chomp) {
+ li->chomp_start = ss;
+
+ /* if the character at the chomp point is whitespace
+ * then we're indented
+ */
+ li->indented = fy_is_ws(lastc);
+#ifdef DEBUG_CHUNK
+ fprintf(stderr, "%s:%d is_block && !li->chomp_start && (unsigned int)col >= iter->chomp\n", __FILE__, __LINE__);
+#endif
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d chomp_start=%d\n", __FILE__, __LINE__, (int)(li->chomp_start - li->start));
+#endif
+
+ }
+
+ if (!li->end) {
+ li->end = ss;
+ li->end_ws = cws;
+ li->lb_end = true;
+
+#ifdef DEBUG_CHUNK
+ fprintf(stderr, "%s:%d li->final && atom->ends_with_eof && !li->end\n", __FILE__, __LINE__);
+#endif
+ cws = 0;
+ }
+
+ /* no chomp point hit, use whatever we have here */
+ if (is_block && !li->chomp_start) {
+ li->chomp_start = ss;
+#ifdef DEBUG_CHUNK
+ fprintf(stderr, "%s:%d li->final && atom->ends_with_eof && !li->chomp_start\n", __FILE__, __LINE__);
+#endif
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d chomp_start=%d\n", __FILE__, __LINE__, (int)(li->chomp_start - li->start));
+#endif
+ }
+
+ if (!last_was_ws) {
+ cws = 0;
+ li->nws_end = ss;
+ last_was_ws = true;
+#ifdef DEBUG_CHUNK
+ fprintf(stderr, "%s:%d li->final && atom->ends_with_eof && !last_was_ws\n", __FILE__, __LINE__);
+#endif
+ }
+ }
if (!last_was_ws)
li->nws_end = ss;
li->nws_end = ss;
/* if we haven't hit the chomp, point use whatever we're now */
- if (is_block && !li->chomp_start)
+ if (is_block && !li->chomp_start) {
li->chomp_start = ss;
+#if defined(DEBUG_CHUNK)
+ fprintf(stderr, "%s:%d chomp_start=%d\n", __FILE__, __LINE__, (int)(li->chomp_start - li->start));
+#endif
+ }
if (li->start_ws == (size_t)-1)
li->start_ws = 0;
iter->empty = atom->empty;
iter->last_ends_with_backslash = li->ends_with_backslash;
#ifdef DEBUG_CHUNK
- fprintf(stderr, "%s:%d ends_with_backslash=%s\n", __FILE__, __LINE__, li->ends_with_backslash ? "true" : "false");
+ fprintf(stderr, "%s:%d single_line=%s empty=%s last_ends_with_backslash=%s\n", __FILE__, __LINE__,
+ iter->single_line ? "true" : "false",
+ iter->empty ? "true" : "false",
+ iter->last_ends_with_backslash ? "true" : "false");
#endif
/* current is 0, next is 1 */
} else if (atom->style == FYAS_LITERAL || atom->style == FYAS_FOLDED) {
li->s = li->chomp_start;
li->e = li->end;
- if (li->empty && li->first && li->last && !iter->single_line)
+ if (li->empty && li->first && li->last)
li->s = li->e;
} else {
li->s = li->nws_start;
pending_nl++;
}
}
- if (atom->chomp == FYAC_CLIP && pending_nl) {
+
+ if (atom->chomp == FYAC_CLIP && (pending_nl || atom->ends_with_eof)) {
ret = fy_atom_iter_add_lb(iter, pending_lb[0]);
if (ret)
goto out;
}
break;
case FYAC_KEEP:
- if (li->lb_end) {
+ if (li->lb_end || atom->ends_with_eof) {
ret = fy_atom_iter_add_lb(iter, li->actual_lb > 0 ? li->actual_lb : '\n');
if (ret)
goto out;
}
+
+ /* nothing more if it's an EOF */
+ if (atom->ends_with_eof && atom->empty)
+ break;
+
while ((li = fy_atom_iter_line(iter)) != NULL) {
if (!iter->empty && li->chomp_start < li->end) {
ret = fy_atom_iter_add_chunk(iter, li->chomp_start, li->end - li->chomp_start);
struct fy_input *fyi; /* input on which atom is on */
uint64_t fyi_generation; /* to detect reallocs */
unsigned int increment;
- /* save a little bit of space with bitfields */
- enum fy_atom_style style;
- enum fy_lb_mode lb_mode; /* atom linebreak mode */
- enum fy_flow_ws_mode fws_mode; /* atom flow whitespace mode */
- enum fy_atom_chomp chomp : 4;
- bool direct_output : 1; /* can directly output */
- bool storage_hint_valid : 1;
- bool empty : 1; /* atom contains whitespace and linebreaks only if length > 0 */
- bool has_lb : 1; /* atom contains at least one linebreak */
- bool has_ws : 1; /* atom contains at least one whitespace */
- bool starts_with_ws : 1; /* atom starts with whitespace */
- bool starts_with_lb : 1; /* atom starts with linebreak */
- bool ends_with_ws : 1; /* atom ends with whitespace */
- bool ends_with_lb : 1; /* atom ends with linebreak */
- bool trailing_lb : 1; /* atom ends with trailing linebreaks > 1 */
- bool size0 : 1; /* atom contains absolutely nothing */
- bool valid_anchor : 1; /* atom is a valid anchor */
- bool json_mode : 1; /* atom was read in json mode */
- unsigned int tabsize : 4;
+ union {
+ uint64_t tozero; /* fast way to zero everything here */
+ struct {
+ /* save a little bit of space with bitfields */
+ enum fy_atom_style style : 8; /* note that it's a big perf win for bytes */
+ enum fy_atom_chomp chomp : 8;
+ unsigned int tabsize : 8;
+ enum fy_lb_mode lb_mode : 1;
+ enum fy_flow_ws_mode fws_mode : 1;
+ bool direct_output : 1; /* can directly output */
+ bool storage_hint_valid : 1;
+ bool empty : 1; /* atom contains whitespace and linebreaks only if length > 0 */
+ bool has_lb : 1; /* atom contains at least one linebreak */
+ bool has_ws : 1; /* atom contains at least one whitespace */
+ bool starts_with_ws : 1; /* atom starts with whitespace */
+ bool starts_with_lb : 1; /* atom starts with linebreak */
+ bool ends_with_ws : 1; /* atom ends with whitespace */
+ bool ends_with_lb : 1; /* atom ends with linebreak */
+ bool trailing_lb : 1; /* atom ends with trailing linebreaks > 1 */
+ bool size0 : 1; /* atom contains absolutely nothing */
+ bool valid_anchor : 1; /* atom is a valid anchor */
+ bool json_mode : 1; /* atom was read in json mode */
+ bool ends_with_eof : 1; /* atom ends at EOF of input */
+ };
+ };
};
static inline bool fy_atom_is_set(const struct fy_atom *atom)
int fy_atom_format_utf8_length(struct fy_atom *atom);
-void fy_reader_fill_atom_start(struct fy_reader *fyr, struct fy_atom *handle);
-void fy_reader_fill_atom_end_at(struct fy_reader *fyr, struct fy_atom *handle, struct fy_mark *end_mark);
-void fy_reader_fill_atom_end(struct fy_reader *fyr, struct fy_atom *handle);
-struct fy_atom *fy_reader_fill_atom(struct fy_reader *fyr, int advance, struct fy_atom *handle);
+static inline void
+fy_reader_fill_atom_start(struct fy_reader *fyr, struct fy_atom *handle)
+{
+ /* start mark */
+ fy_reader_get_mark(fyr, &handle->start_mark);
+ handle->fyi = fy_reader_current_input(fyr);
+ handle->fyi_generation = fy_reader_current_input_generation(fyr);
+
+ handle->increment = 0;
+ handle->tozero = 0;
+
+ /* note that handle->data may be zero for empty input */
+}
+
+static inline void
+fy_reader_fill_atom_end_at(struct fy_reader *fyr, struct fy_atom *handle, struct fy_mark *end_mark)
+{
+ if (end_mark)
+ handle->end_mark = *end_mark;
+ else
+ fy_reader_get_mark(fyr, &handle->end_mark);
+
+ /* default is plain, modify at return */
+ handle->style = FYAS_PLAIN;
+ handle->chomp = FYAC_CLIP;
+ /* by default we don't do storage hints, it's the job of the caller */
+ handle->storage_hint = 0;
+ handle->storage_hint_valid = false;
+ handle->tabsize = fy_reader_tabsize(fyr);
+ handle->json_mode = fy_reader_json_mode(fyr);
+ handle->lb_mode = fy_reader_lb_mode(fyr);
+ handle->fws_mode = fy_reader_flow_ws_mode(fyr);
+}
+
+static inline void
+fy_reader_fill_atom_end(struct fy_reader *fyr, struct fy_atom *handle)
+{
+ fy_reader_fill_atom_end_at(fyr, handle, NULL);
+}
+struct fy_atom *fy_reader_fill_atom(struct fy_reader *fyr, int advance, struct fy_atom *handle);
struct fy_atom *fy_reader_fill_atom_mark(struct fy_reader *fyr, const struct fy_mark *start_mark,
const struct fy_mark *end_mark, struct fy_atom *handle);
struct fy_atom *fy_reader_fill_atom_at(struct fy_reader *fyr, int advance, int count, struct fy_atom *handle);
#include "fy-utils.h"
-#undef DBG
-// #define DBG fyp_notice
-#define DBG fyp_scan_debug
-
struct fy_composer *
fy_composer_create(struct fy_composer_cfg *cfg)
{
err_no_path:
free(fyc);
return NULL;
-
}
void fy_composer_destroy(struct fy_composer *fyc)
}
static enum fy_composer_return
-fy_composer_process_event_private(struct fy_composer *fyc, struct fy_parser *fyp,
- struct fy_event *fye, struct fy_path *fypp)
+fy_composer_process_event_private(struct fy_composer *fyc, struct fy_event *fye, struct fy_path *fypp)
{
const struct fy_composer_ops *ops;
struct fy_eventp *fyep;
struct fy_path *fyppt;
struct fy_document *fyd;
bool is_collection, is_map, is_start, is_end;
- char tbuf[80] __attribute__((__unused__));
int rc = 0;
enum fy_composer_return ret;
bool stop_req = false;
assert(fyc);
- assert(fyp);
assert(fye);
assert(fypp);
case FYET_STREAM_END:
case FYET_DOCUMENT_START:
case FYET_DOCUMENT_END:
- // fprintf(stderr, "%s:%d process_event\n", __FILE__, __LINE__);
- return ops->process_event(fyc, fypp, fyp, fye);
+ return ops->process_event(fyc, fypp, fye);
default:
- // DBG(fyp, "ignoring\n");
return FYCR_OK_CONTINUE;
}
fypc_last = fy_path_component_list_tail(&fypp->components);
- // DBG(fyp, "%s: start - %s\n", fy_path_get_text0(fypp), fy_token_dump_format(fyt, tbuf, sizeof(tbuf)));
-
if (fy_path_component_is_mapping(fypc_last) && fypc_last->map.accumulating_complex_key) {
- // DBG(fyp, "accumulating for complex key\n");
- // fprintf(stderr, "accumulating for complex key %s\n",
- // fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf)));
-
/* get the next one */
fyppt = fy_path_next(&fyc->paths, fypp);
assert(fyppt);
assert(fyppt->parent == fypp);
/* and pass along */
- ret = fy_composer_process_event_private(fyc, fyp, fye, fyppt);
+ ret = fy_composer_process_event_private(fyc, fye, fyppt);
if (!fy_composer_return_is_ok(ret)) {
/* XXX TODO handle skip */
return ret;
if (!stop_req)
stop_req = ret == FYCR_OK_STOP;
- rc = fy_document_builder_process_event(fypp->fydb, fyp, fyep);
- if (rc == 0) {
- // DBG(fyp, "accumulating still\n");
- // fprintf(stderr, "accumulating still %s\n",
- // fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf)));
+ rc = fy_document_builder_process_event(fypp->fydb, fyep);
+ if (rc == 0)
return FYCR_OK_CONTINUE;
- }
fyc_error_check(fyc, rc > 0, err_out,
"fy_document_builder_process_event() failed\n");
- // fprintf(stderr, "accumulating complete %s\n",
- // fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf)));
-
- // DBG(fyp, "accumulation complete\n");
-
/* get the document */
fyd = fy_document_builder_take_document(fypp->fydb);
fyc_error_check(fyc, fyd, err_out,
fypc_last->map.has_key = true;
fypc_last->map.await_key = false;
fypc_last->map.complex_key_complete = true;
+ fypc_last->map.root = false;
fyppt = fy_path_list_pop_tail(&fyc->paths);
assert(fyppt);
fy_path_destroy(fyppt);
- // DBG(fyp, "%s: %s complex KEY\n", __func__, fy_path_get_text0(fypp));
-
fyc_error_check(fyc, rc >= 0, err_out,
"fy_path_component_build_text() failed\n");
/* start of something on a mapping */
if (is_start && fy_path_component_is_mapping(fypc_last) && fypc_last->map.await_key && is_collection) {
- /* non scalar key case */
- // DBG(fyp, "Non scalar key - using document builder\n");
- if (!fypp->fydb) {
- fypp->fydb = fy_document_builder_create(&fyp->cfg);
- fyc_error_check(fyc, fypp->fydb, err_out,
- "fy_document_builder_create() failed\n");
- }
-
- /* start with this document state */
- rc = fy_document_builder_set_in_document(fypp->fydb, fy_parser_get_document_state(fyp), true);
- fyc_error_check(fyc, !rc, err_out,
- "fy_document_builder_set_in_document() failed\n");
+ /* the configuration must support a document builder for complex keys */
+ FYC_TOKEN_ERROR_CHECK(fyc, fy_event_get_token(fye), FYEM_DOC,
+ ops->create_document_builder, err_out,
+ "composer configuration does not support complex keys");
- // fprintf(stderr, "initial complex key %s\n",
- // fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf)));
+ /* call out for creating the document builder */
+ fypp->fydb = ops->create_document_builder(fyc);
+ fyc_error_check(fyc, fypp->fydb, err_out,
+ "ops->create_document_builder() failed\n");
/* and pass the current event; must return 0 since we know it's a collection start */
- rc = fy_document_builder_process_event(fypp->fydb, fyp, fyep);
+ rc = fy_document_builder_process_event(fypp->fydb, fyep);
fyc_error_check(fyc, !rc, err_out,
"fy_document_builder_process_event() failed\n");
fy_path_list_add_tail(&fyc->paths, fyppt);
/* and pass along */
- ret = fy_composer_process_event_private(fyc, fyp, fye, fyppt);
+ ret = fy_composer_process_event_private(fyc, fye, fyppt);
if (!fy_composer_return_is_ok(ret)) {
/* XXX TODO handle skip */
return ret;
} else if (!is_collection && fy_path_component_is_mapping(fypc_last) && fypc_last->map.await_key) {
- // DBG(fyp, "scalar key: %s\n", fy_token_dump_format(fyt, tbuf, sizeof(tbuf)));
fypc_last->map.is_complex_key = false;
- fypc_last->map.scalar_key = fy_token_ref(fy_event_get_token(fye));
+ fypc_last->map.scalar.tag = fy_token_ref(fy_event_get_tag_token(fye));
+ fypc_last->map.scalar.key = fy_token_ref(fy_event_get_token(fye));
fypc_last->map.has_key = true;
+ fypc_last->map.root = false;
}
/* process the event */
- ret = ops->process_event(fyc, fypp, fyp, fye);
+ ret = ops->process_event(fyc, fypp, fye);
if (!fy_composer_return_is_ok(ret)) {
/* XXX TODO handle skip */
return ret;
/* at the end of something */
if (is_end && fy_path_component_is_mapping(fypc_last)) {
-
if (!fypc_last->map.await_key) {
-
fy_path_component_clear_state(fypc_last);
-
- // DBG(fyp, "%s: set await_key %p\n", fy_path_get_text0(fypp), fypc_last);
fypc_last->map.await_key = true;
-
- } else {
+ } else
fypc_last->map.await_key = false;
- }
}
- // DBG(fyp, "%s: exit\n", fy_path_get_text0(fypp));
return !stop_req ? FYCR_OK_CONTINUE : FYCR_OK_STOP;
err_out:
}
enum fy_composer_return
-fy_composer_process_event(struct fy_composer *fyc, struct fy_parser *fyp, struct fy_event *fye)
+fy_composer_process_event(struct fy_composer *fyc, struct fy_event *fye)
{
struct fy_path *fypp;
int rc;
- if (!fyc || !fyp || !fye)
+ if (!fyc || !fye)
return -1;
/* start at the head */
if (!fypp)
return -1;
- rc = fy_composer_process_event_private(fyc, fyp, fye, fypp);
+ rc = fy_composer_process_event_private(fyc, fye, fypp);
return rc;
}
return NULL;
return fyc->cfg.diag;
}
-
-enum fy_composer_return
-fy_composer_parse(struct fy_composer *fyc, struct fy_parser *fyp)
-{
- struct fy_event *fye;
- enum fy_composer_return ret;
-
- if (!fyp || !fyc)
- return FYCR_ERROR;
-
- ret = FYCR_OK_CONTINUE;
- while ((fye = fy_parser_parse(fyp)) != NULL) {
- ret = fy_composer_process_event(fyc, fyp, fye);
- fy_parser_event_free(fyp, fye);
- if (ret != FYCR_OK_CONTINUE)
- break;
- }
-
- return ret;
-}
#include "fy-path.h"
struct fy_composer;
-struct fy_parser;
struct fy_token;
-struct fy_document_state;
struct fy_diag;
struct fy_event;
struct fy_eventp;
+struct fy_document_builder;
struct fy_composer_ops {
/* single process event callback */
- enum fy_composer_return (*process_event)(struct fy_composer *fyc, struct fy_path *path, struct fy_parser *fyp, struct fy_event *fye);
+ enum fy_composer_return (*process_event)(struct fy_composer *fyc, struct fy_path *path, struct fy_event *fye);
+ struct fy_document_builder *(*create_document_builder)(struct fy_composer *fyc);
};
struct fy_composer_cfg {
struct fy_composer *fy_composer_create(struct fy_composer_cfg *cfg);
void fy_composer_destroy(struct fy_composer *fyc);
-int fy_composer_process_event(struct fy_composer *fyc, struct fy_parser *fyp, struct fy_event *fye);
+int fy_composer_process_event(struct fy_composer *fyc, struct fy_event *fye);
struct fy_composer_cfg *fy_composer_get_cfg(struct fy_composer *fyc);
void *fy_composer_get_cfg_userdata(struct fy_composer *fyc);
struct fy_diag *fy_composer_get_diag(struct fy_composer *fyc);
-int fy_composer_parse(struct fy_composer *fyc, struct fy_parser *fyp);
-
#endif
return txt[module];
}
+/* really concervative options */
+static const struct fy_diag_term_info default_diag_term_info_template = {
+ .rows = 25,
+ .columns = 80
+};
+
static const struct fy_diag_cfg default_diag_cfg_template = {
.fp = NULL, /* must be overriden */
.level = FYET_INFO,
/* nothing */
}
+static bool fy_diag_isatty(struct fy_diag *diag)
+{
+ return diag && diag->cfg.fp && isatty(fileno(diag->cfg.fp));
+}
+
+static void fy_diag_update_term_info(struct fy_diag *diag)
+{
+ int fd, rows, columns, ret;
+
+ /* start by setting things to the default */
+ diag->term_info = default_diag_term_info_template;
+
+ fd = diag->cfg.fp && isatty(fileno(diag->cfg.fp)) ?
+ fileno(diag->cfg.fp) : -1;
+
+ if (fd == -1)
+ goto out;
+
+ rows = columns = 0;
+ ret = fy_term_query_size(fd, &rows, &columns);
+ if (ret != 0)
+ goto out;
+
+ if (rows > 0 && columns > 0) {
+ diag->term_info.rows = rows;
+ diag->term_info.columns = columns;
+ }
+out:
+ diag->terminal_probed = true;
+}
+
+void fy_diag_errorp_free(struct fy_diag_errorp *errp)
+{
+ if (errp->space)
+ free(errp->space);
+ fy_token_unref(errp->e.fyt);
+ free(errp);
+}
+
struct fy_diag *fy_diag_create(const struct fy_diag_cfg *cfg)
{
struct fy_diag *diag;
diag->on_error = false;
diag->refs = 1;
+ diag->terminal_probed = false;
+ if (!fy_diag_isatty(diag))
+ fy_diag_update_term_info(diag);
+
+ fy_diag_errorp_list_init(&diag->errors);
+
return diag;
}
void fy_diag_destroy(struct fy_diag *diag)
{
+ struct fy_diag_errorp *errp;
+
if (!diag)
return;
diag->destroyed = true;
+ /* free everything */
+ while ((errp = fy_diag_errorp_list_pop(&diag->errors)) != NULL)
+ fy_diag_errorp_free(errp);
+
return fy_diag_unref(diag);
}
void fy_diag_reset_error(struct fy_diag *diag)
{
+ struct fy_diag_errorp *errp;
+
if (!diag)
return;
diag->on_error = false;
+
+ while ((errp = fy_diag_errorp_list_pop(&diag->errors)) != NULL)
+ fy_diag_errorp_free(errp);
}
-/**
- * fy_diag_reset_error() - Reset the error flag of
- * the diagnostic object
- *
- * Clears the error flag which was set by an output
- * of an error level diagnostic
- *
- * @diag: The diagnostic object
- */
-void
-fy_diag_reset_error(struct fy_diag *diag)
- FY_EXPORT;
+void fy_diag_set_collect_errors(struct fy_diag *diag, bool collect_errors)
+{
+ struct fy_diag_errorp *errp;
+
+ if (!diag || diag->destroyed)
+ return;
+
+ diag->collect_errors = collect_errors;
+
+ /* clear collected errors on disable */
+ if (!diag->collect_errors) {
+ while ((errp = fy_diag_errorp_list_pop(&diag->errors)) != NULL)
+ fy_diag_errorp_free(errp);
+ }
+}
+
+struct fy_diag_error *fy_diag_errors_iterate(struct fy_diag *diag, void **prevp)
+{
+ struct fy_diag_errorp *errp;
+
+ if (!diag || !prevp)
+ return NULL;
+
+ if (!*prevp)
+ errp = fy_diag_errorp_list_head(&diag->errors);
+ else {
+ errp = *prevp;
+ errp = fy_diag_errorp_next(&diag->errors, errp);
+ }
+
+ if (!errp)
+ return NULL;
+ *prevp = errp;
+ return &errp->e;
+}
void fy_diag_free(struct fy_diag *diag)
{
if (!diag)
return;
- if (!cfg) {
+ if (!cfg)
fy_diag_cfg_default(&diag->cfg);
- return;
- }
+ else
+ diag->cfg = *cfg;
- diag->cfg = *cfg;
+ fy_diag_update_term_info(diag);
}
void fy_diag_set_level(struct fy_diag *diag, enum fy_error_type level)
diag->refs--;
}
+ssize_t fy_diag_write(struct fy_diag *diag, const void *buf, size_t count)
+{
+ size_t ret;
+
+ if (!diag || !buf)
+ return -1;
+
+ /* no more output */
+ if (diag->destroyed)
+ return 0;
+
+ ret = 0;
+ if (diag->cfg.fp) {
+ ret = fwrite(buf, 1, count, diag->cfg.fp);
+ } else if (diag->cfg.output_fn) {
+ diag->cfg.output_fn(diag, diag->cfg.user, buf, count);
+ ret = count;
+ }
+
+ return ret == count ? (ssize_t)count : -1;
+}
+
int fy_diag_vprintf(struct fy_diag *diag, const char *fmt, va_list ap)
{
char *buf;
level = fydc->level;
- /* turn errors into notices while not reset */
+ /* turn errors into debugs while not reset */
if (level >= FYET_ERROR && diag->on_error)
- level = FYET_NOTICE;
+ level = FYET_DEBUG;
if (level < diag->cfg.level) {
rc = 0;
return rc;
}
+static void fy_diag_get_error_colors(struct fy_diag *diag, enum fy_error_type type,
+ const char **start, const char **end, const char **white)
+{
+ if (!diag->cfg.colorize) {
+ *start = *end = *white = "";
+ return;
+ }
+
+ switch (type) {
+ case FYET_DEBUG:
+ *start = "\x1b[37m"; /* normal white */
+ break;
+ case FYET_INFO:
+ *start = "\x1b[37;1m"; /* bright white */
+ break;
+ case FYET_NOTICE:
+ *start = "\x1b[34;1m"; /* bright blue */
+ break;
+ case FYET_WARNING:
+ *start = "\x1b[33;1m"; /* bright yellow */
+ break;
+ case FYET_ERROR:
+ *start = "\x1b[31;1m"; /* bright red */
+ break;
+ default:
+ *start = "\x1b[0m"; /* catch-all reset */
+ break;
+ }
+ *end = "\x1b[0m";
+ *white = "\x1b[37;1m";
+}
+
+void fy_diag_error_atom_display(struct fy_diag *diag, enum fy_error_type type, struct fy_atom *atom)
+{
+ const struct fy_raw_line *l, *ln;
+ struct fy_raw_line l_tmp;
+ struct fy_atom_raw_line_iter iter;
+ int content_start_col, content_end_col, content_width;
+ int pass, cols, min_col, max_col, total_lines, max_line_count, max_line_col8, max_width;
+ int start_col, end_col;
+ const char *color_start, *color_end, *white;
+ bool first_line, last_line;
+ const char *display;
+ int display_len, line_shift;
+ char qc, first_mark;
+ char *rowbuf = NULL, *rbs = NULL, *rbe = NULL;
+ const char *s, *e;
+ int col8, c, w;
+ int tab8_len, tilde_start, tilde_width, tilde_width_m1;
+ size_t rowbufsz;
+
+ (void)end_col;
+
+ if (!diag || !atom)
+ return;
+
+ fy_diag_get_error_colors(diag, type, &color_start, &color_end, &white);
+
+ /* two passes, first one collects extents */
+
+ start_col = -1;
+ end_col = -1;
+ min_col = -1;
+ max_col = -1;
+ max_line_count = -1;
+ max_line_col8 = -1;
+ total_lines = 0;
+ line_shift = -1;
+ for (pass = 0; pass < 2; pass++) {
+
+ /* on the start of the second pass */
+ if (pass > 0) {
+
+ cols = 0;
+
+ /* if it's probed, use what's there */
+ if (diag->terminal_probed && diag->term_info.columns > 0)
+ cols = diag->term_info.columns;
+
+ /* heuristic, avoid probing terminal size if maximum column is less than 80
+ * columns. This is faster and avoid problems with terminals...
+ */
+ if (!cols && max_line_col8 < 80)
+ cols = 80;
+
+ /* no choice but to probe */
+ if (!cols) {
+ /* only need the terminal width when outputting an error */
+ if (!diag->terminal_probed && fy_diag_isatty(diag))
+ fy_diag_update_term_info(diag);
+
+ cols = diag->term_info.columns;
+ }
+
+ /* worse case utf8 + 2 color sequences + zero terminated */
+ rowbufsz = cols * 4 + 2 * 16 + 1;
+ rowbuf = alloca(rowbufsz);
+ rbe = rowbuf + rowbufsz;
+
+ /* if the maximum column number is less than the terminal
+ * width everything fits, and we're fine */
+ if (max_line_col8 < cols) {
+ line_shift = 0;
+ } else {
+ max_width = max_col - min_col;
+
+ /* try to center */
+ line_shift = min_col + (max_width - cols) / 2;
+
+ /* the start of the content must always be included */
+ if (start_col < line_shift)
+ line_shift = start_col;
+ }
+ }
+
+ fy_atom_raw_line_iter_start(atom, &iter);
+ l = fy_atom_raw_line_iter_next(&iter);
+ for (; l != NULL; l = ln) {
+
+ /* save it */
+ l_tmp = *l;
+ l = &l_tmp;
+
+ /* get the next too */
+ ln = fy_atom_raw_line_iter_next(&iter);
+
+ first_line = l->lineno <= 1;
+ last_line = ln == NULL;
+
+ content_start_col = l->content_start_col8;
+ content_end_col = l->content_end_col8;
+
+ /* adjust for single and double quoted to include the quote marks (usually works) */
+ if (fy_atom_style_is_quoted(atom->style)) {
+ qc = atom->style == FYAS_SINGLE_QUOTED ? '\'' : '"';
+ if (first_line && l->content_start > l->line_start &&
+ l->content_start[-1] == qc)
+ content_start_col--;
+ if (last_line && (l->content_start + l->content_len) < (l->line_start + l->line_len) &&
+ l->content_start[l->content_len] == qc)
+ content_end_col++;
+ }
+
+ content_width = content_end_col - content_start_col;
+
+ if (pass == 0) {
+
+ total_lines++;
+
+ if (min_col < 0 || content_start_col < min_col)
+ min_col = content_start_col;
+ if (max_col < 0 || content_end_col > max_col)
+ max_col = content_end_col;
+ if (max_line_count < 0 || (int)l->line_count > max_line_count)
+ max_line_count = (int)l->line_count;
+ if (first_line)
+ start_col = content_start_col;
+ if (last_line)
+ end_col = content_end_col;
+
+ /* optimize by using the content end as a starting point */
+ s = l->content_start + l->content_len;
+ e = l->line_start + l->line_count;
+ col8 = l->content_end_col8;
+ while ((c = fy_utf8_get(s, (e - s), &w)) >= 0) {
+ s += w;
+ if (fy_is_tab(c))
+ col8 += 8 - (col8 % 8);
+ else
+ col8++;
+ }
+ /* update the max column number of the lines */
+ if (max_line_col8 < 0 || col8 > max_line_col8)
+ max_line_col8 = col8;
+
+ continue;
+ }
+
+ /* output pass */
+
+ /* the defaults if everything fits */
+ first_mark = first_line ? '^' : '~';
+
+ tab8_len = 0;
+
+ /* find the starting point */
+ s = l->line_start;
+ e = s + l->line_len;
+ col8 = 0;
+ while (col8 < line_shift && (c = fy_utf8_get(s, (e - s), &w)) >= 0) {
+ if (fy_is_tab(c))
+ col8 += 8 - (col8 % 8);
+ else
+ col8++;
+ s += w;
+ }
+ if (col8 > line_shift)
+ tab8_len = col8 - line_shift; /* the remaining of the tab */
+ else
+ tab8_len = 0;
+
+ /* start filling the row buffer */
+ assert(rowbuf);
+ rbs = rowbuf;
+ rbe = rowbuf + rowbufsz;
+
+ /* remaining tabs */
+ while (tab8_len > 0) {
+ *rbs++ = ' ';
+ tab8_len--;
+ }
+
+ /* go forward until end of line or cols */
+ while (col8 < (line_shift + cols) && (c = fy_utf8_get(s, (e - s), &w)) >= 0 && rbs < rbe) {
+ if (fy_is_tab(c)) {
+ s++;
+ tab8_len = 8 - (col8 % 8);
+ col8 += tab8_len;
+ while (tab8_len > 0 && rbs < rbe) {
+ *rbs++ = ' ';
+ tab8_len--;
+ }
+ } else {
+ while (w > 0 && rbs < rbe) {
+ *rbs++ = *s++;
+ w--;
+ }
+ col8++;
+ }
+ }
+ display = rowbuf;
+ display_len = rbs - rowbuf;
+
+ tilde_start = content_start_col - line_shift;
+ tilde_width = content_width;
+ if (tilde_start + tilde_width > cols)
+ tilde_width = cols - tilde_start;
+ tilde_width_m1 = tilde_width > 0 ? (tilde_width - 1) : 0;
+
+ /* output the line */
+ fy_diag_write(diag, display, display_len);
+
+ /* set the tildes */
+ assert((int)rowbufsz > tilde_width_m1 + 1);
+ memset(rowbuf, '~', tilde_width_m1);
+ rowbuf[tilde_width_m1] = '\0';
+
+ fy_diag_printf(diag, "\n%*s%s%c%.*s%s\n",
+ tilde_start, "",
+ color_start, first_mark, tilde_width_m1, rowbuf, color_end);
+
+ }
+ fy_atom_raw_line_iter_finish(&iter);
+ }
+}
+
+void fy_diag_error_token_display(struct fy_diag *diag, enum fy_error_type type, struct fy_token *fyt)
+{
+ if (!diag || !fyt)
+ return;
+
+ fy_diag_error_atom_display(diag, type, fy_token_atom(fyt));
+}
+
void fy_diag_vreport(struct fy_diag *diag,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap)
const char *name, *color_start = NULL, *color_end = NULL, *white = NULL;
char *msg_str = NULL, *name_str = NULL;
const struct fy_mark *start_mark;
- struct fy_atom_raw_line_iter iter;
- const struct fy_raw_line *l;
- char *tildes = "";
- int j, k, tildesz = 0, line, column;
+ int line, column;
+ struct fy_diag_errorp *errp;
+ struct fy_diag_error *err;
+ size_t spacesz, msgsz, filesz;
+ char *s;
if (!diag || !fydrc || !fmt || !fydrc->fyt)
return;
/* it will strip trailing newlines */
msg_str = alloca_vsprintf(fmt, ap);
- if (diag->cfg.colorize) {
- switch (fydrc->type) {
- case FYET_DEBUG:
- color_start = "\x1b[37m"; /* normal white */
- break;
- case FYET_INFO:
- color_start = "\x1b[37;1m"; /* bright white */
- break;
- case FYET_NOTICE:
- color_start = "\x1b[34;1m"; /* bright blue */
- break;
- case FYET_WARNING:
- color_start = "\x1b[33;1m"; /* bright yellow */
- break;
- case FYET_ERROR:
- color_start = "\x1b[31;1m"; /* bright red */
- break;
- default:
- break;
- }
- color_end = "\x1b[0m";
- white = "\x1b[37;1m";
- } else
- color_start = color_end = white = "";
+ /* get the colors */
+ fy_diag_get_error_colors(diag, fydrc->type, &color_start, &color_end, &white);
if (name || (line > 0 && column > 0))
name_str = (line > 0 && column > 0) ?
alloca_sprintf("%s%s:%d:%d: ", white, name, line, column) :
alloca_sprintf("%s%s: ", white, name);
- fy_diag_printf(diag, "%s" "%s%s: %s" "%s\n",
- name_str ? : "",
- color_start, fy_error_type_to_string(fydrc->type), color_end,
- msg_str);
-
- fy_atom_raw_line_iter_start(fy_token_atom(fydrc->fyt), &iter);
- while ((l = fy_atom_raw_line_iter_next(&iter)) != NULL) {
- fy_diag_printf(diag, "%.*s\n",
- (int)l->line_len, l->line_start);
- j = l->content_start_col8;
- k = (l->content_end_col8 - l->content_start_col8) - 1;
- if (k > tildesz) {
- if (!tildesz)
- tildesz = 32;
- while (tildesz < k)
- tildesz *= 2;
- tildes = alloca(tildesz + 1);
- memset(tildes, '~', tildesz);
- tildes[tildesz] = '\0';
- }
- fy_diag_printf(diag, "%*s%s%c%.*s%s\n",
- j, "", color_start,
- l->lineno == 1 ? '^' : '~',
- k > 0 ? k : 0, tildes, color_end);
- }
- fy_atom_raw_line_iter_finish(&iter);
+ if (!diag->collect_errors) {
+ fy_diag_printf(diag, "%s" "%s%s: %s" "%s\n",
+ name_str ? : "",
+ color_start, fy_error_type_to_string(fydrc->type), color_end,
+ msg_str);
+
+ fy_diag_error_token_display(diag, fydrc->type, fydrc->fyt);
- fy_token_unref(fydrc->fyt);
+ fy_token_unref(fydrc->fyt);
+ } else if ((errp = malloc(sizeof(*errp))) != NULL) {
+
+ msgsz = strlen(msg_str) + 1;
+ filesz = strlen(name) + 1;
+ spacesz = msgsz + filesz;
+
+ errp->space = malloc(spacesz);
+ if (!errp->space) {
+ free(errp);
+ goto out;
+ }
+ s = errp->space;
+
+ err = &errp->e;
+ memset(err, 0, sizeof(*err));
+ err->type = fydrc->type;
+ err->module = fydrc->module;
+ err->fyt = fydrc->fyt;
+ err->msg = s;
+ memcpy(s, msg_str, msgsz);
+ s += msgsz;
+ err->file = s;
+ memcpy(s, name, filesz);
+ s += filesz;
+ err->line = line;
+ err->column = column;
+
+ fy_diag_errorp_list_add_tail(&diag->errors, errp);
+ }
+out:
if (!diag->on_error && fydrc->type == FYET_ERROR)
diag->on_error = true;
}
}
/* composer */
-
int fy_composer_vdiag(struct fy_composer *fyc, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, va_list ap)
va_end(ap);
}
+/* document_builder */
+int fy_document_builder_vdiag(struct fy_document_builder *fydb, unsigned int flags,
+ const char *file, int line, const char *func,
+ const char *fmt, va_list ap)
+{
+ struct fy_diag_ctx fydc;
+ int rc;
+
+ if (!fydb || !fmt || !fydb->cfg.diag)
+ return -1;
+
+ /* perform the enable tests early to avoid the overhead */
+ if (((flags & FYDF_LEVEL_MASK) >> FYDF_LEVEL_SHIFT) < fydb->cfg.diag->cfg.level)
+ return 0;
+
+ /* fill in fy_diag_ctx */
+ memset(&fydc, 0, sizeof(fydc));
+
+ fydc.level = (flags & FYDF_LEVEL_MASK) >> FYDF_LEVEL_SHIFT;
+ fydc.module = (flags & FYDF_MODULE_MASK) >> FYDF_MODULE_SHIFT;
+ fydc.source_file = file;
+ fydc.source_line = line;
+ fydc.source_func = func;
+ fydc.line = -1;
+ fydc.column = -1;
+
+ rc = fy_vdiag(fydb->cfg.diag, &fydc, fmt, ap);
+
+ return rc;
+}
+
+int fy_document_builder_diag(struct fy_document_builder *fydb, unsigned int flags,
+ const char *file, int line, const char *func,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int rc;
+
+ va_start(ap, fmt);
+ rc = fy_document_builder_vdiag(fydb, flags, file, line, func, fmt, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+void fy_document_builder_diag_vreport(struct fy_document_builder *fydb,
+ const struct fy_diag_report_ctx *fydrc,
+ const char *fmt, va_list ap)
+{
+ if (!fydb || !fydb->cfg.diag || !fydrc || !fmt)
+ return;
+
+ fy_diag_vreport(fydb->cfg.diag, fydrc, fmt, ap);
+}
+
+void fy_document_builder_diag_report(struct fy_document_builder *fydb,
+ const struct fy_diag_report_ctx *fydrc,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fy_document_builder_diag_vreport(fydb, fydrc, fmt, ap);
+ va_end(ap);
+}
+
/* reader */
int fy_reader_vdiag(struct fy_reader *fyr, unsigned int flags,
#define FYDF_MODULE_USER_MASK 7
#define FYDF_MODULE_USER(x) FYDF_MODULE(8 + ((x) & FYDF_MODULE_USER_MASK))
-struct fy_diag {
- struct fy_diag_cfg cfg;
- int refs;
- bool on_error : 1;
- bool destroyed : 1;
+struct fy_diag_term_info {
+ int rows;
+ int columns;
};
-void fy_diag_free(struct fy_diag *diag);
-
struct fy_diag_report_ctx {
enum fy_error_type type;
enum fy_error_module module;
int override_column;
};
+FY_TYPE_FWD_DECL_LIST(diag_errorp);
+struct fy_diag_errorp {
+ struct list_head node;
+ char *space;
+ struct fy_diag_error e;
+};
+FY_TYPE_DECL_LIST(diag_errorp);
+
+struct fy_diag {
+ struct fy_diag_cfg cfg;
+ int refs;
+ bool on_error : 1;
+ bool destroyed : 1;
+ bool collect_errors : 1;
+ bool terminal_probed : 1;
+ struct fy_diag_term_info term_info;
+ struct fy_diag_errorp_list errors;
+};
+
+void fy_diag_free(struct fy_diag *diag);
+
void fy_diag_vreport(struct fy_diag *diag,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
const char *fmt, ...)
__attribute__((format(printf, 6, 7)));
+void fy_diag_error_atom_display(struct fy_diag *diag, enum fy_error_type type,
+ struct fy_atom *atom);
+void fy_diag_error_token_display(struct fy_diag *diag, enum fy_error_type type,
+ struct fy_token *fyt);
+
void fy_parser_diag_vreport(struct fy_parser *fyp,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
#define FYC_TOKEN_WARNING(_fyc, _fyt, _module, _fmt, ...) \
FYC_TOKEN_DIAG(_fyc, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
+/* document builder */
+struct fy_document_builder;
+
+int fy_document_builder_vdiag(struct fy_document_builder *fydb, unsigned int flags,
+ const char *file, int line, const char *func,
+ const char *fmt, va_list ap);
+
+int fy_document_builder_diag(struct fy_document_builder *fydb, unsigned int flags,
+ const char *file, int line, const char *func,
+ const char *fmt, ...)
+ __attribute__((format(printf, 6, 7)));
+
+void fy_document_builder_diag_vreport(struct fy_document_builder *fydb,
+ const struct fy_diag_report_ctx *fydrc,
+ const char *fmt, va_list ap);
+void fy_document_builder_diag_report(struct fy_document_builder *fydb,
+ const struct fy_diag_report_ctx *fydrc,
+ const char *fmt, ...)
+ __attribute__((format(printf, 3, 4)));
+
+#ifndef NDEBUG
+
+#define fydb_debug(_fydb, _module, _fmt, ...) \
+ fy_document_builder_diag((_fydb), FYET_DEBUG | FYDF_MODULE(_module), \
+ __FILE__, __LINE__, __func__, \
+ (_fmt) , ## __VA_ARGS__)
+
+#else
+
+#define fydb_debug(_fydb, _module, _fmt, ...) \
+ do { } while(0)
+
+#endif
+
+#define fydb_info(_fydb, _fmt, ...) \
+ fy_document_builder_diag((_fydb), FYET_INFO, __FILE__, __LINE__, __func__, \
+ (_fmt) , ## __VA_ARGS__)
+#define fydb_notice(_fydb, _fmt, ...) \
+ fy_document_builder_diag((_fydb), FYET_NOTICE, __FILE__, __LINE__, __func__, \
+ (_fmt) , ## __VA_ARGS__)
+#define fydb_warning(_fydb, _fmt, ...) \
+ fy_document_builder_diag((_fydb), FYET_WARNING, __FILE__, __LINE__, __func__, \
+ (_fmt) , ## __VA_ARGS__)
+#define fydb_error(_fydb, _fmt, ...) \
+ fy_document_builder_diag((_fydb), FYET_ERROR, __FILE__, __LINE__, __func__, \
+ (_fmt) , ## __VA_ARGS__)
+
+#define fydb_error_check(_fydb, _cond, _label, _fmt, ...) \
+ do { \
+ if (!(_cond)) { \
+ fydb_error((_fydb), _fmt, ## __VA_ARGS__); \
+ goto _label ; \
+ } \
+ } while(0)
+
+#define _FYDB_TOKEN_DIAG(_fydb, _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_document_builder_diag_report((_fydb), &_drc, (_fmt) , ## __VA_ARGS__); \
+ } while(0)
+
+#define FYDB_TOKEN_DIAG(_fydb, _fyt, _type, _module, _fmt, ...) \
+ _FYDB_TOKEN_DIAG(_fydb, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__)
+
+#define FYDB_NODE_DIAG(_fydb, _fyn, _type, _module, _fmt, ...) \
+ _FYDB_TOKEN_DIAG(_fydb, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__)
+
+#define FYDB_TOKEN_ERROR(_fydb, _fyt, _module, _fmt, ...) \
+ FYDB_TOKEN_DIAG(_fydb, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
+
+#define FYDB_NODE_ERROR(_fydb, _fyn, _module, _fmt, ...) \
+ FYDB_NODE_DIAG(_fydb, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
+
+#define FYDB_TOKEN_ERROR_CHECK(_fydb, _fyt, _module, _cond, _label, _fmt, ...) \
+ do { \
+ if (!(_cond)) { \
+ FYDB_TOKEN_ERROR(_fydb, _fyt, _module, _fmt, ## __VA_ARGS__); \
+ goto _label; \
+ } \
+ } while(0)
+
+#define FYDB_NODE_ERROR_CHECK(_fydb, _fyn, _module, _cond, _label, _fmt, ...) \
+ do { \
+ if (!(_cond)) { \
+ FYDB_NODE_ERROR(_fydb, _fyn, _module, _fmt, ## __VA_ARGS__); \
+ goto _label; \
+ } \
+ } while(0)
+
+#define FYDB_TOKEN_WARNING(_fydb, _fyt, _module, _fmt, ...) \
+ FYDB_TOKEN_DIAG(_fydb, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
+
/* alloca formatted print methods */
#define alloca_vsprintf(_fmt, _ap) \
({ \
}
fynpp1 = alloca(sizeof(*fynpp1) * (count1 + 1));
- fynpp2 = alloca(sizeof(*fynpp2) * (count2 + 1));
-
+ fy_node_mapping_fill_array(fyn1, fynpp1, count1);
fy_node_mapping_perform_sort(fyn1, sort_fn, sort_fn_arg, fynpp1, count1);
+
+ fynpp2 = alloca(sizeof(*fynpp2) * (count2 + 1));
+ fy_node_mapping_fill_array(fyn2, fynpp2, count2);
fy_node_mapping_perform_sort(fyn2, sort_fn, sort_fn_arg, fynpp2, count2);
for (i = 0; i < count1; i++) {
fyp_error_check(fyp, !rc, err_out_rc,
"fy_parse_document_load_node() failed");
- /* make sure we don't add an already existing key */
- duplicate = fy_node_mapping_key_is_duplicate(fyn, fyn_key);
+ /* if we don't allow duplicate keys */
+ if (!(fyd->parse_cfg.flags & FYPCF_ALLOW_DUPLICATE_KEYS)) {
+
+ /* make sure we don't add an already existing key */
+ duplicate = fy_node_mapping_key_is_duplicate(fyn, fyn_key);
- FYP_NODE_ERROR_CHECK(fyp, fyn_key, FYEM_DOC,
- !duplicate, err_out,
- "duplicate key");
+ FYP_NODE_ERROR_CHECK(fyp, fyn_key, FYEM_DOC,
+ !duplicate, err_out,
+ "duplicate key");
+ }
fyep = fy_parse_private(fyp);
return rc;
}
-/* TODO vary according to platfom */
-static inline int fy_depth_limit(void)
-{
- return FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT;
-}
-
static int
fy_parse_document_load_node(struct fy_parser *fyp, struct fy_document *fyd,
struct fy_eventp *fyep, struct fy_node **fynp,
struct fy_document *fy_parse_load_document_with_builder(struct fy_parser *fyp)
{
+ struct fy_document_builder_cfg cfg;
struct fy_document *fyd;
int rc;
return NULL;
if (!fyp->fydb) {
- fyp->fydb = fy_document_builder_create(&fyp->cfg);
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.parse_cfg = fyp->cfg;
+ cfg.userdata = fyp;
+ cfg.diag = fy_diag_ref(fyp->diag);
+
+ fyp->fydb = fy_document_builder_create(&cfg);
if (!fyp->fydb)
return NULL;
}
for (fynpi = fy_node_pair_list_head(&fynm->mapping); fynpi;
fynpi = fy_node_pair_next(&fynm->mapping, fynpi)) {
- /* make sure we don't override an already existing key */
- if (fy_node_mapping_key_is_duplicate(fyn, fynpi->key))
- continue;
+ /* if we don't allow duplicate keys */
+ if (!(fyd->parse_cfg.flags & FYPCF_ALLOW_DUPLICATE_KEYS)) {
+
+ /* make sure we don't override an already existing key */
+ if (fy_node_mapping_key_is_duplicate(fyn, fynpi->key))
+ continue;
+ }
fynpn = fy_node_pair_alloc(fyd);
fyd_error_check(fyd, fynpn, err_out,
fyd_error_check(fyd, fyd->fyds, err_out,
"fy_document_state_default() failed");
+ /* turn on JSON mode if it's forced */
+ fyd->fyds->json_mode = (cfg->flags &
+ (FYPCF_JSON_MASK << FYPCF_JSON_SHIFT)) == FYPCF_JSON_FORCE;
+
fy_document_list_init(&fyd->children);
return fyd;
return fynp ? fynp->key : NULL;
}
+bool fy_node_is_empty(struct fy_node *fyn)
+{
+ struct fy_node *fyni;
+ struct fy_node_pair *fynp;
+ struct fy_atom *atom;
+
+ /* skip if no value node or token */
+ if (!fyn)
+ return true;
+
+ switch (fyn->type) {
+ case FYNT_SCALAR:
+ atom = fy_token_atom(fyn->scalar);
+ if (atom && !atom->size0 && !atom->empty)
+ return false;
+ break;
+ case FYNT_SEQUENCE:
+ for (fyni = fy_node_list_head(&fyn->sequence); fyni;
+ fyni = fy_node_next(&fyn->sequence, fyni)) {
+ if (!fy_node_is_empty(fyni))
+ return false;
+ }
+ break;
+ case FYNT_MAPPING:
+ for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp;
+ fynp = fy_node_pair_next(&fyn->mapping, fynp)) {
+ if (!fy_node_is_empty(fynp->value))
+ return false;
+ }
+ break;
+ }
+ return true;
+}
+
#define fy_node_walk_ctx_create_a(_max_depth, _mark) \
({ \
unsigned int __max_depth = (_max_depth); \
(fyn_value && fyn_value->attached))
return NULL;
- if (fy_node_mapping_key_is_duplicate(fyn_map, fyn_key))
- return NULL;
+ /* if we don't allow duplicate keys */
+ if (!(fyd->parse_cfg.flags & FYPCF_ALLOW_DUPLICATE_KEYS)) {
+
+ if (fy_node_mapping_key_is_duplicate(fyn_map, fyn_key))
+ return NULL;
+ }
fynp = fy_node_pair_alloc(fyd);
if (!fynp)
return idx_a > idx_b ? 1 : (idx_a < idx_b ? -1 : 0);
}
-void fy_node_mapping_perform_sort(struct fy_node *fyn_map,
- fy_node_mapping_sort_fn key_cmp, void *arg,
+void fy_node_mapping_fill_array(struct fy_node *fyn_map,
struct fy_node_pair **fynpp, int count)
{
- int i;
struct fy_node_pair *fynpi;
- struct fy_node_mapping_sort_ctx ctx;
- struct fy_node_cmp_arg def_arg;
+ int i;
for (i = 0, fynpi = fy_node_pair_list_head(&fyn_map->mapping); i < count && fynpi;
fynpi = fy_node_pair_next(&fyn_map->mapping, fynpi), i++)
fynpp[i++] = NULL;
assert(i == count);
+}
+
+void fy_node_mapping_perform_sort(struct fy_node *fyn_map,
+ fy_node_mapping_sort_fn key_cmp, void *arg,
+ struct fy_node_pair **fynpp, int count)
+{
+ struct fy_node_mapping_sort_ctx ctx;
+ struct fy_node_cmp_arg def_arg;
+
if (!key_cmp) {
def_arg.cmp_fn = fy_node_scalar_cmp_default;
def_arg.arg = arg;
memset(fynpp, 0, (count + 1) * sizeof(*fynpp));
+ fy_node_mapping_fill_array(fyn_map, fynpp, count);
fy_node_mapping_perform_sort(fyn_map, key_cmp, arg, fynpp, count);
if (countp)
return fynpp;
}
-void fy_node_mapping_sort_release_array(struct fy_node *fyn_map, struct fy_node_pair **fynpp)
+void fy_node_mapping_release_array(struct fy_node *fyn_map, struct fy_node_pair **fynpp)
{
if (!fyn_map || !fynpp)
return;
fy_node_pair_list_add_tail(&fyn_map->mapping, fynpi);
}
- fy_node_mapping_sort_release_array(fyn_map, fynpp);
+ fy_node_mapping_release_array(fyn_map, fynpp);
return 0;
}
count = fy_node_mapping_item_count(fyn);
fynpp = alloca(sizeof(*fynpp) * (count + 1));
+
+ fy_node_mapping_fill_array(fyn, fynpp, count);
fy_node_mapping_perform_sort(fyn, NULL, NULL, fynpp, count);
/* MAPPING */
return 0;
}
-const char *fy_document_builder_state_txt[] = {
- [FYDBS_NODE] = "node",
- [FYDBS_MAP_KEY] = "map-key",
- [FYDBS_MAP_VAL] = "map-val",
- [FYDBS_SEQ] = "seq",
-};
-
-void
-fy_document_builder_reset(struct fy_document_builder *fydb)
-{
- struct fy_document_builder_ctx *c;
- unsigned int i;
-
- if (!fydb)
- return;
-
- for (i = 0, c = fydb->stack; i < fydb->next; i++, c++) {
- fy_node_free(c->fyn);
- c->fyn = NULL;
- fy_node_pair_free(c->fynp);
- c->fynp = NULL;
- }
- fydb->next = 0;
-
- if (fydb->fyd) {
- fy_document_destroy(fydb->fyd);
- fydb->fyd = NULL;
- }
- fydb->in_stream = false;
- fydb->doc_done = false;
-}
-
-struct fy_document_builder *
-fy_document_builder_create(const struct fy_parse_cfg *cfg)
-{
- struct fy_document_builder *fydb = NULL;
-
- if (!cfg)
- cfg = &doc_parse_default_cfg;
-
- fydb = malloc(sizeof(*fydb));
- if (!fydb)
- goto err_out;
-
- memset(fydb, 0, sizeof(*fydb));
- fydb->cfg = *cfg;
- fydb->next = 0;
- fydb->in_stream = false;
- fydb->doc_done = false;
- fydb->alloc = fy_depth_limit(); /* always start with this */
- fydb->max_depth = (cfg->flags & FYPCF_DISABLE_DEPTH_LIMIT) ? 0 : fy_depth_limit();
-
- fydb->stack = malloc(fydb->alloc * sizeof(*fydb->stack));
- if (!fydb->stack)
- goto err_out;
-
- return fydb;
-
-err_out:
- if (fydb) {
- if (fydb->stack)
- free(fydb->stack);
- free(fydb);
- }
-
- return NULL;
-}
-
-void
-fy_document_builder_destroy(struct fy_document_builder *fydb)
+struct fy_ptr_node *fy_ptr_node_create(struct fy_node *fyn)
{
- if (!fydb)
- return;
-
- fy_document_builder_reset(fydb);
+ struct fy_ptr_node *fypn;
- if (fydb->stack)
- free(fydb->stack);
- free(fydb);
-}
+ if (!fyn)
+ return NULL;
-struct fy_document *
-fy_document_builder_get_document(struct fy_document_builder *fydb)
-{
- return fydb ? fydb->fyd : NULL;
+ fypn = malloc(sizeof(*fypn));
+ if (!fypn)
+ return NULL;
+ memset(&fypn->node, 0, sizeof(fypn->node));
+ fypn->fyn = fyn;
+ return fypn;
}
-bool
-fy_document_builder_is_in_stream(struct fy_document_builder *fydb)
+void fy_ptr_node_destroy(struct fy_ptr_node *fypn)
{
- return fydb && fydb->in_stream;
+ free(fypn);
}
-bool
-fy_document_builder_is_in_document(struct fy_document_builder *fydb)
+void fy_ptr_node_list_free_all(struct fy_ptr_node_list *fypnl)
{
- return fydb && fydb->fyd != NULL && !fydb->doc_done;
-}
+ struct fy_ptr_node *fypn;
-bool
-fy_document_builder_is_document_complete(struct fy_document_builder *fydb)
-{
- return fydb && fydb->fyd != NULL && fydb->doc_done;
+ while ((fypn = fy_ptr_node_list_pop(fypnl)) != NULL)
+ fy_ptr_node_destroy(fypn);
}
-struct fy_document *
-fy_document_builder_take_document(struct fy_document_builder *fydb)
+bool fy_ptr_node_list_contains(struct fy_ptr_node_list *fypnl, struct fy_node *fyn)
{
- struct fy_document *fyd;
+ struct fy_ptr_node *fypn;
- if (!fy_document_builder_is_document_complete(fydb))
- return NULL;
- fyd = fydb->fyd;
- fydb->fyd = NULL;
- fydb->doc_done = false;
- return fyd;
+ if (!fypnl || !fyn)
+ return false;
+ for (fypn = fy_ptr_node_list_head(fypnl); fypn; fypn = fy_ptr_node_next(fypnl, fypn)) {
+ if (fypn->fyn == fyn)
+ return true;
+ }
+ return false;
}
struct fy_document *
-fy_document_builder_peek_document(struct fy_document_builder *fydb)
+fy_document_create_from_event(struct fy_parser *fyp, struct fy_event *fye)
{
struct fy_document *fyd;
- struct fy_document_builder_ctx *c;
+ int rc;
- if (!fydb)
+ if (!fyp || !fye || fye->type != FYET_DOCUMENT_START)
return NULL;
- /* just peek; may be incomplete */
- fyd = fydb->fyd;
-
- assert(fydb->next > 0);
- c = &fydb->stack[0];
+ /* TODO update document end */
+ fyd = fy_document_create(&fyp->cfg);
+ fyp_error_check(fyp, fyd, err_out,
+ "fy_document_create() failed");
- /* wire the root */
- if (!fyd->root)
- fyd->root = c->fyn;
+ rc = fy_document_set_document_state(fyd, fye->document_start.document_state);
+ fyp_error_check(fyp, !rc, err_out,
+ "fy_document_set_document_state() failed");
return fyd;
-}
-
-void
-fy_document_builder_set_in_stream(struct fy_document_builder *fydb)
-{
- if (!fydb)
- return;
- /* reset */
- fy_document_builder_reset(fydb);
-
- fydb->in_stream = true;
+err_out:
+ fy_document_destroy(fyd);
+ return NULL;
}
int
-fy_document_builder_set_in_document(struct fy_document_builder *fydb, struct fy_document_state *fyds, bool single)
+fy_document_update_from_event(struct fy_document *fyd, struct fy_parser *fyp, struct fy_event *fye)
{
- struct fy_document_builder_ctx *c;
- int rc;
-
- if (!fydb)
- return -1;
-
- /* reset */
- fy_document_builder_reset(fydb);
-
- fydb->in_stream = true;
-
- fydb->fyd = fy_document_create(&fydb->cfg);
- if (!fydb->fyd)
+ if (!fyd || !fyp || !fye || fye->type != FYET_DOCUMENT_END)
return -1;
- if (fyds) {
- rc = fy_document_set_document_state(fydb->fyd, fyds);
- if (rc)
- return rc;
- }
-
- fydb->doc_done = false;
- fydb->single_mode = single;
-
- /* be paranoid */
- assert(fydb->next < fydb->alloc);
-
- c = &fydb->stack[++fydb->next - 1];
- memset(c, 0, sizeof(*c));
- c->s = FYDBS_NODE;
-
+ /* nothing besides checks */
return 0;
}
-#undef DBG
-// #define DBG fyp_info
-#define DBG fyp_doc_debug
-
-int
-fy_document_builder_process_event(struct fy_document_builder *fydb,
- struct fy_parser *fyp, struct fy_eventp *fyep)
+struct fy_node *
+fy_node_create_from_event(struct fy_document *fyd, struct fy_parser *fyp, struct fy_event *fye)
{
- struct fy_event *fye;
- enum fy_event_type etype;
- struct fy_document *fyd;
- struct fy_document_builder_ctx *c, *cp;
- struct fy_node *fyn, *fyn_parent;
- struct fy_node_pair *fynp;
- struct fy_document_builder_ctx *newc;
- struct fy_token *fyt;
+ struct fy_node *fyn = NULL;
+ struct fy_token *value = NULL, *anchor = NULL;
int rc;
- fye = fyep ? &fyep->e : NULL;
- etype = fye ? fye->type : FYET_NONE;
- fyt = fye ? fy_event_get_token(fye) : NULL;
-
- /* not in document */
- if (!fydb->next) {
- switch (etype) {
- case FYET_STREAM_START:
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC,
- !fydb->in_stream, err_out,
- "STREAM_START while in stream error");
- fydb->in_stream = true;
- break;
-
- case FYET_STREAM_END:
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC,
- fydb->in_stream, err_out,
- "STREAM_END while not in stream error");
- fydb->in_stream = false;
- return 1;
-
- case FYET_DOCUMENT_START:
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC,
- fydb->in_stream, err_out,
- "DOCUMENT_START while not in stream error");
-
- /* no-one cares, destroy the document */
- if (!fydb->fyd)
- fy_document_destroy(fydb->fyd);
-
- fydb->fyd = fy_document_create(&fydb->cfg);
- fyp_error_check(fyp, fydb->fyd, err_out,
- "fy_document_create() failed");
-
- rc = fy_document_set_document_state(fydb->fyd, fyep->e.document_start.document_state);
- fyp_error_check(fyp, !rc, err_out,
- "fy_document_set_document_state() failed");
-
- fydb->doc_done = false;
- goto push;
-
- case FYET_DOCUMENT_END:
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC,
- fydb->in_stream, err_out,
- "DOCUMENT_END while not in stream error");
-
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC,
- fydb->fyd, err_out,
- "DOCUMENT_END without a document");
-
- fydb->doc_done = true;
- break;
-
- default:
- /* unexpected event */
- FYP_TOKEN_ERROR(fyp, fyt, FYEM_DOC,
- "Unexpected event %s in non-build mode\n",
- fy_event_type_txt[etype]);
- goto err_out;
- }
+ if (!fyd || !fye)
+ return NULL;
- return 0;
- }
+ switch (fye->type) {
+ default:
+ break;
- fyd = fydb->fyd;
+ case FYET_SCALAR:
+ fyn = fy_node_alloc(fyd, FYNT_SCALAR);
+ fyp_error_check(fyp, fyn, err_out,
+ "fy_node_alloc() scalar failed");
- c = &fydb->stack[fydb->next - 1];
- fyn = NULL;
+ value = fye->scalar.value;
- /* verify that we have a document */
- assert(fydb->fyd);
- /* the top state must always be NODE for processing the event */
- assert(c->s == FYDBS_NODE);
+ if (value) /* NULL scalar */
+ fyn->style = fy_node_style_from_scalar_style(value->scalar.style);
+ else
+ fyn->style = FYNS_PLAIN;
- // DBG(fyp, "%d: %s <- %s (%s)\n", fydb->next - 1, fy_document_builder_state_txt[c->s], fy_event_type_txt[etype], fy_token_debug_text_a(fyt));
+ /* NULLs are OK */
+ fyn->tag = fy_token_ref(fye->scalar.tag);
+ fyn->scalar = fy_token_ref(value);
+ anchor = fye->scalar.anchor;
+ break;
- switch (etype) {
- case FYET_SCALAR:
case FYET_ALIAS:
fyn = fy_node_alloc(fyd, FYNT_SCALAR);
fyp_error_check(fyp, fyn, err_out,
- "fy_node_alloc() SCALAR failed");
+ "fy_node_alloc() alias failed");
- if (etype == FYET_SCALAR) {
- if (fye->scalar.value)
- fyn->style = fy_node_style_from_scalar_style(fye->scalar.value->scalar.style);
- else
- fyn->style = FYNS_PLAIN;
- fyn->tag = fy_token_ref(fye->scalar.tag);
- if (fye->scalar.anchor) {
- rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(fye->scalar.anchor));
- fyp_error_check(fyp, !rc, err_out,
- "fy_document_register_anchor() failed");
- }
- fyn->scalar = fy_token_ref(fye->scalar.value);
- } else {
- fyn->style = FYNS_ALIAS;
- fyn->scalar = fy_token_ref(fye->alias.anchor);
- }
- goto complete;
+ value = fye->alias.anchor;
+ fyn->style = FYNS_ALIAS;
+ fyn->scalar = fy_token_ref(value);
+ anchor = NULL;
+ break;
case FYET_MAPPING_START:
- // DBG(fyp, "%d: %s -> %s\n", fydb->next - 1, fy_document_builder_state_txt[c->s], fy_document_builder_state_txt[FYDBS_MAP_KEY]);
- c->s = FYDBS_MAP_KEY;
-
- fyn = fy_node_alloc(fyd, FYNT_MAPPING);
+ fyn = fy_node_create_mapping(fyd);
fyp_error_check(fyp, fyn, err_out,
- "fy_node_alloc() MAPPING failed");
+ "fy_node_create_mapping() failed");
+
+ value = fye->mapping_start.mapping_start;
+ fyn->style = value->type == FYTT_FLOW_MAPPING_START ? FYNS_FLOW : FYNS_BLOCK;
- c->fyn = fyn;
- fyn->style = fye->mapping_start.mapping_start->type == FYTT_FLOW_MAPPING_START ? FYNS_FLOW : FYNS_BLOCK;
fyn->tag = fy_token_ref(fye->mapping_start.tag);
- if (fye->mapping_start.anchor) {
- rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(fye->mapping_start.anchor));
- fyp_error_check(fyp, !rc, err_out,
- "fy_document_register_anchor() failed");
- }
- fyn->mapping_start = fy_token_ref(fye->mapping_start.mapping_start);
+ fyn->mapping_start = fy_token_ref(value);
+ fyn->mapping_end = NULL;
+ anchor = fye->mapping_start.anchor;
break;
- case FYET_MAPPING_END:
-
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC, fydb->next > 1, err_out,
- "Unexpected MAPPING_END (unexpected end of mapping)");
-
- cp = &fydb->stack[fydb->next - 2];
-
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC, cp->s == FYDBS_MAP_KEY, err_out,
- "Unexpected MAPPING_END (not in mapping)");
-
- fyn = cp->fyn;
- fyn->mapping_end = fy_token_ref(fye->mapping_end.mapping_end);
- fydb->next--;
- goto complete;
-
case FYET_SEQUENCE_START:
- // DBG(fyp, "%d: %s -> %s\n", fydb->next - 1, fy_document_builder_state_txt[c->s], fy_document_builder_state_txt[FYDBS_SEQ]);
- c->s = FYDBS_SEQ;
- fyn = fy_node_alloc(fyd, FYNT_SEQUENCE);
+ fyn = fy_node_create_sequence(fyd);
fyp_error_check(fyp, fyn, err_out,
- "fy_node_alloc() SEQUENCE failed");
+ "fy_node_create_sequence() failed");
- c->fyn = fyn;
- fyn->style = fye->sequence_start.sequence_start->type == FYTT_FLOW_SEQUENCE_START ? FYNS_FLOW : FYNS_BLOCK;
- fyn->tag = fy_token_ref(fye->sequence_start.tag);
- if (fye->sequence_start.anchor) {
- rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(fye->sequence_start.anchor));
- fyp_error_check(fyp, !rc, err_out,
- "fy_document_register_anchor() failed");
- }
- fyn->sequence_start = fy_token_ref(fye->sequence_start.sequence_start);
- break;
+ value = fye->sequence_start.sequence_start;
- case FYET_SEQUENCE_END:
+ fyn->style = value->type == FYTT_FLOW_SEQUENCE_START ? FYNS_FLOW : FYNS_BLOCK;
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC, fydb->next > 1, err_out,
- "Unexpected SEQUENCE_END (unexpected end of sequence)");
-
- cp = &fydb->stack[fydb->next - 2];
-
- FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_DOC, cp->s == FYDBS_SEQ, err_out,
- "Unexpected MAPPING_SEQUENCE (not in sequence)");
-
- fyn = cp->fyn;
- fyn->sequence_end = fy_token_ref(fye->sequence_end.sequence_end);
- fydb->next--;
- goto complete;
-
- default:
- /* unexpected event */
- FYP_TOKEN_ERROR(fyp, fyt, FYEM_DOC,
- "Unexpected event %s in build mode\n",
- fy_event_type_txt[etype]);
- goto err_out;
- }
-
-push:
- FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC,
- !fydb->max_depth || fydb->next < fydb->max_depth, err_out,
- "Max depth (%d) exceeded\n", fydb->next);
-
- /* grow the stack? */
- if (fydb->next >= fydb->alloc) {
- newc = realloc(fydb->stack, fydb->alloc * 2 * sizeof(*fydb->stack));
- fyp_error_check(fyp, newc, err_out,
- "Unable to grow the context stack");
- fydb->alloc *= 2;
- fydb->stack = newc;
- }
- assert(fydb->next < fydb->alloc);
-
- // DBG(fyp, "%d: PUSH %s -> %s\n", fydb->next - 1,
- // fydb->next > 0 ? fy_document_builder_state_txt[fydb->stack[fydb->next - 1].s] : "<NIL>",
- // fy_document_builder_state_txt[FYDBS_NODE]);
-
- c = &fydb->stack[++fydb->next - 1];
- memset(c, 0, sizeof(*c));
- c->s = FYDBS_NODE;
- return 0;
-
-err_out:
- return -1;
-
-complete:
- assert(fydb->next > 0);
- c = &fydb->stack[fydb->next - 1];
- c->fyn = fyn;
- // DBG(fyp, "%d: COMPLETE %s -> %s\n", fydb->next - 1,
- // fy_document_builder_state_txt[c->s],
- // fydb->next > 1 ? fy_document_builder_state_txt[fydb->stack[fydb->next - 2].s] : "<NIL>");
- assert(fydb->next > 0);
- fydb->next--;
-
- /* root */
- if (fydb->next == 0) {
- fyd->root = fyn;
- // DBG(fyp, "root done\n");
- /* if we're in single mode, don't wait for doc end */
- if (fydb->single_mode)
- fydb->doc_done = true;
- return 1;
- }
-
- c = &fydb->stack[fydb->next - 1];
-
- // DBG(fyp, "%d: %s - COMPLETE\n", fydb->next - 1, fy_document_builder_state_txt[c->s]);
-
- fyn_parent = c->fyn;
-
- switch (c->s) {
-
- case FYDBS_MAP_KEY:
- fynp = fy_node_pair_alloc(fyd);
- assert(fynp);
- fynp->key = fyn;
- c->fynp = fynp;
-
- /* make sure we don't add an already existing key */
- if (fy_node_mapping_key_is_duplicate(fyn_parent, fyn)) {
- FYP_NODE_ERROR(fyp, fyn, FYEM_DOC, "duplicate key");
- goto err_out;
- }
-
- // DBG(fyp, "%d: %s -> %s\n", fydb->next - 1, fy_document_builder_state_txt[c->s], fy_document_builder_state_txt[FYDBS_MAP_VAL]);
- c->s = FYDBS_MAP_VAL;
- goto push;
-
- case FYDBS_MAP_VAL:
- fynp = c->fynp;
- assert(fynp);
- fynp->value = fyn;
-
- /* set the parent of the node pair and value */
- fynp->parent = fyn_parent;
- if (fynp->key) {
- fynp->key->parent = fyn_parent;
- fynp->key->key_root = true;
- }
- if (fynp->value)
- fynp->value->parent = fyn_parent;
-
- fy_node_pair_list_add_tail(&c->fyn->mapping, fynp);
- if (fyn->xl) {
- rc = fy_accel_insert(fyn->xl, fynp->key, fynp);
- assert(!rc);
- }
- if (fynp->key)
- fynp->key->attached = true;
- if (fynp->value)
- fynp->value->attached = true;
-
- c->fynp = NULL;
- // DBG(fyp, "%d: %s -> %s\n", fydb->next - 1, fy_document_builder_state_txt[c->s], fy_document_builder_state_txt[FYDBS_MAP_KEY]);
- c->s = FYDBS_MAP_KEY;
- goto push;
-
- case FYDBS_SEQ:
- /* append sequence */
- fyn->parent = fyn_parent;
- fy_node_list_add_tail(&c->fyn->sequence, fyn);
- fyn->attached = true;
- goto push;
-
- case FYDBS_NODE:
- /* complete is a scalar */
- fyn->parent = fyn_parent;
- return 0;
- }
-
- return 0;
-}
-
-struct fy_document *
-fy_document_builder_load_document(struct fy_document_builder *fydb,
- struct fy_parser *fyp)
-{
- struct fy_eventp *fyep = NULL;
- int rc;
-
- if (fyp->state == FYPS_END)
- return NULL;
-
- while (!fy_document_builder_is_document_complete(fydb) &&
- (fyep = fy_parse_private(fyp)) != NULL) {
- rc = fy_document_builder_process_event(fydb, fyp, fyep);
- fy_parse_eventp_recycle(fyp, fyep);
- if (rc < 0) {
- fyp->stream_error = true;
- return NULL;
- }
- }
-
- /* get ownership of the document */
- return fy_document_builder_take_document(fydb);
-}
-
-static bool fy_node_iterator_ensure_space(struct fy_node_iterator *fyi)
-{
- struct fy_node_iterator_state *new_stack;
- size_t size;
-
- if (fyi->count < fyi->alloc)
- return true;
-
- size = fyi->alloc * sizeof(*new_stack);
-
- if (fyi->stack == fyi->in_place) {
- new_stack = malloc(size * 2);
- if (!new_stack) {
- fyi->result = FYNIR_NOMEM;
- assert(0);
- return false;
- }
- memcpy(new_stack, fyi->stack, size);
- } else {
- new_stack = realloc(fyi->stack, size * 2);
- if (!new_stack) {
- fyi->result = FYNIR_NOMEM;
- assert(0);
- return false;
- }
- }
- fyi->stack = new_stack;
- fyi->alloc *= 2;
- return true;
-}
-
-void fy_node_iterator_setup(struct fy_node_iterator *fyi, enum fy_node_iterator_flags flags)
-{
- fyi->flags = flags;
- fyi->result = FYNIR_OK;
- fyi->count = 0;
- fyi->alloc = sizeof(fyi->in_place) / sizeof(fyi->in_place[0]);
- fyi->stack = fyi->in_place;
-}
-
-void fy_node_iterator_cleanup(struct fy_node_iterator *fyi)
-{
- if (!fyi)
- return;
- if (fyi->stack != fyi->in_place)
- free(fyi->stack);
- fyi->result = FYNIR_OK;
- fyi->count = 0;
- fyi->alloc = sizeof(fyi->in_place) / sizeof(fyi->in_place[0]);
- fyi->stack = fyi->in_place;
-}
-
-struct fy_node_iterator *fy_node_iterator_create(enum fy_node_iterator_flags flags)
-{
- struct fy_node_iterator *fyi;
-
- fyi = malloc(sizeof(*fyi));
- if (!fyi)
- return NULL;
- fy_node_iterator_setup(fyi, flags);
- return fyi;
-}
-
-void fy_node_iterator_destroy(struct fy_node_iterator *fyi)
-{
- if (!fyi)
- return;
- fy_node_iterator_cleanup(fyi);
- free(fyi);
-}
-
-void fy_node_iterator_start(struct fy_node_iterator *fyi, struct fy_node *fyn)
-{
- if (!fyi || !fyn)
- return;
-
- fyi->count = 1;
- fyi->stack[0].fyn = fyn;
- fyi->result = FYNIR_OK;
-}
-
-#define fy_node_info_a(_fyn) \
- ({ \
- struct fy_node *__fyn = (_fyn); \
- const char *__text = NULL; \
- \
- if (!__fyn) { \
- __text = "<NULL>"; \
- } else { \
- switch (__fyn->type) { \
- case FYNT_SCALAR: \
- __text = fy_node_get_scalar0(__fyn); \
- break; \
- case FYNT_MAPPING: \
- __text = "{"; \
- break; \
- case FYNT_SEQUENCE: \
- __text = "["; \
- break; \
- } \
- } \
- __text; \
- })
-
-struct fy_node *fy_node_iterator_next(struct fy_node_iterator *fyi, struct fy_node *fyn)
-{
- struct fy_node *fyni, *parent;
- struct fy_node_pair *fynp;
- struct fy_node *fyna;
- unsigned int i;
-
- if (!fyi || fyi->count == 0)
- return NULL;
-
- if (!fyn) {
- assert(fyi->count == 1);
- /* start */
- fyn = fyi->stack[fyi->count - 1].fyn;
- assert(fyn);
- // fprintf(stderr, "start: %s\n", fy_node_get_path_a(fyn));
- goto out;
- }
-
- if (fyi->count == 0)
- return NULL;
-
- assert(fyi->count > 0);
-
- /* protect against stupid calls */
- if (fyn != fyi->stack[fyi->count - 1].fyn) {
- fyi->result = FYNIR_ARGS;
- return NULL;
- }
-
-from_the_top:
-
- /* if we're following links, check for self reference loop */
- if (fyi->flags & FYNIF_FOLLOW_LINKS) {
- for (i = 0; i < fyi->count-1; i++) {
- if (fyn == fyi->stack[i].fyn) {
- /* loop! */
- fyi->result = FYNIR_LOOP;
- return NULL;
- }
- }
- }
-
- switch (fyn->type) {
- case FYNT_SCALAR:
- /* we do not follow links, or node is not an alias */
- if (!(fyi->flags & FYNIF_FOLLOW_LINKS) || !fy_node_is_alias(fyn))
- break;
-
- fyna = fy_node_resolve_alias(fyn);
- if (!fyna) {
- fyi->result = FYNIR_BAD_ALIAS;
- return NULL;
- }
-
- if (!fy_node_iterator_ensure_space(fyi))
- return NULL;
-
- fyi->count++;
- fyi->stack[fyi->count - 1].fyn = fyna;
- fyi->stack[fyi->count - 1].fynp = NULL;
- // fprintf(stderr, "+alias: %s @%s - %s @%s\n",
- // fy_node_info_a(fyn), fy_node_get_path_a(fyn),
- // fy_node_info_a(fyna), fy_node_get_path(fyna));
- fyn = fyna;
- goto out;
-
- case FYNT_SEQUENCE:
- fyni = fy_node_list_head(&fyn->sequence);
-
- /* if there are no items, next */
- if (!fyni)
- break;
-
- if (!fy_node_iterator_ensure_space(fyi))
- return NULL;
-
- fyi->count++;
- fyi->stack[fyi->count - 1].fyn = fyni;
- fyi->stack[fyi->count - 1].idx = 0;
-
- // fprintf(stderr, "+seq: %s @%s - first %s @%s\n",
- // fy_node_info_a(fyn), fy_node_get_path_a(fyn),
- // fy_node_info_a(fyni), fy_node_get_path(fyni));
-
- goto out;
-
- case FYNT_MAPPING:
- fynp = fy_node_pair_list_head(&fyn->mapping);
-
- /* empty mapping? next */
- if (!fynp || (!fynp->key && !fynp->value))
- break;
-
- /* we're not following keys, and there's no value? next */
- if (!(fyi->flags & FYNIF_FOLLOW_KEYS) && !fynp->value)
- break;
-
- if (!fy_node_iterator_ensure_space(fyi))
- return NULL;
-
- fyi->count++;
- if ((fyi->flags & FYNIF_FOLLOW_KEYS) && fynp->key) {
- fyi->stack[fyi->count - 1].fyn = fynp->key;
- // fprintf(stderr, "+map: %s @%s - first key %s @%s\n",
- // fy_node_info_a(fyn), fy_node_get_path_a(fyn),
- // fy_node_info_a(fynp->key), fy_node_get_path(fynp->key));
- } else {
- fyi->stack[fyi->count - 1].fyn = fynp->value;
- // fprintf(stderr, "+map: %s @%s - first key %s @%s\n",
- // fy_node_info_a(fyn), fy_node_get_path_a(fyn),
- // fy_node_info_a(fynp->value), fy_node_get_path(fynp->value));
- }
- fyi->stack[fyi->count - 1].fynp = fynp;
- goto out;
- }
-
- /* next */
-again:
- if (fyi->count == 0) {
- // fprintf(stderr, "end: count=0\n");
- return NULL;
- }
- if (fyi->count == 1) {
- // fprintf(stderr, "end: count=1\n");
- /* last one */
- fyi->count--;
- return NULL;
- }
-
- parent = fyi->stack[fyi->count - 2].fyn;
- switch (parent->type) {
- case FYNT_SCALAR:
- assert(fy_node_is_alias(parent));
- // fprintf(stderr, "alias-next: %s @%s\n", fy_node_info_a(fyn), fy_node_get_path_a(fyn));
- fyi->count--;
- fyn = fyi->stack[fyi->count - 1].fyn;
- goto again;
-
- case FYNT_SEQUENCE:
- fyn = fy_node_next(&parent->sequence, fyn);
- if (!fyn) {
- fyi->count--;
- assert(fyi->count > 0);
-
- // fprintf(stderr, "seq-end: %s @%s\n", fy_node_info_a(parent), fy_node_get_path_a(parent));
-
- fyn = fyi->stack[fyi->count - 1].fyn;
- goto again;
- }
-
- // fprintf(stderr, "seq-next: %s @%s\n", fy_node_info_a(fyn), fy_node_get_path_a(fyn));
-
- fyi->stack[fyi->count - 1].fyn = fyn;
- fyi->stack[fyi->count - 1].idx++;
- break;
-
- case FYNT_MAPPING:
- fynp = fyi->stack[fyi->count - 1].fynp;
- assert(fynp);
- assert(fyn == fynp->key || fyn == fynp->value);
-
- /* got key? now get value */
- if (fyn == fynp->key && fynp->value) {
- fyi->stack[fyi->count - 1].fyn = fynp->value;
-
- // fprintf(stderr, "map-next: value1 %s @%s\n", fy_node_info_a(fynp->value), fy_node_get_path_a(fynp->value));
-
- break;
- }
-
- for (;;) {
- fynp = fy_node_pair_next(&parent->mapping, fynp);
- if (!fynp) {
- fyi->count--;
- assert(fyi->count > 0);
-
- // fprintf(stderr, "map-end: %s @%s\n", fy_node_info_a(parent), fy_node_get_path_a(parent));
-
- fyn = fyi->stack[fyi->count - 1].fyn;
- goto again;
- }
- if ((fyi->flags & FYNIF_FOLLOW_KEYS) && fynp->key) {
- fyi->stack[fyi->count - 1].fyn = fynp->key;
- // fprintf(stderr, "map-next: key %s @%s\n", fy_node_info_a(fynp->key), fy_node_get_path_a(fynp->key));
- break;
- }
- if (fynp->value) {
- fyi->stack[fyi->count - 1].fyn = fynp->value;
- // fprintf(stderr, "map-next: value2 %s @%s\n", fy_node_info_a(fynp->value), fy_node_get_path_a(fynp->value));
- break;
- }
- }
- fyi->stack[fyi->count - 1].fynp = fynp;
- break;
- }
-
-out:
- fyn = fyi->stack[fyi->count - 1].fyn;
- assert(fyn);
-
- /* if we're following and erasing the links and an alias, redo */
- if ((fyi->flags & (FYNIF_FOLLOW_LINKS | FYNIF_ERASE_LINKS)) ==
- (FYNIF_FOLLOW_LINKS | FYNIF_ERASE_LINKS) &&
- fy_node_is_alias(fyn))
- goto from_the_top;
-
- return fyn;
-}
-
-enum fy_node_iterator_result fy_node_iterator_end(struct fy_node_iterator *fyi)
-{
- enum fy_node_iterator_result res;
-
- if (!fyi)
- return FYNIR_ARGS;
-
- res = fyi->result;
- fyi->result = FYNIR_OK;
-
- return res;
-}
-
-struct fy_ptr_node *fy_ptr_node_create(struct fy_node *fyn)
-{
- struct fy_ptr_node *fypn;
-
- if (!fyn)
- return NULL;
-
- fypn = malloc(sizeof(*fypn));
- if (!fypn)
- return NULL;
- memset(&fypn->node, 0, sizeof(fypn->node));
- fypn->fyn = fyn;
- return fypn;
-}
-
-void fy_ptr_node_destroy(struct fy_ptr_node *fypn)
-{
- free(fypn);
-}
-
-void fy_ptr_node_list_free_all(struct fy_ptr_node_list *fypnl)
-{
- struct fy_ptr_node *fypn;
-
- while ((fypn = fy_ptr_node_list_pop(fypnl)) != NULL)
- fy_ptr_node_destroy(fypn);
-}
-
-bool fy_ptr_node_list_contains(struct fy_ptr_node_list *fypnl, struct fy_node *fyn)
-{
- struct fy_ptr_node *fypn;
-
- if (!fypnl || !fyn)
- return false;
- for (fypn = fy_ptr_node_list_head(fypnl); fypn; fypn = fy_ptr_node_next(fypnl, fypn)) {
- if (fypn->fyn == fyn)
- return true;
- }
- return false;
-}
-
-int fy_node_linearize_recursive(struct fy_ptr_node_list *fypnl, struct fy_node *fyn)
-{
- struct fy_ptr_node *fypn;
- struct fy_node *fyni;
- struct fy_node_pair *fynp;
- int ret;
-
- if (!fyn)
- return 0;
-
- /* recursive loop */
- if (fy_ptr_node_list_contains(fypnl, fyn))
- return 1;
-
- fypn = fy_ptr_node_create(fyn);
- if (!fypn)
- return -1;
-
- fy_ptr_node_list_add_tail(fypnl, fypn);
-
- switch (fyn->type) {
- case FYNT_SCALAR:
- break;
-
- case FYNT_SEQUENCE:
- for (fyni = fy_node_list_head(&fyn->sequence); fyni;
- fyni = fy_node_next(&fyn->sequence, fyni)) {
-
- ret = fy_node_linearize_recursive(fypnl, fyni);
- if (ret != 0)
- return ret;
- }
- break;
-
- case FYNT_MAPPING:
- for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp;
- fynp = fy_node_pair_next(&fyn->mapping, fynp)) {
-
- ret = fy_node_linearize_recursive(fypnl, fynp->key);
- if (ret != 0)
- return ret;
- ret = fy_node_linearize_recursive(fypnl, fynp->value);
- if (ret != 0)
- return ret;
- }
- break;
- }
-
- return 0;
-}
-
-int fy_node_linearize(struct fy_ptr_node_list *fypnl, struct fy_node *fyn)
-{
- struct fy_node_iterator fyi_local, *fyi = &fyi_local;
- enum fy_node_iterator_result res;
- struct fy_ptr_node *fypn;
- int ret;
-
- fy_node_iterator_setup(fyi, FYNIF_DEPTH_FIRST | FYNIF_FOLLOW_KEYS);
-
- ret = 0;
- fy_node_iterator_start(fyi, fyn);
- fyn = NULL;
- while ((fyn = fy_node_iterator_next(fyi, fyn)) != NULL) {
-
- /* recursive loop */
- if (fy_ptr_node_list_contains(fypnl, fyn)) {
- ret = 1;
- break;
- }
- fypn = fy_ptr_node_create(fyn);
- if (!fypn) {
- ret = -1;
- break;
- }
- fy_ptr_node_list_add_tail(fypnl, fypn);
- }
-
- res = fy_node_iterator_end(fyi);
- if (res != FYNIR_OK)
- return -1;
-
- fy_node_iterator_cleanup(fyi);
-
- return ret;
-}
-
-void fy_node_iterator_check(struct fy_node *fyn)
-{
- struct fy_ptr_node_list l1, l2;
- struct fy_ptr_node *fypn1, *fypn2;
- int ret __FY_DEBUG_UNUSED__;
-
- fy_ptr_node_list_init(&l1);
- fy_ptr_node_list_init(&l2);
-
- ret = fy_node_linearize_recursive(&l1, fyn);
- assert(!ret);
- ret = fy_node_linearize(&l2, fyn);
- assert(!ret);
-
- fypn1 = fy_ptr_node_list_head(&l1);
- fypn2 = fy_ptr_node_list_head(&l2);
-
- while (fypn1 && fypn2) {
- if (fypn1->fyn != fypn2->fyn) {
- fprintf(stderr, "%s: %s != %s\n", __func__, fy_node_get_path_a(fypn1->fyn), fy_node_get_path_a(fypn2->fyn));
- break;
- }
-
- fypn1 = fy_ptr_node_next(&l1, fypn1);
- fypn2 = fy_ptr_node_next(&l2, fypn2);
- }
-
- if (!fypn1) {
- if (fypn2)
- fprintf(stderr, "%s: <NULL> != %s\n", __func__, fy_node_get_path_a(fypn2->fyn));
- }
- if (!fypn2) {
- if (fypn1)
- fprintf(stderr, "%s: %s != <NULL>\n", __func__, fy_node_get_path_a(fypn1->fyn));
- }
-
- fy_ptr_node_list_free_all(&l2);
- fy_ptr_node_list_free_all(&l1);
-}
-
-int fy_node_check_ref_loop(struct fy_node *fyn)
-{
- struct fy_node_iterator fyi_local, *fyi = &fyi_local;
- enum fy_node_iterator_result res;
-
- fy_node_iterator_setup(fyi, FYNIF_DEPTH_FIRST | FYNIF_FOLLOW_KEYS | FYNIF_FOLLOW_LINKS);
-
- fy_node_iterator_start(fyi, fyn);
-
- /* if there's a reference loop the iterator will NULL with an error */
- fyn = NULL;
- while ((fyn = fy_node_iterator_next(fyi, fyn)) != NULL) { }
-
- res = fy_node_iterator_end(fyi);
-
- fy_node_iterator_cleanup(fyi);
-
- return res == FYNIR_OK ? 0 : -1;
-}
-
-struct fy_document *
-fy_document_create_from_event(struct fy_parser *fyp, struct fy_event *fye)
-{
- struct fy_document *fyd;
- int rc;
-
- if (!fyp || !fye || fye->type != FYET_DOCUMENT_START)
- return NULL;
-
- /* TODO update document end */
- fyd = fy_document_create(&fyp->cfg);
- fyp_error_check(fyp, fyd, err_out,
- "fy_document_create() failed");
-
- rc = fy_document_set_document_state(fyd, fye->document_start.document_state);
- fyp_error_check(fyp, !rc, err_out,
- "fy_document_set_document_state() failed");
-
- return fyd;
-
-err_out:
- fy_document_destroy(fyd);
- return NULL;
-}
-
-int
-fy_document_update_from_event(struct fy_document *fyd, struct fy_parser *fyp, struct fy_event *fye)
-{
- if (!fyd || !fyp || !fye || fye->type != FYET_DOCUMENT_END)
- return -1;
-
- /* nothing besides checks */
- return 0;
-}
-
-struct fy_node *
-fy_node_create_from_event(struct fy_document *fyd, struct fy_parser *fyp, struct fy_event *fye)
-{
- struct fy_node *fyn = NULL;
- struct fy_token *value = NULL, *anchor = NULL;
- int rc;
-
- if (!fyd || !fye)
- return NULL;
-
- switch (fye->type) {
- default:
- break;
-
- case FYET_SCALAR:
- fyn = fy_node_alloc(fyd, FYNT_SCALAR);
- fyp_error_check(fyp, fyn, err_out,
- "fy_node_alloc() scalar failed");
-
- value = fye->scalar.value;
-
- if (value) /* NULL scalar */
- fyn->style = fy_node_style_from_scalar_style(value->scalar.style);
- else
- fyn->style = FYNS_PLAIN;
-
- /* NULLs are OK */
- fyn->tag = fy_token_ref(fye->scalar.tag);
- fyn->scalar = fy_token_ref(value);
- anchor = fye->scalar.anchor;
- break;
-
- case FYET_ALIAS:
- fyn = fy_node_alloc(fyd, FYNT_SCALAR);
- fyp_error_check(fyp, fyn, err_out,
- "fy_node_alloc() alias failed");
-
- value = fye->alias.anchor;
- fyn->style = FYNS_ALIAS;
- fyn->scalar = fy_token_ref(value);
- anchor = NULL;
- break;
-
- case FYET_MAPPING_START:
- fyn = fy_node_create_mapping(fyd);
- fyp_error_check(fyp, fyn, err_out,
- "fy_node_create_mapping() failed");
-
- value = fye->mapping_start.mapping_start;
- fyn->style = value->type == FYTT_FLOW_MAPPING_START ? FYNS_FLOW : FYNS_BLOCK;
-
- fyn->tag = fy_token_ref(fye->mapping_start.tag);
- fyn->mapping_start = fy_token_ref(value);
- fyn->mapping_end = NULL;
- anchor = fye->mapping_start.anchor;
- break;
-
- case FYET_SEQUENCE_START:
- fyn = fy_node_create_sequence(fyd);
- fyp_error_check(fyp, fyn, err_out,
- "fy_node_create_sequence() failed");
-
- value = fye->sequence_start.sequence_start;
-
- fyn->style = value->type == FYTT_FLOW_SEQUENCE_START ? FYNS_FLOW : FYNS_BLOCK;
-
- fyn->tag = fy_token_ref(fye->sequence_start.tag);
- fyn->sequence_start = fy_token_ref(value);
- fyn->sequence_end = NULL;
- anchor = fye->sequence_start.anchor;
+ fyn->tag = fy_token_ref(fye->sequence_start.tag);
+ fyn->sequence_start = fy_token_ref(value);
+ fyn->sequence_end = NULL;
+ anchor = fye->sequence_start.anchor;
break;
if (!fyd || !fyn_parent || !fy_node_is_mapping(fyn_parent))
return NULL;
- /* make sure we don't add an already existing key */
- is_duplicate = fy_node_mapping_key_is_duplicate(fyn_parent, fyn);
- if (is_duplicate) {
- FYD_NODE_ERROR(fyd, fyn, FYEM_DOC,
- "duplicate mapping key");
- return NULL;
+ /* if we don't allow duplicate keys */
+ if (!(fyd->parse_cfg.flags & FYPCF_ALLOW_DUPLICATE_KEYS)) {
+
+ /* make sure we don't add an already existing key */
+ is_duplicate = fy_node_mapping_key_is_duplicate(fyn_parent, fyn);
+ if (is_duplicate) {
+ FYD_NODE_ERROR(fyd, fyn, FYEM_DOC,
+ "duplicate mapping key");
+ return NULL;
+ }
}
fynp = fy_node_pair_alloc(fyd);
fyn->attached = true;
return 0;
}
+
+void fy_document_iterator_setup(struct fy_document_iterator *fydi)
+{
+ memset(fydi, 0, sizeof(*fydi));
+ fydi->state = FYDIS_WAITING_STREAM_START;
+ fydi->fyd = NULL;
+ fydi->iterate_root = NULL;
+
+ /* suppress recycling if we must */
+ fydi->suppress_recycling_force = getenv("FY_VALGRIND") && !getenv("FY_VALGRIND_RECYCLING");
+ fydi->suppress_recycling = fydi->suppress_recycling_force;
+
+ fy_eventp_list_init(&fydi->recycled_eventp);
+ fy_token_list_init(&fydi->recycled_token);
+
+ if (!fydi->suppress_recycling) {
+ fydi->recycled_eventp_list = &fydi->recycled_eventp;
+ fydi->recycled_token_list = &fydi->recycled_token;
+ } else {
+ fydi->recycled_eventp_list = NULL;
+ fydi->recycled_token_list = NULL;
+ }
+
+ /* start with the stack pointing to the in place data */
+ fydi->stack_top = (unsigned int)-1;
+ fydi->stack_alloc = sizeof(fydi->in_place) / sizeof(fydi->in_place[0]);
+ fydi->stack = fydi->in_place;
+}
+
+void fy_document_iterator_cleanup(struct fy_document_iterator *fydi)
+{
+ struct fy_token *fyt;
+ struct fy_eventp *fyep;
+
+ /* free the stack if it's not the inplace one */
+ if (fydi->stack != fydi->in_place)
+ free(fydi->stack);
+ fydi->stack_top = (unsigned int)-1;
+ fydi->stack_alloc = sizeof(fydi->in_place) / sizeof(fydi->in_place[0]);
+ fydi->stack = fydi->in_place;
+
+ while ((fyt = fy_token_list_pop(&fydi->recycled_token)) != NULL)
+ fy_token_free(fyt);
+
+ while ((fyep = fy_eventp_list_pop(&fydi->recycled_eventp)) != NULL)
+ fy_eventp_free(fyep);
+
+ fydi->state = FYDIS_WAITING_STREAM_START;
+ fydi->fyd = NULL;
+ fydi->iterate_root = NULL;
+}
+
+struct fy_document_iterator *fy_document_iterator_create(void)
+{
+ struct fy_document_iterator *fydi;
+
+ fydi = malloc(sizeof(*fydi));
+ if (!fydi)
+ return NULL;
+ fy_document_iterator_setup(fydi);
+ return fydi;
+}
+
+void fy_document_iterator_destroy(struct fy_document_iterator *fydi)
+{
+ if (!fydi)
+ return;
+ fy_document_iterator_cleanup(fydi);
+ free(fydi);
+}
+
+static struct fy_event *
+fydi_event_create(struct fy_document_iterator *fydi, struct fy_node *fyn, bool start)
+{
+ struct fy_eventp *fyep;
+ struct fy_event *fye;
+ struct fy_anchor *fya;
+ struct fy_token *anchor = NULL;
+
+ fyep = fy_document_iterator_eventp_alloc(fydi);
+ if (!fyep) {
+ fydi->state = FYDIS_ERROR;
+ return NULL;
+ }
+ fye = &fyep->e;
+
+ if (start) {
+ fya = fy_node_get_anchor(fyn);
+ anchor = fya ? fya->anchor : NULL;
+ }
+
+ switch (fyn->type) {
+
+ case FYNT_SCALAR:
+ if (fyn->style != FYNS_ALIAS) {
+ fye->type = FYET_SCALAR;
+ fye->scalar.anchor = fy_token_ref(anchor);
+ fye->scalar.tag = fy_token_ref(fyn->tag);
+ fye->scalar.value = fy_token_ref(fyn->scalar);
+ } else {
+ fye->type = FYET_ALIAS;
+ fye->alias.anchor = fy_token_ref(fyn->scalar);
+ }
+ break;
+
+ case FYNT_SEQUENCE:
+ if (start) {
+ fye->type = FYET_SEQUENCE_START;
+ fye->sequence_start.anchor = fy_token_ref(anchor);
+ fye->sequence_start.tag = fy_token_ref(fyn->tag);
+ fye->sequence_start.sequence_start = fy_token_ref(fyn->sequence_start);
+ } else {
+ fye->type = FYET_SEQUENCE_END;
+ fye->sequence_end.sequence_end = fy_token_ref(fyn->sequence_end);
+ }
+ break;
+
+ case FYNT_MAPPING:
+ if (start) {
+ fye->type = FYET_MAPPING_START;
+ fye->mapping_start.anchor = fy_token_ref(anchor);
+ fye->mapping_start.tag = fy_token_ref(fyn->tag);
+ fye->mapping_start.mapping_start = fy_token_ref(fyn->mapping_start);
+ } else {
+ fye->type = FYET_MAPPING_END;
+ fye->mapping_end.mapping_end = fy_token_ref(fyn->mapping_end);
+ }
+ break;
+ }
+
+ return fye;
+}
+
+struct fy_event *
+fy_document_iterator_stream_start(struct fy_document_iterator *fydi)
+{
+ struct fy_event *fye;
+
+ if (!fydi || fydi->state == FYDIS_ERROR)
+ return NULL;
+
+ /* both none and stream start are the same for this */
+ if (fydi->state != FYDIS_WAITING_STREAM_START &&
+ fydi->state != FYDIS_WAITING_STREAM_END_OR_DOCUMENT_START)
+ goto err_out;
+
+ fye = fy_document_iterator_event_create(fydi, FYET_STREAM_START);
+ if (!fye)
+ goto err_out;
+
+ fydi->state = FYDIS_WAITING_DOCUMENT_START;
+ return fye;
+
+err_out:
+ fydi->state = FYDIS_ERROR;
+ return NULL;
+}
+
+struct fy_event *
+fy_document_iterator_stream_end(struct fy_document_iterator *fydi)
+{
+ struct fy_event *fye;
+
+ if (!fydi || fydi->state == FYDIS_ERROR)
+ return NULL;
+
+ if (fydi->state != FYDIS_WAITING_STREAM_END_OR_DOCUMENT_START &&
+ fydi->state != FYDIS_WAITING_DOCUMENT_START)
+ goto err_out;
+
+ fye = fy_document_iterator_event_create(fydi, FYET_STREAM_END);
+ if (!fye)
+ goto err_out;
+
+ fydi->state = FYDIS_WAITING_STREAM_START;
+ return fye;
+
+err_out:
+ fydi->state = FYDIS_ERROR;
+ return NULL;
+}
+
+struct fy_event *
+fy_document_iterator_document_start(struct fy_document_iterator *fydi, struct fy_document *fyd)
+{
+ struct fy_event *fye = NULL;
+ struct fy_eventp *fyep;
+
+ if (!fydi || fydi->state == FYDIS_ERROR)
+ return NULL;
+
+ if (!fyd)
+ goto err_out;
+
+ /* we can transition to document start only from document start or stream end */
+ if (fydi->state != FYDIS_WAITING_DOCUMENT_START &&
+ fydi->state != FYDIS_WAITING_STREAM_END_OR_DOCUMENT_START)
+ goto err_out;
+
+ fyep = fy_document_iterator_eventp_alloc(fydi);
+ if (!fyep)
+ goto err_out;
+ fye = &fyep->e;
+
+ fydi->fyd = fyd;
+
+ /* the iteration root is the document root */
+ fydi->iterate_root = fyd->root;
+
+ /* suppress recycling if we must */
+ fydi->suppress_recycling = (fyd->parse_cfg.flags & FYPCF_DISABLE_RECYCLING) ||
+ fydi->suppress_recycling_force;
+
+ if (!fydi->suppress_recycling) {
+ fydi->recycled_eventp_list = &fydi->recycled_eventp;
+ fydi->recycled_token_list = &fydi->recycled_token;
+ } else {
+ fydi->recycled_eventp_list = NULL;
+ fydi->recycled_token_list = NULL;
+ }
+
+ fye->type = FYET_DOCUMENT_START;
+ fye->document_start.document_start = NULL;
+ fye->document_start.document_state = fy_document_state_ref(fyd->fyds);
+ fye->document_start.implicit = fyd->fyds->start_implicit;
+
+ /* and go into body */
+ fydi->state = FYDIS_WAITING_BODY_START_OR_DOCUMENT_END;
+
+ return fye;
+
+err_out:
+ fy_document_iterator_event_free(fydi, fye);
+ fydi->state = FYDIS_ERROR;
+ return NULL;
+}
+
+struct fy_event *
+fy_document_iterator_document_end(struct fy_document_iterator *fydi)
+{
+ struct fy_event *fye;
+
+ if (!fydi || fydi->state == FYDIS_ERROR)
+ return NULL;
+
+ if (!fydi->fyd || !fydi->fyd->fyds ||
+ fydi->state != FYDIS_WAITING_DOCUMENT_END)
+ goto err_out;
+
+ fye = fy_document_iterator_event_create(fydi, FYET_DOCUMENT_END, (int)fydi->fyd->fyds->end_implicit);
+ if (!fye)
+ goto err_out;
+
+ fydi->fyd = NULL;
+ fydi->iterate_root = NULL;
+
+ fydi->state = FYDIS_WAITING_STREAM_END_OR_DOCUMENT_START;
+ return fye;
+
+err_out:
+ fydi->state = FYDIS_ERROR;
+ return NULL;
+}
+
+static bool
+fy_document_iterator_ensure_space(struct fy_document_iterator *fydi, unsigned int space)
+{
+ struct fy_document_iterator_body_state *new_stack;
+ size_t new_size, copy_size;
+ unsigned int new_stack_alloc;
+
+ /* empty stack should always have enough space */
+ if (fydi->stack_top == (unsigned int)-1) {
+ assert(fydi->stack_alloc >= space);
+ return true;
+ }
+
+ if (fydi->stack_top + space < fydi->stack_alloc)
+ return true;
+
+ /* make sure we have enough space */
+ new_stack_alloc = fydi->stack_alloc * 2;
+ while (fydi->stack_top + space >= new_stack_alloc)
+ new_stack_alloc *= 2;
+
+ new_size = new_stack_alloc * sizeof(*new_stack);
+
+ if (fydi->stack == fydi->in_place) {
+ new_stack = malloc(new_size);
+ if (!new_stack)
+ return false;
+ copy_size = (fydi->stack_top + 1) * sizeof(*new_stack);
+ memcpy(new_stack, fydi->stack, copy_size);
+ } else {
+ new_stack = realloc(fydi->stack, new_size);
+ if (!new_stack)
+ return false;
+ }
+ fydi->stack = new_stack;
+ fydi->stack_alloc = new_stack_alloc;
+ return true;
+}
+
+static bool
+fydi_push_collection(struct fy_document_iterator *fydi, struct fy_node *fyn)
+{
+ struct fy_document_iterator_body_state *s;
+
+ /* make sure there's enough space */
+ if (!fy_document_iterator_ensure_space(fydi, 1))
+ return false;
+
+ /* get the next */
+ fydi->stack_top++;
+ s = &fydi->stack[fydi->stack_top];
+ s->fyn = fyn;
+
+ switch (fyn->type) {
+ case FYNT_SEQUENCE:
+ s->fyni = fy_node_list_head(&fyn->sequence);
+ break;
+
+ case FYNT_MAPPING:
+ s->fynp = fy_node_pair_list_head(&fyn->mapping);
+ s->processed_key = false;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ return true;
+}
+
+static inline void
+fydi_pop_collection(struct fy_document_iterator *fydi)
+{
+ assert(fydi->stack_top != (unsigned int)-1);
+ fydi->stack_top--;
+}
+
+static inline struct fy_document_iterator_body_state *
+fydi_last_collection(struct fy_document_iterator *fydi)
+{
+ if (fydi->stack_top == (unsigned int)-1)
+ return NULL;
+ return &fydi->stack[fydi->stack_top];
+}
+
+bool
+fy_document_iterator_body_next_internal(struct fy_document_iterator *fydi,
+ struct fy_document_iterator_body_result *res)
+{
+ struct fy_document_iterator_body_state *s;
+ struct fy_node *fyn, *fyn_col;
+ bool end;
+
+ if (!fydi || !res || fydi->state == FYDIS_ERROR)
+ return false;
+
+ if (fydi->state != FYDIS_WAITING_BODY_START_OR_DOCUMENT_END &&
+ fydi->state != FYDIS_BODY)
+ goto err_out;
+
+ end = false;
+ s = fydi_last_collection(fydi);
+ if (!s) {
+
+ fyn = fydi->iterate_root;
+ /* empty root, or last */
+ if (!fyn || fydi->state == FYDIS_BODY) {
+ fydi->state = FYDIS_WAITING_DOCUMENT_END;
+ return false;
+ }
+
+ /* ok, in body proper */
+ fydi->state = FYDIS_BODY;
+
+ } else {
+
+ fyn_col = s->fyn;
+ assert(fyn_col);
+
+ fyn = NULL;
+ if (fyn_col->type == FYNT_SEQUENCE) {
+ fyn = s->fyni;
+ if (fyn)
+ s->fyni = fy_node_next(&fyn_col->sequence, s->fyni);
+ } else {
+ assert(fyn_col->type == FYNT_MAPPING);
+ if (s->fynp) {
+ if (!s->processed_key) {
+ fyn = s->fynp->key;
+ s->processed_key = true;
+ } else {
+ fyn = s->fynp->value;
+ s->processed_key = false;
+
+ /* next in mapping after value */
+ s->fynp = fy_node_pair_next(&fyn_col->mapping, s->fynp);
+ }
+ }
+ }
+
+ /* if no next node in the collection, it's the end of the collection */
+ if (!fyn) {
+ fyn = fyn_col;
+ end = true;
+ }
+ }
+
+ assert(fyn);
+
+ /* only for collections */
+ if (fyn->type != FYNT_SCALAR) {
+ if (!end) {
+ /* push the new sequence */
+ if (!fydi_push_collection(fydi, fyn))
+ goto err_out;
+ } else
+ fydi_pop_collection(fydi);
+ }
+
+ res->fyn = fyn;
+ res->end = end;
+ return true;
+
+err_out:
+ fydi->state = FYDIS_ERROR;
+ return false;
+}
+
+struct fy_event *fy_document_iterator_body_next(struct fy_document_iterator *fydi)
+{
+ struct fy_document_iterator_body_result res;
+
+ if (!fydi)
+ return NULL;
+
+ if (!fy_document_iterator_body_next_internal(fydi, &res))
+ return NULL;
+
+ return fydi_event_create(fydi, res.fyn, !res.end);
+}
+
+void
+fy_document_iterator_node_start(struct fy_document_iterator *fydi, struct fy_node *fyn)
+{
+ /* do nothing on error */
+ if (!fydi || fydi->state == FYDIS_ERROR)
+ return;
+
+ /* and go into body */
+ fydi->state = FYDIS_WAITING_BODY_START_OR_DOCUMENT_END;
+ fydi->iterate_root = fyn;
+ fydi->fyd = NULL;
+}
+
+struct fy_node *fy_document_iterator_node_next(struct fy_document_iterator *fydi)
+{
+ struct fy_document_iterator_body_result res;
+
+ if (!fydi)
+ return NULL;
+
+ /* do not return ending nodes, are not interested in them */
+ do {
+ if (!fy_document_iterator_body_next_internal(fydi, &res))
+ return NULL;
+
+ } while (res.end);
+
+ return res.fyn;
+}
+
+bool fy_document_iterator_get_error(struct fy_document_iterator *fydi)
+{
+ if (!fydi)
+ return true;
+
+ if (fydi->state != FYDIS_ERROR)
+ return false;
+
+ fy_document_iterator_cleanup(fydi);
+
+ return true;
+}
#include "fy-docstate.h"
#include "fy-accel.h"
#include "fy-walk.h"
+#include "fy-path.h"
struct fy_eventp;
+/* TODO vary according to platfom */
+static inline int fy_depth_limit(void)
+{
+ return FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT;
+}
+
FY_TYPE_FWD_DECL_LIST(document);
struct fy_node;
fy_node_mapping_sort_fn key_cmp, void *arg,
struct fy_node_pair **fynpp, int count);
+void fy_node_mapping_fill_array(struct fy_node *fyn_map,
+ struct fy_node_pair **fynpp, int count);
+
struct fy_node_pair **fy_node_mapping_sort_array(struct fy_node *fyn_map,
fy_node_mapping_sort_fn key_cmp,
void *arg, int *countp);
-void fy_node_mapping_sort_release_array(struct fy_node *fyn_map, struct fy_node_pair **fynpp);
+void fy_node_mapping_release_array(struct fy_node *fyn_map, struct fy_node_pair **fynpp);
struct fy_node_walk_ctx {
unsigned int max_depth;
struct fy_node *marked[0];
};
+bool fy_node_is_empty(struct fy_node *fyn);
+
bool fy_check_ref_loop(struct fy_document *fyd, struct fy_node *fyn,
enum fy_node_walk_flags flags,
struct fy_node_walk_ctx *ctx);
/* TODO move to main include */
struct fy_node *fy_node_collection_iterate(struct fy_node *fyn, void **prevp);
-enum fy_document_builder_state {
- FYDBS_NODE,
- FYDBS_MAP_KEY,
- FYDBS_MAP_VAL,
- FYDBS_SEQ,
-};
-
-struct fy_document_builder_ctx {
- enum fy_document_builder_state s;
+/* indirect node */
+FY_TYPE_FWD_DECL_LIST(ptr_node);
+struct fy_ptr_node {
+ struct list_head node;
struct fy_node *fyn;
- struct fy_node_pair *fynp; /* for mapping */
};
+FY_TYPE_DECL_LIST(ptr_node);
-struct fy_document_builder {
- struct fy_parse_cfg cfg;
- bool single_mode;
- struct fy_document *fyd;
- bool in_stream;
- bool doc_done;
- unsigned int next;
- unsigned int alloc;
- unsigned int max_depth;
- struct fy_document_builder_ctx *stack;
-};
-
-struct fy_document_builder *
-fy_document_builder_create(const struct fy_parse_cfg *cfg);
-
-void
-fy_document_builder_reset(struct fy_document_builder *fydb);
-
-void
-fy_document_builder_destroy(struct fy_document_builder *fydb);
-
-struct fy_document *
-fy_document_builder_get_document(struct fy_document_builder *fydb);
-
-bool
-fy_document_builder_is_in_stream(struct fy_document_builder *fydb);
-
-bool
-fy_document_builder_is_in_document(struct fy_document_builder *fydb);
-
-bool
-fy_document_builder_is_document_complete(struct fy_document_builder *fydb);
-
-struct fy_document *
-fy_document_builder_take_document(struct fy_document_builder *fydb);
-
-struct fy_document *
-fy_document_builder_peek_document(struct fy_document_builder *fydb);
-
-void
-fy_document_builder_set_in_stream(struct fy_document_builder *fydb);
-
-int
-fy_document_builder_set_in_document(struct fy_document_builder *fydb, struct fy_document_state *fyds, bool single);
-
-int
-fy_document_builder_process_event(struct fy_document_builder *fydb,
- struct fy_parser *fyp, struct fy_eventp *fyep);
-
-struct fy_document *
-fy_document_builder_load_document(struct fy_document_builder *fydb,
- struct fy_parser *fyp);
-
-struct fy_document *
-fy_parse_load_document_with_builder(struct fy_parser *fyp);
+struct fy_ptr_node *fy_ptr_node_create(struct fy_node *fyn);
+void fy_ptr_node_destroy(struct fy_ptr_node *fypn);
+void fy_ptr_node_list_free_all(struct fy_ptr_node_list *fypnl);
+bool fy_ptr_node_list_contains(struct fy_ptr_node_list *fypnl, struct fy_node *fyn);
+int fy_node_linearize_recursive(struct fy_ptr_node_list *fypnl, struct fy_node *fyn);
+int fy_node_linearize(struct fy_ptr_node_list *fypnl, struct fy_node *fyn);
+void fy_node_iterator_check(struct fy_node *fyn);
-enum fy_node_iterator_flags {
- FYNIF_DEPTH_FIRST = FY_BIT(0), /* depth first iterator (only one supported for now) */
- FYNIF_FOLLOW_KEYS = FY_BIT(1), /* follow any keys encountered */
- FYNIF_FOLLOW_LINKS = FY_BIT(2), /* follow any links/references encountered */
- FYNIF_ERASE_LINKS = FY_BIT(3), /* do not output any links encountered */
-};
-enum fy_node_iterator_result {
- FYNIR_OK, /* OK */
- FYNIR_ARGS, /* invalid arguments */
- FYNIR_NOMEM, /* out of memory */
- FYNIR_LOOP, /* loop detected */
- FYNIR_BAD_ALIAS, /* unresolvable alias */
+enum fy_document_iterator_state {
+ FYDIS_WAITING_STREAM_START,
+ FYDIS_WAITING_DOCUMENT_START,
+ FYDIS_WAITING_BODY_START_OR_DOCUMENT_END,
+ FYDIS_BODY,
+ FYDIS_WAITING_DOCUMENT_END,
+ FYDIS_WAITING_STREAM_END_OR_DOCUMENT_START,
+ FYDIS_ERROR,
};
-struct fy_node_iterator_state {
- struct fy_node *fyn;
+struct fy_document_iterator_body_state {
+ struct fy_node *fyn; /* the collection node */
+ bool processed_key : 1; /* for mapping only */
union {
- struct fy_node_pair *fynp; /* for map only */
- unsigned int idx; /* for sequence */
+ struct fy_node *fyni; /* for sequence */
+ struct fy_node_pair *fynp; /* for mapping */
};
};
-struct fy_node_iterator {
- enum fy_node_iterator_flags flags;
- enum fy_node_iterator_result result;
- unsigned int count;
- unsigned int alloc;
- struct fy_node_iterator_state *stack;
- struct fy_node_iterator_state in_place[FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT];
+struct fy_document_iterator {
+ enum fy_document_iterator_state state;
+ struct fy_document *fyd;
+ struct fy_node *iterate_root;
+ bool suppress_recycling_force : 1;
+ bool suppress_recycling : 1;
+
+ struct fy_eventp_list recycled_eventp;
+ struct fy_token_list recycled_token;
+
+ struct fy_eventp_list *recycled_eventp_list; /* NULL when suppressing */
+ struct fy_token_list *recycled_token_list; /* NULL when suppressing */
+
+ unsigned int stack_top;
+ unsigned int stack_alloc;
+ struct fy_document_iterator_body_state *stack;
+ struct fy_document_iterator_body_state in_place[FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT];
};
-void fy_node_iterator_setup(struct fy_node_iterator *fyi, enum fy_node_iterator_flags flags);
-void fy_node_iterator_cleanup(struct fy_node_iterator *fyi);
-struct fy_node_iterator *fy_node_iterator_create(enum fy_node_iterator_flags flags);
-void fy_node_iterator_destroy(struct fy_node_iterator *fyi);
-void fy_node_iterator_start(struct fy_node_iterator *fyi, struct fy_node *fyn);
-enum fy_node_iterator_result fy_node_iterator_end(struct fy_node_iterator *fyi);
-struct fy_node *fy_node_iterator_next(struct fy_node_iterator *fyi, struct fy_node *fyn);
-
-#define fy_node_get_path_a(_fyn) \
- ({ \
- char *__path_a, *__path; \
- __path = fy_node_get_path((_fyn)); \
- if (__path) { \
- __path_a = alloca(strlen(__path) + 1); \
- strcpy(__path_a, __path); \
- free(__path); \
- } else { \
- __path_a = alloca(1); \
- __path_a[0] = '\0'; \
- } \
- __path_a; \
- })
+void fy_document_iterator_setup(struct fy_document_iterator *fydi);
+void fy_document_iterator_cleanup(struct fy_document_iterator *fydi);
+struct fy_document_iterator *fy_document_iterator_create(void);
+void fy_document_iterator_destroy(struct fy_document_iterator *fydi);
+void fy_document_iterator_start(struct fy_document_iterator *fydi, struct fy_document *fyd);
+void fy_document_iterator_end(struct fy_document_iterator *fydi);
-/* indirect node */
-FY_TYPE_FWD_DECL_LIST(ptr_node);
-struct fy_ptr_node {
- struct list_head node;
+struct fy_document_iterator_body_result {
struct fy_node *fyn;
+ bool end;
};
-FY_TYPE_DECL_LIST(ptr_node);
-struct fy_ptr_node *fy_ptr_node_create(struct fy_node *fyn);
-void fy_ptr_node_destroy(struct fy_ptr_node *fypn);
-void fy_ptr_node_list_free_all(struct fy_ptr_node_list *fypnl);
-bool fy_ptr_node_list_contains(struct fy_ptr_node_list *fypnl, struct fy_node *fyn);
-int fy_node_linearize_recursive(struct fy_ptr_node_list *fypnl, struct fy_node *fyn);
-int fy_node_linearize(struct fy_ptr_node_list *fypnl, struct fy_node *fyn);
-void fy_node_iterator_check(struct fy_node *fyn);
+bool
+fy_document_iterator_body_next_internal(struct fy_document_iterator *fydi,
+ struct fy_document_iterator_body_result *res);
#endif
--- /dev/null
+/*
+ * fy-docbuilder.c - YAML document builder methods
+ *
+ * Copyright (c) 2022 Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <libfyaml.h>
+
+#include "fy-utils.h"
+
+#include "fy-docbuilder.h"
+
+#include "fy-parse.h"
+#include "fy-doc.h"
+
+const char *fy_document_builder_state_txt[] = {
+ [FYDBS_NODE] = "node",
+ [FYDBS_MAP_KEY] = "map-key",
+ [FYDBS_MAP_VAL] = "map-val",
+ [FYDBS_SEQ] = "seq",
+};
+
+void
+fy_document_builder_reset(struct fy_document_builder *fydb)
+{
+ struct fy_document_builder_ctx *c;
+ unsigned int i;
+
+ if (!fydb)
+ return;
+
+ for (i = 0, c = fydb->stack; i < fydb->next; i++, c++) {
+ fy_node_free(c->fyn);
+ c->fyn = NULL;
+ fy_node_pair_free(c->fynp);
+ c->fynp = NULL;
+ }
+ fydb->next = 0;
+
+ if (fydb->fyd) {
+ fy_document_destroy(fydb->fyd);
+ fydb->fyd = NULL;
+ }
+ fydb->in_stream = false;
+ fydb->doc_done = false;
+}
+
+static const struct fy_document_builder_cfg docbuilder_default_cfg = {
+ .parse_cfg = {
+ .flags = FYPCF_DEFAULT_DOC,
+ }
+};
+
+struct fy_document_builder *
+fy_document_builder_create(const struct fy_document_builder_cfg *cfg)
+{
+ struct fy_document_builder *fydb = NULL;
+
+ if (!cfg)
+ cfg = &docbuilder_default_cfg;
+
+ fydb = malloc(sizeof(*fydb));
+ if (!fydb)
+ goto err_out;
+
+ memset(fydb, 0, sizeof(*fydb));
+ fydb->cfg = *cfg;
+ fydb->next = 0;
+ fydb->in_stream = false;
+ fydb->doc_done = false;
+ fydb->alloc = fy_depth_limit(); /* always start with this */
+ fydb->max_depth = (cfg->parse_cfg.flags & FYPCF_DISABLE_DEPTH_LIMIT) ? 0 : fy_depth_limit();
+
+ fydb->stack = malloc(fydb->alloc * sizeof(*fydb->stack));
+ if (!fydb->stack)
+ goto err_out;
+
+ return fydb;
+
+err_out:
+ if (fydb) {
+ if (fydb->stack)
+ free(fydb->stack);
+ free(fydb);
+ }
+
+ return NULL;
+}
+
+void
+fy_document_builder_destroy(struct fy_document_builder *fydb)
+{
+ if (!fydb)
+ return;
+
+ fy_document_builder_reset(fydb);
+
+ fy_diag_unref(fydb->cfg.diag);
+ if (fydb->stack)
+ free(fydb->stack);
+ free(fydb);
+}
+
+struct fy_document *
+fy_document_builder_get_document(struct fy_document_builder *fydb)
+{
+ return fydb ? fydb->fyd : NULL;
+}
+
+bool
+fy_document_builder_is_in_stream(struct fy_document_builder *fydb)
+{
+ return fydb && fydb->in_stream;
+}
+
+bool
+fy_document_builder_is_in_document(struct fy_document_builder *fydb)
+{
+ return fydb && fydb->fyd != NULL && !fydb->doc_done;
+}
+
+bool
+fy_document_builder_is_document_complete(struct fy_document_builder *fydb)
+{
+ return fydb && fydb->fyd != NULL && fydb->doc_done;
+}
+
+struct fy_document *
+fy_document_builder_take_document(struct fy_document_builder *fydb)
+{
+ struct fy_document *fyd;
+
+ if (!fy_document_builder_is_document_complete(fydb))
+ return NULL;
+ fyd = fydb->fyd;
+ fydb->fyd = NULL;
+ fydb->doc_done = false;
+ return fyd;
+}
+
+struct fy_document *
+fy_document_builder_peek_document(struct fy_document_builder *fydb)
+{
+ struct fy_document *fyd;
+ struct fy_document_builder_ctx *c;
+
+ if (!fydb)
+ return NULL;
+
+ /* just peek; may be incomplete */
+ fyd = fydb->fyd;
+
+ assert(fydb->next > 0);
+ c = &fydb->stack[0];
+
+ /* wire the root */
+ if (!fyd->root)
+ fyd->root = c->fyn;
+
+ return fyd;
+}
+
+
+void
+fy_document_builder_set_in_stream(struct fy_document_builder *fydb)
+{
+ if (!fydb)
+ return;
+ /* reset */
+ fy_document_builder_reset(fydb);
+
+ fydb->in_stream = true;
+}
+
+int
+fy_document_builder_set_in_document(struct fy_document_builder *fydb, struct fy_document_state *fyds, bool single)
+{
+ struct fy_document_builder_ctx *c;
+ int rc;
+
+ if (!fydb)
+ return -1;
+
+ /* reset */
+ fy_document_builder_reset(fydb);
+
+ fydb->in_stream = true;
+
+ fydb->fyd = fy_document_create(&fydb->cfg.parse_cfg);
+ if (!fydb->fyd)
+ return -1;
+
+ if (fyds) {
+ rc = fy_document_set_document_state(fydb->fyd, fyds);
+ if (rc)
+ return rc;
+ }
+
+ fydb->doc_done = false;
+ fydb->single_mode = single;
+
+ /* be paranoid */
+ assert(fydb->next < fydb->alloc);
+
+ c = &fydb->stack[++fydb->next - 1];
+ memset(c, 0, sizeof(*c));
+ c->s = FYDBS_NODE;
+
+ return 0;
+}
+
+int
+fy_document_builder_process_event(struct fy_document_builder *fydb, struct fy_eventp *fyep)
+{
+ struct fy_event *fye;
+ enum fy_event_type etype;
+ struct fy_document *fyd;
+ struct fy_document_builder_ctx *c, *cp;
+ struct fy_node *fyn, *fyn_parent;
+ struct fy_node_pair *fynp;
+ struct fy_document_builder_ctx *newc;
+ struct fy_token *fyt;
+ int rc;
+
+ fye = fyep ? &fyep->e : NULL;
+ etype = fye ? fye->type : FYET_NONE;
+ fyt = fye ? fy_event_get_token(fye) : NULL;
+
+ /* not in document */
+ if (!fydb->next) {
+ switch (etype) {
+ case FYET_STREAM_START:
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC,
+ !fydb->in_stream, err_out,
+ "STREAM_START while in stream error");
+ fydb->in_stream = true;
+ break;
+
+ case FYET_STREAM_END:
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC,
+ fydb->in_stream, err_out,
+ "STREAM_END while not in stream error");
+ fydb->in_stream = false;
+ return 1;
+
+ case FYET_DOCUMENT_START:
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC,
+ fydb->in_stream, err_out,
+ "DOCUMENT_START while not in stream error");
+
+ /* no-one cares, destroy the document */
+ if (!fydb->fyd)
+ fy_document_destroy(fydb->fyd);
+
+ fydb->fyd = fy_document_create(&fydb->cfg.parse_cfg);
+ fydb_error_check(fydb, fydb->fyd, err_out,
+ "fy_document_create() failed");
+
+ rc = fy_document_set_document_state(fydb->fyd, fyep->e.document_start.document_state);
+ fydb_error_check(fydb, !rc, err_out,
+ "fy_document_set_document_state() failed");
+
+ fydb->doc_done = false;
+ goto push;
+
+ case FYET_DOCUMENT_END:
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC,
+ fydb->in_stream, err_out,
+ "DOCUMENT_END while not in stream error");
+
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC,
+ fydb->fyd, err_out,
+ "DOCUMENT_END without a document");
+
+ fydb->doc_done = true;
+ break;
+
+ default:
+ /* unexpected event */
+ FYDB_TOKEN_ERROR(fydb, fyt, FYEM_DOC,
+ "Unexpected event %s in non-build mode\n",
+ fy_event_type_txt[etype]);
+ goto err_out;
+ }
+
+ return 0;
+ }
+
+ fyd = fydb->fyd;
+
+ c = &fydb->stack[fydb->next - 1];
+ fyn = NULL;
+
+ /* verify that we have a document */
+ assert(fydb->fyd);
+ /* the top state must always be NODE for processing the event */
+ assert(c->s == FYDBS_NODE);
+
+ switch (etype) {
+ case FYET_SCALAR:
+ case FYET_ALIAS:
+ fyn = fy_node_alloc(fyd, FYNT_SCALAR);
+ fydb_error_check(fydb, fyn, err_out,
+ "fy_node_alloc() SCALAR failed");
+
+ if (etype == FYET_SCALAR) {
+ if (fye->scalar.value)
+ fyn->style = fy_node_style_from_scalar_style(fye->scalar.value->scalar.style);
+ else
+ fyn->style = FYNS_PLAIN;
+ fyn->tag = fy_token_ref(fye->scalar.tag);
+ if (fye->scalar.anchor) {
+ rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(fye->scalar.anchor));
+ fydb_error_check(fydb, !rc, err_out,
+ "fy_document_register_anchor() failed");
+ }
+ fyn->scalar = fy_token_ref(fye->scalar.value);
+ } else {
+ fyn->style = FYNS_ALIAS;
+ fyn->scalar = fy_token_ref(fye->alias.anchor);
+ }
+ goto complete;
+
+ case FYET_MAPPING_START:
+ c->s = FYDBS_MAP_KEY;
+
+ fyn = fy_node_alloc(fyd, FYNT_MAPPING);
+ fydb_error_check(fydb, fyn, err_out,
+ "fy_node_alloc() MAPPING failed");
+
+ c->fyn = fyn;
+ fyn->style = fye->mapping_start.mapping_start->type == FYTT_FLOW_MAPPING_START ? FYNS_FLOW : FYNS_BLOCK;
+ fyn->tag = fy_token_ref(fye->mapping_start.tag);
+ if (fye->mapping_start.anchor) {
+ rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(fye->mapping_start.anchor));
+ fydb_error_check(fydb, !rc, err_out,
+ "fy_document_register_anchor() failed");
+ }
+ fyn->mapping_start = fy_token_ref(fye->mapping_start.mapping_start);
+ break;
+
+ case FYET_MAPPING_END:
+
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC, fydb->next > 1, err_out,
+ "Unexpected MAPPING_END (unexpected end of mapping)");
+
+ cp = &fydb->stack[fydb->next - 2];
+
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC, cp->s == FYDBS_MAP_KEY, err_out,
+ "Unexpected MAPPING_END (not in mapping)");
+
+ fyn = cp->fyn;
+ fyn->mapping_end = fy_token_ref(fye->mapping_end.mapping_end);
+ fydb->next--;
+ goto complete;
+
+ case FYET_SEQUENCE_START:
+ c->s = FYDBS_SEQ;
+ fyn = fy_node_alloc(fyd, FYNT_SEQUENCE);
+ fydb_error_check(fydb, fyn, err_out,
+ "fy_node_alloc() SEQUENCE failed");
+
+ c->fyn = fyn;
+ fyn->style = fye->sequence_start.sequence_start->type == FYTT_FLOW_SEQUENCE_START ? FYNS_FLOW : FYNS_BLOCK;
+ fyn->tag = fy_token_ref(fye->sequence_start.tag);
+ if (fye->sequence_start.anchor) {
+ rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(fye->sequence_start.anchor));
+ fydb_error_check(fydb, !rc, err_out,
+ "fy_document_register_anchor() failed");
+ }
+ fyn->sequence_start = fy_token_ref(fye->sequence_start.sequence_start);
+ break;
+
+ case FYET_SEQUENCE_END:
+
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC, fydb->next > 1, err_out,
+ "Unexpected SEQUENCE_END (unexpected end of sequence)");
+
+ cp = &fydb->stack[fydb->next - 2];
+
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC, cp->s == FYDBS_SEQ, err_out,
+ "Unexpected MAPPING_SEQUENCE (not in sequence)");
+
+ fyn = cp->fyn;
+ fyn->sequence_end = fy_token_ref(fye->sequence_end.sequence_end);
+ fydb->next--;
+ goto complete;
+
+ default:
+ /* unexpected event */
+ FYDB_TOKEN_ERROR(fydb, fyt, FYEM_DOC,
+ "Unexpected event %s in build mode\n",
+ fy_event_type_txt[etype]);
+ goto err_out;
+ }
+
+push:
+ FYDB_TOKEN_ERROR_CHECK(fydb, fyt, FYEM_DOC,
+ !fydb->max_depth || fydb->next < fydb->max_depth, err_out,
+ "Max depth (%d) exceeded\n", fydb->next);
+
+ /* grow the stack? */
+ if (fydb->next >= fydb->alloc) {
+ newc = realloc(fydb->stack, fydb->alloc * 2 * sizeof(*fydb->stack));
+ fydb_error_check(fydb, newc, err_out,
+ "Unable to grow the context stack");
+ fydb->alloc *= 2;
+ fydb->stack = newc;
+ }
+ assert(fydb->next < fydb->alloc);
+
+ c = &fydb->stack[++fydb->next - 1];
+ memset(c, 0, sizeof(*c));
+ c->s = FYDBS_NODE;
+ return 0;
+
+err_out:
+ return -1;
+
+complete:
+ assert(fydb->next > 0);
+ c = &fydb->stack[fydb->next - 1];
+ c->fyn = fyn;
+ assert(fydb->next > 0);
+ fydb->next--;
+
+ /* root */
+ if (fydb->next == 0) {
+ fyd->root = fyn;
+ /* if we're in single mode, don't wait for doc end */
+ if (fydb->single_mode)
+ fydb->doc_done = true;
+ return 1;
+ }
+
+ c = &fydb->stack[fydb->next - 1];
+
+ fyn_parent = c->fyn;
+
+ switch (c->s) {
+
+ case FYDBS_MAP_KEY:
+ fynp = fy_node_pair_alloc(fyd);
+ assert(fynp);
+ fynp->key = fyn;
+ c->fynp = fynp;
+
+ /* if we don't allow duplicate keys */
+ if (!(fyd->parse_cfg.flags & FYPCF_ALLOW_DUPLICATE_KEYS)) {
+
+ /* make sure we don't add an already existing key */
+ if (fy_node_mapping_key_is_duplicate(fyn_parent, fyn)) {
+ FYDB_NODE_ERROR(fydb, fyn, FYEM_DOC, "duplicate key");
+ goto err_out;
+ }
+ }
+
+ c->s = FYDBS_MAP_VAL;
+ goto push;
+
+ case FYDBS_MAP_VAL:
+ fynp = c->fynp;
+ assert(fynp);
+ fynp->value = fyn;
+
+ /* set the parent of the node pair and value */
+ fynp->parent = fyn_parent;
+ if (fynp->key) {
+ fynp->key->parent = fyn_parent;
+ fynp->key->key_root = true;
+ }
+ if (fynp->value)
+ fynp->value->parent = fyn_parent;
+
+ fy_node_pair_list_add_tail(&c->fyn->mapping, fynp);
+ if (fyn->xl) {
+ rc = fy_accel_insert(fyn->xl, fynp->key, fynp);
+ assert(!rc);
+ }
+ if (fynp->key)
+ fynp->key->attached = true;
+ if (fynp->value)
+ fynp->value->attached = true;
+
+ c->fynp = NULL;
+ c->s = FYDBS_MAP_KEY;
+ goto push;
+
+ case FYDBS_SEQ:
+ /* append sequence */
+ fyn->parent = fyn_parent;
+ fy_node_list_add_tail(&c->fyn->sequence, fyn);
+ fyn->attached = true;
+ goto push;
+
+ case FYDBS_NODE:
+ /* complete is a scalar */
+ fyn->parent = fyn_parent;
+ return 0;
+ }
+
+ return 0;
+}
+
+struct fy_document *
+fy_document_builder_load_document(struct fy_document_builder *fydb,
+ struct fy_parser *fyp)
+{
+ struct fy_eventp *fyep = NULL;
+ int rc;
+
+ if (fyp->state == FYPS_END)
+ return NULL;
+
+ while (!fy_document_builder_is_document_complete(fydb) &&
+ (fyep = fy_parse_private(fyp)) != NULL) {
+ rc = fy_document_builder_process_event(fydb, fyep);
+ fy_parse_eventp_recycle(fyp, fyep);
+ if (rc < 0) {
+ fyp->stream_error = true;
+ return NULL;
+ }
+ }
+
+ /* get ownership of the document */
+ return fy_document_builder_take_document(fydb);
+}
--- /dev/null
+/*
+ * fy-docbuilder.h - YAML document builder internal header file
+ *
+ * Copyright (c) 2022 Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+#ifndef FY_DOCBUILDER_H
+#define FY_DOCBUILDER_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libfyaml.h>
+
+#include "fy-doc.h"
+
+enum fy_document_builder_state {
+ FYDBS_NODE,
+ FYDBS_MAP_KEY,
+ FYDBS_MAP_VAL,
+ FYDBS_SEQ,
+};
+
+struct fy_document_builder_ctx {
+ enum fy_document_builder_state s;
+ struct fy_node *fyn;
+ struct fy_node_pair *fynp; /* for mapping */
+};
+
+struct fy_document_builder_cfg {
+ struct fy_parse_cfg parse_cfg;
+ void *userdata;
+ struct fy_diag *diag;
+};
+
+struct fy_document_builder {
+ struct fy_document_builder_cfg cfg;
+ struct fy_document *fyd;
+ bool single_mode;
+ bool in_stream;
+ bool doc_done;
+ unsigned int next;
+ unsigned int alloc;
+ unsigned int max_depth;
+ struct fy_document_builder_ctx *stack;
+};
+
+struct fy_document_builder *
+fy_document_builder_create(const struct fy_document_builder_cfg *cfg);
+
+void
+fy_document_builder_reset(struct fy_document_builder *fydb);
+
+void
+fy_document_builder_destroy(struct fy_document_builder *fydb);
+
+struct fy_document *
+fy_document_builder_get_document(struct fy_document_builder *fydb);
+
+bool
+fy_document_builder_is_in_stream(struct fy_document_builder *fydb);
+
+bool
+fy_document_builder_is_in_document(struct fy_document_builder *fydb);
+
+bool
+fy_document_builder_is_document_complete(struct fy_document_builder *fydb);
+
+struct fy_document *
+fy_document_builder_take_document(struct fy_document_builder *fydb);
+
+struct fy_document *
+fy_document_builder_peek_document(struct fy_document_builder *fydb);
+
+void
+fy_document_builder_set_in_stream(struct fy_document_builder *fydb);
+
+int
+fy_document_builder_set_in_document(struct fy_document_builder *fydb, struct fy_document_state *fyds, bool single);
+
+int
+fy_document_builder_process_event(struct fy_document_builder *fydb, struct fy_eventp *fyep);
+
+struct fy_document *
+fy_document_builder_load_document(struct fy_document_builder *fydb,
+ struct fy_parser *fyp);
+
+struct fy_document *
+fy_parse_load_document_with_builder(struct fy_parser *fyp);
+
+#endif
fyds->tags_explicit = false;
fyds->start_implicit = true;
fyds->end_implicit = true;
+ fyds->json_mode = false;
memset(&fyds->start_mark, 0, sizeof(fyds->start_mark));
memset(&fyds->end_mark, 0, sizeof(fyds->end_mark));
fyds_new->tags_explicit = fyds->tags_explicit;
fyds_new->start_implicit = fyds->start_implicit;
fyds_new->end_implicit = fyds->end_implicit;
+ fyds_new->json_mode = fyds->json_mode;
fyds_new->start_mark = fyds->start_mark;
fyds_new->end_mark = fyds->end_mark;
fyt_td->tag_directive.uri_length = fyt->tag_directive.uri_length;
fyt_td->tag_directive.is_default = fyt->tag_directive.is_default;
fyt_td->handle = fyt->handle;
+ fyt_td->tag_directive.prefix0 = NULL;
+ fyt_td->tag_directive.handle0 = NULL;
/* take reference */
fy_input_ref(fyt_td->handle.fyi);
/* merge other document state */
fyds->version_explicit |= fydsc->version_explicit;
fyds->tags_explicit |= fydsc->tags_explicit;
+ /* NOTE: json mode is not carried over */
if (fyds->version.major < fydsc->version.major ||
(fyds->version.major == fydsc->version.major &&
return fyds ? fyds->end_implicit : true;
}
+bool fy_document_state_json_mode(struct fy_document_state *fyds)
+{
+ return fyds ? fyds->json_mode : true;
+}
+
const struct fy_tag *
fy_document_state_tag_directive_iterate(struct fy_document_state *fyds, void **iterp)
{
bool tags_explicit : 1;
bool start_implicit : 1;
bool end_implicit : 1;
+ bool json_mode : 1;
struct fy_mark start_mark;
struct fy_mark end_mark;
struct fy_token *fyt_vd; /* version directive */
#include <limits.h>
#include <unistd.h>
#include <ctype.h>
+#include <errno.h>
#include <libfyaml.h>
static inline bool fy_emit_is_json_mode(const struct fy_emitter *emit)
{
- enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK);
+ enum fy_emitter_cfg_flags flags;
+
+ if (emit->force_json)
+ return true;
+ flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK);
return flags == FYECF_MODE_JSON || flags == FYECF_MODE_JSON_TP || flags == FYECF_MODE_JSON_ONELINE;
}
{
enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK);
- return flags == FYECF_MODE_BLOCK || flags == FYECF_MODE_DEJSON;
+ return flags == FYECF_MODE_BLOCK || flags == FYECF_MODE_DEJSON || flags == FYECF_MODE_PRETTY;
}
static inline bool fy_emit_is_oneline(const struct fy_emitter *emit)
return flags == FYECF_MODE_FLOW_ONELINE || flags == FYECF_MODE_JSON_ONELINE;
}
-static inline bool fy_emit_is_pretty_mode(const struct fy_emitter *emit)
+static inline bool fy_emit_is_dejson_mode(const struct fy_emitter *emit)
{
enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK);
return flags == FYECF_MODE_DEJSON;
}
+static inline bool fy_emit_is_pretty_mode(const struct fy_emitter *emit)
+{
+ enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK);
+
+ return flags == FYECF_MODE_PRETTY;
+}
+
static inline int fy_emit_indent(struct fy_emitter *emit)
{
int indent;
if (!fyn)
return 0;
- if (fy_emit_is_json_mode(emit)) {
+ if (fy_emit_is_json_mode(emit) && !emit->source_json) {
ret = fy_emit_node_check_json(emit, fyn);
if (ret)
return ret;
return handle && fy_atom_is_set(handle) ? handle : NULL;
}
+void fy_emit_document_start_indicator(struct fy_emitter *emit)
+{
+ /* do not emit twice */
+ if (emit->flags & FYEF_HAD_DOCUMENT_START)
+ return;
+
+ /* do not try to emit if it's json mode */
+ if (fy_emit_is_json_mode(emit))
+ goto no_doc_emit;
+
+ /* output linebreak anyway */
+ if (emit->column)
+ fy_emit_putc(emit, fyewt_linebreak, '\n');
+
+ /* stripping doc indicators, do not emit */
+ if (emit->cfg.flags & FYECF_STRIP_DOC)
+ goto no_doc_emit;
+
+ /* ok, emit document start indicator */
+ fy_emit_puts(emit, fyewt_document_indicator, "---");
+ emit->flags &= ~FYEF_WHITESPACE;
+ emit->flags |= FYEF_HAD_DOCUMENT_START;
+ return;
+
+no_doc_emit:
+ emit->flags &= ~FYEF_HAD_DOCUMENT_START;
+}
+
struct fy_token *fy_node_value_token(struct fy_node *fyn)
{
struct fy_token *fyt;
switch (type) {
case FYNT_SCALAR:
+ /* if we're pretty and root at column 0 (meaning it's a single scalar document) output --- */
+ if ((flags & DDNF_ROOT) && fy_emit_is_pretty_mode(emit) && !emit->column &&
+ !fy_emit_is_flow_mode(emit) && !(flags & DDNF_FLOW))
+ fy_emit_document_start_indicator(emit);
fy_emit_scalar(emit, fyn, flags, indent, is_key);
break;
case FYNT_SEQUENCE:
if (json && (style == FYNS_LITERAL || style == FYNS_FOLDED))
return FYNS_DOUBLE_QUOTED;
- is_json_plain = false;
-
/* is this a plain json atom? */
- is_json_plain = (json || fy_emit_is_pretty_mode(emit)) &&
+ is_json_plain = (json || emit->source_json || fy_emit_is_dejson_mode(emit)) &&
(!atom || atom->size0 ||
!fy_atom_strcmp(atom, "false") ||
!fy_atom_strcmp(atom, "true") ||
}
/* JSON NULL, but with plain style */
- if (json && (!atom || atom->size0) && style == FYNS_PLAIN)
- return FYNS_PLAIN;
-
- if (json && style == FYNS_PLAIN && is_json_plain)
+ if (json && (style == FYNS_PLAIN || style == FYNS_ANY) && (!atom || (is_json_plain && !atom->size0)))
return FYNS_PLAIN;
if (json)
style = !(aflags & FYTTAF_EMPTY) ? FYNS_PLAIN : FYNS_DOUBLE_QUOTED;
}
+ /* try to pretify */
if (!flow && fy_emit_is_pretty_mode(emit) &&
(style == FYNS_ANY || style == FYNS_DOUBLE_QUOTED || style == FYNS_SINGLE_QUOTED)) {
- if ((aflags & FYTTAF_CAN_BE_PLAIN) && (style != FYNS_DOUBLE_QUOTED || !is_json_plain))
+ /* any original style can be a plain, but contains linebreaks, do a literal */
+ if ((aflags & (FYTTAF_CAN_BE_PLAIN | FYTTAF_HAS_LB)) == (FYTTAF_CAN_BE_PLAIN | FYTTAF_HAS_LB)) {
+ style = FYNS_LITERAL;
+ goto out;
+ }
+
+ /* any style, can be just a plain, just make it so */
+ if (style == FYNS_ANY && (aflags & (FYTTAF_CAN_BE_PLAIN | FYTTAF_HAS_LB)) == FYTTAF_CAN_BE_PLAIN) {
+ style = FYNS_PLAIN;
+ goto out;
+ }
+
+ }
+
+ if (!flow && emit->source_json && fy_emit_is_dejson_mode(emit)) {
+ if (is_json_plain || (aflags & (FYTTAF_CAN_BE_PLAIN | FYTTAF_HAS_LB)) == FYTTAF_CAN_BE_PLAIN) {
style = FYNS_PLAIN;
+ goto out;
+ }
}
out:
{
bool json = fy_emit_is_json_mode(emit);
bool oneline = fy_emit_is_oneline(emit);
+ bool was_flow = sc->flow;
sc->old_indent = sc->indent;
if (!json) {
fy_emit_write_indicator(emit, di_left_bracket, sc->flags, sc->indent, fyewt_indicator);
}
- if (!oneline)
- sc->indent = fy_emit_increase_indent(emit, sc->flags, sc->indent);
+ if (!oneline) {
+ if (was_flow || (sc->flags & (DDNF_ROOT | DDNF_SEQ)))
+ sc->indent = fy_emit_increase_indent(emit, sc->flags, sc->indent);
+ }
sc->flags &= ~DDNF_ROOT;
}
fyt_value = fy_node_value_token(fyni);
fy_emit_sequence_item_prolog(emit, sc, fyt_value);
- fy_emit_node_internal(emit, fyni, sc->flags, sc->indent, false);
+ fy_emit_node_internal(emit, fyni, (sc->flags & ~DDNF_ROOT), sc->indent, false);
fy_emit_sequence_item_epilog(emit, sc, last, fyt_value);
}
{
struct fy_node_pair *fynp, *fynpn, **fynpp = NULL;
struct fy_token *fyt_key, *fyt_value;
- bool last, simple_key;
- int aflags, i;
+ bool last, simple_key, used_malloc = false;
+ int aflags, i, count;
struct fy_emit_save_ctx sct, *sc = &sct;
memset(sc, 0, sizeof(*sc));
fy_emit_mapping_prolog(emit, sc);
- if (!(emit->cfg.flags & FYECF_SORT_KEYS)) {
+ if (!(emit->cfg.flags & (FYECF_SORT_KEYS | FYECF_STRIP_EMPTY_KV))) {
fynp = fy_node_pair_list_head(&fyn->mapping);
fynpp = NULL;
} else {
- fynpp = fy_node_mapping_sort_array(fyn, NULL, NULL, NULL);
+ count = fy_node_mapping_item_count(fyn);
+
+ /* heuristic, avoid allocation for small maps */
+ if (count > 64) {
+ fynpp = malloc((count + 1) * sizeof(*fynpp));
+ fyd_error_check(fyn->fyd, fynpp, err_out,
+ "malloc() failed");
+ used_malloc = true;
+ } else
+ fynpp = alloca((count + 1) * sizeof(*fynpp));
+
+ /* fill (removing empty KVs) */
+ i = 0;
+ for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp;
+ fynp = fy_node_pair_next(&fyn->mapping, fynp)) {
+
+ /* strip key/value pair from the output if it's empty */
+ if ((emit->cfg.flags & FYECF_STRIP_EMPTY_KV) && fy_node_is_empty(fynp->value))
+ continue;
+
+ fynpp[i++] = fynp;
+ }
+ count = i;
+ fynpp[count] = NULL;
+
+ /* sort the keys */
+ if (emit->cfg.flags & FYECF_SORT_KEYS)
+ fy_node_mapping_perform_sort(fyn, NULL, NULL, fynpp, count);
+
i = 0;
fynp = fynpp[i];
}
fy_emit_mapping_key_prolog(emit, sc, fyt_key, simple_key);
if (fynp->key)
- fy_emit_node_internal(emit, fynp->key, sc->flags, sc->indent, true);
+ fy_emit_node_internal(emit, fynp->key, (sc->flags & ~DDNF_ROOT), sc->indent, true);
fy_emit_mapping_key_epilog(emit, sc, fyt_key);
fy_emit_mapping_value_prolog(emit, sc, fyt_value);
if (fynp->value)
- fy_emit_node_internal(emit, fynp->value, sc->flags, sc->indent, false);
+ fy_emit_node_internal(emit, fynp->value, (sc->flags & ~DDNF_ROOT), sc->indent, false);
fy_emit_mapping_value_epilog(emit, sc, last, fyt_value);
}
- if (fynpp)
- fy_node_mapping_sort_release_array(fyn, fynpp);
+ if (fynpp && used_malloc)
+ free(fynpp);
fy_emit_mapping_epilog(emit, sc);
!(emit->flags & FYEF_HAD_DOCUMENT_END))
dsm = true;
- if (!fy_emit_is_json_mode(emit) && dsm) {
- if (emit->column)
- fy_emit_putc(emit, fyewt_linebreak, '\n');
- if (!(emit->cfg.flags & FYECF_STRIP_DOC)) {
- fy_emit_puts(emit, fyewt_document_indicator, "---");
- emit->flags &= ~FYEF_WHITESPACE;
- emit->flags |= FYEF_HAD_DOCUMENT_START;
- }
- } else
- emit->flags &= ~FYEF_HAD_DOCUMENT_START;
+ /* output document start indicator if we should */
+ if (dsm)
+ fy_emit_document_start_indicator(emit);
/* clear that in any case */
emit->flags &= ~FYEF_HAD_DOCUMENT_END;
return 0;
}
-int fy_emit_common_document_end(struct fy_emitter *emit)
+int fy_emit_common_document_end(struct fy_emitter *emit, bool override_state, bool implicit_override)
{
const struct fy_document_state *fyds;
enum fy_emitter_cfg_flags flags = emit->cfg.flags;
enum fy_emitter_cfg_flags dem_flags = flags & FYECF_DOC_END_MARK(FYECF_DOC_END_MARK_MASK);
- bool dem;
+ bool implicit, dem;
if (!emit || !emit->fyds)
return -1;
fyds = emit->fyds;
- dem = ((dem_flags == FYECF_DOC_END_MARK_AUTO && !fyds->end_implicit) ||
+ implicit = fyds->end_implicit;
+ if (override_state)
+ implicit = implicit_override;
+
+ dem = ((dem_flags == FYECF_DOC_END_MARK_AUTO && !implicit) ||
dem_flags == FYECF_DOC_END_MARK_ON) &&
!(emit->cfg.flags & FYECF_STRIP_DOC);
{
int ret;
- ret = fy_emit_common_document_end(emit);
+ ret = fy_emit_common_document_end(emit, false, false);
if (ret)
return ret;
fy_eventp_list_init(&emit->recycled_eventp);
fy_token_list_init(&emit->recycled_token);
+ /* suppress recycling if we must */
+ emit->suppress_recycling_force = getenv("FY_VALGRIND") && !getenv("FY_VALGRIND_RECYCLING");
+ emit->suppress_recycling = emit->suppress_recycling_force;
+
+ if (!emit->suppress_recycling) {
+ emit->recycled_eventp_list = &emit->recycled_eventp;
+ emit->recycled_token_list = &emit->recycled_token;
+ } else {
+ emit->recycled_eventp_list = NULL;
+ emit->recycled_token_list = NULL;
+ }
+
fy_emit_reset(emit, false);
return 0;
struct fy_eventp *fyep;
struct fy_token *fyt;
+ /* call the finalizer if it exists */
+ if (emit->finalizer)
+ emit->finalizer(emit);
+
while ((fyt = fy_token_list_pop(&emit->recycled_token)) != NULL)
fy_token_free(fyt);
- fy_emit_eventp_vacuum(emit);
+ while ((fyep = fy_eventp_list_pop(&emit->recycled_eventp)) != NULL)
+ fy_eventp_free(fyep);
if (!emit->fyd && emit->fyds)
fy_document_state_unref(emit->fyds);
fy_diag_unref(emit->diag);
}
+int fy_emit_node_no_check(struct fy_emitter *emit, struct fy_node *fyn)
+{
+ if (fyn)
+ fy_emit_node_internal(emit, fyn, DDNF_ROOT, -1, false);
+ return 0;
+}
+
int fy_emit_node(struct fy_emitter *emit, struct fy_node *fyn)
{
int ret;
if (ret)
return ret;
- if (fyn)
- fy_emit_node_internal(emit, fyn, DDNF_ROOT, -1, false);
- return 0;
+ return fy_emit_node_no_check(emit, fyn);
}
-int fy_emit_root_node(struct fy_emitter *emit, struct fy_node *fyn)
+int fy_emit_root_node_no_check(struct fy_emitter *emit, struct fy_node *fyn)
{
- int ret;
-
if (!emit || !fyn)
return -1;
- ret = fy_emit_node_check(emit, fyn);
- if (ret)
- return ret;
-
/* top comment first */
fy_emit_node_comment(emit, fyn, DDNF_ROOT, -1, fycp_top);
return 0;
}
-int fy_emit_document(struct fy_emitter *emit, struct fy_document *fyd)
+int fy_emit_root_node(struct fy_emitter *emit, struct fy_node *fyn)
+{
+ int ret;
+
+ if (!emit || !fyn)
+ return -1;
+
+ ret = fy_emit_node_check(emit, fyn);
+ if (ret)
+ return ret;
+
+ return fy_emit_root_node_no_check(emit, fyn);
+}
+
+void fy_emit_prepare_document_state(struct fy_emitter *emit, struct fy_document_state *fyds)
+{
+ if (!emit || !fyds)
+ return;
+
+ /* if the original document was JSON and the mode is ORIGINAL turn on JSON mode */
+ emit->source_json = fyds && fyds->json_mode;
+ emit->force_json = (emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK)) == FYECF_MODE_ORIGINAL &&
+ emit->source_json;
+}
+
+int fy_emit_document_no_check(struct fy_emitter *emit, struct fy_document *fyd)
{
int rc;
if (rc)
return rc;
- rc = fy_emit_root_node(emit, fyd->root);
+ rc = fy_emit_root_node_no_check(emit, fyd->root);
if (rc)
return rc;
return rc;
}
+int fy_emit_document(struct fy_emitter *emit, struct fy_document *fyd)
+{
+ int ret;
+
+ if (!emit)
+ return -1;
+
+ if (fyd) {
+ fy_emit_prepare_document_state(emit, fyd->fyds);
+
+ if (fyd->root) {
+ ret = fy_emit_node_check(emit, fyd->root);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return fy_emit_document_no_check(emit, fyd);
+}
+
struct fy_emitter *fy_emitter_create(const struct fy_emitter_cfg *cfg)
{
struct fy_emitter *emit;
return 0;
}
+void fy_emitter_set_finalizer(struct fy_emitter *emit,
+ void (*finalizer)(struct fy_emitter *emit))
+{
+ if (!emit)
+ return;
+ emit->finalizer = finalizer;
+}
+
struct fy_emit_buffer_state {
+ char **bufp;
+ size_t *sizep;
char *buf;
- int size;
- int pos;
- int need;
- bool grow;
+ size_t size;
+ size_t pos;
+ size_t need;
+ bool allocate_buffer;
};
-static int do_buffer_output(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int len, void *userdata)
+static int do_buffer_output(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int leni, void *userdata)
{
struct fy_emit_buffer_state *state = emit->cfg.userdata;
- int left;
- int pagesize = 0;
- int size;
+ size_t left, pagesize, size, len;
char *bufnew;
+ /* convert to unsigned and use that */
+ len = (size_t)leni;
+
+ /* no funky business */
+ if (len < 0)
+ return -1;
+
state->need += len;
left = state->size - state->pos;
if (left < len) {
- if (!state->grow)
+ if (!state->allocate_buffer)
return 0;
pagesize = sysconf(_SC_PAGESIZE);
return len;
}
-static int fy_emit_str_internal(struct fy_document *fyd,
- enum fy_emitter_cfg_flags flags,
- struct fy_node *fyn, char **bufp, int *sizep,
- bool grow)
+static void
+fy_emitter_str_finalizer(struct fy_emitter *emit)
{
- struct fy_emitter emit_state, *emit = &emit_state;
+ struct fy_emit_buffer_state *state;
+
+ if (!emit || !(state = emit->cfg.userdata))
+ return;
+
+ /* if the buffer is allowed to allocate_buffer... */
+ if (state->allocate_buffer && state->buf)
+ free(state->buf);
+ free(state);
+
+ emit->cfg.userdata = NULL;
+}
+
+static struct fy_emitter *
+fy_emitter_create_str_internal(enum fy_emitter_cfg_flags flags, char **bufp, size_t *sizep, bool allocate_buffer)
+{
+ struct fy_emitter *emit;
struct fy_emitter_cfg emit_cfg;
- struct fy_emit_buffer_state state;
- int rc = -1;
+ struct fy_emit_buffer_state *state;
- memset(&emit_cfg, 0, sizeof(emit_cfg));
- memset(&state, 0, sizeof(state));
+ state = malloc(sizeof(*state));
+ if (!state)
+ return NULL;
+
+ /* if any of these NULL, it's a allocation case */
+ if ((!bufp || !sizep) && !allocate_buffer)
+ return NULL;
+
+ if (bufp && sizep) {
+ state->bufp = bufp;
+ state->buf = *bufp;
+ state->sizep = sizep;
+ state->size = *sizep;
+ } else {
+ state->bufp = NULL;
+ state->buf = NULL;
+ state->sizep = NULL;
+ state->size = 0;
+ }
+ state->pos = 0;
+ state->need = 0;
+ state->allocate_buffer = allocate_buffer;
+ memset(&emit_cfg, 0, sizeof(emit_cfg));
emit_cfg.output = do_buffer_output;
- emit_cfg.userdata = &state;
+ emit_cfg.userdata = state;
emit_cfg.flags = flags;
- state.buf = *bufp;
- state.size = *sizep;
- state.grow = grow;
- fy_emit_setup(emit, &emit_cfg);
- rc = fyd ? fy_emit_document(emit, fyd) : fy_emit_node(emit, fyn);
- fy_emit_cleanup(emit);
+ emit = fy_emitter_create(&emit_cfg);
+ if (!emit)
+ goto err_out;
- if (rc)
- goto out_err;
+ /* set finalizer to cleanup */
+ fy_emitter_set_finalizer(emit, fy_emitter_str_finalizer);
- /* terminating zero */
- rc = do_buffer_output(emit, fyewt_terminating_zero, "\0", 1, emit->cfg.userdata);
+ return emit;
- if (rc != 1) {
- rc = -1;
- goto out_err;
- }
+err_out:
+ if (state)
+ free(state);
+ return NULL;
+}
+
+static int
+fy_emitter_collect_str_internal(struct fy_emitter *emit, char **bufp, size_t *sizep)
+{
+ struct fy_emit_buffer_state *state;
+ char *buf;
+ int rc;
- *sizep = state.need;
+ state = emit->cfg.userdata;
+ assert(state);
- if (!grow)
- return 0;
+ /* if NULL, then use the values stored on the state */
+ if (!bufp)
+ bufp = state->bufp;
+ if (!sizep)
+ sizep = state->sizep;
- *bufp = realloc(state.buf, *sizep);
- if (!*bufp) {
- rc = -1;
- goto out_err;
+ /* terminating zero */
+ rc = do_buffer_output(emit, fyewt_terminating_zero, "\0", 1, state);
+ if (rc != 1)
+ goto err_out;
+
+ state->size = state->need;
+
+ if (state->allocate_buffer) {
+ /* resize */
+ buf = realloc(state->buf, state->size);
+ /* very likely since we shrink the buffer, but make sure we don't error out */
+ if (buf)
+ state->buf = buf;
}
+ /* retreive the buffer and size */
+ *sizep = state->size;
+ *bufp = state->buf;
+
+ /* reset the buffer, ownership now to the caller */
+ state->buf = NULL;
+ state->size = 0;
+ state->pos = 0;
+ state->bufp = NULL;
+ state->sizep = NULL;
+
return 0;
-out_err:
- if (grow && state.buf)
- free(state.buf);
+err_out:
*bufp = NULL;
*sizep = 0;
+ return -1;
+}
+static int fy_emit_str_internal(struct fy_document *fyd,
+ enum fy_emitter_cfg_flags flags,
+ struct fy_node *fyn, char **bufp, size_t *sizep,
+ bool allocate_buffer)
+{
+ struct fy_emitter *emit = NULL;
+ int rc = -1;
+
+ emit = fy_emitter_create_str_internal(flags, bufp, sizep, allocate_buffer);
+ if (!emit)
+ goto out_err;
+
+ if (fyd) {
+ fy_emit_prepare_document_state(emit, fyd->fyds);
+ rc = 0;
+ if (fyd->root)
+ rc = fy_emit_node_check(emit, fyd->root);
+ if (!rc)
+ rc = fy_emit_document_no_check(emit, fyd);
+ } else {
+ rc = fy_emit_node_check(emit, fyn);
+ if (!rc)
+ rc = fy_emit_node_no_check(emit, fyn);
+ }
+
+ if (rc)
+ goto out_err;
+
+ rc = fy_emitter_collect_str_internal(emit, NULL, NULL);
+ if (rc)
+ goto out_err;
+
+ /* OK, all done */
+
+out_err:
+ fy_emitter_destroy(emit);
return rc;
}
-int fy_emit_document_to_buffer(struct fy_document *fyd, enum fy_emitter_cfg_flags flags, char *buf, int size)
+int fy_emit_document_to_buffer(struct fy_document *fyd, enum fy_emitter_cfg_flags flags, char *buf, size_t size)
{
int rc;
char *fy_emit_document_to_string(struct fy_document *fyd, enum fy_emitter_cfg_flags flags)
{
- char *buf = NULL;
- int rc, size = 0;
+ char *buf;
+ size_t size;
+ int rc;
+ buf = NULL;
+ size = 0;
rc = fy_emit_str_internal(fyd, flags, NULL, &buf, &size, true);
if (rc != 0)
return NULL;
return buf;
}
-static int do_file_output(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int len, void *userdata)
+struct fy_emitter *
+fy_emit_to_buffer(enum fy_emitter_cfg_flags flags, char *buf, size_t size)
+{
+ if (!buf)
+ return NULL;
+
+ return fy_emitter_create_str_internal(flags, &buf, &size, false);
+}
+
+char *
+fy_emit_to_buffer_collect(struct fy_emitter *emit, size_t *sizep)
+{
+ int rc;
+ char *buf;
+
+ if (!emit || !sizep)
+ return NULL;
+
+ rc = fy_emitter_collect_str_internal(emit, &buf, sizep);
+ if (rc) {
+ *sizep = 0;
+ return NULL;
+ }
+ return buf;
+}
+
+struct fy_emitter *
+fy_emit_to_string(enum fy_emitter_cfg_flags flags)
+{
+ return fy_emitter_create_str_internal(flags, NULL, NULL, true);
+}
+
+char *
+fy_emit_to_string_collect(struct fy_emitter *emit, size_t *sizep)
+{
+ int rc;
+ char *buf;
+
+ if (!emit || !sizep)
+ return NULL;
+
+ rc = fy_emitter_collect_str_internal(emit, &buf, sizep);
+ if (rc) {
+ *sizep = 0;
+ return NULL;
+ }
+ return buf;
+}
+
+static int do_file_output(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int leni, void *userdata)
{
FILE *fp = userdata;
+ size_t len;
+
+ len = (size_t)leni;
+
+ /* no funky stuff */
+ if (len < 0)
+ return -1;
return fwrite(str, 1, len, fp);
}
emit_cfg.userdata = fp;
emit_cfg.flags = flags;
fy_emit_setup(emit, &emit_cfg);
- rc = fy_emit_document(emit, fyd);
+
+ fy_emit_prepare_document_state(emit, fyd->fyds);
+
+ rc = 0;
+ if (fyd->root)
+ rc = fy_emit_node_check(emit, fyd->root);
+
+ rc = fy_emit_document_no_check(emit, fyd);
+
fy_emit_cleanup(emit);
return rc ? rc : 0;
return rc ? rc : 0;
}
-int fy_emit_node_to_buffer(struct fy_node *fyn, enum fy_emitter_cfg_flags flags, char *buf, int size)
+static int do_fd_output(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int leni, void *userdata)
+{
+ size_t len;
+ int fd;
+ ssize_t wrn;
+ int total;
+
+ len = (size_t)leni;
+
+ /* no funky stuff */
+ if (len < 0)
+ return -1;
+
+ /* get the file descriptor */
+ fd = (int)(uintptr_t)userdata;
+ if (fd < 0)
+ return -1;
+
+ /* loop output to fd */
+ total = 0;
+ while (len > 0) {
+
+ do {
+ wrn = write(fd, str, len);
+ } while (wrn == -1 && errno == EAGAIN);
+
+ if (wrn == -1)
+ return -1;
+
+ if (wrn == 0)
+ return total;
+
+ len -= wrn;
+ str += wrn;
+ total += wrn;
+ }
+
+ return total;
+}
+
+int fy_emit_document_to_fd(struct fy_document *fyd, enum fy_emitter_cfg_flags flags, int fd)
+{
+ struct fy_emitter emit_state, *emit = &emit_state;
+ struct fy_emitter_cfg emit_cfg;
+ int rc;
+
+ if (fd < 0)
+ return -1;
+
+ memset(&emit_cfg, 0, sizeof(emit_cfg));
+ emit_cfg.output = do_fd_output;
+ emit_cfg.userdata = (void *)(uintptr_t)fd;
+ emit_cfg.flags = flags;
+ fy_emit_setup(emit, &emit_cfg);
+
+ fy_emit_prepare_document_state(emit, fyd->fyds);
+
+ rc = 0;
+ if (fyd->root)
+ rc = fy_emit_node_check(emit, fyd->root);
+
+ rc = fy_emit_document_no_check(emit, fyd);
+
+ fy_emit_cleanup(emit);
+
+ return rc ? rc : 0;
+}
+
+int fy_emit_node_to_buffer(struct fy_node *fyn, enum fy_emitter_cfg_flags flags, char *buf, size_t size)
{
int rc;
char *fy_emit_node_to_string(struct fy_node *fyn, enum fy_emitter_cfg_flags flags)
{
- char *buf = NULL;
- int rc, size = 0;
+ char *buf;
+ size_t size;
+ int rc;
+ buf = NULL;
+ size = 0;
rc = fy_emit_str_internal(NULL, flags, fyn, &buf, &size, true);
if (rc != 0)
return NULL;
break;
case FYET_SCALAR:
+ /* if we're pretty and at column 0 (meaning it's a single scalar document) output --- */
+ if ((emit->s_flags & DDNF_ROOT) && fy_emit_is_pretty_mode(emit) && !emit->column &&
+ !fy_emit_is_flow_mode(emit) && !(emit->s_flags & DDNF_FLOW))
+ fy_emit_document_start_indicator(emit);
fy_emit_common_node_preamble(emit, fye->scalar.anchor, fye->scalar.tag, emit->s_flags, emit->s_indent);
style = fye->scalar.value ?
fy_node_style_from_scalar_style(fye->scalar.value->scalar.style) :
/* create new context */
memset(sc, 0, sizeof(*sc));
- sc->flags = DDNF_SEQ | (emit->s_flags & DDNF_ROOT);
+ sc->flags = emit->s_flags & (DDNF_ROOT | DDNF_SEQ | DDNF_MAP);
sc->indent = emit->s_indent;
sc->empty = fy_emit_streaming_sequence_empty(emit);
sc->flow_token = fye->sequence_start.sequence_start &&
sc->s_indent = s_indent;
fy_emit_sequence_prolog(emit, sc);
+ sc->flags &= ~DDNF_MAP;
+ sc->flags |= DDNF_SEQ;
emit->s_flags = sc->flags;
emit->s_indent = sc->indent;
/* create new context */
memset(sc, 0, sizeof(*sc));
- sc->flags = DDNF_MAP | (emit->s_flags & DDNF_ROOT);
+ sc->flags = emit->s_flags & (DDNF_ROOT | DDNF_SEQ | DDNF_MAP);
sc->indent = emit->s_indent;
sc->empty = fy_emit_streaming_mapping_empty(emit);
sc->flow_token = fye->mapping_start.mapping_start &&
sc->s_indent = s_indent;
fy_emit_mapping_prolog(emit, sc);
+ sc->flags &= ~DDNF_SEQ;
+ sc->flags |= DDNF_MAP;
emit->s_flags = sc->flags;
emit->s_indent = sc->indent;
fyds = fye->document_start.document_state;
fye->document_start.document_state = NULL;
+ /* prepare (i.e. adapt to the document state) */
+ fy_emit_prepare_document_state(emit, fyds);
+
fy_emit_common_document_start(emit, fyds, false);
fy_emit_goto_state(emit, FYES_DOCUMENT_CONTENT);
return 0;
}
-static int fy_emit_handle_document_content(struct fy_emitter *emit, struct fy_eventp *fyep)
-{
- int ret;
-
- ret = fy_emit_push_state(emit, FYES_DOCUMENT_END);
- if (ret)
- return ret;
-
- return fy_emit_streaming_node(emit, fyep, DDNF_ROOT);
-}
-
static int fy_emit_handle_document_end(struct fy_emitter *emit, struct fy_eventp *fyep)
{
struct fy_document_state *fyds;
fyds = emit->fyds;
- ret = fy_emit_common_document_end(emit);
+ ret = fy_emit_common_document_end(emit, true, fye->document_end.implicit);
if (ret)
return ret;
return 0;
}
+static int fy_emit_handle_document_content(struct fy_emitter *emit, struct fy_eventp *fyep)
+{
+ struct fy_event *fye = &fyep->e;
+ int ret;
+
+ /* empty document? */
+ if (fye->type == FYET_DOCUMENT_END)
+ return fy_emit_handle_document_end(emit, fyep);
+
+ ret = fy_emit_push_state(emit, FYES_DOCUMENT_END);
+ if (ret)
+ return ret;
+
+ return fy_emit_streaming_node(emit, fyep, DDNF_ROOT);
+}
+
static int fy_emit_handle_sequence_item(struct fy_emitter *emit, struct fy_eventp *fyep, bool first)
{
struct fy_event *fye = &fyep->e;
struct fy_token *fyt_item = NULL;
int ret;
- fy_token_unref_rl(&emit->recycled_token, sc->fyt_last_value);
+ fy_token_unref_rl(emit->recycled_token_list, sc->fyt_last_value);
sc->fyt_last_value = NULL;
switch (fye->type) {
int ret, aflags;
bool simple_key;
- fy_token_unref_rl(&emit->recycled_token, sc->fyt_last_key);
+ fy_token_unref_rl(emit->recycled_token_list, sc->fyt_last_key);
sc->fyt_last_key = NULL;
- fy_token_unref_rl(&emit->recycled_token, sc->fyt_last_value);
+ fy_token_unref_rl(emit->recycled_token_list, sc->fyt_last_value);
sc->fyt_last_value = NULL;
simple_key = false;
int fy_document_default_emit_to_fp(struct fy_document *fyd, FILE *fp)
{
- struct fy_emitter fye_local, *fye = &fye_local;
+ struct fy_emitter emit_local, *emit = &emit_local;
struct fy_emitter_cfg ecfg_local, *ecfg = &ecfg_local;
struct fy_emitter_default_output_data d_local, *d = &d_local;
int rc;
ecfg->diag = fyd->diag;
ecfg->userdata = d;
- rc = fy_emit_setup(fye, ecfg);
+ rc = fy_emit_setup(emit, ecfg);
if (rc)
goto err_setup;
- rc = fy_emit_document(fye, fyd);
+ fy_emit_prepare_document_state(emit, fyd->fyds);
+
+ rc = 0;
+ if (fyd->root)
+ rc = fy_emit_node_check(emit, fyd->root);
+
+ rc = fy_emit_document_no_check(emit, fyd);
if (rc)
goto err_emit;
- fy_emit_cleanup(fye);
+ fy_emit_cleanup(emit);
return 0;
err_emit:
- fy_emit_cleanup(fye);
+ fy_emit_cleanup(emit);
err_setup:
return -1;
}
int flow_level;
unsigned int flags;
bool output_error : 1;
+ bool source_json : 1; /* the source was json */
+ bool force_json : 1; /* force JSON mode unconditionally */
+ bool suppress_recycling_force : 1;
+ bool suppress_recycling : 1;
+
/* current document */
struct fy_emitter_cfg cfg; /* yeah, it isn't worth just to save a few bytes */
struct fy_document *fyd;
/* recycled */
struct fy_eventp_list recycled_eventp;
struct fy_token_list recycled_token;
+
+ struct fy_eventp_list *recycled_eventp_list; /* NULL when suppressing */
+ struct fy_token_list *recycled_token_list; /* NULL when suppressing */
+
+ /* for special needs */
+ void (*finalizer)(struct fy_emitter *emit);
};
int fy_emit_setup(struct fy_emitter *emit, const struct fy_emitter_cfg *cfg);
#include "fy-parse.h"
#include "fy-emit.h"
+#include "fy-doc.h"
#include "fy-ctype.h"
#include "fy-utf8.h"
if (!fyep)
return NULL;
- memset(fyep, 0, sizeof(*fyep));
-
fyep->e.type = FYET_NONE;
return fyep;
void fy_parse_eventp_clean(struct fy_parser *fyp, struct fy_eventp *fyep)
{
- struct fy_token_list *fytl;
-
if (!fyp || !fyep)
return;
- fytl = !fyp->suppress_recycling ? &fyp->recycled_token : NULL;
- fy_eventp_clean_rl(fytl, fyep);
+ fy_eventp_clean_rl(fyp->recycled_token_list, fyep);
}
void fy_emit_eventp_clean(struct fy_emitter *emit, struct fy_eventp *fyep)
if (!emit || !fyep)
return;
- fy_eventp_clean_rl(&emit->recycled_token, fyep);
+ fy_eventp_clean_rl(emit->recycled_token_list, fyep);
}
void fy_eventp_free(struct fy_eventp *fyep)
if (!fyp)
return NULL;
- if (!fyp->suppress_recycling)
- fyep = fy_eventp_list_pop(&fyp->recycled_eventp);
+ if (fyp->recycled_eventp_list)
+ fyep = fy_eventp_list_pop(fyp->recycled_eventp_list);
if (!fyep)
fyep = fy_eventp_alloc();
if (!fyep)
fy_parse_eventp_clean(fyp, fyep);
/* and push to the parser recycle list */
- if (!fyp->suppress_recycling)
- fy_eventp_list_push(&fyp->recycled_eventp, fyep);
+ if (fyp->recycled_eventp_list)
+ fy_eventp_list_push(fyp->recycled_eventp_list, fyep);
else
fy_eventp_free(fyep);
}
-void fy_parse_eventp_vacuum(struct fy_parser *fyp)
-{
- struct fy_eventp *fyep;
-
- if (!fyp)
- return;
-
- while ((fyep = fy_eventp_list_pop(&fyp->recycled_eventp)) != NULL) {
- /* catch double recycles */
- /* assert(fy_eventp_list_head(&fyp->recycled_eventp)!= fyep); */
- fy_eventp_free(fyep);
- }
-}
-
void fy_parser_event_free(struct fy_parser *fyp, struct fy_event *fye)
{
struct fy_eventp *fyep;
/* clean, safe to do */
fy_emit_eventp_clean(emit, fyep);
- /* and push to the parser recycle list */
- fy_eventp_list_push(&emit->recycled_eventp, fyep);
+ if (emit->recycled_eventp_list)
+ fy_eventp_list_push(emit->recycled_eventp_list, fyep);
+ else
+ fy_eventp_free(fyep);
}
void fy_emit_event_free(struct fy_emitter *emit, struct fy_event *fye)
fy_emit_eventp_recycle(emit, fyep);
}
-void fy_emit_eventp_vacuum(struct fy_emitter *emit)
-{
- struct fy_eventp *fyep;
-
- if (!emit)
- return;
-
- while ((fyep = fy_eventp_list_pop(&emit->recycled_eventp)) != NULL)
- fy_eventp_free(fyep);
-}
-
struct fy_eventp *
fy_eventp_vcreate_internal(struct fy_eventp_list *recycled_list, struct fy_diag *diag,
struct fy_document_state *fyds, enum fy_event_type type, va_list ap)
if (!emit)
return NULL;
- fyep = fy_eventp_vcreate_internal(&emit->recycled_eventp, emit->diag, emit->fyds, type, ap);
+ fyep = fy_eventp_vcreate_internal(emit->recycled_eventp_list, emit->diag, emit->fyds, type, ap);
if (!fyep)
return NULL;
if (!fyp)
return NULL;
- fyep = fy_eventp_vcreate_internal(&fyp->recycled_eventp, fyp->diag, fyp->current_document_state, type, ap);
+ fyep = fy_eventp_vcreate_internal(fyp->recycled_eventp_list, fyp->diag, fyp->current_document_state, type, ap);
if (!fyep)
return NULL;
return fy_document_state_version(fye->document_start.document_state);
}
+struct fy_eventp *
+fy_document_iterator_eventp_alloc(struct fy_document_iterator *fydi)
+{
+ struct fy_eventp *fyep = NULL;
+
+ if (!fydi)
+ return NULL;
+
+ if (fydi->recycled_eventp_list)
+ fyep = fy_eventp_list_pop(fydi->recycled_eventp_list);
+ if (!fyep)
+ fyep = fy_eventp_alloc();
+ if (!fyep)
+ return NULL;
+
+ fyep->e.type = FYET_NONE;
+
+ return fyep;
+}
+
+void fy_document_iterator_eventp_clean(struct fy_document_iterator *fydi, struct fy_eventp *fyep)
+{
+ if (!fydi || !fyep)
+ return;
+
+ fy_eventp_clean_rl(fydi->recycled_token_list, fyep);
+}
+
+void fy_document_iterator_eventp_recycle(struct fy_document_iterator *fydi, struct fy_eventp *fyep)
+{
+ if (!fydi || !fyep)
+ return;
+
+ /* clean, safe to do */
+ fy_document_iterator_eventp_clean(fydi, fyep);
+
+ if (fydi->recycled_eventp_list)
+ fy_eventp_list_push(fydi->recycled_eventp_list, fyep);
+ else
+ fy_eventp_free(fyep);
+}
+
+struct fy_event *
+fy_document_iterator_event_vcreate(struct fy_document_iterator *fydi, enum fy_event_type type, va_list ap)
+{
+ struct fy_eventp *fyep;
+
+ if (!fydi)
+ return NULL;
+
+ fyep = fy_eventp_vcreate_internal(fydi->recycled_eventp_list,
+ fydi->fyd ? fydi->fyd->diag : NULL,
+ fydi->fyd ? fydi->fyd->fyds : NULL,
+ type, ap);
+ if (!fyep)
+ return NULL;
+
+ return &fyep->e;
+}
+
+struct fy_event *
+fy_document_iterator_event_create(struct fy_document_iterator *fydi, enum fy_event_type type, ...)
+{
+ struct fy_event *fye;
+ va_list ap;
+
+ va_start(ap, type);
+ fye = fy_document_iterator_event_vcreate(fydi, type, ap);
+ va_end(ap);
+
+ return fye;
+}
+
+void fy_document_iterator_event_free(struct fy_document_iterator *fydi, struct fy_event *fye)
+{
+ struct fy_eventp *fyep;
+
+ if (!fydi || !fye)
+ return;
+
+ fyep = container_of(fye, struct fy_eventp, e);
+
+ fy_document_iterator_eventp_recycle(fydi, fyep);
+}
struct fy_eventp *fy_parse_eventp_alloc(struct fy_parser *fyp);
void fy_parse_eventp_recycle(struct fy_parser *fyp, struct fy_eventp *fyep);
-void fy_parse_eventp_vacuum(struct fy_parser *fyp);
struct fy_eventp *fy_emit_eventp_alloc(struct fy_emitter *fye);
void fy_emit_eventp_recycle(struct fy_emitter *emit, struct fy_eventp *fyep);
-void fy_emit_eventp_vacuum(struct fy_emitter *emit);
+
+struct fy_document_iterator;
+
+struct fy_eventp *fy_document_iterator_eventp_alloc(struct fy_document_iterator *fydi);
+void fy_document_iterator_eventp_recycle(struct fy_document_iterator *fydi, struct fy_eventp *fyep);
+struct fy_event *fy_document_iterator_event_create(struct fy_document_iterator *document_iterator, enum fy_event_type type, ...);
+struct fy_event *fy_document_iterator_event_vcreate(struct fy_document_iterator *document_iterator, enum fy_event_type type, va_list ap);
+void fy_document_iterator_event_free(struct fy_document_iterator *document_iterator, struct fy_event *fye);
#endif
#include "fy-input.h"
+/* amount of multiplication of page size for CHOP size
+ * for a 4K page this is 64K blocks
+ */
+#ifndef FYI_CHOP_MULT
+#define FYI_CHOP_MULT 16
+#endif
+
struct fy_input *fy_input_alloc(void)
{
struct fy_input *fyi;
fyi->allocated = 0;
fyi->read = 0;
fyi->chunk = 0;
+ fyi->chop = 0;
fyi->fp = NULL;
if (!handle)
aflags = fy_analyze_scalar_content(data, size,
false, fylb_cr_nl, fyfws_space_tab); /* hardcoded yaml mode */
else
- aflags = FYACF_EMPTY | FYACF_FLOW_PLAIN | FYACF_BLOCK_PLAIN;
+ aflags = FYACF_EMPTY | FYACF_FLOW_PLAIN | FYACF_BLOCK_PLAIN | FYACF_SIZE0;
handle->start_mark.input_pos = 0;
handle->start_mark.line = 0;
return;
switch (fyi->cfg.type) {
+
case fyit_file:
- if (fyi->file.fd != -1) {
- close(fyi->file.fd);
- fyi->file.fd = -1;
- }
+ case fyit_fd:
+
if (fyi->addr && fyi->addr != MAP_FAILED) {
- munmap(fyi->addr, fyi->file.length);
- fyi->addr = NULL;
+ munmap(fyi->addr, fyi->length);
+ fyi->addr = MAP_FAILED;
+ }
+
+ if (fyi->fd != -1) {
+ if (!fyi->cfg.no_close_fd)
+ close(fyi->fd);
+ fyi->fd = -1;
}
+
if (fyi->buffer) {
free(fyi->buffer);
fyi->buffer = NULL;
}
if (fyi->fp) {
- fclose(fyi->fp);
+ if (!fyi->cfg.no_fclose_fp)
+ fclose(fyi->fp);
fyi->fp = NULL;
}
break;
fy_reader_reset(fyr);
}
+void fy_reader_apply_mode(struct fy_reader *fyr)
+{
+ struct fy_input *fyi;
+
+ assert(fyr);
+
+ /* set input mode from the current reader settings */
+ switch (fyr->mode) {
+ case fyrm_yaml:
+ fyr->json_mode = false;
+ fyr->lb_mode = fylb_cr_nl;
+ fyr->fws_mode = fyfws_space_tab;
+ break;
+ case fyrm_json:
+ fyr->json_mode = true;
+ fyr->lb_mode = fylb_cr_nl;
+ fyr->fws_mode = fyfws_space;
+ break;
+ case fyrm_yaml_1_1:
+ fyr->json_mode = false;
+ fyr->lb_mode = fylb_cr_nl_N_L_P;
+ fyr->fws_mode = fyfws_space_tab;
+ break;
+ }
+ fyi = fyr->current_input;
+ if (fyi) {
+ fyi->json_mode = fyr->json_mode;
+ fyi->lb_mode = fyr->lb_mode;
+ fyi->fws_mode = fyr->fws_mode;
+ }
+}
+
int fy_reader_input_open(struct fy_reader *fyr, struct fy_input *fyi, const struct fy_reader_input_cfg *icfg)
{
struct stat sb;
fy_input_unref(fyr->current_input);
fyr->current_input = fy_input_ref(fyi);
- fy_reader_apply_mode_to_input(fyr);
+ fy_reader_apply_mode(fyr);
if (!icfg)
memset(&fyr->current_input_cfg, 0, sizeof(fyr->current_input_cfg));
fyi->allocated = 0;
fyi->read = 0;
fyi->chunk = 0;
+ fyi->chop = 0;
fyi->fp = NULL;
switch (fyi->cfg.type) {
+
case fyit_file:
- memset(&fyi->file, 0, sizeof(fyi->file));
- fyi->file.fd = fy_reader_file_open(fyr, fyi->cfg.file.filename);
- fyr_error_check(fyr, fyi->file.fd != -1, err_out,
- "failed to open %s", fyi->cfg.file.filename);
+ case fyit_fd:
+
+ switch (fyi->cfg.type) {
+ case fyit_file:
+ fyi->fd = fy_reader_file_open(fyr, fyi->cfg.file.filename);
+ fyr_error_check(fyr, fyi->fd != -1, err_out,
+ "failed to open %s", fyi->cfg.file.filename);
+ break;
+
+ case fyit_fd:
+ fyi->fd = fyi->cfg.fd.fd;
+ fyr_error_check(fyr, fyi->fd >= 0, err_out,
+ "bad file.fd %d", fyi->cfg.fd.fd);
+ break;
+ default:
+ assert(0); // will never happen
+ }
- rc = fstat(fyi->file.fd, &sb);
+ rc = fstat(fyi->fd, &sb);
fyr_error_check(fyr, rc != -1, err_out,
"failed to fstat %s", fyi->cfg.file.filename);
- fyi->file.length = sb.st_size;
+ fyi->length = sb.st_size;
/* only map if not zero (and is not disabled) */
if (sb.st_size > 0 && !fyr->current_input_cfg.disable_mmap_opt) {
- fyi->addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE,
- fyi->file.fd, 0);
+ fyi->addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fyi->fd, 0);
/* convert from MAP_FAILED to NULL */
- if (fyi->addr == MAP_FAILED) {
+ if (fyi->addr == MAP_FAILED)
fyr_debug(fyr, "mmap failed for file %s",
fyi->cfg.file.filename);
- fyi->addr = NULL;
- }
}
/* if we've managed to mmap, we' good */
- if (fyi->addr)
+ if (fyi->addr != MAP_FAILED)
break;
- fyr_debug(fyr, "direct mmap mode unavailable for file %s, switching to stream mode",
- fyi->cfg.file.filename);
-
- fyi->fp = fdopen(fyi->file.fd, "r");
- fyr_error_check(fyr, rc != -1, err_out,
- "failed to fdopen %s", fyi->cfg.file.filename);
-
- /* fd ownership assigned to file */
- fyi->file.fd = -1;
+ /* if we're not ignoring stdio, open a FILE* using the fd */
+ if (!fyi->cfg.ignore_stdio) {
+ fyi->fp = fdopen(fyi->fd, "r");
+ fyr_error_check(fyr, rc != -1, err_out, "failed to fdopen %s", fyi->name);
+ } else
+ fyi->fp = NULL;
- /* switch to stream mode */
- fyi->chunk = sysconf(_SC_PAGESIZE);
- fyi->buffer = malloc(fyi->chunk);
- fyr_error_check(fyr, fyi->buffer, err_out,
- "fy_alloc() failed");
- fyi->allocated = fyi->chunk;
break;
case fyit_stream:
- fyi->chunk = fyi->cfg.stream.chunk;
- if (!fyi->chunk)
- fyi->chunk = sysconf(_SC_PAGESIZE);
- fyi->buffer = malloc(fyi->chunk);
- fyr_error_check(fyr, fyi->buffer, err_out,
- "fy_alloc() failed");
- fyi->allocated = fyi->chunk;
- fyi->fp = fyi->cfg.stream.fp;
+ if (!fyi->cfg.ignore_stdio)
+ fyi->fp = fyi->cfg.stream.fp;
+ else
+ fyi->fd = fileno(fyi->cfg.stream.fp);
break;
case fyit_memory:
break;
case fyit_callback:
- fyi->chunk = sysconf(_SC_PAGESIZE);
- fyi->buffer = malloc(fyi->chunk);
- fyr_error_check(fyr, fyi->buffer, err_out,
- "fy_alloc() failed");
- fyi->allocated = fyi->chunk;
break;
default:
break;
}
+ switch (fyi->cfg.type) {
+
+ /* those two need no memory */
+ case fyit_memory:
+ case fyit_alloc:
+ break;
+
+ /* all the rest need it */
+ default:
+ /* if we're not in mmap mode */
+ if (fyi->addr != MAP_FAILED)
+ break;
+
+ fyi->chunk = fyi->cfg.chunk;
+ if (!fyi->chunk)
+ fyi->chunk = sysconf(_SC_PAGESIZE);
+ fyi->chop = fyi->chunk * FYI_CHOP_MULT;
+ fyi->buffer = malloc(fyi->chunk);
+ fyr_error_check(fyr, fyi->buffer, err_out,
+ "fy_alloc() failed");
+ fyi->allocated = fyi->chunk;
+ break;
+ }
+
+ fyr->this_input_start = 0;
fyr->current_input_pos = 0;
fyr->line = 0;
fyr->column = 0;
switch (fyi->cfg.type) {
case fyit_file:
- if (fyi->addr)
+ case fyit_fd:
+ if (fyi->addr != MAP_FAILED)
break;
/* fall-through */
return -1;
}
+int fy_reader_input_scan_token_mark_slow_path(struct fy_reader *fyr)
+{
+ struct fy_input *fyi, *fyi_new = NULL;
+
+ assert(fyr);
+
+ if (!fy_reader_input_chop_active(fyr))
+ return 0;
+
+ fyi = fyr->current_input;
+ assert(fyi);
+
+ fyi_new = fy_input_alloc();
+ fyr_error_check(fyr, fyi_new, err_out,
+ "fy_input_alloc() failed\n");
+
+ /* copy the config over */
+ fyi_new->cfg = fyi->cfg;
+ fyi_new->name = strdup(fyi->name);
+ fyr_error_check(fyr, fyi_new->name, err_out,
+ "strdup() failed\n");
+
+ fyi_new->chunk = fyi->chunk;
+ fyi_new->chop = fyi->chop;
+ fyi_new->buffer = malloc(fyi->chunk);
+ fyr_error_check(fyr, fyi_new->buffer, err_out,
+ "fy_alloc() failed");
+ fyi_new->allocated = fyi->chunk;
+ fyi_new->fp = fyi->fp;
+
+ fyi->fp = NULL; /* the file pointer now assigned to the new */
+
+ fyi_new->lb_mode = fyi->lb_mode;
+ fyi_new->fws_mode = fyi->fws_mode;
+
+ fyi_new->state = FYIS_PARSE_IN_PROGRESS;
+
+ /* adjust and copy the left over reads */
+ assert(fyi->read >= fyr->current_input_pos);
+ fyi_new->read = fyi->read - fyr->current_input_pos;
+ if (fyi_new->read > 0)
+ memcpy(fyi_new->buffer, fyi->buffer + fyr->current_input_pos, fyi_new->read);
+
+ fyr->this_input_start += fyr->current_input_pos;
+
+ /* update the reader to point to the new input */
+ fyr->current_input = fyi_new;
+ fyr->current_input_pos = 0;
+ fyr->current_ptr = fyi_new->buffer;
+
+ /* free the old input - while references to it exist it will hang around */
+ fyi->state = FYIS_PARSED;
+ fy_input_unref(fyi);
+ fyi = NULL;
+
+ fyr_debug(fyr, "chop at this_input_start=%zu chop=%zu\n", fyr->this_input_start, fyi->chop);
+
+ return 0;
+err_out:
+ fy_input_unref(fyi_new);
+ return -1;
+}
+
const void *fy_reader_ptr_slow_path(struct fy_reader *fyr, size_t *leftp)
{
struct fy_input *fyi;
/* tokens cannot cross boundaries */
switch (fyi->cfg.type) {
case fyit_file:
- if (fyi->addr) {
- left = fyi->file.length - fyr->current_input_pos;
+ case fyit_fd:
+ if (fyi->addr != MAP_FAILED) {
+ left = fyi->length - (fyr->this_input_start + fyr->current_input_pos);
p = fyi->addr + fyr->current_input_pos;
break;
}
case fyit_stream:
case fyit_callback:
- left = fyi->read - fyr->current_input_pos;
+ left = fyi->read - (fyr->this_input_start + fyr->current_input_pos);
p = fyi->buffer + fyr->current_input_pos;
break;
fyr->current_ptr = p;
fyr->current_left = left;
- fyr->current_c = fy_utf8_get(fyr->current_ptr, fyr->current_left, &fyr->current_w);
+ fyr->current_c = fy_utf8_get(p, left, &fyr->current_w);
return p;
}
switch (fyi->cfg.type) {
case fyit_file:
+ case fyit_fd:
- if (fyi->addr) {
- assert(fyi->file.length >= pos);
+ if (fyi->addr != MAP_FAILED) {
+ assert(fyi->length >= (fyr->this_input_start + pos));
- left = fyi->file.length - pos;
+ left = fyi->length - (fyr->this_input_start + pos);
if (!left) {
fyr_debug(fyr, "file input exhausted");
break;
break;
}
- } else {
- if (!fyi->cfg.stream.ignore_stdio) {
+ } else if (fyi->fp) {
- fyr_debug(fyr, "performing fread request of %zu", nreadreq);
+ fyr_debug(fyr, "performing fread request of %zu", nreadreq);
- nread = fread(fyi->buffer + fyi->read, 1, nreadreq, fyi->fp);
+ nread = fread(fyi->buffer + fyi->read, 1, nreadreq, fyi->fp);
- fyr_debug(fyr, "fread returned %zu", nread);
+ fyr_debug(fyr, "fread returned %zu", nread);
- if (nread <= 0) {
- fyi->err = ferror(fyi->fp);
- if (fyi->err) {
- fyi->eof = true;
- fyr_debug(fyr, "fread got ERROR");
- goto err_out;
- }
-
- fyi->eof = feof(fyi->fp);
- if (fyi->eof)
- fyr_debug(fyr, "fread got EOF");
- nread = 0;
- break;
+ if (nread <= 0) {
+ fyi->err = ferror(fyi->fp);
+ if (fyi->err) {
+ fyi->eof = true;
+ fyr_debug(fyr, "fread got ERROR");
+ goto err_out;
}
- } else {
+ fyi->eof = feof(fyi->fp);
+ if (fyi->eof)
+ fyr_debug(fyr, "fread got EOF");
+ nread = 0;
+ break;
+ }
- fyr_debug(fyr, "performing read request of %zu", nreadreq);
+ } else if (fyi->fd >= 0) {
- do {
- snread = read(fileno(fyi->fp), fyi->buffer + fyi->read, nreadreq);
- } while (snread == -1 && errno == EAGAIN);
+ fyr_debug(fyr, "performing read request of %zu", nreadreq);
- fyr_debug(fyr, "read returned %zd", snread);
+ do {
+ snread = read(fyi->fd, fyi->buffer + fyi->read, nreadreq);
+ } while (snread == -1 && errno == EAGAIN);
- if (snread == -1) {
- fyi->err = true;
- fyi->eof = true;
- fyr_error(fyr, "read() failed");
- goto err_out;
- }
+ fyr_debug(fyr, "read returned %zd", snread);
- if (!snread) {
- fyi->eof = true;
- fyr_error(fyr, "read() failed");
- nread = 0;
- break;
- }
+ if (snread == -1) {
+ fyi->err = true;
+ fyi->eof = true;
+ fyr_error(fyr, "read() failed: %s", strerror(errno));
+ goto err_out;
+ }
- nread = snread;
+ if (!snread) {
+ fyi->eof = true;
+ nread = 0;
+ break;
}
+
+ nread = snread;
+ } else {
+ fyr_error(fyr, "No FILE* nor fd available?");
+ fyi->eof = true;
+ nread = 0;
+ goto err_out;
}
assert(nread > 0);
/* copy filename pointers and switch */
switch (fyic->type) {
+
case fyit_file:
fyi->name = strdup(fyic->file.filename);
break;
+
+ case fyit_fd:
+ ret = asprintf(&fyi->name, "<fd-%d>", fyic->fd.fd);
+ if (ret == -1)
+ fyi->name = NULL;
+ break;
+
case fyit_stream:
if (fyic->stream.name)
fyi->name = strdup(fyic->stream.name);
}
break;
case fyit_memory:
- ret = asprintf(&fyi->name, "<memory-@0x%p-0x%p>",
+ ret = asprintf(&fyi->name, "<memory-@%p-%p>",
fyic->memory.data, fyic->memory.data + fyic->memory.size - 1);
if (ret == -1)
fyi->name = NULL;
break;
case fyit_alloc:
- ret = asprintf(&fyi->name, "<alloc-@0x%p-0x%p>",
+ ret = asprintf(&fyi->name, "<alloc-@%p-%p>",
fyic->memory.data, fyic->memory.data + fyic->memory.size - 1);
if (ret == -1)
fyi->name = NULL;
fyi->allocated = 0;
fyi->read = 0;
fyi->chunk = 0;
+ fyi->chop = 0;
fyi->fp = NULL;
-
- switch (fyi->cfg.type) {
- case fyit_file:
- memset(&fyi->file, 0, sizeof(fyi->file));
- fyi->file.fd = -1;
- fyi->addr = MAP_FAILED;
- break;
-
- /* nothing for those two */
- case fyit_stream:
- break;
-
- case fyit_memory:
- /* nothing to do for memory */
- break;
-
- case fyit_alloc:
- /* nothing to do for memory */
- break;
-
- case fyit_callback:
- /* nothing to do for callback */
- break;
-
- default:
- assert(0);
- break;
- }
+ fyi->fd = -1;
+ fyi->addr = MAP_FAILED;
+ fyi->length = -1;
/* default modes */
fyi->lb_mode = fylb_cr_nl;
#include <libfyaml.h>
+#include "fy-utils.h"
#include "fy-typelist.h"
#include "fy-ctype.h"
fyit_memory,
fyit_alloc,
fyit_callback,
+ fyit_fd,
};
struct fy_input_cfg {
enum fy_input_type type;
void *userdata;
+ size_t chunk;
+ bool ignore_stdio : 1;
+ bool no_fclose_fp : 1;
+ bool no_close_fd : 1;
union {
struct {
const char *filename;
struct {
const char *name;
FILE *fp;
- size_t chunk;
- bool ignore_stdio;
} stream;
struct {
const void *data;
/* negative return is error, 0 is EOF */
ssize_t (*input)(void *user, void *buf, size_t count);
} callback;
+ struct {
+ int fd;
+ } fd;
};
};
struct list_head node;
enum fy_input_state state;
struct fy_input_cfg cfg;
+ int refs; /* number of referers */
char *name;
void *buffer; /* when the file can't be mmaped */
uint64_t generation;
size_t allocated;
size_t read;
size_t chunk;
- FILE *fp;
- int refs;
+ size_t chop;
+ FILE *fp; /* FILE* for the input if it exists */
+ int fd; /* fd for file and stream */
+ size_t length; /* length of file */
void *addr; /* mmaped for files, allocated for streams */
bool eof : 1; /* got EOF */
bool err : 1; /* got an error */
/* propagated */
+ bool json_mode;
enum fy_lb_mode lb_mode;
enum fy_flow_ws_mode fws_mode;
-
- union {
- struct {
- int fd; /* fd for file and stream */
- size_t length;
- } file;
- };
};
FY_TYPE_DECL_LIST(input);
switch (fyi->cfg.type) {
case fyit_file:
if (fyi->addr) {
- size = fyi->file.length;
+ size = fyi->length;
break;
}
/* fall-through */
struct fy_reader_input_cfg current_input_cfg;
struct fy_input *current_input;
+ size_t this_input_start; /* this input start */
size_t current_input_pos; /* from start of input */
const void *current_ptr; /* current pointer into the buffer */
int current_c; /* current utf8 character at current_ptr (-1 if not cached) */
int tabsize; /* very experimental tab size for indent purposes */
struct fy_diag *diag;
+
+ /* decoded mode variables; update when changing modes */
+ bool json_mode;
+ enum fy_lb_mode lb_mode;
+ enum fy_flow_ws_mode fws_mode;
};
void fy_reader_reset(struct fy_reader *fyr);
int fy_reader_input_open(struct fy_reader *fyr, struct fy_input *fyi, const struct fy_reader_input_cfg *icfg);
int fy_reader_input_done(struct fy_reader *fyr);
+int fy_reader_input_scan_token_mark_slow_path(struct fy_reader *fyr);
-const void *fy_reader_ptr_slow_path(struct fy_reader *fyr, size_t *leftp);
-const void *fy_reader_ensure_lookahead_slow_path(struct fy_reader *fyr, size_t size, size_t *leftp);
-
-static inline void
-fy_reader_apply_mode_to_input(struct fy_reader *fyr)
+static inline bool
+fy_reader_input_chop_active(struct fy_reader *fyr)
{
- if (!fyr || !fyr->current_input)
- return;
+ struct fy_input *fyi;
- /* set input mode from the current reader settings */
- switch (fyr->mode) {
- case fyrm_yaml:
- fyr->current_input->lb_mode = fylb_cr_nl;
- fyr->current_input->fws_mode = fyfws_space_tab;
- break;
- case fyrm_json:
- fyr->current_input->lb_mode = fylb_cr_nl;
- fyr->current_input->fws_mode = fyfws_space;
- break;
- case fyrm_yaml_1_1:
- fyr->current_input->lb_mode = fylb_cr_nl_N_L_P;
- fyr->current_input->fws_mode = fyfws_space_tab;
+ assert(fyr);
+
+ fyi = fyr->current_input;
+ assert(fyi);
+
+ if (!fyi->chop)
+ return false;
+
+ switch (fyi->cfg.type) {
+ case fyit_file:
+ return !fyi->addr && fyi->fp; /* non-mmap mode */
+
+ case fyit_stream:
+ case fyit_callback:
+ return true;
+
+ default:
+ /* all the others do not support chop */
break;
}
+
+ return false;
+}
+
+static inline int
+fy_reader_input_scan_token_mark(struct fy_reader *fyr)
+{
+ /* don't chop until ready */
+ if (!fy_reader_input_chop_active(fyr) ||
+ fyr->current_input->chop > fyr->current_input_pos)
+ return 0;
+
+ return fy_reader_input_scan_token_mark_slow_path(fyr);
}
-static inline enum fy_reader_mode
+const void *fy_reader_ptr_slow_path(struct fy_reader *fyr, size_t *leftp);
+const void *fy_reader_ensure_lookahead_slow_path(struct fy_reader *fyr, size_t size, size_t *leftp);
+
+void fy_reader_apply_mode(struct fy_reader *fyr);
+
+static FY_ALWAYS_INLINE inline enum fy_reader_mode
fy_reader_get_mode(const struct fy_reader *fyr)
{
- if (!fyr)
- return fyrm_yaml;
+ assert(fyr);
return fyr->mode;
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_set_mode(struct fy_reader *fyr, enum fy_reader_mode mode)
{
- if (!fyr)
- return;
-
+ assert(fyr);
fyr->mode = mode;
- fy_reader_apply_mode_to_input(fyr);
+ fy_reader_apply_mode(fyr);
}
-static inline struct fy_input *
+static FY_ALWAYS_INLINE inline struct fy_input *
fy_reader_current_input(const struct fy_reader *fyr)
{
- if (!fyr)
- return NULL;
+ assert(fyr);
return fyr->current_input;
}
-static inline uint64_t
+static FY_ALWAYS_INLINE inline uint64_t
fy_reader_current_input_generation(const struct fy_reader *fyr)
{
- if (!fyr || !fyr->current_input)
- return 0;
+ assert(fyr);
+ assert(fyr->current_input);
return fyr->current_input->generation;
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_column(const struct fy_reader *fyr)
{
- if (!fyr)
- return -1;
+ assert(fyr);
return fyr->column;
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_tabsize(const struct fy_reader *fyr)
{
- if (!fyr)
- return -1;
+ assert(fyr);
return fyr->tabsize;
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_line(const struct fy_reader *fyr)
{
- if (!fyr)
- return -1;
+ assert(fyr);
return fyr->line;
}
/* force new line at the end of stream */
static inline void fy_reader_stream_end(struct fy_reader *fyr)
{
- if (!fyr)
- return;
+ assert(fyr);
/* force new line */
if (fyr->column) {
}
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_get_mark(struct fy_reader *fyr, struct fy_mark *fym)
{
assert(fyr);
fym->column = fyr->column;
}
-static inline const void *
+static FY_ALWAYS_INLINE inline const void *
fy_reader_ptr(struct fy_reader *fyr, size_t *leftp)
{
if (fyr->current_ptr) {
return fy_reader_ptr_slow_path(fyr, leftp);
}
-static inline bool fy_reader_json_mode(const struct fy_reader *fyr)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_json_mode(const struct fy_reader *fyr)
{
- return fyr && fyr->mode == fyrm_json;
+ assert(fyr);
+ return fyr->json_mode;
}
-static inline enum fy_lb_mode fy_reader_lb_mode(const struct fy_reader *fyr)
+static FY_ALWAYS_INLINE inline enum fy_lb_mode
+fy_reader_lb_mode(const struct fy_reader *fyr)
{
- if (!fyr)
- return fylb_cr_nl;
-
- switch (fyr->mode) {
- case fyrm_yaml:
- case fyrm_json:
- return fylb_cr_nl;
- case fyrm_yaml_1_1:
- return fylb_cr_nl_N_L_P;
- }
-
- return fylb_cr_nl;
+ assert(fyr);
+ return fyr->lb_mode;
}
-static inline enum fy_flow_ws_mode fy_reader_flow_ws_mode(const struct fy_reader *fyr)
+static FY_ALWAYS_INLINE inline enum fy_flow_ws_mode
+fy_reader_flow_ws_mode(const struct fy_reader *fyr)
{
- if (!fyr)
- return fyfws_space_tab;
-
- switch (fyr->mode) {
- case fyrm_yaml:
- case fyrm_yaml_1_1:
- return fyfws_space_tab;
- case fyrm_json:
- return fyfws_space;
- }
-
- return fyfws_space_tab;
+ assert(fyr);
+ return fyr->fws_mode;
}
-static inline bool fy_reader_is_lb(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_lb(const struct fy_reader *fyr, int c)
{
return fy_is_lb_m(c, fy_reader_lb_mode(fyr));
}
-static inline bool fy_reader_is_lbz(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_lbz(const struct fy_reader *fyr, int c)
{
return fy_is_lbz_m(c, fy_reader_lb_mode(fyr));
}
-static inline bool fy_reader_is_blankz(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_blankz(const struct fy_reader *fyr, int c)
{
return fy_is_blankz_m(c, fy_reader_lb_mode(fyr));
}
-static inline bool fy_reader_is_generic_lb(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_generic_lb(const struct fy_reader *fyr, int c)
{
return fy_is_generic_lb_m(c, fy_reader_lb_mode(fyr));
}
-static inline bool fy_reader_is_generic_lbz(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_generic_lbz(const struct fy_reader *fyr, int c)
{
return fy_is_generic_lbz_m(c, fy_reader_lb_mode(fyr));
}
-static inline bool fy_reader_is_generic_blankz(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_generic_blankz(const struct fy_reader *fyr, int c)
{
return fy_is_generic_blankz_m(c, fy_reader_lb_mode(fyr));
}
-static inline bool fy_reader_is_flow_ws(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_flow_ws(const struct fy_reader *fyr, int c)
{
return fy_is_flow_ws_m(c, fy_reader_flow_ws_mode(fyr));
}
-static inline bool fy_reader_is_flow_blank(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_flow_blank(const struct fy_reader *fyr, int c)
{
return fy_reader_is_flow_ws(fyr, c); /* same */
}
-static inline bool fy_reader_is_flow_blankz(const struct fy_reader *fyr, int c)
+static FY_ALWAYS_INLINE inline bool
+fy_reader_is_flow_blankz(const struct fy_reader *fyr, int c)
{
return fy_is_flow_ws_m(c, fy_reader_flow_ws_mode(fyr)) ||
fy_is_generic_lbz_m(c, fy_reader_lb_mode(fyr));
}
-static inline const void *
+static FY_ALWAYS_INLINE inline const void *
fy_reader_ensure_lookahead(struct fy_reader *fyr, size_t size, size_t *leftp)
{
if (fyr->current_ptr && fyr->current_left >= size) {
const char *p;
int ret;
+ assert(fyr);
p = fy_reader_ensure_lookahead(fyr, n, NULL);
if (!p)
return -1;
return ret ? 1 : 0;
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_peek_at_offset(struct fy_reader *fyr, size_t offset)
{
const uint8_t *p;
size_t left;
int w;
+ assert(fyr);
if (offset == 0 && fyr->current_c >= 0)
return fyr->current_c;
return fy_utf8_get(p + offset, left - offset, &w);
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_peek_at_internal(struct fy_reader *fyr, int pos, ssize_t *offsetp)
{
int i, c;
size_t offset;
+ assert(fyr);
if (!offsetp || *offsetp < 0) {
for (i = 0, offset = 0; i < pos; i++, offset += fy_utf8_width(c)) {
c = fy_reader_peek_at_offset(fyr, offset);
return c;
}
-static inline bool
+static FY_ALWAYS_INLINE inline bool
fy_reader_is_blank_at_offset(struct fy_reader *fyr, size_t offset)
{
return fy_is_blank(fy_reader_peek_at_offset(fyr, offset));
}
-static inline bool
+static FY_ALWAYS_INLINE inline bool
fy_reader_is_blankz_at_offset(struct fy_reader *fyr, size_t offset)
{
return fy_reader_is_blankz(fyr, fy_reader_peek_at_offset(fyr, offset));
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_peek_at(struct fy_reader *fyr, int pos)
{
return fy_reader_peek_at_internal(fyr, pos, NULL);
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_peek(struct fy_reader *fyr)
{
if (fyr->current_c >= 0)
return fy_reader_peek_at_offset(fyr, 0);
}
-static inline const void *
+static FY_ALWAYS_INLINE inline const void *
fy_reader_peek_block(struct fy_reader *fyr, size_t *lenp)
{
const void *p;
return p;
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_advance_octets(struct fy_reader *fyr, size_t advance)
{
+ assert(fyr);
assert(fyr->current_left >= advance);
fyr->current_input_pos += advance;
void fy_reader_advance_slow_path(struct fy_reader *fyr, int c);
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_advance_printable_ascii(struct fy_reader *fyr, int c)
{
+ assert(fyr);
fy_reader_advance_octets(fyr, 1);
fyr->column++;
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_advance(struct fy_reader *fyr, int c)
{
if (fy_utf8_is_printable_ascii(c))
fy_reader_advance_slow_path(fyr, c);
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_advance_ws(struct fy_reader *fyr, int c)
{
/* skip this character */
fyr->column++;
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_reader_advance_space(struct fy_reader *fyr)
{
fy_reader_advance_octets(fyr, 1);
fyr->column++;
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_get(struct fy_reader *fyr)
{
int value;
return value;
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_reader_advance_by(struct fy_reader *fyr, int count)
{
int i, c;
/* take off the reference; reader now owns */
fy_input_unref(fyi);
+ // inherit the JSON mode
+ if (fyp->current_document_state)
+ fyp->current_document_state->json_mode = fyp_json_mode(fyp);
+
fyp_scan_debug(fyp, "get next input: new input - %s mode", json_mode ? "JSON" : "YAML");
return 1;
return -1;
}
+static inline void
+fy_token_queue_epilogue(struct fy_parser *fyp, struct fy_token *fyt)
+{
+ /* special handling for zero indented scalars */
+ fyp->token_activity_counter++;
+ if (fyt->type == FYTT_DOCUMENT_START)
+ fyp->document_first_content_token = true;
+ else if (fyp->document_first_content_token && fy_token_type_is_content(fyt->type))
+ fyp->document_first_content_token = false;
+}
+
+static inline struct fy_token *
+fy_token_queue_simple_internal(struct fy_parser *fyp, struct fy_token_list *fytl, enum fy_token_type type, int advance_octets)
+{
+ struct fy_reader *fyr = fyp->reader;
+ struct fy_token *fyt;
+
+ /* allocate and copy in place */
+ fyt = fy_token_alloc_rl(fyp->recycled_token_list);
+ if (!fyt)
+ return NULL;
+
+ fyt->type = type;
+
+ /* the advance is always octets */
+ fy_reader_fill_atom_start(fyr, &fyt->handle);
+ if (advance_octets > 0) {
+ fy_reader_advance_octets(fyr, advance_octets);
+ fyr->column += advance_octets;
+ }
+ fy_reader_fill_atom_end(fyr, &fyt->handle);
+
+ fy_input_ref(fyt->handle.fyi);
+
+ fy_token_list_add_tail(fytl, fyt);
+
+ return fyt;
+}
+
+static inline struct fy_token *
+fy_token_queue_simple(struct fy_parser *fyp, struct fy_token_list *fytl, enum fy_token_type type, int advance_octets)
+{
+ struct fy_token *fyt;
+
+ fyt = fy_token_queue_simple_internal(fyp, fytl, type, advance_octets);
+ if (!fyt)
+ return NULL;
+
+ fy_token_queue_epilogue(fyp, fyt);
+ return fyt;
+}
+
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 *fyt;
- fyt = fy_token_vcreate_rl(fy_parse_recycled_token(fyp), type, ap);
+ fyt = fy_token_vcreate_rl(fyp->recycled_token_list, type, ap);
if (!fyt)
return NULL;
fy_token_list_add_tail(fytl, fyt);
- /* special handling for zero indented scalars */
- if (fyt->type == FYTT_DOCUMENT_START) {
- fyp->document_first_content_token = true;
- fyp_scan_debug(fyp, "document_first_content_token set to true");
- } else if (fyp->document_first_content_token &&
- fy_token_type_is_content(fyt->type)) {
- fyp->document_first_content_token = false;
- fyp_scan_debug(fyp, "document_first_content_token set to false");
- }
-
- fyp_debug_dump_token_list(fyp, fytl, fyt, "queued: ");
+ fy_token_queue_epilogue(fyp, fyt);
return fyt;
}
fyp_error_check(fyp, fyds_new, err_out,
"fy_document_state_copy() failed");
}
+ // inherit the JSON mode
+ fyds_new->json_mode = fyp_json_mode(fyp);
if (fyp->current_document_state)
fy_document_state_unref(fyp->current_document_state);
"duplicate version directive");
} else {
/* in scan mode, we just override everything */
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyds->fyt_vd);
+ fy_token_unref_rl(fyp->recycled_token_list, fyds->fyt_vd);
fyds->fyt_vd = NULL;
}
err_out:
rc = -1;
err_out_rc:
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt);
+ fy_token_unref_rl(fyp->recycled_token_list, fyt);
return rc;
}
if (fyt_td) {
/* fyp_notice(fyp, "overriding tag"); */
fy_token_list_del(&fyds->fyt_td, fyt_td);
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt_td);
+ fy_token_unref_rl(fyp->recycled_token_list, fyt_td);
/* when we override a default tag the tags are explicit */
fyds->tags_explicit = true;
}
return 0;
err_out:
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt);
+ fy_token_unref_rl(fyp->recycled_token_list, fyt);
return -1;
}
if (fyp->suppress_recycling)
fyp_parse_debug(fyp, "Suppressing recycling");
+ if (!fyp->suppress_recycling) {
+ fyp->recycled_eventp_list = &fyp->recycled_eventp;
+ fyp->recycled_token_list = &fyp->recycled_token;
+ } else {
+ fyp->recycled_eventp_list = NULL;
+ fyp->recycled_token_list = NULL;
+ }
+
fyp->current_document_state = NULL;
rc = fy_reset_document_state(fyp);
void fy_parse_cleanup(struct fy_parser *fyp)
{
struct fy_input *fyi, *fyin;
+ struct fy_eventp *fyep;
struct fy_token *fyt;
fy_composer_destroy(fyp->fyc);
fy_parse_parse_state_log_list_recycle_all(fyp, &fyp->state_stack);
fy_parse_flow_list_recycle_all(fyp, &fyp->flow_stack);
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyp->stream_end_token);
+ fy_token_unref_rl(fyp->recycled_token_list, fyp->stream_end_token);
fy_document_state_unref(fyp->current_document_state);
fy_document_state_unref(fyp->default_document_state);
fy_parse_indent_vacuum(fyp);
fy_parse_simple_key_vacuum(fyp);
fy_parse_parse_state_log_vacuum(fyp);
- fy_parse_eventp_vacuum(fyp);
fy_parse_flow_vacuum(fyp);
+ /* free the recycled events */
+ while ((fyep = fy_eventp_list_pop(&fyp->recycled_eventp)) != NULL) {
+ /* catch double recycles */
+ /* assert(fy_eventp_list_head(&fyp->recycled_eventp)!= fyep); */
+ fy_eventp_free(fyep);
+ }
+
/* and the recycled tokens */
while ((fyt = fy_token_list_pop(&fyp->recycled_token)) != NULL)
fy_token_free(fyt);
int fy_scan_to_next_token(struct fy_parser *fyp)
{
int c, c_after_ws, i, rc = 0;
- bool tabs_allowed;
+ bool tabs_allowed, sloppy_flow, no_indent;
ssize_t offset;
struct fy_atom *handle;
struct fy_reader *fyr;
fyr = fyp->reader;
+ rc = fy_reader_input_scan_token_mark(fyr);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_reader_input_scan_token_mark() failed");
+
/* skip BOM at the start of the stream */
if (fyr->current_input_pos == 0 && (c = fy_parse_peek(fyp)) == FY_UTF8_BOM) {
goto done;
}
- for (;;) {
+ tabs_allowed = fyp->flow_level > 0 || !fyp->simple_key_allowed || fyp_tabsize(fyp) > 0;
+ sloppy_flow = fyp->flow_level > 0 && (fyp->cfg.flags & FYPCF_SLOPPY_FLOW_INDENTATION);
- tabs_allowed = fyp->flow_level || !fyp->simple_key_allowed;
+ for (;;) {
/* skip white space, tabs are allowed in flow context */
/* tabs also allowed in block context but not at start of line or after -?: */
- if (!fyp_tabsize(fyp) && !tabs_allowed) {
+ /* if we're not in sloppy flow indent mode, a tab may not be used as indentation */
+ if (!sloppy_flow) {
+ // fyp_notice(fyp, "not sloppy flow check c='%c' col=%d indent=%d\n", fy_parse_peek(fyp), fyp_column(fyp), fyp->indent);
+ c = -1;
+ while (fyp_column(fyp) <= fyp->indent && fy_is_ws(c = fy_parse_peek(fyp))) {
+ if (fy_is_tab(c))
+ break;
+ fy_advance(fyp, c);
+ }
+
+ /* it's an error, only if it is used for intentation */
+ /* comments and empty lines are OK */
+ if (fy_is_tab(c)) {
+
+ /* skip all space and tabs */
+ i = 0;
+ offset = -1;
+ while (fy_is_ws(c_after_ws = fy_parse_peek_at_internal(fyp, i, &offset)))
+ i++;
+
+ no_indent = c_after_ws == '#' || fyp_is_lb(fyp, c_after_ws);
+
+ FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN,
+ no_indent, err_out,
+ "tab character may not be used as indentation");
+
+ /* advance by that amount */
+ fy_advance_by(fyp, i);
+ }
+ }
+
+ if (!tabs_allowed) {
/* skip space only */
fy_reader_skip_space(fyr);
c = fy_parse_peek(fyp);
- /* if it's a tab, we need to see if after ws follows a flow start marker */
+ /* it's a tab, here we go */
if (fy_is_tab(c)) {
+ /* we need to see if after ws follows a flow start marker */
+
/* skip all space and tabs */
i = 0;
offset = -1;
rc = fy_scan_comment(fyp, handle, false);
fyp_error_check(fyp, !rc, err_out_rc,
"fy_scan_comment() failed");
+
+ tabs_allowed = (fyp->flow_level || !fyp->simple_key_allowed) || fyp_tabsize(fyp);
}
c = fy_parse_peek(fyp);
fy_advance(fyp, c);
/* may start simple key (in block ctx) */
- if (!fyp->flow_level) {
+ if (!fyp->flow_level && !fyp->simple_key_allowed) {
fyp->simple_key_allowed = true;
+ tabs_allowed = fyp->flow_level || !fyp->simple_key_allowed || fyp_tabsize(fyp);
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
}
}
fyp_scan_debug(fyp, "%s: no-next-token", __func__);
+ return 0;
+err_out:
+ rc = -1;
err_out_rc:
return rc;
done:
+ rc = fy_reader_input_scan_token_mark(fyr);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_reader_input_scan_token_mark() failed");
+
fyp_scan_debug(fyp, "%s: next token starts with c='%s'", __func__,
fy_utf8_format_a(fy_parse_peek(fyp), fyue_singlequote));
return 0;
"could not find expected ':'");
}
+static inline bool
+fy_any_simple_keys(struct fy_parser *fyp)
+{
+ return !fy_simple_key_list_empty(&fyp->simple_keys);
+}
+
static int fy_purge_stale_simple_keys(struct fy_parser *fyp, bool *did_purgep,
enum fy_token_type next_type)
{
fyp_scan_debug(fyp, "unrolling: %d/%d", fyp->indent, column);
/* create a block end token */
- fyt = fy_token_queue(fyp, FYTT_BLOCK_END, fy_fill_atom_a(fyp, 0));
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_BLOCK_END, 0);
fyp_error_check(fyp, fyt, err_out,
- "fy_token_queue() failed");
+ "fy_token_queue_simple() failed");
rc = fy_pop_indent(fyp);
fyp_error_check(fyp, !rc, err_out,
fyp_error_check(fyp, fyt && mark && end_mark, err_out,
"illegal arguments to fy_save_simple_key");
- rc = fy_purge_stale_simple_keys(fyp, &did_purge, next_type);
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_purge_stale_simple_keys() failed");
+ if (fy_any_simple_keys(fyp)) {
+ rc = fy_purge_stale_simple_keys(fyp, &did_purge, next_type);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_purge_stale_simple_keys() failed");
+ }
/* if no simple key is allowed, don't save */
if (!fyp->simple_key_allowed) {
fyp->simple_key_allowed = true;
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
- fyt = fy_token_queue(fyp, FYTT_STREAM_START, fy_fill_atom_a(fyp, 0));
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_STREAM_START, 0);
fyp_error_check(fyp, fyt, err_out,
- "fy_token_queue() failed");
+ "fy_token_queue_simple() failed");
return 0;
err_out:
fy_remove_all_simple_keys(fyp);
- rc = fy_parse_unroll_indent(fyp, -1);
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_parse_unroll_indent() failed");
+ if (fyp_block_mode(fyp)) {
+ rc = fy_parse_unroll_indent(fyp, -1);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_parse_unroll_indent() failed");
+ }
- fyt = fy_token_queue(fyp, FYTT_STREAM_END, fy_fill_atom_a(fyp, 0));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_STREAM_END, 0);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
return 0;
+err_out:
+ rc = -1;
err_out_rc:
return rc;
}
struct fy_token *fyt;
int i, lastc;
- if (!fy_parse_strcmp(fyp, "YAML")) {
- advance = 4;
+ if (!fy_parse_strcmp(fyp, "YAML") && fy_is_ws(fy_parse_peek_at(fyp, 4))) {
+ advance = 5;
type = FYTT_VERSION_DIRECTIVE;
- } else if (!fy_parse_strcmp(fyp, "TAG")) {
- advance = 3;
+ } else if (!fy_parse_strcmp(fyp, "TAG") && fy_is_ws(fy_parse_peek_at(fyp, 3))) {
+ advance = 4;
type = FYTT_TAG_DIRECTIVE;
} else {
/* skip until linebreak (or #) */
/* advance */
fy_advance_by(fyp, advance);
- /* the next must be space */
- c = fy_parse_peek(fyp);
-
- FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN,
- fy_is_ws(c), err_out,
- "missing space in %s directive",
- type == FYTT_VERSION_DIRECTIVE ? "YAML" : "TAG");
-
/* skip white space */
while (fy_is_ws(c = fy_parse_peek(fyp)))
fy_advance(fyp, c);
fy_remove_all_simple_keys(fyp);
- rc = fy_parse_unroll_indent(fyp, -1);
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_parse_unroll_indent() failed");
+ if (fyp_block_mode(fyp)) {
+ rc = fy_parse_unroll_indent(fyp, -1);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_parse_unroll_indent() failed");
+ }
rc = fy_scan_directive(fyp);
fyp_error_check(fyp, !rc, err_out_rc,
fy_remove_all_simple_keys(fyp);
- rc = fy_parse_unroll_indent(fyp, -1);
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_parse_unroll_indent() failed");
+ if (fyp_block_mode(fyp)) {
+ rc = fy_parse_unroll_indent(fyp, -1);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_parse_unroll_indent() failed");
+ }
fyp->simple_key_allowed = false;
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
- fyt = fy_token_queue(fyp, type, fy_fill_atom_a(fyp, 3));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, type, 3);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
/* skip whitespace after the indicator */
while (fy_is_ws(c = fy_parse_peek(fyp)))
return 0;
+err_out:
+ rc = -1;
err_out_rc:
return rc;
}
-static inline bool fy_flow_indent_check(struct fy_parser *fyp)
+static inline bool fy_flow_indent_check_internal(struct fy_parser *fyp, int column, int indent)
{
- return (!fyp->flow_level || fyp_column(fyp) > fyp->indent) ||
+ return (!fyp->flow_level || column > indent) ||
((fyp->cfg.flags & FYPCF_SLOPPY_FLOW_INDENTATION) && fyp->flow_level);
}
+static inline bool fy_flow_indent_check(struct fy_parser *fyp)
+{
+ return fy_flow_indent_check_internal(fyp, fyp_column(fyp), fyp->indent);
+}
+
static inline bool fy_block_indent_check(struct fy_parser *fyp)
{
return fyp->flow_level > 0 || fyp_column(fyp) > fyp->indent;
fy_get_simple_key_mark(fyp, &skm);
- fyt = fy_token_queue(fyp, type, fy_fill_atom_a(fyp, 1));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, type, 1);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
rc = fy_save_simple_key_mark(fyp, &skm, type, NULL);
fyp_error_check(fyp, !rc, err_out_rc,
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n",
fyp->simple_key_allowed ? "true" : "false");
- fyt = fy_token_queue(fyp, type, fy_fill_atom_a(fyp, 1));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, type, 1);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
if (fyp->parse_flow_only && fyp->flow_level == 0) {
rc = fy_fetch_stream_end(fyp);
/* we must be a key, purge */
if (c == ':') {
- rc = fy_purge_stale_simple_keys(fyp, &did_purge, type);
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_purge_stale_simple_keys() failed");
+ if (fy_any_simple_keys(fyp)) {
+ rc = fy_purge_stale_simple_keys(fyp, &did_purge, type);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_purge_stale_simple_keys() failed");
- /* if we did purge and the the list is now empty, we're hosed */
- if (did_purge && fy_simple_key_list_empty(&fyp->simple_keys)) {
- FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN,
- "invalid multiline flow %s key ", typestr);
- goto err_out;
+ /* if we did purge and the the list is now empty, we're hosed */
+ if (did_purge && fy_simple_key_list_empty(&fyp->simple_keys)) {
+ FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN,
+ "invalid multiline flow %s key ", typestr);
+ goto err_out;
+ }
}
}
/* transform '? a,' to '? a: ,' */
if (fyp->pending_complex_key_column >= 0) {
- fyt = fy_token_queue(fyp, FYTT_VALUE, fy_fill_atom_a(fyp, 0));
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_VALUE, 0);
fyp_error_check(fyp, fyt, err_out,
- "fy_token_queue() failed");
+ "fy_token_queue_simple() failed");
fyp->pending_complex_key_column = -1;
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
fyt_last = fy_token_list_tail(&fyp->queued_tokens);
- fyt = fy_token_queue(fyp, type, fy_fill_atom_a(fyp, 1));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, type, 1);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
/* the comment indicator must have at least a space */
c = fy_parse_peek(fyp);
struct fy_mark mark;
struct fy_simple_key *fysk;
struct fy_token *fyt;
+ int adv, tab_adv;
+ bool indentation, found_tab;
fyp_error_check(fyp, c == '-', err_out,
"illegal block entry");
/* we have to save the start mark */
fy_get_mark(fyp, &mark);
- if (!fyp->flow_level && fyp->indent < fyp_column(fyp)) {
+ if (fyp_block_mode(fyp) && fyp->indent < fyp_column(fyp)) {
/* push the new indent level */
rc = fy_push_indent(fyp, fyp_column(fyp), false, fyp_line(fyp));
fyp_error_check(fyp, !rc, err_out_rc,
"fy_push_indent() failed");
- fyt = fy_token_queue_internal(fyp, &fyp->queued_tokens,
- FYTT_BLOCK_SEQUENCE_START, fy_fill_atom_a(fyp, 0));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue_internal() failed");
+ fyt = fy_token_queue_simple_internal(fyp, &fyp->queued_tokens, FYTT_BLOCK_SEQUENCE_START, 0);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple_internal() failed");
}
if (c == '-' && fyp->flow_level) {
fyp->simple_key_allowed = true;
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
- fyt = fy_token_queue(fyp, FYTT_BLOCK_ENTRY, fy_fill_atom_a(fyp, 1));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_BLOCK_ENTRY, 1);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
/* special case for allowing whitespace (including tabs) after - */
- if (fy_is_ws(c = fy_parse_peek(fyp)))
+ found_tab = false;
+
+ /* scan forward, keeping track if we found a tab */
+ adv = 0;
+ tab_adv = -1;
+ while (fy_is_ws(c = fy_parse_peek_at(fyp, adv))) {
+ if (!found_tab && fy_is_tab(c)) {
+ found_tab = true;
+ tab_adv = adv;
+ }
+ adv++;
+ }
+
+ if (found_tab) {
+ indentation = fy_utf8_strchr("?:|>", c) ||
+ (c == '-' && fyp_is_blankz(fyp, fy_parse_peek_at(fyp, adv + 1)));
+
+ /* any kind of block indentation is not allowed */
+ FYP_PARSE_ERROR_CHECK(fyp, tab_adv, 1, FYEM_SCAN,
+ !indentation, err_out,
+ "cannot use tab for indentation of block entry");
+ fy_advance_by(fyp, tab_adv + 1);
+ }
+
+ /* now chomp spaces only afterwards */
+ while (fy_is_space(c = fy_parse_peek(fyp)))
fy_advance(fyp, c);
return 0;
fyp->flow_level || fyp->simple_key_allowed, err_out,
"invalid mapping key (not allowed in this context)");
- if (!fyp->flow_level && fyp->indent < fyp_column(fyp)) {
+ if (fyp_block_mode(fyp) && fyp->indent < fyp_column(fyp)) {
/* push the new indent level */
rc = fy_push_indent(fyp, fyp_column(fyp), true, fyp_line(fyp));
fyp_error_check(fyp, !rc, err_out_rc,
"fy_push_indent() failed");
- fyt = fy_token_queue_internal(fyp, &fyp->queued_tokens,
- FYTT_BLOCK_MAPPING_START, fy_fill_atom_a(fyp, 0));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue_internal() failed");
+ fyt = fy_token_queue_simple_internal(fyp, &fyp->queued_tokens, FYTT_BLOCK_MAPPING_START, 0);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple_internal() failed");
}
rc = fy_remove_simple_key(fyp, FYTT_KEY);
fyp_scan_debug(fyp, "pending_complex_key_column %d",
fyp->pending_complex_key_column);
- fyt = fy_token_queue(fyp, FYTT_KEY, fy_fill_atom_a(fyp, 1), fyp->flow_level);
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_KEY, 1);
fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ "fy_token_queue_simple() failed");
+ /* extra KEY data */
+ fyt->key.flow_level = fyp->flow_level;
fyp->simple_key_allowed = target_simple_key_allowed;
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
struct fy_simple_key *fysk = NULL;
struct fy_mark mark, mark_insert, mark_end_insert;
struct fy_token *fyt_insert, *fyt;
- struct fy_atom handle;
bool target_simple_key_allowed, is_complex, has_bmap;
bool push_bmap_start, push_key_only, did_purge, final_complex_key;
bool is_multiline __FY_DEBUG_UNUSED__;
"JSON considers keys when not in mapping context invalid");
/* special handling for :: weirdness */
- fyp->colon_follows_colon = fyp->flow_level > 0 && fy_parse_peek_at(fyp, 1) == ':';
+ if (!fyp_json_mode(fyp) && fyp->flow_level > 0) {
+ int adv, nextc, nextcol, tabsize, indent;
+
+ /* this requires some explanation...
+ * we need to detect x::x, x: :x, and x:\n:x as the same
+ */
+ adv = 1;
+ indent = fyp->indent;
+ nextcol = fyp_column(fyp) + 1;
+ tabsize = fyp_tabsize(fyp);
+
+ while ((nextc = fy_parse_peek_at(fyp, adv)) > 0) {
+
+ if (fyp_is_lb(fyp, nextc))
+ nextcol = 0;
+ else if (fy_is_tab(nextc)) {
+ if (tabsize)
+ nextcol += tabsize - (nextcol % tabsize);
+ else
+ nextcol++;
+ } else if (fy_is_space(nextc))
+ nextcol++;
+ else {
+ if (!fy_flow_indent_check_internal(fyp, nextcol, indent))
+ nextc = -1;
+ break;
+ }
+
+ adv++;
+ }
+
+ fyp->colon_follows_colon = nextc == ':';
+ } else
+ fyp->colon_follows_colon = false;
fy_get_mark(fyp, &mark);
fy_flow_indent_check(fyp), err_out,
"wrongly indented mapping value in flow mode");
- rc = fy_purge_stale_simple_keys(fyp, &did_purge, FYTT_VALUE);
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_purge_stale_simple_keys() failed");
+ if (fy_any_simple_keys(fyp)) {
+ rc = fy_purge_stale_simple_keys(fyp, &did_purge, FYTT_VALUE);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_purge_stale_simple_keys() failed");
+ }
/* get the simple key (if available) for the value */
fysk = fy_simple_key_list_head(&fyp->simple_keys);
fyp_error_check(fyp, !rc, err_out_rc,
"fy_push_indent() failed");
- fy_fill_atom_start(fyp, &handle);
- fy_fill_atom_end(fyp, &handle);
-
- handle.start_mark = handle.end_mark = mark_insert;
+ fyt = fy_token_queue_simple_internal(fyp, &sk_tl, FYTT_BLOCK_MAPPING_START, 0);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple_internal() failed");
- /* and the block mapping start */
- fyt = fy_token_queue_internal(fyp, &sk_tl, FYTT_BLOCK_MAPPING_START, &handle);
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue_internal() failed");
+ /* update with this mark */
+ fyt->handle.start_mark = fyt->handle.end_mark = mark_insert;
}
if (push_bmap_start || push_key_only) {
- fyt = fy_token_queue_internal(fyp, &sk_tl, FYTT_KEY, fy_fill_atom_a(fyp, 0), fyp->flow_level);
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue_internal() failed");
+ fyt = fy_token_queue_simple_internal(fyp, &sk_tl, FYTT_KEY, 0);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple_internal() failed");
+ /* update with the flow level */
+ fyt->key.flow_level = fyp->flow_level;
}
fyp_debug_dump_token(fyp, fyt_insert, "insert-token: ");
target_simple_key_allowed = fysk ? false : !fyp->flow_level;
- fyt = fy_token_queue(fyp, FYTT_VALUE, fy_fill_atom_a(fyp, 1));
- fyp_error_check(fyp, fyt, err_out_rc,
- "fy_token_queue() failed");
+ fyt = fy_token_queue_simple(fyp, &fyp->queued_tokens, FYTT_VALUE, 1);
+ fyp_error_check(fyp, fyt, err_out,
+ "fy_token_queue_simple() failed");
fyp->simple_key_allowed = target_simple_key_allowed;
fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false");
}
int fy_scan_block_scalar_indent(struct fy_parser *fyp, int indent, int *breaks, int *breaks_length,
- int *presentation_breaks_length, int *first_break_length)
+ int *presentation_breaks_length, int *first_break_length, int *lastc)
{
int c, max_indent = 0, min_indent, break_length;
/* skip over indentation */
if (!fyp_tabsize(fyp)) {
- while ((c = fy_parse_peek(fyp)) == ' ' &&
- (!indent || fyp_column(fyp) < indent))
+ /* we must respect the enclosed indent */
+ while (fyp_column(fyp) <= fyp->indent && fy_is_ws(c = fy_parse_peek(fyp))) {
+ FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN,
+ !fy_is_tab(c), err_out,
+ "invalid tab character as indent instead of space");
fy_advance(fyp, c);
+ }
- FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN,
- c != '\t' || !(!indent && fyp_column(fyp) < indent), err_out,
- "invalid tab character as indent instead of space");
+ /* skip over spaces only */
+ while ((c = fy_parse_peek(fyp)) == ' ' &&
+ (!indent || fyp_column(fyp) < indent)) {
+ fy_advance(fyp, c);
+ }
} else {
while (fy_is_ws((c = fy_parse_peek(fyp))) &&
(!indent || fyp_column(fyp) < indent))
if (fyp_column(fyp) > max_indent)
max_indent = fyp_column(fyp);
- /* non-empty line? */
- if (!fyp_is_lb(fyp, c))
+ /* non-empty line or EOF */
+ if (!fyp_is_lb(fyp, c)) {
+ *lastc = c;
break;
+ }
fy_advance(fyp, c);
int breaks, breaks_length, presentation_breaks_length, first_break_length;
bool doc_start_end_detected, empty, empty_line, prev_empty_line, indented, prev_indented, first;
bool has_ws, has_lb, starts_with_ws, starts_with_lb, ends_with_ws, ends_with_lb, trailing_lb;
- bool pending_nl;
+ bool pending_nl, ends_with_eof, starts_with_eof;
struct fy_token *fyt;
size_t length, line_length, trailing_ws, trailing_breaks_length;
size_t leading_ws;
fy_fill_atom_start(fyp, &handle);
+ starts_with_eof = c < 0;
+
current_indent = fyp->indent >= 0 ? fyp->indent : 0;
indent = increment ? current_indent + increment : 0;
ends_with_lb = false;
trailing_lb = false;
- new_indent = fy_scan_block_scalar_indent(fyp, indent, &breaks, &breaks_length, &presentation_breaks_length, &first_break_length);
+ new_indent = fy_scan_block_scalar_indent(fyp, indent, &breaks, &breaks_length, &presentation_breaks_length, &first_break_length, &lastc);
fyp_error_check(fyp, new_indent >= 0, err_out,
"fy_scan_block_scalar_indent() failed");
length = breaks_length;
length += presentation_breaks_length;
-
indent = new_indent;
doc_start_end_detected = false;
chomp_amt = increment ? (unsigned int)(current_indent + increment) : (unsigned int)-1;
actual_lb_length = 1;
- lastc = -1;
while ((c = fy_parse_peek(fyp)) > 0 && fyp_column(fyp) >= indent) {
lastc = c;
fy_advance(fyp, c);
has_lb = true;
- new_indent = fy_scan_block_scalar_indent(fyp, indent, &breaks, &breaks_length, &presentation_breaks_length, &first_break_length);
+ new_indent = fy_scan_block_scalar_indent(fyp, indent, &breaks, &breaks_length, &presentation_breaks_length, &first_break_length, &lastc);
fyp_error_check(fyp, new_indent >= 0, err_out,
"fy_scan_block_scalar_indent() failed");
if (fy_is_lb_LS_PS(c))
} else {
has_lb = false;
new_indent = indent;
- chomp = FYAC_STRIP;
+ // was chomp = FYAC_STRIP, very very wrong
breaks = 0;
breaks_length = 0;
first_break_length = 0;
actual_lb_length = 0;
+
}
if (is_literal) {
length += prefix_length + line_length + suffix_length;
-
indent = new_indent;
prev_empty_line = empty_line;
goto err_out;
}
+ /* are we ended with EOF? */
+ ends_with_eof = starts_with_eof || (c == FYUG_EOF && !fyp_is_lb(fyp, lastc) && !breaks);
+
/* detect wrongly indented block scalar */
if (c != FYUG_EOF && !(!empty || fyp_column(fyp) <= fyp->indent || c == '#' || doc_start_end_detected)) {
FYP_MARK_ERROR(fyp, &handle.start_mark, &handle.end_mark, FYEM_SCAN,
switch (chomp) {
case FYAC_CLIP:
- if (pending_nl) {
+ if (pending_nl || (!starts_with_eof && ends_with_eof)) {
if (actual_lb_length <= 2)
length += 1;
else
ends_with_ws = true;
}
break;
- case FYAC_KEEP: {
- length += (pending_nl ? actual_lb_length : 0) + breaks + presentation_breaks_length;
+ case FYAC_KEEP:
+ if (pending_nl || (!starts_with_eof && ends_with_eof))
+ length += actual_lb_length;
+
+ length += breaks + presentation_breaks_length;
trailing_lb = trailing_breaks_length > 0;
- if (pending_nl || trailing_breaks_length) {
+ if (pending_nl || (!starts_with_eof && ends_with_eof) || trailing_breaks_length) {
ends_with_lb = true;
ends_with_ws = false;
} else if (fy_is_ws(lastc)) {
ends_with_ws = true;
ends_with_lb = false;
}
- }
break;
case FYAC_STRIP:
ends_with_lb = false;
handle.lb_mode = fyp_lb_mode(fyp);
handle.fws_mode = fyp_fws_mode(fyp);
handle.tabsize = fyp_tabsize(fyp);
+ handle.ends_with_eof = ends_with_eof;
#ifdef ATOM_SIZE_CHECK
tlength = fy_atom_format_text_length(&handle);
{
size_t length;
int code_length, i = 0, j, end_c, last_line, lastc;
- int breaks_found, blanks_found, break_run, total_code_length, total_digits;
+ int breaks_found, blanks_found, break_run, total_code_length;
int breaks_found_length, first_break_length, value;
uint32_t hi_surrogate, lo_surrogate;
bool is_single, is_multiline, esc_lb, ws_lb_only, has_ws, has_lb, has_esc;
if (unicode_esc) {
total_code_length = 0;
- total_digits = 0;
j = 0;
hi_surrogate = lo_surrogate = 0;
for (;;) {
}
total_code_length += code_length;
- total_digits += code_length;
j++;
/* 0x10000 + (HI - 0xd800) * 0x400 + (LO - 0xdc00) */
break_run = 0;
+ /* check for tab used as indentation */
+ if (!fy_reader_tabsize(fyr) && fy_is_tab(c)) {
+ FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_SCAN,
+ fy_reader_column(fyr) > indent, err_out,
+ "invalid tab used as indentation");
+ }
+
fy_reader_advance(fyr, c);
if (fy_reader_is_lb(fyr, c)) {
handle->ends_with_lb = ends_with_lb;
handle->trailing_lb = trailing_lb;
handle->size0 = length == 0;
+ handle->valid_anchor = false;
+ handle->json_mode = fy_reader_json_mode(fyr);
+ handle->lb_mode = fy_reader_lb_mode(fyr);
+ handle->fws_mode = fy_reader_flow_ws_mode(fyr);
handle->tabsize = fy_reader_tabsize(fyr);
+ handle->ends_with_eof = false; /* flow scalars never end with EOF and be valid */
/* skip over block scalar end */
fy_reader_advance_by(fyr, 1);
bool has_leading_blanks;
bool last_ptr;
struct fy_mark mark, last_mark;
- bool is_multiline, has_lb, has_ws;
+ bool is_multiline, has_lb, has_ws, ends_with_eof;
bool has_json_esc;
#ifdef ATOM_SIZE_CHECK
size_t tlength;
flow_level > 0 || !((c == '?' || c == ':') && fy_reader_is_blank_at_offset(fyr, 1)), err_out,
"plain scalar cannot start with '%c' followed by blank (in block context)", c);
+ /* may not start with - followed by ",[]{}" in flow context */
+ FYR_PARSE_ERROR_CHECK(fyr, 0, 2, FYEM_SCAN,
+ flow_level == 0 || !(c == '-' && fy_utf8_strchr(",[]{}", fy_reader_peek_at(fyr, 1))), err_out,
+ "plain scalar cannot start with '%c' followed by ,[]{} (in flow context)", c);
+
fy_reader_get_mark(fyr, &mark);
fy_reader_fill_atom_start(fyr, handle);
if (fy_reader_is_blankz(fyr, nextc)) {
/* super rare case :: not followed by space */
/* :: not followed by space */
- if (lastc != ':' || fy_is_ws(nextc))
+ if (lastc != ':' || fy_reader_is_blankz(fyr, nextc))
break;
}
"plain scalar is malformed UTF8");
goto err_out;
}
+ ends_with_eof = c == FYUG_EOF && !fy_reader_is_lb(fyr, lastc);
is_multiline = handle->end_mark.line > handle->start_mark.line;
handle->lb_mode = fy_reader_lb_mode(fyr);
handle->fws_mode = fy_reader_flow_ws_mode(fyr);
handle->tabsize = fy_reader_tabsize(fyr);
+ handle->ends_with_eof = ends_with_eof;
#ifdef ATOM_SIZE_CHECK
tlength = fy_atom_format_text_length(handle);
struct fy_atom handle;
struct fy_simple_key_mark skm;
struct fy_token *fyt;
- bool is_multiline, is_complex;
+ bool is_multiline, is_complex, is_tab_start = false;
+ struct fy_mark tab_mark;
int rc = -1, i;
- /* may not start with blankz */
- FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN,
- !(fyp->state == FYPS_BLOCK_MAPPING_VALUE && fy_is_tab(c)), err_out,
- "invalid tab as indendation in a mapping");
+ /* Extremely bad case, a tab... so, either an indentation or separation space in block mode */
+ if (!fyp->flow && fy_is_tab(c)) {
+
+ fy_get_mark(fyp, &tab_mark);
+ is_tab_start = true;
+
+ /* skip all whitespace now */
+ fy_reader_skip_ws(fyp->reader);
+ c = fy_parse_peek(fyp);
+
+ /* if it's a linebreak or a comment start, just try again */
+ if (fyp_is_lb(fyp, c) || c == '#') {
+ /* will need to scan more */
+ fyp->token_activity_counter++;
+ return 0;
+ }
+ }
/* check indentation */
FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN,
return 0;
}
- if (is_multiline && !fyp->flow_level && !is_complex) {
+ if (!fyp->flow_level && !is_complex && (is_multiline || is_tab_start)) {
/* due to the weirdness with simple keys scan forward
- * until a linebreak, ';', or anything else */
+ * until a linebreak, ':', or anything else */
for (i = 0; ; i++) {
c = fy_parse_peek_at(fyp, i);
if (c < 0 || (c == ':' && fy_is_blankz_at_offset(fyp, i + 1)) ||
/* if we're a key, that's invalid */
if (c == ':') {
- FYP_MARK_ERROR(fyp, &handle.start_mark, &handle.end_mark, FYEM_SCAN,
- "invalid multiline plain key");
+
+ if (is_multiline)
+ FYP_MARK_ERROR(fyp, &handle.start_mark, &handle.end_mark, FYEM_SCAN,
+ "invalid multiline plain key");
+ else
+ FYP_MARK_ERROR(fyp, &tab_mark, &tab_mark, FYEM_SCAN,
+ "invalid tab as indendation in a mapping");
+
goto err_out;
}
}
fyp_error_check(fyp, !rc, err_out_rc,
"fy_scan_to_next_token() failed");
- rc = fy_parse_unroll_indent(fyp, fyp_column(fyp));
- fyp_error_check(fyp, !rc, err_out_rc,
- "fy_parse_unroll_indent() failed");
+ if (fyp_block_mode(fyp)) {
+ rc = fy_parse_unroll_indent(fyp, fyp_column(fyp));
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_parse_unroll_indent() failed");
+ }
c = fy_parse_peek(fyp);
if (c < 0 || c == '\0') {
return NULL;
}
-struct fy_token *fy_scan_remove(struct fy_parser *fyp, struct fy_token *fyt)
+static inline struct fy_token *
+fy_scan_remove(struct fy_parser *fyp, struct fy_token *fyt)
{
if (!fyp || !fyt)
return NULL;
return fyt;
}
-struct fy_token *fy_scan_remove_peek(struct fy_parser *fyp, struct fy_token *fyt)
+static inline struct fy_token *
+fy_scan_remove_peek(struct fy_parser *fyp, struct fy_token *fyt)
{
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fy_scan_remove(fyp, fyt));
+ if (fyt != NULL) {
+ (void)fy_scan_remove(fyp, fyt);
+ fy_token_unref_rl(fyp->recycled_token_list, fyt);
+ }
return fy_scan_peek(fyp);
}
void fy_scan_token_free(struct fy_parser *fyp, struct fy_token *fyt)
{
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt);
+ fy_token_unref_rl(fyp->recycled_token_list, fyt);
}
int fy_parse_state_push(struct fy_parser *fyp, enum fy_parser_state state)
struct fy_token *anchor = NULL, *tag = NULL;
const char *handle;
size_t handle_size;
- struct fy_atom atom;
struct fy_token *fyt_td;
+ struct fy_token *fytn;
fyds = fyp->current_document_state;
assert(fyds);
fye->sequence_start.anchor = anchor;
fye->sequence_start.tag = tag;
- atom = fyt->handle;
- atom.end_mark = atom.start_mark; /* no extent */
- fye->sequence_start.sequence_start = fy_token_create_rl(fy_parse_recycled_token(fyp), FYTT_BLOCK_SEQUENCE_START, &atom);
- fyp_error_check(fyp, fye->sequence_start.sequence_start, err_out,
- "fy_token_create_rl() failed!");
+ /* allocate and copy in place */
+ fytn = fy_token_alloc_rl(fyp->recycled_token_list);
+ fyp_error_check(fyp, fytn, err_out,
+ "fy_token_alloc_rl() failed!");
+ fytn->type = FYTT_BLOCK_SEQUENCE_START;
+ fytn->handle = fyt->handle;
+ fytn->handle.end_mark = fytn->handle.start_mark; /* no extent */
+ fy_input_ref(fytn->handle.fyi);
+
+ fye->sequence_start.sequence_start = fytn;
fy_parse_state_set(fyp, FYPS_INDENTLESS_SEQUENCE_ENTRY);
goto return_ok;
return fyep;
err_out:
- fy_token_unref_rl(fy_parse_recycled_token(fyp), anchor);
- fy_token_unref_rl(fy_parse_recycled_token(fyp), tag);
+ fy_token_unref_rl(fyp->recycled_token_list, anchor);
+ fy_token_unref_rl(fyp->recycled_token_list, tag);
fy_parse_eventp_recycle(fyp, fyep);
return NULL;
fy_parse_parse_state_log_list_recycle_all(fyp, &fyp->state_stack);
fy_parse_flow_list_recycle_all(fyp, &fyp->flow_stack);
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyp->stream_end_token);
+ fy_token_unref_rl(fyp->recycled_token_list, fyp->stream_end_token);
fyp->stream_end_token = NULL;
return 0;
int fy_parse_stream_end(struct fy_parser *fyp)
{
- fy_token_unref_rl(fy_parse_recycled_token(fyp), fyp->stream_end_token);
+ fy_token_unref_rl(fyp->recycled_token_list, fyp->stream_end_token);
fyp->stream_end_token = NULL;
return 0;
enum fy_parser_state orig_state;
struct fy_token *version_directive;
struct fy_token_list tag_directives;
- struct fy_atom atom;
const struct fy_mark *fym;
+ struct fy_token *fytn;
char tbuf[16] __FY_DEBUG_UNUSED__;
int rc;
fyp_error_check(fyp, !rc, err_out,
"failed to fy_parse_state_push()");
+ // update document state with json mode
+ fyds->json_mode = fyp_json_mode(fyp);
fye->document_start.document_state = fy_document_state_ref(fyds);
fye->document_start.implicit = fyds->start_implicit;
fye->type = FYET_SEQUENCE_END;
if (orig_state == FYPS_INDENTLESS_SEQUENCE_ENTRY) {
- atom = fyt->handle;
- atom.end_mark = atom.start_mark;
- fye->sequence_end.sequence_end = fy_token_create_rl(fy_parse_recycled_token(fyp), FYTT_BLOCK_END, &atom);
- fyp_error_check(fyp, fye->sequence_end.sequence_end, err_out,
- "fy_token_create_rl() failed!");
+
+ /* allocate and copy in place */
+ fytn = fy_token_alloc_rl(fyp->recycled_token_list);
+ fyp_error_check(fyp, fytn, err_out,
+ "fy_token_alloc_rl() failed!");
+ fytn->type = FYTT_BLOCK_END;
+ fytn->handle = fyt->handle;
+ fytn->handle.end_mark = fytn->handle.start_mark; /* no extent */
+ fy_input_ref(fytn->handle.fyi);
+
+ fye->sequence_end.sequence_end = fytn;
} else
fye->sequence_end.sequence_end = fy_scan_remove(fyp, fyt);
fye->type = FYET_MAPPING_END;
- atom = fyt->handle;
- atom.end_mark = atom.start_mark;
- fye->mapping_end.mapping_end = fy_token_create_rl(fy_parse_recycled_token(fyp), FYTT_BLOCK_END, &atom);
- fyp_error_check(fyp, fye->mapping_end.mapping_end, err_out,
- "fy_token_create_rl() failed!");
+ /* allocate and copy in place */
+ fytn = fy_token_alloc_rl(fyp->recycled_token_list);
+ fyp_error_check(fyp, fytn, err_out,
+ "fy_token_alloc_rl() failed!");
+ fytn->type = FYTT_BLOCK_END;
+ fytn->handle = fyt->handle;
+ fytn->handle.end_mark = fytn->handle.start_mark; /* no extent */
+ fy_input_ref(fytn->handle.fyi);
+
+ fye->mapping_end.mapping_end = fytn;
return fyep;
}
err_out:
- fy_token_unref_rl(fy_parse_recycled_token(fyp), version_directive);
- fy_token_list_unref_all_rl(fy_parse_recycled_token(fyp), &tag_directives);
+ fy_token_unref_rl(fyp->recycled_token_list, version_directive);
+ fy_token_list_unref_all_rl(fyp->recycled_token_list, &tag_directives);
fy_parse_eventp_recycle(fyp, fyep);
fyp->stream_error = true;
return NULL;
fyic.type = fyit_stream;
fyic.stream.name = "stdin";
fyic.stream.fp = stdin;
- fyic.stream.ignore_stdio = !!(fyp->cfg.flags & FYPCF_DISABLE_BUFFERING);
} else {
fyic.type = fyit_file;
fyic.file.filename = file;
}
+ fyic.ignore_stdio = !!(fyp->cfg.flags & FYPCF_DISABLE_BUFFERING);
/* must not be in the middle of something */
fyp_error_check(fyp, fyp->state == FYPS_NONE || fyp->state == FYPS_END,
fyic.type = fyit_stream;
fyic.stream.name = name ? : "<stream>";
fyic.stream.fp = fp;
- fyic.stream.ignore_stdio = !!(fyp->cfg.flags & FYPCF_DISABLE_BUFFERING);
+ fyic.ignore_stdio = !!(fyp->cfg.flags & FYPCF_DISABLE_BUFFERING);
/* must not be in the middle of something */
fyp_error_check(fyp, fyp->state == FYPS_NONE || fyp->state == FYPS_END,
fyic.type = fyit_callback;
fyic.userdata = user;
fyic.callback.input = callback;
+ fyic.ignore_stdio = !!(fyp->cfg.flags & FYPCF_DISABLE_BUFFERING);
+
+ /* must not be in the middle of something */
+ fyp_error_check(fyp, fyp->state == FYPS_NONE || fyp->state == FYPS_END,
+ err_out, "parser cannot be reset at state '%s'",
+ state_txt[fyp->state]);
+
+ fy_parse_input_reset(fyp);
+
+ rc = fy_parse_input_append(fyp, &fyic);
+ fyp_error_check(fyp, !rc, err_out_rc,
+ "fy_parse_input_append() failed");
+
+ return 0;
+err_out:
+ rc = -1;
+err_out_rc:
+ return rc;
+}
+
+int fy_parser_set_input_fd(struct fy_parser *fyp, int fd)
+{
+ struct fy_input_cfg fyic;
+ int rc;
+
+ if (!fyp || fd < 0)
+ return -1;
+
+ memset(&fyic, 0, sizeof(fyic));
+
+ fyic.type = fyit_fd;
+ fyic.fd.fd = fd;
+ fyic.ignore_stdio = !!(fyp->cfg.flags & FYPCF_DISABLE_BUFFERING);
/* must not be in the middle of something */
fyp_error_check(fyp, fyp->state == FYPS_NONE || fyp->state == FYPS_END,
return NULL;
if (fyp->fyc) {
- ret = fy_composer_process_event(fyp->fyc, fyp, &fyep->e);
+ ret = fy_composer_process_event(fyp->fyc, &fyep->e);
if (ret == FYCR_ERROR) {
fyp->stream_error = true;
fy_parse_eventp_recycle(fyp, fyep);
}
static enum fy_composer_return
-parse_process_event(struct fy_composer *fyc, struct fy_path *path, struct fy_parser *fyp, struct fy_event *fye)
+parse_process_event(struct fy_composer *fyc, struct fy_path *path, struct fy_event *fye)
{
- if (!fyp->fyc_cb)
- return 0;
+ struct fy_parser *fyp = fy_composer_get_cfg_userdata(fyc);
- return fyp->fyc_cb(fyp, fye, path, fy_composer_get_cfg_userdata(fyc));
+ assert(fyp);
+ assert(fyp->fyc_cb);
+ return fyp->fyc_cb(fyp, fye, path, fyp->fyc_userdata);
+}
+
+struct fy_document_builder *
+parse_create_document_builder(struct fy_composer *fyc)
+{
+ struct fy_parser *fyp = fy_composer_get_cfg_userdata(fyc);
+ struct fy_document_builder *fydb = NULL;
+ struct fy_document_builder_cfg cfg;
+ struct fy_document_state *fyds;
+ int rc;
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.parse_cfg = fyp->cfg;
+ cfg.diag = fy_diag_ref(fyp->diag);
+
+ fydb = fy_document_builder_create(&cfg);
+ fyp_error_check(fyp, fydb, err_out,
+ "fy_document_builder_create() failed\n");
+
+ /* start with this document state */
+ fyds = fy_parser_get_document_state(fyp);
+ rc = fy_document_builder_set_in_document(fydb, fyds, true);
+ fyp_error_check(fyp, !rc, err_out,
+ "fy_document_builder_set_in_document() failed\n");
+
+ return fydb;
+
+err_out:
+ fy_document_builder_destroy(fydb);
+ return NULL;
}
static const struct fy_composer_ops parser_composer_ops = {
.process_event = parse_process_event,
+ .create_document_builder = parse_create_document_builder,
};
int fy_parse_set_composer(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata)
fyp->fyc = NULL;
}
fyp->fyc_cb = NULL;
+ fyp->fyc_userdata = NULL;
return 0;
}
/* already exists */
if (fyp->fyc) {
fyp->fyc_cb = cb;
+ fyp->fyc_userdata = userdata;
return 0;
}
/* prepare the composer configuration */
memset(&ccfg, 0, sizeof(ccfg));
ccfg.ops = &parser_composer_ops;
- ccfg.userdata = userdata;
+ ccfg.userdata = fyp;
ccfg.diag = fy_parser_get_diag(fyp);
fyp->fyc = fy_composer_create(&ccfg);
fyp_error_check(fyp, fyp->fyc, err_out,
"fy_composer_create() failed");
fyp->fyc_cb = cb;
+ fyp->fyc_userdata = userdata;
return 0;
err_out:
return -1;
}
-int fy_parse_compose(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata)
+static enum fy_composer_return fy_parse_compose_internal(struct fy_parser *fyp)
{
+ struct fy_composer *fyc;
+ struct fy_document_iterator *fydi;
+ struct fy_event *fye;
struct fy_eventp *fyep;
+ struct fy_document *fyd = NULL;
enum fy_composer_return ret;
- int rc;
- if (!fyp || !cb)
- return -1;
+ assert(fyp);
- /* set the composer callback */
- rc = fy_parse_set_composer(fyp, cb, userdata);
- fyp_error_check(fyp, !rc, err_out,
- "fy_parse_set_composer() failed\n");
+ fyc = fyp->fyc;
+ assert(fyc);
+
+ /* simple, without resolution */
+ if (!(fyp->cfg.flags & FYPCF_RESOLVE_DOCUMENT)) {
+
+ ret = FYCR_OK_STOP;
+ while ((fyep = fy_parse_private(fyp)) != NULL) {
+ ret = fy_composer_process_event(fyc, &fyep->e);
+ fy_parse_eventp_recycle(fyp, fyep);
+ if (ret != FYCR_OK_CONTINUE)
+ break;
+ }
+ return ret;
+ }
- /* insane but check anyway */
- assert(fyp->fyc);
+ fydi = fy_document_iterator_create();
+ fyp_error_check(fyp, fydi, err_out,
+ "fy_document_iterator_create() failed");
- /* pump events */
- rc = 0;
- while ((fyep = fy_parse_private(fyp)) != NULL) {
+ /* stream start event generation and processing */
+ fye = fy_document_iterator_stream_start(fydi);
+ fyp_error_check(fyp, fye, err_out,
+ "fy_document_iterator_stream_start() failed");
+ ret = fy_composer_process_event(fyc, fye);
+ fy_document_iterator_event_free(fydi, fye);
+ fye = NULL;
+ if (ret != FYCR_OK_CONTINUE)
+ goto out;
- /* call the composer */
- ret = fy_composer_process_event(fyp->fyc, fyp, &fyep->e);
- fy_parse_eventp_recycle(fyp, fyep);
+ /* convert to document and then process the generator event stream it */
+ while ((fyd = fy_parse_load_document(fyp)) != NULL) {
+
+ /* document start event generation and processing */
+ fye = fy_document_iterator_document_start(fydi, fyd);
+ fyp_error_check(fyp, fye, err_out,
+ "fy_document_iterator_document_start() failed");
+ ret = fy_composer_process_event(fyc, fye);
+ fy_document_iterator_event_free(fydi, fye);
+ fye = NULL;
+ if (ret != FYCR_OK_CONTINUE)
+ goto out;
- /* on error stop */
- if (ret == FYCR_ERROR) {
- fyp->stream_error = true;
- rc = -1;
- break;
+ /* and now process the body */
+ ret = FYCR_OK_CONTINUE;
+ while ((fye = fy_document_iterator_body_next(fydi)) != NULL) {
+ ret = fy_composer_process_event(fyc, fye);
+ fy_document_iterator_event_free(fydi, fye);
+ fye = NULL;
+ if (ret != FYCR_OK_CONTINUE)
+ goto out;
}
- /* on normal requested stop, stop */
- if (ret == FYCR_OK_STOP)
- break;
+ /* document end event generation and processing */
+ fye = fy_document_iterator_document_end(fydi);
+ fyp_error_check(fyp, fye, err_out,
+ "fy_document_iterator_document_end() failed");
+ ret = fy_composer_process_event(fyc, fye);
+ fy_document_iterator_event_free(fydi, fye);
+ fye = NULL;
+ if (ret != FYCR_OK_CONTINUE)
+ goto out;
+
+ /* and destroy the document */
+ fy_parse_document_destroy(fyp, fyd);
+ fyd = NULL;
}
+ /* stream end event generation and processing */
+ fye = fy_document_iterator_stream_end(fydi);
+ fyp_error_check(fyp, fye, err_out,
+ "fy_document_iterator_stream_end() failed");
+ ret = fy_composer_process_event(fyc, fye);
+ fy_document_iterator_event_free(fydi, fye);
+ fye = NULL;
+ if (ret != FYCR_OK_CONTINUE)
+ goto out;
+
+out:
+ /* NULLs are OK */
+ fy_parse_document_destroy(fyp, fyd);
+ fy_document_iterator_destroy(fydi);
+ return ret;
+
+err_out:
+ ret = FYCR_ERROR;
+ goto out;
+}
+
+int fy_parse_compose(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata)
+{
+ enum fy_composer_return ret;
+ int rc, rc_out;
+
+ if (!fyp || !cb)
+ return -1;
+
+ /* set the composer callback */
+ rc = fy_parse_set_composer(fyp, cb, userdata);
+ fyp_error_check(fyp, !rc, err_out,
+ "fy_parse_set_composer() failed\n");
+
+ /* use the composer to parse */
+ ret = fy_parse_compose_internal(fyp);
+ /* on error set the stream error */
+ if (ret == FYCR_ERROR) {
+ fyp->stream_error = true;
+ rc_out = -1;
+ } else
+ rc_out = 0;
+
/* reset the parser; the composer clear must always succeed */
fy_parser_reset(fyp);
fyp_error_check(fyp, !rc, err_out,
"fy_parse_set_composer() failed\n");
- return rc;
+ return rc_out;
err_out:
return -1;
#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"
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_eventp_list recycled_eventp;
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;
+
/* the diagnostic object */
struct fy_diag *diag;
/* when using the composer interface */
struct fy_composer *fyc;
fy_parse_composer_cb fyc_cb;
+ void *fyc_userdata;
};
static inline struct fy_input *
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_strncmp(fyp->reader, str, n);
}
-static inline int
+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 inline int
+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_is_generic_blankz(fyp->reader, fy_reader_peek_at_offset(fyp->reader, offset));
}
-static inline int
+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 inline int
+static FY_ALWAYS_INLINE inline int
fy_parse_peek(struct fy_parser *fyp)
{
assert(fyp);
return fy_reader_peek(fyp->reader);
}
-static inline void
+static FY_ALWAYS_INLINE inline void
fy_advance(struct fy_parser *fyp, int c)
{
assert(fyp);
fy_reader_advance(fyp->reader, c);
}
-static inline void
+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 inline void
+static FY_ALWAYS_INLINE inline void
fy_advance_space(struct fy_parser *fyp)
{
assert(fyp);
fy_reader_advance_space(fyp->reader);
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_parse_get(struct fy_parser *fyp)
{
assert(fyp);
return fy_reader_get(fyp->reader);
}
-static inline int
+static FY_ALWAYS_INLINE inline int
fy_advance_by(struct fy_parser *fyp, int count)
{
assert(fyp);
return fy_version_compare(fy_document_state_version(fyds), vb);
}
-static inline struct fy_token_list *
-fy_parse_recycled_token(struct fy_parser *fyp)
-{
- return fyp && !fyp->suppress_recycling ? &fyp->recycled_token : NULL;
-}
-
int fy_parse_set_composer(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata);
#endif
fy_document_destroy(fypc->map.complex_key);
fypc->map.complex_key = NULL;
} else {
- fy_token_unref(fypc->map.scalar_key);
- fypc->map.scalar_key = NULL;
+ fy_token_unref(fypc->map.scalar.tag);
+ fy_token_unref(fypc->map.scalar.key);
+ fypc->map.scalar.tag = NULL;
+ fypc->map.scalar.key = NULL;
}
}
+ fypc->map.root = true;
fypc->map.has_key = false;
fypc->map.await_key = true;
fypc->map.is_complex_key = false;
fypc->type = FYPCT_MAP;
+ fypc->map.root = true;
fypc->map.await_key = true;
fypc->map.is_complex_key = false;
fypc->map.accumulating_complex_key = false;
struct fy_token *fy_path_component_mapping_get_scalar_key(struct fy_path_component *fypc)
{
return fypc && fypc->type == FYPCT_MAP &&
- fypc->map.has_key && !fypc->map.is_complex_key ? fypc->map.scalar_key : NULL;
+ fypc->map.has_key && !fypc->map.is_complex_key ? fypc->map.scalar.key : NULL;
+}
+
+struct fy_token *fy_path_component_mapping_get_scalar_key_tag(struct fy_path_component *fypc)
+{
+ return fypc && fypc->type == FYPCT_MAP &&
+ fypc->map.has_key && !fypc->map.is_complex_key ? fypc->map.scalar.tag : NULL;
}
struct fy_document *fy_path_component_mapping_get_complex_key(struct fy_path_component *fypc)
return fypc && fypc->type == FYPCT_SEQ;
}
+static int fy_path_component_get_text_internal(struct fy_emit_accum *ea, struct fy_path_component *fypc)
+{
+ char *doctxt;
+ const char *text;
+ size_t len;
+
+ switch (fypc->type) {
+ case FYPCT_NONE:
+ abort();
+
+ case FYPCT_MAP:
+
+ /* we don't handle transitionals */
+ if (!fypc->map.has_key || fypc->map.await_key || fypc->map.root)
+ return -1;
+
+ if (!fypc->map.is_complex_key && fypc->map.scalar.key) {
+ text = fy_token_get_text(fypc->map.scalar.key, &len);
+ if (!text)
+ return -1;
+
+ if (fypc->map.scalar.key->type == FYTT_ALIAS)
+ fy_emit_accum_utf8_put_raw(ea, '*');
+ fy_emit_accum_utf8_write_raw(ea, text, len);
+
+ } else if (fypc->map.complex_key) {
+ /* complex key */
+ doctxt = fy_emit_document_to_string(fypc->map.complex_key,
+ FYECF_WIDTH_INF | FYECF_INDENT_DEFAULT |
+ FYECF_MODE_FLOW_ONELINE | FYECF_NO_ENDING_NEWLINE);
+ fy_emit_accum_utf8_write_raw(ea, doctxt, strlen(doctxt));
+ free(doctxt);
+ }
+ break;
+
+ case FYPCT_SEQ:
+
+ /* not started filling yet */
+ if (fypc->seq.idx < 0)
+ return -1;
+
+ fy_emit_accum_utf8_printf_raw(ea, "%d", fypc->seq.idx);
+ break;
+ }
+
+ return 0;
+}
+
static int fy_path_get_text_internal(struct fy_emit_accum *ea, struct fy_path *fypp)
{
struct fy_path_component *fypc;
case FYPCT_MAP:
- if (!fypc->map.has_key)
+ if (!fypc->map.has_key || fypc->map.root)
break;
/* key reference ? wrap in .key(X)*/
if (!fypc->map.is_complex_key) {
- if (fypc->map.scalar_key) {
- text = fy_token_get_text(fypc->map.scalar_key, &len);
+ if (fypc->map.scalar.key) {
+ text = fy_token_get_text(fypc->map.scalar.key, &len);
assert(text);
if (!text)
return -1;
- if (fypc->map.scalar_key->type == FYTT_ALIAS)
+ if (fypc->map.scalar.key->type == FYTT_ALIAS)
fy_emit_accum_utf8_put_raw(ea, '*');
fy_emit_accum_utf8_write_raw(ea, text, len);
} else {
return path;
}
+char *fy_path_component_get_text(struct fy_path_component *fypc)
+{
+ struct fy_emit_accum ea; /* use an emit accumulator */
+ char *text = NULL;
+ size_t len;
+ int rc;
+
+ /* no inplace buffer; we will need the malloc'ed contents anyway */
+ fy_emit_accum_init(&ea, NULL, 0, 0, fylb_cr_nl);
+
+ fy_emit_accum_start(&ea, 0, fylb_cr_nl);
+
+ rc = fy_path_component_get_text_internal(&ea, fypc);
+ if (rc)
+ goto err_out;
+
+ fy_emit_accum_make_0_terminated(&ea);
+
+ text = fy_emit_accum_steal(&ea, &len);
+
+err_out:
+ fy_emit_accum_cleanup(&ea);
+
+ return text;
+}
+
int fy_path_depth(struct fy_path *fypp)
{
struct fy_path_component *fypc;
return fypc_last->type == FYPCT_MAP && !fypc_last->map.await_key;
}
-bool fy_path_is_collection_root(struct fy_path *fypp)
+bool fy_path_in_collection_root(struct fy_path *fypp)
{
struct fy_path_component *fypc_last;
return fy_path_component_is_collection_root(fypc_last);
}
+void *fy_path_get_root_user_data(struct fy_path *fypp)
+{
+ if (!fypp)
+ return NULL;
+
+ if (!fypp->parent)
+ return fypp->user_data;
+
+ return fy_path_get_root_user_data(fypp->parent);
+}
+
+void fy_path_set_root_user_data(struct fy_path *fypp, void *data)
+{
+ if (!fypp)
+ return;
+
+ if (!fypp->parent) {
+ fypp->user_data = data;
+ return;
+ }
+
+ fy_path_set_root_user_data(fypp->parent, data);
+}
+
void *fy_path_component_get_mapping_user_data(struct fy_path_component *fypc)
{
return fypc && fypc->type == FYPCT_MAP ? fypc->user_data : NULL;
#define FY_PATH_MAPPING_SHORT_KEY 32
struct fy_path_mapping_state {
+ bool root : 1; /* no keys, values yet */
bool await_key : 1;
bool accumulating_complex_key : 1;
- bool has_key : 1; /* has a key */
+ bool has_key : 1; /* has a key */
bool is_complex_key : 1;
bool complex_key_complete : 1;
union {
- struct fy_token *scalar_key;
+ struct {
+ struct fy_token *tag;
+ struct fy_token *key;
+ } scalar;
struct fy_document *complex_key;
};
void *key_user_data;
case FYPCT_SEQ:
return fypc->seq.idx < 0;
case FYPCT_MAP:
- return fypc->map.await_key && !fypc->map.has_key && !fypc->map.complex_key_complete;
+ return fypc->map.root;
}
return false;
struct fy_path_component_list components;
struct fy_document_builder *fydb; /* for complex keys */
struct fy_path *parent; /* when we have a parent */
+ void *user_data;
};
FY_TYPE_DECL_LIST(path);
enum fy_scalar_style fy_token_scalar_style(struct fy_token *fyt)
{
- if (!fyt || fyt->type != FYTT_SCALAR)
- return FYSS_PLAIN;
-
- if (fyt->type == FYTT_SCALAR)
- return fyt->scalar.style;
-
- return FYSS_PLAIN;
+ return fy_token_scalar_style_inline(fyt);
}
enum fy_token_type fy_token_get_type(struct fy_token *fyt)
{
- return fyt ? fyt->type : FYTT_NONE;
-}
-
-struct fy_token *fy_token_alloc_rl(struct fy_token_list *fytl)
-{
- struct fy_token *fyt;
-
- fyt = NULL;
- if (fytl) {
- fyt = fy_token_list_pop(fytl);
- if (fyt) {
- fyt->analyze_flags = 0;
- fyt->text_len = 0;
- fyt->text = NULL;
- fyt->text0 = NULL;
- fyt->handle.fyi = NULL;
- fyt->comment = NULL;
- }
- }
- if (!fyt) {
- fyt = malloc(sizeof(*fyt));
- if (!fyt)
- return NULL;
-
- memset(fyt, 0, sizeof(*fyt));
- }
-
- fyt->type = FYTT_NONE;
- fyt->refs = 1;
-
- return fyt;
+ return fy_token_get_type_inline(fyt);
}
void fy_token_clean_rl(struct fy_token_list *fytl, struct fy_token *fyt)
/* release reference */
fy_input_unref(fyt->handle.fyi);
+ fyt->handle.fyi = NULL;
/* release comment references */
if (fyt->comment) {
for (i = 0; i < fycp_max; i++)
fy_input_unref(fyt->comment[i].fyi);
free(fyt->comment);
+ fyt->comment = NULL;
}
switch (fyt->type) {
case FYTT_TAG:
fy_token_unref(fyt->tag.fyt_td);
- if (fyt->tag.handle0)
+ fyt->tag.fyt_td = NULL;
+ if (fyt->tag.handle0) {
free(fyt->tag.handle0);
- if (fyt->tag.suffix0)
+ fyt->tag.handle0 = NULL;
+ }
+ if (fyt->tag.suffix0) {
free(fyt->tag.suffix0);
- fyt->tag.fyt_td = NULL;
- fyt->tag.handle0 = NULL;
- fyt->tag.suffix0 = NULL;
+ fyt->tag.suffix0 = NULL;
+ }
break;
case FYTT_TAG_DIRECTIVE:
- if (fyt->tag_directive.prefix0)
+ if (fyt->tag_directive.prefix0) {
free(fyt->tag_directive.prefix0);
- if (fyt->tag_directive.handle0)
+ fyt->tag_directive.prefix0 = NULL;
+ }
+ if (fyt->tag_directive.handle0) {
free(fyt->tag_directive.handle0);
- fyt->tag_directive.prefix0 = NULL;
- fyt->tag_directive.handle0 = NULL;
+ fyt->tag_directive.handle0 = NULL;
+ }
break;
case FYTT_PE_MAP_KEY:
break;
case FYTT_SCALAR:
- if (fyt->scalar.path_key_storage)
+ if (fyt->scalar.path_key_storage) {
free(fyt->scalar.path_key_storage);
- fyt->scalar.path_key_storage = NULL;
+ fyt->scalar.path_key_storage = NULL;
+ }
break;
case FYTT_ALIAS:
- if (fyt->alias.expr)
+ if (fyt->alias.expr) {
fy_path_expr_free(fyt->alias.expr);
- fyt->alias.expr = NULL;
+ fyt->alias.expr = NULL;
+ }
break;
default:
break;
}
- if (fyt->text0)
+ if (fyt->text0) {
free(fyt->text0);
+ fyt->text0 = NULL;
+ }
fyt->type = FYTT_NONE;
fyt->analyze_flags = 0;
fyt->text_len = 0;
fyt->text = NULL;
- fyt->text0 = NULL;
- fyt->handle.fyi = NULL;
- fyt->comment = NULL;
-}
-
-void fy_token_free_rl(struct fy_token_list *fytl, struct fy_token *fyt)
-{
- if (!fyt)
- return;
-
- fy_token_clean_rl(fytl, fyt);
-
- if (fytl)
- fy_token_list_push(fytl, fyt);
- else
- free(fyt);
}
void fy_token_list_unref_all_rl(struct fy_token_list *fytl, struct fy_token_list *fytl_tofree)
if (handle)
fyt->handle = *handle;
else
- memset(&fyt->handle, 0, sizeof(fyt->handle));
+ fy_atom_reset(&fyt->handle);
switch (fyt->type) {
case FYTT_TAG_DIRECTIVE:
fyt->tag_directive.tag_length = va_arg(ap, unsigned int);
fyt->tag_directive.uri_length = va_arg(ap, unsigned int);
fyt->tag_directive.is_default = va_arg(ap, int) ? true : false;
+ fyt->tag_directive.prefix0 = NULL;
+ fyt->tag_directive.handle0 = NULL;
break;
case FYTT_SCALAR:
fyt->scalar.style = va_arg(ap, enum fy_scalar_style);
- if ((unsigned int)fyt->scalar.style >= FYSS_MAX)
+ if (fyt->scalar.style != FYSS_ANY && (unsigned int)fyt->scalar.style >= FYSS_MAX)
goto err_out;
fyt->scalar.path_key = NULL;
fyt->scalar.path_key_len = 0;
if (!fyt_td)
goto err_out;
fyt->tag.fyt_td = fy_token_ref(fyt_td);
+ fyt->tag.handle0 = NULL;
+ fyt->tag.suffix0 = NULL;
break;
case FYTT_VERSION_DIRECTIVE:
return NULL;
va_start(ap, type);
- fyt = fy_token_vcreate_rl(&fyp->recycled_token, type, ap);
+ fyt = fy_token_vcreate_rl(fyp->recycled_token_list, type, ap);
va_end(ap);
return fyt;
#include <libfyaml.h>
+#include "fy-utils.h"
#include "fy-atom.h"
extern const char *fy_token_type_txt[FYTT_COUNT];
return fyt->text && fyt->text != fyt->text0;
}
-struct fy_token *fy_token_alloc_rl(struct fy_token_list *fytl);
void fy_token_clean_rl(struct fy_token_list *fytl, struct fy_token *fyt);
-void fy_token_free_rl(struct fy_token_list *fytl, struct fy_token *fyt);
void fy_token_list_unref_all_rl(struct fy_token_list *fytl, struct fy_token_list *fytl_tofree);
-static inline void
+static inline FY_ALWAYS_INLINE struct fy_token *
+fy_token_alloc_rl(struct fy_token_list *fytl)
+{
+ struct fy_token *fyt;
+
+ fyt = NULL;
+ if (fytl)
+ fyt = fy_token_list_pop(fytl);
+ if (!fyt) {
+ fyt = malloc(sizeof(*fyt));
+ if (!fyt)
+ return NULL;
+ }
+
+ fyt->type = FYTT_NONE;
+ fyt->refs = 1;
+
+ fyt->analyze_flags = 0;
+ fyt->text_len = 0;
+ fyt->text = NULL;
+ fyt->text0 = NULL;
+ fyt->handle.fyi = NULL;
+ fyt->comment = NULL;
+
+ return fyt;
+}
+
+static inline FY_ALWAYS_INLINE void
+fy_token_free_rl(struct fy_token_list *fytl, struct fy_token *fyt)
+{
+ if (!fyt)
+ return;
+
+ fy_token_clean_rl(fytl, fyt);
+
+ if (fytl)
+ fy_token_list_push(fytl, fyt);
+ else
+ free(fyt);
+}
+
+static inline FY_ALWAYS_INLINE void
fy_token_unref_rl(struct fy_token_list *fytl, struct fy_token *fyt)
{
if (!fyt)
fy_token_free_rl(fytl, fyt);
}
-static inline struct fy_token *
+static inline FY_ALWAYS_INLINE struct fy_token *
fy_token_alloc(void)
{
return fy_token_alloc_rl(NULL);
}
-static inline void
+static inline FY_ALWAYS_INLINE void
fy_token_clean(struct fy_token *fyt)
{
return fy_token_clean_rl(NULL, fyt);
}
-static inline void
+static inline FY_ALWAYS_INLINE void
fy_token_free(struct fy_token *fyt)
{
return fy_token_free_rl(NULL, fyt);
}
-static inline struct fy_token *
+static inline FY_ALWAYS_INLINE struct fy_token *
fy_token_ref(struct fy_token *fyt)
{
/* take care of overflow */
return fyt;
}
-static inline void
+static inline FY_ALWAYS_INLINE void
fy_token_unref(struct fy_token *fyt)
{
return fy_token_unref_rl(NULL, fyt);
struct fy_atom *fy_token_comment_handle(struct fy_token *fyt, enum fy_comment_placement placement, bool alloc);
+static inline FY_ALWAYS_INLINE enum fy_scalar_style
+fy_token_scalar_style_inline(struct fy_token *fyt)
+{
+ if (!fyt || fyt->type != FYTT_SCALAR)
+ return FYSS_PLAIN;
+
+ if (fyt->type == FYTT_SCALAR)
+ return fyt->scalar.style;
+
+ return FYSS_PLAIN;
+}
+
+static inline FY_ALWAYS_INLINE enum fy_token_type
+fy_token_get_type_inline(struct fy_token *fyt)
+{
+ return fyt ? fyt->type : FYTT_NONE;
+}
+
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include "fy-utf8.h"
#include "fy-ctype.h"
return 0;
}
+
+/* simple terminal methods; mainly for getting size of terminal */
+int fy_term_set_raw(int fd, struct termios *oldt)
+{
+ struct termios newt, t;
+ int ret;
+
+ /* must be a terminal */
+ if (!isatty(fd))
+ return -1;
+
+ ret = tcgetattr(fd, &t);
+ if (ret != 0)
+ return ret;
+
+ newt = t;
+
+ cfmakeraw(&newt);
+
+ ret = tcsetattr(fd, TCSANOW, &newt);
+ if (ret != 0)
+ return ret;
+
+ if (oldt)
+ *oldt = t;
+
+ return 0;
+}
+
+int fy_term_restore(int fd, const struct termios *oldt)
+{
+ /* must be a terminal */
+ if (!isatty(fd))
+ return -1;
+
+ return tcsetattr(fd, TCSANOW, oldt);
+}
+
+ssize_t fy_term_write(int fd, const void *data, size_t count)
+{
+ ssize_t wrn, r;
+
+ if (!isatty(fd))
+ return -1;
+ r = 0;
+ wrn = 0;
+ while (count > 0) {
+ do {
+ r = write(fd, data, count);
+ } while (r == -1 && errno == EAGAIN);
+ if (r < 0)
+ break;
+ wrn += r;
+ data += r;
+ count -= r;
+ }
+
+ /* return the amount written, or the last error code */
+ return wrn > 0 ? wrn : r;
+}
+
+int fy_term_safe_write(int fd, const void *data, size_t count)
+{
+ if (!isatty(fd))
+ return -1;
+
+ return fy_term_write(fd, data, count) == (ssize_t)count ? 0 : -1;
+}
+
+ssize_t fy_term_read(int fd, void *data, size_t count, int timeout_us)
+{
+ ssize_t rdn, r;
+ struct timeval tv, tvto, *tvp;
+ fd_set rdfds;
+
+ if (!isatty(fd))
+ return -1;
+
+ FD_ZERO(&rdfds);
+
+ memset(&tvto, 0, sizeof(tvto));
+ memset(&tv, 0, sizeof(tv));
+
+ if (timeout_us >= 0) {
+ tvto.tv_sec = timeout_us / 1000000;
+ tvto.tv_usec = timeout_us % 1000000;
+ tvp = &tv;
+ } else {
+ tvp = NULL;
+ }
+
+ r = 0;
+ rdn = 0;
+ while (count > 0) {
+ do {
+ FD_SET(fd, &rdfds);
+ if (tvp)
+ *tvp = tvto;
+ r = select(fd + 1, &rdfds, NULL, NULL, tvp);
+ } while (r == -1 && errno == EAGAIN);
+
+ /* select ends, or something weird */
+ if (r <= 0 || !FD_ISSET(fd, &rdfds))
+ break;
+
+ /* now read */
+ do {
+ r = read(fd, data, count);
+ } while (r == -1 && errno == EAGAIN);
+ if (r < 0)
+ break;
+
+ rdn += r;
+ data += r;
+ count -= r;
+ }
+
+ /* return the amount written, or the last error code */
+ return rdn > 0 ? rdn : r;
+}
+
+ssize_t fy_term_read_escape(int fd, void *buf, size_t count)
+{
+ char *p;
+ int r, rdn;
+ char c;
+
+ /* at least 3 characters */
+ if (count < 3)
+ return -1;
+
+ p = buf;
+ rdn = 0;
+
+ /* ESC */
+ r = fy_term_read(fd, &c, 1, 100 * 1000);
+ if (r != 1 || c != '\x1b')
+ return -1;
+ *p++ = c;
+ count--;
+ rdn++;
+
+ /* [ */
+ r = fy_term_read(fd, &c, 1, 100 * 1000);
+ if (r != 1 || c != '[')
+ return rdn;
+ *p++ = c;
+ count--;
+ rdn++;
+
+ /* read until error, out of buffer, or < 0x40 || > 0x7e */
+ r = -1;
+ while (count > 0) {
+ r = fy_term_read(fd, &c, 1, 100 * 1000);
+ if (r != 1)
+ r = -1;
+ if (r != 1)
+ break;
+ *p++ = c;
+ count--;
+ rdn++;
+
+ /* end of escape */
+ if (c >= 0x40 && c <= 0x7e)
+ break;
+ }
+
+ return rdn;
+}
+
+int fy_term_query_size_raw(int fd, int *rows, int *cols)
+{
+ char buf[32];
+ char *s, *e;
+ ssize_t r;
+
+ /* must be a terminal */
+ if (!isatty(fd))
+ return -1;
+
+ *rows = *cols = 0;
+
+ /* query text area */
+ r = fy_term_safe_write(fd, "\x1b[18t", 5);
+ if (r != 0)
+ return r;
+
+ /* read a character */
+ r = fy_term_read_escape(fd, buf, sizeof(buf));
+
+ /* return must be ESC[8;<height>;<width>;t */
+
+ if (r < 8 || r >= (int)sizeof(buf) - 2) /* minimum ESC[8;1;1t */
+ return -1;
+
+ s = buf;
+ e = s + r;
+
+ /* correct response? starts with ESC[8; */
+ if (s[0] != '\x1b' || s[1] != '[' || s[2] != '8' || s[3] != ';')
+ return -1;
+ s += 4;
+
+ /* must end with t */
+ if (e[-1] != 't')
+ return -1;
+ *--e = '\0'; /* remove trailing t, and zero terminate */
+
+ /* scan two ints separated by ; */
+ r = sscanf(s, "%d;%d", rows, cols);
+ if (r != 2)
+ return -1;
+
+ return 0;
+}
+
+int fy_term_query_size(int fd, int *rows, int *cols)
+{
+ struct termios old_term;
+ int ret, r;
+
+ if (!isatty(fd))
+ return -1;
+
+ r = fy_term_set_raw(fd, &old_term);
+ if (r != 0)
+ return -1;
+
+ ret = fy_term_query_size_raw(fd, rows, cols);
+
+ r = fy_term_restore(fd, &old_term);
+ if (r != 0)
+ return -1;
+
+ return ret;
+}
#include <stdio.h>
#include <stdbool.h>
+#include <unistd.h>
+#include <termios.h>
#if defined(__APPLE__) && (_POSIX_C_SOURCE < 200809L)
FILE *open_memstream(char **ptr, size_t *sizeloc);
#define ARRAY_SIZE(x) ((sizeof(x)/sizeof((x)[0])))
#endif
+#if !defined(NDEBUG) && (defined(__GNUC__) && __GNUC__ >= 4)
+#define FY_ALWAYS_INLINE __attribute__((always_inline))
+#else
+#define FY_ALWAYS_INLINE /* nothing */
+#endif
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define FY_UNUSED __attribute__((unused))
+#else
+#define FY_UNUSED /* nothing */
+#endif
+
+int fy_term_set_raw(int fd, struct termios *oldt);
+int fy_term_restore(int fd, const struct termios *oldt);
+ssize_t fy_term_write(int fd, const void *data, size_t count);
+int fy_term_safe_write(int fd, const void *data, size_t count);
+ssize_t fy_term_read(int fd, void *data, size_t count, int timeout_us);
+ssize_t fy_term_read_escape(int fd, void *buf, size_t count);
+
+/* the raw methods require the terminal to be in raw mode */
+int fy_term_query_size_raw(int fd, int *rows, int *cols);
+
+/* the non raw methods will set the terminal to raw and then restore */
+int fy_term_query_size(int fd, int *rows, int *cols);
+
#endif
return -1;
}
-static inline void
+static inline FY_UNUSED void
dump_operand_stack(struct fy_path_parser *fypp)
{
return fy_expr_stack_dump(fypp->cfg.diag, &fypp->operands);
return fy_expr_stack_push(&fypp->operands, expr);
}
-static inline struct fy_path_expr *
+static inline FY_UNUSED struct fy_path_expr *
peek_operand_at(struct fy_path_parser *fypp, unsigned int pos)
{
return fy_expr_stack_peek_at(&fypp->operands, pos);
}
-static inline struct fy_path_expr *
+static inline FY_UNUSED struct fy_path_expr *
peek_operand(struct fy_path_parser *fypp)
{
return fy_expr_stack_peek(&fypp->operands);
}
-static inline struct fy_path_expr *
+static inline FY_UNUSED struct fy_path_expr *
pop_operand(struct fy_path_parser *fypp)
{
return fy_expr_stack_pop(&fypp->operands);
#define YPATH_ALIASES_DEFAULT false
#define DISABLE_FLOW_MARKERS_DEFAULT false
#define DUMP_PATH_DEFAULT false
+#define DOCUMENT_EVENT_STREAM_DEFAULT false
+#define COLLECT_ERRORS_DEFAULT false
+#define ALLOW_DUPLICATE_KEYS_DEFAULT false
+#define STRIP_EMPTY_KV_DEFAULT false
#define OPT_DUMP 1000
#define OPT_TESTSUITE 1001
#define OPT_YPATH_ALIASES 2013
#define OPT_DISABLE_FLOW_MARKERS 2014
#define OPT_DUMP_PATH 2015
+#define OPT_DOCUMENT_EVENT_STREAM 2016
+#define OPT_COLLECT_ERRORS 2017
+#define OPT_ALLOW_DUPLICATE_KEYS 2018
+#define OPT_STRIP_EMPTY_KV 2019
#define OPT_DISABLE_DIAG 3000
#define OPT_ENABLE_DIAG 3001
{"ypath-aliases", no_argument, 0, OPT_YPATH_ALIASES },
{"disable-flow-markers",no_argument, 0, OPT_DISABLE_FLOW_MARKERS },
{"dump-pathexpr", no_argument, 0, OPT_DUMP_PATHEXPR },
+ {"document-event-stream",no_argument, 0, OPT_DOCUMENT_EVENT_STREAM },
{"noexec", no_argument, 0, OPT_NOEXEC },
{"null-output", no_argument, 0, OPT_NULL_OUTPUT },
+ {"collect-errors", no_argument, 0, OPT_COLLECT_ERRORS },
+ {"allow-duplicate-keys",no_argument, 0, OPT_ALLOW_DUPLICATE_KEYS },
+ {"strip-empty-kv", no_argument, 0, OPT_STRIP_EMPTY_KV },
{"to", required_argument, 0, 'T' },
{"from", required_argument, 0, 'F' },
{"quiet", no_argument, 0, 'q' },
DEBUG_LEVEL_DEFAULT);
fprintf(fp, "\t--disable-diag <x> : Disable diag error module <x>\n");
fprintf(fp, "\t--enable-diag <x> : Enable diag error module <x>\n");
- fprintf(fp, "\t--show-diag-diag <x> : Show diag option <x>\n");
+ fprintf(fp, "\t--show-diag <x> : Show diag option <x>\n");
fprintf(fp, "\t--hide-diag <x> : Hide diag optione <x>\n");
fprintf(fp, "\t--indent, -i <indent> : Set dump indent to <indent>"
fprintf(fp, "\t--ypath-aliases : Use YPATH aliases (default %s)\n",
YPATH_ALIASES_DEFAULT ? "true" : "false");
fprintf(fp, "\t--null-output : Do not generate output (for scanner profiling)\n");
+ fprintf(fp, "\t--collect-errors : Collect errors instead of outputting directly"
+ " (default %s)\n",
+ COLLECT_ERRORS_DEFAULT ? "true" : "false");
+ fprintf(fp, "\t--allow-duplicate-keys : Allow duplicate keys"
+ " (default %s)\n",
+ ALLOW_DUPLICATE_KEYS_DEFAULT ? "true" : "false");
+ fprintf(fp, "\t--strip-empty-kv : Strip keys with empty values when emitting (not available in streaming mode)"
+ " (default %s)\n",
+ STRIP_EMPTY_KV_DEFAULT ? "true" : "false");
fprintf(fp, "\t--quiet, -q : Quiet operation, do not "
"output messages (default %s)\n",
QUIET_DEFAULT ? "true" : "false");
fprintf(fp, "\t--comment, -c : Output comments (experimental)"
" (default %s)\n",
COMMENT_DEFAULT ? "true" : "false");
- fprintf(fp, "\t--mode, -m <mode> : Output mode can be one of original, block, flow, flow-oneline, json, json-tp, json-oneline, dejson"
+ fprintf(fp, "\t--mode, -m <mode> : Output mode can be one of original, block, flow, flow-oneline, json, json-tp, json-oneline, dejson, pretty|yamlfmt"
" (default %s)\n",
MODE_DEFAULT);
fprintf(fp, "\t--disable-flow-markers : Disable testsuite's flow-markers"
" (default %s)\n",
DISABLE_FLOW_MARKERS_DEFAULT ? "true" : "false");
+ fprintf(fp, "\t--document-event-stream : Generate a document and then produce the event stream"
+ " (default %s)\n",
+ DOCUMENT_EVENT_STREAM_DEFAULT ? "true" : "false");
if (tool_mode == OPT_TOOL || tool_mode == OPT_DUMP)
fprintf(fp, "\t--streaming : Use streaming output mode"
" (default %s)\n",
{ .name = "json-tp", .value = FYECF_MODE_JSON_TP },
{ .name = "json-oneline", .value = FYECF_MODE_JSON_ONELINE },
{ .name = "dejson", .value = FYECF_MODE_DEJSON },
+ { .name = "pretty", .value = FYECF_MODE_PRETTY },
+ { .name = "yamlfmt", .value = FYECF_MODE_PRETTY }, /* alias for pretty */
};
unsigned int i;
fy_path_in_mapping(path) ? 'M' : '-',
fy_path_in_mapping_key(path) ? 'K' :
fy_path_in_mapping_value(path) ? 'V' : '-',
- fy_path_is_collection_root(path) ? '/' : '-',
+ fy_path_in_collection_root(path) ? '/' : '-',
fy_path_depth(path),
fy_path_get_text_alloca(path));
}
bool stdin_input;
void *res_iter;
bool disable_flow_markers = false;
+ bool document_event_stream = DOCUMENT_EVENT_STREAM_DEFAULT;
+ bool collect_errors = COLLECT_ERRORS_DEFAULT;
+ bool allow_duplicate_keys = ALLOW_DUPLICATE_KEYS_DEFAULT;
struct composer_data cd;
bool dump_path = DUMP_PATH_DEFAULT;
+ const char *input_arg;
fy_valgrind_check(&argc, &argv);
case OPT_DISABLE_FLOW_MARKERS:
disable_flow_markers = true;
break;
+ case OPT_DOCUMENT_EVENT_STREAM:
+ document_event_stream = true;
+ break;
+ case OPT_COLLECT_ERRORS:
+ collect_errors = true;
+ break;
+ case OPT_ALLOW_DUPLICATE_KEYS:
+ allow_duplicate_keys = true;
+ break;
+ case OPT_STRIP_EMPTY_KV:
+ emit_flags |= FYECF_STRIP_EMPTY_KV;
+ break;
case 'h' :
default:
if (opt != 'h')
goto cleanup;
}
+ /* collect errors, instead of outputting directly */
+ if (collect_errors)
+ fy_diag_set_collect_errors(diag, true);
+
+ if (allow_duplicate_keys)
+ cfg.flags |= FYPCF_ALLOW_DUPLICATE_KEYS;
+
/* all set, use fy_diag for error reporting, debugging now */
cfg.diag = diag;
fprintf(stderr, "failed to create token iterator\n");
goto cleanup;
}
- while ((fyev = fy_parser_parse(fyp)) != NULL) {
+
+ if (!document_event_stream) {
+ /* regular test suite */
+ while ((fyev = fy_parser_parse(fyp)) != NULL) {
+ dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers);
+ fy_parser_event_free(fyp, fyev);
+ }
+ } else {
+ struct fy_document_iterator *fydi;
+
+ fydi = fy_document_iterator_create();
+ assert(fydi);
+
+ fyev = fy_document_iterator_stream_start(fydi);
+ if (!fyev) {
+ fprintf(stderr, "failed to create document iterator's stream start event\n");
+ goto cleanup;
+ }
+ dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers);
+ fy_document_iterator_event_free(fydi, fyev);
+
+ /* convert to document and then process the generator event stream it */
+ while ((fyd = fy_parse_load_document(fyp)) != NULL) {
+
+ fyev = fy_document_iterator_document_start(fydi, fyd);
+ if (!fyev) {
+ fprintf(stderr, "failed to create document iterator's document start event\n");
+ goto cleanup;
+ }
+ dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers);
+ fy_document_iterator_event_free(fydi, fyev);
+
+ while ((fyev = fy_document_iterator_body_next(fydi)) != NULL) {
+ dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers);
+ fy_document_iterator_event_free(fydi, fyev);
+ }
+
+ fyev = fy_document_iterator_document_end(fydi);
+ if (!fyev) {
+ fprintf(stderr, "failed to create document iterator's stream document end\n");
+ goto cleanup;
+ }
+ dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers);
+ fy_document_iterator_event_free(fydi, fyev);
+
+ fy_parse_document_destroy(fyp, fyd);
+ if (rc)
+ break;
+
+ }
+
+ fyev = fy_document_iterator_stream_end(fydi);
+ if (!fyev) {
+ fprintf(stderr, "failed to create document iterator's stream end event\n");
+ goto cleanup;
+ }
dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers);
- fy_parser_event_free(fyp, fyev);
+ fy_document_iterator_event_free(fydi, fyev);
+
+ fy_document_iterator_destroy(fydi);
+ fydi = NULL;
}
+
fy_token_iter_destroy(iter);
iter = NULL;
+
if (fy_parser_get_stream_error(fyp))
goto cleanup;
break;
case OPT_DUMP:
- if (optind >= argc) {
- fprintf(stderr, "missing yaml file to dump\n");
- goto cleanup;
- }
-
count = 0;
- for (i = optind; i < argc; i++) {
- rc = set_parser_input(fyp, argv[i], false);
+ for (i = optind; ; i++) {
+
+ if (optind < argc) {
+ if (i >= argc)
+ break;
+ input_arg = argv[i];
+ } else {
+ if (i >= argc + 1)
+ break;
+ input_arg = "-";
+ }
+
+ rc = set_parser_input(fyp, input_arg, false);
if (rc) {
- fprintf(stderr, "failed to set parser input to '%s' for dump\n", argv[i]);
+ fprintf(stderr, "failed to set parser input to '%s' for dump\n", input_arg);
goto cleanup;
}
}
fyd_join = NULL;
- for (i = optind; i < argc; i++) {
- rc = set_parser_input(fyp, argv[i], false);
+ for (i = optind; ; i++) {
+
+ if (optind < argc) {
+ if (i >= argc)
+ break;
+ input_arg = argv[i];
+ } else {
+ if (i >= argc + 1)
+ break;
+ input_arg = "-";
+ }
+
+ rc = set_parser_input(fyp, input_arg, false);
if (rc) {
- fprintf(stderr, "failed to set parser input to '%s' for join\n", argv[i]);
+ fprintf(stderr, "failed to set parser input to '%s' for join\n", input_arg);
goto cleanup;
}
if (fyp)
fy_parser_destroy(fyp);
- if (diag)
+ if (diag) {
+ if (collect_errors) {
+ struct fy_diag_error *err;
+ void *iter;
+
+ iter = NULL;
+ while ((err = fy_diag_errors_iterate(diag, &iter)) != NULL) {
+ fprintf(stderr, "%s:%d:%d %s\n", err->file, err->line, err->column, err->msg);
+ }
+
+ }
fy_diag_destroy(diag);
+ }
return exitcode;
}
check_PROGRAMS = libfyaml-test
libfyaml_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/valgrind/ \
-I$(top_srcdir)/src/lib/
-libfyaml_test_LDADD = $(AM_LDADD) $(CHECK_LIBS) $(top_builddir)/src/libfyaml-@MAJOR@.@MINOR@.la
+libfyaml_test_LDADD = $(AM_LDADD) $(CHECK_LIBS) $(top_builddir)/src/libfyaml.la
libfyaml_test_CFLAGS = $(AM_CFLAGS) $(CHECK_CFLAGS)
libfyaml_test_LDFLAGS = $(AM_LDFLAGS) $(CHECK_LDFLAGS)
# normal JSON testsuite
TESTS += jsontestsuite.test
+# normal YAML testsuite using document event stream
+TESTS += testsuite-evstream.test
+
testsuite.test: test-suite-data json-test-suite-data
test-suite-data:
@HAVE_GIT_TRUE@@HAVE_JQ_TRUE@@HAVE_NETWORK_TRUE@am__append_3 = testsuite-json.test
# normal JSON testsuite
-@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@am__append_4 = jsontestsuite.test
+
+# normal YAML testsuite using document event stream
+@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@am__append_4 = jsontestsuite.test \
+@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ testsuite-evstream.test
subdir = test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_enable_debug.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/shave.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/shave.m4 $(top_srcdir)/.libtool-version \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
am__DEPENDENCIES_1 =
@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_DEPENDENCIES = \
@HAVE_COMPATIBLE_CHECK_TRUE@ $(am__DEPENDENCIES_1) \
-@HAVE_COMPATIBLE_CHECK_TRUE@ $(top_builddir)/src/libfyaml-@MAJOR@.@MINOR@.la
+@HAVE_COMPATIBLE_CHECK_TRUE@ $(top_builddir)/src/libfyaml.la
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEBVERSION = @DEBVERSION@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
+LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIBYAML_CFLAGS = @LIBYAML_CFLAGS@
LIBYAML_LIBS = @LIBYAML_LIBS@
LIPO = @LIPO@
@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/valgrind/ \
@HAVE_COMPATIBLE_CHECK_TRUE@ -I$(top_srcdir)/src/lib/
-@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_LDADD = $(AM_LDADD) $(CHECK_LIBS) $(top_builddir)/src/libfyaml-@MAJOR@.@MINOR@.la
+@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_LDADD = $(AM_LDADD) $(CHECK_LIBS) $(top_builddir)/src/libfyaml.la
@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_CFLAGS = $(AM_CFLAGS) $(CHECK_CFLAGS)
@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_LDFLAGS = $(AM_LDFLAGS) $(CHECK_LDFLAGS)
@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_SOURCES = \
--- /dev/null
+#!/bin/bash
+
+count=0
+for basetst in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
+ for tst in ${basetst} ${basetst}[0-9][0-9]/; do
+ # there must be a test there
+ if [ ! -e "$tst/===" ]; then
+ continue
+ fi
+ # skip tests that are expected to fail
+ if [ -e "$tst/error" ]; then
+ continue
+ fi
+ count=`expr $count + 1`
+ done
+done
+
+# output plan
+echo 1..$count
+
+skiplist="2JQS"
+xfaillist=""
+
+i=0
+for basetst in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
+
+ for tst in ${basetst} ${basetst}[0-9][0-9]/; do
+
+ # there must be a test there
+ if [ ! -e "$tst/===" ]; then
+ continue
+ fi
+
+ # skip tests that are expected to fail
+ if [ -e "$tst/error" ]; then
+ continue
+ fi
+
+ i=`expr $i + 1`
+
+ # strip trailing /
+ t=${tst%/}
+ # remove test-suite-data/
+ test_subtest_id=`echo $t | cut -d/ -f2-`
+ test_id=`echo $test_subtest_id | cut -d/ -f1`
+ subtest_id=`echo $test_subtest_id | cut -s -d/ -f2`
+
+ desctxt=`cat 2>/dev/null "$tst/==="`
+
+ t=`mktemp`
+
+ directive=""
+ for skip in $skiplist; do
+ if [ "$test_subtest_id" == "$skip" ]; then
+ directive=" # skip: duplicate keys in testcase; cannot load as document"
+ break
+ fi
+ done
+
+ res="ok"
+ if [ "x$directive" == "x" ]; then
+ res="not ok"
+ # run the test using document-event-stream
+ ${TOP_BUILDDIR}/src/fy-tool --testsuite --document-event-stream "$tst/in.yaml" >"$t"
+ if [ $? -eq 0 ]; then
+ diff -u "$tst/test.event" "$t"
+ if [ $? -eq 0 ]; then
+ res="ok"
+ else
+ res="not ok"
+ fi
+ else
+ res="not ok"
+ fi
+
+ rm -f "$t"
+
+ for xfail in $xfaillist; do
+ if [ "$test_subtest_id" == "$xfail" ]; then
+ directive=" # TODO: known failure."
+ break
+ fi
+ done
+ fi
+
+ echo "$res $i $test_subtest_id - $desctxt$directive"
+ done
+done
#!/bin/bash
count=0
-for file in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/in.json; do
-
- dir=`dirname $file`
-
- # ignore tests which are expected to fail
- if [ -e "$dir/error" ]; then
- continue
- fi
-
- count=`expr $count + 1`
+for basetst in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
+ for tst in ${basetst} ${basetst}[0-9][0-9]/; do
+ # there must be a test there
+ if [ ! -e "$tst/===" ]; then
+ continue
+ fi
+ # ignore tests which are expected to fail
+ if [ -e "$tst/error" ]; then
+ continue
+ fi
+ # a json file must be there
+ if [ ! -e "$tst/in.json" ]; then
+ continue
+ fi
+ count=`expr $count + 1`
+ done
done
# output plan
echo 1..$count
skiplist="C4HZ"
+xfaillist=""
i=0
-for file in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/in.json; do
+for basetst in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
- dir=`dirname $file`
+ for tst in ${basetst} ${basetst}[0-9][0-9]/; do
- # ignore tests which are expected to fail
- if [ -e "$dir/error" ]; then
- continue
- fi
+ # ignore tests which are expected to fail
+ if [ -e "$tst/error" ]; then
+ continue
+ fi
+ # a json file must be there
+ if [ ! -e "$tst/in.json" ]; then
+ continue
+ fi
- i=`expr $i + 1`
- desctxt=`cat 2>/dev/null "$dir/==="`
- tdir=`basename $dir`
+ i=`expr $i + 1`
- skipdirective=""
- for skip in $skiplist; do
- if [ "$tdir" == "$skip" ]; then
- skipdirective="# skip does not apply to libfyaml"
- break
- fi
- done
+ # strip trailing /
+ t=${tst%/}
+ # remove test-suite-data/
+ test_subtest_id=`echo $t | cut -d/ -f2-`
+ test_id=`echo $test_subtest_id | cut -d/ -f1`
+ subtest_id=`echo $test_subtest_id | cut -s -d/ -f2`
- res="ok"
+ desctxt=`cat 2>/dev/null "$tst/==="`
- if [ "x$skipdirective" == "x" ]; then
- t1=`mktemp`
- t2=`mktemp`
+ directive=""
+ for skip in $skiplist; do
+ if [ "$test_subtest_id" == "$skip" ]; then
+ directive="# SKIP: does not apply to libfyaml"
+ break
+ fi
+ done
- # output yaml in json format
- ${TOP_BUILDDIR}/src/fy-tool --dump --strip-labels --strip-tags --strip-doc -r -mjson "$dir/in.yaml" | "${JQ}" --sort-keys . >"$t1"
+ res="ok"
- # do the same with the json input (canonicalize)
- cat "$dir/in.json" | "${JQ}" --sort-keys . > "$t2"
+ if [ "x$directive" == "x" ]; then
+ t1=`mktemp`
+ t2=`mktemp`
- diff -u "$t1" "$t2"
- if [ $? -eq 0 ]; then
- res="ok"
- else
- res="not ok"
- fi
+ # output yaml in json format
+ ${TOP_BUILDDIR}/src/fy-tool --dump --strip-labels --strip-tags --strip-doc -r -mjson "$tst/in.yaml" | "${JQ}" --sort-keys . >"$t1"
+
+ # do the same with the json input (canonicalize)
+ cat "$tst/in.json" | "${JQ}" --sort-keys . > "$t2"
- rm -f "$t1" "$t2"
- fi
+ diff -u "$t1" "$t2"
+ if [ $? -eq 0 ]; then
+ res="ok"
+ else
+ res="not ok"
+ fi
- echo "$res $i $tdir - $desctxt (JSON)$skipdirective"
+ rm -f "$t1" "$t2"
+
+ for xfail in $xfaillist; do
+ if [ "$test_subtest_id" == "$xfail" ]; then
+ directive=" # TODO: known failure."
+ break
+ fi
+ done
+ fi
+
+ echo "$res $i $test_subtest_id - $desctxt (JSON)$directive"
+ done
done
#!/bin/bash
count=0
-for dir in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
- count=`expr $count + 1`
+for basetst in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
+ for tst in ${basetst} ${basetst}[0-9][0-9]/; do
+ # there must be a test there
+ if [ ! -e "$tst/===" ]; then
+ continue
+ fi
+ count=`expr $count + 1`
+ done
done
# output plan
echo 1..$count
+skiplist=""
+xfaillist=""
+
i=0
-for dir in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
+for basetst in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do
+
+ for tst in ${basetst} ${basetst}[0-9][0-9]/; do
+
+ # there must be a test there
+ if [ ! -e "$tst/===" ]; then
+ continue
+ fi
+
+ i=`expr $i + 1`
- i=`expr $i + 1`
- desctxt=`cat 2>/dev/null "$dir/==="`
- tdir=`basename $dir`
+ # strip trailing /
+ t=${tst%/}
+ # remove test-suite-data/
+ test_subtest_id=`echo $t | cut -d/ -f2-`
+ test_id=`echo $test_subtest_id | cut -d/ -f1`
+ subtest_id=`echo $test_subtest_id | cut -s -d/ -f2`
- t=`mktemp`
+ desctxt=`cat 2>/dev/null "$tst/==="`
- res="not ok"
+ t=`mktemp`
- pass_yaml=0
- ${TOP_BUILDDIR}/src/fy-tool --testsuite "$dir/in.yaml" >"$t"
- if [ $? -eq 0 ]; then
- pass_yaml=1
- fi
+ directive=""
+ for skip in $skiplist; do
+ if [ "$test_subtest_id" == "$skip" ]; then
+ directive=" # SKIP"
+ break
+ fi
+ done
- if [ -e "$dir/error" ]; then
- # test is expected to fail
- if [ $pass_yaml == "0" ]; then
- res="ok"
- else
+ res="ok"
+ if [ "x$directive" == "x" ]; then
res="not ok"
- fi
- else
- # test is expected to pass
- if [ $pass_yaml == "1" ]; then
- diff_yaml=0
- # diff -u "$dir/test.event" "$t" | sed -e 's/^/# /'
- diff -u "$dir/test.event" "$t"
+
+ pass_yaml=0
+ ${TOP_BUILDDIR}/src/fy-tool --testsuite "$tst/in.yaml" >"$t"
if [ $? -eq 0 ]; then
- res="ok"
+ pass_yaml=1
+ fi
+
+ if [ -e "$tst/error" ]; then
+ # test is expected to fail
+ if [ $pass_yaml == "0" ]; then
+ res="ok"
+ else
+ res="not ok"
+ fi
else
- res="not ok"
+ # test is expected to pass
+ if [ $pass_yaml == "1" ]; then
+ diff_yaml=0
+ # diff -u "$tst/test.event" "$t" | sed -e 's/^/# /'
+ diff -u "$tst/test.event" "$t"
+ if [ $? -eq 0 ]; then
+ res="ok"
+ else
+ res="not ok"
+ fi
+ else
+ res="not ok"
+ fi
fi
- else
- res="not ok"
- fi
- fi
- rm -f "$t"
+ rm -f "$t"
+
+ for xfail in $xfaillist; do
+ if [ "$test_subtest_id" == "$xfail" ]; then
+ directive=" # TODO: known failure."
+ break
+ fi
+ done
+ fi
- echo "$res $i $tdir - $desctxt"
+ echo "$res $i $test_subtest_id - $desctxt$directive"
+ done
done