From: Jose Luis Blanco Claraco Date: Wed, 24 Nov 2021 22:17:26 +0000 (+0100) Subject: New upstream version 0.7.3 X-Git-Tag: archive/raspbian/0.9.4-1+rpi1~1^2~56 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=c5ac9bacea77a786a6bdf9a8659e08ae5bf6fbf1;p=libfyaml.git New upstream version 0.7.3 --- c5ac9bacea77a786a6bdf9a8659e08ae5bf6fbf1 diff --git a/.tarball-version b/.tarball-version new file mode 100644 index 0000000..f38fc53 --- /dev/null +++ b/.tarball-version @@ -0,0 +1 @@ +0.7.3 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ffb66c7 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Pantelis Antoniou diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b7347ad --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +ARG IMAGE=ubuntu +FROM ${IMAGE} +# install build dependencies +RUN apt-get update -qq +RUN apt-get install --no-install-recommends -y \ + gcc autoconf automake libtool git make libyaml-dev libltdl-dev \ + pkg-config check python3 python3-pip python3-setuptools +# install sphinx doc dependencies +RUN pip3 install wheel sphinx git+http://github.com/return42/linuxdoc.git sphinx_rtd_theme sphinx-markdown-builder +# configure argument +ARG CONFIG_ARGS +ENV CONFIG_ARGS=${CONFIG_ARGS:-"--enable-debug --prefix=/usr"} +COPY . /build +WORKDIR /build +# do a maintainer clean if the directory was unclean (it can fail) +RUN make maintainer-clean >/dev/null 2>&1|| true +RUN ./bootstrap.sh 2>&1 +RUN ./configure 2>&1 ${CONFIG_ARGS} +RUN make +RUN make check +RUN make distcheck +RUN make doc-html diff --git a/Dockerfile-build-deb b/Dockerfile-build-deb new file mode 100644 index 0000000..079ffbc --- /dev/null +++ b/Dockerfile-build-deb @@ -0,0 +1,21 @@ +ARG IMAGE=ubuntu +FROM ${IMAGE} +# install build dependencies +RUN apt-get update -qq +RUN apt-get install --no-install-recommends --fix-missing -y \ + gcc autoconf automake libtool git make libyaml-dev libltdl-dev \ + pkg-config check python3 python3-pip python3-setuptools \ + devscripts build-essential lintian debhelper dh-buildinfo dh-autoreconf fakeroot \ + gnupg +# install sphinx doc dependencies +RUN pip3 install wheel sphinx git+http://github.com/return42/linuxdoc.git sphinx_rtd_theme sphinx-markdown-builder +# configure argument +ARG CONFIG_ARGS +ENV CONFIG_ARGS=${CONFIG_ARGS} +COPY . /build +WORKDIR /build +# do a maintainer clean if the directory was unclean (it can fail) +RUN make maintainer-clean >/dev/null 2>&1|| true +RUN ./bootstrap.sh 2>&1 +RUN ./configure 2>&1 ${CONFIG_ARGS} +RUN make deb diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 0000000..5aa6105 --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,16 @@ +ARG IMAGE=alpine +FROM ${IMAGE} +# install build dependencies +RUN apk update +RUN apk add musl-dev gcc autoconf automake libtool git make pkgconf bash +# configure argument +ARG CONFIG_ARGS +ENV CONFIG_ARGS=${CONFIG_ARGS:-"--enable-debug --prefix=/usr"} +COPY . /build +WORKDIR /build +# do a maintainer clean if the directory was unclean (it can fail) +RUN make maintainer-clean >/dev/null 2>&1|| true +RUN ./bootstrap.sh 2>&1 +RUN ./configure 2>&1 ${CONFIG_ARGS} +RUN make +# NOTE: no check, since alpine it's only a build test distro diff --git a/Dockerfile.centos b/Dockerfile.centos new file mode 100644 index 0000000..cb9495d --- /dev/null +++ b/Dockerfile.centos @@ -0,0 +1,16 @@ +ARG IMAGE=centos +FROM ${IMAGE} +# install build dependencies +RUN yum update -y +RUN yum install -y gcc autoconf automake libtool git make pkgconf +# configure argument +ARG CONFIG_ARGS +ENV CONFIG_ARGS=${CONFIG_ARGS:-"--enable-debug --prefix=/usr"} +COPY . /build +WORKDIR /build +# do a maintainer clean if the directory was unclean (it can fail) +RUN make maintainer-clean >/dev/null 2>&1|| true +RUN ./bootstrap.sh 2>&1 +RUN ./configure 2>&1 ${CONFIG_ARGS} +RUN make +# NOTE: no check, since alpine it's only a build test distro diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7403da9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019 Pantelis Antoniou + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..d097218 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,66 @@ +BUILT_SOURCES = .version +.version: + echo $(VERSION) > $@-t && mv $@-t $@ +dist-hook: + echo $(VERSION) > $(distdir)/.tarball-version +tarball-version: + echo $(VERSION) > .tarball-version + +# files to keep in the distribution (in case you want to boostrap) +EXTRA_DIST=bootstrap.sh \ + build-aux/shave.in build-aux/shave-libtool.in \ + build-aux/git-version-gen \ + README.md LICENSE \ + Dockerfile Dockerfile-build-deb \ + Dockerfile.alpine Dockerfile.centos + +MAINTAINERCLEANFILES = \ + Makefile.in src/Makefile.in config.h.in configure \ + install-sh ltmain.sh missing mkinstalldirs \ + config.log config.status config.guess config.sub config.h \ + build-stamp compile depcomp acinclude.m4 aclocal.m4 \ + stamp-h1 \ + ar-lib m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ + m4/lt~obsolete.m4 src/mock/.dirstamp src/mock/Makefile.in \ + config.h.in~ \ + test-driver test/Makefile.in \ + build-aux/ar-lib build-aux/compile build-aux/config.guess \ + build-aux/config.sub build-aux/depcomp build-aux/install-sh \ + build-aux/ltmain.sh build-aux/missing build-aux/tap-driver.sh + +DISTCLEANFILES = \ + .version + +clean-local: + +SUBDIRS = src test doc + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libfyaml.pc + +maintainer-clean-local: + @rm -rf install sphinx + @rm -rf install artifacts + +# extra file to put in the distribution +EXTRA_DIST += \ + scripts/create-virtual-env \ + scripts/install-linuxdoc.sh \ + scripts/run-check-errors.sh \ + scripts/run-compare-dump.sh \ + scripts/run-compare-examples.sh \ + scripts/run-compare-parse.sh \ + scripts/run-compare-scan.sh \ + scripts/run-compare-testsuite.sh \ + scripts/run-emit-check.sh \ + scripts/run-kcachegrind.sh \ + scripts/run-list-testsuite.sh \ + scripts/run-massif.sh \ + scripts/run-test.sh \ + scripts/run-valgrind.sh \ + scripts/show-desc.sh + +if HAVE_DOCKER +docker: Dockerfile + @DOCKER@ build -t libfyaml:$(VERSION) $(top_srcdir) +endif diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..239085e --- /dev/null +++ b/Makefile.in @@ -0,0 +1,1036 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_enable_debug.m4 \ + $(top_srcdir)/m4/ax_check_flag.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 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = build-aux/shave build-aux/shave-libtool \ + libfyaml.pc +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__extra_recursive_targets = doc-help-recursive doc-html-recursive \ + doc-latexpdf-recursive doc-man-recursive doc-clean-recursive \ + doc-markdown-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/libfyaml.pc.in $(top_srcdir)/build-aux/ar-lib \ + $(top_srcdir)/build-aux/compile \ + $(top_srcdir)/build-aux/config.guess \ + $(top_srcdir)/build-aux/config.sub \ + $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/build-aux/ltmain.sh \ + $(top_srcdir)/build-aux/missing \ + $(top_srcdir)/build-aux/shave-libtool.in \ + $(top_srcdir)/build-aux/shave.in \ + $(top_srcdir)/build-aux/tap-driver.sh AUTHORS build-aux/ar-lib \ + build-aux/compile build-aux/config.guess build-aux/config.sub \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_MAKEFLAGS = @AM_MAKEFLAGS@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LDFLAGS = @CHECK_LDFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBVERSION = @DEBVERSION@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCKER = @DOCKER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA = @EXTRA@ +F77 = @F77@ +FC = @FC@ +FGREP = @FGREP@ +GIT = @GIT@ +GREP = @GREP@ +HAVE_CHECK = @HAVE_CHECK@ +HAVE_COMPATIBLE_CHECK = @HAVE_COMPATIBLE_CHECK@ +HAVE_LIBYAML = @HAVE_LIBYAML@ +HAVE_NETWORK = @HAVE_NETWORK@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JQ = @JQ@ +JSONTESTSUITECHECKOUT = @JSONTESTSUITECHECKOUT@ +JSONTESTSUITEURL = @JSONTESTSUITEURL@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ +LIBYAML_LIBS = @LIBYAML_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4 = @M4@ +MAJOR = @MAJOR@ +MAKEFLAGS = @MAKEFLAGS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MCS = @MCS@ +MINOR = @MINOR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATCH = @PATCH@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PIP3 = @PIP3@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +Q = @Q@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX = @SPHINX@ +STRIP = @STRIP@ +TESTSUITECHECKOUT = @TESTSUITECHECKOUT@ +TESTSUITEURL = @TESTSUITEURL@ +V = @V@ +VERSION = @VERSION@ +YACC = @YACC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +shavedir = @shavedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +BUILT_SOURCES = .version + +# files to keep in the distribution (in case you want to boostrap) + +# extra file to put in the distribution +EXTRA_DIST = bootstrap.sh build-aux/shave.in \ + build-aux/shave-libtool.in build-aux/git-version-gen README.md \ + LICENSE Dockerfile Dockerfile-build-deb Dockerfile.alpine \ + Dockerfile.centos scripts/create-virtual-env \ + scripts/install-linuxdoc.sh scripts/run-check-errors.sh \ + scripts/run-compare-dump.sh scripts/run-compare-examples.sh \ + scripts/run-compare-parse.sh scripts/run-compare-scan.sh \ + scripts/run-compare-testsuite.sh scripts/run-emit-check.sh \ + scripts/run-kcachegrind.sh scripts/run-list-testsuite.sh \ + scripts/run-massif.sh scripts/run-test.sh \ + scripts/run-valgrind.sh scripts/show-desc.sh +MAINTAINERCLEANFILES = \ + Makefile.in src/Makefile.in config.h.in configure \ + install-sh ltmain.sh missing mkinstalldirs \ + config.log config.status config.guess config.sub config.h \ + build-stamp compile depcomp acinclude.m4 aclocal.m4 \ + stamp-h1 \ + ar-lib m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ + m4/lt~obsolete.m4 src/mock/.dirstamp src/mock/Makefile.in \ + config.h.in~ \ + test-driver test/Makefile.in \ + build-aux/ar-lib build-aux/compile build-aux/config.guess \ + build-aux/config.sub build-aux/depcomp build-aux/install-sh \ + build-aux/ltmain.sh build-aux/missing build-aux/tap-driver.sh + +DISTCLEANFILES = \ + .version + +SUBDIRS = src test doc +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libfyaml.pc +all: $(BUILT_SOURCES) config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +build-aux/shave: $(top_builddir)/config.status $(top_srcdir)/build-aux/shave.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +build-aux/shave-libtool: $(top_builddir)/config.status $(top_srcdir)/build-aux/shave-libtool.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +libfyaml.pc: $(top_builddir)/config.status $(srcdir)/libfyaml.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" +doc-help-local: +doc-html-local: +doc-latexpdf-local: +doc-man-local: +doc-clean-local: +doc-markdown-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +doc-clean: doc-clean-recursive + +doc-clean-am: doc-clean-local + +doc-help: doc-help-recursive + +doc-help-am: doc-help-local + +doc-html: doc-html-recursive + +doc-html-am: doc-html-local + +doc-latexpdf: doc-latexpdf-recursive + +doc-latexpdf-am: doc-latexpdf-local + +doc-man: doc-man-recursive + +doc-man-am: doc-man-local + +doc-markdown: doc-markdown-recursive + +doc-markdown-am: doc-markdown-local + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool clean-local cscope cscopelist-am ctags ctags-am \ + dist dist-all dist-bzip2 dist-gzip dist-hook dist-lzip \ + dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck \ + doc-clean-am doc-clean-local doc-help-am doc-help-local \ + doc-html-am doc-html-local doc-latexpdf-am doc-latexpdf-local \ + doc-man-am doc-man-local doc-markdown-am doc-markdown-local \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + maintainer-clean-local mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + +.version: + echo $(VERSION) > $@-t && mv $@-t $@ +dist-hook: + echo $(VERSION) > $(distdir)/.tarball-version +tarball-version: + echo $(VERSION) > .tarball-version + +clean-local: + +maintainer-clean-local: + @rm -rf install sphinx + @rm -rf install artifacts + +@HAVE_DOCKER_TRUE@docker: Dockerfile +@HAVE_DOCKER_TRUE@ @DOCKER@ build -t libfyaml:$(VERSION) $(top_srcdir) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/README.md b/README.md new file mode 100644 index 0000000..4883f16 --- /dev/null +++ b/README.md @@ -0,0 +1,466 @@ +# libfyaml · ![](https://github.com/pantoniou/libfyaml/workflows/Standard%20Automake%20CI/badge.svg) + +A fancy 1.2 YAML and JSON parser/writer. + +Fully feature complete YAML parser and emitter, supporting the latest YAML spec and +passing the full YAML testsuite. + +It is designed to be very efficient, avoiding copies of data, and +has no artificial limits like the 1024 character limit for implicit keys. + +libfyaml is using https://github.com/yaml/yaml-test-suite as a core part +of it's testsuite. + +## Features +* Fully supports YAML version 1.2. +* Attempts to adhere to features coming with YAML version 1.3 so that it + will be ready. +* Zero content copy operation, which means that content is never copied to + internal structures. On input types that support it (mmap files and + constant strings) that means that memory usage is kept low, and arbitrary + large content can be manipulated without problem. +* Parser may be used in event mode (like libyaml) or in document generating mode. +* Extensive programmable API capable of manipulating parsed YAML documents or + creating them from scratch. +* YAML emitter with programmable options, supporting colored output. +* Extensive testsuite for the API, the full YAML test-suite and correct + emitter operation. +* Easy printf/scanf based YAML creation and data extraction API. +* Accurate and descriptive error messages, in standard compiler format that + can be parsed by editors and developer GUIs. +* Testsuite supports running under valgrind and checking for memory leaks. No + leaks should be possible under normal operation, so it is usable for long- + running applications. + +## Contents +- [Features](#features) +- [Prerequisites](#prerequisites) +- [Building](#building) +- [Usage and examples](#usage-and-examples) +- [API documentation](#api-documentation) +- [fy-tool reference](#fy-tool-reference) +- [Missing Features](#missing-features) + +## Prerequisites + +libfyaml is primarily developed on Linux based debian distros but Apple MacOS X builds +(using homebrew) are supported as well. + +On a based debian distro (i.e. ubuntu 19.04 disco) you should install the following +dependencies: + +* `sudo apt-get install gcc autoconf automake libtool git make libltdl-dev pkg-config` + +To enable the libyaml comparison checker: + +* `sudo apt-get install libyaml-dev` + +For the API testsuite libcheck is required: + +* `sudo apt-get install check` + +And finally in order to build the sphinx based documentation: + +* `sudo apt-get install python3 python3-pip python3-setuptools` +* `pip3 install wheel sphinx git+http://github.com/return42/linuxdoc.git sphinx\_rtd\_theme sphinx-markdown-builder` + +Note that some older distros (like xenial) do not have a sufficiently recent +sphinx in their repos. In that case you can create a virtual environment +using scripts/create-virtual-env + +## Building + +``libfyaml`` uses a standard autotools based build scheme so: + +* `./bootstrap.sh` +* `./configure` +* `make` + +Will build the library and `fy-tool`. + +* `make check` + +Will run the test-suite. + +Binaries, libraries, header files and pkgconfig files maybe installed with + +* `make install` + +By default, the installation prefix will be `/usr/local`, which you can change +with the `--prefix ` option during configure. + +To build the documentation API in HTML format use: + +* `make doc-html` + +The documentation for the public API will be found in doc/\_build/html + +* `make doc-latexpdf` + +Will generate a single pdf containing everything. + +## Usage and examples + +Usage of libfyaml is somewhat similar to libyaml, but with a few notable differences. + +1. The objects of the library are opaque, they are pointers that may be used but + may not be derefenced via library users. This makes the public API not be dependent of + internal changes in the library structures. + +2. The object pointers used are guaranteed to not 'move' like libyaml object pointers + so you may embed them freely in your own structures. + +3. The convenience methods of libyaml allow you to avoid tedious iteration and code + duplication. While fully manual YAML document tree manipulation is available, if your + application is not performance sensitive when manipulating YAML, you are advised to + use the helpers. + +### Using libfyaml in your projects + +Typically you only have to include the single header file `libfyaml.h` and +link against the correct fyaml-\-\ library. + +It is recommended to use pkg-config, i.e. + +```make +CFLAGS+= `pkg-config --cflags libfyaml` +LDFLAGS+= `pkg-config --libs libfyaml` +``` + +For use in an automake based project you may use the following fragment +```bash +PKG_CHECK_MODULES(LIBFYAML, [ libfyaml ], HAVE_LIBFYAML=1, HAVE_LIBFYAML=0) + +if test "x$HAVE_LIBFYAML" != "x1" ; then + AC_MSG_ERROR([failed to find libfyaml]) +fi + +AC_SUBST(HAVE_LIBFYAML) +AC_SUBST(LIBFYAML_CFLAGS) +AC_SUBST(LIBFYAML_LIBS) +AC_DEFINE_UNQUOTED([HAVE_LIBFYAML], [$HAVE_LIBFYAML], [Define to 1 if you have libfyaml available]) +AM_CONDITIONAL([HAVE_LIBFYAML], [ test x$HAVE_LIBFYAML = x1 ]) +``` + +The examples that follow will make things clear. + +### Display libfyaml version example + +This is the minimal example that checks that you've compiled against the correct libfyaml. + +```c +/* + * fy-version.c - libfyaml version example + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + printf("%s\n", fy_library_version()); + return EXIT_SUCCESS; +} +``` + +### libfyaml example using simplified inprogram YAML generation + +This example simply parses an in-program YAML string and displays +a string. + +The standard header plus variables definition. + +```c +/* + * inprogram.c - libfyaml inprogram YAML example + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + static const char *yaml = + "invoice: 34843\n" + "date : !!str 2001-01-23\n" + "bill-to: &id001\n" + " given : Chris\n" + " family : Dumars\n" + " address:\n" + " lines: |\n" + " 458 Walkman Dr.\n" + " Suite #292\n"; + struct fy_document *fyd = NULL; + int rc, count, ret = EXIT_FAILURE; + unsigned int invoice_nr; + char given[256 + 1]; +``` + +Parsing and creating a YAML document from either the built-in +YAML, or an invoice file given on the command line: + +```c + if (argc == 1) + fyd = fy_document_build_from_string(NULL, yaml); + else + fyd = fy_document_build_from_file(NULL, argv[1]); + if (!fyd) { + fprintf(stderr, "failed to build document"); + goto fail; + } +``` + +Get the invoice number and the given name using a single call. + +```c + /* get the invoice number and the given name */ + count = fy_document_scanf(fyd, + "/invoice %u " + "/bill-to/given %256s", + &invoice_nr, given); + if (count != 2) { + fprintf(stderr, "Failed to retreive the two items\n"); + goto fail; + } + + /* print them as comments in the emitted YAML */ + printf("# invoice number was %u\n", invoice_nr); + printf("# given name is %s\n", given); +``` + +In sequence, increase the invoice number, add a spouse and a secondary +address. + +```c + rc = + /* set increased invoice number (modify existing node) */ + fy_document_insert_at(fyd, "/invoice", + fy_node_buildf(fyd, "%u", invoice_nr + 1)) || + /* add spouse (create new mapping pair) */ + fy_document_insert_at(fyd, "/bill-to", + fy_node_buildf(fyd, "spouse: %s", "Doris")) || + /* add a second address */ + fy_document_insert_at(fyd, "/bill-to", + fy_node_buildf(fyd, "delivery-address:\n" + " lines: |\n" + " 1226 Windward Ave.\n")); + if (rc) { + fprintf(stderr, "failed to insert to document\n"); + goto fail; + } +``` + +Emit the document to standard output (while sorting the keys) + +```c + /* emit the document to stdout (but sorted) */ + rc = fy_emit_document_to_fp(fyd, FYECF_DEFAULT | FYECF_SORT_KEYS, stdout); + if (rc) { + fprintf(stderr, "failed to emit document to stdout"); + goto fail; + } +``` + +Finally exit and report condition. + +```c + ret = EXIT_SUCCESS; +fail: + fy_document_destroy(fyd); /* NULL is OK */ + + return ret; +} +``` + +## API documentation + +For complete documentation of libfyaml API, visit https://pantoniou.github.io/libfyaml/ + +## fy-tool reference + +A YAML manipulation tool is included in libfyaml, aptly name `fy-tool`. +It's a multi tool application, acting differently according to the name it has +when it's invoked. There are four tool modes, namely: + +* fy-testsuite: Used for outputing a test-suite specific event stream which is + used for comparison with the expected output of the suite. +* fy-dump: General purpose YAML parser and dumper, with syntax coloring support, + visible whitespace options, and a number of output modes. +* fy-filter: YAML filtering tool allows to extract information out of a YAML + document. +* fy-join: YAML flexible join tool. + +### fy-testsuite usage + +A number of options are common in every fy-tool invocation: + +``` +Usage : fy-tool [options] [args] + +Options: + + --include, -I : Add directory to include path (default path "") + --debug-level, -d : Set debug level to (default level 3) + --indent, -i : Set dump indent to (default indent 2) + --width, -w : Set dump width to (default width 80) + --resolve, -r : Perform anchor and merge key resolution (default false) + --color, -C : Color output can be one of on, off, auto (default auto) + --visible, -V : Make all whitespace and linebreaks visible (default false) + --follow, -l : Follow aliases when using paths (default false) + --strip-labels : Strip labels when emitting (default false) + --strip-tags : Strip tags when emitting (default false) + --strip-doc : Strip document headers and indicators when emitting (default false) + --quiet, -q : Quiet operation, do not output messages (default false) + --version, -v : Display libfyaml version + --help, -h : Display help message + +``` + +``` +Usage: fy-testsuite [options] [args] + + [common options] + + Parse and dump test-suite event format + $ fy-testsuite input.yaml + ... + + Parse and dump of event example + $ echo "foo: bar" | fy-testsuite - + +STR + +DOC + +MAP + =VAL :foo + =VAL :bar + -MAP + -DOC + -STR +``` + +### fy-dump usage + +``` +Usage: fy-dump [options] [args] + +Options: + + [common options] + + --sort, -s : Perform mapping key sort (valid for dump) (default false) + --comment, -c : Output comments (experimental) (default false) + --mode, -m : Output mode can be one of original, block, flow, flow-oneline, json, json-tp, json-oneline (default original) + --streaming : Use streaming output mode (default false) + + [common options] + + Parse and dump generated YAML document tree in the original YAML form + $ fy-dump input.yaml + ... + + Parse and dump generated YAML document tree in block YAML form (and make whitespace visible) + $ fy-dump -V -mblock input.yaml + ... + + Parse and dump generated YAML document from the input string + $ fy-dump -mjson ">foo: bar" + { + "foo": "bar" + } + + Parse and dump generated YAML document from the input string (using streaming mode) + $ fy-dump --streaming ">foo: bar" + foo: bar + + Note that streaming mode can not perform document validity checks, like duplicate keys nor + support the sort keys option. +``` + +### fy-filter usage + +``` +Usage: fy-filter [options] [args] + +Options: + + [common options] + + --sort, -s : Perform mapping key sort (valid for dump) (default false) + --comment, -c : Output comments (experimental) (default false) + --mode, -m : Output mode can be one of original, block, flow, flow-oneline, json, json-tp, json-oneline (default original) + --file, -f : Use given file instead of + Note that using a string with a leading '>' is equivalent to a file with the trailing content + --file ">foo: bar" is as --file file.yaml with file.yaml "foo: bar" + + Parse and filter YAML document tree starting from the '/foo' path followed by the '/bar' path + $ fy-filter --file input.yaml /foo /bar + ... + + Parse and filter for two paths (note how a multi-document stream is produced) + $ fy-filter --file -mblock --filter --file ">{ foo: bar, baz: [ frooz, whee ] }" /foo /baz + bar + --- + - frooz + - whee + + Parse and filter YAML document in stdin (note how the key may be complex) + $ echo "{ foo: bar }: baz" | fy-filter "/{foo: bar}/" + baz +``` + +### fy-join usage + +``` +Usage: fy-join [options] [args] + +Options: + + [common options] + + --sort, -s : Perform mapping key sort (valid for dump) (default false) + --comment, -c : Output comments (experimental) (default false) + --mode, -m : Output mode can be one of original, block, flow, flow-oneline, json, json-tp, json-oneline (default original) + --file, -f : Use given file instead of + Note that using a string with a leading '>' is equivalent to a file with the trailing content + --file ">foo: bar" is as --file file.yaml with file.yaml "foo: bar" + --to, -T : Join to (default /) + --from, -F : Join from (default /) + --trim, -t : Output given path (default /) + + Parse and join two YAML files + $ fy-join file1.yaml file2.yaml + ... + + Parse and join two YAML maps + $ fy-join ">foo: bar" ">baz: frooz" + foo: bar + baz: frooz +``` + +## Missing features and omissions + +1. Windows - libfyaml is not supporting windows yet. +2. Unicode - libfyaml only supports UTF8 and has no support for wide character input. + +## Development and contributing +Feel free to send pull requests and raise issues. diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..58ff3da --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,2424 @@ +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- +# +# Copyright (C) 1999-2008, 2011-2015 Free Software Foundation, Inc. +# Written by Thomas Tanner, 1999 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 20 LTDL_INIT + +# LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE]) +# ------------------------------------------ +# DIRECTORY contains the libltdl sources. It is okay to call this +# function multiple times, as long as the same DIRECTORY is always given. +AC_DEFUN([LT_CONFIG_LTDL_DIR], +[AC_BEFORE([$0], [LTDL_INIT]) +_$0($*) +])# LT_CONFIG_LTDL_DIR + +# We break this out into a separate macro, so that we can call it safely +# internally without being caught accidentally by the sed scan in libtoolize. +m4_defun([_LT_CONFIG_LTDL_DIR], +[dnl remove trailing slashes +m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$])) +m4_case(_LTDL_DIR, + [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply '.' + m4_if(_ARG_DIR, [.], + [], + [m4_define([_LTDL_DIR], _ARG_DIR) + _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])], + [m4_if(_ARG_DIR, _LTDL_DIR, + [], + [m4_fatal([multiple libltdl directories: ']_LTDL_DIR[', ']_ARG_DIR['])])]) +m4_popdef([_ARG_DIR]) +])# _LT_CONFIG_LTDL_DIR + +# Initialise: +m4_define([_LTDL_DIR], []) + + +# _LT_BUILD_PREFIX +# ---------------- +# If Autoconf is new enough, expand to '$(top_build_prefix)', otherwise +# to '$(top_builddir)/'. +m4_define([_LT_BUILD_PREFIX], +[m4_ifdef([AC_AUTOCONF_VERSION], + [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]), + [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX], + [$(top_build_prefix)], + [$(top_builddir)/])], + [$(top_build_prefix)])], + [$(top_builddir)/])[]dnl +]) + + +# LTDL_CONVENIENCE +# ---------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with +# '$(top_build_prefix)' if available, otherwise with '$(top_builddir)/', +# and LTDLINCL will be prefixed with '$(top_srcdir)/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_build_prefix, top_builddir, and top_srcdir appropriately +# in your Makefiles. +AC_DEFUN([LTDL_CONVENIENCE], +[AC_BEFORE([$0], [LTDL_INIT])dnl +dnl Although the argument is deprecated and no longer documented, +dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one +dnl here make sure it is the same as any other declaration of libltdl's +dnl location! This also ensures lt_ltdl_dir is set when configure.ac is +dnl not yet using an explicit LT_CONFIG_LTDL_DIR. +m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl +_$0() +])# LTDL_CONVENIENCE + +# AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools, +# now we have LT_CONFIG_LTDL_DIR: +AU_DEFUN([AC_LIBLTDL_CONVENIENCE], +[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_CONVENIENCE]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], []) + + +# _LTDL_CONVENIENCE +# ----------------- +# Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]). +m4_defun([_LTDL_CONVENIENCE], +[case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; +esac +LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" +LTDLDEPS=$LIBLTDL +LTDLINCL='-I$(top_srcdir)'"${lt_ltdl_dir+/$lt_ltdl_dir}" + +AC_SUBST([LIBLTDL]) +AC_SUBST([LTDLDEPS]) +AC_SUBST([LTDLINCL]) + +# For backwards non-gettext consistent compatibility... +INCLTDL=$LTDLINCL +AC_SUBST([INCLTDL]) +])# _LTDL_CONVENIENCE + + +# LTDL_INSTALLABLE +# ---------------- +# sets LIBLTDL to the link flags for the libltdl installable library +# and LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl +# is not found, LIBLTDL will be prefixed with '$(top_build_prefix)' if +# available, otherwise with '$(top_builddir)/', and LTDLINCL will be +# prefixed with '$(top_srcdir)/' (note the single quotes!). If your +# package is not flat and you're not using automake, define top_build_prefix, +# top_builddir, and top_srcdir appropriately in your Makefiles. +# In the future, this macro may have to be called after LT_INIT. +AC_DEFUN([LTDL_INSTALLABLE], +[AC_BEFORE([$0], [LTDL_INIT])dnl +dnl Although the argument is deprecated and no longer documented, +dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one +dnl here make sure it is the same as any other declaration of libltdl's +dnl location! This also ensures lt_ltdl_dir is set when configure.ac is +dnl not yet using an explicit LT_CONFIG_LTDL_DIR. +m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl +_$0() +])# LTDL_INSTALLABLE + +# AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools, +# now we have LT_CONFIG_LTDL_DIR: +AU_DEFUN([AC_LIBLTDL_INSTALLABLE], +[_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) +_LTDL_INSTALLABLE]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], []) + + +# _LTDL_INSTALLABLE +# ----------------- +# Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]). +m4_defun([_LTDL_INSTALLABLE], +[if test -f "$prefix/lib/libltdl.la"; then + lt_save_LDFLAGS=$LDFLAGS + LDFLAGS="-L$prefix/lib $LDFLAGS" + AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes]) + LDFLAGS=$lt_save_LDFLAGS + if test yes = "${lt_lib_ltdl-no}"; then + if test yes != "$enable_ltdl_install"; then + # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install + AC_MSG_WARN([not overwriting libltdl at $prefix, force with '--enable-ltdl-install']) + enable_ltdl_install=no + fi + elif test no = "$enable_ltdl_install"; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + fi +fi + +# If configure.ac declared an installable ltdl, and the user didn't override +# with --disable-ltdl-install, we will install the shipped libltdl. +case $enable_ltdl_install in + no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL=-lltdl + LTDLDEPS= + LTDLINCL= + ;; + *) enable_ltdl_install=yes + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" + LTDLDEPS=$LIBLTDL + LTDLINCL='-I$(top_srcdir)'"${lt_ltdl_dir+/$lt_ltdl_dir}" + ;; +esac + +AC_SUBST([LIBLTDL]) +AC_SUBST([LTDLDEPS]) +AC_SUBST([LTDLINCL]) + +# For backwards non-gettext consistent compatibility... +INCLTDL=$LTDLINCL +AC_SUBST([INCLTDL]) +])# LTDL_INSTALLABLE + + +# _LTDL_MODE_DISPATCH +# ------------------- +m4_define([_LTDL_MODE_DISPATCH], +[dnl If _LTDL_DIR is '.', then we are configuring libltdl itself: +m4_if(_LTDL_DIR, [], + [], + dnl if _LTDL_MODE was not set already, the default value is 'subproject': + [m4_case(m4_default(_LTDL_MODE, [subproject]), + [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR) + _LT_SHELL_INIT([lt_dlopen_dir=$lt_ltdl_dir])], + [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir=$lt_ltdl_dir; lt_libobj_prefix=$lt_ltdl_dir/])], + [recursive], [], + [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl +dnl Be careful not to expand twice: +m4_define([$0], []) +])# _LTDL_MODE_DISPATCH + + +# _LT_LIBOBJ(MODULE_NAME) +# ----------------------- +# Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead +# of into LIBOBJS. +AC_DEFUN([_LT_LIBOBJ], [ + m4_pattern_allow([^_LT_LIBOBJS$]) + _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" +])# _LT_LIBOBJS + + +# LTDL_INIT([OPTIONS]) +# -------------------- +# Clients of libltdl can use this macro to allow the installer to +# choose between a shipped copy of the ltdl sources or a preinstalled +# version of the library. If the shipped ltdl sources are not in a +# subdirectory named libltdl, the directory name must be given by +# LT_CONFIG_LTDL_DIR. +AC_DEFUN([LTDL_INIT], +[dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +dnl We need to keep our own list of libobjs separate from our parent project, +dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while +dnl we look for our own LIBOBJs. +m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) +m4_pushdef([AC_LIBSOURCES]) + +dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: +m4_if(_LTDL_MODE, [], + [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) + m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], + [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) + +AC_ARG_WITH([included_ltdl], + [AS_HELP_STRING([--with-included-ltdl], + [use the GNU ltdl sources included here])]) + +if test yes != "$with_included_ltdl"; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + AC_CHECK_HEADER([ltdl.h], + [AC_CHECK_DECL([lt_dlinterface_register], + [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], + [with_included_ltdl=no], + [with_included_ltdl=yes])], + [with_included_ltdl=yes], + [AC_INCLUDES_DEFAULT + #include ])], + [with_included_ltdl=yes], + [AC_INCLUDES_DEFAULT] + ) +fi + +dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE +dnl was called yet, then for old times' sake, we assume libltdl is in an +dnl eponymous directory: +AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) + +AC_ARG_WITH([ltdl_include], + [AS_HELP_STRING([--with-ltdl-include=DIR], + [use the ltdl headers installed in DIR])]) + +if test -n "$with_ltdl_include"; then + if test -f "$with_ltdl_include/ltdl.h"; then : + else + AC_MSG_ERROR([invalid ltdl include directory: '$with_ltdl_include']) + fi +else + with_ltdl_include=no +fi + +AC_ARG_WITH([ltdl_lib], + [AS_HELP_STRING([--with-ltdl-lib=DIR], + [use the libltdl.la installed in DIR])]) + +if test -n "$with_ltdl_lib"; then + if test -f "$with_ltdl_lib/libltdl.la"; then : + else + AC_MSG_ERROR([invalid ltdl library directory: '$with_ltdl_lib']) + fi +else + with_ltdl_lib=no +fi + +case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in + ,yes,no,no,) + m4_case(m4_default(_LTDL_TYPE, [convenience]), + [convenience], [_LTDL_CONVENIENCE], + [installable], [_LTDL_INSTALLABLE], + [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) + ;; + ,no,no,no,) + # If the included ltdl is not to be used, then use the + # preinstalled libltdl we found. + AC_DEFINE([HAVE_LTDL], [1], + [Define this if a modern libltdl is already installed]) + LIBLTDL=-lltdl + LTDLDEPS= + LTDLINCL= + ;; + ,no*,no,*) + AC_MSG_ERROR(['--with-ltdl-include' and '--with-ltdl-lib' options must be used together]) + ;; + *) with_included_ltdl=no + LIBLTDL="-L$with_ltdl_lib -lltdl" + LTDLDEPS= + LTDLINCL=-I$with_ltdl_include + ;; +esac +INCLTDL=$LTDLINCL + +# Report our decision... +AC_MSG_CHECKING([where to find libltdl headers]) +AC_MSG_RESULT([$LTDLINCL]) +AC_MSG_CHECKING([where to find libltdl library]) +AC_MSG_RESULT([$LIBLTDL]) + +_LTDL_SETUP + +dnl restore autoconf definition. +m4_popdef([AC_LIBOBJ]) +m4_popdef([AC_LIBSOURCES]) + +AC_CONFIG_COMMANDS_PRE([ + _ltdl_libobjs= + _ltdl_ltlibobjs= + if test -n "$_LT_LIBOBJS"; then + # Remove the extension. + _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do + _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" + _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" + done + fi + AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) + AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) +]) + +# Only expand once: +m4_define([LTDL_INIT]) +])# LTDL_INIT + +# Old names: +AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) +AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) +AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIB_LTDL], []) +dnl AC_DEFUN([AC_WITH_LTDL], []) +dnl AC_DEFUN([LT_WITH_LTDL], []) + + +# _LTDL_SETUP +# ----------- +# Perform all the checks necessary for compilation of the ltdl objects +# -- including compiler checks and header checks. This is a public +# interface mainly for the benefit of libltdl's own configure.ac, most +# other users should call LTDL_INIT instead. +AC_DEFUN([_LTDL_SETUP], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_SYS_MODULE_EXT])dnl +AC_REQUIRE([LT_SYS_MODULE_PATH])dnl +AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl +AC_REQUIRE([LT_LIB_DLLOAD])dnl +AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl +AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl +AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl +AC_REQUIRE([LT_FUNC_ARGZ])dnl + +m4_require([_LT_CHECK_OBJDIR])dnl +m4_require([_LT_HEADER_DLFCN])dnl +m4_require([_LT_CHECK_DLPREOPEN])dnl +m4_require([_LT_DECL_SED])dnl + +dnl Don't require this, or it will be expanded earlier than the code +dnl that sets the variables it relies on: +_LT_ENABLE_INSTALL + +dnl _LTDL_MODE specific code must be called at least once: +_LTDL_MODE_DISPATCH + +# In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS +# the user used. This is so that ltdl.h can pick up the parent projects +# config.h file, The first file in AC_CONFIG_HEADERS must contain the +# definitions required by ltdl.c. +# FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). +AC_CONFIG_COMMANDS_PRE([dnl +m4_pattern_allow([^LT_CONFIG_H$])dnl +m4_ifset([AH_HEADER], + [LT_CONFIG_H=AH_HEADER], + [m4_ifset([AC_LIST_HEADERS], + [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's|^[[ ]]*||;s|[[ :]].*$||'`], + [])])]) +AC_SUBST([LT_CONFIG_H]) + +AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], + [], [], [AC_INCLUDES_DEFAULT]) + +AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) +AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) + +m4_pattern_allow([LT_LIBEXT])dnl +AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) + +name= +eval "lt_libprefix=\"$libname_spec\"" +m4_pattern_allow([LT_LIBPREFIX])dnl +AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix]) + +name=ltdl +eval "LTDLOPEN=\"$libname_spec\"" +AC_SUBST([LTDLOPEN]) +])# _LTDL_SETUP + + +# _LT_ENABLE_INSTALL +# ------------------ +m4_define([_LT_ENABLE_INSTALL], +[AC_ARG_ENABLE([ltdl-install], + [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])]) + +case ,$enable_ltdl_install,$enable_ltdl_convenience in + *yes*) ;; + *) enable_ltdl_convenience=yes ;; +esac + +m4_ifdef([AM_CONDITIONAL], +[AM_CONDITIONAL(INSTALL_LTDL, test no != "${enable_ltdl_install-no}") + AM_CONDITIONAL(CONVENIENCE_LTDL, test no != "${enable_ltdl_convenience-no}")]) +])# _LT_ENABLE_INSTALL + + +# LT_SYS_DLOPEN_DEPLIBS +# --------------------- +AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + [lt_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + lt_cv_sys_dlopen_deplibs=unknown + case $host_os in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this 'case' here to explicitly catch those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + aix[[4-9]]*) + lt_cv_sys_dlopen_deplibs=yes + ;; + amigaos*) + case $host_cpu in + powerpc) + lt_cv_sys_dlopen_deplibs=no + ;; + esac + ;; + bitrig*) + lt_cv_sys_dlopen_deplibs=yes + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + lt_cv_sys_dlopen_deplibs=yes + ;; + freebsd* | dragonfly*) + lt_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + lt_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + lt_cv_sys_dlopen_deplibs=yes + ;; + interix*) + lt_cv_sys_dlopen_deplibs=yes + ;; + irix[[12345]]*|irix6.[[01]]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + lt_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + lt_cv_sys_dlopen_deplibs=yes + ;; + netbsd* | netbsdelf*-gnu) + lt_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + lt_cv_sys_dlopen_deplibs=yes + ;; + osf[[1234]]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explicitly say 'no'. + lt_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to 'yes'. Without it, it would be 'no'. + lt_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say 'yes'. + lt_cv_sys_dlopen_deplibs=yes + ;; + qnx*) + lt_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + lt_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) +if test yes != "$lt_cv_sys_dlopen_deplibs"; then + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen().]) +fi +])# LT_SYS_DLOPEN_DEPLIBS + +# Old name: +AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], []) + + +# LT_SYS_MODULE_EXT +# ----------------- +AC_DEFUN([LT_SYS_MODULE_EXT], +[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([what extension is used for runtime loadable modules], + [libltdl_cv_shlibext], +[ +module=yes +eval libltdl_cv_shlibext=$shrext_cmds +module=no +eval libltdl_cv_shrext=$shrext_cmds + ]) +if test -n "$libltdl_cv_shlibext"; then + m4_pattern_allow([LT_MODULE_EXT])dnl + AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], + [Define to the extension used for runtime loadable modules, say, ".so".]) +fi +if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then + m4_pattern_allow([LT_SHARED_EXT])dnl + AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"], + [Define to the shared library suffix, say, ".dylib".]) +fi +if test -n "$shared_archive_member_spec"; then + m4_pattern_allow([LT_SHARED_LIB_MEMBER])dnl + AC_DEFINE_UNQUOTED([LT_SHARED_LIB_MEMBER], ["($shared_archive_member_spec.o)"], + [Define to the shared archive member specification, say "(shr.o)".]) +fi +])# LT_SYS_MODULE_EXT + +# Old name: +AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SHLIBEXT], []) + + +# LT_SYS_MODULE_PATH +# ------------------ +AC_DEFUN([LT_SYS_MODULE_PATH], +[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([what variable specifies run-time module search path], + [lt_cv_module_path_var], [lt_cv_module_path_var=$shlibpath_var]) +if test -n "$lt_cv_module_path_var"; then + m4_pattern_allow([LT_MODULE_PATH_VAR])dnl + AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], + [Define to the name of the environment variable that determines the run-time module search path.]) +fi +])# LT_SYS_MODULE_PATH + +# Old name: +AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SHLIBPATH], []) + + +# LT_SYS_DLSEARCH_PATH +# -------------------- +AC_DEFUN([LT_SYS_DLSEARCH_PATH], +[m4_require([_LT_SYS_DYNAMIC_LINKER])dnl +AC_CACHE_CHECK([for the default library search path], + [lt_cv_sys_dlsearch_path], + [lt_cv_sys_dlsearch_path=$sys_lib_dlsearch_path_spec]) +if test -n "$lt_cv_sys_dlsearch_path"; then + sys_dlsearch_path= + for dir in $lt_cv_sys_dlsearch_path; do + if test -z "$sys_dlsearch_path"; then + sys_dlsearch_path=$dir + else + sys_dlsearch_path=$sys_dlsearch_path$PATH_SEPARATOR$dir + fi + done + m4_pattern_allow([LT_DLSEARCH_PATH])dnl + AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], + [Define to the system default library search path.]) +fi +])# LT_SYS_DLSEARCH_PATH + +# Old name: +AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], []) + + +# _LT_CHECK_DLPREOPEN +# ------------------- +m4_defun([_LT_CHECK_DLPREOPEN], +[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], + [libltdl_cv_preloaded_symbols], + [if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + ]) +if test yes = "$libltdl_cv_preloaded_symbols"; then + AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], + [Define if libtool can extract symbol lists from object files.]) +fi +])# _LT_CHECK_DLPREOPEN + + +# LT_LIB_DLLOAD +# ------------- +AC_DEFUN([LT_LIB_DLLOAD], +[m4_pattern_allow([^LT_DLLOADERS$]) +LT_DLLOADERS= +AC_SUBST([LT_DLLOADERS]) + +AC_LANG_PUSH([C]) +lt_dlload_save_LIBS=$LIBS + +LIBADD_DLOPEN= +AC_SEARCH_LIBS([dlopen], [dl], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + if test "$ac_cv_search_dlopen" != "none required"; then + LIBADD_DLOPEN=-ldl + fi + libltdl_cv_lib_dl_dlopen=yes + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H +# include +#endif + ]], [[dlopen(0, 0);]])], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + libltdl_cv_func_dlopen=yes + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], + [AC_CHECK_LIB([svld], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DLOPEN=-lsvld libltdl_cv_func_dlopen=yes + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) +if test yes = "$libltdl_cv_func_dlopen" || test yes = "$libltdl_cv_lib_dl_dlopen" +then + lt_save_LIBS=$LIBS + LIBS="$LIBS $LIBADD_DLOPEN" + AC_CHECK_FUNCS([dlerror]) + LIBS=$lt_save_LIBS +fi +AC_SUBST([LIBADD_DLOPEN]) + +LIBADD_SHL_LOAD= +AC_CHECK_FUNC([shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" + LIBADD_SHL_LOAD=-ldld])]) +AC_SUBST([LIBADD_SHL_LOAD]) + +case $host_os in +darwin[[1567]].*) +# We only want this for pre-Mac OS X 10.4. + AC_CHECK_FUNC([_dyld_func_lookup], + [AC_DEFINE([HAVE_DYLD], [1], + [Define if you have the _dyld_func_lookup function.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) + ;; +beos*) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" + ;; +cygwin* | mingw* | pw32*) + AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include ]]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" + ;; +esac + +AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) +AC_SUBST([LIBADD_DLD_LINK]) + +m4_pattern_allow([^LT_DLPREOPEN$]) +LT_DLPREOPEN= +if test -n "$LT_DLLOADERS" +then + for lt_loader in $LT_DLLOADERS; do + LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " + done + AC_DEFINE([HAVE_LIBDLLOADER], [1], + [Define if libdlloader will be built on this platform]) +fi +AC_SUBST([LT_DLPREOPEN]) + +dnl This isn't used anymore, but set it for backwards compatibility +LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" +AC_SUBST([LIBADD_DL]) + +LIBS=$lt_dlload_save_LIBS +AC_LANG_POP +])# LT_LIB_DLLOAD + +# Old name: +AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_DLLIB], []) + + +# LT_SYS_SYMBOL_USCORE +# -------------------- +# does the compiler prefix global symbols with an underscore? +AC_DEFUN([LT_SYS_SYMBOL_USCORE], +[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +AC_CACHE_CHECK([for _ prefix in compiled symbols], + [lt_cv_sys_symbol_underscore], + [lt_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext <<_LT_EOF +void nm_test_func(){} +int main(){nm_test_func;return 0;} +_LT_EOF + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + lt_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.c >&AS_MESSAGE_LOG_FD + fi + rm -rf conftest* + ]) + sys_symbol_underscore=$lt_cv_sys_symbol_underscore + AC_SUBST([sys_symbol_underscore]) +])# LT_SYS_SYMBOL_USCORE + +# Old name: +AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], []) + + +# LT_FUNC_DLSYM_USCORE +# -------------------- +AC_DEFUN([LT_FUNC_DLSYM_USCORE], +[AC_REQUIRE([_LT_COMPILER_PIC])dnl for lt_prog_compiler_wl +AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl for lt_cv_sys_symbol_underscore +AC_REQUIRE([LT_SYS_MODULE_EXT])dnl for libltdl_cv_shlibext +if test yes = "$lt_cv_sys_symbol_underscore"; then + if test yes = "$libltdl_cv_func_dlopen" || test yes = "$libltdl_cv_lib_dl_dlopen"; then + AC_CACHE_CHECK([whether we have to add an underscore for dlsym], + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + dlsym_uscore_save_LIBS=$LIBS + LIBS="$LIBS $LIBADD_DLOPEN" + libname=conftmod # stay within 8.3 filename limits! + cat >$libname.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif +int fnord () { return 42; }] +_LT_EOF + + # ltfn_module_cmds module_cmds + # Execute tilde-delimited MODULE_CMDS with environment primed for + # $module_cmds or $archive_cmds type content. + ltfn_module_cmds () + {( # subshell avoids polluting parent global environment + module_cmds_save_ifs=$IFS; IFS='~' + for cmd in @S|@1; do + IFS=$module_cmds_save_ifs + libobjs=$libname.$ac_objext; lib=$libname$libltdl_cv_shlibext + rpath=/not-exists; soname=$libname$libltdl_cv_shlibext; output_objdir=. + major=; versuffix=; verstring=; deplibs= + ECHO=echo; wl=$lt_prog_compiler_wl; allow_undefined_flag= + eval $cmd + done + IFS=$module_cmds_save_ifs + )} + + # Compile a loadable module using libtool macro expansion results. + $CC $pic_flag -c $libname.$ac_ext + ltfn_module_cmds "${module_cmds:-$archive_cmds}" + + # Try to fetch fnord with dlsym(). + libltdl_dlunknown=0; libltdl_dlnouscore=1; libltdl_dluscore=2 + cat >conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" +#if HAVE_DLFCN_H +#include +#endif +#include +#ifndef RTLD_GLOBAL +# ifdef DL_GLOBAL +# define RTLD_GLOBAL DL_GLOBAL +# else +# define RTLD_GLOBAL 0 +# endif +#endif +#ifndef RTLD_NOW +# ifdef DL_NOW +# define RTLD_NOW DL_NOW +# else +# define RTLD_NOW 0 +# endif +#endif +int main () { + void *handle = dlopen ("`pwd`/$libname$libltdl_cv_shlibext", RTLD_GLOBAL|RTLD_NOW); + int status = $libltdl_dlunknown; + if (handle) { + if (dlsym (handle, "fnord")) + status = $libltdl_dlnouscore; + else { + if (dlsym (handle, "_fnord")) + status = $libltdl_dluscore; + else + puts (dlerror ()); + } + dlclose (handle); + } else + puts (dlerror ()); + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + libltdl_status=$? + case x$libltdl_status in + x$libltdl_dlnouscore) libltdl_cv_need_uscore=no ;; + x$libltdl_dluscore) libltdl_cv_need_uscore=yes ;; + x*) libltdl_cv_need_uscore=unknown ;; + esac + fi + rm -rf conftest* $libname* + LIBS=$dlsym_uscore_save_LIBS + ]) + fi +fi + +if test yes = "$libltdl_cv_need_uscore"; then + AC_DEFINE([NEED_USCORE], [1], + [Define if dlsym() requires a leading underscore in symbol names.]) +fi +])# LT_FUNC_DLSYM_USCORE + +# Old name: +AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) + +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# AM_EXTRA_RECURSIVE_TARGETS -*- Autoconf -*- + +# Copyright (C) 2012-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_EXTRA_RECURSIVE_TARGETS +# -------------------------- +# Define the list of user recursive targets. This macro exists only to +# be traced by Automake, which will ensure that a proper definition of +# user-defined recursive targets (and associated rules) is propagated +# into all the generated Makefiles. +# TODO: We should really reject non-literal arguments here... +AC_DEFUN([AM_EXTRA_RECURSIVE_TARGETS], []) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_check_enable_debug.m4]) +m4_include([m4/ax_check_flag.m4]) +m4_include([m4/ax_pthread.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/shave.m4]) diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..5d39576 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# potato autoconf +touch build-aux/tap-driver.sh +autoreconf -fvi diff --git a/build-aux/ar-lib b/build-aux/ar-lib new file mode 100755 index 0000000..05094d3 --- /dev/null +++ b/build-aux/ar-lib @@ -0,0 +1,270 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2012-03-01.08; # UTC + +# Copyright (C) 2010-2017 Free Software Foundation, Inc. +# Written by Peter Rosin . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/config.guess b/build-aux/config.guess new file mode 100755 index 0000000..f50dcdb --- /dev/null +++ b/build-aux/config.guess @@ -0,0 +1,1480 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-24' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > "$dummy.c" ; + for c in cc gcc c89 c99 ; do + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval "$set_cc_for_build" + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + then + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + eval "$set_cc_for_build" + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + i*86:Minix:*:*) + echo "$UNAME_MACHINE"-pc-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + eval "$set_cc_for_build" + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + if objdump -f /bin/sh | grep -q elf32-x86-64; then + echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 + else + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + fi + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval "$set_cc_for_build" + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/build-aux/config.sub b/build-aux/config.sub new file mode 100755 index 0000000..1d8e98b --- /dev/null +++ b/build-aux/config.sub @@ -0,0 +1,1801 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | wasm32 \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | wasm32-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-pc + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2*) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + x64) + basic_machine=x86_64-pc + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases that might get confused + # with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4*) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + pru-*) + os=-elf + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` + ;; +esac + +echo "$basic_machine$os" +exit + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/build-aux/depcomp b/build-aux/depcomp new file mode 100755 index 0000000..b39f98f --- /dev/null +++ b/build-aux/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2016-01-11.22; # UTC + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen new file mode 100755 index 0000000..b287cb7 --- /dev/null +++ b/build-aux/git-version-gen @@ -0,0 +1,160 @@ +#!/bin/sh +# Print a version string. +scriptversion=2011-02-19.19; # UTC + +# Copyright (C) 2007-2011 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/. +# It may be run two ways: +# - from a git repository in which the "git describe" command below +# produces useful output (thus requiring at least one signed tag) +# - from a non-git-repo directory containing a .tarball-version file, which +# presumes this script is invoked like "./git-version-gen .tarball-version". + +# In order to use intra-version strings in your project, you will need two +# separate generated version string files: +# +# .tarball-version - present only in a distribution tarball, and not in +# a checked-out repository. Created with contents that were learned at +# the last time autoconf was run, and used by git-version-gen. Must not +# be present in either $(srcdir) or $(builddir) for git-version-gen to +# give accurate answers during normal development with a checked out tree, +# but must be present in a tarball when there is no version control system. +# Therefore, it cannot be used in any dependencies. GNUmakefile has +# hooks to force a reconfigure at distribution time to get the value +# correct, without penalizing normal development with extra reconfigures. +# +# .version - present in a checked-out repository and in a distribution +# tarball. Usable in dependencies, particularly for files that don't +# want to depend on config.h but do want to track version changes. +# Delete this file prior to any autoconf run where you want to rebuild +# files to pick up a version string change; and leave it stale to +# minimize rebuild time after unrelated changes to configure sources. +# +# It is probably wise to add these two files to .gitignore, so that you +# don't accidentally commit either generated file. +# +# Use the following line in your configure.ac, so that $(VERSION) will +# automatically be up-to-date each time configure is run (and note that +# since configure.ac no longer includes a version string, Makefile rules +# should not depend on configure.ac for version updates). +# +# AC_INIT([GNU project], +# m4_esyscmd([build-aux/git-version-gen .tarball-version]), +# [bug-project@example]) +# +# Then use the following lines in your Makefile.am, so that .version +# will be present for dependencies, and so that .tarball-version will +# exist in distribution tarballs. +# +# BUILT_SOURCES = $(top_srcdir)/.version +# $(top_srcdir)/.version: +# echo $(VERSION) > $@-t && mv $@-t $@ +# dist-hook: +# echo $(VERSION) > $(distdir)/.tarball-version + +case $# in + 1|2) ;; + *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version" \ + '[TAG-NORMALIZATION-SED-SCRIPT]' + exit 1;; +esac + +tarball_version_file=$1 +tag_sed_script="${2:-s/x/x/}" +nl=' +' + +# Avoid meddling by environment variable of the same name. +v= +v_from_git= + +# First see if there is a tarball-only version file. +# then try "git describe", then default. +if test -f $tarball_version_file +then + v=`cat $tarball_version_file` || v= + case $v in + *$nl*) v= ;; # reject multi-line output + [0-9]*) ;; + *) v= ;; + esac + test -z "$v" \ + && echo "$0: WARNING: $tarball_version_file is missing or damaged" 1>&2 +fi + +if test -n "$v" +then + : # use $v +# Otherwise, if there is at least one git commit involving the working +# directory, and "git describe" output looks sensible, use that to +# derive a version string. +elif test "`git log -1 --pretty=format:x . 2>&1`" = x \ + && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \ + || git describe --abbrev=4 HEAD 2>/dev/null` \ + && v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \ + && case $v in + v[0-9]*) ;; + *) (exit 1) ;; + esac +then + + # Remove the "g" in git describe's output string, to save a byte. + v=`echo "$v" | sed 's/-g/-/'`; + + case $v in + *-rc*) + ;; + *) + # Change the first '-' to a '.', so version-comparing tools work properly. + v=`echo "$v" | sed 's/-/./'`; + ;; + esac + v_from_git=1 +else + v=UNKNOWN +fi + +v=`echo "$v" |sed 's/^v//'` + +# Test whether to append the "-dirty" suffix only if the version +# string we're using came from git. I.e., skip the test if it's "UNKNOWN" +# or if it came from .tarball-version. +if test -n "$v_from_git"; then + # Don't declare a version "dirty" merely because a time stamp has changed. + git update-index --refresh > /dev/null 2>&1 + + dirty=`exec 2>/dev/null;git diff-index --name-only HEAD` || dirty= + case "$dirty" in + '') ;; + *) # Append the suffix only if there isn't one already. + case $v in + *-dirty) ;; + *) v="$v-dirty" ;; + esac ;; + esac +fi + +# Omit the trailing newline, so that m4_esyscmd can use the result directly. +echo "$v" | tr -d "$nl" + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/install-sh b/build-aux/install-sh new file mode 100755 index 0000000..59990a1 --- /dev/null +++ b/build-aux/install-sh @@ -0,0 +1,508 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2014-09-12.12; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh new file mode 100644 index 0000000..a736cf9 --- /dev/null +++ b/build-aux/ltmain.sh @@ -0,0 +1,11156 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-2" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname $scriptversion Debian-2.4.6-2 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/build-aux/missing b/build-aux/missing new file mode 100755 index 0000000..f62bbae --- /dev/null +++ b/build-aux/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/shave-libtool.in b/build-aux/shave-libtool.in new file mode 100644 index 0000000..0f7fb12 --- /dev/null +++ b/build-aux/shave-libtool.in @@ -0,0 +1,109 @@ +#!/bin/sh +# +# Copyright (c) 2009, Damien Lespiau +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# we need sed +SED=@SED@ +if test -z "$SED" ; then +SED=sed +fi + +lt_unmangle () +{ + last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'` +} + +# the real libtool to use +LIBTOOL="$1" +shift + +# if 1, don't print anything, the underlaying wrapper will do it +pass_though=0 + +# scan the arguments, keep the right ones for libtool, and discover the mode +preserved_args= + +# have we seen the --tag option of libtool in the command line ? +tag_seen=0 + +while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --mode=*) + mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'` + preserved_args="$preserved_args $opt" + ;; + -o) + lt_output="$1" + preserved_args="$preserved_args $opt" + ;; + --tag=*) + tag_seen=1 + preserved_args="$preserved_args $opt" + ;; + *) + preserved_args="$preserved_args '$opt'" + ;; + esac +done + +case "$mode" in +compile) + # shave will be called and print the actual CC/CXX/LINK line + preserved_args="$preserved_args --shave-mode=$mode" + pass_though=1 + ;; +link) + preserved_args="$preserved_args --shave-mode=$mode" + Q=" LINK " + ;; +*) + # let's u + # echo "*** libtool: Unimplemented mode: $mode, fill a bug report" + ;; +esac + +lt_unmangle "$lt_output" +output=$last_result + +# automake does not add a --tag switch to its libtool invocation when +# assembling a .s file and rely on libtool to infer the right action based +# on the compiler name. As shave is using CC to hook a wrapper, libtool gets +# confused. Let's detect these cases and add a --tag=CC option. +tag="" +if test $tag_seen -eq 0 -a x"$mode" = xcompile; then + tag="--tag=CC" +fi + +if test -z $V; then + if test $pass_though -eq 0; then + echo "$Q$output" + fi + eval "$LIBTOOL --silent $tag $preserved_args" +else + echo $LIBTOOL $tag $preserved_args + eval "$LIBTOOL $tag $preserved_args" +fi diff --git a/build-aux/shave.in b/build-aux/shave.in new file mode 100644 index 0000000..689badc --- /dev/null +++ b/build-aux/shave.in @@ -0,0 +1,130 @@ +#!/bin/sh +# +# Copyright (c) 2009, Damien Lespiau +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# we need sed +SED=@SED@ +if test -z "$SED" ; then +SED=sed +fi + +lt_unmangle () +{ + last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'` +} + +# the tool to wrap (cc, cxx, ar, ranlib, ..) +tool="$1" +shift + +# the reel tool (to call) +REEL_TOOL="$1" +shift + +pass_through=0 +preserved_args= +while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --shave-mode=*) + mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'` + ;; + -o) + lt_output="$1" + preserved_args="$preserved_args $opt" + ;; + -out:*|/out:*) + lt_output="${opt#-out:}" + preserved_args="$preserved_args $opt" + ;; + *.l) + if [ "$tool" = "lex" ]; then + lt_output="$opt" + fi + preserved_args="$preserved_args $opt" + ;; + *.y) + if [ "$tool" = "yacc" ]; then + lt_output="$opt" + fi + preserved_args="$preserved_args $opt" + ;; + *) + preserved_args="$preserved_args '$opt'" + ;; + esac +done + +# mode=link is handled in the libtool wrapper +case "$mode,$tool" in +link,*) + pass_through=1 + ;; +*,cxx) + Q=" CXX " + ;; +*,ccas) + Q=" AS " + ;; +*,cc) + Q=" CC " + ;; +*,fc) + Q=" FC " + ;; +*,f77) + Q=" F77 " + ;; +*,objc) + Q=" OBJC " + ;; +*,mcs) + Q=" MCS " + ;; +*,lex) + Q=" LEX " + ;; +*,yacc) + Q=" YACC " + ;; +*,*) + # should not happen + Q=" CC " + ;; +esac + +lt_unmangle "$lt_output" +output=$last_result + +if test -z $V; then + if test $pass_through -eq 0; then + echo "$Q$output" + fi + eval "$REEL_TOOL $preserved_args" +else + echo $REEL_TOOL $preserved_args + eval "$REEL_TOOL $preserved_args" +fi diff --git a/build-aux/tap-driver.sh b/build-aux/tap-driver.sh new file mode 100755 index 0000000..82efa96 --- /dev/null +++ b/build-aux/tap-driver.sh @@ -0,0 +1,651 @@ +#! /bin/sh +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +scriptversion=2013-12-23.17; # UTC + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +me=tap-driver.sh + +fatal () +{ + echo "$me: fatal: $*" >&2 + exit 1 +} + +usage_error () +{ + echo "$me: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat < + # + trap : 1 3 2 13 15 + if test $merge -gt 0; then + exec 2>&1 + else + exec 2>&3 + fi + "$@" + echo $? + ) | LC_ALL=C ${AM_TAP_AWK-awk} \ + -v me="$me" \ + -v test_script_name="$test_name" \ + -v log_file="$log_file" \ + -v trs_file="$trs_file" \ + -v expect_failure="$expect_failure" \ + -v merge="$merge" \ + -v ignore_exit="$ignore_exit" \ + -v comments="$comments" \ + -v diag_string="$diag_string" \ +' +# TODO: the usages of "cat >&3" below could be optimized when using +# GNU awk, and/on on systems that supports /dev/fd/. + +# Implementation note: in what follows, `result_obj` will be an +# associative array that (partly) simulates a TAP result object +# from the `TAP::Parser` perl module. + +## ----------- ## +## FUNCTIONS ## +## ----------- ## + +function fatal(msg) +{ + print me ": " msg | "cat >&2" + exit 1 +} + +function abort(where) +{ + fatal("internal error " where) +} + +# Convert a boolean to a "yes"/"no" string. +function yn(bool) +{ + return bool ? "yes" : "no"; +} + +function add_test_result(result) +{ + if (!test_results_index) + test_results_index = 0 + test_results_list[test_results_index] = result + test_results_index += 1 + test_results_seen[result] = 1; +} + +# Whether the test script should be re-run by "make recheck". +function must_recheck() +{ + for (k in test_results_seen) + if (k != "XFAIL" && k != "PASS" && k != "SKIP") + return 1 + return 0 +} + +# Whether the content of the log file associated to this test should +# be copied into the "global" test-suite.log. +function copy_in_global_log() +{ + for (k in test_results_seen) + if (k != "PASS") + return 1 + return 0 +} + +function get_global_test_result() +{ + if ("ERROR" in test_results_seen) + return "ERROR" + if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) + return "FAIL" + all_skipped = 1 + for (k in test_results_seen) + if (k != "SKIP") + all_skipped = 0 + if (all_skipped) + return "SKIP" + return "PASS"; +} + +function stringify_result_obj(result_obj) +{ + if (result_obj["is_unplanned"] || result_obj["number"] != testno) + return "ERROR" + + if (plan_seen == LATE_PLAN) + return "ERROR" + + if (result_obj["directive"] == "TODO") + return result_obj["is_ok"] ? "XPASS" : "XFAIL" + + if (result_obj["directive"] == "SKIP") + return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; + + if (length(result_obj["directive"])) + abort("in function stringify_result_obj()") + + return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL +} + +function decorate_result(result) +{ + color_name = color_for_result[result] + if (color_name) + return color_map[color_name] "" result "" color_map["std"] + # If we are not using colorized output, or if we do not know how + # to colorize the given result, we should return it unchanged. + return result +} + +function report(result, details) +{ + if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) + { + msg = ": " test_script_name + add_test_result(result) + } + else if (result == "#") + { + msg = " " test_script_name ":" + } + else + { + abort("in function report()") + } + if (length(details)) + msg = msg " " details + # Output on console might be colorized. + print decorate_result(result) msg + # Log the result in the log file too, to help debugging (this is + # especially true when said result is a TAP error or "Bail out!"). + print result msg | "cat >&3"; +} + +function testsuite_error(error_message) +{ + report("ERROR", "- " error_message) +} + +function handle_tap_result() +{ + details = result_obj["number"]; + if (length(result_obj["description"])) + details = details " " result_obj["description"] + + if (plan_seen == LATE_PLAN) + { + details = details " # AFTER LATE PLAN"; + } + else if (result_obj["is_unplanned"]) + { + details = details " # UNPLANNED"; + } + else if (result_obj["number"] != testno) + { + details = sprintf("%s # OUT-OF-ORDER (expecting %d)", + details, testno); + } + else if (result_obj["directive"]) + { + details = details " # " result_obj["directive"]; + if (length(result_obj["explanation"])) + details = details " " result_obj["explanation"] + } + + report(stringify_result_obj(result_obj), details) +} + +# `skip_reason` should be empty whenever planned > 0. +function handle_tap_plan(planned, skip_reason) +{ + planned += 0 # Avoid getting confused if, say, `planned` is "00" + if (length(skip_reason) && planned > 0) + abort("in function handle_tap_plan()") + if (plan_seen) + { + # Error, only one plan per stream is acceptable. + testsuite_error("multiple test plans") + return; + } + planned_tests = planned + # The TAP plan can come before or after *all* the TAP results; we speak + # respectively of an "early" or a "late" plan. If we see the plan line + # after at least one TAP result has been seen, assume we have a late + # plan; in this case, any further test result seen after the plan will + # be flagged as an error. + plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) + # If testno > 0, we have an error ("too many tests run") that will be + # automatically dealt with later, so do not worry about it here. If + # $plan_seen is true, we have an error due to a repeated plan, and that + # has already been dealt with above. Otherwise, we have a valid "plan + # with SKIP" specification, and should report it as a particular kind + # of SKIP result. + if (planned == 0 && testno == 0) + { + if (length(skip_reason)) + skip_reason = "- " skip_reason; + report("SKIP", skip_reason); + } +} + +function extract_tap_comment(line) +{ + if (index(line, diag_string) == 1) + { + # Strip leading `diag_string` from `line`. + line = substr(line, length(diag_string) + 1) + # And strip any leading and trailing whitespace left. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + # Return what is left (if any). + return line; + } + return ""; +} + +# When this function is called, we know that line is a TAP result line, +# so that it matches the (perl) RE "^(not )?ok\b". +function setup_result_obj(line) +{ + # Get the result, and remove it from the line. + result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) + sub("^(not )?ok[ \t]*", "", line) + + # If the result has an explicit number, get it and strip it; otherwise, + # automatically assing the next progresive number to it. + if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) + { + match(line, "^[0-9]+") + # The final `+ 0` is to normalize numbers with leading zeros. + result_obj["number"] = substr(line, 1, RLENGTH) + 0 + line = substr(line, RLENGTH + 1) + } + else + { + result_obj["number"] = testno + } + + if (plan_seen == LATE_PLAN) + # No further test results are acceptable after a "late" TAP plan + # has been seen. + result_obj["is_unplanned"] = 1 + else if (plan_seen && testno > planned_tests) + result_obj["is_unplanned"] = 1 + else + result_obj["is_unplanned"] = 0 + + # Strip trailing and leading whitespace. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + + # This will have to be corrected if we have a "TODO"/"SKIP" directive. + result_obj["description"] = line + result_obj["directive"] = "" + result_obj["explanation"] = "" + + if (index(line, "#") == 0) + return # No possible directive, nothing more to do. + + # Directives are case-insensitive. + rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" + + # See whether we have the directive, and if yes, where. + pos = match(line, rx "$") + if (!pos) + pos = match(line, rx "[^a-zA-Z0-9_]") + + # If there was no TAP directive, we have nothing more to do. + if (!pos) + return + + # Let`s now see if the TAP directive has been escaped. For example: + # escaped: ok \# SKIP + # not escaped: ok \\# SKIP + # escaped: ok \\\\\# SKIP + # not escaped: ok \ # SKIP + if (substr(line, pos, 1) == "#") + { + bslash_count = 0 + for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) + bslash_count += 1 + if (bslash_count % 2) + return # Directive was escaped. + } + + # Strip the directive and its explanation (if any) from the test + # description. + result_obj["description"] = substr(line, 1, pos - 1) + # Now remove the test description from the line, that has been dealt + # with already. + line = substr(line, pos) + # Strip the directive, and save its value (normalized to upper case). + sub("^[ \t]*#[ \t]*", "", line) + result_obj["directive"] = toupper(substr(line, 1, 4)) + line = substr(line, 5) + # Now get the explanation for the directive (if any), with leading + # and trailing whitespace removed. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + result_obj["explanation"] = line +} + +function get_test_exit_message(status) +{ + if (status == 0) + return "" + if (status !~ /^[1-9][0-9]*$/) + abort("getting exit status") + if (status < 127) + exit_details = "" + else if (status == 127) + exit_details = " (command not found?)" + else if (status >= 128 && status <= 255) + exit_details = sprintf(" (terminated by signal %d?)", status - 128) + else if (status > 256 && status <= 384) + # We used to report an "abnormal termination" here, but some Korn + # shells, when a child process die due to signal number n, can leave + # in $? an exit status of 256+n instead of the more standard 128+n. + # Apparently, both behaviours are allowed by POSIX (2008), so be + # prepared to handle them both. See also Austing Group report ID + # 0000051 + exit_details = sprintf(" (terminated by signal %d?)", status - 256) + else + # Never seen in practice. + exit_details = " (abnormal termination)" + return sprintf("exited with status %d%s", status, exit_details) +} + +function write_test_results() +{ + print ":global-test-result: " get_global_test_result() > trs_file + print ":recheck: " yn(must_recheck()) > trs_file + print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file + for (i = 0; i < test_results_index; i += 1) + print ":test-result: " test_results_list[i] > trs_file + close(trs_file); +} + +BEGIN { + +## ------- ## +## SETUP ## +## ------- ## + +'"$init_colors"' + +# Properly initialized once the TAP plan is seen. +planned_tests = 0 + +COOKED_PASS = expect_failure ? "XPASS": "PASS"; +COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; + +# Enumeration-like constants to remember which kind of plan (if any) +# has been seen. It is important that NO_PLAN evaluates "false" as +# a boolean. +NO_PLAN = 0 +EARLY_PLAN = 1 +LATE_PLAN = 2 + +testno = 0 # Number of test results seen so far. +bailed_out = 0 # Whether a "Bail out!" directive has been seen. + +# Whether the TAP plan has been seen or not, and if yes, which kind +# it is ("early" is seen before any test result, "late" otherwise). +plan_seen = NO_PLAN + +## --------- ## +## PARSING ## +## --------- ## + +is_first_read = 1 + +while (1) + { + # Involutions required so that we are able to read the exit status + # from the last input line. + st = getline + if (st < 0) # I/O error. + fatal("I/O error while reading from input stream") + else if (st == 0) # End-of-input + { + if (is_first_read) + abort("in input loop: only one input line") + break + } + if (is_first_read) + { + is_first_read = 0 + nextline = $0 + continue + } + else + { + curline = nextline + nextline = $0 + $0 = curline + } + # Copy any input line verbatim into the log file. + print | "cat >&3" + # Parsing of TAP input should stop after a "Bail out!" directive. + if (bailed_out) + continue + + # TAP test result. + if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) + { + testno += 1 + setup_result_obj($0) + handle_tap_result() + } + # TAP plan (normal or "SKIP" without explanation). + else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) + { + # The next two lines will put the number of planned tests in $0. + sub("^1\\.\\.", "") + sub("[^0-9]*$", "") + handle_tap_plan($0, "") + continue + } + # TAP "SKIP" plan, with an explanation. + else if ($0 ~ /^1\.\.0+[ \t]*#/) + { + # The next lines will put the skip explanation in $0, stripping + # any leading and trailing whitespace. This is a little more + # tricky in truth, since we want to also strip a potential leading + # "SKIP" string from the message. + sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") + sub("[ \t]*$", ""); + handle_tap_plan(0, $0) + } + # "Bail out!" magic. + # Older versions of prove and TAP::Harness (e.g., 3.17) did not + # recognize a "Bail out!" directive when preceded by leading + # whitespace, but more modern versions (e.g., 3.23) do. So we + # emulate the latter, "more modern" behaviour. + else if ($0 ~ /^[ \t]*Bail out!/) + { + bailed_out = 1 + # Get the bailout message (if any), with leading and trailing + # whitespace stripped. The message remains stored in `$0`. + sub("^[ \t]*Bail out![ \t]*", ""); + sub("[ \t]*$", ""); + # Format the error message for the + bailout_message = "Bail out!" + if (length($0)) + bailout_message = bailout_message " " $0 + testsuite_error(bailout_message) + } + # Maybe we have too look for dianogtic comments too. + else if (comments != 0) + { + comment = extract_tap_comment($0); + if (length(comment)) + report("#", comment); + } + } + +## -------- ## +## FINISH ## +## -------- ## + +# A "Bail out!" directive should cause us to ignore any following TAP +# error, as well as a non-zero exit status from the TAP producer. +if (!bailed_out) + { + if (!plan_seen) + { + testsuite_error("missing test plan") + } + else if (planned_tests != testno) + { + bad_amount = testno > planned_tests ? "many" : "few" + testsuite_error(sprintf("too %s tests run (expected %d, got %d)", + bad_amount, planned_tests, testno)) + } + if (!ignore_exit) + { + # Fetch exit status from the last line. + exit_message = get_test_exit_message(nextline) + if (exit_message) + testsuite_error(exit_message) + } + } + +write_test_results() + +exit 0 + +} # End of "BEGIN" block. +' + +# TODO: document that we consume the file descriptor 3 :-( +} 3>"$log_file" + +test $? -eq 0 || fatal "I/O or internal error" + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..eea84d0 --- /dev/null +++ b/config.h.in @@ -0,0 +1,173 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to 1 if you have check available */ +#undef HAVE_CHECK + +/* Define to 1 if you have a compatible version of check available */ +#undef HAVE_COMPATIBLE_CHECK + +/* Define to 1 if you have the declaration of `environ', and to 0 if you + don't. */ +#undef HAVE_DECL_ENVIRON + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have git available */ +#undef HAVE_GIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have jq available */ +#undef HAVE_JQ + +/* Define to 1 if you have libyaml available */ +#undef HAVE_LIBYAML + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Have PTHREAD_PRIO_INHERIT. */ +#undef HAVE_PTHREAD_PRIO_INHERIT + +/* Define to 1 if you have qsort_r available */ +#undef HAVE_QSORT_R + +/* Define to 1 if you have sphinx (and all required packages) available */ +#undef HAVE_SPHINX + +/* Define to 1 if the system has the type `ssize_t'. */ +#undef HAVE_SSIZE_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Define if debugging is disabled */ +#undef NDEBUG + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to `long int' if does not define. */ +#undef off_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define ssize_t if it is not done by the standard libs. */ +#undef ssize_t + +/* Define to `int' if doesn't define. */ +#undef uid_t diff --git a/configure b/configure new file mode 100755 index 0000000..fa33dd7 --- /dev/null +++ b/configure @@ -0,0 +1,21779 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for libfyaml 0.7.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: pantelis.antoniou@konsulko.com about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +lt_ltdl_dir='libltdl' + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='libfyaml' +PACKAGE_TARNAME='libfyaml' +PACKAGE_VERSION='0.7.3' +PACKAGE_STRING='libfyaml 0.7.3' +PACKAGE_BUGREPORT='pantelis.antoniou@konsulko.com' +PACKAGE_URL='' + +ac_unique_file="src/lib/fy-parse.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +enable_option_checking=no +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +Q +V +YACC +LEX +MCS +OBJC +F77 +FC +CCAS +AM_MAKEFLAGS +MAKEFLAGS +shavedir +HAVE_JQ_FALSE +HAVE_JQ_TRUE +JQ +HAVE_DOCKER_FALSE +HAVE_DOCKER_TRUE +DOCKER +JSONTESTSUITECHECKOUT +JSONTESTSUITEURL +TESTSUITECHECKOUT +TESTSUITEURL +HAVE_GIT_FALSE +HAVE_GIT_TRUE +GIT +HAVE_SPHINX_FALSE +HAVE_SPHINX_TRUE +PIP3 +SPHINX +HAVE_NETWORK_FALSE +HAVE_NETWORK_TRUE +HAVE_NETWORK +HAVE_COMPATIBLE_CHECK_FALSE +HAVE_COMPATIBLE_CHECK_TRUE +HAVE_COMPATIBLE_CHECK +HAVE_CHECK_FALSE +HAVE_CHECK_TRUE +CHECK_LDFLAGS +HAVE_CHECK +CHECK_LIBS +CHECK_CFLAGS +HAVE_LIBYAML_FALSE +HAVE_LIBYAML_TRUE +HAVE_LIBYAML +LIBYAML_LIBS +LIBYAML_CFLAGS +HAVE_QSORT_R_FALSE +HAVE_QSORT_R_TRUE +HAVE_QSORT_R +subdirs +CXXCPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +INCLTDL +LTDLINCL +LTDLDEPS +LIBLTDL +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +ACLOCAL_AMFLAGS +M4 +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +ax_pthread_config +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LN_S +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +ac_ct_AR +AR +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +DEBVERSION +EXTRA +PATCH +MINOR +MAJOR +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_debug +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_network +enable_shave +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +LT_SYS_LIBRARY_PATH +CXXCPP +LIBYAML_CFLAGS +LIBYAML_LIBS +CHECK_CFLAGS +CHECK_LIBS +TESTSUITEURL +TESTSUITECHECKOUT +JSONTESTSUITEURL +JSONTESTSUITECHECKOUT' +ac_subdirs_all='libltdl' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # 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. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libfyaml] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libfyaml 0.7.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-debug=[yes/info/profile/no] + compile with debugging + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-network Disable tests requiring network access + --enable-shave use shave to make the build pretty [[default=yes]] + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CXXCPP C++ preprocessor + LIBYAML_CFLAGS + C compiler flags for LIBYAML, overriding pkg-config + LIBYAML_LIBS + linker flags for LIBYAML, overriding pkg-config + CHECK_CFLAGS + C compiler flags for CHECK, overriding pkg-config + CHECK_LIBS linker flags for CHECK, overriding pkg-config + TESTSUITEURL + Testsuite git repo URL (default: + https://github.com/yaml/yaml-test-suite) + TESTSUITECHECKOUT + Testsuite checkout (default: + 80f289435a56189bbc5ca2f318574e48dbeef8aa) + JSONTESTSUITEURL + JSON Testsuite git repo URL (default: + https://github.com/nst/JSONTestSuite) + JSONTESTSUITECHECKOUT + JSON Testsuite checkout (default: + d64aefb55228d9584d3e5b2433f720ea8fd00c82) + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +libfyaml configure 0.7.3 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------------- ## +## Report this to pantelis.antoniou@konsulko.com ## +## --------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl +cat >config.log <<_ACEOF +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 +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_config_headers="$ac_config_headers config.h" + + +ac_aux_dir= +for ac_dir in build-aux "$srcdir"/build-aux; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +am__api_version='1.15' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libfyaml' + VERSION='0.7.3' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + + +# supoort older versions of automake +# only define the recursive targets when it's defined +# note that the top level makefile rules will not +# include them + + + + + + + +MAJOR=`echo $VERSION | cut -d. -f1 | cut -d- -f1` + +MINOR=`echo $VERSION | cut -d. -f2 | cut -d- -f1` + +PATCH=`echo $VERSION | cut -d. -f3- | cut -d- -f1` + +EXTRA=`echo $VERSION | cut -d- -f2-` + + +DEBVERSION="$MAJOR.$MINOR" + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 +$as_echo_n "checking whether to enable debugging... " >&6; } + + ax_enable_debug_default=no + ax_enable_debug_is_release=$ax_is_release + + # If this is a release, override the default. + if test "$ax_enable_debug_is_release" = "yes"; then : + ax_enable_debug_default="no" +fi + + + + + # Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +else + enable_debug=$ax_enable_debug_default +fi + + + # empty mean debug yes + if test "x$enable_debug" = "x"; then : + enable_debug="yes" +fi + + # case of debug + case $enable_debug in #( + yes) : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="${CFLAGS} -g -O0" + CXXFLAGS="${CXXFLAGS} -g -O0" + FFLAGS="${FFLAGS} -g -O0" + FCFLAGS="${FCFLAGS} -g -O0" + OBJCFLAGS="${OBJCFLAGS} -g -O0" + ;; #( + info) : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: info" >&5 +$as_echo "info" >&6; } + CFLAGS="${CFLAGS} -g" + CXXFLAGS="${CXXFLAGS} -g" + FFLAGS="${FFLAGS} -g" + FCFLAGS="${FCFLAGS} -g" + OBJCFLAGS="${OBJCFLAGS} -g" + ;; #( + profile) : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: profile" >&5 +$as_echo "profile" >&6; } + CFLAGS="${CFLAGS} -g -pg" + CXXFLAGS="${CXXFLAGS} -g -pg" + FFLAGS="${FFLAGS} -g -pg" + FCFLAGS="${FCFLAGS} -g -pg" + OBJCFLAGS="${OBJCFLAGS} -g -pg" + LDFLAGS="${LDFLAGS} -pg" + ;; #( + *) : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test "x${CFLAGS+set}" != "xset"; then : + CFLAGS="" +fi + if test "x${CXXFLAGS+set}" != "xset"; then : + CXXFLAGS="" +fi + if test "x${FFLAGS+set}" != "xset"; then : + FFLAGS="" +fi + if test "x${FCFLAGS+set}" != "xset"; then : + FCFLAGS="" +fi + if test "x${OBJCFLAGS+set}" != "xset"; then : + OBJCFLAGS="" +fi + ;; +esac + + if test "x$enable_debug" = "xyes"; then : + +else + +$as_echo "#define NDEBUG 1" >>confdefs.h + +fi + ax_enable_debug=$enable_debug + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } +if ${ac_cv_prog_gcc_traditional+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_pattern="Autoconf.*'x'" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +$as_echo_n "checking the archiver ($AR) interface... " >&6; } +if ${am_cv_ar_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +$as_echo "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 +$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 +$as_echo_n "checking whether pthreads work with $flag... " >&6; } + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ax_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ax_pthread_config"; then + ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ax_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" +fi +fi +ax_pthread_config=$ac_cv_prog_ax_pthread_config +if test -n "$ax_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 +$as_echo "$ax_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 +$as_echo_n "checking for the pthreads library -l$flag... " >&6; } + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; } +int +main () +{ +pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int attr = $attr; return attr /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + attr_name=$attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 +$as_echo "$attr_name" >&6; } + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $attr_name +_ACEOF + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 +$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 +$as_echo "${flag}" >&6; } + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 +$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } +if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include +int +main () +{ +int i = PTHREAD_PRIO_INHERIT; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_PRIO_INHERIT=yes +else + ax_cv_PTHREAD_PRIO_INHERIT=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 +$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } + if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : + +$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h + +fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != xyes; then + case $host_os in + aix*) + case "x/$CC" in #( + x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : + #handle absolute path differently from PATH based program lookup + case "x$CC" in #( + x/*) : + if as_fn_executable_p ${CC}_r; then : + PTHREAD_CC="${CC}_r" +fi ;; #( + *) : + for ac_prog in ${CC}_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + ;; +esac ;; #( + *) : + ;; +esac + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + + : +else + ax_pthread_ok=no + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Extract the first word of "m4 gm4", so it can be a program name with args. +set dummy m4 gm4; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_M4+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $M4 in + [\\/]* | ?:[\\/]*) + ac_cv_path_M4="$M4" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_M4" && ac_cv_path_M4="no" + ;; +esac +fi +M4=$ac_cv_path_M4 +if test -n "$M4"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5 +$as_echo "$M4" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "x$M4" = xno ; then + as_fn_error $? "m4 missing" "$LINENO" 5 +fi + +ACLOCAL_AMFLAGS="-I m4" + + +# pkg-config + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + + + + + + + +if test -f "$prefix/lib/libltdl.la"; then + lt_save_LDFLAGS=$LDFLAGS + LDFLAGS="-L$prefix/lib $LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lt_dlinit in -lltdl" >&5 +$as_echo_n "checking for lt_dlinit in -lltdl... " >&6; } +if ${ac_cv_lib_ltdl_lt_dlinit+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lltdl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char lt_dlinit (); +int +main () +{ +return lt_dlinit (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ltdl_lt_dlinit=yes +else + ac_cv_lib_ltdl_lt_dlinit=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ltdl_lt_dlinit" >&5 +$as_echo "$ac_cv_lib_ltdl_lt_dlinit" >&6; } +if test "x$ac_cv_lib_ltdl_lt_dlinit" = xyes; then : + lt_lib_ltdl=yes +fi + + LDFLAGS=$lt_save_LDFLAGS + if test yes = "${lt_lib_ltdl-no}"; then + if test yes != "$enable_ltdl_install"; then + # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not overwriting libltdl at $prefix, force with '--enable-ltdl-install'" >&5 +$as_echo "$as_me: WARNING: not overwriting libltdl at $prefix, force with '--enable-ltdl-install'" >&2;} + enable_ltdl_install=no + fi + elif test no = "$enable_ltdl_install"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libltdl not installed, but installation disabled" >&5 +$as_echo "$as_me: WARNING: libltdl not installed, but installation disabled" >&2;} + fi +fi + +# If configure.ac declared an installable ltdl, and the user didn't override +# with --disable-ltdl-install, we will install the shipped libltdl. +case $enable_ltdl_install in + no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL=-lltdl + LTDLDEPS= + LTDLINCL= + ;; + *) enable_ltdl_install=yes + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='$(top_build_prefix)'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" + LTDLDEPS=$LIBLTDL + LTDLINCL='-I$(top_srcdir)'"${lt_ltdl_dir+/$lt_ltdl_dir}" + ;; +esac + + + + + +# For backwards non-gettext consistent compatibility... +INCLTDL=$LTDLINCL + + +enable_dlopen=yes + + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + + + +subdirs="$subdirs libltdl" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SSIZE_T 1 +_ACEOF + + +else + +$as_echo "#define ssize_t signed long" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if ${ac_cv_type_signal+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + +ac_fn_c_check_decl "$LINENO" "environ" "ac_cv_have_decl_environ" "$ac_includes_default" +if test "x$ac_cv_have_decl_environ" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_ENVIRON $ac_have_decl +_ACEOF + + +for flag in -Wall -Wsign-compare; 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; } +if eval \${$as_CACHEVAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -pedantic -Werror $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_CACHEVAR=yes" +else + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"\"yes\""; then : + +if ${CFLAGS+:} false; then : + if $as_echo " $CFLAGS " | $GREP " $flag " 2>&1 >/dev/null; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 + (: CFLAGS already contains $flag) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS \$flag\""; } >&5 + (: CFLAGS="$CFLAGS $flag") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + as_fn_append CFLAGS " $flag" +fi +else + CFLAGS=$flag +fi + +else + : +fi + +done + + +if test "x$ax_enable_debug" != "xyes" ; then + CFLAGS="$CFLAGS -O2" +fi + +# include -lm in the link +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing llrintf" >&5 +$as_echo_n "checking for library containing llrintf... " >&6; } +if ${ac_cv_search_llrintf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char llrintf (); +int +main () +{ +return llrintf (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_llrintf=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_llrintf+:} false; then : + break +fi +done +if ${ac_cv_search_llrintf+:} false; then : + +else + ac_cv_search_llrintf=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_llrintf" >&5 +$as_echo "$ac_cv_search_llrintf" >&6; } +ac_res=$ac_cv_search_llrintf +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "unable to find the llrintf() function" "$LINENO" 5 +fi + + +# check if there's a qsort_r available (musl does not have it) +ac_fn_c_check_func "$LINENO" "qsort_r" "ac_cv_func_qsort_r" +if test "x$ac_cv_func_qsort_r" = xyes; then : + HAVE_QSORT_R=1 +else + HAVE_QSORT_R=0 +fi + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_QSORT_R $HAVE_QSORT_R +_ACEOF + + if test x$HAVE_QSORT_R = x1 ; then + HAVE_QSORT_R_TRUE= + HAVE_QSORT_R_FALSE='#' +else + HAVE_QSORT_R_TRUE='#' + HAVE_QSORT_R_FALSE= +fi + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBYAML" >&5 +$as_echo_n "checking for LIBYAML... " >&6; } + +if test -n "$LIBYAML_CFLAGS"; then + pkg_cv_LIBYAML_CFLAGS="$LIBYAML_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" yaml-0.1 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " yaml-0.1 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBYAML_CFLAGS=`$PKG_CONFIG --cflags " yaml-0.1 " 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBYAML_LIBS"; then + pkg_cv_LIBYAML_LIBS="$LIBYAML_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" yaml-0.1 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " yaml-0.1 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBYAML_LIBS=`$PKG_CONFIG --libs " yaml-0.1 " 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBYAML_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " yaml-0.1 " 2>&1` + else + LIBYAML_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " yaml-0.1 " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBYAML_PKG_ERRORS" >&5 + + HAVE_LIBYAML=0 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + HAVE_LIBYAML=0 +else + LIBYAML_CFLAGS=$pkg_cv_LIBYAML_CFLAGS + LIBYAML_LIBS=$pkg_cv_LIBYAML_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + HAVE_LIBYAML=1 +fi + +# update with pkg-config's flags +if test "x$HAVE_LIBYAML" != "x1" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: failed to find libyaml; compatibility disabled" >&5 +$as_echo "$as_me: WARNING: failed to find libyaml; compatibility disabled" >&2;} +fi + + + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_LIBYAML $HAVE_LIBYAML +_ACEOF + + if test x$HAVE_LIBYAML = x1 ; then + HAVE_LIBYAML_TRUE= + HAVE_LIBYAML_FALSE='#' +else + HAVE_LIBYAML_TRUE='#' + HAVE_LIBYAML_FALSE= +fi + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CHECK" >&5 +$as_echo_n "checking for CHECK... " >&6; } + +if test -n "$CHECK_CFLAGS"; then + pkg_cv_CHECK_CFLAGS="$CHECK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" check \""; } >&5 + ($PKG_CONFIG --exists --print-errors " check ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CHECK_CFLAGS=`$PKG_CONFIG --cflags " check " 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CHECK_LIBS"; then + pkg_cv_CHECK_LIBS="$CHECK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" check \""; } >&5 + ($PKG_CONFIG --exists --print-errors " check ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CHECK_LIBS=`$PKG_CONFIG --libs " check " 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CHECK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " check " 2>&1` + else + CHECK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " check " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CHECK_PKG_ERRORS" >&5 + + HAVE_CHECK=0 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + HAVE_CHECK=0 +else + CHECK_CFLAGS=$pkg_cv_CHECK_CFLAGS + CHECK_LIBS=$pkg_cv_CHECK_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + HAVE_CHECK=1 +fi + + + + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_CHECK $HAVE_CHECK +_ACEOF + + if test x$HAVE_CHECK = x1 ; then + HAVE_CHECK_TRUE= + HAVE_CHECK_FALSE='#' +else + HAVE_CHECK_TRUE='#' + HAVE_CHECK_FALSE= +fi + + +HAVE_COMPATIBLE_CHECK=0 +if test "x$HAVE_CHECK" == "x1" ; then + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$LIBS $CHECK_LIBS" + CFLAGS="$CFLAGS $CHECK_CFLAGS" + + # check if libcheck has srunner_set_tap (jessie has outdated libcheck) + ac_fn_c_check_func "$LINENO" "srunner_set_tap" "ac_cv_func_srunner_set_tap" +if test "x$ac_cv_func_srunner_set_tap" = xyes; then : + HAVE_COMPATIBLE_CHECK=1 +else + HAVE_COMPATIBLE_CHECK=0 +fi + + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_COMPATIBLE_CHECK $HAVE_COMPATIBLE_CHECK +_ACEOF + + if test x$HAVE_COMPATIBLE_CHECK = x1 ; then + HAVE_COMPATIBLE_CHECK_TRUE= + HAVE_COMPATIBLE_CHECK_FALSE='#' +else + HAVE_COMPATIBLE_CHECK_TRUE='#' + HAVE_COMPATIBLE_CHECK_FALSE= +fi + + +# Check whether --enable-network was given. +if test "${enable_network+set}" = set; then : + enableval=$enable_network; +fi + + +if test "x$enable_network" != "xno" ; then + HAVE_NETWORK=1 +else + HAVE_NETWORK=0 +fi + + if test x$HAVE_NETWORK = x1 ; then + HAVE_NETWORK_TRUE= + HAVE_NETWORK_FALSE='#' +else + HAVE_NETWORK_TRUE='#' + HAVE_NETWORK_FALSE= +fi + + +# check for sphinx +# Extract the first word of "sphinx-build", so it can be a program name with args. +set dummy sphinx-build; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SPHINX+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SPHINX in + [\\/]* | ?:[\\/]*) + ac_cv_path_SPHINX="$SPHINX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SPHINX="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +SPHINX=$ac_cv_path_SPHINX +if test -n "$SPHINX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINX" >&5 +$as_echo "$SPHINX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +HAVE_SPHINX=0 +if test "x$SPHINX" != "x" ; then + # Extract the first word of "pip3", so it can be a program name with args. +set dummy pip3; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PIP3+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PIP3 in + [\\/]* | ?:[\\/]*) + ac_cv_path_PIP3="$PIP3" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PIP3="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PIP3=$ac_cv_path_PIP3 +if test -n "$PIP3"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PIP3" >&5 +$as_echo "$PIP3" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + # if both pip3 and sphinx-build are available check for versions + if test "x$PIP3" != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking sphinx version" >&5 +$as_echo_n "checking sphinx version... " >&6; } + SPHINX_VERSION=`pip3 2>/dev/null show sphinx | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_VERSION" != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINX_VERSION" >&5 +$as_echo "$SPHINX_VERSION" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: N/A" >&5 +$as_echo "N/A" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking sphinx RTD theme version" >&5 +$as_echo_n "checking sphinx RTD theme version... " >&6; } + SPHINX_RTD_THEME_VERSION=`pip3 2>/dev/null show sphinx_rtd_theme | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_VERSION" != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINX_RTD_THEME_VERSION" >&5 +$as_echo "$SPHINX_RTD_THEME_VERSION" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: N/A" >&5 +$as_echo "N/A" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking sphinx markdown builder version" >&5 +$as_echo_n "checking sphinx markdown builder version... " >&6; } + SPHINX_MARKDOWN_BUILDER_VERSION=`pip3 2>/dev/null show sphinx-markdown-builder | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_MARKDOWN_BUILDER_VERSION" != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINX_MARKDOWN_BUILDER_VERSION" >&5 +$as_echo "$SPHINX_MARKDOWN_BUILDER_VERSION" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: N/A" >&5 +$as_echo "N/A" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking sphinx linuxdoc version" >&5 +$as_echo_n "checking sphinx linuxdoc version... " >&6; } + SPHINX_LINUXDOC_VERSION=`pip3 2>/dev/null show linuxdoc | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_LINUXDOC_VERSION" != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINX_LINUXDOC_VERSION" >&5 +$as_echo "$SPHINX_LINUXDOC_VERSION" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: N/A" >&5 +$as_echo "N/A" >&6; } + fi + + if test "x$SPHINX_VERSION" != "x" -a "x$SPHINX_RTD_THEME_VERSION" != "x" -a "x$SPHINX_MARKDOWN_BUILDER_VERSION" != "x" -a "x$SPHINX_LINUXDOC_VERSION" != "x" ; then + HAVE_SPHINX=1 + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sphinx installation works" >&5 +$as_echo_n "checking whether sphinx installation works... " >&6; } + if test "x$HAVE_SPHINX" == "x1" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi +fi + + +cat >>confdefs.h <<_ACEOF +#define HAVE_SPHINX $HAVE_SPHINX +_ACEOF + + if test x$HAVE_SPHINX = x1 ; then + HAVE_SPHINX_TRUE= + HAVE_SPHINX_FALSE='#' +else + HAVE_SPHINX_TRUE='#' + HAVE_SPHINX_FALSE= +fi + + +# check for git +# Extract the first word of "git", so it can be a program name with args. +set dummy git; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GIT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GIT="$GIT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GIT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +GIT=$ac_cv_path_GIT +if test -n "$GIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GIT" >&5 +$as_echo "$GIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "x$GIT" != "x" ; then + HAVE_GIT=1 +else + HAVE_GIT=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_GIT $HAVE_GIT +_ACEOF + + if test x$HAVE_GIT = x1 ; then + HAVE_GIT_TRUE= + HAVE_GIT_FALSE='#' +else + HAVE_GIT_TRUE='#' + HAVE_GIT_FALSE= +fi + + + + +if test "x$TESTSUITEURL" == "x" ; then + TESTSUITEURL="https://github.com/yaml/yaml-test-suite" +fi + + + +if test "x$TESTSUITECHECKOUT" == "x" ; then + TESTSUITECHECKOUT="80f289435a56189bbc5ca2f318574e48dbeef8aa" +fi + + + +if test "x$JSONTESTSUITEURL" == "x" ; then + JSONTESTSUITEURL="https://github.com/nst/JSONTestSuite" +fi + + + +if test "x$JSONTESTSUITECHECKOUT" == "x" ; then + JSONTESTSUITECHECKOUT="d64aefb55228d9584d3e5b2433f720ea8fd00c82" +fi + +# check for docker +# Extract the first word of "docker", so it can be a program name with args. +set dummy docker; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DOCKER+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DOCKER in + [\\/]* | ?:[\\/]*) + ac_cv_path_DOCKER="$DOCKER" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DOCKER="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +DOCKER=$ac_cv_path_DOCKER +if test -n "$DOCKER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOCKER" >&5 +$as_echo "$DOCKER" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "x$DOCKER" != "x" ; then + HAVE_DOCKER=1 +else + HAVE_DOCKER=0 +fi + if test x$HAVE_DOCKER = x1 ; then + HAVE_DOCKER_TRUE= + HAVE_DOCKER_FALSE='#' +else + HAVE_DOCKER_TRUE='#' + HAVE_DOCKER_FALSE= +fi + + +# check for jq +# Extract the first word of "jq", so it can be a program name with args. +set dummy jq; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_JQ+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $JQ in + [\\/]* | ?:[\\/]*) + ac_cv_path_JQ="$JQ" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_JQ="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +JQ=$ac_cv_path_JQ +if test -n "$JQ"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JQ" >&5 +$as_echo "$JQ" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "x$JQ" != "x" ; then + HAVE_JQ=1 +else + HAVE_JQ=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_JQ $HAVE_JQ +_ACEOF + + if test x$HAVE_JQ = x1 ; then + HAVE_JQ_TRUE= + HAVE_JQ_FALSE='#' +else + HAVE_JQ_TRUE='#' + HAVE_JQ_FALSE= +fi + +JQ="$JQ" + + +# Shave by default on supported autoconf versions + + + # Check whether --enable-shave was given. +if test "${enable_shave+set}" = set; then : + enableval=$enable_shave; +else + enable_shave=yes + +fi + + + + if test x"$enable_shave" = xyes; then + shavedir="$ac_pwd/build-aux" + + + MAKEFLAGS=-s + + AM_MAKEFLAGS='`test -z $V && echo -s`' + + + # Extract the first word of "sed", so it can be a program name with args. +set dummy sed; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$SED"; then + ac_cv_prog_SED="$SED" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_SED="sed" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_SED" && ac_cv_prog_SED="false" +fi +fi +SED=$ac_cv_prog_SED +if test -n "$SED"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 +$as_echo "$SED" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + SHAVE_SAVED_LIBTOOL=$LIBTOOL + LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'" + + + SHAVE_SAVED_CCAS=$CCAS + SHAVE_SAVED_CC=$CC + SHAVE_SAVED_CXX=$CXX + SHAVE_SAVED_FC=$FC + SHAVE_SAVED_F77=$F77 + SHAVE_SAVED_OBJC=$OBJC + SHAVE_SAVED_MCS=$MCS + SHAVE_SAVED_LEX=$LEX + SHAVE_SAVED_YACC=$YACC + CCAS="${SHELL} ${shavedir}/shave ccas ${SHAVE_SAVED_CCAS}" + CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}" + CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}" + FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}" + F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}" + OBJC="${SHELL} ${shavedir}/shave objc ${SHAVE_SAVED_OBJC}" + MCS="${SHELL} ${shavedir}/shave mcs ${SHAVE_SAVED_MCS}" + LEX="${SHELL} ${shavedir}/shave lex ${SHAVE_SAVED_LEX}" + YACC="${SHELL} ${shavedir}/shave yacc ${SHAVE_SAVED_YACC}" + + + + + + + + + + + V=@ + else + V=1 + fi + Q='$(V:1=)' + + + + +ac_config_files="$ac_config_files build-aux/shave build-aux/shave-libtool Makefile src/Makefile test/Makefile doc/Makefile libfyaml.pc" + + + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${HAVE_QSORT_R_TRUE}" && test -z "${HAVE_QSORT_R_FALSE}"; then + as_fn_error $? "conditional \"HAVE_QSORT_R\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_LIBYAML_TRUE}" && test -z "${HAVE_LIBYAML_FALSE}"; then + as_fn_error $? "conditional \"HAVE_LIBYAML\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CHECK_TRUE}" && test -z "${HAVE_CHECK_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CHECK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_COMPATIBLE_CHECK_TRUE}" && test -z "${HAVE_COMPATIBLE_CHECK_FALSE}"; then + as_fn_error $? "conditional \"HAVE_COMPATIBLE_CHECK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_NETWORK_TRUE}" && test -z "${HAVE_NETWORK_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NETWORK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_SPHINX_TRUE}" && test -z "${HAVE_SPHINX_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SPHINX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_GIT_TRUE}" && test -z "${HAVE_GIT_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GIT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_DOCKER_TRUE}" && test -z "${HAVE_DOCKER_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DOCKER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_JQ_TRUE}" && test -z "${HAVE_JQ_FALSE}"; then + as_fn_error $? "conditional \"HAVE_JQ\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# 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 +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +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 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "build-aux/shave") CONFIG_FILES="$CONFIG_FILES build-aux/shave" ;; + "build-aux/shave-libtool") CONFIG_FILES="$CONFIG_FILES build-aux/shave-libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "libfyaml.pc") CONFIG_FILES="$CONFIG_FILES libfyaml.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ac_sub_configure_args= + ac_prev= + eval "set x $ac_configure_args" + shift + for ac_arg + do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + --disable-option-checking) + ;; + *) + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_sub_configure_args " '$ac_arg'" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_arg="--prefix=$prefix" + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi + + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d "$srcdir/$ac_dir" || continue + + ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" + $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 + $as_echo "$ac_msg" >&6 + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + cd "$ac_dir" + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f "$ac_srcdir/configure.gnu"; then + ac_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ac_sub_configure=$ac_srcdir/configure + elif test -f "$ac_srcdir/configure.in"; then + # This should be Cygnus configure. + ac_sub_configure=$ac_aux_dir/configure + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 +$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative name. + ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ + --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || + as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 + fi + + cd "$ac_popdir" + done +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +echo " + ---{ $PACKAGE_NAME $VERSION }--- + + VERSION: ${VERSION} + MAJOR.MINOR: ${MAJOR}.${MINOR} + PATCH: ${PATCH} + EXTRA: ${EXTRA} + prefix: ${prefix} + C compiler: ${CC} + CFLAGS: ${CFLAGS} + Linker: ${LD} + LDFLAGS: ${LDFLAGS} + LIBS: ${LIBS} + HAVE_CHECK: ${HAVE_CHECK} + HAVE_COMPATIBLE_CHECK: ${HAVE_COMPATIBLE_CHECK} + HAVE_NETWORK: ${HAVE_NETWORK} + HAVE_SPHINX: ${HAVE_SPHINX} + GIT: $GIT + DOCKER: $DOCKER + TESTSUITEURL: $TESTSUITEURL + TESTSUITECHECKOUT: $TESTSUITECHECKOUT + JSONTESTSUITEURL: $JSONTESTSUITEURL + JSONTESTSUITECHECKOUT: $JSONTESTSUITECHECKOUT + +" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..4d198f5 --- /dev/null +++ b/configure.ac @@ -0,0 +1,316 @@ +AC_PREREQ(2.61) + +AC_INIT([libfyaml], + m4_esyscmd([build-aux/git-version-gen .tarball-version]), + [pantelis.antoniou@konsulko.com]) + +AC_CONFIG_SRCDIR([src/lib/fy-parse.c]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([foreign 1.8.5 -Wall subdir-objects ]) + +m4_pattern_allow([^(AM_EXTRA_RECURSIVE_TARGETS|AM_PROG_AR)$])dnl + +# supoort older versions of automake +# only define the recursive targets when it's defined +# note that the top level makefile rules will not +# include them +m4_ifdef([AM_EXTRA_RECURSIVE_TARGETS], + [AM_EXTRA_RECURSIVE_TARGETS([doc-help doc-html doc-latexpdf doc-man doc-clean doc-markdown])], + [AC_MSG_WARN([Old automake version without AM_EXTRA_RECURSIVE_TARGETS, doc-* rules won't be available at top level])]) + +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-`) + +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") + +dnl AX_* requires 2.64 +m4_version_prereq(2.64, [AX_CHECK_ENABLE_DEBUG()], [true]) + +AC_PROG_MKDIR_P +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O + +AC_PROG_GCC_TRADITIONAL +AC_USE_SYSTEM_EXTENSIONS +m4_ifdef([AM_PROG_AR], [AM_PROG_AR], + [AC_MSG_WARN([Old automake version without AM_PROG_AR, library versioning will not be available])]) + +AC_PROG_CXX +AC_PROG_AWK +AC_PROG_LN_S + +AX_PTHREAD + +AC_PATH_PROG([M4], [m4 gm4], [no]) +if test "x$M4" = xno ; then + AC_MSG_ERROR([m4 missing]) +fi + +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4") + +# pkg-config +PKG_PROG_PKG_CONFIG + +AC_LTDL_ENABLE_INSTALL +AC_LIBLTDL_INSTALLABLE +AC_LIBTOOL_DLOPEN +AC_LIBTOOL_WIN32_DLL +AC_PROG_LIBTOOL +AC_SUBST(LTDLINCL) +AC_SUBST(LIBLTDL) +AC_CONFIG_SUBDIRS(libltdl) + +AC_HEADER_STDC +AC_C_CONST +AC_C_BIGENDIAN +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_CHECK_TYPES(ssize_t, , [AC_DEFINE([ssize_t], [signed long], + [Define ssize_t if it is not done by the standard libs.])]) +AC_TYPE_OFF_T +AC_TYPE_SIGNAL +AC_TYPE_UID_T +AC_CHECK_DECLS(environ) + +dnl for old autoconf version AX_APPEND_COMPILE_FLAGS does not work +m4_version_prereq(2.64, + [AX_APPEND_COMPILE_FLAGS([-Wall -Wsign-compare], + [CFLAGS], [-pedantic -Werror])], + [CFLAGS="$CFLAGS -Wall -Wsign-compare"]) + +dnl -O2 is universal no need for AX_APPEND_COMPILE_FLAGS +if test "x$ax_enable_debug" != "xyes" ; then + CFLAGS="$CFLAGS -O2" +fi + +# include -lm in the link +AC_SEARCH_LIBS([llrintf], [m], [], [AC_MSG_ERROR([unable to find the llrintf() function])]) + +# check if there's a qsort_r available (musl does not have it) +AC_CHECK_FUNC([qsort_r], + HAVE_QSORT_R=1, + HAVE_QSORT_R=0) +AC_SUBST(HAVE_QSORT_R) +AC_DEFINE_UNQUOTED([HAVE_QSORT_R], [$HAVE_QSORT_R], [Define to 1 if you have qsort_r available]) +AM_CONDITIONAL([HAVE_QSORT_R], [ test x$HAVE_QSORT_R = x1 ]) + +PKG_CHECK_MODULES(LIBYAML, [ yaml-0.1 ], HAVE_LIBYAML=1, HAVE_LIBYAML=0) + +# update with pkg-config's flags +if test "x$HAVE_LIBYAML" != "x1" ; then + AC_MSG_WARN([failed to find libyaml; compatibility disabled]) +fi + +AC_SUBST(HAVE_LIBYAML) +AC_SUBST(LIBYAML_CFLAGS) +AC_SUBST(LIBYAML_LIBS) +AC_DEFINE_UNQUOTED([HAVE_LIBYAML], [$HAVE_LIBYAML], [Define to 1 if you have libyaml available]) +AM_CONDITIONAL([HAVE_LIBYAML], [ test x$HAVE_LIBYAML = x1 ]) + +PKG_CHECK_MODULES(CHECK, [ check ], HAVE_CHECK=1, HAVE_CHECK=0) + +AC_SUBST(HAVE_CHECK) +AC_SUBST(CHECK_CFLAGS) +AC_SUBST(CHECK_LDFLAGS) +AC_SUBST(CHECK_LIBS) +AC_DEFINE_UNQUOTED([HAVE_CHECK], [$HAVE_CHECK], [Define to 1 if you have check available]) +AM_CONDITIONAL([HAVE_CHECK], [ test x$HAVE_CHECK = x1 ]) + +HAVE_COMPATIBLE_CHECK=0 +if test "x$HAVE_CHECK" == "x1" ; then + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$LIBS $CHECK_LIBS" + CFLAGS="$CFLAGS $CHECK_CFLAGS" + + # check if libcheck has srunner_set_tap (jessie has outdated libcheck) + AC_CHECK_FUNC([srunner_set_tap], + HAVE_COMPATIBLE_CHECK=1, + HAVE_COMPATIBLE_CHECK=0) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +AC_SUBST(HAVE_COMPATIBLE_CHECK) +AC_DEFINE_UNQUOTED([HAVE_COMPATIBLE_CHECK], [$HAVE_COMPATIBLE_CHECK], [Define to 1 if you have a compatible version of check available]) +AM_CONDITIONAL([HAVE_COMPATIBLE_CHECK], [ test x$HAVE_COMPATIBLE_CHECK = x1 ]) + +dnl enable internet available when checking +AC_ARG_ENABLE([network], + AS_HELP_STRING([--disable-network], + [Disable tests requiring network access])) + +if test "x$enable_network" != "xno" ; then + HAVE_NETWORK=1 +else + HAVE_NETWORK=0 +fi +AC_SUBST(HAVE_NETWORK) +AM_CONDITIONAL([HAVE_NETWORK], + [ test x$HAVE_NETWORK = x1 ]) + +# check for sphinx +AC_PATH_PROG([SPHINX], [sphinx-build]) + +HAVE_SPHINX=0 +if test "x$SPHINX" != "x" ; then + AC_PATH_PROG([PIP3], [pip3]) + + # if both pip3 and sphinx-build are available check for versions + if test "x$PIP3" != "x" ; then + AC_MSG_CHECKING([sphinx version]) + SPHINX_VERSION=`pip3 2>/dev/null show sphinx | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_VERSION" != "x" ; then + AC_MSG_RESULT([$SPHINX_VERSION]) + else + AC_MSG_RESULT([N/A]) + fi + + AC_MSG_CHECKING([sphinx RTD theme version]) + SPHINX_RTD_THEME_VERSION=`pip3 2>/dev/null show sphinx_rtd_theme | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_VERSION" != "x" ; then + AC_MSG_RESULT([$SPHINX_RTD_THEME_VERSION]) + else + AC_MSG_RESULT([N/A]) + fi + + AC_MSG_CHECKING([sphinx markdown builder version]) + SPHINX_MARKDOWN_BUILDER_VERSION=`pip3 2>/dev/null show sphinx-markdown-builder | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_MARKDOWN_BUILDER_VERSION" != "x" ; then + AC_MSG_RESULT([$SPHINX_MARKDOWN_BUILDER_VERSION]) + else + AC_MSG_RESULT([N/A]) + fi + + AC_MSG_CHECKING([sphinx linuxdoc version]) + SPHINX_LINUXDOC_VERSION=`pip3 2>/dev/null show linuxdoc | grep -i Version: | cut -d: -f2 | sed -e 's/ //g'` + if test "x$SPHINX_LINUXDOC_VERSION" != "x" ; then + AC_MSG_RESULT([$SPHINX_LINUXDOC_VERSION]) + else + AC_MSG_RESULT([N/A]) + fi + + if test "x$SPHINX_VERSION" != "x" -a "x$SPHINX_RTD_THEME_VERSION" != "x" -a "x$SPHINX_MARKDOWN_BUILDER_VERSION" != "x" -a "x$SPHINX_LINUXDOC_VERSION" != "x" ; then + HAVE_SPHINX=1 + fi + fi + + AC_MSG_CHECKING([whether sphinx installation works]) + if test "x$HAVE_SPHINX" == "x1" ; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +fi + +AC_DEFINE_UNQUOTED([HAVE_SPHINX], [$HAVE_SPHINX], [Define to 1 if you have sphinx (and all required packages) available]) +AM_CONDITIONAL([HAVE_SPHINX], [ test x$HAVE_SPHINX = x1 ]) + +# check for git +AC_PATH_PROG([GIT], [git]) +if test "x$GIT" != "x" ; then + HAVE_GIT=1 +else + HAVE_GIT=0 +fi +AC_DEFINE_UNQUOTED([HAVE_GIT], [$HAVE_GIT], [Define to 1 if you have git available]) +AM_CONDITIONAL([HAVE_GIT], [ test x$HAVE_GIT = x1 ]) + +AC_ARG_VAR(TESTSUITEURL, [Testsuite git repo URL (default: https://github.com/yaml/yaml-test-suite)]) + +if test "x$TESTSUITEURL" == "x" ; then + TESTSUITEURL="https://github.com/yaml/yaml-test-suite" +fi + +AC_ARG_VAR(TESTSUITECHECKOUT, [Testsuite checkout (default: 80f289435a56189bbc5ca2f318574e48dbeef8aa)]) + +if test "x$TESTSUITECHECKOUT" == "x" ; then + TESTSUITECHECKOUT="80f289435a56189bbc5ca2f318574e48dbeef8aa" +fi + +AC_ARG_VAR(JSONTESTSUITEURL, [JSON Testsuite git repo URL (default: https://github.com/nst/JSONTestSuite)]) + +if test "x$JSONTESTSUITEURL" == "x" ; then + JSONTESTSUITEURL="https://github.com/nst/JSONTestSuite" +fi + +AC_ARG_VAR(JSONTESTSUITECHECKOUT, [JSON Testsuite checkout (default: d64aefb55228d9584d3e5b2433f720ea8fd00c82)]) + +if test "x$JSONTESTSUITECHECKOUT" == "x" ; then + JSONTESTSUITECHECKOUT="d64aefb55228d9584d3e5b2433f720ea8fd00c82" +fi + +# check for docker +AC_PATH_PROG([DOCKER], [docker]) +if test "x$DOCKER" != "x" ; then + HAVE_DOCKER=1 +else + HAVE_DOCKER=0 +fi +AM_CONDITIONAL([HAVE_DOCKER], [ test x$HAVE_DOCKER = x1 ]) + +# check for jq +AC_PATH_PROG([JQ], [jq]) +if test "x$JQ" != "x" ; then + HAVE_JQ=1 +else + HAVE_JQ=0 +fi +AC_DEFINE_UNQUOTED([HAVE_JQ], [$HAVE_JQ], [Define to 1 if you have jq available]) +AM_CONDITIONAL([HAVE_JQ], [ test x$HAVE_JQ = x1 ]) +AC_SUBST(JQ, "$JQ") + +# Shave by default on supported autoconf versions +dnl m4_version_prereq(2.64, SHAVE_INIT([build-aux], [enable]), [true]) +m4_ifdef([SHAVE_INIT], [SHAVE_INIT([build-aux], [enable])]) + +AC_CONFIG_FILES([ + build-aux/shave + build-aux/shave-libtool + Makefile + src/Makefile + test/Makefile + doc/Makefile + libfyaml.pc +]) + +AC_REQUIRE_AUX_FILE([tap-driver.sh]) + +AC_OUTPUT + +echo " + ---{ $PACKAGE_NAME $VERSION }--- + + VERSION: ${VERSION} + MAJOR.MINOR: ${MAJOR}.${MINOR} + PATCH: ${PATCH} + EXTRA: ${EXTRA} + prefix: ${prefix} + C compiler: ${CC} + CFLAGS: ${CFLAGS} + Linker: ${LD} + LDFLAGS: ${LDFLAGS} + LIBS: ${LIBS} + HAVE_CHECK: ${HAVE_CHECK} + HAVE_COMPATIBLE_CHECK: ${HAVE_COMPATIBLE_CHECK} + HAVE_NETWORK: ${HAVE_NETWORK} + HAVE_SPHINX: ${HAVE_SPHINX} + GIT: $GIT + DOCKER: $DOCKER + TESTSUITEURL: $TESTSUITEURL + TESTSUITECHECKOUT: $TESTSUITECHECKOUT + JSONTESTSUITEURL: $JSONTESTSUITEURL + JSONTESTSUITECHECKOUT: $JSONTESTSUITECHECKOUT + +" diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..d93a491 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,41 @@ +BUILDDIR=_build + +if HAVE_SPHINX + +MANPAGES1 = $(BUILDDIR)/man/fy-tool.1 + +doc-%: + srctree=@top_srcdir@ @SPHINX@ -M `echo $@ | sed -s 's/^doc-//g'` "@srcdir@" "$(BUILDDIR)" + +$(MANPAGES1): doc-man + +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) + +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 + +clean-local: + @rm -rf "$(BUILDDIR)" + +maintainer-clean-local: + @rm -rf Makefile.in + +EXTRA_DIST = \ + conf.py \ + index.rst \ + intro.rst \ + libfyaml.rst \ + man/fy-tool.rst diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..ca57d4b --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,571 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_enable_debug.m4 \ + $(top_srcdir)/m4/ax_check_flag.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 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__extra_recursive_targets = doc-help-recursive doc-html-recursive \ + doc-latexpdf-recursive doc-man-recursive doc-clean-recursive \ + doc-markdown-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_MAKEFLAGS = @AM_MAKEFLAGS@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LDFLAGS = @CHECK_LDFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBVERSION = @DEBVERSION@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCKER = @DOCKER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA = @EXTRA@ +F77 = @F77@ +FC = @FC@ +FGREP = @FGREP@ +GIT = @GIT@ +GREP = @GREP@ +HAVE_CHECK = @HAVE_CHECK@ +HAVE_COMPATIBLE_CHECK = @HAVE_COMPATIBLE_CHECK@ +HAVE_LIBYAML = @HAVE_LIBYAML@ +HAVE_NETWORK = @HAVE_NETWORK@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JQ = @JQ@ +JSONTESTSUITECHECKOUT = @JSONTESTSUITECHECKOUT@ +JSONTESTSUITEURL = @JSONTESTSUITEURL@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ +LIBYAML_LIBS = @LIBYAML_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4 = @M4@ +MAJOR = @MAJOR@ +MAKEFLAGS = @MAKEFLAGS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MCS = @MCS@ +MINOR = @MINOR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATCH = @PATCH@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PIP3 = @PIP3@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +Q = @Q@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX = @SPHINX@ +STRIP = @STRIP@ +TESTSUITECHECKOUT = @TESTSUITECHECKOUT@ +TESTSUITEURL = @TESTSUITEURL@ +V = @V@ +VERSION = @VERSION@ +YACC = @YACC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +shavedir = @shavedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +BUILDDIR = _build +@HAVE_SPHINX_TRUE@MANPAGES1 = $(BUILDDIR)/man/fy-tool.1 +EXTRA_DIST = \ + conf.py \ + index.rst \ + intro.rst \ + libfyaml.rst \ + man/fy-tool.rst + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +doc-help-local: +doc-html-local: +doc-latexpdf-local: +doc-man-local: +doc-clean-local: +doc-markdown-local: +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +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 + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +doc-clean: doc-clean-am + +doc-clean-am: doc-clean-local + +doc-help: doc-help-am + +doc-help-am: doc-help-local + +doc-html: doc-html-am + +doc-html-am: doc-html-local + +doc-latexpdf: doc-latexpdf-am + +doc-latexpdf-am: doc-latexpdf-local + +doc-man: doc-man-am + +doc-man-am: doc-man-local + +doc-markdown: doc-markdown-am + +doc-markdown-am: doc-markdown-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-data-am install-strip uninstall-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + clean-local cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir doc-clean-am doc-clean-local \ + doc-help-am doc-help-local doc-html-am doc-html-local \ + doc-latexpdf-am doc-latexpdf-local doc-man-am doc-man-local \ + doc-markdown-am doc-markdown-local dvi dvi-am html html-am \ + info info-am install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic maintainer-clean-local mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am uninstall-hook + +.PRECIOUS: Makefile + + +@HAVE_SPHINX_TRUE@doc-%: +@HAVE_SPHINX_TRUE@ srctree=@top_srcdir@ @SPHINX@ -M `echo $@ | sed -s 's/^doc-//g'` "@srcdir@" "$(BUILDDIR)" + +@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) + +clean-local: + @rm -rf "$(BUILDDIR)" + +maintainer-clean-local: + @rm -rf Makefile.in + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..eb9f181 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,69 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'libfyaml' +copyright = '2019, Pantelis Antoniou' +author = 'Pantelis Antoniou' + +# The full version, including alpha/beta/rc tags +release = '0.1' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'linuxdoc.rstFlatTable' # Implementation of the 'flat-table' reST-directive. + , 'linuxdoc.rstKernelDoc' # Implementation of the 'kernel-doc' reST-directive. + , 'linuxdoc.kernel_include' # Implementation of the 'kernel-include' reST-directive. + , 'linuxdoc.manKernelDoc' # Implementation of the 'kernel-doc-man' builder + , 'linuxdoc.cdomain' # Replacement for the sphinx c-domain. + , 'linuxdoc.kfigure' # Sphinx extension which implements scalable image handling. + , 'sphinx_markdown_builder' # Sphinx markdown builder +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +# html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +master_doc = 'index' + +man_pages = [ + ('man/fy-tool', 'fy-tool', 'fy-tool documentation ', '', 1), +] diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..a6b88a1 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,23 @@ +.. libfyaml documentation master file, created by + sphinx-quickstart on Sat May 25 20:55:33 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to libfyaml's documentation! +==================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + intro + man/fy-tool + libfyaml + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/intro.rst b/doc/intro.rst new file mode 100644 index 0000000..1bf5d59 --- /dev/null +++ b/doc/intro.rst @@ -0,0 +1,4 @@ +Introduction +============ + +This is the documentation for libfyaml, a fancy 1.2 YAML and JSON parser/writer. diff --git a/doc/libfyaml.rst b/doc/libfyaml.rst new file mode 100644 index 0000000..4585332 --- /dev/null +++ b/doc/libfyaml.rst @@ -0,0 +1,5 @@ +Public API +========== + + .. kernel-doc:: include/libfyaml.h + :internal: diff --git a/doc/man/fy-tool.rst b/doc/man/fy-tool.rst new file mode 100644 index 0000000..5da4b9e --- /dev/null +++ b/doc/man/fy-tool.rst @@ -0,0 +1,679 @@ +fy-tool +======= + +Synopsis +-------- + +**fy-tool** [*OPTIONS*] [<*file*> ...] + +**fy-dump** [*OPTIONS*] [<*file*> ...] + +**fy-testsuite** [*OPTIONS*] <*file*> + +**fy-filter** [*OPTIONS*] [-f*FILE*] [<*path*> ...] + +**fy-join** [*OPTIONS*] [-T*PATH*] [-F*PATH*] [-t*PATH*] [<*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. + +* In `dump` mode it will parse YAML/JSON input files and output YAML/JSON + according to the output format options. + +* In `testsuite` mode it will parse a single YAML input file and output + yaml testsuite reference output. + +* In `filter` mode it will parse YAML/JSON files and output YAML/JSON + output filtered according to the given option. + +* 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. + +Options +------- + +.. program:: fy-tool + +A number of options are common for all the different modes of operation +and they are as follows: + +.. rubric:: Common options + +.. option:: -q, --quiet + + Quiet operation, does not output informational messages at all. + +.. option:: -h, --help + + Display usage information. + +.. option:: -v, --version + + Display version information. + +.. option:: -I DIR, --include=DIR + + Add the `DIR` directory to the search path which will be used to locate a YAML/JSON file. + The default path is set to "" + +.. option:: -d LEVEL, --debug-level=LEVEL + + Set the minimum numeric debug level value of the library to `LEVEL`. + The numeric value must be in the range of 0 to 4 and their meaning is as follows: + + - **0** (`DEBUG`) + + Internal library debugging messages. No output is produced when the + library was compiled with `--disable-debug` + + - **1** (`INFO`) + + Informational messages about the internal operation of the library. + + - **2** (`NOTICE`) + + Messsages that could require attention. + + - **3** (`WARNING`) + + A warning message, something is wrong, but operation can continue. + This is the default value. + + - **4** (`ERROR`) + + A fatal error occured, it is impossible to continue. + + The default level is 3 (`WARNING`), which means that messages + with level 3 and higher will be displayed. + +.. rubric:: Parser Options + +.. option:: -j JSONOPT, --json=JSONOPT + + Marks the input files as JSON or YAML accordingly to: + + - **no** + + The input files are always in YAML mode. + + - **yes** + + The input files are always set to JSON mode. + + - **auto** + + 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. + +.. option:: --streaming + + Only valid when in **dump** 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. + + Note that in streaming mode: + + - Key duplication checks are disabled. + - No reording of key order is possible when emitting (i.e. `--sort` is not available). + - Alias resolution is not available (i.e. `--resolve`). + +.. rubric:: Resolver Options + +.. option:: -r, --resolve + + Perform anchor and merge key resolution. By default this option is disabled. + +.. option:: -l, --follow + + Follow aliases when performing path traversal. By default this option is disabled. + +.. rubric:: Emitter Options + +.. option:: -i INDENT, --indent=INDENT + + Sets the emitter indent (in spaces). Default is **2**. + +.. option:: -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. `flow-oneline` or `json-oneline`). + Default value is 80. + +.. option:: -m MODE, --mode=MODE + + Sets the output mode of the YAML emitted. Possible values are: + + - **original** + + The original formatting used in the input. This is default mode. + + - **block** + + The output is forced to be in block mode. All flow constructs will + be converted to block mode. + + - **flow** + + The output is forced to be in flow mode. All block constructs will + be converted to flow mode. + + - **flow-oneline** + + 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. + + - **json** + + 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. + + - **json-oneline** + + The output is forced to be in JSON mode and in a single line. + + - **dejson** + + Output is in block YAML mode but with special care to convert + JSON quoted strings in as non-idiomatic YAML as possible. + For example `{ foo: "this is a test" }` will be emitted as + `foo: this is a test`. YAML can handle scalars without using + excessive quoting. + +.. option:: -C MODE, --color=MODE + + It is possible to colorize output using ANSI color escape sequences, + and the mode can be one of: + + - **off** + + Never colorize output. + + - **on** + + Always colorize output. + + - **auto** + + Automatically colorize output when the output is a terminal. + This is the default. + +.. option:: -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. + +.. option:: -s, --sort + + Sort keys on output. This option is disabled by default. + +.. option:: -c, --comment + + Experimental output comments option. Enabled output while preserving comments. + Disabled by default. + +.. option:: --strip-labels + + Strip labels on output. Disabled by default. + +.. option:: --strip-tags + + Strip tags on output. Disabled by default. + +.. option:: --strip-doc + + Strip document indicators on output. Disabled by default. + +.. rubric:: Tool mode select options + +.. option:: --dump + + Select `dump` mode of operation. This is the default. + This mode is also enabled when the called binary is aliased to + *fy-dump*. + + 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. + + If the file provided is `-` then the input is the standard input. + +.. option:: --testsuite + + Select `testsuite` mode of operation. + This mode is also enabled when the called binary is aliased to *fy-testsuite*. + + In this mode, a single YAML file is read and an event stream is + generated which is the format used for *yaml-testsuite* compliance. + + If the file provided is `-` then the input is the standard input. + +.. option:: --filter + + Select `filter` mode of operation. + This mode is also enabled when the called binary is aliased to *fy-filter*. + + 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 `-f/--file` option. + + If the file provided is `-` then the input is the standard input. + + .. option:: -f FILE, --file=FILE + + Use the given file as input instead of standard input. + + If first character of `FILE` is **>** 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" + +.. option:: --join + + Select `join` mode of operation. + This mode is also enabled when the called binary is aliased to *fy-join*. + + In this mode, multiple YAML files are joined into a single document, emitted + to the standard output. + + If the file provided is `-` then the input is the standard input. + + .. option:: -T PATH, --to=PATH + + The target path of the join. By default this is the root **/**. + + If first character of `FILE` is **>** the the input is the content of the option + that follows. + + .. option:: -F PATH, --from=PATH + + The origin path of the join (for each input). By default this is the root **/**. + + If first character of `FILE` is **>** the the input is the content of the option + that follows. + + .. option:: -t PATH, --trim=PATH + + Trim path of the output of the join. By default this is the root **/**. + + If first character of `FILE` is **>** the the input is the content of the option + that follows. + +Examples +-------- + +.. rubric:: Example input files + +We're going to be using a couple of YAML files in our examples. + +.. code-block:: yaml + :caption: invoice.yaml + + # invoice.yaml + invoice: 34843 + date : !!str 2001-01-23 + bill-to: &id001 + given : Chris + family : Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + +.. code-block:: yaml + :caption: simple-anchors.yaml + + # simple-anchors.yaml + foo: &label { bar: frooz } + baz: *label + +.. code-block:: yaml + :caption: mergekeyspec.yaml + + --- + - &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 + + +.. code-block:: yaml + :caption: bomb.yaml + + 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] + +.. rubric:: fy-dump examples. + +Parse and dump generated YAML document tree in the original YAML form + +.. code-block:: bash + + $ fy-dump invoice.yaml + +.. code-block:: yaml + + invoice: 34843 + date: !!str 2001-01-23 + bill-to: &id001 + given: Chris + family: Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + +Parse and dump generated YAML document tree in flow YAML form + +.. code-block:: bash + + $ fy-dump -mflow invoice.yaml + +.. code-block:: yaml + + { + invoice: 34843, + date: !!str 2001-01-23, + bill-to: &id001 { + given: Chris, + family: Dumars, + address: { + lines: "458 Walkman Dr.\nSuite #292\n" + } + } + } + +Parse and dump generated YAML document from the input string + +.. code-block:: bash + + $ fy-dump -mjson ">foo: bar" + +.. code-block:: json + + { + "foo": "bar" + } + +Using the resolve option on the `simple-anchors.yaml` + +.. code-block:: bash + + $ fy-dump -r simple-anchor.yaml + +.. code-block:: yaml + + foo: &label { + bar: frooz + } + baz: { + bar: frooz + } + +Stripping the labels too: + +.. code-block:: bash + + $ fy-dump -r --strip-label simple-anchor.yaml + +.. code-block:: yaml + + foo: { + bar: frooz + } + baz: { + bar: frooz + } + +Merge key support: + +.. code-block:: bash + + $ fy-dump -r --strip-label mergekeyspec.yaml + +.. code-block:: yaml + + --- + - { + 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 + +Sorting option: + +.. code-block:: bash + + $ fy-dump -s invoice.yaml + +.. code-block:: yaml + + bill-to: &id001 + address: + lines: | + 458 Walkman Dr. + Suite #292 + family: Dumars + given: Chris + date: !!str 2001-01-23 + invoice: 34843 + +.. rubric:: fy-testsuite example. + +An example using the testsuite mode generates the following +event stream from `invoice.yaml` + +Parse and dump test-suite event format + +.. code-block:: bash + + $ fy-testsuite invoice.yaml + +.. code-block:: + + +STR + +DOC + +MAP + =VAL :invoice + =VAL :34843 + =VAL :date + =VAL :2001-01-23 + =VAL :bill-to + +MAP &id001 + =VAL :given + =VAL :Chris + =VAL :family + =VAL :Dumars + =VAL :address + +MAP + =VAL :lines + =VAL |458 Walkman Dr.\nSuite #292\n + -MAP + -MAP + -MAP + -DOC + -STR + +.. rubric:: fy-filter examples. + +Filter out from the `/bill-to` path of `invoice.yaml` + +.. code-block:: bash + + $ cat invoice.yaml | fy-filter /bill-to + +.. code-block:: yaml + + &id001 + given: Chris + family: Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + +Filter example with arrays (and use the --file option) + +.. code-block:: bash + + $ fy-filter --file=mergekeyspec.yaml /5 + +.. code-block:: yaml + + --- + <<: *CENTER + r: 10 + label: center/big + +Follow anchors example + +.. code-block:: bash + + $ fy-filter --file=simple-anchors.yaml /baz/bar + +.. code-block:: yaml + + frooz + +Handle YAML bombs (if you can spare the memory and cpu time) + +.. code-block:: bash + + $ fy-filter --file=bomb.yaml -r / | wc -l + 6726047 + +You don\'t have to, you can just follow links to retrieve data. + +.. code-block:: bash + + $ fy-filter --file=stuff/bomb.yaml -l --strip-label /g/0/1/2/3/4/5/6 + +.. code-block:: yaml + + "lol" + +Following links works with merge keys too: + +.. code-block:: bash + + $ fy-filter --file=mergekeyspec.yaml -l --strip-label /5/x + +.. code-block:: yaml + + --- 1 + +.. rubric:: fy-join examples. + +Joining two YAML files that have root mappings. + +.. code-block:: bash + + $ fy-join simple-anchors.yaml invoice.yaml + +.. code-block:: yaml + + 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 + +Join two files with sequences at root: + +.. code-block:: bash + + $ fy-join -mblock ">[ foo, bar ]" ">[ baz ]" + +.. code-block:: yaml + + - foo + - bar + - baz + +Author +------ + +Pantelis Antoniou + +Bugs +---- + +* The only supported input and output character encoding is UTF8. +* Sorting does not respect language settings. +* There is no way for the user to specific a different coloring scheme. + +See also +-------- + +:manpage:`libfyaml(1)` diff --git a/include/libfyaml.h b/include/libfyaml.h new file mode 100644 index 0000000..61ffdb2 --- /dev/null +++ b/include/libfyaml.h @@ -0,0 +1,6788 @@ +/* + * libfyaml.h - Main header file of the public interface + * + * Copyright (c) 2019 Pantelis Antoniou + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LIBFYAML_H +#define LIBFYAML_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) +#include +#endif + +/* opaque types for the user */ +struct fy_token; +struct fy_document_state; +struct fy_parser; +struct fy_emitter; +struct fy_document; +struct fy_node; +struct fy_node_pair; +struct fy_anchor; +struct fy_node_mapping_sort_ctx; +struct fy_token_iter; +struct fy_diag; +struct fy_path_parser; +struct fy_path_expr; +struct fy_path_exec; +struct fy_path_component; +struct fy_path; + + +#ifndef FY_BIT +#define FY_BIT(x) (1U << (x)) +#endif + +/* NULL terminated string length specifier */ +#define FY_NT ((size_t)-1) + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define FY_EXPORT __attribute__ ((visibility ("default"))) +#define FY_DEPRECATED __attribute__ ((deprecated)) +#else +#define FY_EXPORT /* nothing */ +#define FY_DEPRECATED /* nothing */ +#endif + +/* make a copy of an allocated string and return it on stack + * note that this is a convenience, and should not be called + * in a loop. The string is always '\0' terminated. + * If the _str pointer is NULL, then NULL will be returned + */ +#ifndef FY_ALLOCA_COPY_FREE +#define FY_ALLOCA_COPY_FREE(_str, _len) \ + ({ \ + char *__str = (_str), *__stra = NULL; \ + size_t __len = (size_t)(_len); \ + \ + if (__str) { \ + if (__len == FY_NT) \ + __len = strlen(__str); \ + __stra = alloca(__len + 1); \ + memcpy(__stra, __str, __len); \ + __stra[__len] = '\0'; \ + free(__str); \ + } \ + (const char *)__stra; \ + }) +#endif + +/* same as above but when _str == NULL return "" */ +#ifndef FY_ALLOCA_COPY_FREE_NO_NULL +#define FY_ALLOCA_COPY_FREE_NO_NULL(_str, _len) \ + ({ \ + const char *__strb; \ + \ + __strb = FY_ALLOCA_COPY_FREE(_str, _len); \ + if (!__strb) \ + __strb = ""; \ + __strb; \ + }) +#endif + +/** + * DOC: libfyaml public API + * + */ + +/** + * struct fy_version - The YAML version + * + * @major: Major version number + * @minor: Major version number + * + * The parser fills it according to the \%YAML directive + * found in the document. + */ +struct fy_version { + int major; + int minor; +}; + +/* Build a fy_version * from the given major and minor */ +#define fy_version_make(_maj, _min) (&(struct fy_version){ (_maj), (_min) }) + +/** + * fy_version_compare() - Compare two yaml versions + * + * Compare the versions + * + * @va: The first version, if NULL use default version + * @vb: The second version, if NULL use default version + * + * Returns: + * 0 if versions are equal, > 0 if version va is higher than vb + * < 0 if version va is lower than vb + */ +int +fy_version_compare(const struct fy_version *va, const struct fy_version *vb) + FY_EXPORT; + +/** + * fy_version_default() - Get the default version of the library + * + * Return the default version of the library, i.e. the highest + * stable version that is supported. + * + * Returns: + * The default YAML version of this library + */ +const struct fy_version * +fy_version_default(void) + FY_EXPORT; + +/** + * fy_version_is_supported() - Check if supported version + * + * Check if the given YAML version is supported. + * + * @vers: The version to check, NULL means default version. + * + * Returns: + * true if version supported, false otherwise. + */ +bool +fy_version_is_supported(const struct fy_version *vers) + FY_EXPORT; + +/** + * fy_version_supported_iterate() - Iterate over the supported YAML versions + * + * This method iterates over the supported YAML versions of this ibrary. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @prevp: The previous version iterator + * + * Returns: + * The next node in sequence or NULL at the end of the sequence. + */ +const struct fy_version * +fy_version_supported_iterate(void **prevp) + FY_EXPORT; + +/** + * struct fy_tag - The YAML tag structure. + * + * @handle: Handle of the tag (i.e. `"!!"` ) + * @prefix: The prefix of the tag (i.e. `"tag:yaml.org,2002:"` + * + * The parser fills it according to the \%TAG directives + * encountered during parsing. + */ +struct fy_tag { + const char *handle; + const char *prefix; +}; + +/** + * struct fy_mark - marker holding information about a location + * in a &struct fy_input + * + * @input_pos: Position of the mark (from the start of the current input) + * @line: Line position (0 index based) + * @column: Column position (0 index based) + */ +struct fy_mark { + size_t input_pos; + int line; + int column; +}; + +/** + * enum fy_error_type - The supported diagnostic/error types + * + * @FYET_DEBUG: Debug level (disabled if library is not compiled in debug mode) + * @FYET_INFO: Informational level + * @FYET_NOTICE: Notice level + * @FYET_WARNING: Warning level + * @FYET_ERROR: Error level - error reporting is using this level + * @FYET_MAX: Non inclusive maximum fy_error_type value + * + */ +enum fy_error_type { + FYET_DEBUG, + FYET_INFO, + FYET_NOTICE, + FYET_WARNING, + FYET_ERROR, + FYET_MAX, +}; + +/** + * enum fy_error_module - Module which generated the diagnostic/error + * + * @FYEM_UNKNOWN: Unknown, default if not specific + * @FYEM_ATOM: Atom module, used by atom chunking + * @FYEM_SCAN: Scanner module + * @FYEM_PARSE: Parser module + * @FYEM_DOC: Document module + * @FYEM_BUILD: Build document module (after tree is constructed) + * @FYEM_INTERNAL: Internal error/diagnostic module + * @FYEM_SYSTEM: System error/diagnostic module + * @FYEM_MAX: Non inclusive maximum fy_error_module value + */ +enum fy_error_module { + FYEM_UNKNOWN, + FYEM_ATOM, + FYEM_SCAN, + FYEM_PARSE, + FYEM_DOC, + FYEM_BUILD, + FYEM_INTERNAL, + FYEM_SYSTEM, + FYEM_MAX, +}; + +/* Shift amount of the default version */ +#define FYPCF_DEFAULT_VERSION_SHIFT 9 +/* Mask of the default version */ +#define FYPCF_DEFAULT_VERSION_MASK ((1U << 5) - 1) +/* Build a default version */ +#define FYPCF_DEFAULT_VERSION(x) (((unsigned int)(x) & FYPCF_DEFAULT_VERSION_MASK) << FYPCF_DEFAULT_VERSION_SHIFT) + +/* Shift amount of the JSON input mode */ +#define FYPCF_JSON_SHIFT 16 +/* Mask of the JSON input mode */ +#define FYPCF_JSON_MASK ((1U << 2) - 1) +/* Build a JSON input mode option */ +#define FYPCF_JSON(x) (((unsigned int)(x) & FYPCF_JSON_MASK) << FYPCF_JSON_SHIFT) + +/* guaranteed minimum depth limit for generated document */ +/* the actual limit is larger depending on the platform */ +#define FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT 64 + +/** + * enum fy_parse_cfg_flags - Parse configuration flags + * + * These flags control the operation of the parse and the debugging + * output/error reporting via filling in the &fy_parse_cfg->flags member. + * + * @FYPCF_QUIET: Quiet, do not output any information messages + * @FYPCF_COLLECT_DIAG: Collect diagnostic/error messages + * @FYPCF_RESOLVE_DOCUMENT: When producing documents, automatically resolve them + * @FYPCF_DISABLE_MMAP_OPT: Disable mmap optimization + * @FYPCF_DISABLE_RECYCLING: Disable recycling optimization + * @FYPCF_PARSE_COMMENTS: Enable parsing of comments (experimental) + * @FYPCF_DISABLE_DEPTH_LIMIT: Disable depth limit check, use with enlarged stack + * @FYPCF_DISABLE_ACCELERATORS: Disable use of access accelerators (saves memory) + * @FYPCF_DISABLE_BUFFERING: Disable use of buffering where possible + * @FYPCF_DEFAULT_VERSION_AUTO: Automatically use the most recent version the library supports + * @FYPCF_DEFAULT_VERSION_1_1: Default version is YAML 1.1 + * @FYPCF_DEFAULT_VERSION_1_2: Default version is YAML 1.2 + * @FYPCF_DEFAULT_VERSION_1_3: Default version is YAML 1.3 (experimental) + * @FYPCF_SLOPPY_FLOW_INDENTATION: Allow sloppy indentation in flow mode + * @FYPCF_PREFER_RECURSIVE: Prefer recursive algorighms instead of iterative whenever possible + * @FYPCF_JSON_AUTO: Automatically enable JSON mode (when extension is .json) + * @FYPCF_JSON_NONE: Never enable JSON input mode + * @FYPCF_JSON_FORCE: Force JSON mode always + * @FYPCF_YPATH_ALIASES: Enable YPATH aliases mode + */ +enum fy_parse_cfg_flags { + FYPCF_QUIET = FY_BIT(0), + FYPCF_COLLECT_DIAG = FY_BIT(1), + FYPCF_RESOLVE_DOCUMENT = FY_BIT(2), + FYPCF_DISABLE_MMAP_OPT = FY_BIT(3), + FYPCF_DISABLE_RECYCLING = FY_BIT(4), + FYPCF_PARSE_COMMENTS = FY_BIT(5), + FYPCF_DISABLE_DEPTH_LIMIT = FY_BIT(6), + FYPCF_DISABLE_ACCELERATORS = FY_BIT(7), + FYPCF_DISABLE_BUFFERING = FY_BIT(8), + FYPCF_DEFAULT_VERSION_AUTO = FYPCF_DEFAULT_VERSION(0), + FYPCF_DEFAULT_VERSION_1_1 = FYPCF_DEFAULT_VERSION(1), + FYPCF_DEFAULT_VERSION_1_2 = FYPCF_DEFAULT_VERSION(2), + FYPCF_DEFAULT_VERSION_1_3 = FYPCF_DEFAULT_VERSION(3), + FYPCF_SLOPPY_FLOW_INDENTATION = FY_BIT(14), + FYPCF_PREFER_RECURSIVE = FY_BIT(15), + FYPCF_JSON_AUTO = FYPCF_JSON(0), + FYPCF_JSON_NONE = FYPCF_JSON(1), + FYPCF_JSON_FORCE = FYPCF_JSON(2), + FYPCF_YPATH_ALIASES = FY_BIT(18), +}; + +#define FYPCF_DEFAULT_PARSE (0) + +#define FYPCF_DEFAULT_DOC (FYPCF_QUIET | FYPCF_DEFAULT_PARSE) + +/* + * The FYPCF_DEBUG and FYPCF_COLOR flags have been removed, however + * to help with backwards compatibility we will define them as 0 + * so that code can continue to compile. + * + * You will need to eventualy modify the code if you actually depended + * on the old behaviour. + */ +#define FYPCF_MODULE_SHIFT 0 +#define FYPCF_MODULE_MASK 0 +#define FYPCF_DEBUG_LEVEL_SHIFT 0 +#define FYPCF_DEBUG_LEVEL_MASK 0 +#define FYPCF_DEBUG_LEVEL(x) 0 +#define FYPCF_DEBUG_DIAG_SHIFT 0 +#define FYPCF_DEBUG_DIAG_MASK 0 +#define FYPCF_DEBUG_DIAG_ALL 0 +#define FYPCF_DEBUG_DIAG_DEFAULT 0 +#define FYPCF_DEBUG_UNKNOWN 0 +#define FYPCF_DEBUG_ATOM 0 +#define FYPCF_DEBUG_SCAN 0 +#define FYPCF_DEBUG_PARSE 0 +#define FYPCF_DEBUG_DOC 0 +#define FYPCF_DEBUG_BUILD 0 +#define FYPCF_DEBUG_INTERNAL 0 +#define FYPCF_DEBUG_SYSTEM 0 +#define FYPCF_DEBUG_LEVEL_DEBUG 0 +#define FYPCF_DEBUG_LEVEL_INFO 0 +#define FYPCF_DEBUG_LEVEL_NOTICE 0 +#define FYPCF_DEBUG_LEVEL_WARNING 0 +#define FYPCF_DEBUG_LEVEL_ERROR 0 +#define FYPCF_DEBUG_DIAG_SOURCE 0 +#define FYPCF_DEBUG_DIAG_POSITION 0 +#define FYPCF_DEBUG_DIAG_TYPE 0 +#define FYPCF_DEBUG_DIAG_MODULE 0 +#define FYPCF_DEBUG_ALL 0 +#define FYPCF_DEBUG_DEFAULT 0 +#define FYPCF_COLOR_SHIFT 0 +#define FYPCF_COLOR_MASK 0 +#define FYPCF_COLOR(x) 0 +#define FYPCF_COLOR_AUTO 0 +#define FYPCF_COLOR_NONE 0 +#define FYPCF_COLOR_FORCE 0 + +/** + * struct fy_parse_cfg - parser configuration structure. + * + * Argument to the fy_parser_create() method which + * perform parsing of YAML files. + * + * @search_path: Search path when accessing files, seperate with ':' + * @flags: Configuration flags + * @userdata: Opaque user data pointer + * @diag: Optional diagnostic interface to use + */ +struct fy_parse_cfg { + const char *search_path; + enum fy_parse_cfg_flags flags; + void *userdata; + struct fy_diag *diag; +}; + +/** + * enum fy_event_type - Event types + * + * @FYET_NONE: No event + * @FYET_STREAM_START: Stream start event + * @FYET_STREAM_END: Stream end event + * @FYET_DOCUMENT_START: Document start event + * @FYET_DOCUMENT_END: Document end event + * @FYET_MAPPING_START: YAML mapping start event + * @FYET_MAPPING_END: YAML mapping end event + * @FYET_SEQUENCE_START: YAML sequence start event + * @FYET_SEQUENCE_END: YAML sequence end event + * @FYET_SCALAR: YAML scalar event + * @FYET_ALIAS: YAML alias event + */ +enum fy_event_type { + FYET_NONE, + FYET_STREAM_START, + FYET_STREAM_END, + FYET_DOCUMENT_START, + FYET_DOCUMENT_END, + FYET_MAPPING_START, + FYET_MAPPING_END, + FYET_SEQUENCE_START, + FYET_SEQUENCE_END, + FYET_SCALAR, + FYET_ALIAS, +}; + +/** + * fy_event_type_get_text() - Return text of an event type + * + * @type: The event type to get text from + * + * Returns: + * A pointer to a text, i.e for FYET_SCALAR "=VAL". + */ +const char * +fy_event_type_get_text(enum fy_event_type type) + FY_EXPORT; + +/** + * enum fy_scalar_style - Scalar styles supported by the parser/emitter + * + * @FYSS_ANY: Any scalar style, not generated by the parser. + * Lets the emitter to choose + * @FYSS_PLAIN: Plain scalar style + * @FYSS_SINGLE_QUOTED: Single quoted style + * @FYSS_DOUBLE_QUOTED: Double quoted style + * @FYSS_LITERAL: YAML literal block style + * @FYSS_FOLDED: YAML folded block style + * @FYSS_MAX: marks end of scalar styles + */ +enum fy_scalar_style { + FYSS_ANY = -1, + FYSS_PLAIN, + FYSS_SINGLE_QUOTED, + FYSS_DOUBLE_QUOTED, + FYSS_LITERAL, + FYSS_FOLDED, + FYSS_MAX, +}; + +/** + * struct fy_event - Event generated by the parser + * + * This structure is generated by the parser by each call + * to fy_parser_parse() and release by fy_parser_event_free() + * + * @type: Type of the event, see &enum fy_event_type + * + * @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 + * + * @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; + }; +}; + +/** + * fy_library_version() - Return the library version string + * + * Returns: + * A pointer to a version string of the form + * .[[.][-EXTRA-VERSION-INFO]] + */ +const char * +fy_library_version(void) + FY_EXPORT; + +/** + * fy_string_to_error_type() - Return the error type from a string + * + * @str: The string to convert to an error type + * + * Returns: + * The error type if greater or equal to zero, FYET_MAX otherwise + */ +enum fy_error_type fy_string_to_error_type(const char *str); + +/** + * fy_error_type_to_string() - Convert an error type to string + * + * @type: The error type to convert + * + * Returns: + * The string value of the error type or the empty string "" on error + */ +const char *fy_error_type_to_string(enum fy_error_type type); + +/** + * fy_string_to_error_module() - Return the error module from a string + * + * @str: The string to convert to an error module + * + * Returns: + * The error type if greater or equal to zero, FYEM_MAX otherwise + */ +enum fy_error_module fy_string_to_error_module(const char *str); + +/** + * fy_error_module_to_string() - Convert an error module to string + * + * @module: The error module to convert + * + * Returns: + * The string value of the error module or the empty string "" on error + */ +const char *fy_error_module_to_string(enum fy_error_module module); + +/** + * fy_event_is_implicit() - Check whether the given event is an implicit one + * + * @fye: A pointer to a &struct fy_event to check. + * + * Returns: + * true if the event is an implicit one. + */ +bool +fy_event_is_implicit(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_document_event_is_implicit() - Check whether the given document event is an implicit one + * + * @fye: A pointer to a &struct fy_event to check. + * It must be either a document start or document end event. + * + * Returns: + * true if the event is an implicit one. + */ +bool +fy_document_event_is_implicit(const struct fy_event *fye) + FY_EXPORT; + +/** + * fy_parser_create() - Create a parser. + * + * Creates a parser with its configuration @cfg + * The parser may be destroyed by a corresponding call to + * fy_parser_destroy(). + * + * @cfg: The configuration for the parser + * + * Returns: + * A pointer to the parser or NULL in case of an error. + */ +struct fy_parser * +fy_parser_create(const struct fy_parse_cfg *cfg) + FY_EXPORT; + +/** + * fy_parser_destroy() - Destroy the given parser + * + * Destroy a parser created earlier via fy_parser_create(). + * + * @fyp: The parser to destroy + */ +void +fy_parser_destroy(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_parser_get_cfg() - Get the configuration of a parser + * + * @fyp: The parser + * + * Returns: + * The configuration of the parser + */ +const struct fy_parse_cfg * +fy_parser_get_cfg(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_parser_get_diag() - Get the diagnostic object of a parser + * + * Return a pointer to the diagnostic object of a parser object. + * Note that the returned diag object has a reference taken so + * you should fy_diag_unref() it when you're done with it. + * + * @fyp: The parser to get the diagnostic object + * + * Returns: + * A pointer to a ref'ed diagnostic object or NULL in case of an + * error. + */ +struct fy_diag * +fy_parser_get_diag(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_parser_set_diag() - Set the diagnostic object of a parser + * + * Replace the parser's current diagnostic object with the one + * given as an argument. The previous diagnostic object will be + * unref'ed (and freed if its reference gets to 0). + * Also note that the diag argument shall take a reference too. + * + * @fyp: The parser to replace the diagnostic object + * @diag: The parser's new diagnostic object, NULL for default + * + * Returns: + * 0 if everything OK, -1 otherwise + */ +int +fy_parser_set_diag(struct fy_parser *fyp, struct fy_diag *diag) + FY_EXPORT; + +/** + * fy_parser_reset() - Reset a parser completely + * + * Completely reset a parser, including after an error + * that caused a parser error to be emitted. + * + * @fyp: The parser to reset + * + * Returns: + * 0 if the reset was successful, -1 otherwise + */ +int +fy_parser_reset(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_parser_set_input_file() - Set the parser to process the given file + * + * Point the parser to the given @file for processing. The file + * is located by honoring the search path of the configuration set + * by the earlier call to fy_parser_create(). + * While the parser is in use the file will must be available. + * + * @fyp: The parser + * @file: The file to parse. + * + * Returns: + * zero on success, -1 on error + */ +int +fy_parser_set_input_file(struct fy_parser *fyp, const char *file) + FY_EXPORT; + +/** + * fy_parser_set_string() - Set the parser to process the given string. + * + * Point the parser to the given (NULL terminated) string. Note that + * while the parser is active the string must not go out of scope. + * + * @fyp: The parser + * @str: The YAML string to parse. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * zero on success, -1 on error + */ +int +fy_parser_set_string(struct fy_parser *fyp, const char *str, size_t len) + FY_EXPORT; + +/** + * fy_parser_set_malloc_string() - Set the parser to process the given malloced string. + * + * Point the parser to the given (possible NULL terminated) string. Note that + * the string is expected to be allocated via malloc(3) and ownership is transferred + * to the created input. When the input is free'ed the memory will be automatically + * freed. + * + * In case of an error the string is not freed. + * + * @fyp: The parser + * @str: The YAML string to parse (allocated). + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * zero on success, -1 on error + */ +int +fy_parser_set_malloc_string(struct fy_parser *fyp, char *str, size_t len) + FY_EXPORT; + +/** + * fy_parser_set_input_fp() - Set the parser to process the given file + * + * Point the parser to use @fp for processing. + * + * @fyp: The parser + * @name: The label of the stream + * @fp: The FILE pointer, it must be open in read mode. + * + * Returns: + * zero on success, -1 on error + */ +int +fy_parser_set_input_fp(struct fy_parser *fyp, const char *name, FILE *fp) + FY_EXPORT; + +/** + * fy_parser_set_input_callback() - Set the parser to process via a callback + * + * Point the parser to use a callback for input. + * + * @fyp: The parser + * @user: The user data pointer + * @callback: The callback method to request data with + * + * Returns: + * zero on success, -1 on error + */ +int fy_parser_set_input_callback(struct fy_parser *fyp, void *user, + ssize_t (*callback)(void *user, void *buf, size_t count)) + FY_EXPORT; + +/** + * fy_parser_parse() - Parse and return the next event. + * + * Each call to fy_parser_parse() returns the next event from + * the configured input of the parser, or NULL at the end of + * the stream. The returned event must be released via + * a matching call to fy_parser_event_free(). + * + * @fyp: The parser + * + * Returns: + * The next event in the stream or NULL. + */ +struct fy_event * +fy_parser_parse(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_parser_event_free() - Free an event + * + * Free a previously returned event from fy_parser_parse(). + * + * @fyp: The parser + * @fye: The event to free (may be NULL) + */ +void +fy_parser_event_free(struct fy_parser *fyp, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_parser_get_stream_error() - Check the parser for stream errors + * + * @fyp: The parser + * + * Returns: + * true in case of a stream error, false otherwise. + */ +bool +fy_parser_get_stream_error(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_token_scalar_style() - Get the style of a scalar token + * + * @fyt: The scalar token to get it's style. Note that a NULL + * token is a &enum FYSS_PLAIN. + * + * Returns: + * The scalar style of the token, or FYSS_PLAIN on each other case + */ +enum fy_scalar_style +fy_token_scalar_style(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_token_get_text() - Get text (and length of it) of a token + * + * This method will return a pointer to the text of a token + * along with the length of it. Note that this text is *not* + * NULL terminated. If you need a NULL terminated pointer + * use fy_token_get_text0(). + * + * In case that the token is 'simple' enough (i.e. a plain scalar) + * or something similar the returned pointer is a direct pointer + * to the space of the input that contains the token. + * + * That means that the pointer is *not* guaranteed to be valid + * after the parser is destroyed. + * + * If the token is 'complex' enough, then space shall be allocated, + * filled and returned. + * + * Note that the concept of 'simple' and 'complex' is vague, and + * that's on purpose. + * + * @fyt: The token out of which the text pointer will be returned. + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the text representation of the token, while + * @lenp will be assigned the character length of said representation. + * NULL in case of an error. + */ +const char * +fy_token_get_text(struct fy_token *fyt, size_t *lenp) + FY_EXPORT; + +/** + * fy_token_get_text0() - Get zero terminated text of a token + * + * This method will return a pointer to the text of a token + * which is zero terminated. It will allocate memory to hold + * it in the token structure so try to use fy_token_get_text() + * instead if possible. + * + * @fyt: The token out of which the text pointer will be returned. + * + * Returns: + * A pointer to a zero terminated text representation of the token. + * NULL in case of an error. + */ +const char * +fy_token_get_text0(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_token_get_text_length() - Get length of the text of a token + * + * This method will return the length of the text representation + * of a token. + * + * @fyt: The token + * + * Returns: + * The size of the text representation of a token, -1 in case of an error. + * Note that the NULL token will return a length of zero. + */ +size_t +fy_token_get_text_length(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_token_get_utf8_length() - Get length of the text of a token + * + * This method will return the length of the text representation + * of a token as a utf8 string. + * + * @fyt: The token + * + * Returns: + * The size of the utf8 text representation of a token, -1 in case of an error. + * Note that the NULL token will return a length of zero. + */ +size_t +fy_token_get_utf8_length(struct fy_token *fyt) + FY_EXPORT; + +/** + * enum fy_comment_placement - Comment placement relative to token + * + * @fycp_top: Comment on top of token + * @fycp_right: Comment to the right of the token + * @fycp_bottom: Comment to the bottom of the token + */ +enum fy_comment_placement { + fycp_top, + fycp_right, + fycp_bottom +}; +#define fycp_max (fycp_bottom + 1) + +/** + * fy_token_get_comment() - Get zero terminated comment of a token + * + * @fyt: The token out of which the comment text will be returned. + * + * Returns: + * A pointer to a zero terminated text representation of the token comment. + * NULL in case of an error or if the token has no comment. + */ +const char * +fy_token_get_comment(struct fy_token *fyt, char *buf, size_t maxsz, + enum fy_comment_placement which) + FY_EXPORT; + +/** + * struct fy_iter_chunk - An iteration chunk + * + * @str: Pointer to the start of the chunk + * @len: The size of the chunk + * + * The iterator produces a stream of chunks which + * cover the whole object. + */ +struct fy_iter_chunk { + const char *str; + size_t len; +}; + +/** + * fy_token_iter_create() - Create a token iterator + * + * Create an iterator for operating on the given token, or + * a generic iterator for use with fy_token_iter_start(). + * The iterator must be destroyed with a matching call to + * fy_token_iter_destroy(). + * + * @fyt: The token to iterate, or NULL. + * + * Returns: + * A pointer to the newly created iterator, or NULL in case of + * an error. + */ +struct fy_token_iter * +fy_token_iter_create(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_token_iter_destroy() - Destroy the iterator + * + * Destroy the iterator created by fy_token_iter_create(). + * + * @iter: The iterator to destroy. + */ +void +fy_token_iter_destroy(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_start() - Start iterating over the contents of a token + * + * Prepare an iterator for operating on the given token. + * The iterator must be created via a previous call to fy_token_iter_create() + * for user level API access. + * + * @fyt: The token to iterate over + * @iter: The iterator to prepare. + */ +void +fy_token_iter_start(struct fy_token *fyt, struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_finish() - Stop iterating over the contents of a token + * + * Stop the iteration operation. + * + * @iter: The iterator. + */ +void +fy_token_iter_finish(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_peek_chunk() - Peek at the next iterator chunk + * + * Peek at the next iterator chunk + * + * @iter: The iterator. + * + * Returns: + * A pointer to the next iterator chunk, or NULL in case there's + * no other. + */ +const struct fy_iter_chunk * +fy_token_iter_peek_chunk(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_chunk_next() - Get next iterator chunk + * + * Get the next iterator chunk in sequence, + * + * @iter: The iterator. + * @curr: The current chunk, or NULL for the first one. + * @errp: Pointer to an error return value or NULL + * + * Returns: + * A pointer to the next iterator chunk, or NULL in case there's + * no other. When the return value is NULL, the errp variable + * will be filled with 0 for normal end, or -1 in case of an error. + */ +const struct fy_iter_chunk * +fy_token_iter_chunk_next(struct fy_token_iter *iter, + const struct fy_iter_chunk *curr, int *errp) + FY_EXPORT; + +/** + * fy_token_iter_advance() - Advance the iterator position + * + * Advance the read pointer of the iterator. + * Note that mixing calls of this with any call of fy_token_iter_ungetc() / + * fy_token_iter_utf8_unget() in a single iterator sequence leads + * to undefined behavior. + * + * @iter: The iterator. + * @len: Number of bytes to advance the iterator position + */ +void +fy_token_iter_advance(struct fy_token_iter *iter, size_t len) + FY_EXPORT; + +/** + * fy_token_iter_read() - Read a block from an iterator + * + * Read a block from an iterator. Note than mixing calls of this + * and any of the ungetc methods leads to undefined behavior. + * + * @iter: The iterator. + * @buf: Pointer to a block of memory to receive the data. Must be at + * least count bytes long. + * @count: Amount of bytes to read. + * + * Returns: + * The amount of data read, or -1 in case of an error. + */ +ssize_t +fy_token_iter_read(struct fy_token_iter *iter, void *buf, size_t count) + FY_EXPORT; + +/** + * fy_token_iter_getc() - Get a single character from an iterator + * + * Reads a single character from an iterator. If the iterator is + * finished, it will return -1. If any calls to ungetc have pushed + * a character in the iterator it shall return that. + * + * @iter: The iterator. + * + * Returns: + * The next character in the iterator, or -1 in case of an error, or + * end of stream. + */ +int +fy_token_iter_getc(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_ungetc() - Ungets a single character from an iterator + * + * Pushes back a single character to an iterator stream. It will be + * returned in subsequent calls of fy_token_iter_getc(). Currently + * only a single character is allowed to be pushed back, and any + * further calls to ungetc will return an error. + * + * @iter: The iterator. + * @c: The character to push back, or -1 to reset the pushback buffer. + * + * Returns: + * The pushed back character given as argument, or -1 in case of an error. + * If the pushed back character was -1, then 0 will be returned. + */ +int +fy_token_iter_ungetc(struct fy_token_iter *iter, int c) + FY_EXPORT; + +/** + * fy_token_iter_peekc() - Peeks at single character from an iterator + * + * Peeks at the next character to get from an iterator. If the iterator is + * finished, it will return -1. If any calls to ungetc have pushed + * a character in the iterator it shall return that. The character is not + * removed from the iterator stream. + * + * @iter: The iterator. + * + * Returns: + * The next character in the iterator, or -1 in case of an error, or end + * of stream. + */ +int +fy_token_iter_peekc(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_utf8_get() - Get a single utf8 character from an iterator + * + * Reads a single utf8 character from an iterator. If the iterator is + * finished, it will return -1. If any calls to ungetc have pushed + * a character in the iterator it shall return that. + * + * @iter: The iterator. + * + * Returns: + * The next utf8 character in the iterator, or -1 in case of an error, or end + * of stream. + */ +int +fy_token_iter_utf8_get(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_token_iter_utf8_unget() - Ungets a single utf8 character from an iterator + * + * Pushes back a single utf8 character to an iterator stream. It will be + * returned in subsequent calls of fy_token_iter_utf8_getc(). Currently + * only a single character is allowed to be pushed back, and any + * further calls to ungetc will return an error. + * + * @iter: The iterator. + * @c: The character to push back, or -1 to reset the pushback buffer. + * + * Returns: + * The pushed back utf8 character given as argument, or -1 in case of an error. + * If the pushed back utf8 character was -1, then 0 will be returned. + */ +int +fy_token_iter_utf8_unget(struct fy_token_iter *iter, int c) + FY_EXPORT; + +/** + * fy_token_iter_utf8_peek() - Peeks at single utf8 character from an iterator + * + * Peeks at the next utf8 character to get from an iterator. If the iterator is + * finished, it will return -1. If any calls to ungetc have pushed + * a character in the iterator it shall return that. The character is not + * removed from the iterator stream. + * + * @iter: The iterator. + * + * Returns: + * The next utf8 character in the iterator, or -1 in case of an error, or end + * of stream. + */ +int +fy_token_iter_utf8_peek(struct fy_token_iter *iter) + FY_EXPORT; + +/** + * fy_parse_load_document() - Parse the next document from the parser stream + * + * This method performs parsing on a parser stream and returns the next + * document. This means that for a compound document with multiple + * documents, each call will return the next document. + * + * @fyp: The parser + * + * Returns: + * The next document from the parser stream. + */ +struct fy_document * +fy_parse_load_document(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_parse_document_destroy() - Destroy a document created by fy_parse_load_document() + * + * @fyp: The parser + * @fyd: The document to destroy + */ +void +fy_parse_document_destroy(struct fy_parser *fyp, struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_resolve() - Resolve anchors and merge keys + * + * This method performs resolution of the given document, + * by replacing references to anchors with their contents + * and handling merge keys (<<) + * + * @fyd: The document to resolve + * + * Returns: + * zero on success, -1 on error + */ +int +fy_document_resolve(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_has_directives() - Document directive check + * + * Checks whether the given document has any directives, i.e. + * %TAG or %VERSION. + * + * @fyd: The document to check for directives existence + * + * Returns: + * true if directives exist, false if not + */ +bool +fy_document_has_directives(const struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_has_explicit_document_start() - Explicit document start check + * + * Checks whether the given document has an explicit document start marker, + * i.e. --- + * + * @fyd: The document to check for explicit start marker + * + * Returns: + * true if document has an explicit document start marker, false if not + */ +bool +fy_document_has_explicit_document_start(const struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_has_explicit_document_end() - Explicit document end check + * + * Checks whether the given document has an explicit document end marker, + * i.e. ... + * + * @fyd: The document to check for explicit end marker + * + * Returns: + * true if document has an explicit document end marker, false if not + */ +bool +fy_document_has_explicit_document_end(const struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_node_document() - Retreive the document the node belong to + * + * Returns the document of the node; note that while the node may not + * be reachable via a path expression, it may still be member of a + * document. + * + * @fyn: The node to retreive it's document + * + * Returns: + * The document of the node, or NULL in case of an error, or + * when the node has no document attached. + */ +struct fy_document * +fy_node_document(struct fy_node *fyn) + FY_EXPORT; + +/* + * enum fy_emitter_write_type - Type of the emitted output + * + * Describes the kind of emitted output, which makes it + * possible to colorize the output, or do some other content related + * filtering. + * + * @fyewt_document_indicator: Output chunk is a document indicator + * @fyewt_tag_directive: Output chunk is a tag directive + * @fyewt_version_directive: Output chunk is a version directive + * @fyewt_indent: Output chunk is a document indicator + * @fyewt_indicator: Output chunk is an indicator + * @fyewt_whitespace: Output chunk is white space + * @fyewt_plain_scalar: Output chunk is a plain scalar + * @fyewt_single_quoted_scalar: Output chunk is a single quoted scalar + * @fyewt_double_quoted_scalar: Output chunk is a double quoted scalar + * @fyewt_literal_scalar: Output chunk is a literal block scalar + * @fyewt_folded_scalar: Output chunk is a folded block scalar + * @fyewt_anchor: Output chunk is an anchor + * @fyewt_tag: Output chunk is a tag + * @fyewt_linebreak: Output chunk is a linebreak + * @fyewt_alias: Output chunk is an alias + * @fyewt_terminating_zero: Output chunk is a terminating zero + * @fyewt_plain_scalar_key: Output chunk is an plain scalar key + * @fyewt_single_quoted_scalar_key: Output chunk is an single quoted scalar key + * @fyewt_double_quoted_scalar_key: Output chunk is an double quoted scalar key + * @fyewt_comment: Output chunk is a comment + * + */ +enum fy_emitter_write_type { + fyewt_document_indicator, + fyewt_tag_directive, + fyewt_version_directive, + fyewt_indent, + fyewt_indicator, + fyewt_whitespace, + fyewt_plain_scalar, + fyewt_single_quoted_scalar, + fyewt_double_quoted_scalar, + fyewt_literal_scalar, + fyewt_folded_scalar, + fyewt_anchor, + fyewt_tag, + fyewt_linebreak, + fyewt_alias, + fyewt_terminating_zero, + fyewt_plain_scalar_key, + fyewt_single_quoted_scalar_key, + fyewt_double_quoted_scalar_key, + fyewt_comment, +}; + +#define FYECF_INDENT_SHIFT 8 +#define FYECF_INDENT_MASK 0xf +#define FYECF_INDENT(x) (((x) & FYECF_INDENT_MASK) << FYECF_INDENT_SHIFT) + +#define FYECF_WIDTH_SHIFT 12 +#define FYECF_WIDTH_MASK 0xff +#define FYECF_WIDTH(x) (((x) & FYECF_WIDTH_MASK) << FYECF_WIDTH_SHIFT) + +#define FYECF_MODE_SHIFT 20 +#define FYECF_MODE_MASK 0xf +#define FYECF_MODE(x) (((x) & FYECF_MODE_MASK) << FYECF_MODE_SHIFT) + +#define FYECF_DOC_START_MARK_SHIFT 24 +#define FYECF_DOC_START_MARK_MASK 0x3 +#define FYECF_DOC_START_MARK(x) (((x) & FYECF_DOC_START_MARK_MASK) << FYECF_DOC_START_MARK_SHIFT) + +#define FYECF_DOC_END_MARK_SHIFT 26 +#define FYECF_DOC_END_MARK_MASK 0x3 +#define FYECF_DOC_END_MARK(x) (((x) & FYECF_DOC_END_MARK_MASK) << FYECF_DOC_END_MARK_SHIFT) + +#define FYECF_VERSION_DIR_SHIFT 28 +#define FYECF_VERSION_DIR_MASK 0x3 +#define FYECF_VERSION_DIR(x) (((x) & FYECF_VERSION_DIR_MASK) << FYECF_VERSION_DIR_SHIFT) + +#define FYECF_TAG_DIR_SHIFT 30 +#define FYECF_TAG_DIR_MASK 0x3 +#define FYECF_TAG_DIR(x) (((unsigned int)(x) & FYECF_TAG_DIR_MASK) << FYECF_TAG_DIR_SHIFT) + +/** + * enum fy_emitter_cfg_flags - Emitter configuration flags + * + * These flags control the operation of the emitter + * + * @FYECF_SORT_KEYS: Sort key when emitting + * @FYECF_OUTPUT_COMMENTS: Output comments (experimental) + * @FYECF_STRIP_LABELS: Strip labels when emitting + * @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_INDENT_DEFAULT: Default emit output indent + * @FYECF_INDENT_1: Output indent is 1 + * @FYECF_INDENT_2: Output indent is 2 + * @FYECF_INDENT_3: Output indent is 3 + * @FYECF_INDENT_4: Output indent is 4 + * @FYECF_INDENT_5: Output indent is 5 + * @FYECF_INDENT_6: Output indent is 6 + * @FYECF_INDENT_7: Output indent is 7 + * @FYECF_INDENT_8: Output indent is 8 + * @FYECF_INDENT_9: Output indent is 9 + * @FYECF_WIDTH_DEFAULT: Default emit output width + * @FYECF_WIDTH_80: Output width is 80 + * @FYECF_WIDTH_132: Output width is 132 + * @FYECF_WIDTH_INF: Output width is infinite + * @FYECF_MODE_ORIGINAL: Emit using the same flow mode as the original + * @FYECF_MODE_BLOCK: Emit using only the block mode + * @FYECF_MODE_FLOW: Emit using only the flow mode + * @FYECF_MODE_FLOW_ONELINE: Emit using only the flow mode (in one line) + * @FYECF_MODE_JSON: Emit using JSON mode (non type preserving) + * @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_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_DOC_END_MARK_AUTO: Automatically generate document end markers if required + * @FYECF_DOC_END_MARK_OFF: Do not generate document end markers + * @FYECF_DOC_END_MARK_ON: Always generate document end markers + * @FYECF_VERSION_DIR_AUTO: Automatically generate version directive + * @FYECF_VERSION_DIR_OFF: Never generate version directive + * @FYECF_VERSION_DIR_ON: Always generate version directive + * @FYECF_TAG_DIR_AUTO: Automatically generate tag directives + * @FYECF_TAG_DIR_OFF: Never generate tag directives + * @FYECF_TAG_DIR_ON: Always generate tag directives + * @FYECF_DEFAULT: The default emitter configuration + */ +enum fy_emitter_cfg_flags { + FYECF_SORT_KEYS = FY_BIT(0), + FYECF_OUTPUT_COMMENTS = FY_BIT(1), + FYECF_STRIP_LABELS = FY_BIT(2), + FYECF_STRIP_TAGS = FY_BIT(3), + FYECF_STRIP_DOC = FY_BIT(4), + FYECF_NO_ENDING_NEWLINE = FY_BIT(5), + FYECF_INDENT_DEFAULT = FYECF_INDENT(0), + FYECF_INDENT_1 = FYECF_INDENT(1), + FYECF_INDENT_2 = FYECF_INDENT(2), + FYECF_INDENT_3 = FYECF_INDENT(3), + FYECF_INDENT_4 = FYECF_INDENT(4), + FYECF_INDENT_5 = FYECF_INDENT(5), + FYECF_INDENT_6 = FYECF_INDENT(6), + FYECF_INDENT_7 = FYECF_INDENT(7), + FYECF_INDENT_8 = FYECF_INDENT(8), + FYECF_INDENT_9 = FYECF_INDENT(9), + FYECF_WIDTH_DEFAULT = FYECF_WIDTH(80), + FYECF_WIDTH_80 = FYECF_WIDTH(80), + FYECF_WIDTH_132 = FYECF_WIDTH(132), + FYECF_WIDTH_INF = FYECF_WIDTH(255), + FYECF_MODE_ORIGINAL = FYECF_MODE(0), + FYECF_MODE_BLOCK = FYECF_MODE(1), + FYECF_MODE_FLOW = FYECF_MODE(2), + FYECF_MODE_FLOW_ONELINE = FYECF_MODE(3), + FYECF_MODE_JSON = FYECF_MODE(4), + FYECF_MODE_JSON_TP = FYECF_MODE(5), + FYECF_MODE_JSON_ONELINE = FYECF_MODE(6), + FYECF_MODE_DEJSON = FYECF_MODE(7), + 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), + FYECF_DOC_END_MARK_AUTO = FYECF_DOC_END_MARK(0), + FYECF_DOC_END_MARK_OFF = FYECF_DOC_END_MARK(1), + FYECF_DOC_END_MARK_ON = FYECF_DOC_END_MARK(2), + FYECF_VERSION_DIR_AUTO = FYECF_VERSION_DIR(0), + FYECF_VERSION_DIR_OFF = FYECF_VERSION_DIR(1), + FYECF_VERSION_DIR_ON = FYECF_VERSION_DIR(2), + FYECF_TAG_DIR_AUTO = FYECF_TAG_DIR(0), + FYECF_TAG_DIR_OFF = FYECF_TAG_DIR(1), + FYECF_TAG_DIR_ON = FYECF_TAG_DIR(2), + + FYECF_DEFAULT = FYECF_WIDTH_INF | + FYECF_MODE_ORIGINAL | + FYECF_INDENT_DEFAULT, +}; + +/** + * struct fy_emitter_cfg - emitter configuration structure. + * + * Argument to the fy_emitter_create() method which + * is the way to convert a runtime document structure back to YAML. + * + * @flags: Configuration flags + * @output: Pointer to the method that will perform output. + * @userdata: Opaque user data pointer + * @diag: Diagnostic interface + */ +struct fy_emitter_cfg { + enum fy_emitter_cfg_flags flags; + int (*output)(struct fy_emitter *emit, enum fy_emitter_write_type type, + const char *str, int len, void *userdata); + void *userdata; + struct fy_diag *diag; +}; + +/** + * fy_emitter_create() - Create an emitter + * + * Creates an emitter using the supplied configuration + * + * @cfg: The emitter configuration + * + * Returns: + * The newly created emitter or NULL on error. + */ +struct fy_emitter * +fy_emitter_create(const struct fy_emitter_cfg *cfg) + FY_EXPORT; + +/** + * fy_emitter_destroy() - Destroy an emitter + * + * Destroy an emitter previously created by fy_emitter_create() + * + * @emit: The emitter to destroy + */ +void +fy_emitter_destroy(struct fy_emitter *emit) + FY_EXPORT; + +/** + * fy_emitter_get_cfg() - Get the configuration of an emitter + * + * @emit: The emitter + * + * Returns: + * The configuration of the emitter + */ +const struct fy_emitter_cfg * +fy_emitter_get_cfg(struct fy_emitter *emit) + FY_EXPORT; + +/** + * fy_emitter_get_diag() - Get the diagnostic object of an emitter + * + * Return a pointer to the diagnostic object of an emitter object. + * Note that the returned diag object has a reference taken so + * you should fy_diag_unref() it when you're done with it. + * + * @emit: The emitter to get the diagnostic object + * + * Returns: + * A pointer to a ref'ed diagnostic object or NULL in case of an + * error. + */ +struct fy_diag * +fy_emitter_get_diag(struct fy_emitter *emit) + FY_EXPORT; + +/** + * fy_emitter_set_diag() - Set the diagnostic object of an emitter + * + * Replace the emitters's current diagnostic object with the one + * given as an argument. The previous diagnostic object will be + * unref'ed (and freed if its reference gets to 0). + * Also note that the diag argument shall take a reference too. + * + * @emit: The emitter to replace the diagnostic object + * @diag: The emitter's new diagnostic object, NULL for default + * + * Returns: + * 0 if everything OK, -1 otherwise + */ +int +fy_emitter_set_diag(struct fy_emitter *emit, struct fy_diag *diag) + FY_EXPORT; + +/** + * struct fy_emitter_default_output_data - emitter default output configuration + * + * This is the argument to the default output method of the emitter. + * + * @fp: File where the output is directed to + * @colorize: Use ANSI color sequences to colorize the output + * @visible: Make whitespace visible (requires a UTF8 capable terminal) + */ +struct fy_emitter_default_output_data { + FILE *fp; + bool colorize; + bool visible; +}; + +/** + * fy_emitter_default_output() - The default colorizing output method + * + * This is the default colorizing output method. + * Will be used when the output field of the emitter configuration is NULL. + * + * @fye: The emitter + * @type: Type of the emitted output + * @str: Pointer to the string to output + * @len: Length of the string + * @userdata: Must point to a fy_emitter_default_output_data structure + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emitter_default_output(struct fy_emitter *fye, enum fy_emitter_write_type type, + const char *str, int len, void *userdata) + FY_EXPORT; + +/** + * fy_document_default_emit_to_fp() - Emit a document to a file, using defaults + * + * Simple one shot emitter to a file, using the default emitter output. + * The output will be colorized if the the file points to a tty. + * + * @fyd: The document to emit + * @fp: The file where the output is sent + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_document_default_emit_to_fp(struct fy_document *fyd, FILE *fp) + FY_EXPORT; + +/** + * fy_emit_event() - Queue (and possibly emit) an event + * + * Queue and output using the emitter. This is the streaming + * output method which does not require creating a document. + * + * @emit: The emitter to use + * @fye: The event to queue for emission + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_event(struct fy_emitter *emit, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_emit_event_from_parser() - Queue (and possibly emit) an event + * generated by the parser. + * + * Queue and output using the emitter. This is the streaming + * output method which does not require creating a document. + * Similar to fy_emit_event() but it is more efficient. + * + * @emit: The emitter to use + * @fyp: The parser that generated the event + * @fye: The event to queue for emission + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_event_from_parser(struct fy_emitter *emit, struct fy_parser *fyp, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_emit_document() - Emit the document using the emitter + * + * Emits a document in YAML format using the emitter. + * + * @emit: The emitter + * @fyd: The document to emit + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_document(struct fy_emitter *emit, struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_emit_document_start() - Emit document start using the emitter + * + * Emits a document start using the emitter. This is used in case + * you need finer control over the emitting output. + * + * @emit: The emitter + * @fyd: The document to use for emitting it's start + * @fyn: The root (or NULL for using the document's root) + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_document_start(struct fy_emitter *emit, struct fy_document *fyd, + struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_emit_document_end() - Emit document end using the emitter + * + * Emits a document end using the emitter. This is used in case + * you need finer control over the emitting output. + * + * @emit: The emitter + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_document_end(struct fy_emitter *emit) + FY_EXPORT; + +/** + * fy_emit_node() - Emit a single node using the emitter + * + * Emits a single node using the emitter. This is used in case + * you need finer control over the emitting output. + * + * @emit: The emitter + * @fyn: The node to emit + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_node(struct fy_emitter *emit, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_emit_root_node() - Emit a single root node using the emitter + * + * Emits a single root node using the emitter. This is used in case + * you need finer control over the emitting output. + * + * @emit: The emitter + * @fyn: The root node to emit + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_root_node(struct fy_emitter *emit, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_emit_explicit_document_end() - Emit an explicit document end + * + * Emits an explicit document end, i.e. ... . Use this if you + * you need finer control over the emitting output. + * + * @emit: The emitter + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_explicit_document_end(struct fy_emitter *emit) + FY_EXPORT; + +/** + * fy_emit_document_to_fp() - Emit a document to an file pointer + * + * Emits a document from the root to the given file pointer. + * + * @fyd: The document to emit + * @flags: The emitter flags to use + * @fp: The file pointer to output to + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_document_to_fp(struct fy_document *fyd, + enum fy_emitter_cfg_flags flags, FILE *fp) + FY_EXPORT; + +/** + * fy_emit_document_to_file() - Emit a document to file + * + * Emits a document from the root to the given file. + * The file will be fopen'ed using a "wa" mode. + * + * @fyd: The document to emit + * @flags: The emitter flags to use + * @filename: The filename to output to, or NULL for stdout + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_emit_document_to_file(struct fy_document *fyd, + enum fy_emitter_cfg_flags flags, + const char *filename) + FY_EXPORT; + +/** + * fy_emit_document_to_buffer() - Emit a document to a buffer + * + * Emits an document from the root to the given buffer. + * If the document does not fit, an error will be returned. + * + * @fyd: The document to emit + * @flags: The emitter flags to use + * @buf: Pointer to the buffer area to fill + * @size: Size of the buffer + * + * Returns: + * A positive number, which is the size of the emitted document + * on the buffer on success, -1 on error + */ +int +fy_emit_document_to_buffer(struct fy_document *fyd, + enum fy_emitter_cfg_flags flags, + char *buf, int size) + FY_EXPORT; + +/** + * fy_emit_document_to_string() - Emit a document to an allocated string + * + * Emits an document from the root to a string which will be dynamically + * allocated. + * + * @fyd: The document to emit + * @flags: The emitter flags to use + * + * Returns: + * A pointer to the allocated string, or NULL in case of an error + */ +char * +fy_emit_document_to_string(struct fy_document *fyd, + enum fy_emitter_cfg_flags flags) + FY_EXPORT; + +#define fy_emit_document_to_string_alloca(_fyd, _flags) \ + FY_ALLOCA_COPY_FREE(fy_emit_document_to_string((_fyd), (_flags)), FY_NT) + +/** + * fy_emit_node_to_buffer() - Emit a node (recursively) to a buffer + * + * Emits a node recursively to the given buffer. + * If the document does not fit, an error will be returned. + * + * @fyn: The node to emit + * @flags: The emitter flags to use + * @buf: Pointer to the buffer area to fill + * @size: Size of the buffer + * + * Returns: + * A positive number, which is the size of the emitted node + * on the buffer on success, -1 on error + */ +int +fy_emit_node_to_buffer(struct fy_node *fyn, enum fy_emitter_cfg_flags flags, + char *buf, int size) + FY_EXPORT; + +/** + * fy_emit_node_to_string() - Emit a node to an allocated string + * + * Emits a node recursively to a string which will be dynamically + * allocated. + * + * @fyn: The node to emit + * @flags: The emitter flags to use + * + * Returns: + * A pointer to the allocated string, or NULL in case of an error + */ +char * +fy_emit_node_to_string(struct fy_node *fyn, enum fy_emitter_cfg_flags flags) + 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_node_copy() - Copy a node, associating the new node with the given document + * + * Make a deep copy of a node, associating the copy with the given document. + * Note that no content copying takes place as the contents of the nodes + * are reference counted. This means that the operation is relatively inexpensive. + * + * Note that the copy includes all anchors contained in the subtree of the + * source, so this call will register them with the document. + * + * @fyd: The document which the resulting node will be associated with + * @fyn_from: The source node to recursively copy + * + * Returns: + * The copied node on success, NULL on error + */ +struct fy_node * +fy_node_copy(struct fy_document *fyd, struct fy_node *fyn_from) + FY_EXPORT; + +/** + * fy_document_clone() - Clones a document + * + * Clone a document, by making a deep copy of the source. + * Note that no content copying takes place as the contents of the nodes + * are reference counted. This means that the operation is relatively inexpensive. + * + * @fydsrc: The source document to clone + * + * Returns: + * The newly created clone document, or NULL in case of an error + */ +struct fy_document * +fy_document_clone(struct fy_document *fydsrc) + FY_EXPORT; + +/** + * fy_node_insert() - Insert a node to the given node + * + * Insert a node to another node. If @fyn_from is NULL then this + * operation will delete the @fyn_to node. + * + * The operation varies according to the types of the arguments: + * + * from: scalar + * + * to: another-scalar -> scalar + * to: { key: value } -> scalar + * to: [ seq0, seq1 ] -> scalar + * + * from: [ seq2 ] + * to: scalar -> [ seq2 ] + * to: { key: value } -> [ seq2 ] + * to: [ seq0, seq1 ] -> [ seq0, seq1, sec2 ] + * + * from: { another-key: another-value } + * to: scalar -> { another-key: another-value } + * to: { key: value } -> { key: value, another-key: another-value } + * to: [ seq0, seq1 ] -> { another-key: another-value } + * + * from: { key: another-value } + * to: scalar -> { key: another-value } + * to: { key: value } -> { key: another-value } + * to: [ seq0, seq1 ] -> { key: another-value } + * + * The rules are: + * - If target node changes type, source ovewrites target. + * - If source or target node are scalars, source it overwrites target. + * - If target and source are sequences the items of the source sequence + * are appended to the target sequence. + * - If target and source are maps the key, value pairs of the source + * are appended to the target map. If the target map contains a + * key-value pair that is present in the source map, it is overwriten + * by it. + * + * @fyn_to: The target node + * @fyn_from: The source node + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_insert(struct fy_node *fyn_to, struct fy_node *fyn_from) + FY_EXPORT; + +/** + * fy_document_insert_at() - Insert a node to the given path in the document + * + * Insert a node to a given point in the document. If @fyn is NULL then this + * operation will delete the target node. + * + * Please see fy_node_insert for details of operation. + * + * Note that in any case the fyn node will be unref'ed. + * So if the operation fails, and the reference is 0 + * the node will be freed. If you want it to stick around + * take a reference before. + * + * @fyd: The document + * @path: The path where the insert operation will target + * @pathlen: The length of the path (or -1 if '\0' terminated) + * @fyn: The source node + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_document_insert_at(struct fy_document *fyd, + const char *path, size_t pathlen, + struct fy_node *fyn) + FY_EXPORT; + +/** + * enum fy_node_type - Node type + * + * Each node may be one of the following types + * + * @FYNT_SCALAR: Node is a scalar + * @FYNT_SEQUENCE: Node is a sequence + * @FYNT_MAPPING: Node is a mapping + */ +enum fy_node_type { + FYNT_SCALAR, + FYNT_SEQUENCE, + FYNT_MAPPING, +}; + +/** + * enum fy_node_style - Node style + * + * A node may contain a hint of how it should be + * rendered, encoded as a style. + * + * @FYNS_ANY: No hint, let the emitter decide + * @FYNS_FLOW: Prefer flow style (for sequence/mappings) + * @FYNS_BLOCK: Prefer block style (for sequence/mappings) + * @FYNS_PLAIN: Plain style preferred + * @FYNS_SINGLE_QUOTED: Single quoted style preferred + * @FYNS_DOUBLE_QUOTED: Double quoted style preferred + * @FYNS_LITERAL: Literal style preferred (valid in block context) + * @FYNS_FOLDED: Folded style preferred (valid in block context) + * @FYNS_ALIAS: It's an alias + */ +enum fy_node_style { + FYNS_ANY = -1, + FYNS_FLOW, + FYNS_BLOCK, + FYNS_PLAIN, + FYNS_SINGLE_QUOTED, + FYNS_DOUBLE_QUOTED, + FYNS_LITERAL, + FYNS_FOLDED, + FYNS_ALIAS, +}; + +/* maximum depth is 256 */ +#define FYNWF_MAXDEPTH_SHIFT 4 +#define FYNWF_MAXDEPTH_MASK 0xff +#define FYNWF_MAXDEPTH(x) (((x) & FYNWF_MAXDEPTH_MASK) << FYNWF_MAXDEPTH_SHIFT) +#define FYNWF_MARKER_SHIFT 12 +#define FYNWF_MARKER_MASK 0x1f +#define FYNWF_MARKER(x) (((x) & FYNWF_MARKER_MASK) << FYNWF_MARKER_SHIFT) +#define FYNWF_PTR_SHIFT 16 +#define FYNWF_PTR_MASK 0x03 +#define FYNWF_PTR(x) (((x) & FYNWF_PTR_MASK) << FYNWF_PTR_SHIFT) + +/** + * enum fy_node_walk_flags - Node walk flags + * + * @FYNWF_DONT_FOLLOW: Don't follow aliases during pathwalk + * @FYNWF_FOLLOW: Follow aliases during pathwalk + * @FYNWF_PTR_YAML: YAML pointer path walks + * @FYNWF_PTR_JSON: JSON pointer path walks + * @FYNWF_PTR_RELJSON: Relative JSON pointer path walks + * @FYNWF_PTR_YPATH: YPATH pointer path walks + * @FYNWF_URI_ENCODED: The path is URI encoded + * @FYNWF_MAXDEPTH_DEFAULT: Max follow depth is automatically determined + * @FYNWF_MARKER_DEFAULT: Default marker to use when scanning + * @FYNWF_PTR_DEFAULT: Default path type + */ +enum fy_node_walk_flags { + FYNWF_DONT_FOLLOW = 0, + FYNWF_FOLLOW = FY_BIT(0), + FYNWF_PTR_YAML = FYNWF_PTR(0), + FYNWF_PTR_JSON = FYNWF_PTR(1), + FYNWF_PTR_RELJSON = FYNWF_PTR(2), + FYNWF_PTR_YPATH = FYNWF_PTR(3), + FYNWF_URI_ENCODED = FY_BIT(18), + FYNWF_MAXDEPTH_DEFAULT = FYNWF_MAXDEPTH(0), + FYNWF_MARKER_DEFAULT = FYNWF_MARKER(0), + FYNWF_PTR_DEFAULT = FYNWF_PTR(0), +}; + +/* the maximum user marker */ +#define FYNWF_MAX_USER_MARKER 24 + +/** + * fy_node_style_from_scalar_style() - Convert from scalar to node style + * + * Convert a scalar style to a node style. + * + * @sstyle: The input scalar style + * + * Returns: + * The matching node style + */ +static inline enum fy_node_style +fy_node_style_from_scalar_style(enum fy_scalar_style sstyle) +{ + if (sstyle == FYSS_ANY) + return FYNS_ANY; + return (enum fy_node_style)(FYNS_PLAIN + (sstyle - FYSS_PLAIN)); +} + +/** + * typedef fy_node_mapping_sort_fn - Mapping sorting method function + * + * @fynp_a: The first node_pair used in the comparison + * @fynp_b: The second node_pair used in the comparison + * @arg: The opaque user provided pointer to the sort operation + * + * Returns: + * <0 if @fynp_a is less than @fynp_b + * 0 if @fynp_a is equal to fynp_b + * >0 if @fynp_a is greater than @fynp_b + */ +typedef int (*fy_node_mapping_sort_fn)(const struct fy_node_pair *fynp_a, + const struct fy_node_pair *fynp_b, + void *arg); + +/** + * typedef fy_node_scalar_compare_fn - Node compare method function for scalars + * + * @fyn_a: The first scalar node used in the comparison + * @fyn_b: The second scalar node used in the comparison + * @arg: The opaque user provided pointer to the compare operation + * + * Returns: + * <0 if @fyn_a is less than @fyn_b + * 0 if @fyn_a is equal to fyn_b + * >0 if @fyn_a is greater than @fyn_b + */ +typedef int (*fy_node_scalar_compare_fn)(struct fy_node *fyn_a, + struct fy_node *fyn_b, + void *arg); + +/** + * fy_node_compare() - Compare two nodes for equality + * + * Compare two nodes for equality. + * The comparison is 'deep', i.e. it recurses in subnodes, + * and orders the keys of maps using default libc strcmp + * ordering. For scalar the comparison is performed after + * any escaping so it's a true content comparison. + * + * @fyn1: The first node to use in the comparison + * @fyn2: The second node to use in the comparison + * + * Returns: + * true if the nodes contain the same content, false otherwise + */ +bool +fy_node_compare(struct fy_node *fyn1, struct fy_node *fyn2) + FY_EXPORT; + +/** + * fy_node_compare_user() - Compare two nodes for equality using + * user supplied sort and scalar compare methods + * + * Compare two nodes for equality using user supplied sot and scalar + * compare methods. + * The comparison is 'deep', i.e. it recurses in subnodes, + * and orders the keys of maps using the supplied mapping sort method for + * ordering. For scalars the comparison is performed using the supplied + * scalar node compare methods. + * + * @fyn1: The first node to use in the comparison + * @fyn2: The second node to use in the comparison + * @sort_fn: The method to use for sorting maps, or NULL for the default + * @sort_fn_arg: The extra user supplied argument to the @sort_fn + * @cmp_fn: The method to use for comparing scalars, or NULL for the default + * @cmp_fn_arg: The extra user supplied argument to the @cmp_fn + * + * Returns: + * true if the nodes contain the same content, false otherwise + */ +bool +fy_node_compare_user(struct fy_node *fyn1, struct fy_node *fyn2, + fy_node_mapping_sort_fn sort_fn, void *sort_fn_arg, + fy_node_scalar_compare_fn cmp_fn, void *cmp_fn_arg) + FY_EXPORT; + +/** + * fy_node_compare_string() - Compare a node for equality with a YAML string + * + * Compare a node for equality with a YAML string. + * The comparison is performed using fy_node_compare() with the + * first node supplied as an argument and the second being generated + * by calling fy_document_build_from_string with the YAML string. + * + * @fyn: The node to use in the comparison + * @str: The YAML string to compare against + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * true if the node and the string are equal. + */ +bool +fy_node_compare_string(struct fy_node *fyn, const char *str, size_t len) + FY_EXPORT; + +/** + * fy_node_compare_token() - Compare a node for equality against a token + * + * Compare a node for equality with a token. + * Both the node and the tokens must be a scalars. + * + * @fyn: The node to use in the comparison + * @fyt: The scalar token + * + * Returns: + * true if the node and the token are equal. + */ +bool +fy_node_compare_token(struct fy_node *fyn, struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_node_compare_text() - Compare a node for equality with a raw C text + * + * Compare a node for equality with a raw C string. + * The node must be a scalar. + * + * @fyn: The node to use in the comparison + * @text: The raw C text to compare against + * @len: The length of the text (or -1 if '\0' terminated) + * + * Returns: + * true if the node and the text are equal. + */ +bool +fy_node_compare_text(struct fy_node *fyn, const char *text, size_t len) + FY_EXPORT; + +/** + * fy_document_create() - Create an empty document + * + * Create an empty document using the provided parser configuration. + * If NULL use the default parse configuration. + * + * @cfg: The parse configuration to use or NULL for the default. + * + * Returns: + * The created empty document, or NULL on error. + */ +struct fy_document * +fy_document_create(const struct fy_parse_cfg *cfg) + FY_EXPORT; + +/** + * fy_document_destroy() - Destroy a document previously created via + * fy_document_create() + * + * Destroy a document (along with all children documents) + * + * @fyd: The document to destroy + * + */ +void +fy_document_destroy(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_get_cfg() - Get the configuration of a document + * + * @fyd: The document + * + * Returns: + * The configuration of the document + */ +const struct fy_parse_cfg * +fy_document_get_cfg(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_get_diag() - Get the diagnostic object of a document + * + * Return a pointer to the diagnostic object of a document object. + * Note that the returned diag object has a reference taken so + * you should fy_diag_unref() it when you're done with it. + * + * @fyd: The document to get the diagnostic object + * + * Returns: + * A pointer to a ref'ed diagnostic object or NULL in case of an + * error. + */ +struct fy_diag * +fy_document_get_diag(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_set_diag() - Set the diagnostic object of a document + * + * Replace the documents's current diagnostic object with the one + * given as an argument. The previous diagnostic object will be + * unref'ed (and freed if its reference gets to 0). + * Also note that the diag argument shall take a reference too. + * + * @fyd: The document to replace the diagnostic object + * @diag: The document's new diagnostic object, NULL for default + * + * Returns: + * 0 if everything OK, -1 otherwise + */ +int +fy_document_set_diag(struct fy_document *fyd, struct fy_diag *diag) + FY_EXPORT; + +/** + * fy_document_set_parent() - Make a document a child of another + * + * Set the parent of @fyd_child document to be @fyd + * + * @fyd: The parent document + * @fyd_child: The child document + * + * Returns: + * 0 if all OK, -1 on error. + */ +int +fy_document_set_parent(struct fy_document *fyd, struct fy_document *fyd_child) + FY_EXPORT; + +/** + * fy_document_build_from_string() - Create a document using the provided YAML source. + * + * Create a document parsing the provided string as a YAML source. + * + * @cfg: The parse configuration to use or NULL for the default. + * @str: The YAML source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_document_build_from_string(const struct fy_parse_cfg *cfg, + const char *str, size_t len) + FY_EXPORT; + +/** + * fy_document_build_from_malloc_string() - Create a document using the provided YAML source which was malloced. + * + * Create a document parsing the provided string as a YAML source. The string is expected to have been + * allocated by malloc(3) and when the document is destroyed it will be automatically freed. + * + * @cfg: The parse configuration to use or NULL for the default. + * @str: The YAML source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_document_build_from_malloc_string(const struct fy_parse_cfg *cfg, + char *str, size_t len) + FY_EXPORT; +/** + * fy_document_build_from_file() - Create a document parsing the given file + * + * Create a document parsing the provided file as a YAML source. + * + * @cfg: The parse configuration to use or NULL for the default. + * @file: The name of the file to parse + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_document_build_from_file(const struct fy_parse_cfg *cfg, const char *file) + FY_EXPORT; + +/** + * fy_document_build_from_fp() - Create a document parsing the given file pointer + * + * Create a document parsing the provided file pointer as a YAML source. + * + * @cfg: The parse configuration to use or NULL for the default. + * @fp: The file pointer + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_document_build_from_fp(const struct fy_parse_cfg *cfg, FILE *fp) + FY_EXPORT; + +/** + * fy_document_vbuildf() - Create a document using the provided YAML via vprintf formatting + * + * Create a document parsing the provided string as a YAML source. The string + * is created by applying vprintf formatting. + * + * @cfg: The parse configuration to use or NULL for the default. + * @fmt: The format string creating the YAML source to use. + * @ap: The va_list argument pointer + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_document_vbuildf(const struct fy_parse_cfg *cfg, + const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_document_buildf() - Create a document using the provided YAML source via printf formatting + * + * Create a document parsing the provided string as a YAML source. The string + * is created by applying printf formatting. + * + * @cfg: The parse configuration to use or NULL for the default. + * @fmt: The format string creating the YAML source to use. + * @...: The printf arguments + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_document_buildf(const struct fy_parse_cfg *cfg, const char *fmt, ...) + __attribute__((format(printf, 2, 3))) + FY_EXPORT; + +/** + * fy_flow_document_build_from_string() - Create a document using the provided YAML source. + * + * Create a document parsing the provided string as a YAML source. + * + * The document is a flow document, i.e. does not contain any block content + * and is usually laid out in a single line. + * + * Example of flow documents: + * + * plain-scalar + * "double-quoted-scalar" + * 'single-quoted-scalar' + * { foo: bar } + * [ 0, 1, 2 ] + * + * A flow document is important because parsing stops at the end + * of it, and so can be placed in other non-yaml content. + * + * @cfg: The parse configuration to use or NULL for the default. + * @str: The YAML source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * @consumed: A pointer to the consumed amount + * + * Returns: + * The created document, or NULL on error. + */ +struct fy_document * +fy_flow_document_build_from_string(const struct fy_parse_cfg *cfg, + const char *str, size_t len, size_t *consumed) + FY_EXPORT; + +/** + * fy_document_root() - Return the root node of the document + * + * Returns the root of the document. If the document is empty + * NULL will be returned instead. + * + * @fyd: The document + * + * Returns: + * The root of the document, or NULL if the document is empty. + */ +struct fy_node * +fy_document_root(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_set_root() - Set the root of the document + * + * Set the root of a document. If the document was not empty + * the old root will be freed. If @fyn is NULL then the + * document is set to empty. + * + * @fyd: The document + * @fyn: The new root of the document. + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_document_set_root(struct fy_document *fyd, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_type() - Get the node type + * + * Retrieve the node type. It is one of FYNT_SCALAR, FYNT_SEQUENCE + * or FYNT_MAPPING. A NULL node argument is a FYNT_SCALAR. + * + * @fyn: The node + * + * Returns: + * The node type + */ +enum fy_node_type +fy_node_get_type(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_style() - Get the node style + * + * Retrieve the node rendering style. + * If the node is NULL then the style is FYNS_PLAIN. + * + * @fyn: The node + * + * Returns: + * The node style + */ +enum fy_node_style +fy_node_get_style(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_is_scalar() - Check whether the node is a scalar + * + * Convenience method for checking whether a node is a scalar. + * + * @fyn: The node + * + * Returns: + * true if the node is a scalar, false otherwise + */ +static inline bool +fy_node_is_scalar(struct fy_node *fyn) +{ + return fy_node_get_type(fyn) == FYNT_SCALAR; +} + +/** + * fy_node_is_sequence() - Check whether the node is a sequence + * + * Convenience method for checking whether a node is a sequence. + * + * @fyn: The node + * + * Returns: + * true if the node is a sequence, false otherwise + */ +static inline bool +fy_node_is_sequence(struct fy_node *fyn) +{ + return fy_node_get_type(fyn) == FYNT_SEQUENCE; +} + +/** + * fy_node_is_mapping() - Check whether the node is a mapping + * + * Convenience method for checking whether a node is a mapping. + * + * @fyn: The node + * + * Returns: + * true if the node is a mapping, false otherwise + */ +static inline bool +fy_node_is_mapping(struct fy_node *fyn) +{ + return fy_node_get_type(fyn) == FYNT_MAPPING; +} + +/** + * fy_node_is_alias() - Check whether the node is an alias + * + * Convenience method for checking whether a node is an alias. + * + * @fyn: The node + * + * Returns: + * true if the node is an alias, false otherwise + */ +static inline bool +fy_node_is_alias(struct fy_node *fyn) +{ + return fy_node_get_type(fyn) == FYNT_SCALAR && + fy_node_get_style(fyn) == FYNS_ALIAS; +} + +/** + * fy_node_is_null() - Check whether the node is a NULL + * + * Convenience method for checking whether a node is a NULL scalar.. + * Note that a NULL node argument returns true... + * + * @fyn: The node + * + * Returns: + * true if the node is a NULL scalar, false otherwise + */ +bool +fy_node_is_null(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_is_attached() - Check whether the node is attached + * + * Checks whether a node is attached in a document structure. + * An attached node may not be freed, before being detached. + * Note that there is no method that explicitly detaches + * a node, since this is handled internaly by the sequence + * and mapping removal methods. + * + * @fyn: The node + * + * Returns: + * true if the node is attached, false otherwise + */ +bool +fy_node_is_attached(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_tag_token() - Gets the tag token of a node (if it exists) + * + * Gets the tag token of a node, if it exists + * + * @fyn: The node which has the tag token to be returned + * + * Returns: + * The tag token of the given node, or NULL if the tag does not + * exist. + */ +struct fy_token * +fy_node_get_tag_token(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_scalar_token() - Gets the scalar token of a node (if it exists) + * + * Gets the scalar token of a node, if it exists and the node is a valid scalar + * node. Note that aliases are scalars, so if this call is issued on an alias + * node the return shall be of an alias token. + * + * @fyn: The node which has the scalar token to be returned + * + * Returns: + * The scalar token of the given node, or NULL if the node is not a scalar. + */ +struct fy_token * +fy_node_get_scalar_token(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_resolve_alias() - Resolve an alias node + * + * Resolve an alias node, following any subsequent aliases until + * a non alias node has been found. This call performs cycle detection + * and excessive redirections checks so it's safe to call in any + * context. + * + * @fyn: The alias node to be resolved + * + * Returns: + * The resolved alias node, or NULL if either fyn is not an alias, or + * resolution fails due to a graph cycle. + */ +struct fy_node * +fy_node_resolve_alias(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_dereference() - Dereference a single alias node + * + * Dereference an alias node. This is different than resolution + * in that will only perform a single alias follow call and + * it will fail if the input is not an alias. + * This call performs cycle detection + * and excessive redirections checks so it's safe to call in any + * context. + * + * @fyn: The alias node to be dereferenced + * + * Returns: + * The dereferenced alias node, or NULL if either fyn is not an alias, or + * resolution fails due to a graph cycle. + */ +struct fy_node * +fy_node_dereference(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_free() - Free a node + * + * Recursively frees the given node releasing the memory it uses, removing + * any anchors on the document it contains, and releasing references + * on the tokens it contains. + * + * This method will return an error if the node is attached, or + * if not NULL it is not a member of a document. + * + * @fyn: The node to free + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_free(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_build_from_string() - Create a node using the provided YAML source. + * + * Create a node parsing the provided string as a YAML source. The + * node created will be associated with the provided document. + * + * @fyd: The document + * @str: The YAML source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_build_from_string(struct fy_document *fyd, + const char *str, size_t len) + FY_EXPORT; + +/** + * fy_node_build_from_malloc_string() - Create a node using the provided YAML source which was malloced. + * + * Create a node parsing the provided string as a YAML source. The + * node created will be associated with the provided document. The string is expected to have been + * allocated by malloc(3) and when the document is destroyed it will be automatically freed. + * + * @fyd: The document + * @str: The YAML source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_build_from_malloc_string(struct fy_document *fyd, + char *str, size_t len) + FY_EXPORT; + + +/** + * fy_node_build_from_file() - Create a node using the provided YAML file. + * + * Create a node parsing the provided file as a YAML source. The + * node created will be associated with the provided document. + * + * @fyd: The document + * @file: The name of the file to parse + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_build_from_file(struct fy_document *fyd, const char *file) + FY_EXPORT; + +/** + * fy_node_build_from_fp() - Create a node using the provided file pointer. + * + * Create a node parsing the provided file pointer as a YAML source. The + * node created will be associated with the provided document. + * + * @fyd: The document + * @fp: The file pointer + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_build_from_fp(struct fy_document *fyd, FILE *fp) + FY_EXPORT; + +/** + * fy_node_vbuildf() - Create a node using the provided YAML source via vprintf formatting + * + * Create a node parsing the resulting string as a YAML source. The string + * is created by applying vprintf formatting. + * + * @fyd: The document + * @fmt: The format string creating the YAML source to use. + * @ap: The va_list argument pointer + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_vbuildf(struct fy_document *fyd, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_node_buildf() - Create a node using the provided YAML source via printf formatting + * + * Create a node parsing the resulting string as a YAML source. The string + * is created by applying printf formatting. + * + * @fyd: The document + * @fmt: The format string creating the YAML source to use. + * @...: The printf arguments + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_buildf(struct fy_document *fyd, const char *fmt, ...) + __attribute__((format(printf, 2, 3))) + FY_EXPORT; + +/** + * fy_node_by_path() - Retrieve a node using the provided path spec. + * + * This method will retrieve a node relative to the given node using + * the provided path spec. + * + * Path specs are comprised of keys seperated by slashes '/'. + * Keys are either regular YAML expressions in flow format for traversing + * mappings, or indexes in brackets for traversing sequences. + * Path specs may start with '/' which is silently ignored. + * + * A few examples will make this clear + * + * fyn = { foo: bar } - fy_node_by_path(fyn, "/foo") -> bar + * fyn = [ foo, bar ] - fy_node_by_path(fyn, "1") -> bar + * fyn = { { foo: bar }: baz } - fy_node_by_path(fyn, "{foo: bar}") -> baz + * fyn = [ foo, { bar: baz } } - fy_node_by_path(fyn, "1/bar") -> baz + * + * Note that the special characters /{}[] are not escaped in plain style, + * so you will not be able to use them as path traversal keys. + * In that case you can easily use either the single, or double quoted forms: + * + * fyn = { foo/bar: baz } - fy_node_by_path(fyn, "'foo/bar'") -> baz + * + * @fyn: The node to use as start of the traversal operation + * @path: The path spec to use in the traversal operation + * @len: The length of the path (or -1 if '\0' terminated) + * @flags: The extra path walk flags + * + * Returns: + * The retrieved node, or NULL if not possible to be found. + */ +struct fy_node * +fy_node_by_path(struct fy_node *fyn, const char *path, size_t len, + enum fy_node_walk_flags flags) + FY_EXPORT; + +/** + * fy_node_get_path() - Get the path of this node + * + * Retrieve the given node's path address relative to the document root. + * The address is dynamically allocated and should be freed when + * you're done with it. + * + * @fyn: The node + * + * Returns: + * The node's address, or NULL if fyn is the root. + */ +char * +fy_node_get_path(struct fy_node *fyn) + FY_EXPORT; + +#define fy_node_get_path_alloca(_fyn) \ + FY_ALLOCA_COPY_FREE_NO_NULL(fy_node_get_path((_fyn)), FY_NT) + +/** + * fy_node_get_parent() - Get the parent node of a node + * + * Get the parent node of a node. The parent of a document's root + * is NULL, and so is the parent of the root of a key node's of a mapping. + * This is because the nodes of a key may not be addressed using a + * path expression. + * + * @fyn: The node + * + * Returns: + * The node's parent, or NULL if fyn is the root, or the root of a key mapping. + */ +struct fy_node * +fy_node_get_parent(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_document_parent() - Get the document parent node of a node + * + * Get the document parent node of a node. The document parent differs + * than the regular parent in that a key's root node of a mapping is not + * NULL, rather it points to the actual node parent. + * + * @fyn: The node + * + * Returns: + * The node's document parent, or NULL if fyn is the root + */ +struct fy_node * +fy_node_get_document_parent(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_parent_address() - Get the path address of this node's parent + * + * Retrieve the given node's parent path address + * The address is dynamically allocated and should be freed when + * you're done with it. + * + * @fyn: The node + * + * Returns: + * The parent's address, or NULL if fyn is the root. + */ +char * +fy_node_get_parent_address(struct fy_node *fyn) + FY_EXPORT; + +#define fy_node_get_parent_address_alloca(_fyn) \ + FY_ALLOCA_COPY_FREE_NO_NULL(fy_node_get_parent_address((_fyn)), FY_NT) + +/** + * fy_node_get_path_relative_to() - Get a path address of a node + * relative to one of it's parents + * + * Retrieve the given node's path address relative to an arbitrary + * parent in the tree. + * The address is dynamically allocated and should be freed when + * you're done with it. + * + * @fyn_parent: The node parent/grandparent... + * @fyn: The node + * + * Returns: + * The relative address from the parent to the node + */ +char * +fy_node_get_path_relative_to(struct fy_node *fyn_parent, struct fy_node *fyn) + FY_EXPORT; + +#define fy_node_get_path_relative_to_alloca(_fynp, _fyn) \ + FY_ALLOCA_COPY_FREE_NO_NULL(fy_node_get_path_relative_to((_fynp), (_fyn)), FY_NT) + +/** + * fy_node_get_short_path() - Get a path address of a node in the shortest + * path possible + * + * Retrieve the given node's short path address relative to the + * closest anchor (either on this node, or it's parent). + * If no such parent is found then returns the absolute path + * from the start of the document. + * + * --- &foo + * foo: &bar + * bar + * baz + * + * - The short path of /foo is \*foo + * - The short path of /foo/bar is \*bar + * - The short path of /baz is \*foo/baz + * + * The address is dynamically allocated and should be freed when + * you're done with it. + * + * @fyn: The node + * + * Returns: + * The shortest path describing the node + */ +char * +fy_node_get_short_path(struct fy_node *fyn) + FY_EXPORT; + +#define fy_node_get_short_path_alloca(_fyn) \ + FY_ALLOCA_COPY_FREE_NO_NULL(fy_node_get_short_path((_fyn)), FY_NT) + +/** + * fy_node_get_reference() - Get a textual reference to a node + * + * Retrieve the given node's textual reference. If the node + * contains an anchor the expression that references the anchor + * will be returned, otherwise an absolute path reference relative + * to the root of the document will be returned. + * + * The address is dynamically allocated and should be freed when + * you're done with it. + * + * @fyn: The node + * + * Returns: + * The node's text reference. + */ +char * +fy_node_get_reference(struct fy_node *fyn) + FY_EXPORT; + +#define fy_node_get_reference_alloca(_fyn) \ + FY_ALLOCA_COPY_FREE_NO_NULL(fy_node_get_reference((_fyn)), FY_NT) + +/** + * fy_node_create_reference() - Create an alias reference node + * + * Create an alias node reference. If the node + * contains an anchor the expression that references the alias will + * use the anchor, otherwise an absolute path reference relative + * to the root of the document will be created. + * + * @fyn: The node + * + * Returns: + * An alias node referencing the argument node + */ +struct fy_node * +fy_node_create_reference(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_relative_reference() - Get a textual reference to a node + * relative to a base node. + * + * Retrieve the given node's textual reference as generated using + * another parent (or grand parent) as a base. + * If the node contains an anchor the expression that references the anchor + * will be returned. + * If the base node contains an anchor the reference will be relative to it + * otherwise an absolute path reference will be returned. + * + * The address is dynamically allocated and should be freed when + * you're done with it. + * + * @fyn_base: The base node + * @fyn: The node + * + * Returns: + * The node's text reference. + */ +char * +fy_node_get_relative_reference(struct fy_node *fyn_base, struct fy_node *fyn) + FY_EXPORT; + +#define fy_node_get_relative_reference_alloca(_fynb, _fyn) \ + FY_ALLOCA_COPY_FREE_NO_NULL(fy_node_get_relative_reference((_fynb), (_fyn)), FY_NT) + +/** + * fy_node_create_relative_reference() - Create an alias reference node + * + * Create a relative alias node reference using + * another parent (or grand parent) as a base. + * If the node contains an anchor the alias will reference the anchor. + * If the base node contains an anchor the alias will be relative to it + * otherwise an absolute path reference will be created. + * + * @fyn_base: The base node + * @fyn: The node + * + * Returns: + * An alias node referencing the argument node relative to the base + */ +struct fy_node * +fy_node_create_relative_reference(struct fy_node *fyn_base, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_create_scalar() - Create a scalar node. + * + * Create a scalar node using the provided memory area as input. + * The input is expected to be regular utf8 encoded. It may contain + * escaped characters in which case the style of the scalar will be + * set to double quoted. + * + * Note that the data are not copied, merely a reference is taken, so + * it must be available while the node is in use. + * + * @fyd: The document which the resulting node will be associated with + * @data: Pointer to the data area + * @size: Size of the data area, or (size_t)-1 for '\0' terminated data. + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_create_scalar(struct fy_document *fyd, + const char *data, size_t size) + FY_EXPORT; + +/** + * fy_node_create_scalar_copy() - Create a scalar node copying the data. + * + * Create a scalar node using the provided memory area as input. + * The input is expected to be regular utf8 encoded. It may contain + * escaped characters in which case the style of the scalar will be + * set to double quoted. + * + * A copy of the data will be made, so it is safe to free the data + * after the call. + * + * @fyd: The document which the resulting node will be associated with + * @data: Pointer to the data area + * @size: Size of the data area, or (size_t)-1 for '\0' terminated data. + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_create_scalar_copy(struct fy_document *fyd, + const char *data, size_t size) + FY_EXPORT; + +/** + * fy_node_create_vscalarf() - vprintf interface for creating scalars + * + * Create a scalar node using a vprintf interface. + * The input is expected to be regular utf8 encoded. It may contain + * escaped characters in which case the style of the scalar will be + * set to double quoted. + * + * @fyd: The document which the resulting node will be associated with + * @fmt: The printf based format string + * @ap: The va_list containing the arguments + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_create_vscalarf(struct fy_document *fyd, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_node_create_scalarf() - printf interface for creating scalars + * + * Create a scalar node using a printf interface. + * The input is expected to be regular utf8 encoded. It may contain + * escaped characters in which case the style of the scalar will be + * set to double quoted. + * + * @fyd: The document which the resulting node will be associated with + * @fmt: The printf based format string + * @...: The arguments + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_create_scalarf(struct fy_document *fyd, const char *fmt, ...) + FY_EXPORT + __attribute__((format(printf, 2, 3))); + +/** + * fy_node_create_sequence() - Create an empty sequence node. + * + * Create an empty sequence node associated with the given document. + * + * @fyd: The document which the resulting node will be associated with + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_create_sequence(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_node_create_mapping() - Create an empty mapping node. + * + * Create an empty mapping node associated with the given document. + * + * @fyd: The document which the resulting node will be associated with + * + * Returns: + * The created node, or NULL on error. + */ +struct fy_node * +fy_node_create_mapping(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_node_set_tag() - Set the tag of node + * + * Manually set the tag of a node. The tag must be a valid one for + * the document the node belongs to. + * + * Note that the data are not copied, merely a reference is taken, so + * it must be available while the node is in use. + * + * If the node already contains a tag it will be overwriten. + * + * @fyn: The node to set it's tag. + * @data: Pointer to the tag data. + * @len: Size of the tag data, or (size_t)-1 for '\0' terminated. + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_set_tag(struct fy_node *fyn, const char *data, size_t len) + FY_EXPORT; + +/** + * fy_node_get_tag() - Get the tag of the node + * + * This method will return a pointer to the text of a tag + * along with the length of it. Note that this text is *not* + * NULL terminated. + * + * @fyn: The node + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the tag of the node, while @lenp will be assigned the + * length of said tag. + * A NULL will be returned in case of an error. + */ +const char * +fy_node_get_tag(struct fy_node *fyn, size_t *lenp) + FY_EXPORT; + +/** + * fy_node_get_scalar() - Get the scalar content of the node + * + * This method will return a pointer to the text of the scalar + * content of a node along with the length of it. + * Note that this pointer is *not* NULL terminated. + * + * @fyn: The scalar node + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the scalar content of the node, while @lenp will be assigned the + * length of said content. + * A NULL will be returned in case of an error, i.e. the node is not + * a scalar. + */ +const char * +fy_node_get_scalar(struct fy_node *fyn, size_t *lenp) + FY_EXPORT; + +/** + * fy_node_get_scalar0() - Get the scalar content of the node + * + * This method will return a pointer to the text of the scalar + * content of a node as a null terminated string. + * Note that this call will allocate memory to hold the null terminated + * string so if possible use fy_node_get_scalar() + * + * @fyn: The scalar node + * + * Returns: + * A pointer to the scalar content of the node or NULL in returned in case of an error. + */ +const char * +fy_node_get_scalar0(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_scalar_length() - Get the length of the scalar content + * + * This method will return the size of the scalar content of the node. + * If the node is not a scalar it will return 0. + * + * @fyn: The scalar node + * + * Returns: + * The size of the scalar content, or 0 if node is not scalar. + */ +size_t +fy_node_get_scalar_length(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_scalar_utf8_length() - Get the length of the scalar content + * in utf8 characters + * + * This method will return the size of the scalar content of the node in + * utf8 characters. + * If the node is not a scalar it will return 0. + * + * @fyn: The scalar node + * + * Returns: + * The size of the scalar content in utf8 characters, or 0 if node is not scalar. + */ +size_t +fy_node_get_scalar_utf8_length(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_iterate() - Iterate over a sequence node + * + * This method iterates over all the item nodes in the sequence node. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @fyn: The sequence node + * @prevp: The previous sequence iterator + * + * Returns: + * The next node in sequence or NULL at the end of the sequence. + */ +struct fy_node * +fy_node_sequence_iterate(struct fy_node *fyn, void **prevp) + FY_EXPORT; + +/** + * fy_node_sequence_reverse_iterate() - Iterate over a sequence node in reverse + * + * This method iterates in reverse over all the item nodes in the sequence node. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @fyn: The sequence node + * @prevp: The previous sequence iterator + * + * Returns: + * The next node in reverse sequence or NULL at the end of the sequence. + */ +struct fy_node * +fy_node_sequence_reverse_iterate(struct fy_node *fyn, void **prevp) + FY_EXPORT; + +/** + * fy_node_sequence_item_count() - Return the item count of the sequence + * + * Get the item count of the sequence. + * + * @fyn: The sequence node + * + * Returns: + * The count of items in the sequence or -1 in case of an error. + */ +int +fy_node_sequence_item_count(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_is_empty() - Check whether the sequence is empty + * + * Check whether the sequence contains items. + * + * @fyn: The sequence node + * + * Returns: + * true if the node is a sequence containing items, false otherwise + */ +bool +fy_node_sequence_is_empty(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_get_by_index() - Return a sequence item by index + * + * Retrieve a node in the sequence using it's index. If index + * is positive or zero the count is from the start of the sequence, + * while if negative from the end. I.e. -1 returns the last item + * in the sequence. + * + * @fyn: The sequence node + * @index: The index of the node to retrieve. + * - >= 0 counting from the start + * - < 0 counting from the end + * + * Returns: + * The node at the specified index or NULL if no such item exist. + */ +struct fy_node * +fy_node_sequence_get_by_index(struct fy_node *fyn, int index) + FY_EXPORT; + +/** + * fy_node_sequence_append() - Append a node item to a sequence + * + * Append a node item to a sequence. + * + * @fyn_seq: The sequence node + * @fyn: The node item to append + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_sequence_append(struct fy_node *fyn_seq, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_prepend() - Append a node item to a sequence + * + * Prepend a node item to a sequence. + * + * @fyn_seq: The sequence node + * @fyn: The node item to prepend + * + * Returns: + * 0 on success, -1 on error + */ +int fy_node_sequence_prepend(struct fy_node *fyn_seq, struct fy_node *fyn); + +/** + * fy_node_sequence_insert_before() - Insert a node item before another + * + * Insert a node item before another in the sequence. + * + * @fyn_seq: The sequence node + * @fyn_mark: The node item which the node will be inserted before. + * @fyn: The node item to insert in the sequence. + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_sequence_insert_before(struct fy_node *fyn_seq, + struct fy_node *fyn_mark, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_insert_after() - Insert a node item after another + * + * Insert a node item after another in the sequence. + * + * @fyn_seq: The sequence node + * @fyn_mark: The node item which the node will be inserted after. + * @fyn: The node item to insert in the sequence. + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_sequence_insert_after(struct fy_node *fyn_seq, + struct fy_node *fyn_mark, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_remove() - Remove an item from a sequence + * + * Remove a node item from a sequence and return it. + * + * @fyn_seq: The sequence node + * @fyn: The node item to remove from the sequence. + * + * Returns: + * The removed node item fyn, or NULL in case of an error. + */ +struct fy_node * +fy_node_sequence_remove(struct fy_node *fyn_seq, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_mapping_iterate() - Iterate over a mapping node + * + * This method iterates over all the node pairs in the mapping node. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * Note that while a mapping is an unordered collection of key/values + * the order of which they are created is important for presentation + * purposes. + * + * @fyn: The mapping node + * @prevp: The previous sequence iterator + * + * Returns: + * The next node pair in the mapping or NULL at the end of the mapping. + */ +struct fy_node_pair * +fy_node_mapping_iterate(struct fy_node *fyn, void **prevp) + FY_EXPORT; + +/** + * fy_node_mapping_reverse_iterate() - Iterate over a mapping node in reverse + * + * This method iterates in reverse over all the node pairs in the mapping node. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * Note that while a mapping is an unordered collection of key/values + * the order of which they are created is important for presentation + * purposes. + * + * @fyn: The mapping node + * @prevp: The previous sequence iterator + * + * Returns: + * The next node pair in reverse sequence in the mapping or NULL at the end of the mapping. + */ +struct fy_node_pair * +fy_node_mapping_reverse_iterate(struct fy_node *fyn, void **prevp) + FY_EXPORT; + +/** + * fy_node_mapping_item_count() - Return the node pair count of the mapping + * + * Get the count of the node pairs in the mapping. + * + * @fyn: The mapping node + * + * Returns: + * The count of node pairs in the mapping or -1 in case of an error. + */ +int +fy_node_mapping_item_count(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_mapping_is_empty() - Check whether the mapping is empty + * + * Check whether the mapping contains any node pairs. + * + * @fyn: The mapping node + * + * Returns: + * true if the node is a mapping containing node pairs, false otherwise + */ +bool +fy_node_mapping_is_empty(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_mapping_get_by_index() - Return a node pair by index + * + * Retrieve a node pair in the mapping using its index. If index + * is positive or zero the count is from the start of the sequence, + * while if negative from the end. I.e. -1 returns the last node pair + * in the mapping. + * + * @fyn: The mapping node + * @index: The index of the node pair to retrieve. + * - >= 0 counting from the start + * - < 0 counting from the end + * + * Returns: + * The node pair at the specified index or NULL if no such item exist. + */ +struct fy_node_pair * +fy_node_mapping_get_by_index(struct fy_node *fyn, int index) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_pair_by_string() - Lookup a node pair in mapping by string + * + * This method will return the node pair that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using fy_node_compare() + * + * @fyn: The mapping node + * @key: The YAML source to use as key + * @len: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The value matching the given key, or NULL if not found. + */ +struct fy_node_pair * +fy_node_mapping_lookup_pair_by_string(struct fy_node *fyn, + const char *key, size_t len) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_by_string() - Lookup a node value in mapping by string + * + * This method will return the value of node pair that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using fy_node_compare() + * + * @fyn: The mapping node + * @key: The YAML source to use as key + * @len: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The value matching the given key, or NULL if not found. + */ +struct fy_node * +fy_node_mapping_lookup_by_string(struct fy_node *fyn, + const char *key, size_t len) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_value_by_string() - Lookup a node value in mapping by string + * + * This method will return the value of node pair that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using fy_node_compare() + * + * It is synonymous with fy_node_mapping_lookup_by_string(). + * + * @fyn: The mapping node + * @key: The YAML source to use as key + * @len: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The value matching the given key, or NULL if not found. + */ +struct fy_node * +fy_node_mapping_lookup_value_by_string(struct fy_node *fyn, + const char *key, size_t len) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_key_by_string() - Lookup a node key in mapping by string + * + * This method will return the key of node pair that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using fy_node_compare() + * + * @fyn: The mapping node + * @key: The YAML source to use as key + * @len: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The key matching the given key, or NULL if not found. + */ +struct fy_node * +fy_node_mapping_lookup_key_by_string(struct fy_node *fyn, + const char *key, size_t len) + FY_EXPORT; + + +/** + * fy_node_mapping_lookup_pair_by_simple_key() - Lookup a node pair in mapping by simple string + * + * This method will return the node pair that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using by comparing the strings for identity. + * + * @fyn: The mapping node + * @key: The string to use as key + * @len: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The node pair matching the given key, or NULL if not found. + */ +struct fy_node_pair * +fy_node_mapping_lookup_pair_by_simple_key(struct fy_node *fyn, + const char *key, size_t len) + FY_EXPORT; +/** + * fy_node_mapping_lookup_value_by_simple_key() - Lookup a node value in mapping by simple string + * + * This method will return the value of node pair that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using by comparing the strings for identity. + * + * @fyn: The mapping node + * @key: The string to use as key + * @len: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The value matching the given key, or NULL if not found. + */ +struct fy_node * +fy_node_mapping_lookup_value_by_simple_key(struct fy_node *fyn, + const char *key, size_t len) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_pair_by_null_key() - Lookup a node pair in mapping that has a NULL key + * + * This method will return the node pair that has a NULL key. + * Note this method is not using the mapping accelerator + * and arguably NULL keys should not exist. Alas... + * + * @fyn: The mapping node + * + * Returns: + * The node pair with a NULL key, NULL otherwise + */ +struct fy_node_pair * +fy_node_mapping_lookup_pair_by_null_key(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_value_by_null_key() - Lookup a node value with a NULL key. + * + * Return the value of a node pair that has a NULL key. + * + * @fyn: The mapping node + * + * Returns: + * The value matching the null key, NULL otherwise. + * Note that the value may be NULL too, but for that pathological case + * use the node pair method instead. + */ +struct fy_node * +fy_node_mapping_lookup_value_by_null_key(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_scalar_by_simple_key() - Lookup a scalar in mapping by simple string + * + * This method will return the scalar contents that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using by comparing the strings for identity. + * + * @fyn: The mapping node + * @lenp: Pointer to a variable that will hold the returned length + * @key: The string to use as key + * @keylen: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The scalar contents matching the given key, or NULL if not found. + */ +const char * +fy_node_mapping_lookup_scalar_by_simple_key(struct fy_node *fyn, size_t *lenp, + const char *key, size_t keylen) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_scalar0_by_simple_key() - Lookup a scalar in mapping by simple string + * returning a '\0' terminated scalar + * + * This method will return the NUL terminated scalar contents that contains the same key + * from the YAML node created from the @key argument. The comparison of the + * node is using by comparing the strings for identity. + * + * @fyn: The mapping node + * @key: The string to use as key + * @keylen: The length of the key (or -1 if '\0' terminated) + * + * Returns: + * The NUL terminated scalar contents matching the given key, or NULL if not found. + */ +const char * +fy_node_mapping_lookup_scalar0_by_simple_key(struct fy_node *fyn, + const char *key, size_t keylen) + FY_EXPORT; + +/** + * fy_node_mapping_lookup_pair() - Lookup a node pair matching the provided key + * + * This method will return the node pair that matches the provided @fyn_key + * + * @fyn: The mapping node + * @fyn_key: The node to use as key + * + * Returns: + * The node pair matching the given key, or NULL if not found. + */ +struct fy_node_pair * +fy_node_mapping_lookup_pair(struct fy_node *fyn, struct fy_node *fyn_key) + FY_EXPORT; + + +/** + * fy_node_mapping_lookup_value_by_key() - Lookup a node pair's value matching the provided key + * + * This method will return the node pair that matches the provided @fyn_key + * The key may be collection and a content match check is performed recursively + * in order to find the right key. + * + * @fyn: The mapping node + * @fyn_key: The node to use as key + * + * Returns: + * The node value matching the given key, or NULL if not found. + */ +struct fy_node * +fy_node_mapping_lookup_value_by_key(struct fy_node *fyn, struct fy_node *fyn_key); + +/** + * fy_node_mapping_lookup_key_by_key() - Lookup a node pair's key matching the provided key + * + * This method will return the node pair that matches the provided @fyn_key + * The key may be collection and a content match check is performed recursively + * in order to find the right key. + * + * @fyn: The mapping node + * @fyn_key: The node to use as key + * + * Returns: + * The node key matching the given key, or NULL if not found. + */ +struct fy_node * +fy_node_mapping_lookup_key_by_key(struct fy_node *fyn, struct fy_node *fyn_key); + +/** + * fy_node_mapping_get_pair_index() - Return the node pair index in the mapping + * + * This method will return the node pair index in the mapping of the given + * node pair argument. + * + * @fyn: The mapping node + * @fynp: The node pair + * + * Returns: + * The index of the node pair in the mapping or -1 in case of an error. + */ +int +fy_node_mapping_get_pair_index(struct fy_node *fyn, + const struct fy_node_pair *fynp) + FY_EXPORT; + +/** + * fy_node_pair_key() - Return the key of a node pair + * + * This method will return the node pair's key. + * Note that this may be NULL, which is returned also in case + * the node pair argument is NULL, so you should protect against + * such a case. + * + * @fynp: The node pair + * + * Returns: + * The node pair key + */ +struct fy_node * +fy_node_pair_key(struct fy_node_pair *fynp) + FY_EXPORT; + +/** + * fy_node_pair_value() - Return the value of a node pair + * + * This method will return the node pair's value. + * Note that this may be NULL, which is returned also in case + * the node pair argument is NULL, so you should protect against + * such a case. + * + * @fynp: The node pair + * + * Returns: + * The node pair value + */ +struct fy_node * +fy_node_pair_value(struct fy_node_pair *fynp) + FY_EXPORT; + +/** + * fy_node_pair_set_key() - Sets the key of a node pair + * + * This method will set the key part of the node pair. + * It will ovewrite any previous key. + * + * Note that no checks for duplicate keys are going to be + * performed. + * + * @fynp: The node pair + * @fyn: The key node + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_pair_set_key(struct fy_node_pair *fynp, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_pair_set_value() - Sets the value of a node pair + * + * This method will set the value part of the node pair. + * It will ovewrite any previous value. + * + * @fynp: The node pair + * @fyn: The value node + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_pair_set_value(struct fy_node_pair *fynp, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_mapping_append() - Append a node item to a mapping + * + * Append a node pair to a mapping. + * + * @fyn_map: The mapping node + * @fyn_key: The node pair's key + * @fyn_value: The node pair's value + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_mapping_append(struct fy_node *fyn_map, + struct fy_node *fyn_key, struct fy_node *fyn_value) + FY_EXPORT; + +/** + * fy_node_mapping_prepend() - Prepend a node item to a mapping + * + * Prepend a node pair to a mapping. + * + * @fyn_map: The mapping node + * @fyn_key: The node pair's key + * @fyn_value: The node pair's value + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_mapping_prepend(struct fy_node *fyn_map, + struct fy_node *fyn_key, struct fy_node *fyn_value) + FY_EXPORT; + +/** + * fy_node_mapping_remove() - Remove a node pair from a mapping + * + * Remove node pair from a mapping. + * + * @fyn_map: The mapping node + * @fynp: The node pair to remove + * + * Returns: + * 0 on success, -1 on failure. + */ +int +fy_node_mapping_remove(struct fy_node *fyn_map, struct fy_node_pair *fynp) + FY_EXPORT; + +/** + * fy_node_mapping_remove_by_key() - Remove a node pair from a mapping returning the value + * + * Remove node pair from a mapping using the supplied key. + * + * @fyn_map: The mapping node + * @fyn_key: The node pair's key + * + * Returns: + * The value part of removed node pair, or NULL in case of an error. + */ +struct fy_node * +fy_node_mapping_remove_by_key(struct fy_node *fyn_map, struct fy_node *fyn_key) + FY_EXPORT; + +/** + * fy_node_sort() - Recursively sort node + * + * Recursively sort all mappings of the given node, using the given + * comparison method (if NULL use the default one). + * + * @fyn: The node to sort + * @key_cmp: The comparison method + * @arg: An opaque user pointer for the comparison method + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_sort(struct fy_node *fyn, fy_node_mapping_sort_fn key_cmp, void *arg) + FY_EXPORT; + +/** + * fy_node_vscanf() - Retrieve data via vscanf + * + * This method easily retrieves data using a familiar vscanf interface. + * The format string is a regular scanf format string with the following format. + * + * "pathspec %opt pathspec %opt..." + * + * Each pathspec is separated with space from the scanf option + * + * For example: + * fyn = { foo: 3 } -> fy_node_scanf(fyn, "/foo %d", &var) -> var = 3 + * + * + * @fyn: The node to use as a pathspec root + * @fmt: The scanf based format string + * @ap: The va_list containing the arguments + * + * Returns: + * The number of scanned arguments, or -1 on error. + */ +int fy_node_vscanf(struct fy_node *fyn, const char *fmt, va_list ap); + +/** + * fy_node_scanf() - Retrieve data via scanf + * + * This method easily retrieves data using a familiar vscanf interface. + * The format string is a regular scanf format string with the following format. + * + * "pathspec %opt pathspec %opt..." + * + * Each pathspec is separated with space from the scanf option + * + * For example: + * fyn = { foo: 3 } -> fy_node_scanf(fyn, "/foo %d", &var) -> var = 3 + * + * + * @fyn: The node to use as a pathspec root + * @fmt: The scanf based format string + * @...: The arguments + * + * Returns: + * The number of scanned arguments, or -1 on error. + */ +int +fy_node_scanf(struct fy_node *fyn, const char *fmt, ...) + __attribute__((format(scanf, 2, 3))) + FY_EXPORT; + +/** + * fy_document_vscanf() - Retrieve data via vscanf relative to document root + * + * This method easily retrieves data using a familiar vscanf interface. + * The format string is a regular scanf format string with the following format. + * + * "pathspec %opt pathspec %opt..." + * + * Each pathspec is separated with space from the scanf option + * + * For example: + * fyd = { foo: 3 } -> fy_document_scanf(fyd, "/foo %d", &var) -> var = 3 + * + * + * @fyd: The document + * @fmt: The scanf based format string + * @ap: The va_list containing the arguments + * + * Returns: + * The number of scanned arguments, or -1 on error. + */ +int +fy_document_vscanf(struct fy_document *fyd, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_document_scanf() - Retrieve data via scanf relative to document root + * + * This method easily retrieves data using a familiar vscanf interface. + * The format string is a regular scanf format string with the following format. + * + * "pathspec %opt pathspec %opt..." + * + * Each pathspec is separated with space from the scanf option + * + * For example: + * fyn = { foo: 3 } -> fy_node_scanf(fyd, "/foo %d", &var) -> var = 3 + * + * + * @fyd: The document + * @fmt: The scanf based format string + * @...: The arguments + * + * Returns: + * The number of scanned arguments, or -1 on error. + */ +int +fy_document_scanf(struct fy_document *fyd, const char *fmt, ...) + __attribute__((format(scanf, 2, 3))) + FY_EXPORT; + +/** + * fy_document_tag_directive_iterate() - Iterate over a document's tag directives + * + * This method iterates over all the documents tag directives. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @fyd: The document + * @prevp: The previous state of the iterator + * + * Returns: + * The next tag directive token in the document or NULL at the end of them. + */ +struct fy_token * +fy_document_tag_directive_iterate(struct fy_document *fyd, void **prevp) + FY_EXPORT; + +/** + * fy_document_tag_directive_lookup() - Retreive a document's tag directive + * + * Retreives the matching tag directive token of the document matching the handle. + * + * @fyd: The document + * @handle: The handle to look for + * + * Returns: + * The tag directive token with the given handle or NULL if not found + */ +struct fy_token * +fy_document_tag_directive_lookup(struct fy_document *fyd, const char *handle) + FY_EXPORT; + +/** + * fy_tag_directive_token_handle() - Get a tag directive handle + * + * Retreives the tag directives token handle value. Only valid on + * tag directive tokens. + * + * @fyt: The tag directive token + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the tag directive's handle, while @lenp will be assigned the + * length of said handle. + * A NULL will be returned in case of an error. + */ +const char * +fy_tag_directive_token_handle(struct fy_token *fyt, size_t *lenp) + FY_EXPORT; + +/** + * fy_tag_directive_token_prefix() - Get a tag directive prefix + * + * Retreives the tag directives token prefix value. Only valid on + * tag directive tokens. + * + * @fyt: The tag directive token + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the tag directive's prefix, while @lenp will be assigned the + * length of said prefix. + * A NULL will be returned in case of an error. + */ +const char * +fy_tag_directive_token_prefix(struct fy_token *fyt, size_t *lenp) + FY_EXPORT; + +/** + * fy_document_tag_directive_add() - Add a tag directive to a document + * + * Add tag directive to the document. + * + * @fyd: The document + * @handle: The handle of the tag directive + * @prefix: The prefix of the tag directive + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_document_tag_directive_add(struct fy_document *fyd, + const char *handle, const char *prefix) + FY_EXPORT; + +/** + * fy_document_tag_directive_remove() - Remove a tag directive + * + * Remove a tag directive from a document. + * Note that removal is prohibited if any node is still using this tag directive. + * + * @fyd: The document + * @handle: The handle of the tag directive to remove. + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_document_tag_directive_remove(struct fy_document *fyd, const char *handle) + FY_EXPORT; + +/** + * fy_document_lookup_anchor() - Lookup an anchor + * + * Lookup for an anchor having the name provided + * + * @fyd: The document + * @anchor: The anchor to look for + * @len: The length of the anchor (or -1 if '\0' terminated) + * + * Returns: + * The anchor if found, NULL otherwise + */ +struct fy_anchor * +fy_document_lookup_anchor(struct fy_document *fyd, + const char *anchor, size_t len) + FY_EXPORT; + +/** + * fy_document_lookup_anchor_by_token() - Lookup an anchor by token text + * + * Lookup for an anchor having the name provided from the text of the token + * + * @fyd: The document + * @anchor: The token contains the anchor text to look for + * + * Returns: + * The anchor if found, NULL otherwise + */ +struct fy_anchor * +fy_document_lookup_anchor_by_token(struct fy_document *fyd, + struct fy_token *anchor) + FY_EXPORT; + +/** + * fy_document_lookup_anchor_by_node() - Lookup an anchor by node + * + * Lookup for an anchor located in the given node + * + * @fyd: The document + * @fyn: The node + * + * Returns: + * The anchor if found, NULL otherwise + */ +struct fy_anchor * +fy_document_lookup_anchor_by_node(struct fy_document *fyd, + struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_anchor_get_text() - Get the text of an anchor + * + * This method will return a pointer to the text of an anchor + * along with the length of it. Note that this text is *not* + * NULL terminated. + * + * @fya: The anchor + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the text of the anchor, while @lenp will be assigned the + * length of said anchor. + * A NULL will be returned in case of an error. + */ +const char * +fy_anchor_get_text(struct fy_anchor *fya, size_t *lenp) + FY_EXPORT; + +/** + * fy_anchor_node() - Get the node of an anchor + * + * This method returns the node associated with the anchor. + * + * @fya: The anchor + * + * Returns: + * The node of the anchor, or NULL in case of an error. + */ +struct fy_node * +fy_anchor_node(struct fy_anchor *fya) + FY_EXPORT; + +/** + * fy_document_anchor_iterate() - Iterate over a document's anchors + * + * This method iterates over all the documents anchors. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @fyd: The document + * @prevp: The previous state of the iterator + * + * Returns: + * The next anchor in the document or NULL at the end of them. + */ +struct fy_anchor * +fy_document_anchor_iterate(struct fy_document *fyd, void **prevp) + FY_EXPORT; + +/** + * fy_document_set_anchor() - Place an anchor + * + * Places an anchor to the node with the give text name. + * + * Note that the data are not copied, merely a reference is taken, so + * it must be available while the node is in use. + * + * Also not that this method is deprecated; use fy_node_set_anchor() + * instead. + * + * @fyd: The document + * @fyn: The node to set the anchor to + * @text: Pointer to the anchor text + * @len: Size of the anchor text, or (size_t)-1 for '\0' terminated. + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_document_set_anchor(struct fy_document *fyd, struct fy_node *fyn, + const char *text, size_t len) + FY_EXPORT FY_DEPRECATED; + +/** + * fy_node_set_anchor() - Place an anchor to the node + * + * Places an anchor to the node with the give text name. + * + * Note that the data are not copied, merely a reference is taken, so + * it must be available while the node is in use. + * + * This is similar to fy_document_set_anchor() with the document set + * to the document of the @fyn node. + * + * @fyn: The node to set the anchor to + * @text: Pointer to the anchor text + * @len: Size of the anchor text, or (size_t)-1 for '\0' terminated. + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_set_anchor(struct fy_node *fyn, const char *text, size_t len) + FY_EXPORT; + +/** + * fy_node_set_anchor_copy() - Place an anchor to the node copying the text + * + * Places an anchor to the node with the give text name, which + * will be copied, so it's safe to dispose the text after the call. + * + * @fyn: The node to set the anchor to + * @text: Pointer to the anchor text + * @len: Size of the anchor text, or (size_t)-1 for '\0' terminated. + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_set_anchor_copy(struct fy_node *fyn, const char *text, size_t len) + FY_EXPORT; + +/** + * fy_node_set_vanchorf() - Place an anchor to the node using a vprintf interface. + * + * Places an anchor to the node with the give text name as created + * via vprintf'ing the arguments. + * + * @fyn: The node to set the anchor to + * @fmt: Pointer to the anchor format string + * @ap: The argument list. + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_set_vanchorf(struct fy_node *fyn, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_node_set_anchorf() - Place an anchor to the node using a printf interface. + * + * Places an anchor to the node with the give text name as created + * via printf'ing the arguments. + * + * @fyn: The node to set the anchor to + * @fmt: Pointer to the anchor format string + * @...: The extra arguments. + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_set_anchorf(struct fy_node *fyn, const char *fmt, ...) + FY_EXPORT __attribute__((format(printf, 2, 3))); + +/** + * fy_node_remove_anchor() - Remove an anchor + * + * Remove an anchor for the given node (if it exists) + * + * @fyn: The node to remove anchors from + * + * Returns: + * 0 on success, -1 on error. + */ +int +fy_node_remove_anchor(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_anchor() - Get the anchor of a node + * + * Retrieve the anchor of the given node (if it exists) + * + * @fyn: The node + * + * Returns: + * The anchor if there's one at the node, or NULL otherwise + */ +struct fy_anchor * +fy_node_get_anchor(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_nearest_anchor() - Get the nearest anchor of the node + * + * Retrieve the anchor of the nearest parent of the given node or + * the given node if it has one. + * + * @fyn: The node + * + * Returns: + * The nearest anchor if there's one, or NULL otherwise + */ +struct fy_anchor * +fy_node_get_nearest_anchor(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_get_nearest_child_of() - Get the nearest node which is a + * child of the base + * + * Retrieve the nearest node which is a child of fyn_base starting + * at fyn and working upwards. + * + * @fyn_base: The base node + * @fyn: The node to start from + * + * Returns: + * The nearest child of the base if there's one, or NULL otherwise + */ +struct fy_node * +fy_node_get_nearest_child_of(struct fy_node *fyn_base, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_create_alias() - Create an alias node + * + * Create an alias on the given document + * + * Note that the data are not copied, merely a reference is taken, so + * it must be available while the node is in use. + * + * @fyd: The document + * @alias: The alias text + * @len: The length of the alias (or -1 if '\0' terminated) + * + * Returns: + * The created alias node, or NULL in case of an error + */ +struct fy_node * +fy_node_create_alias(struct fy_document *fyd, + const char *alias, size_t len) + FY_EXPORT; + +/** + * fy_node_create_alias_copy() - Create an alias node copying the data + * + * Create an alias on the given document + * + * A copy of the data will be made, so it is safe to free the data + * after the call. + * + * @fyd: The document + * @alias: The alias text + * @len: The length of the alias (or -1 if '\0' terminated) + * + * Returns: + * The created alias node, or NULL in case of an error + */ +struct fy_node * +fy_node_create_alias_copy(struct fy_document *fyd, + const char *alias, size_t len) + FY_EXPORT; + +/** + * fy_node_get_meta() - Get the meta pointer of a node + * + * Return the meta pointer of a node. + * + * @fyn: The node to get meta data from + * + * Returns: + * The stored meta data pointer + */ +void * +fy_node_get_meta(struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_set_meta() - Set the meta pointer of a node + * + * Set the meta pointer of a node. If @meta is NULL + * then clear the meta data. + * + * @fyn: The node to set meta data + * @meta: The meta data pointer + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_set_meta(struct fy_node *fyn, void *meta) + FY_EXPORT; + +/** + * fy_node_clear_meta() - Clear the meta data of a node + * + * Clears the meta data of a node. + * + * @fyn: The node to clear meta data + */ +void +fy_node_clear_meta(struct fy_node *fyn) + FY_EXPORT; + +/** + * typedef fy_node_meta_clear_fn - Meta data clear method + * + * This is the callback called when meta data are cleared. + * + * @fyn: The node which the meta data is being cleared + * @meta: The meta data of the node assigned via fy_node_set_meta() + * @user: The user pointer of fy_document_register_meta() + * + */ +typedef void (*fy_node_meta_clear_fn)(struct fy_node *fyn, void *meta, void *user); + +/** + * fy_document_register_meta() - Register a meta cleanup hook + * + * Register a meta data cleanup hook, to be called when + * the node is freed via a final call to fy_node_free(). + * The hook is active for all nodes belonging to the document. + * + * @fyd: The document which the hook is registered to + * @clear_fn: The clear hook method + * @user: Opaque user provided pointer to the clear method + * + * Returns: + * 0 on success, -1 if another hook is already registered. + */ +int +fy_document_register_meta(struct fy_document *fyd, + fy_node_meta_clear_fn clear_fn, void *user) + FY_EXPORT; + +/** + * fy_document_unregister_meta() - Unregister a meta cleanup hook + * + * Unregister the currently active meta cleanup hook. + * The previous cleanup hook will be called for every node in + * the document. + * + * @fyd: The document to unregister it's meta cleanup hook. + */ +void +fy_document_unregister_meta(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_node_set_marker() - Set a marker of a node + * + * Sets the marker of the given node, while returning + * the previous state of the marker. Note that the + * markers use the same space as the node follow markers. + * + * @fyn: The node + * @marker: The marker to set + * + * Returns: + * The previous value of the marker + */ +bool +fy_node_set_marker(struct fy_node *fyn, unsigned int marker) + FY_EXPORT; + +/** + * fy_node_clear_marker() - Clear a marker of a node + * + * Clears the marker of the given node, while returning + * the previous state of the marker. Note that the + * markers use the same space as the node follow markers. + * + * @fyn: The node + * @marker: The marker to clear + * + * Returns: + * The previous value of the marker + */ +bool +fy_node_clear_marker(struct fy_node *fyn, unsigned int marker) + FY_EXPORT; + +/** + * fy_node_is_marker_set() - Checks whether a marker is set + * + * Check the state of the given marker. + * + * @fyn: The node + * @marker: The marker index (must be less that FYNWF_MAX_USER_MARKER) + * + * Returns: + * The value of the marker (invalid markers return false) + */ +bool +fy_node_is_marker_set(struct fy_node *fyn, unsigned int marker) + FY_EXPORT; + +/** + * fy_node_vreport() - Report about a node vprintf style + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. + * + * @fyn: The node + * @type: The error type + * @fmt: The printf format string + * @ap: The argument list + */ +void +fy_node_vreport(struct fy_node *fyn, enum fy_error_type type, + const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_node_report() - Report about a node printf style + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. + * + * @fyn: The node + * @type: The error type + * @fmt: The printf format string + * @...: The extra arguments. + */ +void +fy_node_report(struct fy_node *fyn, enum fy_error_type type, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))) + FY_EXPORT; + +/** + * fy_node_override_vreport() - Report about a node vprintf style, + * overriding file, line and column info + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. This method will use the overrides provided in order + * to massage the reporting information. + * If @file is NULL, no file location will be reported. + * If either @line or @column is negative no location will be reported. + * + * @fyn: The node + * @type: The error type + * @file: The file override + * @line: The line override + * @column: The column override + * @fmt: The printf format string + * @ap: The argument list + */ +void +fy_node_override_vreport(struct fy_node *fyn, enum fy_error_type type, + const char *file, int line, int column, + const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_node_override_report() - Report about a node printf style, + * overriding file, line and column info + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. This method will use the overrides provided in order + * to massage the reporting information. + * If @file is NULL, no file location will be reported. + * If either @line or @column is negative no location will be reported. + * + * @fyn: The node + * @type: The error type + * @file: The file override + * @line: The line override + * @column: The column override + * @fmt: The printf format string + * @...: The extra arguments. + */ +void +fy_node_override_report(struct fy_node *fyn, enum fy_error_type type, + const char *file, int line, int column, + const char *fmt, ...) + __attribute__((format(printf, 6, 7))) + FY_EXPORT; + +typedef void (*fy_diag_output_fn)(struct fy_diag *diag, void *user, + const char *buf, size_t len); + +/** + * struct fy_diag_cfg - The diagnostics configuration + * + * @fp: File descriptor of the error output + * @output_fn: Callback to use when fp is NULL + * @user: User pointer to pass to the output_fn + * @level: The minimum debugging level + * @module_mask: A bitmask of the enabled modules + * @colorize: true if output should be colorized using ANSI sequences + * @show_source: true if source location should be displayed + * @show_position: true if position should be displayed + * @show_type: true if the type should be displayed + * @show_module: true if the module should be displayed + * @source_width: Width of the source field + * @position_width: Width of the position field + * @type_width: Width of the type field + * @module_width: Width of the module field + * + * This structure contains the configuration of the + * diagnostic object. + */ +struct fy_diag_cfg { + FILE *fp; + fy_diag_output_fn output_fn; + void *user; + enum fy_error_type level; + unsigned int module_mask; + bool colorize : 1; + bool show_source : 1; + bool show_position : 1; + bool show_type : 1; + bool show_module : 1; + int source_width; + int position_width; + int type_width; + int module_width; +}; + +/** + * fy_diag_create() - Create a diagnostic object + * + * Creates a diagnostic object using the provided configuration. + * + * @cfg: The configuration for the diagnostic object (NULL is default) + * + * Returns: + * A pointer to the diagnostic object or NULL in case of an error. + */ +struct fy_diag * +fy_diag_create(const struct fy_diag_cfg *cfg) + FY_EXPORT; + +/** + * fy_diag_destroy() - Destroy a diagnostic object + * + * Destroy a diagnostic object; note that the actual + * destruction only occurs when no more references to the + * object are present. However no output will be generated + * after this call. + * + * @diag: The diagnostic object to destroy + */ +void +fy_diag_destroy(struct fy_diag *diag) + FY_EXPORT; + +/** + * fy_diag_get_cfg() - Get a diagnostic object's configuration + * + * Return the current configuration of a diagnostic object + * + * @diag: The diagnostic object + * + * Returns: + * A const pointer to the diagnostic object configuration, or NULL + * in case where diag is NULL + */ +const struct fy_diag_cfg * +fy_diag_get_cfg(struct fy_diag *diag) + FY_EXPORT; + +/** + * fy_diag_set_cfg() - Set a diagnostic object's configuration + * + * Replace the current diagnostic configuration with the given + * configuration passed as an argument. + * + * @diag: The diagnostic object + * @cfg: The diagnostic configuration + */ +void +fy_diag_set_cfg(struct fy_diag *diag, const struct fy_diag_cfg *cfg) + FY_EXPORT; + +/** + * fy_diag_set_level() - Set a diagnostic object's debug error level + * + * @diag: The diagnostic object + * @level: The debugging level to set + */ +void +fy_diag_set_level(struct fy_diag *diag, enum fy_error_type level); + +/** + * fy_diag_set_colorize() - Set a diagnostic object's colorize option + * + * @diag: The diagnostic object + * @colorize: The colorize option + */ +void +fy_diag_set_colorize(struct fy_diag *diag, bool colorize); + +/** + * fy_diag_ref() - Increment that reference counter of a diagnostic object + * + * Increment the reference. + * + * @diag: The diagnostic object to reference + * + * Returns: + * Always returns the @diag argument + */ +struct fy_diag * +fy_diag_ref(struct fy_diag *diag) + FY_EXPORT; + +/** + * fy_diag_unref() - Take away a ref from a diagnostic object + * + * Take away a reference, if it gets to 0, the diagnostic object + * is freed. + * + * @diag: The diagnostic object to unref + */ +void +fy_diag_unref(struct fy_diag *diag) + FY_EXPORT; + +/** + * fy_diag_got_error() - Test whether an error level diagnostic + * has been produced + * + * Tests whether an error diagnostic has been produced. + * + * @diag: The diagnostic object + * + * Returns: + * true if an error has been produced, false otherwise + */ +bool +fy_diag_got_error(struct fy_diag *diag) + FY_EXPORT; + +/** + * 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; + +/** + * fy_diag_cfg_default() - Fill in the configuration structure + * with defaults + * + * Fills the configuration structure with defaults. The default + * always associates the file descriptor to stderr. + * + * @cfg: The diagnostic configuration structure + */ +void +fy_diag_cfg_default(struct fy_diag_cfg *cfg) + FY_EXPORT; + +/** + * fy_diag_cfg_from_parser_flags() - Fill partial diagnostic config + * structure from parser config flags + * + * Fills in part of the configuration structure using parser flags. + * Since the parser flags do not contain debugging flags anymore this + * method is deprecated. + * + * @cfg: The diagnostic configuration structure + * @pflags: The parser flags + */ +void +fy_diag_cfg_from_parser_flags(struct fy_diag_cfg *cfg, + enum fy_parse_cfg_flags pflags) + FY_EXPORT FY_DEPRECATED; + +/** + * fy_diag_vprintf() - vprintf raw interface to diagnostics + * + * Raw output to the diagnostic object using a standard + * vprintf interface. Note that this is the lowest level + * interface, and as such is not recommended for use, since + * no formatting or coloring will take place. + * + * @diag: The diagnostic object to use + * @fmt: The vprintf format string + * @ap: The arguments + * + * Returns: + * The number of characters output, or -1 in case of an error + * Note that 0 shall be returned if the diagnostic object has + * been destroyed but not yet freed. + */ +int +fy_diag_vprintf(struct fy_diag *diag, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_diag_printf() - printf raw interface to diagnostics + * + * Raw output to the diagnostic object using a standard + * printf interface. Note that this is the lowest level + * interface, and as such is not recommended for use, since + * no formatting or coloring will take place. + * + * @diag: The diagnostic object to use + * @fmt: The printf format string + * @...: The arguments + * + * Returns: + * The number of characters output, or -1 in case of an error + * Note that 0 shall be returned if the diagnostic object has + * been destroyed but not yet freed. + */ +int +fy_diag_printf(struct fy_diag *diag, const char *fmt, ...) + FY_EXPORT + __attribute__((format(printf, 2, 3))); + +/** + * struct fy_diag_ctx - The diagnostics context + * + * @level: The level of the diagnostic + * @module: The module of the diagnostic + * @source_func: The source function + * @source_file: The source file + * @source_line: The source line + * @file: The file that caused the error + * @line: The line where the diagnostic occured + * @column: The column where the diagnostic occured + * + * This structure contains the diagnostic context + */ +struct fy_diag_ctx { + enum fy_error_type level; + enum fy_error_module module; + const char *source_func; + const char *source_file; + int source_line; + const char *file; + int line; + int column; +}; + +/** + * fy_vdiag() - context aware diagnostic output like vprintf + * + * Context aware output to the diagnostic object using a standard + * vprintf interface. + * + * @diag: The diagnostic object to use + * @fydc: The diagnostic context + * @fmt: The vprintf format string + * @ap: The arguments + * + * Returns: + * The number of characters output, or -1 in case of an error + * Note that 0 shall be returned if the diagnostic object has + * been destroyed but not yet freed. + */ +int +fy_vdiag(struct fy_diag *diag, const struct fy_diag_ctx *fydc, + const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_diagf() - context aware diagnostic output like printf + * + * Context aware output to the diagnostic object using a standard + * printf interface. + * + * @diag: The diagnostic object to use + * @fydc: The diagnostic context + * @fmt: The vprintf format string + * + * Returns: + * The number of characters output, or -1 in case of an error + * Note that 0 shall be returned if the diagnostic object has + * been destroyed but not yet freed. + */ +int +fy_diagf(struct fy_diag *diag, const struct fy_diag_ctx *fydc, + const char *fmt, ...) + FY_EXPORT + __attribute__((format(printf, 3, 4))); + +#define fy_diag_diag(_diag, _level, _fmt, ...) \ + ({ \ + struct fy_diag_ctx _ctx = { \ + .level = (_level), \ + .module = FYEM_UNKNOWN, \ + .source_func = __func__, \ + .source_file = __FILE__, \ + .source_line = __LINE__, \ + .file = NULL, \ + .line = 0, \ + .column = 0, \ + }; \ + fy_diagf((_diag), &_ctx, (_fmt) , ## __VA_ARGS__); \ + }) + +#ifndef NDEBUG + +#define fy_debug(_diag, _fmt, ...) \ + fy_diag_diag((_diag), FYET_DEBUG, (_fmt) , ## __VA_ARGS__) +#else + +#define fy_debug(_diag, _fmt, ...) \ + do { } while(0) + +#endif + +#define fy_info(_diag, _fmt, ...) \ + fy_diag_diag((_diag), FYET_INFO, (_fmt) , ## __VA_ARGS__) +#define fy_notice(_diag, _fmt, ...) \ + fy_diag_diag((_diag), FYET_NOTICE, (_fmt) , ## __VA_ARGS__) +#define fy_warning(_diag, _fmt, ...) \ + fy_diag_diag((_diag), FYET_WARNING, (_fmt) , ## __VA_ARGS__) +#define fy_error(_diag, _fmt, ...) \ + fy_diag_diag((_diag), FYET_ERROR, (_fmt) , ## __VA_ARGS__) + +/** + * fy_diag_node_vreport() - Report about a node vprintf style using + * the given diagnostic object + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. + * + * @diag: The diag object + * @fyn: The node + * @type: The error type + * @fmt: The printf format string + * @ap: The argument list + */ +void +fy_diag_node_vreport(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_diag_node_report() - Report about a node printf style using + * the given diagnostic object + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. + * + * @diag: The diag object + * @fyn: The node + * @type: The error type + * @fmt: The printf format string + * @...: The extra arguments. + */ +void +fy_diag_node_report(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *fmt, ...) + __attribute__((format(printf, 4, 5))) + FY_EXPORT; + +/** + * fy_diag_node_override_vreport() - Report about a node vprintf style, + * overriding file, line and column info using + * the given diagnostic object + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. This method will use the overrides provided in order + * to massage the reporting information. + * If @file is NULL, no file location will be reported. + * If either @line or @column is negative no location will be reported. + * + * @diag: The diag object + * @fyn: The node + * @type: The error type + * @file: The file override + * @line: The line override + * @column: The column override + * @fmt: The printf format string + * @ap: The argument list + */ +void +fy_diag_node_override_vreport(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *file, + int line, int column, const char *fmt, va_list ap) + FY_EXPORT; + +/** + * fy_diag_node_override_report() - Report about a node printf style, + * overriding file, line and column info using + * the given diagnostic object + * + * Output a report about the given node via the specific + * error type, and using the reporting configuration of the node's + * document. This method will use the overrides provided in order + * to massage the reporting information. + * If @file is NULL, no file location will be reported. + * If either @line or @column is negative no location will be reported. + * + * @diag: The diag object + * @fyn: The node + * @type: The error type + * @file: The file override + * @line: The line override + * @column: The column override + * @fmt: The printf format string + * @...: The extra arguments. + */ +void +fy_diag_node_override_report(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *file, + int line, int column, const char *fmt, ...) + __attribute__((format(printf, 7, 8))) + FY_EXPORT; + +/** + * enum fy_path_parse_cfg_flags - Path parse configuration flags + * + * These flags control the operation of the path parse + * + * @FYPPCF_QUIET: Quiet, do not output any information messages + * @FYPPCF_DISABLE_RECYCLING: Disable recycling optimization + * @FYPPCF_DISABLE_ACCELERATORS: Disable use of access accelerators (saves memory) + */ +enum fy_path_parse_cfg_flags { + FYPPCF_QUIET = FY_BIT(0), + FYPPCF_DISABLE_RECYCLING = FY_BIT(1), + FYPPCF_DISABLE_ACCELERATORS = FY_BIT(2), +}; + +/** + * struct fy_path_parse_cfg - path parser configuration structure. + * + * Argument to the fy_path_parser_create() method which + * performs parsing of a ypath expression + * + * @flags: Configuration flags + * @userdata: Opaque user data pointer + * @diag: Optional diagnostic interface to use + */ +struct fy_path_parse_cfg { + enum fy_path_parse_cfg_flags flags; + void *userdata; + struct fy_diag *diag; +}; + +/** + * fy_path_parser_create() - Create a ypath parser. + * + * Creates a path parser with its configuration @cfg + * The path parser may be destroyed by a corresponding call to + * fy_path_parser_destroy(). + * + * @cfg: The configuration for the path parser + * + * Returns: + * A pointer to the path parser or NULL in case of an error. + */ +struct fy_path_parser * +fy_path_parser_create(const struct fy_path_parse_cfg *cfg) + FY_EXPORT; + +/** + * fy_path_parser_destroy() - Destroy the given path parser + * + * Destroy a path parser created earlier via fy_path_parser_create(). + * + * @fypp: The path parser to destroy + */ +void +fy_path_parser_destroy(struct fy_path_parser *fypp) + FY_EXPORT; + +/** + * fy_path_parser_reset() - Reset a path parser completely + * + * Completely reset a path parser, including after an error + * that caused a parser error to be emitted. + * + * @fypp: The path parser to reset + * + * Returns: + * 0 if the reset was successful, -1 otherwise + */ +int +fy_path_parser_reset(struct fy_path_parser *fypp) + FY_EXPORT; + +/** + * fy_path_parse_expr_from_string() - Parse an expression from a given string + * + * Create a path expression from a string using the provided path parser. + * + * @fypp: The path parser to use + * @str: The ypath source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * The created path expression or NULL on error. + */ +struct fy_path_expr * +fy_path_parse_expr_from_string(struct fy_path_parser *fypp, + const char *str, size_t len) + FY_EXPORT; + +/** + * fy_path_expr_build_from_string() - Parse an expression from a given string + * + * Create a path expression from a string using the provided path parser + * configuration. + * + * @pcfg: The path parser configuration to use, or NULL for default + * @str: The ypath source to use. + * @len: The length of the string (or -1 if '\0' terminated) + * + * Returns: + * The created path expression or NULL on error. + */ +struct fy_path_expr * +fy_path_expr_build_from_string(const struct fy_path_parse_cfg *pcfg, + const char *str, size_t len); + +/** + * fy_path_expr_free() - Free a path expression + * + * Free a previously returned expression from any of the path parser + * methods like fy_path_expr_build_from_string() + * + * @expr: The expression to free (may be NULL) + */ +void +fy_path_expr_free(struct fy_path_expr *expr) + FY_EXPORT; + +/** + * fy_path_expr_dump() - Dump the contents of a path expression to + * the diagnostic object + * + * Dumps the expression using the provided error level. + * + * @expr: The expression to dump + * @diag: The diagnostic object to use + * @errlevel: The error level which the diagnostic will use + * @level: The nest level; should be set to 0 + * @banner: The banner to display on level 0 + */ +void +fy_path_expr_dump(struct fy_path_expr *expr, struct fy_diag *diag, + enum fy_error_type errlevel, int level, const char *banner); + +/** + * fy_path_expr_to_document() - Converts the path expression to a YAML document + * + * Converts the expression to a YAML document which is useful for + * understanding what the expression evaluates to. + * + * @expr: The expression to convert to a document + * + * Returns: + * The document of the expression or NULL on error. + */ +struct fy_document * +fy_path_expr_to_document(struct fy_path_expr *expr) + FY_EXPORT; + +/** + * enum fy_path_exec_cfg_flags - Path executor configuration flags + * + * These flags control the operation of the path expression executor + * + * @FYPXCF_QUIET: Quiet, do not output any information messages + * @FYPXCF_DISABLE_RECYCLING: Disable recycling optimization + * @FYPXCF_DISABLE_ACCELERATORS: Disable use of access accelerators (saves memory) + */ +enum fy_path_exec_cfg_flags { + FYPXCF_QUIET = FY_BIT(0), + FYPXCF_DISABLE_RECYCLING = FY_BIT(1), + FYPXCF_DISABLE_ACCELERATORS = FY_BIT(2), +}; + +/** + * struct fy_path_exec_cfg - path expression executor configuration structure. + * + * Argument to the fy_path_exec_create() method which + * performs execution of a ypath expression + * + * @flags: Configuration flags + * @userdata: Opaque user data pointer + * @diag: Optional diagnostic interface to use + */ +struct fy_path_exec_cfg { + enum fy_path_exec_cfg_flags flags; + void *userdata; + struct fy_diag *diag; +}; + +/** + * fy_path_exec_create() - Create a ypath expression executor. + * + * Creates a ypath expression parser with its configuration @cfg + * The executor may be destroyed by a corresponding call to + * fy_path_exec_destroy(). + * + * @xcfg: The configuration for the executor + * + * Returns: + * A pointer to the executor or NULL in case of an error. + */ +struct fy_path_exec * +fy_path_exec_create(const struct fy_path_exec_cfg *xcfg) + FY_EXPORT; + +/** + * fy_path_exec_destroy() - Destroy the given path expression executor + * + * Destroy ane executor created earlier via fy_path_exec_create(). + * + * @fypx: The path parser to destroy + */ +void +fy_path_exec_destroy(struct fy_path_exec *fypx) + FY_EXPORT; + +/** + * fy_path_exec_reset() - Reset an executor + * + * Completely reset an executor without releasing it. + * + * @fypx: The executor to reset + * + * Returns: + * 0 if the reset was successful, -1 otherwise + */ +int +fy_path_exec_reset(struct fy_path_exec *fypx) + FY_EXPORT; + +/** + * fy_path_exec_execute() - Execute a path expression starting at + * the given start node + * + * Execute the expression starting at fyn_start. If execution + * is successful the results are available via fy_path_exec_results_iterate() + * + * Note that it is illegal to modify the state of the document that the + * results reside between this call and the results collection. + * + * @fypx: The executor to use + * @expr: The expression to use + * @fyn_start: The node on which the expression will begin. + * + * Returns: + * 0 if the execution was successful, -1 otherwise + * + * Note that the execution may be successful but no results were + * produced, in which case the iterator will return NULL. + */ +int +fy_path_exec_execute(struct fy_path_exec *fypx, struct fy_path_expr *expr, + struct fy_node *fyn_start) + FY_EXPORT; + +/** + * fy_path_exec_results_iterate() - Iterate over the results of execution + * + * This method iterates over all the results in the executor. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @fypx: The executor + * @prevp: The previous result iterator + * + * Returns: + * The next node in the result set or NULL at the end of the results. + */ +struct fy_node * +fy_path_exec_results_iterate(struct fy_path_exec *fypx, void **prevp) + FY_EXPORT; + +/* + * Helper methods for binding implementers + * Note that users of the library do not need to know these details. + * However bindings that were developed against libyaml expect these + * to be exported, so provide a shim here + */ + +/** + * enum fy_token_type - Token types + * + * The available token types that the tokenizer produces. + * + * @FYTT_NONE: No token + * @FYTT_STREAM_START: Stream start + * @FYTT_STREAM_END: Stream end + * @FYTT_VERSION_DIRECTIVE: Version directive + * @FYTT_TAG_DIRECTIVE: Tag directive + * @FYTT_DOCUMENT_START: Document start + * @FYTT_DOCUMENT_END: Document end + * @FYTT_BLOCK_SEQUENCE_START: Start of a block sequence + * @FYTT_BLOCK_MAPPING_START: Start of a block mapping + * @FYTT_BLOCK_END: End of a block mapping or a sequence + * @FYTT_FLOW_SEQUENCE_START: Start of a flow sequence + * @FYTT_FLOW_SEQUENCE_END: End of a flow sequence + * @FYTT_FLOW_MAPPING_START: Start of a flow mapping + * @FYTT_FLOW_MAPPING_END: End of a flow mapping + * @FYTT_BLOCK_ENTRY: A block entry + * @FYTT_FLOW_ENTRY: A flow entry + * @FYTT_KEY: A key of a mapping + * @FYTT_VALUE: A value of a mapping + * @FYTT_ALIAS: An alias + * @FYTT_ANCHOR: An anchor + * @FYTT_TAG: A tag + * @FYTT_SCALAR: A scalar + * @FYTT_INPUT_MARKER: Internal input marker token + * @FYTT_PE_SLASH: A slash + * @FYTT_PE_ROOT: A root + * @FYTT_PE_THIS: A this + * @FYTT_PE_PARENT: A parent + * @FYTT_PE_MAP_KEY: A map key + * @FYTT_PE_SEQ_INDEX: A sequence index + * @FYTT_PE_SEQ_SLICE: A sequence slice + * @FYTT_PE_SCALAR_FILTER: A scalar filter + * @FYTT_PE_COLLECTION_FILTER: A collection filter + * @FYTT_PE_SEQ_FILTER: A sequence filter + * @FYTT_PE_MAP_FILTER: A mapping filter + * @FYTT_PE_UNIQUE_FILTER: Filters out duplicates + * @FYTT_PE_EVERY_CHILD: Every child + * @FYTT_PE_EVERY_CHILD_R: Every child recursive + * @FYTT_PE_ALIAS: An alias + * @FYTT_PE_SIBLING: A sibling marker + * @FYTT_PE_COMMA: A comma + * @FYTT_PE_BARBAR: A || + * @FYTT_PE_AMPAMP: A && + * @FYTT_PE_LPAREN: A left parenthesis + * @FYTT_PE_RPAREN: A right parenthesis + * @FYTT_PE_EQEQ: Equality operator + * @FYTT_PE_NOTEQ: Non-equality operator + * @FYTT_PE_LT: Less than operator + * @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_PE_METHOD: Path expression method (chained) + * @FYTT_SE_METHOD: Scalar expression method (non chained) + */ +enum fy_token_type { + /* non-content token types */ + FYTT_NONE, + FYTT_STREAM_START, + FYTT_STREAM_END, + FYTT_VERSION_DIRECTIVE, + FYTT_TAG_DIRECTIVE, + FYTT_DOCUMENT_START, + FYTT_DOCUMENT_END, + /* content token types */ + FYTT_BLOCK_SEQUENCE_START, + FYTT_BLOCK_MAPPING_START, + FYTT_BLOCK_END, + FYTT_FLOW_SEQUENCE_START, + FYTT_FLOW_SEQUENCE_END, + FYTT_FLOW_MAPPING_START, + FYTT_FLOW_MAPPING_END, + FYTT_BLOCK_ENTRY, + FYTT_FLOW_ENTRY, + FYTT_KEY, + FYTT_VALUE, + FYTT_ALIAS, + FYTT_ANCHOR, + FYTT_TAG, + FYTT_SCALAR, + + /* special error reporting */ + FYTT_INPUT_MARKER, + + /* path expression tokens */ + FYTT_PE_SLASH, + FYTT_PE_ROOT, + FYTT_PE_THIS, + FYTT_PE_PARENT, + FYTT_PE_MAP_KEY, + FYTT_PE_SEQ_INDEX, + FYTT_PE_SEQ_SLICE, + FYTT_PE_SCALAR_FILTER, + FYTT_PE_COLLECTION_FILTER, + FYTT_PE_SEQ_FILTER, + FYTT_PE_MAP_FILTER, + FYTT_PE_UNIQUE_FILTER, + FYTT_PE_EVERY_CHILD, + FYTT_PE_EVERY_CHILD_R, + FYTT_PE_ALIAS, + FYTT_PE_SIBLING, + FYTT_PE_COMMA, + FYTT_PE_BARBAR, + FYTT_PE_AMPAMP, + FYTT_PE_LPAREN, + FYTT_PE_RPAREN, + + /* comparison operators */ + FYTT_PE_EQEQ, /* == */ + FYTT_PE_NOTEQ, /* != */ + FYTT_PE_LT, /* < */ + FYTT_PE_GT, /* > */ + FYTT_PE_LTE, /* <= */ + FYTT_PE_GTE, /* >= */ + + /* scalar expression tokens */ + FYTT_SE_PLUS, + FYTT_SE_MINUS, + FYTT_SE_MULT, + FYTT_SE_DIV, + + FYTT_PE_METHOD, /* path expr method (chained) */ + FYTT_SE_METHOD, /* scalar expr method (non chained) */ +}; + +/* The number of token types available */ +#define FYTT_COUNT (FYTT_SE_METHOD+1) + +/** + * fy_token_type_is_valid() - Check token type validity + * + * Check if argument token type is a valid one. + * + * @type: The token type + * + * Returns: + * true if the token type is valid, false otherwise + */ +static inline bool +fy_token_type_is_valid(enum fy_token_type type) +{ + return type >= FYTT_NONE && type < FYTT_COUNT; +} + +/** + * fy_token_type_is_yaml() - Check if token type is valid for YAML + * + * Check if argument token type is a valid YAML one. + * + * @type: The token type + * + * Returns: + * true if the token type is a valid YAML one, false otherwise + */ +static inline bool +fy_token_type_is_yaml(enum fy_token_type type) +{ + return type >= FYTT_STREAM_START && type <= FYTT_SCALAR; +} + +/** + * fy_token_type_is_content() - Check if token type is + * valid for YAML content + * + * Check if argument token type is a valid YAML content one. + * + * @type: The token type + * + * Returns: + * true if the token type is a valid YAML content one, false otherwise + */ +static inline bool +fy_token_type_is_content(enum fy_token_type type) +{ + return type >= FYTT_BLOCK_SEQUENCE_START && type <= FYTT_SCALAR; +} + +/** + * fy_token_type_is_path_expr() - Check if token type is + * valid for a YPATH expression + * + * Check if argument token type is a valid YPATH parse expression token + * + * @type: The token type + * + * Returns: + * true if the token type is a valid YPATH one, false otherwise + */ +static inline bool +fy_token_type_is_path_expr(enum fy_token_type type) +{ + return type >= FYTT_PE_SLASH && type <= FYTT_PE_GTE; +} + +/** + * fy_token_type_is_scalar_expr() - Check if token type is + * valid for a YPATH scalar expression + * + * Check if argument token type is a valid YPATH parse scalar expression token + * + * @type: The token type + * + * Returns: + * true if the token type is a valid YPATH scalar one, false otherwise + */ +static inline bool +fy_token_type_is_scalar_expr(enum fy_token_type type) +{ + return type >= FYTT_SE_PLUS && type <= FYTT_SE_DIV; +} + +/** + * fy_token_get_type() - Return the token's type + * + * Return the token's type; if NULL then FYTT_NONE is returned + * + * @fyt: The token + * + * Returns: + * The token's type; FYTT_NONE if not a valid token (or NULL) + */ +enum fy_token_type +fy_token_get_type(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_token_start_mark() - Get token's start marker + * + * Return the token's start marker if it exists. Note + * it is permissable for some token types to have no + * start marker because they are without content. + * + * @fyt: The token to get its start marker + * + * Returns: + * The token's start marker, NULL if not available. + */ +const struct fy_mark * +fy_token_start_mark(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_token_end_mark() - Get token's end marker + * + * Return the token's end marker if it exists. Note + * it is permissable for some token types to have no + * end marker because they are without content. + * + * @fyt: The token to get its end marker + * + * Returns: + * The token's end marker, NULL if not available. + */ +const struct fy_mark * +fy_token_end_mark(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_scan() - Low level access to the scanner + * + * Return the next scanner token. Note this is a very + * low level interface, intended for users that want/need + * to implement their own YAML parser. The returned + * token is expected to be disposed using fy_scan_token_free() + * + * @fyp: The parser to get the next token from. + * + * Returns: + * The next token, or NULL if no more tokens are available. + */ +struct fy_token * +fy_scan(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_scan_token_free() - Free the token returned by fy_scan() + * + * Free the token returned by fy_scan(). + * + * @fyp: The parser of which the token was returned by fy_scan() + * @fyt: The token to free + */ +void +fy_scan_token_free(struct fy_parser *fyp, struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_tag_directive_token_prefix0() - Get the prefix contained in the + * tag directive token as zero terminated + * string + * + * Retrieve the tag directive's prefix contents as a zero terminated string. + * It is similar to fy_tag_directive_token_prefix(), with the difference + * that the returned string is zero terminated and memory may be allocated + * to hold it associated with the token. + * + * @fyt: The tag directive token out of which the prefix pointer + * will be returned. + * + * Returns: + * A pointer to the zero terminated text representation of the prefix token. + * NULL in case of an error. + */ +const char * +fy_tag_directive_token_prefix0(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_tag_directive_token_handle0() - Get the handle contained in the + * tag directive token as zero terminated + * string + * + * Retrieve the tag directive's handle contents as a zero terminated string. + * It is similar to fy_tag_directive_token_handle(), with the difference + * that the returned string is zero terminated and memory may be allocated + * to hold it associated with the token. + * + * @fyt: The tag directive token out of which the handle pointer + * will be returned. + * + * Returns: + * A pointer to the zero terminated text representation of the handle token. + * NULL in case of an error. + */ +const char * +fy_tag_directive_token_handle0(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_tag_token_handle() - Get the handle contained in the + * tag token + * + * Retrieve the tag handle contents. Will fail if + * token is not a tag token, or if a memory error happens. + * + * @fyt: The tag token out of which the handle pointer + * will be returned. + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the text representation of the handle token, while + * @lenp will be assigned the character length of said representation. + * NULL in case of an error. + */ +const char * +fy_tag_token_handle(struct fy_token *fyt, size_t *lenp) + FY_EXPORT; + +/** + * fy_tag_token_suffix() - Get the suffix contained in the + * tag token + * + * Retrieve the tag suffix contents. Will fail if + * token is not a tag token, or if a memory error happens. + * + * @fyt: The tag token out of which the suffix pointer + * will be returned. + * @lenp: Pointer to a variable that will hold the returned length + * + * Returns: + * A pointer to the text representation of the suffix token, while + * @lenp will be assigned the character length of said representation. + * NULL in case of an error. + */ +const char * +fy_tag_token_suffix(struct fy_token *fyt, size_t *lenp) + FY_EXPORT; + +/** + * fy_tag_token_handle0() - Get the handle contained in the + * tag token as zero terminated string + * + * Retrieve the tag handle contents as a zero terminated string. + * It is similar to fy_tag_token_handle(), with the difference + * that the returned string is zero terminated and memory may be allocated + * to hold it associated with the token. + * + * @fyt: The tag token out of which the handle pointer will be returned. + * + * Returns: + * A pointer to the zero terminated text representation of the handle token. + * NULL in case of an error. + */ +const char * +fy_tag_token_handle0(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_tag_token_suffix0() - Get the suffix contained in the + * tag token as zero terminated string + * + * Retrieve the tag suffix contents as a zero terminated string. + * It is similar to fy_tag_token_suffix(), with the difference + * that the returned string is zero terminated and memory may be allocated + * to hold it associated with the token. + * + * @fyt: The tag token out of which the suffix pointer will be returned. + * + * Returns: + * A pointer to the zero terminated text representation of the suffix token. + * NULL in case of an error. + */ +const char * +fy_tag_token_suffix0(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_version_directive_token_version() - Return the version of a version + * directive token + * + * Retrieve the version stored in a version directive token. + * + * @fyt: The version directive token + * + * Returns: + * A pointer to the version stored in the version directive token, or + * NULL in case of an error, or the token not being a version directive token. + */ +const struct fy_version * +fy_version_directive_token_version(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_scalar_token_get_style() - Return the style of a scalar token + * + * Retrieve the style of a scalar token. + * + * @fyt: The scalar token + * + * Returns: + * The scalar style of the token, or FYSS_ANY for an error + */ +enum fy_scalar_style +fy_scalar_token_get_style(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_tag_token_tag() - Get tag of a tag token + * + * Retrieve the tag of a tag token. + * + * @fyt: The tag token + * + * Returns: + * A pointer to the tag or NULL in case of an error + */ +const struct fy_tag * +fy_tag_token_tag(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_tag_directive_token_tag() - Get tag of a tag directive token + * + * Retrieve the tag of a tag directive token. + * + * @fyt: The tag directive token + * + * Returns: + * A pointer to the tag or NULL in case of an error + */ +const struct fy_tag * +fy_tag_directive_token_tag(struct fy_token *fyt) + FY_EXPORT; + +/** + * fy_event_get_token() - Return the main token of an event + * + * Retrieve the main token (i.e. not the tag or the anchor) of + * an event. It may be NULL in case of an implicit event. + * + * @fye: The event to get its main token + * + * Returns: + * The main token if it exists, NULL otherwise or in case of an error + */ +struct fy_token * +fy_event_get_token(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_event_get_anchor_token() - Return the anchor token of an event + * + * Retrieve the anchor token if it exists. Only valid for + * mapping/sequence start and scalar events. + * + * @fye: The event to get its anchor token + * + * Returns: + * The anchor token if it exists, NULL otherwise or in case of an error + */ +struct fy_token * +fy_event_get_anchor_token(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_event_get_tag_token() - Return the tag token of an event + * + * Retrieve the tag token if it exists. Only valid for + * mapping/sequence start and scalar events. + * + * @fye: The event to get its tag token + * + * Returns: + * The tag token if it exists, NULL otherwise or in case of an error + */ +struct fy_token * +fy_event_get_tag_token(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_event_start_mark() - Get event's start marker + * + * Return the event's start marker if it exists. The + * start marker is the one of the event's main token. + * + * @fye: The event to get its start marker + * + * Returns: + * The event's start marker, NULL if not available. + */ +const struct fy_mark * +fy_event_start_mark(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_event_end_mark() - Get event's end marker + * + * Return the event's end marker if it exists. The + * end marker is the one of the event's main token. + * + * @fye: The event to get its end marker + * + * Returns: + * The event's end marker, NULL if not available. + */ +const struct fy_mark * +fy_event_end_mark(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_event_get_node_style() - Get the node style of an event + * + * Return the node style (FYNS_*) of an event. May return + * FYNS_ANY if the event is implicit. + * For collection start events the only possible values is + * FYNS_ANY, FYNS_FLOW, FYNS_BLOCK. + * A scalar event may return any. + * + * @fye: The event to get it's node style + * + * Returns: + * The event's end marker, NULL if not available. + */ +enum fy_node_style +fy_event_get_node_style(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_document_start_event_version() - Return the version of a document + * start event + * + * Retrieve the version stored in a document start event + * + * @fye: The document start event + * + * Returns: + * A pointer to the version, or NULL in case of an error, or the event + * not being a document start event. + */ +const struct fy_version * +fy_document_start_event_version(struct fy_event *fye) + FY_EXPORT; + +/** + * fy_document_state_version() - Return the version of a document state + * object + * + * Retrieve the version stored in a document state object + * + * @fyds: The document state object + * + * Returns: + * A pointer to the version, or NULL in case of an error + */ +const struct fy_version * +fy_document_state_version(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_start_mark() - Get document state's start mark + * + * Return the document state's start mark (if it exists). + * Note that purely synthetic documents do not contain one + * + * @fyds: The document state object + * + * Returns: + * The document's start marker, NULL if not available. + */ +const struct fy_mark * +fy_document_state_start_mark(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_end_mark() - Get document state's end mark + * + * Return the document state's end mark (if it exists). + * Note that purely synthetic documents do not contain one + * + * @fyds: The document state object + * + * Returns: + * The document's end marker, NULL if not available. + */ +const struct fy_mark * +fy_document_state_end_mark(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_version_explicit() - Version explicit? + * + * Find out if a document state object's version was explicitly + * set in the document. + * Note that for synthetic documents this method returns false. + * + * @fyds: The document state object + * + * Returns: + * true if version was set explicitly, false otherwise + */ +bool +fy_document_state_version_explicit(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_tags_explicit() - Tags explicit? + * + * Find out if a document state object's tags were explicitly + * set in the document. + * Note that for synthetic documents this method returns false. + * + * @fyds: The document state object + * + * Returns: + * true if document had tags set explicitly, false otherwise + */ +bool +fy_document_state_tags_explicit(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_start_implicit() - Started implicitly? + * + * Find out if a document state object's document was + * started implicitly. + * Note that for synthetic documents this method returns false. + * + * @fyds: The document state object + * + * Returns: + * true if document was started implicitly, false otherwise + */ +bool +fy_document_state_start_implicit(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_end_implicit() - Started implicitly? + * + * Find out if a document state object's document was + * ended implicitly. + * Note that for synthetic documents this method returns false. + * + * @fyds: The document state object + * + * Returns: + * true if document was ended implicitly, false otherwise + */ +bool +fy_document_state_end_implicit(struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_state_tag_directive_iterate() - Iterate over the tag + * directives of a document state + * object + * + * This method iterates over all the tag directives nodes in the document state + * object. + * The start of the iteration is signalled by a NULL in \*prevp. + * + * @fyds: The document state + * @prevp: The previous iterator + * + * Returns: + * The next tag or NULL at the end of the iteration sequence. + */ +const struct fy_tag * +fy_document_state_tag_directive_iterate(struct fy_document_state *fyds, void **prevp) + FY_EXPORT; + +/** + * fy_document_state_tag_is_default() - Test whether the given tag is a default one + * + * Test whether a tag is a default (i.e. impliciticly set) + * + * @fyds: The document state + * @tag: The tag to check + * + * Returns: + * true in case that the tag is a default one, false otherwise + */ +bool +fy_document_state_tag_is_default(struct fy_document_state *fyds, const struct fy_tag *tag) + FY_EXPORT; + +/** + * fy_parser_get_document_state() - Get the document state of a parser object + * + * Retrieve the document state object of a parser. Note that this is only + * valid during parsing. + * + * @fyp: The parser + * + * Returns: + * The active document state object of the parser, NULL otherwise + */ +struct fy_document_state * +fy_parser_get_document_state(struct fy_parser *fyp) + FY_EXPORT; + +/** + * fy_document_get_document_state() - Get the document state of a document + * + * Retrieve the document state object of a document. + * + * @fyd: The document + * + * Returns: + * The document state object of the document, NULL otherwise + */ +struct fy_document_state * +fy_document_get_document_state(struct fy_document *fyd) + FY_EXPORT; + +/** + * fy_document_set_document_state() - Set the document state of a document + * + * Set the document state of a document + * + * @fyd: The document + * @fyds: The document state to use, or NULL for default + * + * Returns: + * 0 if set operation was successful, -1 otherwise + */ +int +fy_document_set_document_state(struct fy_document *fyd, struct fy_document_state *fyds) + FY_EXPORT; + +/** + * fy_document_create_from_event() - Create an empty document using the event + * + * Create an empty document using the FYET_DOCUMENT_START event generated + * by the parser. + * + * @fyp: The parser + * @fye: The event + * + * Returns: + * The created empty document, or NULL on error. + */ +struct fy_document * +fy_document_create_from_event(struct fy_parser *fyp, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_document_update_from_event() - Update the document with the event + * + * Update the document using the FYET_DOCUMENT_END event generated + * by the parser. + * + * @fyd: The document + * @fyp: The parser + * @fye: The event + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_document_update_from_event(struct fy_document *fyd, struct fy_parser *fyp, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_node_create_from_event() - Create a node using the event + * + * Create a new node using the supplied event. + * Allowed events are FYET_SCALAR, FYET_ALIAS, FYET_MAPPING_START & FYET_SEQUENCE_START + * + * @fyd: The document + * @fyp: The parser + * @fye: The event + * + * Returns: + * The newly created node, or NULL on error + */ +struct fy_node * +fy_node_create_from_event(struct fy_document *fyd, struct fy_parser *fyp, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_node_update_from_event() - Update a node using the event + * + * Update information of node created using fy_node_create_from_event() + * Allowed events are FYET_MAPPING_END & FYET_SEQUENCE_END + * + * @fyn: The node + * @fyp: The parser + * @fye: The event + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_update_from_event(struct fy_node *fyn, struct fy_parser *fyp, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_node_pair_create_with_key() - Create a new node pair and set it's key + * + * Create a new node pair using the supplied fyn_parent mapping and fyn node as + * a key. Note that the nodes _must_ have been created by fy_node_create_from_event + * and they are not interchangeable with other node pair methods. + * + * The node pair will be added to the fyn_parent mapping with a subsequent call + * to fy_node_pair_update_with_value(). + * + * @fyd: The document + * @fyn_parent: The mapping + * @fyn: The node pair key + * + * Returns: + * The newly created node pair, or NULL on error + */ +struct fy_node_pair * +fy_node_pair_create_with_key(struct fy_document *fyd, struct fy_node *fyn_parent, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_pair_update_with_value() - Update a node pair with a value and add it to the parent mapping + * + * Update the node pair with the given value and add it to the parent mapping. + * Note that the fyn node _must_ have been created by fy_node_create_from_event + * and the node pair created by fy_node_pair_create_with_key(). + * Do not intermix other node pair manipulation methods. + * + * @fynp: The node pair + * @fyn: The node pair value + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_pair_update_with_value(struct fy_node_pair *fynp, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_node_sequence_add_item() - Add an item node to a sequence node + * + * Add an item to the end of the sequence node fyn_parent. + * Note that the fyn_parent and fyn nodes _must_ have been created by + * fy_node_create_from_event. + * Do not intermix other sequence node manipulation methods. + * + * @fyn_parent: The parent sequence node + * @fyn: The node pair item + * + * Returns: + * 0 on success, -1 on error + */ +int +fy_node_sequence_add_item(struct fy_node *fyn_parent, struct fy_node *fyn) + FY_EXPORT; + +/** + * fy_emitter_get_document_state() - Get the document state of an emitter object + * + * Retrieve the document state object of an emitter. Note that this is only + * valid during emitting. + * + * @emit: The emitter + * + * Returns: + * The active document state object of the emitter, NULL otherwise + */ +struct fy_document_state * +fy_emitter_get_document_state(struct fy_emitter *emit) + FY_EXPORT; + +/** + * fy_emit_event_create() - Create an emit event. + * + * Create an emit event to pass to fy_emit_event() + * The extra arguments differ according to the event to be created + * + * FYET_STREAM_START: + * - None + * + * FYET_STREAM_END: + * - None + * + * FYET_DOCUMENT_START: + * - int implicit + * true if document start should be marked implicit + * false if document start should not be marked implicit + * - const struct fy_version \*vers + * Pointer to version to use for the document, or NULL for default + * - const struct fy_tag \* const \*tags + * Pointer to a NULL terminated array of tag pointers (like argv) + * NULL if no extra tags are to be used + * + * FYET_DOCUMENT_END: + * - int implicit + * true if document end should be marked implicit + * false if document end should not be marked implicit + * + * FYET_MAPPING_START: + * - enum fy_node_style style + * Style of the mapping (one of FYNS_ANY, FYNS_BLOCK or FYNS_FLOW) + * - const char \*anchor + * Anchor to place at the mapping, or NULL for none + * - const char \*tag + * Tag to place at the mapping, or NULL for none + * + * FYET_MAPPING_END: + * - None + * + * FYET_SEQUENCE_START: + * - enum fy_node_style style + * Style of the sequence (one of FYNS_ANY, FYNS_BLOCK or FYNS_FLOW) + * - const char \*anchor + * Anchor to place at the sequence, or NULL for none + * - const char \*tag + * Tag to place at the sequence, or NULL for none + * + * FYET_SEQUENCE_END: + * - None + * + * FYET_SCALAR: + * - enum fy_scalar_style style + * Style of the scalar, any valid FYSS_* value + * Note that certain styles may not be used according to the + * contents of the data + * - const char \*value + * Pointer to the scalar contents. + * - size_t len + * Length of the scalar contents, of FY_NT (-1) for strlen(value) + * - const char \*anchor + * Anchor to place at the scalar, or NULL for none + * - const char \*tag + * Tag to place at the scalar, or NULL for none + * + * FYET_ALIAS: + * - const char \*value + * Pointer to the alias. + * + * @emit: The emitter + * @type: The event type to create + * + * Returns: + * The created event or NULL in case of an error + */ +struct fy_event * +fy_emit_event_create(struct fy_emitter *emit, enum fy_event_type type, ...) + FY_EXPORT; + +/** + * fy_emit_event_vcreate() - Create an emit event using varargs. + * + * Create an emit event to pass to fy_emit_event() + * The varargs analogous to fy_emit_event_create(). + * + * @emit: The emitter + * @type: The event type to create + * @ap: The variable argument list pointer. + * + * Returns: + * The created event or NULL in case of an error + */ +struct fy_event * +fy_emit_event_vcreate(struct fy_emitter *emit, enum fy_event_type type, va_list ap) + FY_EXPORT; + +/** + * fy_emit_event_free() - Free an event created via fy_emit_event_create() + * + * Free an event previously created via fy_emit_event_create(). Note + * that usually you don't have to call this method since if you pass + * the event to fy_emit_event() it shall be disposed properly. + * Only use is error recovery and cleanup. + * + * @emit: The emitter + * @fye: The event to free + */ +void +fy_emit_event_free(struct fy_emitter *emit, struct fy_event *fye) + FY_EXPORT; + +/** + * fy_parse_event_create() - Create an emit event. + * + * See fy_emit_event_create()... + * + * @fyp: The parser + * @type: The event type to create + * + * Returns: + * The created event or NULL in case of an error + */ +struct fy_event * +fy_parse_event_create(struct fy_parser *fyp, enum fy_event_type type, ...) + FY_EXPORT; + +/** + * fy_parse_event_vcreate() - Create an emit event using varargs. + * + * Create an emit event to pass to fy_emit_event() + * The varargs analogous to fy_parse_event_create(). + * + * @fyp: The parser + * @type: The event type to create + * @ap: The variable argument list pointer. + * + * Returns: + * The created event or NULL in case of an error + */ +struct fy_event * +fy_parse_event_vcreate(struct fy_parser *fyp, enum fy_event_type type, va_list ap) + FY_EXPORT; + +/** + * enum fy_composer_return - The returns of the composer callback + * + * @FYCR_OK_CONTINUE: continue processing, event processed + * @FYCR_OK_STOP: stop processing, event processed + * @FYCR_OK_START_SKIP: start skip object(s), event processed + * @FYCR_OK_STOP_SKIP: stop skipping of objects, event processed + * @FYCR_ERROR: error, stop processing + */ +enum fy_composer_return { + FYCR_OK_CONTINUE = 0, + FYCR_OK_STOP = 1, + FYCR_OK_START_SKIP = 2, + FYCR_OK_STOP_SKIP = 3, + FYCR_ERROR = -1, +}; + +/** + * fy_composer_return_is_ok() - Check if the return code is OK + * + * Convenience method for checking if it's OK to continue + * + * @ret: the composer return to check + * + * Returns: + * true if non error or skip condition + */ +static inline bool +fy_composer_return_is_ok(enum fy_composer_return ret) +{ + return ret == FYCR_OK_CONTINUE || ret == FYCR_OK_STOP; +} + +/** + * typedef fy_parse_composer_cb - composer callback method + * + * This method is called by the fy_parse_compose() method + * when an event must be processed. + * + * @fyp: The parser + * @fye: The event + * @path: The path that the parser is processing + * @userdata: The user data of the fy_parse_compose() method + * + * Returns: + * fy_composer_return code telling the parser what to do + */ +typedef enum fy_composer_return +(*fy_parse_composer_cb)(struct fy_parser *fyp, struct fy_event *fye, + struct fy_path *path, void *userdata); + +/** + * fy_parse_compose() - Parse using a compose callback + * + * Alternative parsing method using a composer callback. + * + * The parser will construct a path argument that is used + * by the callback to make intelligent decisions about + * creating a document and/or DOM. + * + * @fyp: The parser + * @cb: The callback that will be called + * @userdata: user pointer to pass to the callback + * + * Returns: + * 0 if no error occured + * -1 on error + */ +int +fy_parse_compose(struct fy_parser *fyp, fy_parse_composer_cb cb, + void *userdata) + FY_EXPORT; + +/** + * fy_path_component_is_mapping() - Check if the component is a mapping + * + * @fypc: The path component to check + * + * Returns: + * true if the path component is a mapping, false otherwise + */ +bool +fy_path_component_is_mapping(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_is_sequence() - Check if the component is a sequence + * + * @fypc: The path component to check + * + * Returns: + * true if the path component is a sequence, false otherwise + */ +bool +fy_path_component_is_sequence(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_sequence_get_index() - Get the index of sequence path component + * + * @fypc: The sequence path component to return it's index value + * + * Returns: + * >= 0 the sequence index + * -1 if the component is either not in the proper mode, or not a sequence + */ +int +fy_path_component_sequence_get_index(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_mapping_get_scalar_key() - Get the scalar key of a mapping + * + * @fypc: The mapping path component to return it's scalar key + * + * Returns: + * a non NULL scalar or alias token if the mapping contains a scalar key + * NULL in case of an error, or if the component has a complex key + */ +struct fy_token * +fy_path_component_mapping_get_scalar_key(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_mapping_get_complex_key() - Get the complex key of a mapping + * + * @fypc: The mapping path component to return it's complex key + * + * Returns: + * a non NULL document if the mapping contains a complex key + * NULL in case of an error, or if the component has a simple key + */ +struct fy_document * +fy_path_component_mapping_get_complex_key(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_depth() - Get the depth of a path + * + * @fypp: The path to query + * + * Returns: + * The depth of the path, or -1 on error + */ +int +fy_path_depth(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_parent() - Get the parent of a path + * + * Paths may contain parents when traversing complex keys. + * This method returns the immediate parent. + * + * @fypp: The path to return it's parent + * + * Returns: + * The path parent or NULL on error, if it doesn't exist + */ +struct fy_path * +fy_path_parent(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_get_text() - Get the textual representation of a path + * + * Given a path, return a malloc'ed string which contains + * the textual representation of it. + * + * Note that during processing, complex key paths are simply + * indicative and not to be used for addressing. + * + * @fypp: The path to get it's textual representation + * + * Returns: + * The textual representation of the path, NULL on error. + * The string must be free'ed using free. + */ +char * +fy_path_get_text(struct fy_path *fypp) + FY_EXPORT; + +#define fy_path_get_text_alloca(_fypp) \ + FY_ALLOCA_COPY_FREE(fy_path_get_text((_fypp)), FY_NT) + +/** + * fy_path_in_root() - Check if the path is in the root of the document + * + * @fypp: The path + * + * Returns: + * true if the path is located within the root of the document + */ +bool +fy_path_in_root(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_in_mapping() - Check if the path is in a mapping + * + * @fypp: The path + * + * Returns: + * true if the path is located within a mapping + */ +bool +fy_path_in_mapping(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_in_sequence() - Check if the path is in a sequence + * + * @fypp: The path + * + * Returns: + * true if the path is located within a sequence + */ +bool +fy_path_in_sequence(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_in_mapping_key() - Check if the path is in a mapping key state + * + * @fypp: The path + * + * Returns: + * true if the path is located within a mapping key state + */ +bool +fy_path_in_mapping_key(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_in_mapping_key() - Check if the path is in a mapping value state + * + * @fypp: The path + * + * Returns: + * true if the path is located within a mapping value state + */ +bool +fy_path_in_mapping_value(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_in_collection_root() - Check if the path is in a collection root + * + * A collection root state is when the path points to a sequence or mapping + * but the state does not allow setting keys, values or adding items. + * + * This occurs on MAPPING/SEQUENCE START/END events. + * + * @fypp: The path + * + * Returns: + * true if the path is located within a collectin root state + */ +bool +fy_path_is_collection_root(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_component_get_mapping_user_data() - Return the userdata associated with the mapping + * + * @fypc: The path component + * + * Returns: + * The user data associated with the mapping, or NULL if not a mapping or the user data are NULL + */ +void * +fy_path_component_get_mapping_user_data(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_get_mapping_key_user_data() - Return the userdata associated with the mapping key + * + * @fypc: The path component + * + * Returns: + * The user data associated with the mapping key, or NULL if not a mapping or the user data are NULL + */ +void * +fy_path_component_get_mapping_key_user_data(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_get_sequence_data() - Return the userdata associated with the sequence + * + * @fypc: The path component + * + * Returns: + * The user data associated with the sequence, or NULL if not a sequence or the user data are NULL + */ +void * +fy_path_component_get_sequence_user_data(struct fy_path_component *fypc) + FY_EXPORT; + +/** + * fy_path_component_set_mapping_user_data() - Set the user data associated with a mapping + * + * Note, no error condition if not a mapping + * + * @fypc: The path component + * @data: The data to set as mapping data + */ +void +fy_path_component_set_mapping_user_data(struct fy_path_component *fypc, void *data) + FY_EXPORT; + +/** + * fy_path_component_set_mapping_key_user_data() - Set the user data associated with a mapping key + * + * Note, no error condition if not in a mapping key state + * + * @fypc: The path component + * @data: The data to set as mapping key data + */ +void +fy_path_component_set_mapping_key_user_data(struct fy_path_component *fypc, void *data) + FY_EXPORT; + +/** + * fy_path_component_set_sequence_user_data() - Set the user data associated with a sequence + * + * Note, no error condition if not a sequence + * + * @fypc: The path component + * @data: The data to set as sequence data + */ +void +fy_path_component_set_sequence_user_data(struct fy_path_component *fypc, void *data) + FY_EXPORT; + +/** + * fy_path_last_component() - Get the very last component of a path + * + * Returns the last component of a path. + * + * @fypp: The path + * + * Returns: + * The last path component (which may be a collection root component), or NULL + * if it does not exist + */ +struct fy_path_component * +fy_path_last_component(struct fy_path *fypp) + FY_EXPORT; + +/** + * fy_path_last_not_collection_root_component() - Get the last non collection root component of a path + * + * Returns the last non collection root component of a path. This may not be the + * last component that is returned by fy_path_last_component(). + * + * The difference is present on MAPPING/SEQUENCE START/END events where the + * last component is present but not usuable as a object parent. + * + * @fypp: The path + * + * Returns: + * The last non collection root component, or NULL if it does not exist + */ +struct fy_path_component * +fy_path_last_not_collection_root_component(struct fy_path *fypp) + FY_EXPORT; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libfyaml.pc.in b/libfyaml.pc.in new file mode 100644 index 0000000..bf9d8d5 --- /dev/null +++ b/libfyaml.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libfyaml +Description: Fancy YAML 1.3 parser library +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lfyaml-@MAJOR@.@MINOR@ @PTHREAD_LIBS@ +Cflags: -I${includedir} @PTHREAD_CFLAGS@ diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 new file mode 100644 index 0000000..7bc7710 --- /dev/null +++ b/m4/ax_check_enable_debug.m4 @@ -0,0 +1,124 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE]) +# +# DESCRIPTION +# +# Check for the presence of an --enable-debug option to configure, with +# the specified default value used when the option is not present. Return +# the value in the variable $ax_enable_debug. +# +# Specifying 'yes' adds '-g -O0' to the compilation flags for all +# languages. Specifying 'info' adds '-g' to the compilation flags. +# Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to +# the linking flags. Otherwise, nothing is added. +# +# Define the variables listed in the second argument if debug is enabled, +# defaulting to no variables. Defines the variables listed in the third +# argument if debug is disabled, defaulting to NDEBUG. All lists of +# variables should be space-separated. +# +# If debug is not enabled, ensure AC_PROG_* will not add debugging flags. +# Should be invoked prior to any AC_PROG_* compiler checks. +# +# IS-RELEASE can be used to change the default to 'no' when making a +# release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it +# uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE +# macro, there is no need to pass this parameter. +# +# AX_IS_RELEASE([git-directory]) +# AX_CHECK_ENABLE_DEBUG() +# +# LICENSE +# +# Copyright (c) 2011 Rhys Ulerich +# Copyright (c) 2014, 2015 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +#serial 9 + +AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ + AC_BEFORE([$0],[AC_PROG_CC])dnl + AC_BEFORE([$0],[AC_PROG_CXX])dnl + AC_BEFORE([$0],[AC_PROG_F77])dnl + AC_BEFORE([$0],[AC_PROG_FC])dnl + + AC_MSG_CHECKING(whether to enable debugging) + + ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1]))) + ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],, + [$ax_is_release], + [$4]))) + + # If this is a release, override the default. + AS_IF([test "$ax_enable_debug_is_release" = "yes"], + [ax_enable_debug_default="no"]) + + m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))]) + m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))]) + + AC_ARG_ENABLE(debug, + [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], + [],enable_debug=$ax_enable_debug_default) + + # empty mean debug yes + AS_IF([test "x$enable_debug" = "x"], + [enable_debug="yes"]) + + # case of debug + AS_CASE([$enable_debug], + [yes],[ + AC_MSG_RESULT(yes) + CFLAGS="${CFLAGS} -g -O0" + CXXFLAGS="${CXXFLAGS} -g -O0" + FFLAGS="${FFLAGS} -g -O0" + FCFLAGS="${FCFLAGS} -g -O0" + OBJCFLAGS="${OBJCFLAGS} -g -O0" + ], + [info],[ + AC_MSG_RESULT(info) + CFLAGS="${CFLAGS} -g" + CXXFLAGS="${CXXFLAGS} -g" + FFLAGS="${FFLAGS} -g" + FCFLAGS="${FCFLAGS} -g" + OBJCFLAGS="${OBJCFLAGS} -g" + ], + [profile],[ + AC_MSG_RESULT(profile) + CFLAGS="${CFLAGS} -g -pg" + CXXFLAGS="${CXXFLAGS} -g -pg" + FFLAGS="${FFLAGS} -g -pg" + FCFLAGS="${FCFLAGS} -g -pg" + OBJCFLAGS="${OBJCFLAGS} -g -pg" + LDFLAGS="${LDFLAGS} -pg" + ], + [ + AC_MSG_RESULT(no) + dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags + dnl by setting any unset environment flag variables + AS_IF([test "x${CFLAGS+set}" != "xset"], + [CFLAGS=""]) + AS_IF([test "x${CXXFLAGS+set}" != "xset"], + [CXXFLAGS=""]) + AS_IF([test "x${FFLAGS+set}" != "xset"], + [FFLAGS=""]) + AS_IF([test "x${FCFLAGS+set}" != "xset"], + [FCFLAGS=""]) + AS_IF([test "x${OBJCFLAGS+set}" != "xset"], + [OBJCFLAGS=""]) + ]) + + dnl Define various variables if debugging is disabled. + dnl assert.h is a NOP if NDEBUG is defined, so define it by default. + AS_IF([test "x$enable_debug" = "xyes"], + [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,[1],[Define if debugging is enabled])])], + [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,[1],[Define if debugging is disabled])])]) + ax_enable_debug=$enable_debug +]) diff --git a/m4/ax_check_flag.m4 b/m4/ax_check_flag.m4 new file mode 100644 index 0000000..52405fd --- /dev/null +++ b/m4/ax_check_flag.m4 @@ -0,0 +1,147 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS]) +# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's +# preprocessor/compiler/linker, or whether they give an error. (Warnings, +# however, are ignored.) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check us thus made +# with the following flags: "CFLAGS EXTRA-FLAGS FLAG". EXTRA-FLAGS can +# for example be used to force the compiler to issue an error when a bad +# flag is given. +# +# AX_APPEND_FLAG appends the FLAG to the FLAG-VARIABLE shell variable or +# the current language's flags if not specified. FLAG is not added to +# FLAG-VARIABLE if it is already in the shell variable. +# +# AX_APPEND_COMPILE_FLAGS checks for each FLAG1, FLAG2, etc. using +# AX_CHECK_COMPILE_FLAG and if the check is successful the flag is added +# to the appropriate FLAGS variable with AX_APPEND_FLAG. The +# FLAGS-VARIABLE and EXTRA-FLAGS arguments are the same as in the other +# macros. AX_APPEND_LINK_FLAGS does the same for linker flags. +# +# NOTE: Based on AX_CHECK_COMPILER_FLAGS and AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2009 Steven G. Johnson +# Copyright (c) 2009 Matteo Frigo +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_PREPROC_FLAG], +[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [ + ax_check_save_flags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $4 $1" + AC_PREPROC_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET([CACHEVAR],[yes])], + [AS_VAR_SET([CACHEVAR],[no])]) + CPPFLAGS=$ax_check_save_flags]) +AS_VAR_IF([CACHEVAR], "yes", + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_PREPROC_FLAGS + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET([CACHEVAR],[yes])], + [AS_VAR_SET([CACHEVAR],[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF([CACHEVAR], "yes", + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET([CACHEVAR],[yes])], + [AS_VAR_SET([CACHEVAR],[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF([CACHEVAR], "yes", + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS + + +AC_DEFUN([AX_APPEND_FLAG], +[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX +AC_REQUIRE([AC_PROG_GREP]) +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[]FLAGS)])dnl +AS_VAR_SET_IF([FLAGS], + [AS_IF([AS_ECHO(" $[]FLAGS ") | $GREP " $1 " 2>&1 >/dev/null], + [AC_RUN_LOG([: FLAGS already contains $1])], + [AC_RUN_LOG([: FLAGS="$FLAGS $1"]) + AS_VAR_APPEND([FLAGS], [" $1"])])], + [AS_VAR_SET([FLAGS],[$1])]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG + +AC_DEFUN([AX_APPEND_COMPILE_FLAGS], +[for flag in $1; do + AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3]) +done +])dnl AX_APPEND_COMPILE_FLAGS + +AC_DEFUN([AX_APPEND_LINK_FLAGS], +[for flag in $1; do + AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3]) +done +])dnl AX_APPEND_LINK_FLAGS diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 new file mode 100644 index 0000000..6d400ed --- /dev/null +++ b/m4/ax_pthread.m4 @@ -0,0 +1,317 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 20 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != xyes; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/m4/libtool.m4 b/m4/libtool.m4 new file mode 100644 index 0000000..ee80844 --- /dev/null +++ b/m4/libtool.m4 @@ -0,0 +1,8387 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4 new file mode 100644 index 0000000..94b0829 --- /dev/null +++ b/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4 new file mode 100644 index 0000000..48bc934 --- /dev/null +++ b/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/m4/ltversion.m4 b/m4/ltversion.m4 new file mode 100644 index 0000000..fa04b52 --- /dev/null +++ b/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c6b26f8 --- /dev/null +++ b/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/m4/shave.m4 b/m4/shave.m4 new file mode 100644 index 0000000..f2da7d8 --- /dev/null +++ b/m4/shave.m4 @@ -0,0 +1,111 @@ +dnl Make automake/libtool output more friendly to humans +dnl +dnl Copyright (c) 2009, Damien Lespiau +dnl +dnl Permission is hereby granted, free of charge, to any person +dnl obtaining a copy of this software and associated documentation +dnl files (the "Software"), to deal in the Software without +dnl restriction, including without limitation the rights to use, +dnl copy, modify, merge, publish, distribute, sublicense, and/or sell +dnl copies of the Software, and to permit persons to whom the +dnl Software is furnished to do so, subject to the following +dnl conditions: +dnl +dnl The above copyright notice and this permission notice shall be +dnl included in all copies or substantial portions of the Software. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +dnl EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +dnl OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +dnl NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +dnl HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +dnl WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +dnl OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl SHAVE_INIT([shavedir],[default_mode]) +dnl +dnl shavedir: the directory where the shave scripts are, it defaults to +dnl $(top_builddir) +dnl default_mode: (enable|disable) default shave mode. This parameter +dnl controls shave's behaviour when no option has been +dnl given to configure. It defaults to disable. +dnl +dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just +dnl before AC_CONFIG_FILE/AC_OUTPUT is perfect. This macro rewrites CC and +dnl LIBTOOL, you don't want the configure tests to have these variables +dnl re-defined. +dnl * This macro requires GNU make's -s option. + +AC_DEFUN([_SHAVE_ARG_ENABLE], +[ + AC_ARG_ENABLE([shave], + AS_HELP_STRING( + [--enable-shave], + [use shave to make the build pretty [[default=$1]]]),, + [enable_shave=$1] + ) +]) + +AC_DEFUN([SHAVE_INIT], +[ + dnl you can tweak the default value of enable_shave + m4_if([$2], [enable], [_SHAVE_ARG_ENABLE(yes)], [_SHAVE_ARG_ENABLE(no)]) + + if test x"$enable_shave" = xyes; then + dnl where can we find the shave scripts? + m4_if([$1],, + [shavedir="$ac_pwd"], + [shavedir="$ac_pwd/$1"]) + AC_SUBST(shavedir) + + dnl make is now quiet + AC_SUBST([MAKEFLAGS], [-s]) + AC_SUBST([AM_MAKEFLAGS], ['`test -z $V && echo -s`']) + + dnl we need sed + AC_CHECK_PROG(SED,sed,sed,false) + + dnl substitute libtool + SHAVE_SAVED_LIBTOOL=$LIBTOOL + LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'" + AC_SUBST(LIBTOOL) + + dnl substitute cc/cxx + SHAVE_SAVED_CCAS=$CCAS + SHAVE_SAVED_CC=$CC + SHAVE_SAVED_CXX=$CXX + SHAVE_SAVED_FC=$FC + SHAVE_SAVED_F77=$F77 + SHAVE_SAVED_OBJC=$OBJC + SHAVE_SAVED_MCS=$MCS + SHAVE_SAVED_LEX=$LEX + SHAVE_SAVED_YACC=$YACC + CCAS="${SHELL} ${shavedir}/shave ccas ${SHAVE_SAVED_CCAS}" + CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}" + CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}" + FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}" + F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}" + OBJC="${SHELL} ${shavedir}/shave objc ${SHAVE_SAVED_OBJC}" + MCS="${SHELL} ${shavedir}/shave mcs ${SHAVE_SAVED_MCS}" + LEX="${SHELL} ${shavedir}/shave lex ${SHAVE_SAVED_LEX}" + YACC="${SHELL} ${shavedir}/shave yacc ${SHAVE_SAVED_YACC}" + AC_SUBST(CCAS) + AC_SUBST(CC) + AC_SUBST(CXX) + AC_SUBST(FC) + AC_SUBST(F77) + AC_SUBST(OBJC) + AC_SUBST(MCS) + AC_SUBST(LEX) + AC_SUBST(YACC) + + V=@ + else + V=1 + fi + Q='$(V:1=)' + AC_SUBST(V) + AC_SUBST(Q) +]) + diff --git a/scripts/create-virtual-env b/scripts/create-virtual-env new file mode 100644 index 0000000..0d3595d --- /dev/null +++ b/scripts/create-virtual-env @@ -0,0 +1,6 @@ +virtualenv -p python3 sphinx +. sphinx/bin/activate +pip3 install sphinx +pip3 install git+http://github.com/return42/linuxdoc.git +pip3 install sphinx_rtd_theme +pip3 install sphinx-markdown-builder diff --git a/scripts/install-linuxdoc.sh b/scripts/install-linuxdoc.sh new file mode 100755 index 0000000..7a64900 --- /dev/null +++ b/scripts/install-linuxdoc.sh @@ -0,0 +1,2 @@ +#!/bin/sh +pip3 install --user git+http://github.com/return42/linuxdoc.git diff --git a/scripts/run-check-errors.sh b/scripts/run-check-errors.sh new file mode 100755 index 0000000..144b4b0 --- /dev/null +++ b/scripts/run-check-errors.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +ERROR=1 +PARSER="./src/libfyaml-parser -mtestsuite" +FILE= + +while true; do + case "$1" in + -- ) shift; break ;; + + --errors | -e ) + ERROR=1 + PASS=0 + shift ;; + + --file | -f ) + shift + FILE=$1 + shift ;; + + * ) break ;; + esac +done + +declare -a rf + +# check tty mode (whether we can colorize) +if [ -t 1 ]; then + GRN="\e[32m" + RED="\e[31m" + GRY="\e[37m" + YLW="\e[33m" + CYN="\e[36m" + NRM="\e[0m" +else + GRN="" + RED="" + GRY="" + YLW="" + CYN="" + NRM="" +fi + +rf=() +i=0 + +if [ "x$FILE" = "x" ]; then + for prefix in $*; do + echo "Collecting tests from $prefix" + while read full ; do + + # full-path:prefix:path-without-prefix:path-without-prefix-filename + relative=`echo $full | sed -e "s#^$prefix##g"` + file=`echo $relative | sed -e "s#/in.yaml##g" | tr '/' '-'` + rf+=( "$full:$prefix:$relative:$file" ) + # echo ${rf[$i]} + i=$(($i + 1)) + done < <(find "$prefix" -name "in.yaml" -print | sort) + done +else + echo "reading tests from $FILE" + DIR=`echo $1 | sed -e 's#/$##g'` + for dir in `cat $FILE`; do + prefix="$DIR/$dir" + + # only if directory exists + if [ ! -d "$prefix" ]; then + continue + fi + + while read full ; do + + # full-path:prefix:path-without-prefix:path-without-prefix-filename + relative=`echo $full | sed -e "s#^$DIR##g"` + file=`echo $relative | sed -e "s#/in.yaml##g" | sed -e "s#^/##g"` + rf+=( "$full:$1:$relative:$file" ) + # echo ${rf[$i]} + i=$(($i + 1)) + done < <(find "$prefix" -name "in.yaml" -print | sort) + done +fi + +count=${#rf[@]} + +for (( i=0; i < $count; i++)); do + v="${rf[$i]}" + full=`echo $v | cut -d: -f1` + prefix=`echo $v | cut -d: -f2` + relative=`echo $v | cut -d: -f3` + file=`echo $v | cut -d: -f4` + # echo "$i: full=$full prefix=$prefix relative=$relative file=$file" + + has_yaml=1 + + desc=`echo $full | sed -e 's#in.yaml#===#'` + desctxt="" + if [ -e "$desc" ]; then + descf=`realpath "$desc"` + desctxt=`cat 2>/dev/null "$descf"` + has_desc=1 + else + has_desc=0 + fi + + errf=`echo $full | sed -e 's#in.yaml#error#'` + if [ -e "$errf" ] ; then + expected_error="1" + has_error=1 + else + expected_error="0" + has_error=0 + continue + fi + + if [ $expected_error == 0 ]; then + col="$GRN" + else + col="$RED" + fi + echo -e "$col$file$NRM: $desctxt" + + ${PARSER} >/dev/null "$full" + + echo +done diff --git a/scripts/run-compare-dump.sh b/scripts/run-compare-dump.sh new file mode 100755 index 0000000..506cc12 --- /dev/null +++ b/scripts/run-compare-dump.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# VALGRIND="" +VALGRIND="valgrind" +BN=`basename $1` +ON="output/$BN" +mkdir -p output +a="$ON.libyaml.dump" +b="$ON.libfyaml.dump" +./src/libfyaml-parser -mlibyaml-dump "$1" >"$a" +./src/libfyaml-parser -mdump "$1" >"$b" +diff -au "$a" "$b" | tee "$ON.dump.diff" +./src/libfyaml-parser -mscan -d0 "$1" >"$ON.dump.log" 2>&1 diff --git a/scripts/run-compare-examples.sh b/scripts/run-compare-examples.sh new file mode 100755 index 0000000..655e0c5 --- /dev/null +++ b/scripts/run-compare-examples.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +for i in $*; do + echo "checking: $i" + ./run-compare-scan.sh $i + ./run-compare-parse.sh $i + echo +done diff --git a/scripts/run-compare-parse.sh b/scripts/run-compare-parse.sh new file mode 100755 index 0000000..fafa8cf --- /dev/null +++ b/scripts/run-compare-parse.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# VALGRIND="" +VALGRIND="valgrind" +BN=`basename $1` +ON="output/$BN" +mkdir -p output +a="$ON.libyaml.parse" +b="$ON.libfyaml.parse" +./src/libfyaml-parser -mlibyaml-parse "$1" >"$a" +./src/libfyaml-parser -mparse "$1" >"$b" +diff -u "$a" "$b" | tee "$ON.parse.diff" +./src/libfyaml-parser -mparse -d0 "$1" >"$ON.parse.log" 2>&1 diff --git a/scripts/run-compare-scan.sh b/scripts/run-compare-scan.sh new file mode 100755 index 0000000..68d0375 --- /dev/null +++ b/scripts/run-compare-scan.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# VALGRIND="" +VALGRIND="valgrind" +BN=`basename $1` +ON="output/$BN" +mkdir -p output +a="$ON.libyaml.scan" +b="$ON.libfyaml.scan" +./src/libfyaml-parser -mlibyaml-scan "$1" >"$a" +./src/libfyaml-parser -mscan "$1" >"$b" +diff -u "$a" "$b" | tee "$ON.scan.diff" +./src/libfyaml-parser -mscan -d0 "$1" >"$ON.scan.log" 2>&1 diff --git a/scripts/run-compare-testsuite.sh b/scripts/run-compare-testsuite.sh new file mode 100755 index 0000000..5595bd5 --- /dev/null +++ b/scripts/run-compare-testsuite.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +declare -a rf + +# check tty mode (whether we can colorize) +if [ -t 1 ]; then + GRN="\e[32m" + RED="\e[31m" + GRY="\e[37m" + YLW="\e[33m" + CYN="\e[36m" + NRM="\e[0m" +else + GRN="" + RED="" + GRY="" + YLW="" + CYN="" + NRM="" +fi + +rf=() +i=0 +for prefix in $*; do + echo "Collecting tests from $prefix" + while read full ; do + + # full-path:prefix:path-without-prefix:path-without-prefix-filename + relative=`echo $full | sed -e "s#^$prefix##g"` + file=`echo $relative | sed -e "s#/in.yaml##g" | tr '/' '-'` + rf+=( "$full:$prefix:$relative:$file" ) + # echo ${rf[$i]} + i=$(($i + 1)) + done < <(find "$prefix" -name "in.yaml" -print | sort) +done + +count=${#rf[@]} + +mkdir -p output + +pass=0 +fail=0 +unknown=0 +experr=0 +for (( i=0; i < $count; i++)); do + v="${rf[$i]}" + full=`echo $v | cut -d: -f1` + prefix=`echo $v | cut -d: -f2` + relative=`echo $v | cut -d: -f3` + file=`echo $v | cut -d: -f4` + # echo "$i: full=$full prefix=$prefix relative=$relative file=$file" + + f="output/$file.yaml" + rm -f "$f" "output/$file.pass" "output/$file.fail" \ + "output/$file.unknown" "output/$file.desc" \ + "output/$file.event" + ln -s `realpath $full` "$f" + + desc=`echo $full | sed -e 's#in.yaml#===#'` + desctxt="" + if [ -e "$desc" ]; then + descf=`realpath $desc` + ln -s "$descf" "output/$file.desc" + desctxt=`cat 2>/dev/null "$descf"` + fi + + event=`echo $full | sed -e 's#in.yaml#test.event#'` + if [ -e "$event" ]; then + eventf=`realpath $event` + ln -s "$eventf" "output/$file.event" + fi + + errf=`echo $full | sed -e 's#in.yaml#error#'` + if [ -e "$errf" ] ; then + expected_error="1" + exp="!" + else + expected_error="0" + exp="-" + fi + + this_fail=0 + this_unknown=0 + + a0="output/$file.libyaml" + a1="output/$file.libfyaml" + + pass0=0 + pass1=0 + diff=0 + + # execute both libyaml & libfyaml + ./src/libfyaml-parser -mlibyaml-parse "$f" > "$a0" 2>/dev/null + if [ $? -eq 0 ]; then pass0=1; fi + + ./src/libfyaml-parser -mparse "$f" > "$a1" 2>/dev/null + if [ $? -eq 0 ]; then pass1=1; fi + + # compare output anyway + diff -u "$a0" "$a1" > "output/$file.diff" + if [ $? -eq 0 ]; then diff=1; fi + + if [ $expected_error -eq 0 ]; then + # it fails if any fail + this_fail=$(($pass0 == 0 || $pass1 == 0 || $diff == 0)) + this_unknown=$(($pass0 == 0)) + else + # test expected to fail (both must fail) + this_fail=$(($pass0 == 1 || $pass1 == 1)) + this_unknown=$(($pass0 == 1)) + fi + + if [ $this_unknown -ne 0 ]; then + touch "output/$file.unknown" + if [[ $pass1 == $pass0 ]]; then + COL="${GRY}" + else + COL="${CYN}" + fi + res="${COL}UNKN${NRM}" + unknown=$(($unknown + 1)) + elif [ $this_fail -ne 0 ]; then + touch "output/$file.fail" + res="${RED}FAIL${NRM}" + fail=$(($fail + 1)) + else + touch "output/$file.pass" + res="${GRN}PASS${NRM}" + pass=$(($pass + 1)) + fi + + echo -e "${exp}${pass0}${pass1} ${res} $file: $desctxt" +done + +echo +echo -e " TOTAL: ${count}" +echo -e " PASS: ${GRN}${pass}${NRM}" +echo -e " FAIL: ${RED}${fail}${NRM}" +echo -e "UNKNOWN: ${GRY}${unknown}${NRM}" diff --git a/scripts/run-emit-check.sh b/scripts/run-emit-check.sh new file mode 100755 index 0000000..5fd7186 --- /dev/null +++ b/scripts/run-emit-check.sh @@ -0,0 +1,12 @@ +#!/bin/bash +BN=`basename $1` +ON="output/$BN" +mkdir -p output +a="$ON.1.dump" +b="$ON.2.dump" +./src/fy-tool --testsuite "$1" >"$a" +./src/fy-tool --dump "$1" | ./src/fy-tool --testsuite - >"$b" +diff -au "$a" "$b" | tee "$ON.12.diff" +if [ ! -s "${ON}.12.diff" ] ; then + rm -f "${ON}.1.dump" "${ON}.2.dump" "${ON}.12.diff" +fi diff --git a/scripts/run-kcachegrind.sh b/scripts/run-kcachegrind.sh new file mode 100755 index 0000000..002129b --- /dev/null +++ b/scripts/run-kcachegrind.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# LD_LIBRARY_PATH=${PWD}/src/.libs/ valgrind --leak-check=full ./src/.libs/libfyaml-parser -mscan "$1" 2>&1 | tee valgrind.log +LD_LIBRARY_PATH=${PWD}/src/.libs/ valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes \ + ./src/.libs/libfyaml-parser $* 2>&1 | tee valgrind.log diff --git a/scripts/run-list-testsuite.sh b/scripts/run-list-testsuite.sh new file mode 100755 index 0000000..4dc676e --- /dev/null +++ b/scripts/run-list-testsuite.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +ERROR=1 +PASS=1 + +while true; do + case "$1" in + -- ) shift; break ;; + + --pass | -p) + ERROR=0 + PASS=1 + shift ;; + + --errors | -e ) + ERROR=1 + PASS=0 + shift ;; + + * ) break ;; + esac +done + +declare -a rf + +# check tty mode (whether we can colorize) +if [ -t 1 ]; then + GRN="\e[32m" + RED="\e[31m" + GRY="\e[37m" + YLW="\e[33m" + CYN="\e[36m" + NRM="\e[0m" +else + GRN="" + RED="" + GRY="" + YLW="" + CYN="" + NRM="" +fi + +rf=() +i=0 +for prefix in $*; do + echo "Collecting tests from $prefix" + while read full ; do + + # full-path:prefix:path-without-prefix:path-without-prefix-filename + relative=`echo $full | sed -e "s#^$prefix##g"` + file=`echo $relative | sed -e "s#/in.yaml##g" | tr '/' '-'` + rf+=( "$full:$prefix:$relative:$file" ) + # echo ${rf[$i]} + i=$(($i + 1)) + done < <(find "$prefix" -name "in.yaml" -print | sort) +done + +count=${#rf[@]} + +for (( i=0; i < $count; i++)); do + v="${rf[$i]}" + full=`echo $v | cut -d: -f1` + prefix=`echo $v | cut -d: -f2` + relative=`echo $v | cut -d: -f3` + file=`echo $v | cut -d: -f4` + # echo "$i: full=$full prefix=$prefix relative=$relative file=$file" + + f="output/$file.yaml" + + has_yaml=1 + + desc=`echo $full | sed -e 's#in.yaml#===#'` + desctxt="" + if [ -e "$desc" ]; then + descf=`realpath "$desc"` + desctxt=`cat 2>/dev/null "$descf"` + has_desc=1 + else + has_desc=0 + fi + + errf=`echo $full | sed -e 's#in.yaml#error#'` + if [ -e "$errf" ] ; then + expected_error="1" + has_error=1 + else + expected_error="0" + has_error=0 + fi + + if [ $expected_error == 0 -a $PASS != 1 ]; then + continue + fi + + if [ $expected_error == 1 -a $ERROR != 1 ]; then + continue + fi + + if [ $expected_error == 0 ]; then + col="$GRN" + else + col="$RED" + fi + echo -e "$col$file$NRM: $desctxt" +done diff --git a/scripts/run-massif.sh b/scripts/run-massif.sh new file mode 100755 index 0000000..6078345 --- /dev/null +++ b/scripts/run-massif.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# LD_LIBRARY_PATH=${PWD}/src/.libs/ valgrind --leak-check=full ./src/.libs/libfyaml-parser -mscan "$1" 2>&1 | tee valgrind.log +LD_LIBRARY_PATH=${PWD}/src/.libs/ valgrind --tool=massif ./src/.libs/libfyaml-parser $* 2>&1 | tee massif.log diff --git a/scripts/run-test.sh b/scripts/run-test.sh new file mode 100755 index 0000000..f4bbdb1 --- /dev/null +++ b/scripts/run-test.sh @@ -0,0 +1,275 @@ +#!/bin/bash + +PREFIX="./src" +PARSER="libfyaml-parser -d0 -mtestsuite" +# PARSER="fy-public-parser -d0" +KEEP=0 +VALGRIND=0 +STDIN=0 + +while true; do + case "$1" in + -- ) shift; break ;; + + --private | -P ) + PARSER="libfyaml-parser -d0 -mtestsuite" + shift ;; + + --public | -p ) + PARSER="fy-public-parser -d0" + shift ;; + + --libyaml | -l ) + PARSER="libfyaml-parser -d0 -mlibyaml-testsuite" + shift ;; + + --valgrind | -V) + VALGRIND=1 + shift ;; + + --keep | -k) + KEEP=1 + shift ;; + + --stdin | -s ) + STDIN=1 + shift ;; + + * ) break ;; + esac +done + +if [[ $VALGRIND != 0 ]]; then + export LD_LIBRARY_PATH="${PWD}/src/.libs" + PARSER="valgrind --track-origins=yes --leak-check=full $PREFIX/.libs/$PARSER" +else + PARSER="$PREFIX/$PARSER" +fi + +echo " PARSER: ${PARSER}" + +declare -a rf + +# check tty mode (whether we can colorize) +if [ -t 1 ]; then + GRN="\e[32m" + RED="\e[31m" + GRY="\e[37m" + YLW="\e[33m" + CYN="\e[36m" + NRM="\e[0m" +else + GRN="" + RED="" + GRY="" + YLW="" + CYN="" + NRM="" +fi + +rf=() +i=0 +for prefix in $*; do + echo "Collecting tests from $prefix" + while read full ; do + + # full-path:prefix:path-without-prefix:path-without-prefix-filename + relative=`echo $full | sed -e "s#^$prefix##g"` + file=`echo $relative | sed -e "s#/in.yaml##g" | tr '/' '-'` + rf+=( "$full:$prefix:$relative:$file" ) + # echo ${rf[$i]} + i=$(($i + 1)) + done < <(find "$prefix" -name "in.yaml" -print | sort) +done + +count=${#rf[@]} + +mkdir -p output + +pass=0 +fail=0 +unknown=0 +experr=0 + +pass_count_yaml=0 +fail_count_yaml=0 + +pass_count_json=0 +fail_count_json=0 + +for (( i=0; i < $count; i++)); do + v="${rf[$i]}" + full=`echo $v | cut -d: -f1` + prefix=`echo $v | cut -d: -f2` + relative=`echo $v | cut -d: -f3` + file=`echo $v | cut -d: -f4` + # echo "$i: full=$full prefix=$prefix relative=$relative file=$file" + + f="output/$file.yaml" + rm -f "$f" "output/$file.pass" "output/$file.fail" \ + "output/$file.unknown" "output/$file.desc" \ + "output/$file.event" "output/$file.log" \ + "output/$file.gm-event" \ + "output/$file.libyaml-event" \ + "output/$file.json" "output/$file.json.diff" \ + "output/$file.json.event" + ln -s `realpath $full` "$f" + has_yaml=1 + + desc=`echo $full | sed -e 's#in.yaml#===#'` + desctxt="" + if [ -e "$desc" ]; then + descf=`realpath "$desc"` + ln -s "$descf" "output/$file.desc" + desctxt=`cat 2>/dev/null "$descf"` + has_desc=1 + else + has_desc=0 + fi + + event=`echo $full | sed -e 's#in.yaml#test.event#'` + if [ -e "$event" ]; then + eventf=`realpath "$event"` + ln -s "$eventf" "output/$file.gm-event" + has_event=1 + else + has_event=0 + fi + + errf=`echo $full | sed -e 's#in.yaml#error#'` + if [ -e "$errf" ] ; then + expected_error="1" + has_error=1 + else + expected_error="0" + has_error=0 + fi + + jsonf=`echo $full | sed -e 's#in.yaml#in.json#'` + if [ -e "$jsonf" ]; then + ln -s `realpath "$jsonf"` "output/$file.json" + has_json=1 + # verify that the json file is a valid one + jsonlint-php -q "$jsonf" >/dev/null 2>&1 + if [ $? -eq 0 ]; then + has_good_json=1 + else + has_good_json=0 + fi + else + has_json=0 + has_good_json=1 + fi + + this_fail=0 + + a0="output/$file.event" + + # execute in testsuite event mode + pass_yaml=0 + if [[ $STDIN == 0 ]]; then + ${PARSER} "$f" > "$a0" 2> "output/$file.log" + else + cat "$f" | ${PARSER} > "$a0" 2> "output/$file.log" + fi + if [ $? -eq 0 ]; then pass_yaml=1; fi + + # compare output + diff_yaml=0 + diff -u "$a0" "$event" > "output/$file.diff" + if [ $? -eq 0 ]; then diff_yaml=1; fi + + if [ $expected_error -eq 0 ]; then + eexp="${GRN}e${NRM}" + else + eexp="${RED}E${NRM}" + fi + + if [[ $has_json == 1 && $has_good_json == 1 ]]; then + a1="output/$file.json.event" + + pass_json=0 + if [[ $STDIN == 0 ]]; then + ${PARSER} "$jsonf" > "$a1" 2> "output/$file.log" + else + cat "$jsonf" | ${PARSER} > "$a1" 2> "output/$file.log" + fi + if [ $? -eq 0 ]; then pass_json=1; fi + + # it is not possible to diff test.event again json + # because the json output does not contain anchor + # and tag information + else + pass_json=$(( ! ${expected_error})) + fi + + if [ $expected_error -eq 0 ]; then + # it fails if any fail + this_fail=$(($pass_yaml == 0 || $diff_yaml == 0 || $pass_json == 0)) + eexp="${GRN}e${NRM}" + else + # test expected to fail + this_fail=$(($pass_yaml == 1 || $pass_json == 1)) + eexp="${RED}E${NRM}" + fi + + if [[ $has_json == 1 && $has_good_json == 1 ]]; then + hjexp="${GRN}+${NRM}"; + elif [[ $has_json == 1 && $has_good_json == 0 ]]; then + hjexp="${CYN}!${NRM}"; + else + hjexp="-"; + fi + + if [[ $pass_yaml == 1 ]]; then + yexp="${GRN}Y${NRM}"; + else + yexp="${RED}y${NRM}"; + fi + + if [[ $diff_yaml == 1 ]]; then + dyexp="${GRN}D${NRM}"; + else + dyexp="${RED}d${NRM}"; + fi + + if [[ $has_json == 1 && $has_good_json == 1 ]]; then + if [[ $pass_json == 1 ]]; then + jexp="${GRN}J${NRM}"; + else + jexp="${RED}j${NRM}"; + fi + else + jexp="-" + fi + + if [ $this_fail -ne 0 ]; then + touch "output/$file.fail" + res="${RED}FAIL${NRM}" + fail=$(($fail + 1)) + else + touch "output/$file.pass" + res="${GRN}PASS${NRM}" + pass=$(($pass + 1)) + + if [[ $KEEP == 0 ]]; then + # remove intermediate files + rm -f "$f" "output/$file.pass" "output/$file.fail" \ + "output/$file.unknown" "output/$file.desc" \ + "output/$file.event" "output/$file.log" \ + "output/$file.gm-event" "output/$file.diff" \ + "output/$file.libyaml-event" \ + "output/$file.json" "output/$file.json.diff" \ + "output/$file.json.event" + fi + fi + + echo -e "${eexp}${yexp}${dyexp}${hjexp}${jexp} ${res} $file: $desctxt" +done + +echo +echo " PARSER: ${PARSER}" +echo -e " TOTAL: ${count}" +echo -e " PASS: ${GRN}${pass}${NRM}" +echo -e " FAIL: ${RED}${fail}${NRM}" +echo -e "UNKNOWN: ${GRY}${unknown}${NRM}" diff --git a/scripts/run-valgrind.sh b/scripts/run-valgrind.sh new file mode 100755 index 0000000..451c69d --- /dev/null +++ b/scripts/run-valgrind.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# LD_LIBRARY_PATH=${PWD}/src/.libs/ valgrind --leak-check=full ./src/.libs/libfyaml-parser -mscan "$1" 2>&1 | tee valgrind.log +LD_LIBRARY_PATH=${PWD}/src/.libs/ valgrind --track-origins=yes --leak-check=full --error-exitcode=5 ./src/.libs/libfyaml-parser $* 2>&1 | tee valgrind.log diff --git a/scripts/show-desc.sh b/scripts/show-desc.sh new file mode 100755 index 0000000..cec4f88 --- /dev/null +++ b/scripts/show-desc.sh @@ -0,0 +1,2 @@ +#!/bin/bash +for i in output/*.desc; do echo -n "$i: "; cat $i; done diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..67688a9 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,82 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/include +AM_CFLAGS = + +lib_LTLIBRARIES = libfyaml-@MAJOR@.@MINOR@.la +libfyaml_@MAJOR@_@MINOR@_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-list.h \ + lib/fy-typelist.h \ + lib/fy-diag.c lib/fy-diag.h \ + lib/fy-dump.c lib/fy-dump.h \ + lib/fy-atom.c lib/fy-atom.h \ + lib/fy-ctype.c lib/fy-ctype.h \ + lib/fy-token.c lib/fy-token.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-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 \ + xxhash/xxhash.c xxhash/xxhash.h \ + lib/fy-accel.c lib/fy-accel.h \ + lib/fy-walk.c lib/fy-walk.h \ + lib/fy-path.c lib/fy-path.h \ + lib/fy-composer.c lib/fy-composer.h + +libfyaml_@MAJOR@_@MINOR@_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 + +bin_PROGRAMS = +noinst_PROGRAMS = + +if HAVE_LIBYAML + +noinst_PROGRAMS += libfyaml-parser + +libfyaml_parser_SOURCES = \ + internal/libfyaml-parser.c \ + valgrind/fy-valgrind.h + +libfyaml_parser_CPPFLAGS = $(AM_CPPFLAGS) \ + -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_CFLAGS = $(AM_CFLAGS) $(LIBYAML_CFLAGS) + +libfyaml_parser_LDFLAGS = $(AM_LDFLAGS) +endif + +bin_PROGRAMS += fy-tool + +fy_tool_SOURCES = \ + tool/fy-tool.c \ + 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_CFLAGS = $(AM_CFLAGS) +fy_tool_LDFLAGS = $(AM_LDFLAGS) + +include_HEADERS = \ + $(top_srcdir)/include/libfyaml.h + +install-exec-hook: + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-dump) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-filter) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-testsuite) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-join) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-ypath) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-compose) + +uninstall-hook: + (cd "$(DESTDIR)$(bindir)" && rm -f fy-dump fy-filter fy-testsuite fy-join fy-ypath fy-compose) diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..65e9b36 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,1220 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = fy-tool$(EXEEXT) +noinst_PROGRAMS = $(am__EXEEXT_1) +@HAVE_LIBYAML_TRUE@am__append_1 = libfyaml-parser +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_enable_debug.m4 \ + $(top_srcdir)/m4/ax_check_flag.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 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libfyaml_@MAJOR@_@MINOR@_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_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 $@ +@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_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(fy_tool_CFLAGS) \ + $(CFLAGS) $(fy_tool_LDFLAGS) $(LDFLAGS) -o $@ +am__libfyaml_parser_SOURCES_DIST = internal/libfyaml-parser.c \ + valgrind/fy-valgrind.h +@HAVE_LIBYAML_TRUE@am_libfyaml_parser_OBJECTS = internal/libfyaml_parser-libfyaml-parser.$(OBJEXT) +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 +libfyaml_parser_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libfyaml_parser_CFLAGS) $(CFLAGS) $(libfyaml_parser_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +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) \ + $(libfyaml_parser_SOURCES) +DIST_SOURCES = $(libfyaml_@MAJOR@_@MINOR@_la_SOURCES) \ + $(fy_tool_SOURCES) $(am__libfyaml_parser_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(include_HEADERS) +am__extra_recursive_targets = doc-help-recursive doc-html-recursive \ + doc-latexpdf-recursive doc-man-recursive doc-clean-recursive \ + doc-markdown-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_MAKEFLAGS = @AM_MAKEFLAGS@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LDFLAGS = @CHECK_LDFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBVERSION = @DEBVERSION@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCKER = @DOCKER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA = @EXTRA@ +F77 = @F77@ +FC = @FC@ +FGREP = @FGREP@ +GIT = @GIT@ +GREP = @GREP@ +HAVE_CHECK = @HAVE_CHECK@ +HAVE_COMPATIBLE_CHECK = @HAVE_COMPATIBLE_CHECK@ +HAVE_LIBYAML = @HAVE_LIBYAML@ +HAVE_NETWORK = @HAVE_NETWORK@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JQ = @JQ@ +JSONTESTSUITECHECKOUT = @JSONTESTSUITECHECKOUT@ +JSONTESTSUITEURL = @JSONTESTSUITEURL@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ +LIBYAML_LIBS = @LIBYAML_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4 = @M4@ +MAJOR = @MAJOR@ +MAKEFLAGS = @MAKEFLAGS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MCS = @MCS@ +MINOR = @MINOR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATCH = @PATCH@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PIP3 = @PIP3@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +Q = @Q@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX = @SPHINX@ +STRIP = @STRIP@ +TESTSUITECHECKOUT = @TESTSUITECHECKOUT@ +TESTSUITEURL = @TESTSUITEURL@ +V = @V@ +VERSION = @VERSION@ +YACC = @YACC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +shavedir = @shavedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/include + +AM_CFLAGS = +lib_LTLIBRARIES = libfyaml-@MAJOR@.@MINOR@.la +libfyaml_@MAJOR@_@MINOR@_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-list.h \ + lib/fy-typelist.h \ + lib/fy-diag.c lib/fy-diag.h \ + lib/fy-dump.c lib/fy-dump.h \ + lib/fy-atom.c lib/fy-atom.h \ + lib/fy-ctype.c lib/fy-ctype.h \ + lib/fy-token.c lib/fy-token.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-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 \ + xxhash/xxhash.c xxhash/xxhash.h \ + lib/fy-accel.c lib/fy-accel.h \ + lib/fy-walk.c lib/fy-walk.h \ + lib/fy-path.c lib/fy-path.h \ + lib/fy-composer.c lib/fy-composer.h + +libfyaml_@MAJOR@_@MINOR@_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 + +@HAVE_LIBYAML_TRUE@libfyaml_parser_SOURCES = \ +@HAVE_LIBYAML_TRUE@ internal/libfyaml-parser.c \ +@HAVE_LIBYAML_TRUE@ valgrind/fy-valgrind.h + +@HAVE_LIBYAML_TRUE@libfyaml_parser_CPPFLAGS = $(AM_CPPFLAGS) \ +@HAVE_LIBYAML_TRUE@ -I$(top_srcdir)/src/valgrind \ +@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_CFLAGS = $(AM_CFLAGS) $(LIBYAML_CFLAGS) +@HAVE_LIBYAML_TRUE@libfyaml_parser_LDFLAGS = $(AM_LDFLAGS) +fy_tool_SOURCES = \ + tool/fy-tool.c \ + 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_CFLAGS = $(AM_CFLAGS) +fy_tool_LDFLAGS = $(AM_LDFLAGS) +include_HEADERS = \ + $(top_srcdir)/include/libfyaml.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +lib/$(am__dirstamp): + @$(MKDIR_P) lib + @: > lib/$(am__dirstamp) +lib/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) lib/$(DEPDIR) + @: > lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-parse.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utf8.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-types.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-diag.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-dump.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-atom.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-ctype.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-token.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-input.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-docstate.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-doc.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-emit.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-utils.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-event.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +xxhash/$(am__dirstamp): + @$(MKDIR_P) xxhash + @: > xxhash/$(am__dirstamp) +xxhash/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) xxhash/$(DEPDIR) + @: > xxhash/$(DEPDIR)/$(am__dirstamp) +xxhash/libfyaml_@MAJOR@_@MINOR@_la-xxhash.lo: xxhash/$(am__dirstamp) \ + xxhash/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-accel.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-walk.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_la-fy-path.lo: lib/$(am__dirstamp) \ + lib/$(DEPDIR)/$(am__dirstamp) +lib/libfyaml_@MAJOR@_@MINOR@_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) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +tool/$(am__dirstamp): + @$(MKDIR_P) tool + @: > tool/$(am__dirstamp) +tool/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tool/$(DEPDIR) + @: > tool/$(DEPDIR)/$(am__dirstamp) +tool/fy_tool-fy-tool.$(OBJEXT): tool/$(am__dirstamp) \ + tool/$(DEPDIR)/$(am__dirstamp) + +fy-tool$(EXEEXT): $(fy_tool_OBJECTS) $(fy_tool_DEPENDENCIES) $(EXTRA_fy_tool_DEPENDENCIES) + @rm -f fy-tool$(EXEEXT) + $(AM_V_CCLD)$(fy_tool_LINK) $(fy_tool_OBJECTS) $(fy_tool_LDADD) $(LIBS) +internal/$(am__dirstamp): + @$(MKDIR_P) internal + @: > internal/$(am__dirstamp) +internal/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) internal/$(DEPDIR) + @: > internal/$(DEPDIR)/$(am__dirstamp) +internal/libfyaml_parser-libfyaml-parser.$(OBJEXT): \ + internal/$(am__dirstamp) internal/$(DEPDIR)/$(am__dirstamp) + +libfyaml-parser$(EXEEXT): $(libfyaml_parser_OBJECTS) $(libfyaml_parser_DEPENDENCIES) $(EXTRA_libfyaml_parser_DEPENDENCIES) + @rm -f libfyaml-parser$(EXEEXT) + $(AM_V_CCLD)$(libfyaml_parser_LINK) $(libfyaml_parser_OBJECTS) $(libfyaml_parser_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f internal/*.$(OBJEXT) + -rm -f lib/*.$(OBJEXT) + -rm -f lib/*.lo + -rm -f tool/*.$(OBJEXT) + -rm -f xxhash/*.$(OBJEXT) + -rm -f xxhash/*.lo + +distclean-compile: + -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@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@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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@ +@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 + +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 +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tool/$(DEPDIR)/fy_tool-fy-tool.Tpo tool/$(DEPDIR)/fy_tool-fy-tool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tool/fy-tool.c' object='tool/fy_tool-fy-tool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fy_tool_CPPFLAGS) $(CPPFLAGS) $(fy_tool_CFLAGS) $(CFLAGS) -c -o tool/fy_tool-fy-tool.o `test -f 'tool/fy-tool.c' || echo '$(srcdir)/'`tool/fy-tool.c + +tool/fy_tool-fy-tool.obj: 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.obj -MD -MP -MF tool/$(DEPDIR)/fy_tool-fy-tool.Tpo -c -o tool/fy_tool-fy-tool.obj `if test -f 'tool/fy-tool.c'; then $(CYGPATH_W) 'tool/fy-tool.c'; else $(CYGPATH_W) '$(srcdir)/tool/fy-tool.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tool/$(DEPDIR)/fy_tool-fy-tool.Tpo tool/$(DEPDIR)/fy_tool-fy-tool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tool/fy-tool.c' object='tool/fy_tool-fy-tool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fy_tool_CPPFLAGS) $(CPPFLAGS) $(fy_tool_CFLAGS) $(CFLAGS) -c -o tool/fy_tool-fy-tool.obj `if test -f 'tool/fy-tool.c'; then $(CYGPATH_W) 'tool/fy-tool.c'; else $(CYGPATH_W) '$(srcdir)/tool/fy-tool.c'; fi` + +internal/libfyaml_parser-libfyaml-parser.o: internal/libfyaml-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_parser_CPPFLAGS) $(CPPFLAGS) $(libfyaml_parser_CFLAGS) $(CFLAGS) -MT internal/libfyaml_parser-libfyaml-parser.o -MD -MP -MF internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Tpo -c -o internal/libfyaml_parser-libfyaml-parser.o `test -f 'internal/libfyaml-parser.c' || echo '$(srcdir)/'`internal/libfyaml-parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Tpo internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='internal/libfyaml-parser.c' object='internal/libfyaml_parser-libfyaml-parser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_parser_CPPFLAGS) $(CPPFLAGS) $(libfyaml_parser_CFLAGS) $(CFLAGS) -c -o internal/libfyaml_parser-libfyaml-parser.o `test -f 'internal/libfyaml-parser.c' || echo '$(srcdir)/'`internal/libfyaml-parser.c + +internal/libfyaml_parser-libfyaml-parser.obj: internal/libfyaml-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_parser_CPPFLAGS) $(CPPFLAGS) $(libfyaml_parser_CFLAGS) $(CFLAGS) -MT internal/libfyaml_parser-libfyaml-parser.obj -MD -MP -MF internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Tpo -c -o internal/libfyaml_parser-libfyaml-parser.obj `if test -f 'internal/libfyaml-parser.c'; then $(CYGPATH_W) 'internal/libfyaml-parser.c'; else $(CYGPATH_W) '$(srcdir)/internal/libfyaml-parser.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Tpo internal/$(DEPDIR)/libfyaml_parser-libfyaml-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='internal/libfyaml-parser.c' object='internal/libfyaml_parser-libfyaml-parser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_parser_CPPFLAGS) $(CPPFLAGS) $(libfyaml_parser_CFLAGS) $(CFLAGS) -c -o internal/libfyaml_parser-libfyaml-parser.obj `if test -f 'internal/libfyaml-parser.c'; then $(CYGPATH_W) 'internal/libfyaml-parser.c'; else $(CYGPATH_W) '$(srcdir)/internal/libfyaml-parser.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf lib/.libs lib/_libs + -rm -rf xxhash/.libs xxhash/_libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) +doc-help-local: +doc-html-local: +doc-latexpdf-local: +doc-man-local: +doc-clean-local: +doc-markdown-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f internal/$(DEPDIR)/$(am__dirstamp) + -rm -f internal/$(am__dirstamp) + -rm -f lib/$(DEPDIR)/$(am__dirstamp) + -rm -f lib/$(am__dirstamp) + -rm -f tool/$(DEPDIR)/$(am__dirstamp) + -rm -f tool/$(am__dirstamp) + -rm -f xxhash/$(DEPDIR)/$(am__dirstamp) + -rm -f xxhash/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf internal/$(DEPDIR) lib/$(DEPDIR) tool/$(DEPDIR) xxhash/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +doc-clean: doc-clean-am + +doc-clean-am: doc-clean-local + +doc-help: doc-help-am + +doc-help-am: doc-help-local + +doc-html: doc-html-am + +doc-html-am: doc-html-local + +doc-latexpdf: doc-latexpdf-am + +doc-latexpdf-am: doc-latexpdf-local + +doc-man: doc-man-am + +doc-man-am: doc-man-local + +doc-markdown: doc-markdown-am + +doc-markdown-am: doc-markdown-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf internal/$(DEPDIR) lib/$(DEPDIR) tool/$(DEPDIR) xxhash/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-exec-am install-strip uninstall-am + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir doc-clean-am \ + doc-clean-local doc-help-am doc-help-local doc-html-am \ + doc-html-local doc-latexpdf-am doc-latexpdf-local doc-man-am \ + doc-man-local doc-markdown-am doc-markdown-local dvi dvi-am \ + html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-hook \ + install-html install-html-am install-includeHEADERS \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-hook \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +install-exec-hook: + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-dump) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-filter) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-testsuite) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-join) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-ypath) + (cd "$(DESTDIR)$(bindir)" && $(LN_S) -f fy-tool fy-compose) + +uninstall-hook: + (cd "$(DESTDIR)$(bindir)" && rm -f fy-dump fy-filter fy-testsuite fy-join fy-ypath fy-compose) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/internal/libfyaml-parser.c b/src/internal/libfyaml-parser.c new file mode 100644 index 0000000..3f8a5c3 --- /dev/null +++ b/src/internal/libfyaml-parser.c @@ -0,0 +1,4255 @@ +/* + * libfyaml-parser.c - swiss army knife testing of libfyaml+libyaml + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML +#include +#endif + +#include "fy-parse.h" +#include "fy-walk.h" + +#include "fy-valgrind.h" + +#include "xxhash.h" + +#define QUIET_DEFAULT false +#define INCLUDE_DEFAULT "" +#define MODE_DEFAULT "parse" +#define DEBUG_LEVEL_DEFAULT FYET_WARNING +#define INDENT_DEFAULT 2 +#define WIDTH_DEFAULT 80 +#define RESOLVE_DEFAULT false +#define SORT_DEFAULT false +#define CHUNK_DEFAULT 0 +#define COLOR_DEFAULT "auto" +#define MMAP_DISABLE_DEFAULT false + +#define OPT_DISABLE_MMAP 128 +#define OPT_USE_CALLBACK 129 +#define OPT_DISABLE_ACCEL 130 +#define OPT_DISABLE_BUFFERING 131 +#define OPT_DISABLE_DEPTH_LIMIT 132 +#define OPT_NULL_OUTPUT 133 + +#define OPT_SLOPPY_FLOW_INDENTATION 2007 +#define OPT_YPATH_ALIASES 2008 + +#define OPT_YAML_1_1 4000 +#define OPT_YAML_1_2 4001 +#define OPT_YAML_1_3 4002 + +static struct option lopts[] = { + {"include", required_argument, 0, 'I' }, + {"mode", required_argument, 0, 'm' }, + {"debug-level", required_argument, 0, 'd' }, + {"indent", required_argument, 0, 'i' }, + {"width", required_argument, 0, 'w' }, + {"resolve", no_argument, 0, 'r' }, + {"sort", no_argument, 0, 's' }, + {"chunk", required_argument, 0, 'c' }, + {"color", required_argument, 0, 'C' }, + {"diag", required_argument, 0, 'D' }, + {"module", required_argument, 0, 'M' }, + {"disable-mmap", no_argument, 0, OPT_DISABLE_MMAP }, + {"disable-accel", no_argument, 0, OPT_DISABLE_ACCEL }, + {"disable-buffering", no_argument, 0, OPT_DISABLE_BUFFERING }, + {"disable-depth-limit", no_argument, 0, OPT_DISABLE_DEPTH_LIMIT }, + {"use-callback", no_argument, 0, OPT_USE_CALLBACK }, + {"null-output", no_argument, 0, OPT_NULL_OUTPUT }, + {"walk-path", required_argument, 0, 'W' }, + {"walk-start", required_argument, 0, 'S' }, + {"yaml-1.1", no_argument, 0, OPT_YAML_1_1 }, + {"yaml-1.2", no_argument, 0, OPT_YAML_1_2 }, + {"yaml-1.3", no_argument, 0, OPT_YAML_1_3 }, + {"sloppy-flow-indentation", no_argument, 0, OPT_SLOPPY_FLOW_INDENTATION }, + {"ypath-aliases", no_argument, 0, OPT_YPATH_ALIASES }, + {"quiet", no_argument, 0, 'q' }, + {"help", no_argument, 0, 'h' }, + {0, 0, 0, 0 }, +}; + +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML +#define LIBYAML_MODES "|libyaml-scan|libyaml-parse|libyaml-testsuite|libyaml-dump|libyaml-diff" +#else +#define LIBYAML_MODES "" +#endif + +#define MODES "parse|scan|copy|testsuite|dump|dump2|build|walk|reader|compose|iterate|comment|pathspec" LIBYAML_MODES + +static void display_usage(FILE *fp, char *progname) +{ + fprintf(fp, "Usage: %s [options] [files]\n", progname); + fprintf(fp, "\nOptions:\n\n"); + fprintf(fp, "\t--include, -I : Add directory to include path " + " (default path \"%s\")\n", + INCLUDE_DEFAULT); + fprintf(fp, "\t--mode, -m : Set mode [" MODES "]" + " (default mode \"%s\")\n", + MODE_DEFAULT); + fprintf(fp, "\t--debug-level, -d : Set debug level to " + "(default level %d)\n", + DEBUG_LEVEL_DEFAULT); + fprintf(fp, "\t--indent, -i : Set dump indent to " + " (default indent %d)\n", + INDENT_DEFAULT); + fprintf(fp, "\t--width, -w : Set dump width to " + " (default width %d)\n", + WIDTH_DEFAULT); + fprintf(fp, "\t--resolve, -r : Perform anchor and merge key resolution" + " (default %s)\n", + RESOLVE_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--sort, -s : Perform mapping key sort (valid for dump)" + " (default %s)\n", + SORT_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--color, -C : Color output can be one of on, off, auto" + " (default %s)\n", + COLOR_DEFAULT); + fprintf(fp, "\t--chunk, -c : Set buffer chunk to " + " (default is %d - 0 means PAGE_SIZE)\n", + CHUNK_DEFAULT); + fprintf(fp, "\t--diag, -D : Set debug message diagnostic meta" + " (source, position, type, module, all, none)\n"); + fprintf(fp, "\t--module, -M : Set debug message module enable" + " (unknown, atom, scan, parse, doc, build, internal, system, all, none)\n"); + fprintf(fp, "\t--walk-path, -W : Walk path for work mode\n"); + fprintf(fp, "\t--quiet, -q : Quiet operation, do not " + "output messages (default %s)\n", + QUIET_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--help, -h : Display help message\n"); + fprintf(fp, "\ne.g. %s input.yaml\n", progname); + + if (fp == stderr) + exit(EXIT_FAILURE); +} + +void print_escaped(FILE *fp, const char *str, int length) +{ + fprintf(fp, "%s", fy_utf8_format_text_a(str, length, fyue_doublequote)); +} + +static int txt2esc_internal(const char *s, int l, char *out, int *outszp, int delim) +{ + const char *e; + int ll; + char c; + char *o = NULL, *oe = NULL; + + e = s + l; + if (out) { + o = out; + oe = o + *outszp; + } + +#define O_CH(_c) \ + do { \ + ll++; \ + if (o && (oe - o) > 0) \ + *o++ = (_c); \ + } while(0) + + ll = 0; + while (s < e) { + c = *s++; + if (delim > 0 && c == delim) { + O_CH('\\'); + } else if (c == '\0' || strchr("\a\b\t\n\v\f\r\e", c)) { + /* normal 1 -> 2 character escapes */ + O_CH('\\'); + switch (c) { + case '\0': + c = '0'; + break; + case '\a': + c = 'a'; + break; + case '\b': + c = 'b'; + break; + case '\t': + c = 't'; + break; + case '\n': + c = 'n'; + break; + case '\v': + c = 'v'; + break; + case '\f': + c = 'f'; + break; + case '\r': + c = 'r'; + break; + case '\e': + c = 'e'; + break; + } + } else if ((e - s) >= 1 && (uint8_t)c == 0xc2 && + ((uint8_t)s[1] == 0x85 || (uint8_t)s[1] == 0xa0)) { + /* \N & \_ unicode escapes 2 -> 1 */ + O_CH('\\'); + if ((uint8_t)s[1] == 0x85) + c = 'N'; + else + c = '_'; + } else if ((e - s) >= 2 && (uint8_t)c == 0xe2 && (uint8_t)s[1] == 0x80 && + ((uint8_t)s[2] == 0xa8 || (uint8_t)s[2] == 0xa9)) { + /* \L & \P unicode escapes 3 -> 1 */ + O_CH('\\'); + if ((uint8_t)s[2] == 0xa8) + c = 'L'; + else + c = 'P'; + } + O_CH(c); + } + /* terminating \0 */ + O_CH('\0'); + + if (out) + *outszp = oe - o; + + return ll; +} + +static int txt2esc_length(const char *s, int l, int delim) +{ + if (l < 0) + l = strlen(s); + return txt2esc_internal(s, l, NULL, NULL, delim); +} + +static char *txt2esc_format(const char *s, int l, char *buf, int maxsz, int delim) +{ + if (l < 0) + l = strlen(s); + + txt2esc_internal(s, l, buf, &maxsz, delim); + return buf; +} + +#define fy_atom_get_text_a(_atom) \ + ({ \ + struct fy_atom *_a = (_atom); \ + int _len; \ + char *_buf; \ + const char *_txt = ""; \ + \ + if (!_a->direct_output) { \ + _len = fy_atom_format_text_length(_a); \ + if (_len > 0) { \ + _buf = alloca(_len + 1); \ + memset(_buf, 0, _len + 1); \ + fy_atom_format_text(_a, _buf, _len + 1); \ + _buf[_len] = '\0'; \ + _txt = _buf; \ + } \ + } else { \ + _len = fy_atom_size(_a); \ + _buf = alloca(_len + 1); \ + memset(_buf, 0, _len + 1); \ + memcpy(_buf, fy_atom_data(_a), _len); \ + _buf[_len] = '\0'; \ + _txt = _buf; \ + } \ + _txt; \ + }) + +#define txt2esc_a(_s, _l) \ + ({ \ + const char *__s = (const void *)(_s); \ + int __l = (_l); \ + int _ll = txt2esc_length(__s, __l, '\''); \ + txt2esc_format(__s, __l, alloca(_ll + 1), _ll + 1, '\''); \ + }) + +#define fy_atom_get_esc_text_a(_atom) txt2esc_a(fy_atom_get_text_a(_atom), -1) +#define fy_token_get_esc_text_a(_atom) txt2esc_a(fy_token_get_text0(_atom), -1) + +void dump_event(struct fy_parser *fyp, struct fy_event *fye) +{ + char mbuf[40]; + char *mm; + char *anchor = NULL, *tag = NULL, *value = NULL; + + snprintf(mbuf, sizeof(mbuf), " %10s-%-10s ", + "", ""); + mm = mbuf; + mm = " "; + + switch (fye->type) { + case FYET_NONE: + printf("NO\n"); + break; + case FYET_STREAM_START: + printf("%-14s%s|\n", "STREAM_START", mm); + break; + case FYET_STREAM_END: + printf("%-14s%s|\n", "STREAM_END", mm); + break; + case FYET_DOCUMENT_START: + printf("%-14s%s|\n", "DOCUMENT_START", mm); + break; + case FYET_DOCUMENT_END: + printf("%-14s%s|\n", "DOCUMENT_END", mm); + break; + case FYET_ALIAS: + anchor = fy_token_get_esc_text_a(fye->alias.anchor); + printf("%-14s%s| '%s'\n", "ALIAS", mm, anchor); + break; + case FYET_SCALAR: + if (fye->scalar.anchor) + anchor = fy_token_get_esc_text_a(fye->scalar.anchor); + if (fye->scalar.tag) + tag = fy_token_get_esc_text_a(fye->scalar.tag); + if (fye->scalar.value) + value = fy_token_get_esc_text_a(fye->scalar.value); + printf("%-14s%s|%s%s%s%s%s%s '%s'\n", "SCALAR", mm, + anchor ? " anchor='" : "", anchor ? : "", anchor ? "'" : "", + tag ? " tag='" : "", tag ? : "", tag ? "'" : "", + value ? : ""); + break; + case FYET_SEQUENCE_START: + if (fye->sequence_start.anchor) + anchor = fy_token_get_esc_text_a(fye->sequence_start.anchor); + if (fye->sequence_start.tag) + tag = fy_token_get_esc_text_a(fye->sequence_start.tag); + printf("%-14s%s|%s%s%s%s%s%s\n", "SEQUENCE_START", mm, + anchor ? " anchor='" : "", anchor ? : "", anchor ? "'" : "", + tag ? " tag='" : "", tag ? : "", tag ? "'" : ""); + break; + case FYET_SEQUENCE_END: + printf("%-14s%s|\n", "SEQUENCE_END", mm); + break; + case FYET_MAPPING_START: + if (fye->mapping_start.anchor) + anchor = fy_token_get_esc_text_a(fye->mapping_start.anchor); + if (fye->mapping_start.tag) + tag = fy_token_get_esc_text_a(fye->mapping_start.tag); + printf("%-14s%s|%s%s%s%s%s%s\n", "MAPPING_START", mm, + anchor ? " anchor='" : "", anchor ? : "", anchor ? "'" : "", + tag ? " tag='" : "", tag ? : "", tag ? "'" : ""); + break; + case FYET_MAPPING_END: + printf("%-14s%s|\n", "MAPPING_END", mm); + break; + default: + assert(0); + } +} + +int do_parse(struct fy_parser *fyp) +{ + struct fy_eventp *fyep; + + while ((fyep = fy_parse_private(fyp)) != NULL) { + dump_event(fyp, &fyep->e); + fy_parse_eventp_recycle(fyp, fyep); + } + + return fyp->stream_error ? -1 : 0; +} + +void dump_testsuite_event(FILE *fp, struct fy_parser *fyp, struct fy_event *fye) +{ + const char *anchor = NULL, *tag = NULL, *value = NULL; + size_t anchor_len = 0, tag_len = 0, value_len = 0; + enum fy_scalar_style style; + + switch (fye->type) { + case FYET_NONE: + fprintf(fp, "???\n"); + break; + case FYET_STREAM_START: + fprintf(fp, "+STR\n"); + break; + case FYET_STREAM_END: + fprintf(fp, "-STR\n"); + break; + case FYET_DOCUMENT_START: + fprintf(fp, "+DOC%s\n", !fy_document_event_is_implicit(fye) ? " ---" : ""); + break; + case FYET_DOCUMENT_END: + fprintf(fp, "-DOC%s\n", !fy_document_event_is_implicit(fye) ? " ..." : ""); + break; + case FYET_MAPPING_START: + if (fye->mapping_start.anchor) + anchor = fy_token_get_text(fye->mapping_start.anchor, &anchor_len); + if (fye->mapping_start.tag) + tag = fy_token_get_text(fye->mapping_start.tag, &tag_len); + fprintf(fp, "+MAP"); + if (anchor) + fprintf(fp, " &%.*s", (int)anchor_len, anchor); + if (tag) + fprintf(fp, " <%.*s>", (int)tag_len, tag); + fprintf(fp, "\n"); + break; + case FYET_MAPPING_END: + fprintf(fp, "-MAP\n"); + break; + case FYET_SEQUENCE_START: + if (fye->sequence_start.anchor) + anchor = fy_token_get_text(fye->sequence_start.anchor, &anchor_len); + if (fye->sequence_start.tag) + tag = fy_token_get_text(fye->sequence_start.tag, &tag_len); + fprintf(fp, "+SEQ"); + if (anchor) + fprintf(fp, " &%.*s", (int)anchor_len, anchor); + if (tag) + fprintf(fp, " <%.*s>", (int)tag_len, tag); + fprintf(fp, "\n"); + break; + case FYET_SEQUENCE_END: + fprintf(fp, "-SEQ\n"); + break; + case FYET_SCALAR: + if (fye->scalar.anchor) + anchor = fy_token_get_text(fye->scalar.anchor, &anchor_len); + if (fye->scalar.tag) + tag = fy_token_get_text(fye->scalar.tag, &tag_len); + + if (fye->scalar.value) + value = fy_token_get_text(fye->scalar.value, &value_len); + + fprintf(fp, "=VAL"); + if (anchor) + fprintf(fp, " &%.*s", (int)anchor_len, anchor); + if (tag) + fprintf(fp, " <%.*s>", (int)tag_len, tag); + + style = fy_token_scalar_style(fye->scalar.value); + switch (style) { + case FYAS_PLAIN: + fprintf(fp, " :"); + break; + case FYAS_SINGLE_QUOTED: + fprintf(fp, " '"); + break; + case FYAS_DOUBLE_QUOTED: + fprintf(fp, " \""); + break; + case FYAS_LITERAL: + fprintf(fp, " |"); + break; + case FYAS_FOLDED: + fprintf(fp, " >"); + break; + default: + abort(); + } + print_escaped(fp, value, value_len); + fprintf(fp, "\n"); + break; + case FYET_ALIAS: + anchor = fy_token_get_text(fye->alias.anchor, &anchor_len); + fprintf(fp, "=ALI *%.*s\n", (int)anchor_len, anchor); + break; + default: + assert(0); + } +} + +int do_testsuite(FILE *fp, struct fy_parser *fyp, bool null_output) +{ + struct fy_eventp *fyep; + + while ((fyep = fy_parse_private(fyp)) != NULL) { + if (!null_output) + dump_testsuite_event(fp, fyp, &fyep->e); + fy_parse_eventp_recycle(fyp, fyep); + } + + return fyp->stream_error ? -1 : 0; +} + +static void dump_token(struct fy_token *fyt) +{ + const char *style; + const struct fy_version *vers; + const char *handle, *prefix, *suffix; + const char *typetxt; + + typetxt = fy_token_type_txt[fyt->type]; + assert(typetxt); + + switch (fyt->type) { + case FYTT_VERSION_DIRECTIVE: + vers = fy_version_directive_token_version(fyt); + assert(vers); + printf("%s value=%d.%d\n", typetxt, + vers->major, vers->minor); + break; + case FYTT_TAG_DIRECTIVE: + handle = fy_tag_directive_token_handle0(fyt); + if (!handle) + handle = ""; + prefix = fy_tag_directive_token_prefix0(fyt); + if (!prefix) + prefix = ""; + printf("%s handle='%s' prefix='%s'\n", typetxt, + txt2esc_a(handle, -1), + txt2esc_a(prefix, -1)); + break; + case FYTT_ALIAS: + printf("%s value='%s'\n", typetxt, + fy_atom_get_esc_text_a(&fyt->handle)); + break; + case FYTT_ANCHOR: + printf("%s value='%s'\n", typetxt, + fy_atom_get_esc_text_a(&fyt->handle)); + break; + case FYTT_TAG: + handle = fy_tag_token_handle0(fyt); + if (!handle) + handle = ""; + suffix = fy_tag_token_suffix0(fyt); + if (!suffix) + suffix = ""; + printf("%s handle='%s' suffix='%s'\n", typetxt, + txt2esc_a(handle, -1), + txt2esc_a(suffix, -1)); + break; + case FYTT_SCALAR: + switch (fy_token_scalar_style(fyt)) { + case FYSS_ANY: + style = "ANY"; + break; + case FYSS_PLAIN: + style = "PLAIN"; + break; + case FYSS_SINGLE_QUOTED: + style = "SINGLE_QUOTED"; + break; + case FYSS_DOUBLE_QUOTED: + style = "DOUBLE_QUOTED"; + break; + case FYSS_LITERAL: + style = "LITERAL"; + break; + case FYSS_FOLDED: + style = "FOLDED"; + break; + default: + style = "*illegal*"; + break; + } + printf("%s value='%s' style=%s\n", typetxt, + fy_atom_get_esc_text_a(&fyt->handle), + style); + break; + + case FYTT_INPUT_MARKER: + printf("%s value='%s'\n", typetxt, + fy_atom_get_esc_text_a(&fyt->handle)); + break; + + case FYTT_PE_MAP_KEY: + printf("%s value='%s'\n", typetxt, + fy_atom_get_esc_text_a(&fyt->handle)); + break; + + case FYTT_PE_SEQ_INDEX: + printf("%s value=%d\n", typetxt, + fyt->seq_index.index); + break; + + case FYTT_PE_SEQ_SLICE: + printf("%s value=%d:%d\n", typetxt, + fyt->seq_slice.start_index, fyt->seq_slice.end_index); + break; + + case FYTT_PE_ALIAS: + printf("%s value='%s'\n", "PE-ALIAS", + fy_atom_get_esc_text_a(&fyt->handle)); + break; + + default: + printf("%s\n", typetxt); + break; + } +} + +int do_scan(struct fy_parser *fyp) +{ + struct fy_token *fyt; + + while ((fyt = fy_scan(fyp)) != NULL) { + dump_token(fyt); + fy_token_unref(fyt); + } + + return 0; +} + +int do_copy(struct fy_parser *fyp) +{ + int c, count, line, column; + char buf[5], *s; + const char *str; + + count = 0; + for (;;) { + line = fyp_line(fyp); + column = fyp_column(fyp); + + c = fy_parse_get(fyp); + if (c < 0) { + break; + } + if (c == '\\') { + str = "\\\\"; + } else if (c == '\0') { + str = "\\0"; + } else if (c == '"') { + str = "\\\""; + } else if (c == '\b') { + str = "\\b"; + } else if (c == '\r') { + str = "\\r"; + } else if (c == '\t') { + str = "\\t"; + } else if (c == '\n') { + str = "\\n"; + } else { + s = buf; + if (c < 0x80) + *s++ = c; + else if (c < 0x800) { + *s++ = (c >> 6) | 0xc0; + *s++ = (c & 0x3f) | 0x80; + } else if (c < 0x10000) { + *s++ = (c >> 12) | 0xe0; + *s++ = ((c >> 6) & 0x3f) | 0x80; + *s++ = (c & 0x3f) | 0x80; + } else { + *s++ = (c >> 18) | 0xf0; + *s++ = ((c >> 12) & 0x3f) | 0x80; + *s++ = ((c >> 6) & 0x3f) | 0x80; + *s++ = (c & 0x3f) | 0x80; + } + *s = '\0'; + str = buf; + } + + printf("[%2d,%2d] = \"%s\"\n", line, column, str); + + count++; + } + printf("\ncount=%d\n", count); + + return 0; +} + +int do_dump(struct fy_parser *fyp, int indent, int width, bool resolve, bool sort, bool null_output) +{ + struct fy_document *fyd; + unsigned int flags; + int rc, count; + + flags = 0; + if (sort) + flags |= FYECF_SORT_KEYS; + flags |= FYECF_INDENT(indent) | FYECF_WIDTH(width); + + count = 0; + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + if (resolve) { + rc = fy_document_resolve(fyd); + if (rc) + return -1; + } + + if (!null_output) + fy_emit_document_to_file(fyd, flags, NULL); + + fy_parse_document_destroy(fyp, fyd); + + count++; + } + + return count > 0 ? 0 : -1; +} + +int do_dump2(struct fy_parser *fyp, int indent, int width, bool resolve, bool sort, bool null_output) +{ + struct fy_document *fyd; + struct fy_document_builder *fydb; + unsigned int flags; + int rc, count; + + flags = 0; + if (sort) + flags |= FYECF_SORT_KEYS; + flags |= FYECF_INDENT(indent) | FYECF_WIDTH(width); + + fydb = fy_document_builder_create(&fyp->cfg); + assert(fydb); + + count = 0; + while ((fyd = fy_document_builder_load_document(fydb, fyp)) != NULL) { + + if (resolve) { + rc = fy_document_resolve(fyd); + if (rc) + goto out; + } + + fy_emit_document_to_file(fyd, flags, NULL); + + fy_parse_document_destroy(fyp, fyd); + + count++; + } + + fy_document_builder_destroy(fydb); + +out: + return count > 0 ? 0 : -1; +} + +struct composer_data { + struct fy_parser *fyp; + struct fy_document *fyd; + bool null_output; + bool document_ready; + bool single_document; +}; + +static enum fy_composer_return +process_event(struct fy_parser *fyp, struct fy_event *fye, struct fy_path *path, void *userdata) +{ + struct composer_data *cd = userdata; + struct fy_document *fyd; + struct fy_path_component *parent, *last; + struct fy_node *fyn, *fyn_parent; + struct fy_node_pair *fynp; + char tbuf[80]; + int rc; + + if (cd->null_output) + return FYCR_OK_CONTINUE; + + fyp_info(fyp, "%s: %c%c%c%c%c %3d - %-32s: %s\n", fy_event_type_txt[fye->type], + fy_path_in_root(path) ? 'R' : '-', + fy_path_in_sequence(path) ? 'S' : '-', + 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_depth(path), + fy_path_get_text_alloca(path), + fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf))); + + switch (fye->type) { + /* nothing to do for those */ + case FYET_NONE: + case FYET_STREAM_START: + case FYET_STREAM_END: + break; + + case FYET_DOCUMENT_START: + if (cd->fyd) { + fy_document_destroy(cd->fyd); + cd->fyd = NULL; + } + cd->document_ready = false; + + cd->fyd = fy_document_create_from_event(fyp, fye); + fyp_error_check(fyp, cd->fyd, err_out, + "fy_document_create_from_event() failed"); + + break; + + case FYET_DOCUMENT_END: + rc = fy_document_update_from_event(cd->fyd, fyp, fye); + fyp_error_check(fyp, !rc, err_out, + "fy_document_update_from_event() failed"); + + cd->document_ready = true; + /* on single document mode we stop here */ + if (cd->single_document) + return FYCR_OK_STOP; + break; + + + case FYET_SCALAR: + case FYET_ALIAS: + case FYET_MAPPING_START: + case FYET_SEQUENCE_START: + + fyd = cd->fyd; + assert(fyd); + + fyn = fy_node_create_from_event(fyd, fyp, fye); + fyp_error_check(fyp, fyn, err_out, + "fy_node_create_from_event() failed"); + + switch (fye->type) { + default: + /* XXX should now happen */ + break; + + case FYET_SCALAR: + case FYET_ALIAS: + last = NULL; + break; + + case FYET_MAPPING_START: + last = fy_path_last_component(path); + assert(last); + + fy_path_component_set_mapping_user_data(last, fyn); + fy_path_component_set_mapping_key_user_data(last, NULL); + + break; + + case FYET_SEQUENCE_START: + + last = fy_path_last_component(path); + assert(last); + + fy_path_component_set_sequence_user_data(last, fyn); + break; + } + + /* parent */ + parent = fy_path_last_not_collection_root_component(path); + + if (fy_path_in_root(path)) { + + rc = fy_document_set_root(cd->fyd, fyn); + fyp_error_check(fyp, !rc, err_out, + "fy_document_set_root() failed"); + + } else if (fy_path_in_sequence(path)) { + + assert(parent); + fyn_parent = fy_path_component_get_sequence_user_data(parent); + assert(fyn_parent); + assert(fy_node_is_sequence(fyn_parent)); + + rc = fy_node_sequence_add_item(fyn_parent, fyn); + fyp_error_check(fyp, !rc, err_out, + "fy_node_sequence_add_item() failed"); + + } else { + /* only thing left */ + assert(fy_path_in_mapping(path)); + + assert(parent); + fyn_parent = fy_path_component_get_mapping_user_data(parent); + assert(fyn_parent); + assert(fy_node_is_mapping(fyn_parent)); + + if (fy_path_in_mapping_key(path)) { + + fynp = fy_node_pair_create_with_key(fyd, fyn_parent, fyn); + fyp_error_check(fyp, fynp, err_out, + "fy_node_pair_create_with_key() failed"); + + fy_path_component_set_mapping_key_user_data(parent, fynp); + + } else { + + assert(fy_path_in_mapping_value(path)); + + fynp = fy_path_component_get_mapping_key_user_data(parent); + assert(fynp); + + rc = fy_node_pair_update_with_value(fynp, fyn); + fyp_error_check(fyp, !rc, err_out, + "fy_node_pair_update_with_value() failed"); + + fy_path_component_set_mapping_key_user_data(parent, NULL); + } + } + + break; + + case FYET_MAPPING_END: + last = fy_path_last_component(path); + assert(last); + + fyn = fy_path_component_get_mapping_user_data(last); + assert(fyn); + assert(fy_node_is_mapping(fyn)); + + rc = fy_node_update_from_event(fyn, fyp, fye); + fyp_error_check(fyp, !rc, err_out, + "fy_node_update_from_event() failed"); + + break; + + case FYET_SEQUENCE_END: + last = fy_path_last_component(path); + assert(last); + + fyn = fy_path_component_get_sequence_user_data(last); + assert(fyn); + assert(fy_node_is_sequence(fyn)); + + rc = fy_node_update_from_event(fyn, fyp, fye); + fyp_error_check(fyp, !rc, err_out, + "fy_node_update_from_event() failed"); + + break; + } + + return FYCR_OK_CONTINUE; + +err_out: + return FYCR_ERROR; +} + +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; + + rc = fy_parse_compose(fyp, process_event, &cd); + if (rc == 0 && cd.fyd) + fy_document_default_emit_to_fp(cd.fyd, stdout); + + fy_document_destroy(cd.fyd); + + return 0; +} + +struct fy_node * +fy_node_get_root(struct fy_node *fyn) +{ + if (!fyn) + return NULL; + while (fyn->parent) + fyn = fyn->parent; + return fyn; +} + +bool +fy_node_belongs_to_key(struct fy_document *fyd, struct fy_node *fyn) +{ + return fyd->root != fy_node_get_root(fyn); +} + +int do_iterate(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; + 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); + + count = 0; + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + fprintf(stderr, "> Start\n"); + fy_node_iterator_start(&ni, fy_document_root(fyd)); + fyn = NULL; + while ((fyn = fy_node_iterator_next(&ni, fyn)) != NULL) { + + belongs_to_key = fy_node_belongs_to_key(fyd, fyn); + path = fy_node_get_path(fyn); + if (fy_node_is_scalar(fyn)) { + text = fy_node_get_scalar(fyn, &len); + assert(text); + fy_utf8_format_text(text, len, textbuf, sizeof(textbuf), fyue_doublequote); + if (!fy_node_is_alias(fyn)) + fprintf(stderr, "%40s \"%s\"%s\n", path, textbuf, belongs_to_key ? " KEY" : ""); + else + fprintf(stderr, "%40s *%s%s\n", path, textbuf, belongs_to_key ? " KEY" : ""); + } else if (fy_node_is_sequence(fyn)) { + fprintf(stderr, "%40s [%s\n", path, belongs_to_key ? " KEY" : ""); + } else if (fy_node_is_mapping(fyn)) { + fprintf(stderr, "%40s {%s\n", path, belongs_to_key ? " KEY" : ""); + } + + 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); + + 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; + char *path; + struct fy_token *fyt; + struct fy_atom *handle; + enum fy_comment_placement placement; + 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); + + count = 0; + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + fy_node_iterator_start(&ni, fy_document_root(fyd)); + fyn = NULL; + while ((fyn = fy_node_iterator_next(&ni, fyn)) != NULL) { + + if (!fy_node_is_scalar(fyn)) + continue; + + fyt = fy_node_get_scalar_token(fyn); + if (!fyt || !fy_token_has_any_comment(fyt)) + continue; + + path = fy_node_get_path(fyn); + + fprintf(stderr, "scalar at %s\n", path); + for (placement = fycp_top; placement < fycp_max; placement++) { + handle = fy_token_comment_handle(fyt, placement, false); + if (!handle || !fy_atom_is_set(handle)) + continue; + + if (!fy_token_get_comment(fyt, buf, sizeof(buf), placement)) + continue; + + fprintf(stderr, "%s: %s\n", placement_txt[placement], buf); + } + + 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); + + return count > 0 ? 0 : -1; +} + +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML + +void dump_libyaml_token(yaml_token_t *token) +{ + const char *style; + + switch (token->type) { + case YAML_NO_TOKEN: + printf("NO\n"); + break; + case YAML_STREAM_START_TOKEN: + printf("STREAM_START\n"); + break; + case YAML_STREAM_END_TOKEN: + printf("STREAM_END\n"); + break; + case YAML_VERSION_DIRECTIVE_TOKEN: + printf("VERSION_DIRECTIVE value=%d.%d\n", + token->data.version_directive.major, + token->data.version_directive.minor); + break; + case YAML_TAG_DIRECTIVE_TOKEN: + printf("TAG_DIRECTIVE handle='%s' prefix='%s'\n", + txt2esc_a(token->data.tag_directive.handle, -1), + txt2esc_a(token->data.tag_directive.prefix, -1)); + break; + case YAML_DOCUMENT_START_TOKEN: + printf("DOCUMENT_START\n"); + break; + case YAML_DOCUMENT_END_TOKEN: + printf("DOCUMENT_END\n"); + break; + case YAML_BLOCK_SEQUENCE_START_TOKEN: + printf("BLOCK_SEQUENCE_START\n"); + break; + case YAML_BLOCK_MAPPING_START_TOKEN: + printf("BLOCK_MAPPING_START\n"); + break; + case YAML_BLOCK_END_TOKEN: + printf("BLOCK_END\n"); + break; + case YAML_FLOW_SEQUENCE_START_TOKEN: + printf("FLOW_SEQUENCE_START\n"); + break; + case YAML_FLOW_SEQUENCE_END_TOKEN: + printf("FLOW_SEQUENCE_END\n"); + break; + case YAML_FLOW_MAPPING_START_TOKEN: + printf("FLOW_MAPPING_START\n"); + break; + case YAML_FLOW_MAPPING_END_TOKEN: + printf("FLOW_MAPPING_END\n"); + break; + case YAML_BLOCK_ENTRY_TOKEN: + printf("BLOCK_ENTRY\n"); + break; + case YAML_FLOW_ENTRY_TOKEN: + printf("FLOW_ENTRY\n"); + break; + case YAML_KEY_TOKEN: + printf("KEY\n"); + break; + case YAML_VALUE_TOKEN: + printf("VALUE\n"); + break; + case YAML_ALIAS_TOKEN: + printf("ALIAS value='%s'\n", + txt2esc_a(token->data.alias.value, -1)); + break; + case YAML_ANCHOR_TOKEN: + printf("ANCHOR value='%s'\n", + txt2esc_a(token->data.anchor.value, -1)); + break; + case YAML_TAG_TOKEN: + printf("TAG handle='%s' suffix='%s'\n", + txt2esc_a(token->data.tag.handle, -1), + txt2esc_a(token->data.tag.suffix, -1)); + break; + case YAML_SCALAR_TOKEN: + switch (token->data.scalar.style) { + case YAML_ANY_SCALAR_STYLE: + style = "ANY"; + break; + case YAML_PLAIN_SCALAR_STYLE: + style = "PLAIN"; + break; + case YAML_SINGLE_QUOTED_SCALAR_STYLE: + style = "SINGLE_QUOTED"; + break; + case YAML_DOUBLE_QUOTED_SCALAR_STYLE: + style = "DOUBLE_QUOTED"; + break; + case YAML_LITERAL_SCALAR_STYLE: + style = "LITERAL"; + break; + case YAML_FOLDED_SCALAR_STYLE: + style = "FOLDED"; + break; + default: + style = "*ERROR*"; + break; + } + printf("SCALAR value='%s' style=%s\n", + txt2esc_a(token->data.scalar.value, token->data.scalar.length), + style); + break; + } +} + +int do_libyaml_scan(yaml_parser_t *parser) +{ + yaml_token_t token; + int done = 0; + + while (!done) + { + if (!yaml_parser_scan(parser, &token)) + return -1; + + dump_libyaml_token(&token); + + done = (token.type == YAML_STREAM_END_TOKEN); + + yaml_token_delete(&token); + } + + return 0; +} + +#define mark_a(_m) \ + ({ \ + yaml_mark_t *__m = (_m); \ + char *_s = alloca(30); \ + snprintf(_s, 30, "%zu/%zu/%zu", __m->index, __m->line, __m->column); \ + _s; \ + }) + +void dump_libyaml_event(yaml_event_t *event) +{ + char mbuf[40]; + char *mm; + char *anchor = NULL, *tag = NULL, *value = NULL; + + snprintf(mbuf, sizeof(mbuf), " %10s-%-10s ", + mark_a(&event->start_mark), + mark_a(&event->end_mark)); + mm = mbuf; + mm = " "; + + switch (event->type) { + case YAML_NO_EVENT: + printf("NO\n"); + break; + case YAML_STREAM_START_EVENT: + printf("%-14s%s|\n", "STREAM_START", mm); + break; + case YAML_STREAM_END_EVENT: + printf("%-14s%s|\n", "STREAM_END", mm); + break; + case YAML_DOCUMENT_START_EVENT: + printf("%-14s%s|\n", "DOCUMENT_START", mm); + break; + case YAML_DOCUMENT_END_EVENT: + printf("%-14s%s|\n", "DOCUMENT_END", mm); + break; + case YAML_ALIAS_EVENT: + anchor = txt2esc_a((char *)event->data.alias.anchor, -1); + printf("%-14s%s| '%s'\n", "ALIAS", mm, anchor); + break; + case YAML_SCALAR_EVENT: + if (event->data.scalar.anchor) + anchor = txt2esc_a((char *)event->data.scalar.anchor, -1); + if (event->data.scalar.tag) + tag = txt2esc_a((char *)event->data.scalar.tag, -1); + value = txt2esc_a((char *)event->data.scalar.value, -1); + printf("%-14s%s|%s%s%s%s%s%s '%s'\n", "SCALAR", mm, + anchor ? " anchor='" : "", anchor ? : "", anchor ? "'" : "", + tag ? " tag='" : "", tag ? : "", tag ? "'" : "", + value); + break; + case YAML_SEQUENCE_START_EVENT: + if (event->data.sequence_start.anchor) + anchor = txt2esc_a((char *)event->data.sequence_start.anchor, -1); + if (event->data.sequence_start.tag) + tag = txt2esc_a((char *)event->data.sequence_start.tag, -1); + printf("%-14s%s|%s%s%s%s%s%s\n", "SEQUENCE_START", mm, + anchor ? " anchor='" : "", anchor ? : "", anchor ? "'" : "", + tag ? " tag='" : "", tag ? : "", tag ? "'" : ""); + break; + case YAML_SEQUENCE_END_EVENT: + printf("%-14s%s|\n", "SEQUENCE_END", mm); + break; + case YAML_MAPPING_START_EVENT: + if (event->data.mapping_start.anchor) + anchor = txt2esc_a((char *)event->data.mapping_start.anchor, -1); + if (event->data.mapping_start.tag) + tag = txt2esc_a((char *)event->data.mapping_start.tag, -1); + printf("%-14s%s|%s%s%s%s%s%s\n", "MAPPING_START", mm, + anchor ? " anchor='" : "", anchor ? : "", anchor ? "'" : "", + tag ? " tag='" : "", tag ? : "", tag ? "'" : ""); + break; + case YAML_MAPPING_END_EVENT: + printf("%-14s%s|\n", "MAPPING_END", mm); + break; + default: + assert(0); + } +} + +int do_libyaml_parse(yaml_parser_t *parser) +{ + yaml_event_t event; + int done = 0; + + while (!done) + { + if (!yaml_parser_parse(parser, &event)) + return -1; + + dump_libyaml_event(&event); + + done = (event.type == YAML_STREAM_END_EVENT); + + yaml_event_delete(&event); + } + + return 0; +} + +void dump_libyaml_testsuite_event(FILE *fp, yaml_event_t *event) +{ + switch (event->type) { + case YAML_NO_EVENT: + fprintf(fp, "???\n"); + break; + case YAML_STREAM_START_EVENT: + fprintf(fp, "+STR\n"); + break; + case YAML_STREAM_END_EVENT: + fprintf(fp, "-STR\n"); + break; + case YAML_DOCUMENT_START_EVENT: + fprintf(fp, "+DOC"); + if (!event->data.document_start.implicit) + fprintf(fp, " ---"); + fprintf(fp, "\n"); + break; + case YAML_DOCUMENT_END_EVENT: + fprintf(fp, "-DOC"); + if (!event->data.document_end.implicit) + fprintf(fp, " ..."); + fprintf(fp, "\n"); + break; + case YAML_MAPPING_START_EVENT: + fprintf(fp, "+MAP"); + if (event->data.mapping_start.anchor) + fprintf(fp, " &%s", event->data.mapping_start.anchor); + if (event->data.mapping_start.tag) + fprintf(fp, " <%s>", event->data.mapping_start.tag); + fprintf(fp, "\n"); + break; + case YAML_MAPPING_END_EVENT: + fprintf(fp, "-MAP\n"); + break; + case YAML_SEQUENCE_START_EVENT: + fprintf(fp, "+SEQ"); + if (event->data.sequence_start.anchor) + fprintf(fp, " &%s", event->data.sequence_start.anchor); + if (event->data.sequence_start.tag) + fprintf(fp, " <%s>", event->data.sequence_start.tag); + fprintf(fp, "\n"); + break; + case YAML_SEQUENCE_END_EVENT: + fprintf(fp, "-SEQ\n"); + break; + case YAML_SCALAR_EVENT: + fprintf(fp, "=VAL"); + if (event->data.scalar.anchor) + fprintf(fp, " &%s", event->data.scalar.anchor); + if (event->data.scalar.tag) + fprintf(fp, " <%s>", event->data.scalar.tag); + switch (event->data.scalar.style) { + case YAML_PLAIN_SCALAR_STYLE: + fprintf(fp, " :"); + break; + case YAML_SINGLE_QUOTED_SCALAR_STYLE: + fprintf(fp, " '"); + break; + case YAML_DOUBLE_QUOTED_SCALAR_STYLE: + fprintf(fp, " \""); + break; + case YAML_LITERAL_SCALAR_STYLE: + fprintf(fp, " |"); + break; + case YAML_FOLDED_SCALAR_STYLE: + fprintf(fp, " >"); + break; + case YAML_ANY_SCALAR_STYLE: + abort(); + } + print_escaped(fp, (char *)event->data.scalar.value, event->data.scalar.length); + fprintf(fp, "\n"); + break; + case YAML_ALIAS_EVENT: + fprintf(fp, "=ALI *%s\n", event->data.alias.anchor); + break; + default: + assert(0); + } +} + +int do_libyaml_testsuite(FILE *fp, yaml_parser_t *parser, bool null_output) +{ + yaml_event_t event; + int done = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + return -1; + + if (!null_output) + dump_libyaml_testsuite_event(fp, &event); + + done = (event.type == YAML_STREAM_END_EVENT); + + yaml_event_delete(&event); + } + + return 0; +} + +int do_libyaml_dump(yaml_parser_t *parser, yaml_emitter_t *emitter, bool null_output) +{ + yaml_document_t document; + int done = 0; + int counter; + + yaml_emitter_set_canonical(emitter, 0); + + counter = 0; + while (!done) + { + if (!yaml_parser_load(parser, &document)) + return -1; + + done = !yaml_document_get_root_node(&document); + + if (!done) { + if (counter > 0) + printf("# document seperator\n"); + + if (!null_output) + yaml_emitter_dump(emitter, &document); + else + yaml_document_delete(&document); + counter++; + + if (!null_output) + yaml_emitter_flush(emitter); + } else + yaml_document_delete(&document); + } + + return 0; +} + +#endif + +struct fy_kv { + struct list_head node; + const char *key; + const char *value; +}; +FY_TYPE_FWD_DECL_LIST(kv); +FY_TYPE_DECL_LIST(kv); + +static int hd_accel_kv_hash(struct fy_accel *xl, const void *key, void *userdata, void *hash) +{ + unsigned int *hashp = hash; + + *hashp = XXH32(key, strlen(key), 2654435761U); + + // printf("%s key=%s hash=%08x\n", __func__, (const char *)key, *hashp); + return 0; +} + +static bool hd_accel_kv_eq(struct fy_accel *xl, const void *hash, const void *key1, const void *key2, void *userdata) +{ + return !strcmp(key1, key2); +} + +struct fy_kv_store { + struct fy_kv_list l; + struct fy_accel xl; + unsigned int count; +}; + +static const struct fy_hash_desc hd_kv_store = { + .size = sizeof(unsigned int), + .max_bucket_grow_limit = 8, + .hash = hd_accel_kv_hash, + .eq = hd_accel_kv_eq, +}; + +int fy_kv_store_setup(struct fy_kv_store *kvs, + unsigned int min_buckets) +{ + int rc; + + if (!kvs) + return -1; + memset(kvs, 0, sizeof(*kvs)); + fy_kv_list_init(&kvs->l); + + rc = fy_accel_setup(&kvs->xl, &hd_kv_store, kvs, min_buckets); + return rc; +} + +void fy_kv_store_cleanup(struct fy_kv_store *kvs) +{ + struct fy_kv *kv; + int rc __FY_DEBUG_UNUSED__; + + if (!kvs) + return; + + while ((kv = fy_kv_list_pop(&kvs->l)) != NULL) { + // printf("%s: removing %s: %s\n", __func__, kv->key, kv->value); + rc = fy_accel_remove(&kvs->xl, kv->key); + assert(!rc); + free(kv); + } + + fy_accel_cleanup(&kvs->xl); +} + +int fy_kv_store_insert(struct fy_kv_store *kvs, const char *key, const char *value) +{ + struct fy_kv *kv; + size_t klen, vlen, size; + char *s; + int rc; + + if (!kvs || !key || !value) + return -1; + + /* no more that UINT_MAX */ + if (kvs->count == UINT_MAX) + return -1; + + klen = strlen(key); + vlen = strlen(value); + size = sizeof(*kv) + klen + 1 + vlen + 1; + + kv = malloc(size); + if (!kv) + return -1; + s = (char *)(kv + 1); + kv->key = s; + memcpy(s, key, klen + 1); + s += klen + 1; + kv->value = s; + memcpy(s, value, vlen + 1); + + rc = fy_accel_insert(&kvs->xl, kv->key, kv); + if (rc) { + free(kv); + return rc; + } + fy_kv_list_add_tail(&kvs->l, kv); + kvs->count++; + + // printf("%s: %s: %s #%d\n", __func__, kv->key, kv->value, kvs->count); + + return 0; +} + +const char *fy_kv_store_lookup(struct fy_kv_store *kvs, const char *key) +{ + const struct fy_kv *kv; + + if (!kvs || !key) + return NULL; + + kv = fy_accel_lookup(&kvs->xl, key); + if (!kv) + return NULL; + + return kv->value; +} + +int fy_kv_store_remove(struct fy_kv_store *kvs, const char *key) +{ + struct fy_kv *kv; + struct fy_accel_entry *xle; + + if (!kvs || !key) + return -1; + + xle = fy_accel_entry_lookup(&kvs->xl, key); + if (!xle) { + printf("%s:%d: %s key=%s\n", __FILE__, __LINE__, __func__, key); + return -1; + } + kv = (void *)xle->value; + fy_accel_entry_remove(&kvs->xl, xle); + + fy_kv_list_del(&kvs->l, kv); + assert(kvs->count > 0); + kvs->count--; + + // printf("%s: %s: %s #%d\n", __func__, kv->key, kv->value, kvs->count); + + free(kv); + + return 0; +} + +const struct fy_kv *fy_kv_store_by_index(struct fy_kv_store *kvs, unsigned int index) +{ + unsigned int i; + struct fy_kv *kv; + + if (!kvs || index >= kvs->count) + return NULL; + + for (i = 0, kv = fy_kv_list_first(&kvs->l); kv && i < index; i++, kv = fy_kv_next(&kvs->l, kv)) + ; + return kv; +} + +const char *fy_kv_store_key_by_index(struct fy_kv_store *kvs, unsigned int index) +{ + const struct fy_kv *kv; + + kv = fy_kv_store_by_index(kvs, index); + return kv ? kv->key : NULL; +} + +static void do_accel_kv(const struct fy_parse_cfg *cfg, int argc, char *argv[]) +{ + struct fy_kv_store kvs; + unsigned int seed, idx; + int i, count; + int rc __FY_DEBUG_UNUSED__; + char keybuf[16], valbuf[16]; + const char *key; + + seed = 0; /* we don't care much about seed practices right now */ + rc = fy_kv_store_setup(&kvs, 8); + assert(!rc); + + count = 1000; + + printf("creating #%d KVs\n", count); + + for (i = 0; i < count; i++) { + snprintf(keybuf, sizeof(keybuf), "%s-%08x", "key", rand_r(&seed)); + snprintf(valbuf, sizeof(valbuf), "%s-%08x", "val", rand_r(&seed)); + + printf("inserting %s: %s\n", keybuf, valbuf); + + rc = fy_kv_store_insert(&kvs, keybuf, valbuf); + assert(rc == 0); + } + + while (count > 0) { + idx = (unsigned int)rand_r(&seed) % count; + + key = fy_kv_store_key_by_index(&kvs, idx); + assert(key); + + printf("removing #%d - %s\n", idx, key); + + rc = fy_kv_store_remove(&kvs, key); + assert(!rc); + + count--; + } + + printf("\n"); + fy_kv_store_cleanup(&kvs); +} + +int do_accel_test(const struct fy_parse_cfg *cfg, int argc, char *argv[]) +{ + do_accel_kv(cfg, argc, argv); + + return 0; +} + +#if 0 +static void test_diag_output(struct fy_diag *diag, void *user, const char *buf, size_t len) +{ + FILE *fp = user; + static int counter = 0; + + fprintf(fp, "%d: %.*s", ++counter, (int)len, buf); +} +#endif + +int do_build(const struct fy_parse_cfg *cfg, int argc, char *argv[]) +{ +#if 0 + struct fy_parse_cfg cfg_tmp; + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + struct fy_diag_report_ctx drc; + struct fy_token *fyt; + void *iter; + const char *handle, *prefix; + size_t handle_size, prefix_size; + int rc __FY_DEBUG_UNUSED__; + struct fy_atom atom; +#endif + +#if 0 + char *path; + struct fy_node *fynt; + struct fy_document *fydt; + struct fy_node_pair *fynp; + const char *scalar; + size_t len; + int count, i, j; + int rc __FY_DEBUG_UNUSED__; + int ret __FY_DEBUG_UNUSED__; + char tbuf[80]; + struct fy_anchor *fya; + const char *handle, *prefix; + size_t handle_size, prefix_size; + + /****/ + + fydt = fy_document_build_from_string(cfg, "#comment \n[ 42, \n 12 ] # comment\n", FY_NT); + assert(fydt); + + buf = fy_emit_document_to_string(fydt, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fydt); + fydt = NULL; + + /****/ + + fydt = fy_document_build_from_string(cfg, "plain-scalar # comment\n", FY_NT); + assert(fydt); + + scalar = fy_node_get_scalar(fy_document_root(fydt), &len); + printf("root scalar content=\"%.*s\"\n", (int)len, scalar); + + fy_document_destroy(fydt); + fydt = NULL; + + /****/ + + fydt = fy_document_build_from_string(cfg, "[ 10, 11, foo ] # comment", FY_NT); + assert(fydt); + + buf = fy_emit_node_to_string(fy_document_root(fydt), 0); + assert(buf); + printf("resulting node: \"%s\"\n", buf); + free(buf); + + count = fy_node_sequence_item_count(fy_document_root(fydt)); + printf("count=%d\n", count); + assert(count == 3); + + /* try iterator first */ + printf("forward iterator:"); + iter = NULL; + while ((fyn = fy_node_sequence_iterate(fy_document_root(fydt), &iter)) != NULL) { + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf(" \"%s\"", buf); + free(buf); + } + printf("\n"); + + printf("reverse iterator:"); + iter = NULL; + while ((fyn = fy_node_sequence_reverse_iterate(fy_document_root(fydt), &iter)) != NULL) { + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf(" \"%s\"", buf); + free(buf); + } + printf("\n"); + + fy_document_destroy(fydt); + fydt = NULL; + + /*****/ + + fydt = fy_document_build_from_string(cfg, "{ foo: 10, bar : 20, baz: [100, 101], [frob, 1]: boo }", FY_NT); + assert(fydt); + + buf = fy_emit_node_to_string(fy_document_root(fydt), 0); + assert(buf); + printf("resulting node: \"%s\"\n", buf); + free(buf); + + count = fy_node_mapping_item_count(fy_document_root(fydt)); + printf("count=%d\n", count); + assert(count == 4); + + /* try iterator first */ + printf("forward iterator:"); + iter = NULL; + while ((fynp = fy_node_mapping_iterate(fy_document_root(fydt), &iter)) != NULL) { + buf = fy_emit_node_to_string(fynp->key, 0); + assert(buf); + printf(" key=\"%s\"", buf); + free(buf); + buf = fy_emit_node_to_string(fynp->value, 0); + assert(buf); + printf(",value=\"%s\"", buf); + free(buf); + } + printf("\n"); + + printf("reverse iterator:"); + iter = NULL; + while ((fynp = fy_node_mapping_reverse_iterate(fy_document_root(fydt), &iter)) != NULL) { + buf = fy_emit_node_to_string(fynp->key, 0); + assert(buf); + printf(" key=\"%s\"", buf); + free(buf); + buf = fy_emit_node_to_string(fynp->value, 0); + assert(buf); + printf(",value=\"%s\"", buf); + free(buf); + } + printf("\n"); + + printf("index based:"); + for (i = 0; i < count; i++) { + fynp = fy_node_mapping_get_by_index(fy_document_root(fydt), i); + assert(fynp); + buf = fy_emit_node_to_string(fynp->key, 0); + assert(buf); + printf(" key=\"%s\"", buf); + free(buf); + buf = fy_emit_node_to_string(fynp->value, 0); + assert(buf); + printf(",value=\"%s\"", buf); + free(buf); + } + printf("\n"); + + printf("key lookup based:"); + + fyn = fy_node_mapping_lookup_by_string(fy_document_root(fydt), "foo", FY_NT); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s->\"%s\"\n", "foo", buf); + free(buf); + + fyn = fy_node_mapping_lookup_by_string(fy_document_root(fydt), "bar", FY_NT); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s->\"%s\"\n", "bar", buf); + free(buf); + + fyn = fy_node_mapping_lookup_by_string(fy_document_root(fydt), "baz", FY_NT); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s->\"%s\"\n", "baz", buf); + free(buf); + + fyn = fy_node_mapping_lookup_by_string(fy_document_root(fydt), "[ frob, 1 ]", FY_NT); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s->\"%s\"\n", "[ frob, 1 ]", buf); + free(buf); + + printf("\n"); + + fy_document_destroy(fydt); + fydt = NULL; + + /*****/ + + fydt = fy_document_build_from_string(cfg, "{ " + "foo: 10, bar : 20, baz:{ frob: boo }, " + "frooz: [ seq1, { key: value} ], \"zero\\0zero\" : 0, " + "{ key2: value2 }: { key3: value3 } " + "}", FY_NT); + + assert(fydt); + + fyn = fy_node_by_path(fy_document_root(fydt), "/", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "foo", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "foo", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "bar", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "bar", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "baz", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "baz", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "baz/frob", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "baz/frob", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "frooz", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "frooz", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "/frooz/[0]", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/frooz/[0]", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "/frooz/[1]", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/frooz/[1]", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "/frooz/[1]/key", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/frooz/[1]/key", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "\"foo\"", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "\"foo\"", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "\"zero\\0zero\"", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "zero\\0zero", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "/{ key2: value2 }", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/{ key2: value2 }", buf); + free(buf); + + fyn = fy_node_by_path(fy_document_root(fydt), "/{ key2: value2 }/key3", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/{ key2: value2 }/key3", buf); + free(buf); + + printf("\npaths....\n"); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fydt), "/", FY_NT, FYNWF_DONT_FOLLOW)); + printf("%s path is %s\n", "/", path); + if (path) + free(path); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fydt), "/frooz", FY_NT, FYNWF_DONT_FOLLOW)); + printf("%s path is %s\n", "/frooz", path); + if (path) + free(path); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fydt), "/frooz/[0]", FY_NT, FYNWF_DONT_FOLLOW)); + printf("%s path is %s\n", "/frooz/[0]", path); + if (path) + free(path); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fydt), "/{ key2: value2 }/key3", FY_NT, FYNWF_DONT_FOLLOW)); + printf("%s path is %s\n", "/{ key2: value2 }/key3", path); + if (path) + free(path); + + fy_document_destroy(fydt); + fydt = NULL; + + /*****/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_build_from_string(fyd, "{ }", FY_NT); + assert(fyn); + + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/", buf); + free(buf); + + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_scalar(fyd, "foo", 3); + assert(fyn); + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_scalar(fyd, "foo\nfoo", 7); + assert(fyn); + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_sequence(fyd); + assert(fyn); + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_mapping(fyd); + assert(fyn); + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_sequence(fyd); + assert(fyn); + + fy_node_sequence_append(fyn, fy_node_create_scalar(fyd, "foo", FY_NT)); + fy_node_sequence_append(fyn, fy_node_create_scalar(fyd, "bar", FY_NT)); + fy_node_sequence_append(fyn, fy_node_build_from_string(fyd, "{ baz: frooz }", FY_NT)); + + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_mapping(fyd); + assert(fyn); + + rc = fy_node_mapping_append(fyn, NULL, fy_node_build_from_string(fyd, "[ 0, 1 ]", FY_NT)); + assert(!rc); + + fynt = fy_node_build_from_string(fyd, "foo", FY_NT); + assert(fynt); + rc = fy_node_mapping_append(fyn, NULL, fynt); + assert(rc); + fy_node_free(fynt); + + rc = fy_node_mapping_append(fyn, fy_node_build_from_string(fyd, "bar", FY_NT), NULL); + assert(!rc); + + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fy_document_set_root(fyd, fy_node_build_from_string(fyd, "scalar", FY_NT)); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_sequence(fyd); + assert(fyn); + + fy_node_sequence_append(fyn, fy_node_build_from_string(fyd, "foo", FY_NT)); + fy_node_sequence_append(fyn, fy_node_build_from_string(fyd, "bar", FY_NT)); + + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_build_from_string(cfg, "[ one, two, four ]", FY_NT); + + fy_node_sequence_append(fy_document_root(fyd), fy_node_build_from_string(fyd, "five", FY_NT)); + fy_node_sequence_prepend(fy_document_root(fyd), fy_node_build_from_string(fyd, "zero", FY_NT)); + + fy_node_sequence_insert_after(fy_document_root(fyd), + fy_node_by_path(fy_document_root(fyd), "/[2]", FY_NT, FYNWF_DONT_FOLLOW), + fy_node_build_from_string(fyd, "three", FY_NT)); + + fy_node_sequence_insert_before(fy_document_root(fyd), + fy_node_by_path(fy_document_root(fyd), "/[3]", FY_NT, FYNWF_DONT_FOLLOW), + fy_node_build_from_string(fyd, "two-and-a-half", FY_NT)); + + fyn = fy_node_sequence_remove(fy_document_root(fyd), + fy_node_by_path(fy_document_root(fyd), "/[3]", FY_NT, FYNWF_DONT_FOLLOW)); + + fy_node_free(fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_build_from_string(cfg, "{ one: 1, two: 2, four: 4 }", FY_NT); + + fy_node_mapping_append(fy_document_root(fyd), + fy_node_build_from_string(fyd, "three", FY_NT), + fy_node_build_from_string(fyd, "3", FY_NT)); + + fy_node_mapping_prepend(fy_document_root(fyd), + fy_node_build_from_string(fyd, "zero", FY_NT), + fy_node_build_from_string(fyd, "0", FY_NT)); + + fy_node_mapping_append(fy_document_root(fyd), + fy_node_build_from_string(fyd, "two-and-a-half", FY_NT), + fy_node_build_from_string(fyd, "2.5", FY_NT)); + + fyn = fy_node_mapping_remove_by_key(fy_document_root(fyd), + fy_node_build_from_string(fyd, "two-and-a-half", FY_NT)); + assert(fyn != NULL); + + fy_node_free(fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_build_from_string(cfg, "{ aaa: 1, zzz: 2, bbb: 4 }", FY_NT); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_build_from_string(cfg, "\naaa: 1\nzzz: 2\nbbb:\n ccc: foo\n", FY_NT); + + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_build_from_string(cfg, "{ aaa: 1, zzz: 2, bbb: 4 }", FY_NT); + + buf = fy_emit_document_to_string(fyd, FYECF_MODE_BLOCK); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + /* {? {z: bar} : map-value1, ? {a: whee} : map-value2, ? [a, b, c] : seq-value, ? [z] : {frooz: ting}, aaa: 1, bbb: 4, zzz: 2} */ + fyd = fy_document_build_from_string(cfg, "{ a: 5, { z: bar }: 1, z: 7, " + "[ a, b, c] : 3, { a: whee } : 2 , b: 6, [ z ]: 4 }", FY_NT); + + buf = fy_emit_document_to_string(fyd, FYECF_SORT_KEYS); + assert(buf); + printf("resulting document (sorted1):\n"); + fputs(buf, stdout); + free(buf); + + ret = fy_node_sort(fy_document_root(fyd), NULL, NULL); + assert(!ret); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document (sorted2):\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + +#if 0 + /******/ + + cfg_tmp = *cfg; + cfg_tmp.flags |= FYPCF_COLLECT_DIAG; + + /* this is an error */ + fyd = fy_document_build_from_string(&cfg_tmp, "{ a: 5 ] }"); + assert(fyd); + assert(!fyd->root); + + fprintf(stderr, "error log:\n%s", fy_document_get_log(fyd, NULL)); + + fy_document_destroy(fyd); +#endif + + /******/ + + fyd = fy_document_buildf(cfg, "{ %s: %d, zzz: 2, bbb: 4 }", "aaa", 1); + assert(fyd); + + buf = fy_emit_document_to_string(fyd, FYECF_MODE_BLOCK); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_buildf(cfg, "{ %s: %d, zzz: \"this is\n\ntext\", bbb: 4 }", "aaa", 1); + assert(fyd); + + i = j = -1; + count = fy_document_scanf(fyd, "aaa %d bbb %d zzz %79[^\xc0]s", &i, &j, tbuf); + printf("count=%d, aaa=%d bbb=%d zzz=\"%s\"\n", count, i, j, tbuf); + + fy_document_destroy(fyd); + + /******/ + + fyd = fy_document_create(cfg); + assert(fyd); + + rc = fy_document_tag_directive_add(fyd, "!foo!", "tag:bar.com,2019:"); + assert(!rc); + + rc = fy_document_tag_directive_add(fyd, "!e!", "tag%21"); + assert(!rc); + + fyn = fy_node_build_from_string(fyd, "{ foo: bar }", FY_NT); + assert(fyn); + + fy_document_set_root(fyd, fyn); + + /* rc = fy_node_set_tag(fyn, "!!", -1); */ + /* rc = fy_node_set_tag(fyn, "!!int", -1); */ + /* rc = fy_node_set_tag(fyn, "!", -1); */ + rc = fy_node_set_tag(fyn, "!foo!baz", FY_NT); + /* rc = fy_node_set_tag(fyn, "!e!tag%21", -1); */ + /* rc = fy_node_set_tag(fyn, "!e!tag:12:", -1); */ + assert(!rc); + + // fy_document_tag_directive_remove(fyd, "!foo!"); + + rc = fy_node_set_anchor(fy_node_by_path(fyn, "/foo", FY_NT, FYNWF_DONT_FOLLOW), "anchor", FY_NT); + assert(!rc); + + rc = fy_node_mapping_append(fyn, + fy_node_build_from_string(fyd, "!foo!whoa baz", FY_NT), + fy_node_build_from_string(fyd, "frooz", FY_NT)); + assert(!rc); + + rc = fy_node_mapping_append(fyn, + fy_node_build_from_string(fyd, "test", FY_NT), + fy_node_build_from_string(fyd, "*anchor", FY_NT)); + assert(!rc); + + rc = fy_node_mapping_append(fyn, + fy_node_build_from_string(fyd, "test-2", FY_NT), + fy_node_create_alias(fyd, "anchor", FY_NT)); + assert(!rc); + + if (cfg->flags & FYPCF_RESOLVE_DOCUMENT) { + rc = fy_document_resolve(fyd); + assert(!rc); + } + + fprintf(stderr, "tag directives of document\n"); + /* dump directives */ + iter = NULL; + while ((fyt = fy_document_tag_directive_iterate(fyd, &iter)) != NULL) { + handle = fy_tag_directive_token_handle(fyt, &handle_size); + assert(handle); + + prefix = fy_tag_directive_token_prefix(fyt, &prefix_size); + assert(prefix); + + fprintf(stderr, "tag-directive \"%.*s\" \"%.*s\"\n", + (int)handle_size, handle, + (int)prefix_size, prefix); + } + + fprintf(stderr, "anchors of document\n"); + iter = NULL; + while ((fya = fy_document_anchor_iterate(fyd, &iter)) != NULL) { + + path = fy_node_get_path(fy_anchor_node(fya)); + assert(path); + + anchor = fy_anchor_get_text(fya, &anchor_size); + assert(anchor); + + fprintf(stderr, "&%.*s %s\n", (int)anchor_size, anchor, path); + + free(path); + } + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + + /*****/ + + printf("\nJSON pointer tests\n"); + + fyd = fy_document_build_from_string(cfg, + "{\n" + " \"foo\": [\"bar\", \"baz\"],\n" + " \"\": 0,\n" + " \"a/b\": 1,\n" + " \"c%d\": 2,\n" + " \"e^f\": 3,\n" + " \"g|h\": 4,\n" + " \"i\\\\j\": 5,\n" + " \"k\\\"l\": 6,\n" + " \" \": 7,\n" + " \"m~n\": 8\n" + "}" , FY_NT); + + assert(fyd); + + fyn = fy_node_by_path(fy_document_root(fyd), "/", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/", buf); + free(buf); + + { + const char *json_paths[] = { + "", + "/foo", + "/foo/0", + "/", + "/a~1b", + "/c%d", + "/e^f", + "/g|h", + "/i\\j", + "/k\"l", + "/ ", + "/m~0n" + }; + unsigned int ii; + + for (ii = 0; ii < sizeof(json_paths)/sizeof(json_paths[0]); ii++) { + fyn = fy_node_by_path(fy_document_root(fyd), json_paths[ii], FY_NT, FYNWF_PTR_JSON); + if (!fyn) { + printf("Unable to lookup JSON path: '%s'\n", json_paths[ii]); + } else { + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("JSON path: '%s' is '%s'\n", json_paths[ii], buf); + free(buf); + } + printf("\n"); + } + } + + fy_document_destroy(fyd); + fyd = NULL; + + /*****/ + + printf("\nRelative JSON pointer tests\n"); + + fyd = fy_document_build_from_string(cfg, + "{\n" + " \"foo\": [\"bar\", \"baz\"],\n" + " \"highly\": {\n" + " \"nested\": {\n" + " \"objects\": true\n" + " }\n" + " }\n" + "}\n", FY_NT); + assert(fyd); + + fyn = fy_node_by_path(fy_document_root(fyd), "/", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("%s is \"%s\"\n", "/", buf); + free(buf); + + { + const char *reljson_paths[] = { + "0", + "1/0", + "2/highly/nested/objects", + }; + unsigned int ii; + + for (ii = 0; ii < sizeof(reljson_paths)/sizeof(reljson_paths[0]); ii++) { + fyn = fy_node_by_path( + fy_node_by_path(fy_document_root(fyd), "/foo/1", FY_NT, FYNWF_DONT_FOLLOW), /* "baz" */ + reljson_paths[ii], FY_NT, FYNWF_PTR_RELJSON); + if (!fyn) { + printf("Unable to lookup relative JSON path: '%s'\n", reljson_paths[ii]); + } else { + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("Relative JSON path: '%s' is '%s'\n", reljson_paths[ii], buf); + free(buf); + } + printf("\n"); + } + } + + { + const char *reljson_paths[] = { + "0/objects", + "1/nested/objects", + "2/foo/0", + }; + unsigned int ii; + + for (ii = 0; ii < sizeof(reljson_paths)/sizeof(reljson_paths[0]); ii++) { + fyn = fy_node_by_path( + fy_node_by_path(fy_document_root(fyd), "/highly/nested", FY_NT, FYNWF_DONT_FOLLOW), /* "baz" */ + reljson_paths[ii], FY_NT, FYNWF_PTR_RELJSON); + if (!fyn) { + printf("Unable to lookup relative JSON path: '%s'\n", reljson_paths[ii]); + } else { + buf = fy_emit_node_to_string(fyn, 0); + assert(buf); + printf("Relative JSON path: '%s' is '%s'\n", reljson_paths[ii], buf); + free(buf); + } + printf("\n"); + } + } + + fy_document_destroy(fyd); + fyd = NULL; + + /*****/ + + fyd = fy_document_create(NULL); + assert(fyd); + + fyn = fy_node_create_sequence(fyd); + assert(fyn); + + fy_document_set_root(fyd, fyn); + fyn = NULL; + + fyn = fy_node_build_from_string(fyd, "%TAG !e! tag:example.com,2000:app/\n---\n- foo\n- !e!foo bar\n", FY_NT); + assert(fyn); + + rc = fy_node_sequence_append(fy_document_root(fyd), fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + printf("tag directives:\n"); + iter = NULL; + while ((fyt = fy_document_tag_directive_iterate(fyd, &iter)) != NULL) { + handle = fy_tag_directive_token_handle(fyt, &handle_size); + prefix = fy_tag_directive_token_prefix(fyt, &prefix_size); + printf("> handle='%.*s' prefix='%.*s'\n", + (int)handle_size, handle, + (int)prefix_size, prefix); + } + + /* try to build another, but with a different !e! prefix, it must fail */ + fyn = fy_node_build_from_string(fyd, "%TAG !e! tag:example.com,2019:app/\n---\n- foo\n- !e!foo bar\n", FY_NT); + assert(!fyn); + + rc = fy_document_tag_directive_add(fyd, "!f!", "tag:example.com,2019:f/"); + assert(!rc); + + printf("new tag directives:\n"); + iter = NULL; + while ((fyt = fy_document_tag_directive_iterate(fyd, &iter)) != NULL) { + handle = fy_tag_directive_token_handle(fyt, &handle_size); + prefix = fy_tag_directive_token_prefix(fyt, &prefix_size); + printf("> handle='%.*s' prefix='%.*s'\n", + (int)handle_size, handle, + (int)prefix_size, prefix); + } + + fyn = fy_node_build_from_string(fyd, "!f!whiz frooz\n", FY_NT); + assert(fyn); + + rc = fy_node_sequence_append(fy_document_root(fyd), fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("resulting document:\n"); + fputs(buf, stdout); + free(buf); + + fy_document_destroy(fyd); + fyd = NULL; + + /***************/ + + fyp_debug(NULL, FYEM_INTERNAL, "(debug) test"); + fyp_info(NULL, "(info) test"); + fyp_notice(NULL, "(notice) test"); + fyp_warning(NULL, "(warning) test"); + fyp_error(NULL, "(error) test"); + + /****/ + + fyd = fy_document_build_from_string(cfg, + "{\n" + " { foo: bar }: baz,\n" + " frooz: whee,\n" + " houston: [ we, have, a, problem ]\n" + "}", FY_NT); + assert(fyd); + + printf("***************************\n"); + printf("fy_node_is_synthetic(\"/\") = %s\n", + fy_node_is_synthetic(fy_document_root(fyd)) ? "true" : "false"); + printf("***************************\n"); + + fyn = fy_node_by_path(fy_document_root(fyd), "/{ foo: bar }", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + printf("fy_node_is_synthetic(\"/{ foo: bar }\") = %s\n", + fy_node_is_synthetic(fyn) ? "true" : "false"); + + buf = fy_emit_node_to_string(fyn, FYECF_MODE_FLOW_ONELINE | FYECF_WIDTH_INF); + assert(buf); + printf("/{ foo: bar }: %s\n", buf); + free(buf); + + memset(&drc, 0, sizeof(drc)); + drc.type = FYET_NOTICE; + drc.module = FYEM_DOC; + drc.fyt = fy_token_ref(fyn->scalar); + fy_document_diag_report(fyd, &drc, "Test %d", 12); + + fyn = fy_node_by_path(fy_document_root(fyd), "/houston", FY_NT, FYNWF_DONT_FOLLOW); + assert(fyn); + printf("fy_node_is_synthetic(/houston) = %s\n", + fy_node_is_synthetic(fyn) ? "true" : "false"); + + buf = fy_emit_node_to_string(fyn, FYECF_MODE_FLOW_ONELINE | FYECF_WIDTH_INF); + assert(buf); + printf("/houston: %s\n", buf); + free(buf); + + memset(&drc, 0, sizeof(drc)); + drc.type = FYET_NOTICE; + drc.module = FYEM_DOC; + drc.fyt = fy_token_ref(fyn->sequence_start); + fy_document_diag_report(fyd, &drc, "Test %d", 13); + + fyt = fy_node_token(fyn); + assert(fyt); + + memset(&drc, 0, sizeof(drc)); + drc.type = FYET_NOTICE; + drc.module = FYEM_DOC; + drc.fyt = fyt; + fy_document_diag_report(fyd, &drc, "Test %d", 14); + + printf("***************************\n"); + printf("fy_node_is_synthetic(\"/\") = %s\n", + fy_node_is_synthetic(fy_document_root(fyd)) ? "true" : "false"); + printf("***************************\n"); + + fy_node_sequence_append(fy_node_by_path(fy_document_root(fyd), "/houston", FY_NT, FYNWF_DONT_FOLLOW), + fy_node_create_scalar(fyd, "synthesonic", FY_NT)); + + printf("***************************\n"); + printf("fy_node_is_synthetic(\"/\") = %s\n", + fy_node_is_synthetic(fy_document_root(fyd)) ? "true" : "false"); + printf("***************************\n"); + + fyt = fy_node_token(fy_document_root(fyd)); + assert(fyt); + + memset(&drc, 0, sizeof(drc)); + drc.type = FYET_NOTICE; + drc.module = FYEM_DOC; + drc.fyt = fyt; + fy_document_diag_report(fyd, &drc, "Test %d", 16); + + fy_node_mapping_append(fy_document_root(fyd), + fy_node_create_scalar(fyd, "key", FY_NT), + fy_node_create_scalar(fyd, "value", FY_NT)); + + printf("***************************\n"); + printf("fy_node_is_synthetic(\"/\") = %s\n", + fy_node_is_synthetic(fy_document_root(fyd)) ? "true" : "false"); + printf("***************************\n"); + + fy_node_sequence_append(fy_node_by_path(fy_document_root(fyd), "/houston", FY_NT, FYNWF_DONT_FOLLOW), + fy_node_create_scalar(fyd, "item", FY_NT)); + + fyt = fy_node_token(fy_node_by_path(fy_document_root(fyd), "/houston", FY_NT, FYNWF_DONT_FOLLOW)); + assert(fyt); + + memset(&drc, 0, sizeof(drc)); + drc.type = FYET_NOTICE; + drc.module = FYEM_DOC; + drc.fyt = fyt; + fy_document_diag_report(fyd, &drc, "Test %d", 17); + + fy_node_report(fy_node_by_path(fy_document_root(fyd), "/houston/0", FY_NT, FYNWF_DONT_FOLLOW), + FYET_WARNING, "/houston/0 checking report"); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + printf("/:\n"); + fputs(buf, stdout); + free(buf); + + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE | FYECF_WIDTH_INF); + assert(buf); + printf("%s\n", buf); + free(buf); + + fy_diag_printf(fyd->diag, "Outputting on document diag\n"); + + fy_debug(fyd->diag, "Debug level\n"); + fy_info(fyd->diag, "Info level\n"); + fy_notice(fyd->diag, "Notice level\n"); + fy_warning(fyd->diag, "Warning level\n"); + fy_error(fyd->diag, "Error level\n"); + + fy_document_destroy(fyd); + fyd = NULL; + + { + struct fy_diag *diag; + struct fy_diag_cfg dcfg; + struct fy_parse_cfg pcfg; + FILE *fp; + char *mbuf = NULL; + size_t msize; + + fp = open_memstream(&mbuf, &msize); + assert(fp); + + fy_diag_cfg_default(&dcfg); + dcfg.fp = fp; + dcfg.colorize = isatty(fileno(stderr)) == 1; + + diag = fy_diag_create(&dcfg); + assert(diag); + + fy_error(diag, "Writting in the diagnostic\n"); + + memset(&pcfg, 0, sizeof(pcfg)); + pcfg.flags = FYPCF_DEFAULT_DOC; + pcfg.diag = diag; + fyd = fy_document_build_from_string(&pcfg, "{ foo: \"\\xeh\", foo: baz }", FY_NT); + /* the document must not be created (duplicate key) */ + assert(!fyd); + + fy_diag_destroy(diag); + + fclose(fp); + + assert(mbuf); + + printf("checking diagnostic\n"); + fwrite(mbuf, msize, 1, stdout); + + free(mbuf); + } + + { + struct fy_diag *diag; + struct fy_diag_cfg dcfg; + struct fy_parse_cfg pcfg; + FILE *fp; + char *mbuf = NULL; + size_t msize; + + fp = open_memstream(&mbuf, &msize); + assert(fp); + + fy_diag_cfg_default(&dcfg); + dcfg.fp = NULL; + dcfg.colorize = isatty(fileno(stderr)) == 1; + dcfg.output_fn = test_diag_output; + dcfg.user = stderr; + + diag = fy_diag_create(&dcfg); + assert(diag); + + fy_error(diag, "Writting in the diagnostic\n"); + + memset(&pcfg, 0, sizeof(pcfg)); + pcfg.flags = FYPCF_DEFAULT_DOC; + pcfg.diag = diag; + fyd = fy_document_build_from_string(&pcfg, "{ foo: \"\\xeh\", foo: baz }", FY_NT); + /* the document must not be created (duplicate key) */ + assert(!fyd); + + fy_diag_destroy(diag); + + fclose(fp); + + assert(mbuf); + + printf("checking diagnostic\n"); + fwrite(mbuf, msize, 1, stdout); + + free(mbuf); + } +#endif + /*****/ + +#if 0 + { +//#define MANUAL_SCALAR_STR "val\"quote'\0null\0&the\nrest " +//#define MANUAL_SCALAR_STR "0\n1" +//#define MANUAL_SCALAR_STR "\\\"\0\a\b\t\v\f\r\e\xc2\x85\xc2\xa0\xe2\x80\xa8\xe2\x80\xa9" +//#define MANUAL_SCALAR_STR "\\\"\0\a\b\t\v\f\r\e\n" +//#define MANUAL_SCALAR_STR "\xc2\x85" +//#define MANUAL_SCALAR_STR "\xc2\xa0" +#define MANUAL_SCALAR_STR "\xff\xff\xff\xff" +//#define MANUAL_SCALAR_STR "foo\xf9\xff\xffzbar\xff\xffwz" + + const char *what = MANUAL_SCALAR_STR; + size_t what_sz = sizeof(MANUAL_SCALAR_STR) - 1; + struct fy_document *fyd; + struct fy_node *fyn; + char *buf, *buf2; + + fyd = fy_document_create(cfg); + assert(fyd); + + fyn = fy_node_create_scalar(fyd, what, what_sz); + assert(fyn); + + fy_document_set_root(fyd, fyn); + + buf = fy_emit_document_to_string(fyd, 0); + assert(buf); + fputs(buf, stdout); + fy_document_destroy(fyd); + + fyd = fy_document_build_from_string(cfg, buf, FY_NT); + assert(fyd); + + buf2 = fy_emit_document_to_string(fyd, 0); + assert(buf2); + fputs(buf2, stdout); + fy_document_destroy(fyd); + + free(buf); + free(buf2); + } +#endif + +#if 0 + do_accel_test(cfg, argc, argv); +#endif + + return 0; +} + +struct pathspec_arg { + const char *arg; + size_t argsz; + struct fy_document *fyd; + bool is_numeric; + int number; + void *user; +}; + +struct pathspec { + const char *func; + size_t funcsz; + unsigned int argc; + struct pathspec_arg arg[10]; + void *user; +}; + +struct path { + bool absolute; /* starts at root */ + bool trailing_slash; + unsigned int count; + unsigned int alloc; + struct pathspec *ps; + struct pathspec ps_local[10]; +}; + +int setup_path(struct path *path) +{ + if (!path) + return -1; + + memset(path, 0, sizeof(*path)); + path->count = 0; + path->alloc = sizeof(path->ps_local)/sizeof(path->ps_local[0]); + path->absolute = false; + path->trailing_slash = false; + path->ps = path->ps_local; + + return 0; +} + +void cleanup_path(struct path *path) +{ + struct pathspec *ps; + unsigned int i; + + if (!path) + return; + + while (path->count > 0) { + ps = &path->ps[--path->count]; + for (i = 0; i < ps->argc; i++) { + if (ps->arg[i].fyd) + fy_document_destroy(ps->arg[i].fyd); + } + } + if (path->ps != path->ps_local) + free(path->ps); + path->ps = path->ps_local; + path->count = 0; + path->alloc = sizeof(path->ps_local)/sizeof(path->ps_local[0]); + path->absolute = false; + path->trailing_slash = false; + path->ps = path->ps_local; +} + +size_t parse_pathspec(const char *str, size_t len, struct pathspec *ps) +{ + const char *s, *e, *ss, *ee; + unsigned int maxargs; + bool is_func; + size_t adv; + struct fy_document *fyd; + struct pathspec_arg *psa; + + s = str; + e = s + len; + + ps->func = NULL; + ps->funcsz = 0; + ps->argc = 0; + + maxargs = sizeof(ps->arg)/sizeof(ps->arg[0]); + + if (s >= e) + return 0; + + is_func = false; + + /* either . .. or .func( */ + if (*s == '.') { + /* . */ + if (s + 1 >= e || s[1] == '/') { + ps->func = s; + ps->funcsz = 1; + s++; + goto out; + } + /* .. */ + if (s[1] == '.') { + if (s + 2 >= e || s[2] == '/') { + ps->func = s; + ps->funcsz = 2; + s += 2; + goto out; + } + + /* error; stop */ + goto err_out; + } + /* skip over . */ + ss = ++s; + while (s < e && *s != '(') + s++; + + /* error; no ( found */ + if (s >= e) + goto err_out; + + ps->func = ss; + ps->funcsz = (size_t)(s - ss); + + is_func = true; + } + + if (is_func && *s == '(') + s++; + + for (;;) { + ss = s; + + fyd = NULL; + if (fy_is_path_flow_key_start(*s)) { + fyd = fy_flow_document_build_from_string(NULL, s, e - s, &adv); + if (!fyd) + goto err_out; + + s = ss + adv; + } else { + if (!is_func) { + while (s < e && *s != '/') + s++; + } else { + while (s < e && *s != ',' && *s != ')') + s++; + } + } + if (ps->argc >= maxargs) + goto err_out; + + psa = &ps->arg[ps->argc++]; + + psa->arg = ss; + psa->argsz = s - ss; + psa->fyd = fyd; + + ee = s; + + /* check for numeric */ + if (ss < ee && (fy_is_num(*ss) || *ss == '-')) { + bool is_neg; + int idx, len, digit; + + if (*ss == '-') { + ss++; + is_neg = true; + } else + is_neg = false; + + idx = 0; + len = 0; + while (ss < ee && fy_is_num(*ss)) { + digit = *ss - '0'; + /* no 0 prefixed numbers allowed */ + if (len > 0 && idx == 0) + goto not_numeric; + + /* number overflow */ + if (idx * 10 < idx) + goto not_numeric; + + idx = idx * 10; + idx += digit; + len++; + ss++; + } + + if (is_neg) + idx = -idx; + psa->is_numeric = true; + psa->number = idx; + + } else { +not_numeric: + psa->is_numeric = false; + psa->number = 0; + } + + if (!is_func || s >= e || *s == ')') + break; + + if (s < e && *s == ',') + s++; + } + + if (is_func && s < e && *s == ')') + s++; +out: + return s - str; + +err_out: + return (size_t)-1; +} + +int parse_path(const char *str, size_t len, struct path *path) +{ + const char *s, *e; + unsigned int i; + struct pathspec *ps, *psnew; + size_t adv; + + path->count = 0; + path->absolute = false; + path->trailing_slash = false; + + if (len == (size_t)-1) + len = strlen(str); + + s = str; + e = s + len; + + if (s >= e) + return -1; + + /* starts at root */ + if (*s == '/') { + s++; + path->absolute = true; + } + + /* check for trailing slash and remove it */ + if (e[-1] == '/') { + e--; + path->trailing_slash = true; + }; + + while (s < e) { + if (path->count >= path->alloc) { + psnew = realloc(path->ps == path->ps_local ? NULL : path->ps, + path->alloc * 2 * sizeof(*psnew)); + if (!psnew) + goto err_out; + if (path->ps == path->ps_local) + memcpy(psnew, path->ps, path->count * sizeof(*psnew)); + path->ps = psnew; + path->alloc *= 2; + } + ps = &path->ps[path->count++]; + adv = parse_pathspec(s, (size_t)(e - s), ps); + if (adv == (size_t)-1) + goto err_out; + + if (adv == 0) + break; + + s += adv; + if (s < e && *s == '/') + s++; + } + + /* error */ + if (s < e) + goto err_out; + + return 0; + +err_out: + while (path->count > 0) { + ps = &path->ps[--path->count]; + for (i = 0; i < ps->argc; i++) { + if (ps->arg[i].fyd) + fy_document_destroy(ps->arg[i].fyd); + } + } + return -1; +} + +int do_pathspec(int argc, char *argv[]) +{ + int i; + const char *s, *e; + size_t adv; + struct pathspec ps; + + assert(argc > 0); + + s = argv[0]; + e = s + strlen(s); + + if (s >= e) + return -1; + + /* starts at root */ + if (*s == '/') { + fprintf(stderr, "starts with /\n"); + s++; + } + + while (s < e) { + fprintf(stderr, "parsing: %.*s\n", (int)(e - s), s); + adv = parse_pathspec(s, (size_t)(e - s), &ps); + if (adv == 0) { + fprintf(stderr, "parse_pathspec() returns 0\n"); + break; + } + fprintf(stderr, "full-ps: %.*s\n", (int)adv, s); + fprintf(stderr, "func: %.*s\n", (int)ps.funcsz, ps.func); + for (i = 0; i < (int)ps.argc; i++) { + fprintf(stderr, "arg[%d]: %.*s\n", i, (int)ps.arg[i].argsz, ps.arg[i].arg); + if (ps.arg[i].fyd) + fy_document_destroy(ps.arg[i].fyd); + } + fprintf(stderr, "\n"); + + s += adv; + + if (s < e && *s == '/') + s++; + } + + return 0; +} + +struct fy_node * +node_find(struct fy_document *fyd, struct fy_node *fyn_start, struct path *path) +{ + struct fy_node *fyn; + struct fy_anchor *fya; + struct pathspec *ps; + struct pathspec_arg *psa; + unsigned int i; + + if (!fyd || !fyn_start || !path) + return NULL; + + if (path->absolute) + fyn_start = fyd->root; + + fyn = fyn_start; + for (i = 0; fyn && i < path->count; i++) { + + ps = &path->ps[i]; + if (ps->funcsz > 0) { + if (ps->funcsz == 1 && !memcmp(ps->func, ".", 1)) { + /* current; nop */ + } else if (ps->funcsz == 2 && !memcmp(ps->func, "..", 2)) { + /* parent */ + fyn = fy_node_get_document_parent(fyn); + } else if (ps->funcsz == 3 && !memcmp(ps->func, "key", 3)) { + if (ps->argc != 1) { + fprintf(stderr, "illegal number of arguments at key\n"); + return NULL; + } + + if (!fy_node_is_mapping(fyn)) { + fprintf(stderr, "key function only works on mappings\n"); + return NULL; + } + + psa = &ps->arg[0]; + + if (psa->fyd) { + fyn = fy_node_mapping_lookup_key_by_key(fyn, fy_document_root(psa->fyd)); + if (!fyn) { + fprintf(stderr, "failed to find complex key\n"); + return NULL; + } + } else { + fyn = fy_node_mapping_lookup_key_by_string(fyn, psa->arg, psa->argsz); + if (!fyn) { + fprintf(stderr, "failed to find simple key\n"); + return NULL; + } + } + + } else { + fprintf(stderr, "unkown function %.*s\n", (int)ps->funcsz, ps->func); + return NULL; + } + } else { + if (ps->argc != 1) { + fprintf(stderr, "illegal number of arguments at key\n"); + return NULL; + } + psa = &ps->arg[0]; + + /* check for alias */ + if (psa->arg[0] == '*') { + /* alias must be the first component and not absolute */ + if (path->absolute) { + fprintf(stderr, "bad alias when absolute\n"); + return NULL; + } + if (i > 0) { + fprintf(stderr, "bad alias not at start\n"); + return NULL; + } + fya = fy_document_lookup_anchor(fyd, &psa->arg[1], psa->argsz-1); + if (!fya) { + fprintf(stderr, "bad alias unable to find anchor\n"); + return NULL; + } + /* continue */ + fyn = fya->fyn; + continue; + } + + switch (fyn->type) { + case FYNT_SCALAR: + if (!fy_node_is_alias(fyn)) { + fprintf(stderr, "at scalar; this is the end\n"); + return NULL; + } + fya = fy_document_lookup_anchor_by_token(fyd, fyn->scalar); + if (!fya) { + fprintf(stderr, "unable to lookup alias\n"); + return NULL; + } + fyn = fya->fyn; + break; + + case FYNT_SEQUENCE: + if (!psa->is_numeric) { + fprintf(stderr, "sequence requires numeric argument\n"); + return NULL; + } + + fyn = fy_node_sequence_get_by_index(fyn, psa->number); + if (!fyn) { + fprintf(stderr, "failed to find sequence idx\n"); + return NULL; + } + + break; + + case FYNT_MAPPING: + if (psa->fyd) { + fyn = fy_node_mapping_lookup_value_by_key(fyn, fy_document_root(psa->fyd)); + if (!fyn) { + fprintf(stderr, "failed to find complex key\n"); + return NULL; + } + } else { + fyn = fy_node_mapping_lookup_by_string(fyn, psa->arg, psa->argsz); + if (!fyn) { + fprintf(stderr, "failed to find simple key\n"); + return NULL; + } + } + break; + } + } + + if (fy_node_is_alias(fyn)) { + struct fy_node *referred[FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT]; + unsigned int derefs, k; + + for (derefs = 0; derefs < FYPCF_GUARANTEED_MINIMUM_DEPTH_LIMIT; derefs++) { + if (!fy_node_is_alias(fyn)) + break; + fya = fy_document_lookup_anchor_by_token(fyd, fyn->scalar); + if (!fya) { + fprintf(stderr, "unable to deref alias\n"); + return NULL; + } + for (k = 0; k < derefs; k++) { + if (fya->fyn == referred[k]) { + fprintf(stderr, "alias loop detected\n"); + return NULL; + } + } + fyn = fya->fyn; + referred[derefs] = fyn; + } + } + } + + return fyn; +} + +struct fy_node * +node_find_exec(struct fy_document *fyd, struct fy_node *fyn_start, const char *path) +{ + struct fy_input *fyi; + struct fy_path_parser fypp_local, *fypp = &fypp_local; + struct fy_path_parse_cfg pcfg_local, *pcfg = &pcfg_local; + struct fy_path_exec *fypx = NULL; + struct fy_path_exec_cfg xcfg_local, *xcfg = &xcfg_local; + struct fy_emitter fye_local, *fye = &fye_local; + struct fy_emitter_cfg ecfg_local, *ecfg = &ecfg_local; + struct fy_path_expr *expr; + struct fy_document *fyd_pe; + struct fy_node *fyn; + void *iterp; + int rc; + + fyi = fy_input_from_data(path, strlen(path), NULL, false); + assert(fyi); + + memset(pcfg, 0, sizeof(*pcfg)); + pcfg->diag = fyd->diag; + fy_path_parser_setup(fypp, pcfg); + + memset(xcfg, 0, sizeof(*xcfg)); + xcfg->diag = fyd->diag; + fypx = fy_path_exec_create(xcfg); + assert(fypx); + + rc = fy_path_parser_open(fypp, fyi, NULL); + assert(!rc); + + fyn = NULL; + expr = fy_path_parse_expression(fypp); + if (!expr) { + fprintf(stderr, "Failed to parse expression \"%s\"\n", path); + goto do_close; + } + fprintf(stderr, "OK; parsed expression \"%s\"\n", path); + + fy_path_expr_dump(expr, fyd->diag, FYET_WARNING, 0, "expression dump"); + + fyd_pe = fy_path_expr_to_document(expr); + if (!fyd_pe) { + fprintf(stderr, "Failed to create YAML path expression tree for \"%s\"\n", path); + goto do_free; + } + + memset(ecfg, 0, sizeof(*ecfg)); + ecfg->diag = fyd->diag; + fy_emit_setup(fye, ecfg); + + fy_emit_document(fye, fyd_pe); + + fy_emit_cleanup(fye); + + fy_document_destroy(fyd_pe); + + rc = fy_path_exec_execute(fypx, expr, fyn_start); + if (rc) { + fprintf(stderr, "Failed to execute expression \"%s\"\n", path); + goto do_free; + } + + iterp = NULL; + fyn = fy_path_exec_results_iterate(fypx, &iterp); + +do_free: + fy_path_expr_free(expr); + +do_close: + fy_path_parser_close(fypp); + + fy_path_exec_unref(fypx); + + fy_path_parser_cleanup(fypp); + fy_input_unref(fyi); + + return fyn; +} + +int do_bypath(struct fy_parser *fyp, const char *pathstr, const char *start) +{ + struct path path; + struct pathspec *ps; + struct pathspec_arg *arg; + struct fy_document *fyd; + struct fy_node *fyn; + int count; + unsigned int i, j; + int rc __FY_DEBUG_UNUSED__; + + setup_path(&path); + + rc = parse_path(pathstr, (size_t)-1, &path); + assert(!rc); + + fprintf(stderr, "%s: pathstr=%s absolute=%s trailing_slash=%s\n", __func__, + pathstr, + path.absolute ? "true" : "false", + path.trailing_slash ? "true" : "false"); + for (i = 0; i < path.count; i++) { + ps = &path.ps[i]; + fprintf(stderr, " func=%.*s argc=%u", (int)ps->funcsz, ps->func, ps->argc); + for (j = 0; j < ps->argc; j++) { + arg = &ps->arg[j]; + fprintf(stderr, " %.*s", (int)arg->argsz, arg->arg); + } + fprintf(stderr, "\n"); + } + + count = 0; + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + fyn = node_find_exec(fyd, fy_document_root(fyd), pathstr); + 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)); + } + + 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)); + } + + fy_parse_document_destroy(fyp, fyd); + + count++; + } + + cleanup_path(&path); + + return count > 0 ? 0 : -1; +} + +struct test_parser { + struct fy_reader reader; + struct fy_diag *diag; + struct fy_input *fyi; +}; + +struct fy_diag *test_parser_reader_get_diag(struct fy_reader *fyr) +{ + struct test_parser *parser = container_of(fyr, struct test_parser, reader); + return parser->diag; +} + +static const struct fy_reader_ops test_parser_reader_ops = { + .get_diag = test_parser_reader_get_diag, + .file_open = NULL, +}; + +int do_reader(struct fy_parser *fyp, int indent, int width, bool resolve, bool sort) +{ + const char *data = "this is a test-testing: more data"; + struct test_parser parser; + struct fy_diag_cfg dcfg; + struct fy_diag *diag; + struct fy_reader *fyr; + struct fy_input *fyi; + struct fy_document *fyd; + char ubuf[5]; + int c; + int r __FY_DEBUG_UNUSED__; + + fy_diag_cfg_default(&dcfg); + diag = fy_diag_create(&dcfg); + assert(diag); + + fyi = fy_input_from_data(data, FY_NT, NULL, false); + assert(fyi); + + memset(&parser, 0, sizeof(parser)); + fyr = &parser.reader; + parser.diag = diag; + + fy_reader_setup(fyr, &test_parser_reader_ops); + fyr_notice(fyr, "Reader initialized\n"); + + r = fy_reader_input_open(fyr, fyi, NULL); + assert(!r); + fyr_notice(fyr, "Reader input opened\n"); + + while ((c = fy_reader_peek(fyr)) >= 0 && c != '{' && c != '[' && c != '"' && c != '\'' && c != '-') { + fy_reader_advance(fyr, c); + fy_utf8_put_unchecked(ubuf, c); + fyr_notice(fyr, "%.*s %d\n", (int)fy_utf8_width(c), ubuf, c); + } + + if (c > 0) { + fy_parser_set_reader(fyp, fyr); + fy_parser_set_flow_only_mode(fyp, true); + + fyd = fy_parse_load_document(fyp); + if (fyd) { + fyr_notice(fyr, "parsed a yaml document\n"); + } + + (void)fy_emit_document_to_file(fyd, 0, NULL); + + fy_document_destroy(fyd); + + /* remaining */ + while ((c = fy_reader_peek(fyr)) >= 0) { + fy_reader_advance(fyr, c); + fy_utf8_put_unchecked(ubuf, c); + fyr_notice(fyr, "%.*s %d\n", (int)fy_utf8_width(c), ubuf, c); + } + } + + fy_reader_input_done(fyr); + fyr_notice(fyr, "Reader input done\n"); + + fy_input_close(fyi); + + fy_reader_cleanup(fyr); + + fy_input_unref(fyi); + fy_diag_destroy(diag); + + return 0; +} + +int do_walk(struct fy_parser *fyp, const char *walkpath, const char *walkstart, int indent, int width, bool resolve, bool sort) +{ + struct fy_path_parse_cfg pcfg; + struct fy_path_parser fypp_data, *fypp = &fypp_data; + struct fy_path_expr *expr; + struct fy_walk_result_list results; + struct fy_walk_result *result; + struct fy_input *fyi; + struct fy_document *fyd, *fyd2; + struct fy_node *fyn, *fyn2; + struct fy_walk_result *fwr; + struct fy_path_exec *fypx = NULL; + struct fy_path_exec_cfg xcfg_local, *xcfg = &xcfg_local; + char *path; + unsigned int flags; + int rc, count; + + flags = 0; + if (sort) + flags |= FYECF_SORT_KEYS; + flags |= FYECF_INDENT(indent) | FYECF_WIDTH(width); + + fy_notice(fyp->diag, "setting up path parser for \"%s\"\n", walkpath); + + memset(&pcfg, 0, sizeof(pcfg)); + pcfg.diag = fyp->diag; + fy_path_parser_setup(fypp, &pcfg); + + fyi = fy_input_from_data(walkpath, FY_NT, NULL, false); + assert(fyi); + + rc = fy_path_parser_open(fypp, fyi, NULL); + assert(!rc); + + fy_notice(fyp->diag, "path parser input set for \"%s\"\n", walkpath); + + /* while ((fyt = fy_path_scan(fypp)) != NULL) { + dump_token(fyt); + fy_token_unref(fyt); + } */ + expr = fy_path_parse_expression(fypp); + if (!expr) { + fy_error(fyp->diag, "failed to parse expression\n"); + } else + fy_path_expr_dump(expr, fyp->diag, FYET_NOTICE, 0, "fypp root "); + + memset(xcfg, 0, sizeof(*xcfg)); + xcfg->diag = fyp->diag; + fypx = fy_path_exec_create(xcfg); + assert(fypx); + + count = 0; + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + if (resolve) { + rc = fy_document_resolve(fyd); + if (rc) + return -1; + } + + fyn = fy_node_by_path(fy_document_root(fyd), walkstart, FY_NT, FYNWF_DONT_FOLLOW); + if (!fyn) { + printf("could not find walkstart node %s\n", walkstart); + continue; + } + + fy_emit_document_to_file(fyd, flags, NULL); + + path = fy_node_get_path(fyn); + assert(path); + printf("# walking starting at %s\n", path); + free(path); + + fy_walk_result_list_init(&results); + fwr = fy_walk_result_alloc_rl(NULL); + assert(fwr); + fwr->type = fwrt_node_ref; + fwr->fyn = fyn; + result = fy_path_expr_execute(fypx, 0, expr, fwr, fpet_none); + + printf("\n"); + if (!result) { + printf("# no results\n"); + goto next; + } + + if (result->type == fwrt_node_ref) { + printf("# single reference result\n"); + + path = fy_node_get_path(result->fyn); + assert(path); + + printf("# %s\n", path); + free(path); + + fyd2 = fy_document_create(&fyp->cfg); + assert(fyd2); + + fyn2 = fy_node_copy(fyd2, result->fyn); + assert(fyn2); + + fy_document_set_root(fyd2, fyn2); + + fy_emit_document_to_file(fyd2, flags, NULL); + + fy_document_destroy(fyd2); + + goto next; + } + + printf("# multiple results\n"); + while ((fwr = fy_walk_result_list_pop(&result->refs)) != NULL) { + + if (fwr->type != fwrt_node_ref) { + fy_walk_result_free_rl(NULL, fwr); + continue; + } + + path = fy_node_get_path(fwr->fyn); + assert(path); + + printf("# %s\n", path); + free(path); + + fyd2 = fy_document_create(&fyp->cfg); + assert(fyd2); + + fyn2 = fy_node_copy(fyd2, fwr->fyn); + assert(fyn2); + + fy_document_set_root(fyd2, fyn2); + + printf("---\n"); + fy_emit_document_to_file(fyd2, flags, NULL); + + fy_document_destroy(fyd2); + + fy_walk_result_free_rl(NULL, fwr); + } +next: + fy_walk_result_free_rl(NULL, result); + + fy_parse_document_destroy(fyp, fyd); + + count++; + } + + fy_path_exec_unref(fypx); + + fy_path_expr_free(expr); + + fy_path_parser_close(fypp); + + fy_input_unref(fyi); + fy_path_parser_cleanup(fypp); + + return 0; +} + +int apply_flags_option(const char *arg, unsigned int *flagsp, + int (*modify_flags)(const char *what, unsigned int *flagsp)) +{ + const char *s, *e, *sn; + char *targ; + int len, ret; + + if (!arg || !flagsp || !modify_flags) + return -1; + + s = arg; + e = arg + strlen(s); + while (s < e) { + sn = strchr(s, ','); + if (!sn) + sn = e; + + len = sn - s; + targ = alloca(len + 1); + memcpy(targ, s, len); + targ[len] = '\0'; + + ret = modify_flags(targ, flagsp); + if (ret) + return ret; + + s = sn < e ? (sn + 1) : sn; + } + + return 0; +} + +static ssize_t callback_stdin_input(void *user, void *buf, size_t count) +{ + return fread(buf, 1, count, stdin); +} + +int main(int argc, char *argv[]) +{ + struct fy_parser ctx, *fyp = &ctx; + struct fy_parse_cfg cfg = { + .search_path = INCLUDE_DEFAULT, + .flags = (QUIET_DEFAULT ? FYPCF_QUIET : 0), + }; + enum fy_error_type error_level = FYET_MAX; + int color_diag = -1; + struct fy_input_cfg *fyic, *fyic_array = NULL; + int i, j, icount, rc, exitcode = EXIT_FAILURE, opt, lidx; + char *tmp, *s; + const char *mode = MODE_DEFAULT; + int indent = INDENT_DEFAULT; + int width = WIDTH_DEFAULT; + bool resolve = RESOLVE_DEFAULT; + bool sort = SORT_DEFAULT; + size_t chunk = CHUNK_DEFAULT; + const char *color = COLOR_DEFAULT; + const char *walkpath = "/"; + const char *walkstart = "/"; + bool use_callback = false; + bool null_output = false; + + fy_valgrind_check(&argc, &argv); + + while ((opt = getopt_long_only(argc, argv, "I:m:i:w:d:rsc:C:D:M:W:S:qh", lopts, &lidx)) != -1) { + switch (opt) { + case 'I': + tmp = alloca(strlen(cfg.search_path) + 1 + strlen(optarg) + 1); + s = tmp; + strcpy(s, cfg.search_path); + if (cfg.search_path && cfg.search_path[0]) { + s += strlen(cfg.search_path); + *s++ = ':'; + } + strcpy(s, optarg); + s += strlen(optarg); + *s = '\0'; + cfg.search_path = tmp; + break; + case 'm': + mode = optarg; + break; + case 'i': + indent = atoi(optarg); + break; + case 'w': + width = atoi(optarg); + break; + case 'd': + error_level = fy_string_to_error_type(optarg); + if (error_level == FYET_MAX) { + fprintf(stderr, "bad diag option %s\n", optarg); + display_usage(stderr, argv[0]); + } + break; + case 'r': + resolve = true; + cfg.flags |= FYPCF_RESOLVE_DOCUMENT; + break; + case 's': + sort = true; + break; + case 'c': + chunk = atoi(optarg); + break; + case 'C': + color = optarg; + if (!strcmp(color, "auto")) + color_diag = -1; + else if (!strcmp(color, "yes") || !strcmp(color, "1") || !strcmp(color, "on")) + color_diag = 1; + else if (!strcmp(color, "no") || !strcmp(color, "0") || !strcmp(color, "off")) + color_diag = 0; + else { + fprintf(stderr, "bad color option %s\n", optarg); + display_usage(stderr, argv[0]); + } + break; + case 'D': + /* XXX TODO if I'm ever bothered */ + break; + case 'M': + /* XXX TODO if I'm ever bothered */ + break; + case 'W': + walkpath = optarg; + break; + case 'S': + walkstart = optarg; + break; + case OPT_DISABLE_MMAP: + cfg.flags |= FYPCF_DISABLE_MMAP_OPT; + break; + case OPT_DISABLE_ACCEL: + cfg.flags |= FYPCF_DISABLE_ACCELERATORS; + break; + case OPT_DISABLE_BUFFERING: + cfg.flags |= FYPCF_DISABLE_BUFFERING; + break; + case OPT_DISABLE_DEPTH_LIMIT: + cfg.flags |= FYPCF_DISABLE_DEPTH_LIMIT; + break; + case OPT_USE_CALLBACK: + use_callback = true; + break; + case OPT_NULL_OUTPUT: + null_output = true; + break; + case OPT_YAML_1_1: + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_1; + break; + case OPT_YAML_1_2: + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_2; + break; + case OPT_YAML_1_3: + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_3; + break; + case OPT_SLOPPY_FLOW_INDENTATION: + cfg.flags |= FYPCF_SLOPPY_FLOW_INDENTATION; + break; + case OPT_YPATH_ALIASES: + cfg.flags |= FYPCF_YPATH_ALIASES; + break; + case 'q': + cfg.flags |= FYPCF_QUIET; + break; + case 'h' : + default: + if (opt != 'h') + fprintf(stderr, "Unknown option\n"); + display_usage(opt == 'h' ? stdout : stderr, argv[0]); + return EXIT_SUCCESS; + } + } + + /* check mode */ + if (strcmp(mode, "parse") && + strcmp(mode, "scan") && + strcmp(mode, "copy") && + strcmp(mode, "testsuite") && + strcmp(mode, "dump") && + strcmp(mode, "dump2") && + strcmp(mode, "build") && + strcmp(mode, "walk") && + strcmp(mode, "reader") && + strcmp(mode, "compose") && + strcmp(mode, "iterate") && + strcmp(mode, "comment") && + strcmp(mode, "pathspec") && + strcmp(mode, "bypath") +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML + && strcmp(mode, "libyaml-scan") + && strcmp(mode, "libyaml-parse") + && strcmp(mode, "libyaml-testsuite") + && strcmp(mode, "libyaml-dump") + && strcmp(mode, "libyaml-diff") +#endif + + ) { + fprintf(stderr, "Unknown mode %s\n", mode); + display_usage(opt == 'h' ? stdout : stderr, argv[0]); + } + + /* libyaml options are first */ +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML + if (!strcmp(mode, "libyaml-scan") || + !strcmp(mode, "libyaml-parse") || + !strcmp(mode, "libyaml-testsuite") || + !strcmp(mode, "libyaml-dump")) { + FILE *fp; + yaml_parser_t parser; + yaml_emitter_t emitter; + + if (optind >= argc) { + fprintf(stderr, "Missing file argument\n"); + goto cleanup; + } + + fp = fopen(argv[optind], "rb"); + if (!fp) { + fprintf(stderr, "Failed to open file %s\n", argv[optind]); + goto cleanup; + } + + rc = yaml_parser_initialize(&parser); + assert(rc); + rc = yaml_emitter_initialize(&emitter); + assert(rc); + + yaml_parser_set_input_file(&parser, fp); + yaml_emitter_set_output_file(&emitter, stdout); + + if (!strcmp(mode, "libyaml-scan")) { + rc = do_libyaml_scan(&parser); + if (rc < 0) { + fprintf(stderr, "do_libyaml_scan() error %d\n", rc); + fprintf(stderr, " problem='%s' context='%s'\n", parser.problem, parser.context); + } + } else if (!strcmp(mode, "libyaml-parse")) { + rc = do_libyaml_parse(&parser); + if (rc < 0) { + fprintf(stderr, "do_libyaml_parse() error %d\n", rc); + fprintf(stderr, " problem='%s' context='%s'\n", parser.problem, parser.context); + } + } else if (!strcmp(mode, "libyaml-testsuite")) { + rc = do_libyaml_testsuite(stdout, &parser, null_output); + if (rc < 0) { + fprintf(stderr, "do_libyaml_testsuite() error %d\n", rc); + fprintf(stderr, " problem='%s' context='%s'\n", parser.problem, parser.context); + } + } else if (!strcmp(mode, "libyaml-dump")) { + rc = do_libyaml_dump(&parser, &emitter, null_output); + if (rc < 0) { + fprintf(stderr, "do_libyaml_dump() error %d\n", rc); + if (parser.problem) + fprintf(stderr, " problem='%s' context='%s'\n", parser.problem, parser.context); + } + } else + rc = -1; + + yaml_parser_delete(&parser); + yaml_emitter_delete(&emitter); + + fclose(fp); + + return !rc ? EXIT_SUCCESS : EXIT_FAILURE; + } +#endif + +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML + /* set yaml 1.1 mode with sloppy indentation to match libyaml */ + if (!strcmp(mode, "libyaml-diff")) { + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_1; + cfg.flags |= FYPCF_SLOPPY_FLOW_INDENTATION; + } +#endif + + if (!strcmp(mode, "build")) { + rc = do_build(&cfg, argc - optind, argv + optind); + return !rc ? EXIT_SUCCESS : EXIT_FAILURE; + } + + if (!strcmp(mode, "pathspec")) { + rc = do_pathspec(argc - optind, argv + optind); + return !rc ? EXIT_SUCCESS : EXIT_FAILURE; + } + + /* turn on comment parsing for comment mode */ + if (!strcmp(mode, "comment")) + cfg.flags |= FYPCF_PARSE_COMMENTS; + + rc = fy_parse_setup(fyp, &cfg); + if (rc) { + fprintf(stderr, "fy_parse_setup() failed\n"); + goto cleanup; + } + + if (error_level != FYET_MAX) + fy_diag_set_level(fy_parser_get_diag(fyp), error_level); + if (color_diag != -1) + fy_diag_set_colorize(fy_parser_get_diag(fyp), !!color_diag); + + icount = argc - optind; + if (!icount) + icount++; + + fyic_array = alloca(sizeof(*fyic_array) * icount); + memset(fyic_array, 0, sizeof(*fyic_array) * icount); + + j = 0; + for (i = optind; i < argc; i++) { + fyic = &fyic_array[i - optind]; + if (!strcmp(argv[i], "-")) { + if (!use_callback) { + fyic->type = fyit_stream; + fyic->stream.name = "stdin"; + fyic->stream.fp = stdin; + fyic->stream.chunk = chunk; + } else { + fyic->type = fyit_callback; + fyic->userdata = stdin; + fyic->callback.input = callback_stdin_input; + } + } else { + fyic->type = fyit_file; + fyic->file.filename = argv[i]; + } + + rc = fy_parse_input_append(fyp, fyic); + if (rc) { + fprintf(stderr, "fy_input_append() failed\n"); + goto cleanup; + } + j++; + } + + if (!j) { + fyic = &fyic_array[0]; + + if (!use_callback) { + fyic->type = fyit_stream; + fyic->stream.name = "stdin"; + fyic->stream.fp = stdin; + fyic->stream.chunk = chunk; + } else { + fyic->type = fyit_callback; + fyic->userdata = stdin; + fyic->callback.input = callback_stdin_input; + } + + rc = fy_parse_input_append(fyp, fyic); + if (rc) { + fprintf(stderr, "fy_input_append() failed\n"); + goto cleanup; + } + } + + if (!strcmp(mode, "parse")) { + rc = do_parse(fyp); + if (rc < 0) { + /* fprintf(stderr, "do_parse() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "scan")) { + rc = do_scan(fyp); + if (rc < 0) { + fprintf(stderr, "do_scan() error %d\n", rc); + goto cleanup; + } + } else if (!strcmp(mode, "copy")) { + rc = do_copy(fyp); + if (rc < 0) { + fprintf(stderr, "do_copy() error %d\n", rc); + goto cleanup; + } + } else if (!strcmp(mode, "testsuite")) { + rc = do_testsuite(stdout, fyp, null_output); + if (rc < 0) { + /* fprintf(stderr, "do_testsuite() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "dump")) { + rc = do_dump(fyp, indent, width, resolve, sort, null_output); + if (rc < 0) { + /* fprintf(stderr, "do_dump() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "dump2")) { + rc = do_dump2(fyp, indent, width, resolve, sort, null_output); + if (rc < 0) { + /* fprintf(stderr, "do_dump() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "walk")) { + rc = do_walk(fyp, walkpath, walkstart, indent, width, resolve, sort); + if (rc < 0) { + /* fprintf(stderr, "do_walk() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "reader")) { + rc = do_reader(fyp, indent, width, resolve, sort); + if (rc < 0) { + /* fprintf(stderr, "do_reader() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "compose")) { + rc = do_compose(fyp, indent, width, resolve, sort, null_output); + if (rc < 0) { + /* fprintf(stderr, "do_compose() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "iterate")) { + rc = do_iterate(fyp); + if (rc < 0) { + /* fprintf(stderr, "do_iterate() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "comment")) { + rc = do_comment(fyp); + if (rc < 0) { + /* fprintf(stderr, "do_comment() error %d\n", rc); */ + goto cleanup; + } + } else if (!strcmp(mode, "bypath")) { + rc = do_bypath(fyp, walkpath, walkstart); + if (rc < 0) { + /* fprintf(stderr, "do_bypath() error %d\n", rc); */ + goto cleanup; + } + } +#if defined(HAVE_LIBYAML) && HAVE_LIBYAML + if (!strcmp(mode, "libyaml-diff")) { + FILE *fp; + // FILE *t1fp, *t2fp; + + yaml_parser_t parser; + + if (optind >= argc) { + fprintf(stderr, "Missing file argument\n"); + goto cleanup; + } + + fp = fopen(argv[optind], "rb"); + if (!fp) { + fprintf(stderr, "Failed to open file %s\n", argv[optind]); + goto cleanup; + } + + rc = yaml_parser_initialize(&parser); + assert(rc); + + yaml_parser_set_input_file(&parser, fp); + + fprintf(stdout, "LIBYAML:\n"); + rc = do_libyaml_testsuite(stdout, &parser, false); + if (rc < 0) { + fprintf(stderr, "do_libyaml_testsuite() failed\n"); + goto cleanup; + } + + fprintf(stdout, "LIBFYAML:\n"); + rc = do_testsuite(stdout, fyp, false); + if (rc < 0) { + fprintf(stderr, "do_libyaml_testsuite() failed\n"); + goto cleanup; + } + + yaml_parser_delete(&parser); + + fclose(fp); + + if (rc < 0) + goto cleanup; + } +#endif + + exitcode = EXIT_SUCCESS; + +cleanup: + fy_parse_cleanup(&ctx); + + return exitcode; +} diff --git a/src/lib/fy-accel.c b/src/lib/fy-accel.c new file mode 100644 index 0000000..1040078 --- /dev/null +++ b/src/lib/fy-accel.c @@ -0,0 +1,415 @@ +/* + * fy-accel.c - YAML accelerated access methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-doc.h" + +#include "fy-accel.h" + +#include "xxhash.h" + +/* powers of two and the closest primes before + * + * pow2: 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 + * prime: 1 2 3 7 13 31 61 127 251 509 1021 2039 4093 8191 16381 32749 65521 + * + * pow2: 131072 262144 524288 + * prime: 130657 262051 524201 + */ + +/* 64K bucket should be enough for everybody */ +static const uint32_t prime_lt_pow2[] = { + 1, 2, 3, 7, 13, 31, 61, 127, 251, 509, 1021, + 2039, 4093, 8191, 16381, 32749, 65521, + 130657, 262051, 524201 +}; + +static inline unsigned int +fy_accel_hash_to_pos(struct fy_accel *xl, const void *hash, unsigned int nbuckets) +{ + uint64_t pos; + + switch (xl->hd->size) { + case 1: + pos = *(const uint8_t *)hash; + break; + case 2: + assert(!((uintptr_t)hash & 1)); + pos = *(const uint16_t *)hash; + break; + case 4: + assert(!((uintptr_t)hash & 3)); + pos = *(const uint32_t *)hash; + break; + case 8: + assert(!((uintptr_t)hash & 7)); + pos = *(const uint64_t *)hash; + break; + default: + /* sigh, what ever */ + pos = XXH32(hash, xl->hd->size, 0); + break; + } + + return (unsigned int)(pos % nbuckets); +} + +static inline bool +fy_accel_hash_eq(struct fy_accel *xl, const void *hash1, const void *hash2) +{ + switch (xl->hd->size) { + case 1: + return *(const uint8_t *)hash1 == *(const uint8_t *)hash2; + case 2: + assert(!((uintptr_t)hash1 & 1)); + assert(!((uintptr_t)hash2 & 1)); + return *(const uint16_t *)hash1 == *(const uint16_t *)hash2; + case 4: + assert(!((uintptr_t)hash1 & 3)); + assert(!((uintptr_t)hash2 & 3)); + return *(const uint32_t *)hash1 == *(const uint32_t *)hash2; + case 8: + assert(!((uintptr_t)hash1 & 7)); + assert(!((uintptr_t)hash2 & 7)); + return *(const uint64_t *)hash1 == *(const uint64_t *)hash2; + default: + break; + } + + return !memcmp(hash1, hash2, xl->hd->size); +} + +int fy_accel_resize(struct fy_accel *xl, unsigned int min_buckets) +{ + unsigned int next_pow2, exp, i, nbuckets, pos; + struct fy_accel_entry_list *xlel; + struct fy_accel_entry *xle; + struct fy_accel_entry_list *buckets_new; + + /* get the next power of two larger or equal */ + next_pow2 = 1; + exp = 0; + while (next_pow2 < min_buckets && + exp < sizeof(prime_lt_pow2)/sizeof(prime_lt_pow2[0])) { + next_pow2 <<= 1; + exp++; + } + + nbuckets = prime_lt_pow2[exp]; + if (nbuckets == xl->nbuckets) + return 0; + + buckets_new = malloc(sizeof(*buckets_new) * nbuckets); + if (!buckets_new) + return -1; + + for (i = 0, xlel = buckets_new; i < nbuckets; i++, xlel++) + fy_accel_entry_list_init(xlel); + + if (xl->buckets) { + for (i = 0, xlel = xl->buckets; i < xl->nbuckets; i++, xlel++) { + while ((xle = fy_accel_entry_list_pop(xlel)) != NULL) { + pos = fy_accel_hash_to_pos(xl, xle->hash, nbuckets); + fy_accel_entry_list_add_tail(&buckets_new[pos], xle); + } + } + free(xl->buckets); + } + xl->buckets = buckets_new; + xl->nbuckets = nbuckets; + xl->next_exp2 = exp; + + return 0; +} + +int fy_accel_grow(struct fy_accel *xl) +{ + if (!xl) + return -1; + + /* should not grow indefinetely */ + if (xl->next_exp2 >= sizeof(prime_lt_pow2)/sizeof(prime_lt_pow2[0])) + return -1; + + return fy_accel_resize(xl, prime_lt_pow2[xl->next_exp2 + 1]); +} + +int fy_accel_shrink(struct fy_accel *xl) +{ + if (!xl) + return -1; + + /* should not shrink indefinetely */ + if (xl->next_exp2 <= 0) + return -1; + + return fy_accel_resize(xl, prime_lt_pow2[xl->next_exp2 - 1]); +} + +int +fy_accel_setup(struct fy_accel *xl, + const struct fy_hash_desc *hd, + void *userdata, + unsigned int min_buckets) +{ + if (!xl || !hd || !hd->size || !hd->hash) + return -1; + + memset(xl, 0, sizeof(*xl)); + xl->hd = hd; + xl->userdata = userdata; + xl->count = 0; + + return fy_accel_resize(xl, min_buckets); +} + +void fy_accel_cleanup(struct fy_accel *xl) +{ + unsigned int i; + struct fy_accel_entry_list *xlel; + struct fy_accel_entry *xle; + + if (!xl) + return; + + for (i = 0, xlel = xl->buckets; i < xl->nbuckets; i++, xlel++) { + while ((xle = fy_accel_entry_list_pop(xlel)) != NULL) { + free(xle); + assert(xl->count > 0); + xl->count--; + } + } + + free(xl->buckets); +} + +struct fy_accel_entry * +fy_accel_entry_insert(struct fy_accel *xl, const void *key, const void *value) +{ + struct fy_accel_entry *xle, *xlet; + struct fy_accel_entry_list *xlel; + unsigned int pos, bucket_size; + int rc; + + if (!xl) + return NULL; + + xle = malloc(sizeof(*xle) + xl->hd->size); + if (!xle) + goto err_out; + + rc = xl->hd->hash(xl, key, xl->userdata, xle->hash); + if (rc) + goto err_out; + xle->key = key; + xle->value = value; + + pos = fy_accel_hash_to_pos(xl, xle->hash, xl->nbuckets); + xlel = &xl->buckets[pos]; + + fy_accel_entry_list_add_tail(xlel, xle); + + assert(xl->count < UINT_MAX); + xl->count++; + + /* if we don't auto-resize, return */ + if (xl->hd->max_bucket_grow_limit) { + bucket_size = 0; + for (xlet = fy_accel_entry_list_first(xlel); xlet; xlet = fy_accel_entry_next(xlel, xlet)) { + bucket_size++; + if (bucket_size >= xl->hd->max_bucket_grow_limit) + break; + } + + /* we don't really care whether the grow up succeeds or not */ + if (bucket_size >= xl->hd->max_bucket_grow_limit) + (void)fy_accel_grow(xl); + } + + return xle; +err_out: + if (xle) + free(xle); + return NULL; +} + +struct fy_accel_entry * +fy_accel_entry_lookup(struct fy_accel *xl, const void *key) +{ + struct fy_accel_entry_iter xli; + struct fy_accel_entry *xle; + + xle = fy_accel_entry_iter_start(&xli, xl, key); + fy_accel_entry_iter_finish(&xli); + + return xle; +} + +struct fy_accel_entry * +fy_accel_entry_lookup_key_value(struct fy_accel *xl, const void *key, const void *value) +{ + struct fy_accel_entry_iter xli; + struct fy_accel_entry *xle; + + for (xle = fy_accel_entry_iter_start(&xli, xl, key); xle; + xle = fy_accel_entry_iter_next(&xli)) { + + if (xle->value == value) + break; + } + fy_accel_entry_iter_finish(&xli); + + return xle; +} + +void +fy_accel_entry_remove(struct fy_accel *xl, struct fy_accel_entry *xle) +{ + unsigned int pos; + + if (!xl || !xle) + return; + + pos = fy_accel_hash_to_pos(xl, xle->hash, xl->nbuckets); + + fy_accel_entry_list_del(&xl->buckets[pos], xle); + + assert(xl->count > 0); + xl->count--; + + free(xle); +} + +int +fy_accel_insert(struct fy_accel *xl, const void *key, const void *value) +{ + struct fy_accel_entry *xle; + + xle = fy_accel_entry_lookup(xl, key); + if (xle) + return -1; /* exists */ + + xle = fy_accel_entry_insert(xl, key, value); + if (!xle) + return -1; /* failure to insert */ + + return 0; +} + +const void * +fy_accel_lookup(struct fy_accel *xl, const void *key) +{ + struct fy_accel_entry *xle; + + xle = fy_accel_entry_lookup(xl, key); + return xle ? xle->value : NULL; +} + +int +fy_accel_remove(struct fy_accel *xl, const void *data) +{ + struct fy_accel_entry *xle; + + xle = fy_accel_entry_lookup(xl, data); + if (!xle) + return -1; + + fy_accel_entry_remove(xl, xle); + + return 0; +} + +struct fy_accel_entry * +fy_accel_entry_iter_next_internal(struct fy_accel_entry_iter *xli) +{ + struct fy_accel *xl; + struct fy_accel_entry *xle; + struct fy_accel_entry_list *xlel; + const void *key; + void *hash; + + if (!xli) + return NULL; + + xl = xli->xl; + hash = xli->hash; + xlel = xli->xlel; + if (!xl || !hash || !xlel) + return NULL; + key = xli->key; + + xle = !xli->xle ? fy_accel_entry_list_first(xlel) : + fy_accel_entry_next(xlel, xli->xle); + for (; xle; xle = fy_accel_entry_next(xlel, xle)) { + if (fy_accel_hash_eq(xl, hash, xle->hash) && + xl->hd->eq(xl, hash, xle->key, key, xl->userdata)) + break; + } + return xli->xle = xle; +} + +struct fy_accel_entry * +fy_accel_entry_iter_start(struct fy_accel_entry_iter *xli, struct fy_accel *xl, const void *key) +{ + unsigned int pos; + int rc; + + if (!xli || !xl) + return NULL; + xli->xl = xl; + xli->key = key; + if (xl->hd->size <= sizeof(xli->hash_inline)) + xli->hash = xli->hash_inline; + else + xli->hash = malloc(xl->hd->size); + xli->xlel = NULL; + + if (!xli->hash) + goto err_out; + + rc = xl->hd->hash(xl, key, xl->userdata, xli->hash); + if (rc) + goto err_out; + + pos = fy_accel_hash_to_pos(xl, xli->hash, xl->nbuckets); + xli->xlel = &xl->buckets[pos]; + + xli->xle = NULL; + + return fy_accel_entry_iter_next_internal(xli); + +err_out: + fy_accel_entry_iter_finish(xli); + return NULL; +} + +void fy_accel_entry_iter_finish(struct fy_accel_entry_iter *xli) +{ + if (!xli) + return; + + if (xli->hash && xli->hash != xli->hash_inline) + free(xli->hash); +} + +struct fy_accel_entry * +fy_accel_entry_iter_next(struct fy_accel_entry_iter *xli) +{ + if (!xli || !xli->xle) + return NULL; + + return fy_accel_entry_iter_next_internal(xli); +} diff --git a/src/lib/fy-accel.h b/src/lib/fy-accel.h new file mode 100644 index 0000000..1531e8c --- /dev/null +++ b/src/lib/fy-accel.h @@ -0,0 +1,92 @@ +/* + * fy-accel.h - YAML accelerated access methods + * + * Copyright (c) 2020 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_ACCEL_H +#define FY_ACCEL_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "fy-list.h" +#include "fy-typelist.h" + +struct fy_accel_entry { + struct list_head node; + const void *key; + const void *value; + uint8_t hash[0]; +}; +FY_TYPE_FWD_DECL_LIST(accel_entry); +FY_TYPE_DECL_LIST(accel_entry); + +struct fy_accel; + +struct fy_hash_desc { + unsigned int size; + unsigned int max_bucket_grow_limit; + bool unique; + int (*hash)(struct fy_accel *xl, const void *key, void *userdata, void *hash); + bool (*eq)(struct fy_accel *xl, const void *hash, const void *key1, const void *key2, void *userdata); +}; + +struct fy_accel { + const struct fy_hash_desc *hd; + void *userdata; + unsigned int count; + unsigned int nbuckets; + unsigned int next_exp2; + struct fy_accel_entry_list *buckets; +}; + +int +fy_accel_setup(struct fy_accel *xl, + const struct fy_hash_desc *hd, + void *userdata, + unsigned int min_buckets); + +void fy_accel_cleanup(struct fy_accel *xl); + +int fy_accel_resize(struct fy_accel *xl, unsigned int min_buckets); +int fy_accel_grow(struct fy_accel *xl); +int fy_accel_shrink(struct fy_accel *xl); + +int fy_accel_insert(struct fy_accel *xl, const void *key, const void *value); +const void *fy_accel_lookup(struct fy_accel *xl, const void *key); +int fy_accel_remove(struct fy_accel *xl, const void *key); + +struct fy_accel_entry_iter { + struct fy_accel *xl; + const void *key; + void *hash; + struct fy_accel_entry_list *xlel; + struct fy_accel_entry *xle; + uint64_t hash_inline[4]; /* to avoid allocation */ +}; + +struct fy_accel_entry * +fy_accel_entry_insert(struct fy_accel *xl, const void *key, const void *value); + +struct fy_accel_entry * +fy_accel_entry_lookup(struct fy_accel *xl, const void *key); +struct fy_accel_entry * +fy_accel_entry_lookup_key_value(struct fy_accel *xl, const void *key, const void *value); + +void fy_accel_entry_remove(struct fy_accel *xl, struct fy_accel_entry *xle); + +struct fy_accel_entry * +fy_accel_entry_iter_start(struct fy_accel_entry_iter *xli, + struct fy_accel *xl, const void *key); +void fy_accel_entry_iter_finish(struct fy_accel_entry_iter *xli); +struct fy_accel_entry * +fy_accel_entry_iter_next(struct fy_accel_entry_iter *xli); + +#endif diff --git a/src/lib/fy-atom.c b/src/lib/fy-atom.c new file mode 100644 index 0000000..9ce4a0d --- /dev/null +++ b/src/lib/fy-atom.c @@ -0,0 +1,1800 @@ +/* + * fy-atom.c - YAML atom methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 */ + fy_reader_fill_atom_start(fyr, handle); + + /* advance the given number of characters */ + if (advance > 0) + fy_reader_advance_by(fyr, advance); + + fy_reader_fill_atom_end(fyr, handle); + + return handle; +} + +int fy_reader_advance_mark(struct fy_reader *fyr, int advance, struct fy_mark *m) +{ + int i, c, tabsize; + bool is_line_break; + + tabsize = fy_reader_tabsize(fyr); + i = 0; + while (advance-- > 0) { + c = fy_reader_peek_at(fyr, i++); + if (c == -1) + return -1; + m->input_pos += fy_utf8_width(c); + + /* first check for CR/LF */ + if (c == '\r' && fy_reader_peek_at(fyr, i) == '\n') { + m->input_pos++; + i++; + is_line_break = true; + } else if (fy_reader_is_lb(fyr, c)) + is_line_break = true; + else + is_line_break = false; + + if (is_line_break) { + m->column = 0; + m->line++; + } else if (tabsize > 0 && fy_is_tab(c)) + m->column += (tabsize - (fy_reader_column(fyr) % tabsize)); + else + m->column++; + } + + return 0; +} + +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) +{ + if (!fyr || !start_mark || !end_mark || !handle) + return NULL; + + memset(handle, 0, sizeof(*handle)); + + handle->start_mark = *start_mark; + handle->end_mark = *end_mark; + handle->fyi = fy_reader_current_input(fyr); + handle->fyi_generation = fy_reader_current_input_generation(fyr); + + /* 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; + + return handle; +} + +struct fy_atom *fy_reader_fill_atom_at(struct fy_reader *fyr, int advance, int count, struct fy_atom *handle) +{ + struct fy_mark start_mark, end_mark; + int rc; + + if (!fyr || !handle) + return NULL; + + /* start mark */ + fy_reader_get_mark(fyr, &start_mark); + rc = fy_reader_advance_mark(fyr, advance, &start_mark); + (void)rc; + /* ignore the return, if the advance failed, it's the end of input */ + + /* end mark */ + end_mark = start_mark; + rc = fy_reader_advance_mark(fyr, count, &end_mark); + (void)rc; + /* ignore the return, if the advance failed, it's the end of input */ + + return fy_reader_fill_atom_mark(fyr, &start_mark, &end_mark, handle); +} + +static inline void +fy_atom_iter_chunk_reset(struct fy_atom_iter *iter) +{ + iter->top = 0; + iter->read = 0; +} + +static int +fy_atom_iter_grow_chunk(struct fy_atom_iter *iter) +{ + struct fy_atom_iter_chunk *chunks, *c; + size_t asz; + const char *old_s, *old_e, *ss; + unsigned int i; + size_t offset; + + old_s = (const char *)iter->chunks; + old_e = (const char *)(iter->chunks + iter->alloc); + + asz = sizeof(*chunks) * iter->alloc * 2; + chunks = realloc(iter->chunks == iter->startup_chunks ? NULL : iter->chunks, asz); + if (!chunks) /* out of memory */ + return -1; + if (iter->chunks == iter->startup_chunks) + memcpy(chunks, iter->startup_chunks, sizeof(iter->startup_chunks)); + + /* for chunks that point to the inplace buffer, reassign pointers */ + for (ss = old_s, c = chunks, i = 0; i < iter->top; ss += sizeof(*c), c++, i++) { + if (c->ic.str < old_s || c->ic.str >= old_e || + c->ic.len > sizeof(c->inplace_buf)) + continue; + + /* get offset */ + offset = (size_t)(c->ic.str - ss); + + /* verify that it points to the inplace_buf area */ + assert(offset >= offsetof(struct fy_atom_iter_chunk, inplace_buf)); + offset -= offsetof(struct fy_atom_iter_chunk, inplace_buf); + + c->ic.str = c->inplace_buf + offset; + } + + iter->alloc *= 2; + iter->chunks = chunks; + + return 0; +} + +static int +_fy_atom_iter_add_chunk(struct fy_atom_iter *iter, const char *str, size_t len) +{ + struct fy_atom_iter_chunk *c; + int ret; + + if (!len) + return 0; + + /* grow iter chunks? */ + if (iter->top >= iter->alloc) { + ret = fy_atom_iter_grow_chunk(iter); + if (ret) + return ret; + } + assert(iter->top < iter->alloc); + c = &iter->chunks[iter->top++]; + + c->ic.str = str; + c->ic.len = len; + + return 0; +} + +static int +_fy_atom_iter_add_chunk_copy(struct fy_atom_iter *iter, const char *str, size_t len) +{ + struct fy_atom_iter_chunk *c; + int ret; + + if (!len) + return 0; + + assert(len <= sizeof(c->inplace_buf)); + + if (iter->top >= iter->alloc) { + ret = fy_atom_iter_grow_chunk(iter); + if (ret) + return ret; + } + assert(iter->top < iter->alloc); + c = &iter->chunks[iter->top++]; + + memcpy(c->inplace_buf, str, len); + + c->ic.str = c->inplace_buf; + c->ic.len = len; + + return 0; +} + +/* keep it around without a warning even though it's unused */ +static int +_fy_atom_iter_add_utf8(struct fy_atom_iter *iter, int c) + __attribute__((__unused__)); + +static int +_fy_atom_iter_add_utf8(struct fy_atom_iter *iter, int c) +{ + char buf[FY_UTF8_FORMAT_BUFMIN]; + char *e; + + /* only fails if invalid utf8 */ + e = fy_utf8_put(buf, sizeof(buf), c); + if (!e) + return -1; + + return _fy_atom_iter_add_chunk_copy(iter, buf, e - buf); +} + +/* optimized linebreaks */ +static int +_fy_atom_iter_add_lb(struct fy_atom_iter *iter, int c) +{ + switch (c) { + /* those are generic linebreaks */ + case '\r': + case '\n': + case 0x85: + return _fy_atom_iter_add_chunk(iter, "\n", 1); + /* these are specific linebreaks */ + case 0x2028: + return _fy_atom_iter_add_chunk(iter, "\xe2\x80\xa8", 3); + case 0x2029: + return _fy_atom_iter_add_chunk(iter, "\xe2\x80\xa9", 3); + } + /* not a linebreak */ + return -1; +} + +// #define DEBUG_CHUNK + +#ifndef DEBUG_CHUNK +#define fy_atom_iter_add_chunk _fy_atom_iter_add_chunk +#define fy_atom_iter_add_chunk_copy _fy_atom_iter_add_chunk_copy +#define fy_atom_iter_add_utf8 _fy_atom_iter_add_utf8 +#define fy_atom_iter_add_lb _fy_atom_iter_add_lb +#else +#define fy_atom_iter_add_chunk(_iter, _str, _len) \ + ({ \ + const char *__str = (_str); \ + size_t __len2 = (_len); \ + char *__out = NULL; \ + int __ret = 0; \ + \ + if (__len2 > 0) { \ + __out = fy_utf8_format_text_alloc(__str, __len2, fyue_doublequote); \ + assert(__out); \ + fprintf(stderr, "%s:%d chunk #%zu \"%s\"\n", __func__, __LINE__, __len2, __out); \ + __ret = _fy_atom_iter_add_chunk((_iter), __str, __len2); \ + free(__out); \ + } \ + __ret; \ + }) + +#define fy_atom_iter_add_chunk_copy(_iter, _str, _len) \ + ({ \ + const char *__str = (_str); \ + size_t __len2 = (_len); \ + char *__out = NULL; \ + int __ret = 0; \ + \ + if (__len2 > 0) { \ + __out = fy_utf8_format_text_alloc(__str, __len2, fyue_doublequote); \ + assert(__out); \ + fprintf(stderr, "%s:%d chunk-copy #%zu \"%s\"\n", __func__, __LINE__, __len2, __out); \ + /* fprintf(stderr, "%s:%d chunk-copy \"%.*s\"\n", __func__, __LINE__, (int)__len, __str); */ \ + __ret = _fy_atom_iter_add_chunk_copy((_iter), __str, __len2); \ + free(__out); \ + } \ + __ret; \ + }) +#define fy_atom_iter_add_utf8(_iter, _c) \ + ({ \ + int __c = (_c); \ + fprintf(stderr, "%s:%d utf8 %d\n", __func__, __LINE__, __c); \ + _fy_atom_iter_add_utf8((_iter), (_c)); \ + }) +#define fy_atom_iter_add_lb(_iter, _c) \ + ({ \ + int __c = (_c); \ + fprintf(stderr, "%s:%d lb 0x%02x\n", __func__, __LINE__, __c); \ + _fy_atom_iter_add_lb((_iter), (_c)); \ + }) +#endif + +static void +fy_atom_iter_line_analyze(struct fy_atom_iter *iter, struct fy_atom_iter_line_info *li, + const char *line_start, size_t len) +{ + const struct fy_atom *atom = iter->atom; + const char *s, *e, *ss; + int col, c, w, ts, cws, advws; + bool last_was_ws, is_block; + + s = line_start; + e = line_start + len; + + is_block = atom->style == FYAS_LITERAL || atom->style == FYAS_FOLDED; + + /* short circuit non multiline, non ws atoms */ + if ((atom->direct_output && !atom->has_lb && !atom->has_ws) || + atom->style == FYAS_DOUBLE_QUOTED_MANUAL) { + li->start = s; + li->end = e; + li->nws_start = s; + li->nws_end = e; + li->chomp_start = s; + li->final = true; + li->empty = atom->empty; + li->trailing_breaks = 0; + li->trailing_breaks_ws = false; + li->start_ws = 0; + li->end_ws = 0; + li->indented = false; + li->lb_end = is_block ? atom->ends_with_lb : false; + li->final = true; + li->actual_lb = -1; + li->s_tb = li->e_tb = NULL; + li->ends_with_backslash = false; + return; + } + + li->start = s; + li->end = NULL; + li->nws_start = NULL; + li->nws_end = NULL; + li->chomp_start = NULL; + li->empty = true; + li->trailing_breaks = 0; + li->trailing_breaks_ws = false; + li->first = false; + li->start_ws = (size_t)-1; + li->end_ws = (size_t)-1; + li->indented = false; + li->lb_end = false; + li->final = false; + li->actual_lb = -1; + li->ends_with_backslash = false; + + last_was_ws = false; + + ts = atom->tabsize ? : 8; /* pick it up from the atom (if there is) */ + + /* consecutive whitespace */ + cws = 0; + + li->s_tb = s; + for (col = 0, ss = s; (c = fy_utf8_get(ss, (e - ss), &w)) >= 0; ss += w) { + + /* 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(c); + } + + if (fy_is_lb_m(c, atom->lb_mode)) { + +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d lb=0x%x\n", __FILE__, __LINE__, c); +#endif + + col = 0; + if (!li->end) { + + li->end = ss; + li->end_ws = cws; + li->lb_end = true; + li->actual_lb = c; + +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d set actual_lb=0x%x\n", __FILE__, __LINE__, li->actual_lb); +#endif + + cws = 0; + } + + /* no chomp point hit, use whatever we have here */ + if (is_block && !li->chomp_start) + li->chomp_start = ss; + + if (!last_was_ws) { + cws = 0; + li->nws_end = ss; + last_was_ws = true; + } + + } else if (fy_is_ws(c)) { + + advws = fy_is_space(c) ? 1 : (ts - (col % ts)); + col += advws; + cws += advws; + + if (!last_was_ws) { + li->nws_end = ss; + last_was_ws = true; + } + + } else { + /* mark start of non whitespace */ + if (!li->nws_start) + li->nws_start = ss; + + if (li->empty) + li->empty = false; + + if (li->start_ws == (size_t)-1) + li->start_ws = cws; + + last_was_ws = false; + cws = 0; + + col++; + } + + /* if we got both break */ + if (li->end && iter->chomp >= 0) + break; + } + li->e_tb = ss; + + li->final = c == -1; + + if (!last_was_ws) + li->nws_end = ss; + + if (!li->nws_start) + li->nws_start = ss; + + if (!li->nws_end) + li->nws_end = ss; + + /* if we haven't hit the chomp, point use whatever we're now */ + if (is_block && !li->chomp_start) + li->chomp_start = ss; + + if (li->start_ws == (size_t)-1) + li->start_ws = 0; + + if (li->end_ws == (size_t)-1) + li->end_ws = 0; + + /* mark next line to the end if no linebreak found */ + if (!li->end) { + li->end = iter->e; + li->last = true; + li->end_ws = cws; + li->lb_end = false; + goto out; + } + + /* find out if any trailing breaks exist afterwards */ + for (; (c = fy_utf8_get(ss, (e - ss), &w)) >= 0 && (fy_is_ws(c) || fy_is_lb_m(c, atom->lb_mode)); ss += w) { + + if (!li->trailing_breaks_ws && is_block && (unsigned int)col > iter->chomp) + li->trailing_breaks_ws = true; + + if (fy_is_lb_m(c, atom->lb_mode)) { + li->trailing_breaks++; + col = 0; + } else { + /* indented whitespace counts as break */ + if (fy_is_tab(c)) + col += (ts - (col % ts)); + else + col++; + } + + } + + /* and mark as last if only whitespace and breaks after this point */ + li->last = ss >= e; + +out: + assert(li->start); + assert(li->end); + assert(li->nws_start); + assert(li->nws_end); + assert(!is_block || li->chomp_start); + + li->ends_with_backslash = atom->style == FYAS_DOUBLE_QUOTED && + !li->empty && + (li->nws_end > li->nws_start && li->nws_end[-1] == '\\') && + ((li->nws_end - li->nws_start) <= 1 || li->nws_end[-2] != '\\'); +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d ends_with_backslash=%s\n", __FILE__, __LINE__, li->ends_with_backslash ? "true" : "false"); +#endif +} + +void fy_atom_iter_start(const struct fy_atom *atom, struct fy_atom_iter *iter) +{ + struct fy_atom_iter_line_info *li; + size_t len; + + if (!atom || !iter) + return; + + memset(iter, 0, sizeof(*iter)); + + iter->atom = atom; + iter->s = fy_atom_data(atom); + len = fy_atom_size(atom); + iter->e = iter->s + len; + + iter->chomp = atom->increment; + + /* default tab size is 8 */ + iter->tabsize = atom->tabsize ? : 8; + + memset(iter->li, 0, sizeof(iter->li)); + li = &iter->li[1]; + fy_atom_iter_line_analyze(iter, li, iter->s, len); + li->first = true; + + /* if there's single quote at the start of a line ending the atom */ + iter->dangling_end_quote = atom->end_mark.column == 0; + iter->single_line = atom->start_mark.line == atom->end_mark.line; + 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"); +#endif + + /* current is 0, next is 1 */ + iter->current = 0; + + iter->alloc = sizeof(iter->startup_chunks)/sizeof(iter->startup_chunks[0]); + iter->top = 0; + iter->read = 0; + iter->chunks = iter->startup_chunks; + + iter->done = false; + + iter->unget_c = -1; +} + +void fy_atom_iter_finish(struct fy_atom_iter *iter) +{ + if (iter->chunks && iter->chunks != iter->startup_chunks) + free(iter->chunks); + + iter->chunks = NULL; +} + +static const struct fy_atom_iter_line_info * +fy_atom_iter_line(struct fy_atom_iter *iter) +{ + const struct fy_atom *atom = iter->atom; + struct fy_atom_iter_line_info *li, *nli; + const char *ss; + + /* return while there's a next line */ + if (!iter) + return NULL; + + /* make next line the current one */ + iter->current = !iter->current; + + li = &iter->li[iter->current]; + + /* if we're out, we're out */ + if (li->start >= iter->e) + return NULL; + + /* scan next line (special handling for '\r\n') */ + ss = li->end; + if (ss < iter->e) { + if (*ss == '\r' && (ss + 1) < iter->e && ss[1] == '\n') + ss += 2; + else + ss += fy_utf8_width_by_first_octet((uint8_t)*ss); + } + + /* get current and next line */ + fy_atom_iter_line_analyze(iter, &iter->li[!iter->current], ss, iter->e - ss); + + /* if no more, mark the next as NULL */ + nli = &iter->li[!iter->current]; + if (nli->start >= iter->e) + nli = NULL; + + /* for quoted, output the white space start */ + if (atom->style == FYAS_SINGLE_QUOTED || atom->style == FYAS_DOUBLE_QUOTED) { + li->s = li->first ? li->start : li->nws_start; + li->e = li->last ? li->end : li->nws_end; + + /* just empty */ + if (li->empty && li->first && li->last && !iter->single_line) + li->s = li->e; + + } 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) + li->s = li->e; + } else { + li->s = li->nws_start; + li->e = li->nws_end; + } + + /* bah, I hate this, */ + if (li->s > li->e) + li->s = li->e; + + assert(li->s <= li->e); + + /* we never fold LS or PS linebreaks (on yaml 1.1) */ + li->need_nl = fy_is_lb_LS_PS(li->actual_lb) && fy_is_lb_m(li->actual_lb, iter->atom->lb_mode) && !li->ends_with_backslash; + li->need_sep = false; + +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d need_nl=%s\n", __FILE__, __LINE__, li->need_nl ? "true" : "false"); +#endif + if (li->need_nl) + return li; + + switch (atom->style) { + case FYAS_PLAIN: + case FYAS_URI: + li->need_nl = !li->last && li->empty; + li->need_sep = !li->need_nl && nli && !nli->empty; + break; + + case FYAS_DOUBLE_QUOTED_MANUAL: + li->need_nl = false; + li->need_sep = false; + break; + + case FYAS_COMMENT: + li->need_nl = !li->final; + li->need_sep = false; + break; + + case FYAS_DOUBLE_QUOTED: +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d ends_with_backslash=%s\n", __FILE__, __LINE__, li->ends_with_backslash ? "true" : "false"); +#endif + if (li->ends_with_backslash) { + + li->need_nl = false; + li->need_sep = false; + break; + } + + /* fall-through */ + case FYAS_SINGLE_QUOTED: + li->need_nl = (!li->last && !li->first && li->empty) || + (nli && iter->empty && !li->first); + + if (li->need_nl) + break; + + li->need_sep = (nli && !nli->empty) || + (!nli && li->last && iter->dangling_end_quote) || + (nli && nli->final && nli->empty); + + break; + case FYAS_LITERAL: + li->need_nl = true; + break; + case FYAS_FOLDED: + li->need_nl = !li->last && (li->empty || li->indented || li->trailing_breaks_ws || (nli && nli->indented)); + if (li->need_nl) + break; + li->need_sep = nli && !nli->indented && !nli->empty; + break; + default: + break; + } + + return li; +} + +static int +fy_atom_iter_format(struct fy_atom_iter *iter) +{ + const struct fy_atom *atom = iter->atom; + const struct fy_atom_iter_line_info *li; + const char *s, *e, *t; + int value, code_length, rlen, ret; + uint8_t code[4], *tt; + int j, pending_nl; + int *pending_lb = NULL, *pending_lb_new = NULL; + int pending_lb_size = 0; + enum fy_utf8_escape esc_mode; + size_t i; + + /* done? */ + li = fy_atom_iter_line(iter); + if (!li) { + iter->done = true; + return 0; + } + if (iter->done) + return 0; + + s = li->s; + e = li->e; + + switch (atom->style) { + + case FYAS_LITERAL: + case FYAS_PLAIN: + case FYAS_FOLDED: + case FYAS_COMMENT: + if (s < e) { + ret = fy_atom_iter_add_chunk(iter, s, e - s); + if (ret) + goto out; + } + + break; + + case FYAS_SINGLE_QUOTED: + if (li->last) + e = li->nws_end; + while (s < e) { + /* find next single quote */ + t = memchr(s, '\'', e - s); + rlen = (t ? t : e) - s; + + ret = fy_atom_iter_add_chunk(iter, s, rlen); + if (ret) + goto out; + + /* end of string */ + if (!t) + break; + + s = t; + /* next character single quote too */ + if ((e - s) >= 2 && s[1] == '\'') + fy_atom_iter_add_chunk(iter, s, 1); + + /* skip over this single quote char */ + s++; + } + break; + + case FYAS_DOUBLE_QUOTED: + if (li->last) + e = li->nws_end; + + esc_mode = atom->json_mode ? fyue_doublequote_json : + atom->lb_mode == fylb_cr_nl ? fyue_doublequote : fyue_doublequote_yaml_1_1; + + while (s < e) { + /* find next escape */ + t = memchr(s, '\\', e - s); + /* copy up to there (or end) */ + rlen = (t ? t : e) - s; + ret = fy_atom_iter_add_chunk(iter, s, rlen); + if (ret) + goto out; + + if (!t || (e - t) < 2) + break; + + ret = fy_utf8_parse_escape(&t, e - t, esc_mode); + if (ret < 0) + goto out; + s = t; + value = ret; + + tt = fy_utf8_put(code, sizeof(code), value); + if (!tt) { + ret = -1; + goto out; + } + + ret = fy_atom_iter_add_chunk_copy(iter, (const char *)code, tt - code); + if (ret) + goto out; + } + break; + + case FYAS_URI: + while (s < e) { + /* find next escape */ + t = memchr(s, '%', e - s); + rlen = (t ? t : e) - s; + ret = fy_atom_iter_add_chunk(iter, s, rlen); + if (ret) + goto out; + + /* end of string */ + if (!t) + break; + s = t; + + code_length = sizeof(code); + t = fy_uri_esc(s, e - s, code, &code_length); + if (!t) { + ret = -1; + goto out; + } + + /* output escaped utf8 */ + ret = fy_atom_iter_add_chunk_copy(iter, (const char *)code, code_length); + if (ret) + goto out; + s = t; + } + break; + + case FYAS_DOUBLE_QUOTED_MANUAL: + /* manual scalar just goes out */ + ret = fy_atom_iter_add_chunk(iter, s, e - s); + if (ret) + goto out; + s = e; + break; + + default: + ret = -1; + goto out; + } + + if (li->last) { + + if (fy_atom_style_is_block(atom->style)) { + + switch (atom->chomp) { + case FYAC_STRIP: + case FYAC_CLIP: + + pending_lb_size = 16; + pending_lb = alloca(sizeof(*pending_lb) * pending_lb_size); + + pending_nl = 0; + if (!li->empty) { + pending_lb[0] = li->actual_lb > 0 ? li->actual_lb : '\n'; + pending_nl = 1; + } + while ((li = fy_atom_iter_line(iter)) != NULL) { + if (!iter->empty && li->chomp_start < li->end) { + for (j = 0; j < pending_nl; j++) { + ret = fy_atom_iter_add_lb(iter, pending_lb[j]); + if (ret) + goto out; + } + pending_nl = 0; + + ret = fy_atom_iter_add_chunk(iter, li->chomp_start, li->end - li->chomp_start); + if (ret) + goto out; + } + if (li->lb_end && !iter->empty) { + if (pending_nl >= pending_lb_size) { + pending_lb_new = alloca(sizeof(*pending_lb) * pending_lb_size * 2); + memcpy(pending_lb_new, pending_lb, sizeof(*pending_lb) * pending_lb_size); + pending_lb_size *= 2; + pending_lb = pending_lb_new; + } + pending_lb[pending_nl] = li->actual_lb > 0 ? li->actual_lb : '\n'; + pending_nl++; + } + } + if (atom->chomp == FYAC_CLIP && pending_nl) { + ret = fy_atom_iter_add_lb(iter, pending_lb[0]); + if (ret) + goto out; + } + break; + case FYAC_KEEP: + if (li->lb_end) { + ret = fy_atom_iter_add_lb(iter, li->actual_lb > 0 ? li->actual_lb : '\n'); + if (ret) + goto out; + } + 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); + if (ret) + goto out; + } + if (li->lb_end) { + ret = fy_atom_iter_add_lb(iter, li->actual_lb > 0 ? li->actual_lb : '\n'); + if (ret) + goto out; + } + } + break; + } + + iter->done = true; + + } else { + +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d trailing_breaks=%zu end_ws=%zu empty=%s\n", __func__, __LINE__, + li->trailing_breaks, li->end_ws, + li->empty ? "true" : "false"); +#endif + + if (li->trailing_breaks == 0 && li->end_ws > 0) { + /* end of quote in a non-blank line having white space */ + ret = fy_atom_iter_add_chunk(iter, li->nws_end, (size_t)(li->e - li->nws_end)); + if (ret) + goto out; + } else if (li->trailing_breaks == 1) { + + if (atom->style == FYAS_DOUBLE_QUOTED) { +#ifdef DEBUG_CHUNK + fprintf(stderr, "%s:%d %s <>%d single trailing break %c\n", __FILE__, __LINE__, __func__, + (int)(li->s_tb - li->s), li->s_tb[-1]); +#endif + } + + if (!li->ends_with_backslash) { + ret = fy_atom_iter_add_chunk(iter, " ", 1); + if (ret) + goto out; + } + } else if (li->trailing_breaks > 1) { + for (i = 0; i < li->trailing_breaks - 1; i++) { + ret = fy_atom_iter_add_lb(iter, '\n'); + if (ret) + goto out; + } + } + + iter->done = true; + } + + } else { + if (li->need_sep) { + ret = fy_atom_iter_add_chunk(iter, " ", 1); + if (ret) + goto out; + } + + if (li->need_nl) { + ret = fy_atom_iter_add_lb(iter, li->actual_lb > 0 ? li->actual_lb : '\n'); + if (ret) + goto out; + } + } + + /* got more */ + ret = 1; + +out: + return ret; +} + +const struct fy_iter_chunk * +fy_atom_iter_peek_chunk(struct fy_atom_iter *iter) +{ + if (iter->read >= iter->top) + return NULL; + + return &iter->chunks[iter->read].ic; +} + +void fy_atom_iter_advance(struct fy_atom_iter *iter, size_t len) +{ + struct fy_atom_iter_chunk *ac; + size_t rlen; + + /* while more and not out */ + while (len > 0 && iter->read < iter->top) { + + ac = iter->chunks + iter->read; + + /* get next run length */ + rlen = len > ac->ic.len ? ac->ic.len : len; + + /* remove from chunk */ + ac->ic.str += rlen; + ac->ic.len -= rlen; + + /* advance if out of data */ + if (ac->ic.len == 0) + iter->read++; + + /* remove run from length */ + len -= rlen; + } + + /* reset when everything is gone */ + if (iter->read >= iter->top) + fy_atom_iter_chunk_reset(iter); +} + +const struct fy_iter_chunk * +fy_atom_iter_chunk_next(struct fy_atom_iter *iter, const struct fy_iter_chunk *curr, int *errp) +{ + const struct fy_iter_chunk *ic; + int ret; + + ic = fy_atom_iter_peek_chunk(iter); + if (curr && curr == ic) + fy_atom_iter_advance(iter, ic->len); + + /* need to pull in data? */ + ic = fy_atom_iter_peek_chunk(iter); + if (!curr || !ic) { + fy_atom_iter_chunk_reset(iter); + + do { + ret = fy_atom_iter_format(iter); + + /* either end or error, means we don't have data */ + if (ret <= 0) { + if (errp) + *errp = ret < 0 ? -1 : 0; + return NULL; + } + + } while (!fy_atom_iter_peek_chunk(iter)); + } + ic = fy_atom_iter_peek_chunk(iter); + if (errp) + *errp = 0; + return ic; +} + +int fy_atom_format_text_length(struct fy_atom *atom) +{ + struct fy_atom_iter iter; + const struct fy_iter_chunk *ic; + size_t len; + int ret; + + if (!atom) + return -1; + + if (atom->storage_hint_valid) + return atom->storage_hint; + + len = 0; + fy_atom_iter_start(atom, &iter); + ic = NULL; + while ((ic = fy_atom_iter_chunk_next(&iter, ic, &ret)) != NULL) + len += ic->len; + fy_atom_iter_finish(&iter); + + /* something funky going on here */ + if ((int)len < 0) + return -1; + + if (ret != 0) + return ret; + + atom->storage_hint = (size_t)len; + atom->storage_hint_valid = true; + return (int)len; +} + +const char *fy_atom_format_text(struct fy_atom *atom, char *buf, size_t maxsz) +{ + struct fy_atom_iter iter; + const struct fy_iter_chunk *ic; + char *s, *e; + int ret; + + if (!atom || !buf) + return NULL; + + s = buf; + e = s + maxsz; + fy_atom_iter_start(atom, &iter); + ic = NULL; + while ((ic = fy_atom_iter_chunk_next(&iter, ic, &ret)) != NULL) { + /* must fit */ + if ((size_t)(e - s) < ic->len) + return NULL; + memcpy(s, ic->str, ic->len); + s += ic->len; + } + fy_atom_iter_finish(&iter); + + if (ret != 0 || s >= e) + return NULL; + *s = '\0'; + + return buf; +} + +int fy_atom_format_utf8_length(struct fy_atom *atom) +{ + struct fy_atom_iter iter; + const struct fy_iter_chunk *ic; + const char *s, *e; + size_t len; + int ret, rem, run, w; + + if (!atom) + return -1; + + len = 0; + rem = 0; + fy_atom_iter_start(atom, &iter); + ic = NULL; + while ((ic = fy_atom_iter_chunk_next(&iter, ic, &ret)) != NULL) { + s = ic->str; + e = s + ic->len; + + /* add the remainder */ + run = (e - s) > rem ? rem : (e - s); + s += run; + + /* count utf8 characters */ + while (s < e) { + w = fy_utf8_width_by_first_octet(*(uint8_t *)s); + + /* how many bytes of this run */ + run = (e - s) > w ? w : (e - s); + /* the remainder of this run */ + rem = w - run; + /* one more character */ + len++; + /* and advance */ + s += run; + } + } + fy_atom_iter_finish(&iter); + + /* something funky going on here */ + if ((int)len < 0) + return -1; + + if (ret != 0) + return ret; + + return (int)len; +} + + +struct fy_atom_iter * +fy_atom_iter_create(const struct fy_atom *atom) +{ + struct fy_atom_iter *iter; + + iter = malloc(sizeof(*iter)); + if (!iter) + return NULL; + if (atom) + fy_atom_iter_start(atom, iter); + else + memset(iter, 0, sizeof(*iter)); + return iter; +} + +void fy_atom_iter_destroy(struct fy_atom_iter *iter) +{ + if (!iter) + return; + + fy_atom_iter_finish(iter); + free(iter); +} + +ssize_t fy_atom_iter_read(struct fy_atom_iter *iter, void *buf, size_t count) +{ + ssize_t nread; + size_t nrun; + const struct fy_iter_chunk *ic; + int ret; + + if (!iter || !buf) + return -1; + + ret = 0; + nread = 0; + while (count > 0) { + ic = fy_atom_iter_peek_chunk(iter); + if (ic) { + nrun = count > ic->len ? ic->len : count; + memcpy(buf, ic->str, nrun); + nread += nrun; + count -= nrun; + fy_atom_iter_advance(iter, nrun); + continue; + } + + fy_atom_iter_chunk_reset(iter); + do { + ret = fy_atom_iter_format(iter); + + /* either end or error, means we don't have data */ + if (ret <= 0) + return ret == 0 ? nread : -1; + + } while (!fy_atom_iter_peek_chunk(iter)); + } + + return nread; +} + +int fy_atom_iter_getc(struct fy_atom_iter *iter) +{ + uint8_t buf; + ssize_t nread; + int c; + + if (!iter) + return -1; + + /* first try the pushed ungetc */ + if (iter->unget_c != -1) { + c = iter->unget_c; + iter->unget_c = -1; + return c & 0xff; + } + + /* read first octet */ + nread = fy_atom_iter_read(iter, &buf, 1); + if (nread != 1) + return -1; + + return (int)buf & 0xff; +} + +int fy_atom_iter_ungetc(struct fy_atom_iter *iter, int c) +{ + if (!iter) + return -1; + + if (iter->unget_c != -1) + return -1; + if (c == -1) { + iter->unget_c = -1; + return 0; + } + iter->unget_c = c & 0xff; + return c & 0xff; +} + +int fy_atom_iter_peekc(struct fy_atom_iter *iter) +{ + int c; + + c = fy_atom_iter_getc(iter); + if (c == -1) + return -1; + + return fy_atom_iter_ungetc(iter, c); +} + +int fy_atom_iter_utf8_get(struct fy_atom_iter *iter) +{ + uint8_t buf[4]; /* maximum utf8 is 4 octets */ + ssize_t nread; + int c, w; + + if (!iter) + return -1; + + /* first try the pushed ungetc */ + if (iter->unget_c != -1) { + c = iter->unget_c; + iter->unget_c = -1; + return c & 0xff; + } + + /* read first octet */ + nread = fy_atom_iter_read(iter, &buf[0], 1); + if (nread != 1) + return -1; + + /* get width from it (0 means illegal) */ + w = fy_utf8_width_by_first_octet(buf[0]); + if (!w) + return -1; + + /* read the rest octets (if possible) */ + if (w > 1) { + nread = fy_atom_iter_read(iter, buf + 1, w - 1); + if (nread != (w - 1)) + return -1; + } + + /* and return the decoded utf8 character */ + return fy_utf8_get(buf, w, &w); +} + +int fy_atom_iter_utf8_quoted_get(struct fy_atom_iter *iter, size_t *lenp, uint8_t *buf) +{ + ssize_t nread; + int c, w, ww; + + if (!iter || !lenp || !buf || *lenp < 4) + return -1; + + /* first try the pushed ungetc */ + if (iter->unget_c != -1) { + c = iter->unget_c; + iter->unget_c = -1; + *lenp = 0; + return c & 0xff; + } + + /* read first octet */ + nread = fy_atom_iter_read(iter, &buf[0], 1); + if (nread != 1) + return -1; + + /* get width from it (0 means illegal) - return it and mark it */ + w = fy_utf8_width_by_first_octet(buf[0]); + if (!w) { + *lenp = 1; + return 0; + } + + /* read the rest octets (if possible) */ + if (w > 1) { + nread = fy_atom_iter_read(iter, buf + 1, w - 1); + if (nread != (w - 1)) { + if (nread != -1 && nread < (w - 1)) + *lenp += nread; + return 0; + } + } + + /* and return the decoded utf8 character */ + c = fy_utf8_get(buf, w, &ww); + if (c >= 0) { + *lenp = 0; + return c; + } + *lenp = w; + return 0; +} + +int fy_atom_iter_utf8_unget(struct fy_atom_iter *iter, int c) +{ + if (iter->unget_c != -1) + return -1; + if (c == -1) { + iter->unget_c = -1; + return 0; + } + iter->unget_c = c; + return c; +} + +int fy_atom_iter_utf8_peek(struct fy_atom_iter *iter) +{ + int c; + + c = fy_atom_iter_utf8_get(iter); + if (c == -1) + return -1; + + return fy_atom_iter_utf8_unget(iter, c); +} + +int fy_atom_memcmp(struct fy_atom *atom, const void *ptr, size_t len) +{ + const char *dstr, *str; + size_t dlen, tlen; + struct fy_atom_iter iter; + int c, ct, ret; + + /* empty? just fine */ + if (!atom && !ptr && !len) + return 0; + + /* empty atom but not ptr */ + if (!atom && (ptr || len)) + return -1; + + /* non empty atom and empty ptr */ + if (atom && (!ptr || !len)) + return 1; + + /* direct output, nice */ + if (atom->direct_output) { + dlen = fy_atom_size(atom); + dstr = fy_atom_data(atom); + tlen = dlen > len ? len : dlen; + ret = memcmp(dstr, ptr, tlen); + if (ret) + return ret; + + return dlen == len ? 0 : len > dlen ? -1 : 1; + } + + str = ptr; + ct = -1; + fy_atom_iter_start(atom, &iter); + while ((c = fy_atom_iter_getc(&iter)) >= 0 && len) { + ct = *str & 0xff; + if (ct != c) + break; + str++; + len--; + } + fy_atom_iter_finish(&iter); + + /* out of data on both */ + if (c == -1 && !len) + return 0; + + return ct > c ? -1 : 1; +} + +int fy_atom_strcmp(struct fy_atom *atom, const char *str) +{ + size_t len; + + len = str ? strlen(str) : 0; + + return fy_atom_memcmp(atom, str, len); +} + +bool fy_atom_is_number(struct fy_atom *atom) +{ + struct fy_atom_iter iter; + int c, len, dec, fract, enot; + bool first_zero; + + /* empty? just fine */ + if (!atom || atom->size0) + return false; + + len = 0; + + fy_atom_iter_start(atom, &iter); + + /* skip minus sign if it's there */ + c = fy_atom_iter_peekc(&iter); + if (c == '-') { + (void)fy_atom_iter_getc(&iter); + len++; + } + + /* skip digits */ + first_zero = false; + dec = 0; + while ((c = fy_atom_iter_peekc(&iter)) >= 0 && isdigit(c)) { + if (dec == 0 && c == '0') + first_zero = true; + else if (dec == 1 && first_zero) + return false; /* 0[0-9] is bad */ + (void)fy_atom_iter_getc(&iter); + dec++; + len++; + } + + /* no digits is bad */ + if (!dec) + return false; + + fract = 0; + /* dot? */ + c = fy_atom_iter_peekc(&iter); + if (c == '.') { + + (void)fy_atom_iter_getc(&iter); + len++; + /* skip decimal part */ + while ((c = fy_atom_iter_peekc(&iter)) >= 0 && isdigit(c)) { + (void)fy_atom_iter_getc(&iter); + len++; + fract++; + } + + /* . without fractional */ + if (!fract) + return false; + } + + enot = 0; + /* scientific notation */ + c = fy_atom_iter_peekc(&iter); + if (c == 'e' || c == 'E') { + (void)fy_atom_iter_getc(&iter); + len++; + + /* skip sign if it's there */ + c = fy_atom_iter_peekc(&iter); + if (c == '+' || c == '-') { + (void)fy_atom_iter_getc(&iter); + len++; + } + + /* skip exponent part */ + while ((c = fy_atom_iter_peekc(&iter)) >= 0 && isdigit(c)) { + (void)fy_atom_iter_getc(&iter); + len++; + enot++; + } + + if (!enot) + return false; + } + + c = fy_atom_iter_peekc(&iter); + + fy_atom_iter_finish(&iter); + + /* everything must be consumed (and something must) */ + return c < 0 && len > 0; +} + +int fy_atom_cmp(struct fy_atom *atom1, struct fy_atom *atom2) +{ + struct fy_atom_iter iter1, iter2; + const char *d1, *d2; + size_t l1, l2, l; + int c1, c2, ret; + + /* handles NULL case too */ + if (atom1 == atom2) + return true; + + /* either null, can't do */ + if (!atom1 || !atom2) + return false; + + /* direct output? */ + if (atom1->direct_output) { + d1 = fy_atom_data(atom1); + l1 = fy_atom_size(atom1); + } else { + d1 = NULL; + l1 = 0; + } + if (atom2->direct_output) { + d2 = fy_atom_data(atom2); + l2 = fy_atom_size(atom2); + } else { + d2 = NULL; + l2 = 0; + } + + /* we have both atoms with direct output */ + if (d1 && d2) { + l = l1 > l2 ? l2 : l1; + ret = memcmp(d1, d2, l); + if (ret) + return ret; + return l1 == l2 ? 0 : l2 > l1 ? -1 : 1; + } + + /* only atom2 is direct */ + if (d2) + return fy_atom_memcmp(atom1, d2, l2); + + /* only atom1 is direct, (note reversing sign) */ + if (d1) + return -fy_atom_memcmp(atom2, d1, l1); + + /* neither is direct, do it with iterators */ + fy_atom_iter_start(atom1, &iter1); + fy_atom_iter_start(atom2, &iter2); + do { + c1 = fy_atom_iter_getc(&iter1); + c2 = fy_atom_iter_getc(&iter2); + } while (c1 == c2 && c1 >= 0 && c2 >= 0); + fy_atom_iter_finish(&iter2); + fy_atom_iter_finish(&iter1); + + if (c1 == -1 && c2 == -1) + return 0; + + return c2 > c1 ? -1 : 1; +} + +const struct fy_raw_line * +fy_atom_raw_line_iter_next(struct fy_atom_raw_line_iter *iter) +{ + struct fy_raw_line *l; + int c, w, col, col8, count; + unsigned int ts; + const char *s; + + if (!iter || !iter->rs || iter->rs > iter->ae) + return NULL; + + l = &iter->line; + + ts = iter->atom->tabsize; + + /* track back to the start of the line */ + s = iter->rs; + + /* we allow a single zero size iteration */ + if (l->lineno > 0 && iter->rs >= iter->ae) + return NULL; + + while (s > iter->is) { + c = fy_utf8_get_right(iter->is, (int)(s - iter->is), &w); + if (c <= 0 || fy_is_lb_m(c, iter->atom->lb_mode)) + break; + s -= w; + } + + l->line_start = s; + col = col8 = 0; + count = 0; + c = -1; + w = 0; + + /* track until the start of the content */ + while (s < iter->as) { + c = fy_utf8_get(s, (int)(iter->ae - s), &w); + /* we should never hit that */ + if (c <= 0) + return NULL; + if (fy_is_tab(c)) { + col8 += (8 - (col8 % 8)); + if (ts) + col += (ts - (col % ts)); + else + col++; + } else if (!fy_is_lb_m(c, iter->atom->lb_mode)) { + col++; + col8++; + } else + return NULL; + count++; + + s += w; + } + /* mark start of content */ + l->content_start = s; + l->content_start_col = col; + l->content_start_col8 = col8; + l->content_start_count = count; + + /* track until the end of the content (or lb) */ + while (s < iter->ae) { + c = fy_utf8_get(s, (int)(iter->ae - s), &w); + /* we should never hit that */ + if (c <= 0) + return NULL; + if (fy_is_tab(c)) { + col8 += (8 - (col8 % 8)); + if (ts) + col += (ts - (col % ts)); + else + col++; + } else if (!fy_is_lb_m(c, iter->atom->lb_mode)) { + col++; + col8++; + } else + break; + count++; + + s += w; + } + + l->content_len = (size_t)(s - l->content_start); + l->content_count = count - l->content_start_count; + l->content_end_col = col; + l->content_end_col8 = col8; + + /* if the stop was due to end of the atom */ + if (s >= iter->ae) { + while (s < iter->ie) { + c = fy_utf8_get(s, (int)(iter->ie - s), &w); + /* just end of input */ + if (c <= 0) + break; + + if (fy_is_tab(c)) { + col8 += (8 - (col8 % 8)); + if (ts) + col += (ts - (col % ts)); + else + col++; + } else if (!fy_is_lb_m(c, iter->atom->lb_mode)) { + col++; + col8++; + } else + break; + count++; + + s += w; + } + } + + l->line_len = (size_t)(s - l->line_start); + l->line_count = count; + + if (fy_is_lb_m(c, iter->atom->lb_mode)) { + s += w; + /* special case for MSDOS */ + if (c == '\r' && (s < iter->ie && s[1] == '\n')) + s++; + /* len_lb includes the lb */ + l->line_len_lb = (size_t)(s - l->line_start); + } else + l->line_len_lb = l->line_len; + + /* start at line #1 */ + l->lineno++; + + iter->rs = s; + + return l; +} + +void fy_atom_raw_line_iter_start(const struct fy_atom *atom, + struct fy_atom_raw_line_iter *iter) +{ + struct fy_input *fyi; + + if (!atom || !iter) + return; + + memset(iter, 0, sizeof(*iter)); + + fyi = atom->fyi; + if (!fyi) + return; + + iter->atom = atom; + + iter->as = fy_atom_data(atom); + iter->ae = iter->as + fy_atom_size(atom); + + iter->is = fy_input_start(fyi); + iter->ie = iter->is + fy_input_size(fyi); + + iter->rs = iter->as; +} + +void fy_atom_raw_line_iter_finish(struct fy_atom_raw_line_iter *iter) +{ + /* nothing */ +} diff --git a/src/lib/fy-atom.h b/src/lib/fy-atom.h new file mode 100644 index 0000000..188f200 --- /dev/null +++ b/src/lib/fy-atom.h @@ -0,0 +1,288 @@ +/* + * fy-atom.h - internal YAML atom methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifndef FY_ATOM_H +#define FY_ATOM_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-list.h" +#include "fy-input.h" + +struct fy_reader; +struct fy_input; +struct fy_node; + +enum fy_atom_style { + /* YAML atoms */ + FYAS_PLAIN, + FYAS_SINGLE_QUOTED, + FYAS_DOUBLE_QUOTED, + FYAS_LITERAL, + FYAS_FOLDED, + FYAS_URI, /* special style for URIs */ + FYAS_DOUBLE_QUOTED_MANUAL, + FYAS_COMMENT /* (possibly multi line) comment */ +}; + +static inline bool fy_atom_style_is_quoted(enum fy_atom_style style) +{ + return style == FYAS_SINGLE_QUOTED || style == FYAS_DOUBLE_QUOTED; +} + +static inline bool fy_atom_style_is_block(enum fy_atom_style style) +{ + return style == FYAS_LITERAL || style == FYAS_FOLDED; +} + +enum fy_atom_chomp { + FYAC_STRIP, + FYAC_CLIP, + FYAC_KEEP, +}; + +struct fy_atom { + struct fy_mark start_mark; + struct fy_mark end_mark; + size_t storage_hint; /* guaranteed to fit in this amount of bytes */ + 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; +}; + +static inline bool fy_atom_is_set(const struct fy_atom *atom) +{ + return atom && atom->fyi; +} + +static inline void fy_atom_reset(struct fy_atom *atom) +{ + if (atom) + atom->fyi = NULL; +} + +static inline bool fy_atom_json_mode(struct fy_atom *handle) +{ + if (!handle) + return false; + + return handle->json_mode; +} + +static inline enum fy_lb_mode fy_atom_lb_mode(struct fy_atom *handle) +{ + if (!handle) + return fylb_cr_nl; + + return handle->lb_mode; +} + +static inline enum fy_flow_ws_mode fy_atom_flow_ws_mode(struct fy_atom *handle) +{ + if (!handle) + return fyfws_space_tab; + + return handle->fws_mode; +} + +/* all atoms are scalars so... */ +static inline bool fy_atom_is_lb(struct fy_atom *handle, int c) +{ + return fy_is_generic_lb_m(c, fy_atom_lb_mode(handle)); +} + +static inline bool fy_atom_is_flow_ws(struct fy_atom *handle, int c) +{ + return fy_is_flow_ws_m(c, fy_atom_flow_ws_mode(handle)); +} + +int fy_atom_format_text_length(struct fy_atom *atom); +const char *fy_atom_format_text(struct fy_atom *atom, char *buf, size_t maxsz); + +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); + +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); + +#define fy_reader_fill_atom_a(_fyr, _advance) fy_reader_fill_atom((_fyr), (_advance), alloca(sizeof(struct fy_atom))) + +struct fy_atom *fy_fill_node_atom(struct fy_node *fyn, struct fy_atom *handle); + +#define fy_fill_node_atom_a(_fyn) fy_fill_node_atom((_fyn), alloca(sizeof(struct fy_atom))) + +struct fy_atom_iter_line_info { + const char *start; + const char *end; + const char *nws_start; + const char *nws_end; + const char *chomp_start; + bool empty : 1; + bool trailing_breaks_ws : 1; + bool first : 1; /* first */ + bool last : 1; /* last (only ws/lb afterwards */ + bool final : 1; /* the final iterator */ + bool indented : 1; + bool lb_end : 1; + bool need_nl : 1; + bool need_sep : 1; + bool ends_with_backslash : 1; /* last ended in \\ */ + size_t trailing_ws; + size_t trailing_breaks; + size_t start_ws, end_ws; + const char *s; + const char *e; + int actual_lb; /* the line break */ + const char *s_tb; /* start of trailing breaks run */ + const char *e_tb; /* end of trailing breaks run */ +}; + +struct fy_atom_iter_chunk { + struct fy_iter_chunk ic; + /* note that it is guaranteed for copied chunks to be + * less or equal to 10 characters (the maximum digitbuf + * for double quoted escapes */ + char inplace_buf[10]; /* small copies in place */ +}; + +#define NR_STARTUP_CHUNKS 8 +#define SZ_STARTUP_COPY_BUFFER 32 + +struct fy_atom_iter { + const struct fy_atom *atom; + const char *s, *e; + unsigned int chomp; + int tabsize; + bool single_line : 1; + bool dangling_end_quote : 1; + bool last_ends_with_backslash : 1; + bool empty : 1; + bool current : 1; + bool done : 1; /* last iteration (for block styles) */ + struct fy_atom_iter_line_info li[2]; + unsigned int alloc; + unsigned int top; + unsigned int read; + struct fy_atom_iter_chunk *chunks; + struct fy_atom_iter_chunk startup_chunks[NR_STARTUP_CHUNKS]; + int unget_c; +}; + +void fy_atom_iter_start(const struct fy_atom *atom, struct fy_atom_iter *iter); +void fy_atom_iter_finish(struct fy_atom_iter *iter); +const struct fy_iter_chunk *fy_atom_iter_peek_chunk(struct fy_atom_iter *iter); +const struct fy_iter_chunk *fy_atom_iter_chunk_next(struct fy_atom_iter *iter, const struct fy_iter_chunk *curr, int *errp); +void fy_atom_iter_advance(struct fy_atom_iter *iter, size_t len); + +struct fy_atom_iter *fy_atom_iter_create(const struct fy_atom *atom); +void fy_atom_iter_destroy(struct fy_atom_iter *iter); +ssize_t fy_atom_iter_read(struct fy_atom_iter *iter, void *buf, size_t count); +int fy_atom_iter_getc(struct fy_atom_iter *iter); +int fy_atom_iter_ungetc(struct fy_atom_iter *iter, int c); +int fy_atom_iter_peekc(struct fy_atom_iter *iter); +int fy_atom_iter_utf8_get(struct fy_atom_iter *iter); +int fy_atom_iter_utf8_quoted_get(struct fy_atom_iter *iter, size_t *lenp, uint8_t *buf); +int fy_atom_iter_utf8_unget(struct fy_atom_iter *iter, int c); +int fy_atom_iter_utf8_peek(struct fy_atom_iter *iter); + +int fy_atom_memcmp(struct fy_atom *atom, const void *ptr, size_t len); +int fy_atom_strcmp(struct fy_atom *atom, const char *str); +bool fy_atom_is_number(struct fy_atom *atom); +int fy_atom_cmp(struct fy_atom *atom1, struct fy_atom *atom2); + +static inline const char *fy_atom_data(const struct fy_atom *atom) +{ + if (!atom) + return NULL; + + return fy_input_start(atom->fyi) + atom->start_mark.input_pos; +} + +static inline size_t fy_atom_size(const struct fy_atom *atom) +{ + if (!atom) + return 0; + + return atom->end_mark.input_pos - atom->start_mark.input_pos; +} + +static inline bool fy_plain_atom_streq(const struct fy_atom *atom, const char *str) +{ + size_t size = strlen(str); + + if (!atom || !str || atom->style != FYAS_PLAIN || fy_atom_size(atom) != size) + return false; + + return !memcmp(str, fy_atom_data(atom), size); +} + +struct fy_raw_line { + int lineno; + const char *line_start; + size_t line_len; + size_t line_len_lb; + size_t line_count; + const char *content_start; + size_t content_len; + size_t content_start_count; + size_t content_count; + int content_start_col; + int content_start_col8; /* this is the tab 8 */ + int content_end_col; + int content_end_col8; +}; + +struct fy_atom_raw_line_iter { + const struct fy_atom *atom; + const char *is, *ie; /* input start, end */ + const char *as, *ae; /* atom start, end */ + const char *rs; + struct fy_raw_line line; +}; + +void fy_atom_raw_line_iter_start(const struct fy_atom *atom, + struct fy_atom_raw_line_iter *iter); +void fy_atom_raw_line_iter_finish(struct fy_atom_raw_line_iter *iter); + +const struct fy_raw_line * +fy_atom_raw_line_iter_next(struct fy_atom_raw_line_iter *iter); + +#endif diff --git a/src/lib/fy-composer.c b/src/lib/fy-composer.c new file mode 100644 index 0000000..f44db63 --- /dev/null +++ b/src/lib/fy-composer.c @@ -0,0 +1,414 @@ +/* + * fy-composer.c - Composer support + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-doc.h" + +#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) +{ + struct fy_composer *fyc; + struct fy_path *fypp; + + /* verify configuration and mandatory ops */ + if (!cfg || !cfg->ops || + !cfg->ops->process_event) + return NULL; + + fyc = malloc(sizeof(*fyc)); + if (!fyc) + return NULL; + memset(fyc, 0, sizeof(*fyc)); + fyc->cfg = *cfg; + + fy_path_list_init(&fyc->paths); + fypp = fy_path_create(); + if (!fypp) + goto err_no_path; + fy_path_list_add_tail(&fyc->paths, fypp); + + return fyc; + +err_no_path: + free(fyc); + return NULL; + +} + +void fy_composer_destroy(struct fy_composer *fyc) +{ + struct fy_path *fypp; + + if (!fyc) + return; + + fy_diag_unref(fyc->cfg.diag); + while ((fypp = fy_path_list_pop(&fyc->paths)) != NULL) + fy_path_destroy(fypp); + free(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) +{ + const struct fy_composer_ops *ops; + struct fy_eventp *fyep; + struct fy_path_component *fypc, *fypc_last; + 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); + + fyep = container_of(fye, struct fy_eventp, e); + + ops = fyc->cfg.ops; + assert(ops); + + rc = 0; + + switch (fye->type) { + case FYET_MAPPING_START: + is_collection = true; + is_start = true; + is_end = false; + is_map = true; + break; + + case FYET_MAPPING_END: + is_collection = true; + is_start = false; + is_end = true; + is_map = true; + break; + + case FYET_SEQUENCE_START: + is_collection = true; + is_start = true; + is_end = false; + is_map = false; + break; + + case FYET_SEQUENCE_END: + is_collection = true; + is_start = false; + is_end = true; + is_map = false; + break; + + case FYET_SCALAR: + is_collection = false; + is_start = true; + is_end = true; + is_map = false; + break; + + case FYET_ALIAS: + is_collection = false; + is_start = true; + is_end = true; + is_map = false; + break; + + case FYET_STREAM_START: + 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); + + 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 != fypp); + assert(fyppt->parent == fypp); + + /* and pass along */ + ret = fy_composer_process_event_private(fyc, fyp, 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))); + 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, + "fy_document_builder_take_document() failed\n"); + + fypc_last->map.is_complex_key = true; + fypc_last->map.accumulating_complex_key = false; + fypc_last->map.complex_key = fyd; + fypc_last->map.has_key = true; + fypc_last->map.await_key = false; + fypc_last->map.complex_key_complete = true; + + 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"); + + return !stop_req ? FYCR_OK_CONTINUE : FYCR_OK_STOP; + } + + /* 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"); + + // fprintf(stderr, "initial complex key %s\n", + // fy_token_dump_format(fy_event_get_token(fye), tbuf, sizeof(tbuf))); + + /* 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); + fyc_error_check(fyc, !rc, err_out, + "fy_document_builder_process_event() failed\n"); + + fypc_last->map.is_complex_key = true; + fypc_last->map.accumulating_complex_key = true; + fypc_last->map.complex_key = NULL; + fypc_last->map.complex_key_complete = false; + + /* create new path */ + fyppt = fy_path_create(); + fyc_error_check(fyc, fyppt, err_out, + "fy_path_create() failed\n"); + + /* append it to the end */ + fyppt->parent = fypp; + fy_path_list_add_tail(&fyc->paths, fyppt); + + /* and pass along */ + ret = fy_composer_process_event_private(fyc, fyp, fye, fyppt); + if (!fy_composer_return_is_ok(ret)) { + /* XXX TODO handle skip */ + return ret; + } + if (!stop_req) + stop_req = ret == FYCR_OK_STOP; + + return !stop_req ? FYCR_OK_CONTINUE : FYCR_OK_STOP; + } + + if (is_start && fy_path_component_is_sequence(fypc_last)) { /* start in a sequence */ + + if (fypc_last->seq.idx < 0) + fypc_last->seq.idx = 0; + else + fypc_last->seq.idx++; + } + + if (is_collection && is_start) { + + /* collection start */ + if (is_map) { + fypc = fy_path_component_create_mapping(fypp); + fyc_error_check(fyc, fypc, err_out, + "fy_path_component_create_mapping() failed\n"); + } else { + fypc = fy_path_component_create_sequence(fypp); + fyc_error_check(fyc, fypc, err_out, + "fy_path_component_create_sequence() failed\n"); + } + + /* append to the tail */ + fy_path_component_list_add_tail(&fypp->components, fypc); + + } else if (is_collection && is_end) { + + /* collection end */ + assert(fypc_last); + fy_path_component_clear_state(fypc_last); + + } 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.has_key = true; + + } + + /* process the event */ + ret = ops->process_event(fyc, fypp, fyp, fye); + if (!fy_composer_return_is_ok(ret)) { + /* XXX TODO handle skip */ + return ret; + } + if (!stop_req) + stop_req = ret == FYCR_OK_STOP; + + if (is_collection && is_end) { + /* for the end of a collection, pop the last component */ + fypc = fy_path_component_list_pop_tail(&fypp->components); + assert(fypc); + + assert(fypc == fypc_last); + + fy_path_component_recycle(fypp, fypc); + + /* and get the new last */ + fypc_last = fy_path_component_list_tail(&fypp->components); + } + + /* 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 { + 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: + return FYCR_ERROR; +} + +enum fy_composer_return +fy_composer_process_event(struct fy_composer *fyc, struct fy_parser *fyp, struct fy_event *fye) +{ + struct fy_path *fypp; + int rc; + + if (!fyc || !fyp || !fye) + return -1; + + /* start at the head */ + fypp = fy_path_list_head(&fyc->paths); + + /* no top? something's very out of order */ + if (!fypp) + return -1; + + rc = fy_composer_process_event_private(fyc, fyp, fye, fypp); + + return rc; +} + +struct fy_composer_cfg *fy_composer_get_cfg(struct fy_composer *fyc) +{ + if (!fyc) + return NULL; + return &fyc->cfg; +} + +void *fy_composer_get_cfg_userdata(struct fy_composer *fyc) +{ + if (!fyc) + return NULL; + return fyc->cfg.userdata; +} + +struct fy_diag *fy_composer_get_diag(struct fy_composer *fyc) +{ + if (!fyc) + 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; +} diff --git a/src/lib/fy-composer.h b/src/lib/fy-composer.h new file mode 100644 index 0000000..4cfea8d --- /dev/null +++ b/src/lib/fy-composer.h @@ -0,0 +1,59 @@ +/* + * fy-composer.h - YAML composer + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_COMPOSER_H +#define FY_COMPOSER_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "fy-list.h" +#include "fy-typelist.h" + +#include "fy-emit-accum.h" +#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_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); +}; + +struct fy_composer_cfg { + const struct fy_composer_ops *ops; + void *userdata; + struct fy_diag *diag; +}; + +struct fy_composer { + struct fy_composer_cfg cfg; + struct fy_path_list paths; +}; + +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); + +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 diff --git a/src/lib/fy-ctype.c b/src/lib/fy-ctype.c new file mode 100644 index 0000000..560fec6 --- /dev/null +++ b/src/lib/fy-ctype.c @@ -0,0 +1,66 @@ +/* + * fy-ctype.c - ctype utilities + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "fy-ctype.h" + +const char *fy_uri_esc(const char *s, size_t len, uint8_t *code, int *code_len) +{ + const char *e = s + len; + int j, k, width; + uint8_t octet; + char c; + + width = 0; + k = 0; + do { + /* check for enough space for %XX */ + if ((e - s) < 3) + return NULL; + + /* if more than one run, expect '%' */ + if (s[0] != '%') + return NULL; + + octet = 0; + for (j = 0; j < 2; j++) { + c = s[1 + j]; + octet <<= 4; + if (c >= '0' && c <= '9') + octet |= c - '0'; + else if (c >= 'a' && c <= 'f') + octet |= 10 + c - 'a'; + else + octet |= 10 + c - 'A'; + } + if (!width) { + width = fy_utf8_width_by_first_octet(octet); + if (!width) + return NULL; + k = 0; + } + if (k >= *code_len) + return NULL; + + code[k++] = octet; + + /* skip over the 3 character escape */ + s += 3; + + } while (--width > 0); + + *code_len = k; + + return s; +} + diff --git a/src/lib/fy-ctype.h b/src/lib/fy-ctype.h new file mode 100644 index 0000000..5f39fab --- /dev/null +++ b/src/lib/fy-ctype.h @@ -0,0 +1,337 @@ +/* + * fy-ctype.h - ctype like macros header + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_CTYPE_H +#define FY_CTYPE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-utf8.h" + +enum fy_lb_mode { + fylb_cr_nl, /* only \r, \n (json + >= yaml1.2 */ + fylb_cr_nl_N_L_P, /* NEL/LS/PS (yaml1.1) */ +}; + +enum fy_flow_ws_mode { + fyfws_space_tab, /* space + TAB (yaml) */ + fyfws_space, /* only space (json) */ +}; + +static inline bool fy_is_first_alpha(int c) +{ + return (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + c == '_'; +} + +static inline bool fy_is_alpha(int c) +{ + return fy_is_first_alpha(c) || c == '-'; +} + +static inline bool fy_is_num(int c) +{ + return c >= '0' && c <= '9'; +} + +static inline bool fy_is_first_alnum(int c) +{ + return fy_is_first_alpha(c); +} + +static inline bool fy_is_alnum(int c) +{ + return fy_is_alpha(c) || fy_is_num(c); +} + +static inline bool fy_is_space(int c) +{ + return c == ' '; +} + +static inline bool fy_is_tab(int c) +{ + return c == '\t'; +} + +static inline bool fy_is_ws(int c) +{ + return fy_is_space(c) || fy_is_tab(c); +} + +static inline bool fy_is_hex(int c) +{ + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F'); +} + +static inline bool fy_is_uri(int c) +{ + return fy_is_alnum(c) || fy_utf8_strchr(";/?:@&=+$,.!~*\'()[]%", c); +} + +static inline bool fy_is_lb_r_n(int c) +{ + return c == '\r' || c == '\n'; +} + +static inline bool fy_is_lb_NEL(int c) +{ + return c == 0x85; +} + +static inline bool fy_is_lb_LS_PS(int c) +{ + return c == 0x2028 || c == 0x2029; +} + +static inline bool fy_is_unicode_lb(int c) +{ + /* note that YAML1.1 supports NEL #x85, LS #x2028 and PS #x2029 as linebreaks */ + /* YAML1.2 and higher does not */ + return fy_is_lb_NEL(c) || fy_is_lb_LS_PS(c); +} + +static inline bool fy_is_any_lb(int c) +{ + return fy_is_lb_r_n(c) || fy_is_unicode_lb(c); +} + +static inline bool fy_is_z(int c) +{ + return c <= 0; +} + +static inline bool fy_is_blank(int c) +{ + return c == ' ' || c == '\t'; +} + +#define FY_UTF8_BOM 0xfeff + +static inline bool fy_is_print(int c) +{ + return c == '\n' || c == '\r' || + (c >= 0x0020 && c <= 0x007e) || + (c >= 0x00a0 && c <= 0xd7ff) || + (c >= 0xe000 && c <= 0xfffd && c != FY_UTF8_BOM); +} + +static inline bool fy_is_printq(int c) +{ + return c != '\t' && c != 0xa0 && !fy_is_any_lb(c) && fy_is_print(c); +} + +static inline bool fy_is_nb_char(int c) +{ + return (c >= 0x0020 && c <= 0x007e) || + (c >= 0x00a0 && c <= 0xd7ff) || + (c >= 0xe000 && c <= 0xfffd && c != FY_UTF8_BOM); +} + +static inline bool fy_is_ns_char(int c) +{ + return fy_is_nb_char(c) && !fy_is_ws(c); +} + +static inline bool fy_is_indicator(int c) +{ + return !!fy_utf8_strchr("-?:,[]{}#&*!|>'\"%%@`", c); +} + +static inline bool fy_is_flow_indicator(int c) +{ + return !!fy_utf8_strchr(",[]{}", c); +} + +static inline bool fy_is_path_flow_scalar_start(int c) +{ + return c == '\'' || c == '"'; +} + +static inline bool fy_is_path_flow_key_start(int c) +{ + return c == '"' || c == '\'' || c == '{' || c == '['; +} + +static inline bool fy_is_path_flow_key_end(int c) +{ + return c == '"' || c == '\'' || c == '}' || c == ']'; +} + +static inline bool fy_is_unicode_control(int c) +{ + return (c >= 0 && c <= 0x1f) || (c >= 0x80 && c <= 0x9f); +} + +static inline bool fy_is_unicode_space(int c) +{ + return c == 0x20 || c == 0xa0 || + (c >= 0x2000 && c <= 0x200a) || + c == 0x202f || c == 0x205f || c == 0x3000; +} + +static inline bool fy_is_json_unescaped(int c) +{ + return c >= 0x20 && c <= 0x110000 && c != '"' && c != '\\'; +} + +static inline bool fy_is_json_unescaped_range_only(int c) +{ + return c >= 0x20 && c <= 0x110000; +} + +static inline bool fy_is_lb_m(int c, enum fy_lb_mode lb_mode) +{ + if (fy_is_lb_r_n(c)) + return true; + return lb_mode == fylb_cr_nl_N_L_P && fy_is_unicode_lb(c); +} + +static inline bool fy_is_generic_lb_m(int c, enum fy_lb_mode lb_mode) +{ + if (fy_is_lb_r_n(c)) + return true; + return lb_mode == fylb_cr_nl_N_L_P && fy_is_lb_NEL(c); +} + +static inline bool fy_is_lbz_m(int c, enum fy_lb_mode lb_mode) +{ + return fy_is_lb_m(c, lb_mode) || fy_is_z(c); +} + +static inline bool fy_is_generic_lbz_m(int c, enum fy_lb_mode lb_mode) +{ + return fy_is_generic_lb_m(c, lb_mode) || fy_is_z(c); +} + +static inline bool fy_is_blankz_m(int c, enum fy_lb_mode lb_mode) +{ + return fy_is_ws(c) || fy_is_lbz_m(c, lb_mode); +} + +static inline bool fy_is_generic_blankz_m(int c, enum fy_lb_mode lb_mode) +{ + return fy_is_ws(c) || fy_is_generic_lbz_m(c, lb_mode); +} + +static inline bool fy_is_flow_ws_m(int c, enum fy_flow_ws_mode fws_mode) +{ + return fy_is_space(c) || (fws_mode == fyfws_space_tab && fy_is_tab(c)); +} + +#define FY_CTYPE_AT_BUILDER(_kind) \ +static inline const void * \ +fy_find_ ## _kind (const void *s, size_t len) \ +{ \ + const void *e = s + len; \ + int c, w; \ + for (; s < e && (c = fy_utf8_get(s, e - s, &w)) >= 0; s += w) { \ + assert(w); \ + if (fy_is_ ## _kind (c)) \ + return s; \ + } \ + return NULL; \ +} \ +static inline const void * \ +fy_find_non_ ## _kind (const void *s, size_t len) \ +{ \ + const void *e = s + len; \ + int c, w; \ + for (; s < e && (c = fy_utf8_get(s, e - s, &w)) >= 0; s += w) { \ + assert(w); \ + if (!(fy_is_ ## _kind (c))) \ + return s; \ + assert(w); \ + } \ + return NULL; \ +} \ +struct useless_struct_for_semicolon + +FY_CTYPE_AT_BUILDER(first_alpha); +FY_CTYPE_AT_BUILDER(alpha); +FY_CTYPE_AT_BUILDER(num); +FY_CTYPE_AT_BUILDER(first_alnum); +FY_CTYPE_AT_BUILDER(alnum); +FY_CTYPE_AT_BUILDER(space); +FY_CTYPE_AT_BUILDER(tab); +FY_CTYPE_AT_BUILDER(ws); +FY_CTYPE_AT_BUILDER(hex); +FY_CTYPE_AT_BUILDER(uri); +FY_CTYPE_AT_BUILDER(z); +FY_CTYPE_AT_BUILDER(any_lb); +FY_CTYPE_AT_BUILDER(blank); +FY_CTYPE_AT_BUILDER(print); +FY_CTYPE_AT_BUILDER(printq); +FY_CTYPE_AT_BUILDER(nb_char); +FY_CTYPE_AT_BUILDER(ns_char); +FY_CTYPE_AT_BUILDER(indicator); +FY_CTYPE_AT_BUILDER(flow_indicator); +FY_CTYPE_AT_BUILDER(path_flow_key_start); +FY_CTYPE_AT_BUILDER(path_flow_key_end); +FY_CTYPE_AT_BUILDER(unicode_control); +FY_CTYPE_AT_BUILDER(unicode_space); +FY_CTYPE_AT_BUILDER(json_unescaped); + +/* + * Very special linebreak/ws methods + * Things get interesting due to \r\n and + * unicode linebreaks/spaces + */ + +/* skip for a _single_ linebreak */ +static inline const void *fy_skip_lb(const void *ptr, int left) +{ + int c, width; + + /* get the utf8 character at this point */ + c = fy_utf8_get(ptr, left, &width); + if (c < 0 || !fy_is_any_lb(c)) + return NULL; + + /* MS-DOS: check if next character is '\n' */ + if (c == '\r' && left > width && *(char *)ptr == '\n') + width++; + + return ptr + width; +} + +/* given a pointer to a chunk of memory, return pointer to first + * ws character after the last non-ws character, or the end + * of the chunk + */ +static inline const void *fy_last_non_ws(const void *ptr, int left) +{ + const char *s, *e; + int c; + + s = ptr; + e = s + left; + while (e > s) { + c = e[-1]; + if (c != ' ' && c != '\t') + return e; + e--; + + } + return NULL; +} + +const char *fy_uri_esc(const char *s, size_t len, uint8_t *code, int *code_len); + +#endif diff --git a/src/lib/fy-diag.c b/src/lib/fy-diag.c new file mode 100644 index 0000000..4820226 --- /dev/null +++ b/src/lib/fy-diag.c @@ -0,0 +1,930 @@ +/* + * fy-diag.c - diagnostics + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" + +static const char *error_type_txt[] = { + [FYET_DEBUG] = "debug", + [FYET_INFO] = "info", + [FYET_NOTICE] = "notice", + [FYET_WARNING] = "warning", + [FYET_ERROR] = "error", +}; + +const char *fy_error_type_to_string(enum fy_error_type type) +{ + + if ((unsigned int)type >= FYET_MAX) + return ""; + return error_type_txt[type]; +} + +enum fy_error_type fy_string_to_error_type(const char *str) +{ + unsigned int i; + int level; + + if (!str) + return FYET_MAX; + + if (isdigit(*str)) { + level = atoi(str); + if (level >= 0 && level < FYET_MAX) + return (enum fy_error_type)level; + } + + for (i = 0; i < FYET_MAX; i++) { + if (!strcmp(str, error_type_txt[i])) + return (enum fy_error_type)i; + } + + return FYET_MAX; +} + +static const char *error_module_txt[] = { + [FYEM_UNKNOWN] = "unknown", + [FYEM_ATOM] = "atom", + [FYEM_SCAN] = "scan", + [FYEM_PARSE] = "parse", + [FYEM_DOC] = "doc", + [FYEM_BUILD] = "build", + [FYEM_INTERNAL] = "internal", + [FYEM_SYSTEM] = "system", +}; + +const char *fy_error_module_to_string(enum fy_error_module module) +{ + + if ((unsigned int)module >= FYEM_MAX) + return ""; + return error_module_txt[module]; +} + +enum fy_error_module fy_string_to_error_module(const char *str) +{ + unsigned int i; + + if (!str) + return FYEM_MAX; + + for (i = 0; i < FYEM_MAX; i++) { + if (!strcmp(str, error_module_txt[i])) + return (enum fy_error_module)i; + } + + return FYEM_MAX; +} + +static const char *fy_error_level_str(enum fy_error_type level) +{ + static const char *txt[] = { + [FYET_DEBUG] = "DBG", + [FYET_INFO] = "INF", + [FYET_NOTICE] = "NOT", + [FYET_WARNING] = "WRN", + [FYET_ERROR] = "ERR", + }; + + if ((unsigned int)level >= FYET_MAX) + return "*unknown*"; + return txt[level]; +} + +static const char *fy_error_module_str(enum fy_error_module module) +{ + static const char *txt[] = { + [FYEM_UNKNOWN] = "UNKWN", + [FYEM_ATOM] = "ATOM ", + [FYEM_SCAN] = "SCAN ", + [FYEM_PARSE] = "PARSE", + [FYEM_DOC] = "DOC ", + [FYEM_BUILD] = "BUILD", + [FYEM_INTERNAL] = "INTRL", + [FYEM_SYSTEM] = "SYSTM", + }; + + if ((unsigned int)module >= FYEM_MAX) + return "*unknown*"; + return txt[module]; +} + +static const struct fy_diag_cfg default_diag_cfg_template = { + .fp = NULL, /* must be overriden */ + .level = FYET_INFO, + .module_mask = (1U << FYEM_MAX) - 1, /* all modules */ + .show_source = false, + .show_position = false, + .show_type = true, + .show_module = false, + .colorize = false, /* can be overriden */ + .source_width = 50, + .position_width = 10, + .type_width = 5, + .module_width = 6, +}; + +void fy_diag_cfg_default(struct fy_diag_cfg *cfg) +{ + if (!cfg) + return; + + *cfg = default_diag_cfg_template; + cfg->fp = stderr; + cfg->colorize = isatty(fileno(stderr)) == 1; +} + +void fy_diag_cfg_from_parser_flags(struct fy_diag_cfg *cfg, enum fy_parse_cfg_flags pflags) +{ + /* nothing */ +} + +struct fy_diag *fy_diag_create(const struct fy_diag_cfg *cfg) +{ + struct fy_diag *diag; + + diag = malloc(sizeof(*diag)); + if (!diag) + return NULL; + memset(diag, 0, sizeof(*diag)); + + if (!cfg) + fy_diag_cfg_default(&diag->cfg); + else + diag->cfg = *cfg; + diag->on_error = false; + diag->refs = 1; + + return diag; +} + +void fy_diag_destroy(struct fy_diag *diag) +{ + if (!diag) + return; + + diag->destroyed = true; + + return fy_diag_unref(diag); +} + +bool fy_diag_got_error(struct fy_diag *diag) +{ + return diag && diag->on_error; +} + +void fy_diag_reset_error(struct fy_diag *diag) +{ + if (!diag) + return; + + diag->on_error = false; +} + +/** + * 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_free(struct fy_diag *diag) +{ + if (!diag) + return; + free(diag); +} + +const struct fy_diag_cfg *fy_diag_get_cfg(struct fy_diag *diag) +{ + if (!diag) + return NULL; + return &diag->cfg; +} + +void fy_diag_set_cfg(struct fy_diag *diag, const struct fy_diag_cfg *cfg) +{ + if (!diag) + return; + + if (!cfg) { + fy_diag_cfg_default(&diag->cfg); + return; + } + + diag->cfg = *cfg; +} + +void fy_diag_set_level(struct fy_diag *diag, enum fy_error_type level) +{ + if (!diag || (unsigned int)level >= FYET_MAX) + return; + diag->cfg.level = level; +} + +void fy_diag_set_colorize(struct fy_diag *diag, bool colorize) +{ + if (!diag) + return; + diag->cfg.colorize = colorize; +} + +struct fy_diag *fy_diag_ref(struct fy_diag *diag) +{ + if (!diag) + return NULL; + + assert(diag->refs + 1 > 0); + diag->refs++; + + return diag; +} + +void fy_diag_unref(struct fy_diag *diag) +{ + if (!diag) + return; + + assert(diag->refs > 0); + + if (diag->refs == 1) + fy_diag_free(diag); + else + diag->refs--; +} + +int fy_diag_vprintf(struct fy_diag *diag, const char *fmt, va_list ap) +{ + char *buf; + int rc; + + if (!diag || !fmt) + return -1; + + /* no more output */ + if (diag->destroyed) + return 0; + + if (diag->cfg.fp) + return vfprintf(diag->cfg.fp, fmt, ap); + + if (diag->cfg.output_fn) { + rc = vasprintf(&buf, fmt, ap); + if (rc < 0) + return rc; + diag->cfg.output_fn(diag, diag->cfg.user, buf, (size_t)rc); + free(buf); + return rc; + } + + return -1; +} + +int fy_diag_printf(struct fy_diag *diag, const char *fmt, ...) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = fy_diag_vprintf(diag, fmt, ap); + va_end(ap); + + return rc; +} + +int fy_vdiag(struct fy_diag *diag, const struct fy_diag_ctx *fydc, + const char *fmt, va_list ap) +{ + char *msg = NULL; + char *source = NULL, *position = NULL, *typestr = NULL, *modulestr = NULL; + const char *file_stripped = NULL; + const char *color_start = NULL, *color_end = NULL; + enum fy_error_type level; + int rc; + + if (!diag || !fydc || !fmt) + return -1; + + level = fydc->level; + + /* turn errors into notices while not reset */ + if (level >= FYET_ERROR && diag->on_error) + level = FYET_NOTICE; + + if (level < diag->cfg.level) { + rc = 0; + goto out; + } + + /* check module enable mask */ + if (!(diag->cfg.module_mask & FY_BIT(fydc->module))) { + rc = 0; + goto out; + } + + msg = alloca_vsprintf(fmt, ap); + + /* source part */ + if (diag->cfg.show_source) { + if (fydc->source_file) { + file_stripped = strrchr(fydc->source_file, '/'); + if (!file_stripped) + file_stripped = fydc->source_file; + else + file_stripped++; + } else + file_stripped = ""; + source = alloca_sprintf("%s:%d @%s()%s", + file_stripped, fydc->source_line, fydc->source_func, " "); + } + + /* position part */ + if (diag->cfg.show_position && fydc->line >= 0 && fydc->column >= 0) + position = alloca_sprintf("<%3d:%2d>%s", fydc->line, fydc->column, ": "); + + /* type part */ + if (diag->cfg.show_type) + typestr = alloca_sprintf("[%s]%s", fy_error_level_str(level), ": "); + + /* module part */ + if (diag->cfg.show_module) + modulestr = alloca_sprintf("<%s>%s", fy_error_module_str(fydc->module), ": "); + + if (diag->cfg.colorize) { + switch (level) { + 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: /* handles FYET_MAX */ + break; + } + if (color_start) + color_end = "\x1b[0m"; + } + + rc = fy_diag_printf(diag, "%s" "%*s" "%*s" "%*s" "%*s" "%s" "%s\n", + color_start ? : "", + source ? diag->cfg.source_width : 0, source ? : "", + position ? diag->cfg.position_width : 0, position ? : "", + typestr ? diag->cfg.type_width : 0, typestr ? : "", + modulestr ? diag->cfg.module_width : 0, modulestr ? : "", + msg, + color_end ? : ""); + + if (rc > 0) + rc++; + +out: + /* if it's the first error we're generating set the + * on_error flag until the top caller clears it + */ + if (!diag->on_error && fydc->level >= FYET_ERROR) + diag->on_error = true; + + return rc; +} + +int fy_diagf(struct fy_diag *diag, const struct fy_diag_ctx *fydc, + const char *fmt, ...) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = fy_vdiag(diag, fydc, fmt, ap); + va_end(ap); + + return rc; +} + +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; + + if (!diag || !fydrc || !fmt || !fydrc->fyt) + return; + + start_mark = fy_token_start_mark(fydrc->fyt); + + if (fydrc->has_override) { + name = fydrc->override_file; + line = fydrc->override_line; + column = fydrc->override_column; + } else { + name = fy_input_get_filename(fy_token_get_input(fydrc->fyt)); + line = start_mark->line + 1; + column = start_mark->column + 1; + } + + /* 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 = ""; + + 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); + + fy_token_unref(fydrc->fyt); + + if (!diag->on_error && fydrc->type == FYET_ERROR) + diag->on_error = true; +} + +void fy_diag_report(struct fy_diag *diag, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_diag_vreport(diag, fydrc, fmt, ap); + va_end(ap); +} + +/* parser */ + +int fy_parser_vdiag(struct fy_parser *fyp, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, va_list ap) +{ + struct fy_diag_ctx fydc; + int rc; + + if (!fyp || !fyp->diag || !fmt) + return -1; + + /* perform the enable tests early to avoid the overhead */ + if (((flags & FYDF_LEVEL_MASK) >> FYDF_LEVEL_SHIFT) < fyp->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 = fyp_line(fyp); + fydc.column = fyp_column(fyp); + + rc = fy_vdiag(fyp->diag, &fydc, fmt, ap); + + if (fyp && !fyp->stream_error && fyp->diag->on_error) + fyp->stream_error = true; + + return rc; +} + +int fy_parser_diag(struct fy_parser *fyp, 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_parser_vdiag(fyp, flags, file, line, func, fmt, ap); + va_end(ap); + + return rc; +} + +void fy_parser_diag_vreport(struct fy_parser *fyp, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap) +{ + struct fy_diag *diag; + + if (!fyp || !fyp->diag || !fydrc || !fmt) + return; + + diag = fyp->diag; + + fy_diag_vreport(diag, fydrc, fmt, ap); + + if (fyp && !fyp->stream_error && diag->on_error) + fyp->stream_error = true; +} + +void fy_parser_diag_report(struct fy_parser *fyp, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_parser_diag_vreport(fyp, fydrc, fmt, ap); + va_end(ap); +} + +/* document */ + +int fy_document_vdiag(struct fy_document *fyd, 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 (!fyd || !fmt || !fyd->diag) + return -1; + + /* perform the enable tests early to avoid the overhead */ + if (((flags & FYDF_LEVEL_MASK) >> FYDF_LEVEL_SHIFT) < fyd->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(fyd->diag, &fydc, fmt, ap); + + return rc; +} + +int fy_document_diag(struct fy_document *fyd, 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_vdiag(fyd, flags, file, line, func, fmt, ap); + va_end(ap); + + return rc; +} + +void fy_document_diag_vreport(struct fy_document *fyd, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap) +{ + if (!fyd || !fyd->diag || !fydrc || !fmt) + return; + + fy_diag_vreport(fyd->diag, fydrc, fmt, ap); +} + +void fy_document_diag_report(struct fy_document *fyd, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_document_diag_vreport(fyd, fydrc, fmt, ap); + va_end(ap); +} + +/* 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) +{ + struct fy_diag_ctx fydc; + int rc; + + if (!fyc || !fmt || !fyc->cfg.diag) + return -1; + + /* perform the enable tests early to avoid the overhead */ + if (((flags & FYDF_LEVEL_MASK) >> FYDF_LEVEL_SHIFT) < fyc->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(fyc->cfg.diag, &fydc, fmt, ap); + + return rc; +} + +int fy_composer_diag(struct fy_composer *fyc, 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_composer_vdiag(fyc, flags, file, line, func, fmt, ap); + va_end(ap); + + return rc; +} + +void fy_composer_diag_vreport(struct fy_composer *fyc, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap) +{ + if (!fyc || !fyc->cfg.diag || !fydrc || !fmt) + return; + + fy_diag_vreport(fyc->cfg.diag, fydrc, fmt, ap); +} + +void fy_composer_diag_report(struct fy_composer *fyc, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_composer_diag_vreport(fyc, fydrc, fmt, ap); + va_end(ap); +} + +/* reader */ + +int fy_reader_vdiag(struct fy_reader *fyr, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, va_list ap) +{ + struct fy_diag_ctx fydc; + int fydc_level, fyd_level; + + if (!fyr || !fyr->diag || !fmt) + return -1; + + /* perform the enable tests early to avoid the overhead */ + fydc_level = (flags & FYDF_LEVEL_MASK) >> FYDF_LEVEL_SHIFT; + fyd_level = fyr->diag->cfg.level; + + if (fydc_level < fyd_level) + return 0; + + /* fill in fy_diag_ctx */ + memset(&fydc, 0, sizeof(fydc)); + + fydc.level = fydc_level; + fydc.module = FYEM_SCAN; /* reader is always scanner */ + fydc.source_file = file; + fydc.source_line = line; + fydc.source_func = func; + fydc.line = fyr->line; + fydc.column = fyr->column; + + return fy_vdiag(fyr->diag, &fydc, fmt, ap); +} + +int fy_reader_diag(struct fy_reader *fyr, 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_reader_vdiag(fyr, flags, file, line, func, fmt, ap); + va_end(ap); + + return rc; +} + +void fy_reader_diag_vreport(struct fy_reader *fyr, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap) +{ + if (!fyr || !fyr->diag || !fydrc || !fmt) + return; + + fy_diag_vreport(fyr->diag, fydrc, fmt, ap); +} + +void fy_reader_diag_report(struct fy_reader *fyr, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_reader_diag_vreport(fyr, fydrc, fmt, ap); + va_end(ap); +} + +void fy_diag_node_vreport(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *fmt, va_list ap) +{ + struct fy_diag_report_ctx drc; + bool save_on_error; + + if (!fyn || !diag) + return; + + save_on_error = diag->on_error; + diag->on_error = false; + + memset(&drc, 0, sizeof(drc)); + drc.type = type; + drc.module = FYEM_UNKNOWN; + drc.fyt = fy_node_token(fyn); + fy_diag_vreport(diag, &drc, fmt, ap); + + diag->on_error = save_on_error; +} + +void fy_diag_node_report(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_diag_node_vreport(diag, fyn, type, fmt, ap); + va_end(ap); +} + +void fy_diag_node_override_vreport(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *file, + int line, int column, + const char *fmt, va_list ap) +{ + struct fy_diag_report_ctx drc; + bool save_on_error; + + if (!fyn || !diag) + return; + + save_on_error = diag->on_error; + diag->on_error = false; + + memset(&drc, 0, sizeof(drc)); + drc.type = type; + drc.module = FYEM_UNKNOWN; + drc.fyt = fy_node_token(fyn); + drc.has_override = true; + drc.override_file = file; + drc.override_line = line; + drc.override_column = column; + fy_diag_vreport(diag, &drc, fmt, ap); + + diag->on_error = save_on_error; +} + +void fy_diag_node_override_report(struct fy_diag *diag, struct fy_node *fyn, + enum fy_error_type type, const char *file, + int line, int column, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_diag_node_override_vreport(diag, fyn, type, file, line, column, fmt, ap); + va_end(ap); +} + +void fy_node_vreport(struct fy_node *fyn, enum fy_error_type type, + const char *fmt, va_list ap) +{ + if (!fyn || !fyn->fyd) + return; + + fy_diag_node_vreport(fyn->fyd->diag, fyn, type, fmt, ap); +} + +void fy_node_report(struct fy_node *fyn, enum fy_error_type type, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_node_vreport(fyn, type, fmt, ap); + va_end(ap); +} + +void fy_node_override_vreport(struct fy_node *fyn, enum fy_error_type type, + const char *file, int line, int column, + const char *fmt, va_list ap) +{ + if (!fyn || !fyn->fyd) + return; + + fy_diag_node_override_vreport(fyn->fyd->diag, fyn, type, + file, line, column, fmt, ap); +} + +void fy_node_override_report(struct fy_node *fyn, enum fy_error_type type, + const char *file, int line, int column, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_node_override_vreport(fyn, type, file, line, column, fmt, ap); + va_end(ap); +} diff --git a/src/lib/fy-diag.h b/src/lib/fy-diag.h new file mode 100644 index 0000000..38dd257 --- /dev/null +++ b/src/lib/fy-diag.h @@ -0,0 +1,606 @@ +/* + * fy-diag.h - diagnostics + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_DIAG_H +#define FY_DIAG_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-list.h" +#include "fy-token.h" + +/* error flags (above 0x100 is library specific) */ +#define FYEF_SOURCE 0x0001 +#define FYEF_POSITION 0x0002 +#define FYEF_TYPE 0x0004 +#define FYEF_USERSTART 0x0100 + +#define FYDF_LEVEL_SHIFT 0 +#define FYDF_LEVEL_MASK (0x0f << FYDF_LEVEL_SHIFT) +#define FYDF_LEVEL(x) (((unsigned int)(x) << FYDF_LEVEL_SHIFT) & FYDF_LEVEL_MASK) +#define FYDF_DEBUG FYDF_LEVEL(FYET_DEBUG) +#define FYDF_INFO FYDF_LEVEL(FYET_INFO) +#define FYDF_NOTICE FYDF_LEVEL(FYET_NOTICE) +#define FYDF_WARNING FYDF_LEVEL(FYET_WARNING) +#define FYDF_ERROR FYDF_LEVEL(FYET_ERROR) + +#define FYDF_MODULE_SHIFT 4 +#define FYDF_MODULE_MASK (0x0f << FYDF_MODULE_SHIFT) +#define FYDF_MODULE(x) (((unsigned int)(x) << FYDF_MODULE_SHIFT) & FYDF_MODULE_MASK) +#define FYDF_ATOM FYDF_MODULE(FYEM_ATOM) +#define FYDF_SCANNER FYDF_MODULE(FYEM_SCANNER) +#define FYDF_PARSER FYDF_MODULE(FYEM_PARSER) +#define FYDF_TREE FYDF_MODULE(FYEM_TREE) +#define FYDF_BUILDER FYDF_MODULE(FYEM_BUILDER) +#define FYDF_INTERNAL FYDF_MODULE(FYEM_INTERNAL) +#define FYDF_SYSTEM FYDF_MODULE(FYEM_SYSTEM) +#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; +}; + +void fy_diag_free(struct fy_diag *diag); + +struct fy_diag_report_ctx { + enum fy_error_type type; + enum fy_error_module module; + struct fy_token *fyt; + bool has_override; + const char *override_file; + int override_line; + int override_column; +}; + +void fy_diag_vreport(struct fy_diag *diag, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap); +void fy_diag_report(struct fy_diag *diag, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +#ifndef NDEBUG +#define __FY_DEBUG_UNUSED__ /* nothing */ +#else +#define __FY_DEBUG_UNUSED__ __attribute__((__unused__)) +#endif + +/* parser diagnostics */ + +struct fy_parser; + +void fy_diag_cfg_from_parser_flags(struct fy_diag_cfg *cfg, enum fy_parse_cfg_flags pflags); + +int fy_parser_vdiag(struct fy_parser *fyp, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, va_list ap); + +int fy_parser_diag(struct fy_parser *fyp, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, ...) + __attribute__((format(printf, 6, 7))); + +void fy_parser_diag_vreport(struct fy_parser *fyp, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap); +void fy_parser_diag_report(struct fy_parser *fyp, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +#ifndef NDEBUG + +#define fyp_debug(_fyp, _module, _fmt, ...) \ + fy_parser_diag((_fyp), FYET_DEBUG | FYDF_MODULE(_module), \ + __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#else + +#define fyp_debug(_fyp, _module, _fmt, ...) \ + do { } while(0) + +#endif + +#define fyp_info(_fyp, _fmt, ...) \ + fy_parser_diag((_fyp), FYET_INFO, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyp_notice(_fyp, _fmt, ...) \ + fy_parser_diag((_fyp), FYET_NOTICE, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyp_warning(_fyp, _fmt, ...) \ + fy_parser_diag((_fyp), FYET_WARNING, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyp_error(_fyp, _fmt, ...) \ + fy_parser_diag((_fyp), FYET_ERROR, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) + +#define fyp_scan_debug(_fyp, _fmt, ...) \ + fyp_debug((_fyp), FYEM_SCAN, (_fmt) , ## __VA_ARGS__) +#define fyp_parse_debug(_fyp, _fmt, ...) \ + fyp_debug((_fyp), FYEM_PARSE, (_fmt) , ## __VA_ARGS__) +#define fyp_doc_debug(_fyp, _fmt, ...) \ + fyp_debug((_fyp), FYEM_DOC, (_fmt) , ## __VA_ARGS__) + +#define fyp_error_check(_fyp, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + fyp_error((_fyp), _fmt, ## __VA_ARGS__); \ + goto _label ; \ + } \ + } while(0) + +#define _FYP_TOKEN_DIAG(_fyp, _fyt, _type, _module, _fmt, ...) \ + do { \ + struct fy_diag_report_ctx _drc; \ + memset(&_drc, 0, sizeof(_drc)); \ + _drc.type = (_type); \ + _drc.module = (_module); \ + _drc.fyt = (_fyt); \ + fy_parser_diag_report((_fyp), &_drc, (_fmt) , ## __VA_ARGS__); \ + } while(0) + +#define FYP_TOKEN_DIAG(_fyp, _fyt, _type, _module, _fmt, ...) \ + _FYP_TOKEN_DIAG(_fyp, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYP_PARSE_DIAG(_fyp, _adv, _cnt, _type, _module, _fmt, ...) \ + _FYP_TOKEN_DIAG(_fyp, \ + fy_token_create(FYTT_INPUT_MARKER, \ + fy_fill_atom_at((_fyp), (_adv), (_cnt), \ + alloca(sizeof(struct fy_atom)))), \ + _type, _module, _fmt, ## __VA_ARGS__) + +#define FYP_MARK_DIAG(_fyp, _sm, _em, _type, _module, _fmt, ...) \ + _FYP_TOKEN_DIAG(_fyp, \ + fy_token_create(FYTT_INPUT_MARKER, \ + fy_fill_atom_mark(((_fyp)), (_sm), (_em), \ + alloca(sizeof(struct fy_atom)))), \ + _type, _module, _fmt, ## __VA_ARGS__) + +#define FYP_NODE_DIAG(_fyp, _fyn, _type, _module, _fmt, ...) \ + _FYP_TOKEN_DIAG(_fyp, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYP_TOKEN_ERROR(_fyp, _fyt, _module, _fmt, ...) \ + FYP_TOKEN_DIAG(_fyp, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYP_PARSE_ERROR(_fyp, _adv, _cnt, _module, _fmt, ...) \ + FYP_PARSE_DIAG(_fyp, _adv, _cnt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYP_MARK_ERROR(_fyp, _sm, _em, _module, _fmt, ...) \ + FYP_MARK_DIAG(_fyp, _sm, _em, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYP_NODE_ERROR(_fyp, _fyn, _module, _fmt, ...) \ + FYP_NODE_DIAG(_fyp, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYP_TOKEN_ERROR_CHECK(_fyp, _fyt, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYP_TOKEN_ERROR(_fyp, _fyt, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYP_PARSE_ERROR_CHECK(_fyp, _adv, _cnt, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYP_PARSE_ERROR(_fyp, _adv, _cnt, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYP_MARK_ERROR_CHECK(_fyp, _sm, _em, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYP_MARK_ERROR(_fyp, _sm, _em, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYP_NODE_ERROR_CHECK(_fyp, _fyn, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYP_NODE_ERROR(_fyp, _fyn, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYP_TOKEN_WARNING(_fyp, _fyt, _module, _fmt, ...) \ + FYP_TOKEN_DIAG(_fyp, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYP_PARSE_WARNING(_fyp, _adv, _cnt, _module, _fmt, ...) \ + FYP_PARSE_DIAG(_fyp, _adv, _cnt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYP_MARK_WARNING(_fyp, _sm, _em, _module, _fmt, ...) \ + FYP_MARK_DIAG(_fyp, _sm, _em, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYP_NODE_WARNING(_fyp, _fyn, _type, _module, _fmt, ...) \ + FYP_NODE_DIAG(_fyp, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +/* reader diagnostics */ + +struct fy_reader; + +int fy_reader_vdiag(struct fy_reader *fyr, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, va_list ap); + +int fy_reader_diag(struct fy_reader *fyr, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, ...) + __attribute__((format(printf, 6, 7))); + +void fy_reader_diag_vreport(struct fy_reader *fyr, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap); +void fy_reader_diag_report(struct fy_reader *fyr, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +#ifndef NDEBUG + +#define fyr_debug(_fyr, _fmt, ...) \ + fy_reader_diag((_fyr), FYET_DEBUG, \ + __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#else + +#define fyr_debug(_fyr, _fmt, ...) \ + do { } while(0) + +#endif + +#define fyr_info(_fyr, _fmt, ...) \ + fy_reader_diag((_fyr), FYET_INFO, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyr_notice(_fyr, _fmt, ...) \ + fy_reader_diag((_fyr), FYET_NOTICE, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyr_warning(_fyr, _fmt, ...) \ + fy_reader_diag((_fyr), FYET_WARNING, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyr_error(_fyr, _fmt, ...) \ + fy_reader_diag((_fyr), FYET_ERROR, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) + +#define fyr_error_check(_fyr, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + fyr_error((_fyr), _fmt, ## __VA_ARGS__); \ + goto _label ; \ + } \ + } while(0) + +#define _FYR_TOKEN_DIAG(_fyr, _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_reader_diag_report((_fyr), &_drc, (_fmt) , ## __VA_ARGS__); \ + } while(0) + +#define FYR_TOKEN_DIAG(_fyr, _fyt, _type, _module, _fmt, ...) \ + _FYR_TOKEN_DIAG(_fyr, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYR_PARSE_DIAG(_fyr, _adv, _cnt, _type, _module, _fmt, ...) \ + _FYR_TOKEN_DIAG(_fyr, \ + fy_token_create(FYTT_INPUT_MARKER, \ + fy_reader_fill_atom_at((_fyr), (_adv), (_cnt), \ + alloca(sizeof(struct fy_atom)))), \ + _type, _module, _fmt, ## __VA_ARGS__) + +#define FYR_MARK_DIAG(_fyr, _sm, _em, _type, _module, _fmt, ...) \ + _FYR_TOKEN_DIAG(_fyr, \ + fy_token_create(FYTT_INPUT_MARKER, \ + fy_reader_fill_atom_mark(((_fyr)), (_sm), (_em), \ + alloca(sizeof(struct fy_atom)))), \ + _type, _module, _fmt, ## __VA_ARGS__) + +#define FYR_NODE_DIAG(_fyr, _fyn, _type, _module, _fmt, ...) \ + _FYR_TOKEN_DIAG(_fyr, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYR_TOKEN_ERROR(_fyr, _fyt, _module, _fmt, ...) \ + FYR_TOKEN_DIAG(_fyr, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYR_PARSE_ERROR(_fyr, _adv, _cnt, _module, _fmt, ...) \ + FYR_PARSE_DIAG(_fyr, _adv, _cnt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYR_MARK_ERROR(_fyr, _sm, _em, _module, _fmt, ...) \ + FYR_MARK_DIAG(_fyr, _sm, _em, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYR_NODE_ERROR(_fyr, _fyn, _module, _fmt, ...) \ + FYR_NODE_DIAG(_fyr, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYR_TOKEN_ERROR_CHECK(_fyr, _fyt, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYR_TOKEN_ERROR(_fyr, _fyt, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYR_PARSE_ERROR_CHECK(_fyr, _adv, _cnt, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYR_PARSE_ERROR(_fyr, _adv, _cnt, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYR_MARK_ERROR_CHECK(_fyr, _sm, _em, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYR_MARK_ERROR(_fyr, _sm, _em, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYR_NODE_ERROR_CHECK(_fyr, _fyn, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYR_NODE_ERROR(_fyr, _fyn, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYR_TOKEN_WARNING(_fyr, _fyt, _module, _fmt, ...) \ + FYR_TOKEN_DIAG(_fyr, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYR_PARSE_WARNING(_fyr, _adv, _cnt, _module, _fmt, ...) \ + FYR_PARSE_DIAG(_fyr, _adv, _cnt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYR_MARK_WARNING(_fyr, _sm, _em, _module, _fmt, ...) \ + FYR_MARK_DIAG(_fyr, _sm, _em, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYR_NODE_WARNING(_fyr, _fyn, _type, _module, _fmt, ...) \ + FYR_NODE_DIAG(_fyr, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +/* doc */ +struct fy_document; + +int fy_document_vdiag(struct fy_document *fyd, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, va_list ap); + +int fy_document_diag(struct fy_document *fyd, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, ...) + __attribute__((format(printf, 6, 7))); + +void fy_document_diag_vreport(struct fy_document *fyd, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap); +void fy_document_diag_report(struct fy_document *fyd, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +#ifndef NDEBUG + +#define fyd_debug(_fyd, _module, _fmt, ...) \ + fy_document_diag((_fyd), FYET_DEBUG | FYDF_MODULE(_module), \ + __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) + +#else + +#define fyd_debug(_fyd, _module, _fmt, ...) \ + do { } while(0) + +#endif + +#define fyd_info(_fyd, _fmt, ...) \ + fy_document_diag((_fyd), FYET_INFO, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyd_notice(_fyd, _fmt, ...) \ + fy_document_diag((_fyd), FYET_NOTICE, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyd_warning(_fyd, _fmt, ...) \ + fy_document_diag((_fyd), FYET_WARNING, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyd_error(_fyd, _fmt, ...) \ + fy_document_diag((_fyd), FYET_ERROR, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) + +#define fyd_doc_debug(_fyd, _fmt, ...) \ + fyd_debug((_fyd), FYEM_DOC, (_fmt) , ## __VA_ARGS__) + +#define fyd_error_check(_fyd, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + fyd_error((_fyd), _fmt, ## __VA_ARGS__); \ + goto _label ; \ + } \ + } while(0) + +#define _FYD_TOKEN_DIAG(_fyd, _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_diag_report((_fyd), &_drc, (_fmt) , ## __VA_ARGS__); \ + } while(0) + +#define FYD_TOKEN_DIAG(_fyd, _fyt, _type, _module, _fmt, ...) \ + _FYD_TOKEN_DIAG(_fyd, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYD_NODE_DIAG(_fyd, _fyn, _type, _module, _fmt, ...) \ + _FYD_TOKEN_DIAG(_fyd, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYD_TOKEN_ERROR(_fyd, _fyt, _module, _fmt, ...) \ + FYD_TOKEN_DIAG(_fyd, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYD_NODE_ERROR(_fyd, _fyn, _module, _fmt, ...) \ + FYD_NODE_DIAG(_fyd, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYD_TOKEN_ERROR_CHECK(_fyd, _fyt, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYD_TOKEN_ERROR(_fyd, _fyt, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYD_NODE_ERROR_CHECK(_fyd, _fyn, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYD_NODE_ERROR(_fyd, _fyn, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYD_TOKEN_WARNING(_fyd, _fyt, _module, _fmt, ...) \ + FYD_TOKEN_DIAG(_fyd, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +#define FYD_NODE_WARNING(_fyd, _fyn, _type, _module, _fmt, ...) \ + FYD_NODE_DIAG(_fyd, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +/* composer */ +struct fy_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); + +int fy_composer_diag(struct fy_composer *fyc, unsigned int flags, + const char *file, int line, const char *func, + const char *fmt, ...) + __attribute__((format(printf, 6, 7))); + +void fy_composer_diag_vreport(struct fy_composer *fyc, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, va_list ap); +void fy_composer_diag_report(struct fy_composer *fyc, + const struct fy_diag_report_ctx *fydrc, + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +#ifndef NDEBUG + +#define fyc_debug(_fyc, _module, _fmt, ...) \ + fy_composer_diag((_fyc), FYET_DEBUG | FYDF_MODULE(_module), \ + __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) + +#else + +#define fyc_debug(_fyc, _module, _fmt, ...) \ + do { } while(0) + +#endif + +#define fyc_info(_fyc, _fmt, ...) \ + fy_composer_diag((_fyc), FYET_INFO, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyc_notice(_fyc, _fmt, ...) \ + fy_composer_diag((_fyc), FYET_NOTICE, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyc_warning(_fyc, _fmt, ...) \ + fy_composer_diag((_fyc), FYET_WARNING, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) +#define fyc_error(_fyc, _fmt, ...) \ + fy_composer_diag((_fyc), FYET_ERROR, __FILE__, __LINE__, __func__, \ + (_fmt) , ## __VA_ARGS__) + +#define fyc_error_check(_fyc, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + fyc_error((_fyc), _fmt, ## __VA_ARGS__); \ + goto _label ; \ + } \ + } while(0) + +#define _FYC_TOKEN_DIAG(_fyc, _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_composer_diag_report((_fyc), &_drc, (_fmt) , ## __VA_ARGS__); \ + } while(0) + +#define FYC_TOKEN_DIAG(_fyc, _fyt, _type, _module, _fmt, ...) \ + _FYC_TOKEN_DIAG(_fyc, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYC_NODE_DIAG(_fyc, _fyn, _type, _module, _fmt, ...) \ + _FYC_TOKEN_DIAG(_fyc, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__) + +#define FYC_TOKEN_ERROR(_fyc, _fyt, _module, _fmt, ...) \ + FYC_TOKEN_DIAG(_fyc, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__) + +#define FYC_TOKEN_ERROR_CHECK(_fyc, _fyt, _module, _cond, _label, _fmt, ...) \ + do { \ + if (!(_cond)) { \ + FYC_TOKEN_ERROR(_fyc, _fyt, _module, _fmt, ## __VA_ARGS__); \ + goto _label; \ + } \ + } while(0) + +#define FYC_TOKEN_WARNING(_fyc, _fyt, _module, _fmt, ...) \ + FYC_TOKEN_DIAG(_fyc, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__) + +/* alloca formatted print methods */ +#define alloca_vsprintf(_fmt, _ap) \ + ({ \ + const char *__fmt = (_fmt); \ + va_list _ap_orig; \ + int _size; \ + int _sizew __FY_DEBUG_UNUSED__; \ + char *_buf = NULL, *_s; \ + \ + va_copy(_ap_orig, (_ap)); \ + _size = vsnprintf(NULL, 0, __fmt, _ap_orig); \ + va_end(_ap_orig); \ + if (_size != -1) { \ + _buf = alloca(_size + 1); \ + _sizew = vsnprintf(_buf, _size + 1, __fmt, _ap); \ + assert(_size == _sizew); \ + _s = _buf + strlen(_buf); \ + while (_s > _buf && _s[-1] == '\n') \ + *--_s = '\0'; \ + } \ + _buf; \ + }) + +#define alloca_sprintf(_fmt, ...) \ + ({ \ + const char *__fmt = (_fmt); \ + int _size; \ + int _sizew __FY_DEBUG_UNUSED__; \ + char *_buf = NULL, *_s; \ + \ + _size = snprintf(NULL, 0, __fmt, ## __VA_ARGS__); \ + if (_size != -1) { \ + _buf = alloca(_size + 1); \ + _sizew = snprintf(_buf, _size + 1, __fmt, __VA_ARGS__); \ + assert(_size == _sizew); \ + _s = _buf + strlen(_buf); \ + while (_s > _buf && _s[-1] == '\n') \ + *--_s = '\0'; \ + } \ + _buf; \ + }) + +#endif diff --git a/src/lib/fy-doc.c b/src/lib/fy-doc.c new file mode 100644 index 0000000..a61d95f --- /dev/null +++ b/src/lib/fy-doc.c @@ -0,0 +1,7747 @@ +/* + * fy-doc.c - YAML document methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-doc.h" + +#include "fy-utils.h" + +#include "xxhash.h" + +static const struct fy_hash_desc hd_anchor; +static const struct fy_hash_desc hd_nanchor; +static const struct fy_hash_desc hd_mapping; + +int fy_node_hash_uint(struct fy_node *fyn, unsigned int *hashp); + +static struct fy_node * +fy_node_by_path_internal(struct fy_node *fyn, + const char *path, size_t pathlen, + enum fy_node_walk_flags flags); + +#define FY_NODE_PATH_WALK_DEPTH_DEFAULT 16 + +static inline unsigned int +fy_node_walk_max_depth_from_flags(enum fy_node_walk_flags flags) +{ + unsigned int max_depth; + + max_depth = ((unsigned int)flags >> FYNWF_MAXDEPTH_SHIFT) & FYNWF_MAXDEPTH_MASK; + if (max_depth == 0) + max_depth = FY_NODE_PATH_WALK_DEPTH_DEFAULT; + + return max_depth; +} + +static inline unsigned int +fy_node_walk_marker_from_flags(enum fy_node_walk_flags flags) +{ + return ((unsigned int)flags >> FYNWF_MARKER_SHIFT) & FYNWF_MARKER_MASK; +} + +/* internal simple key to optimize string lookups */ +static inline bool is_simple_key(const char *str, size_t len) +{ + const char *s, *e; + char c; + + if (!str) + return false; + + if (len == (size_t)-1) + len = strlen(str); + + for (s = str, e = s + len; s < e; s++) { + + c = *s; + + /* note no isalpha() it's locale specific */ + if (!((c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + (c == '_'))) + break; + } + + return s == e; +} + +static void fy_resolve_parent_node(struct fy_document *fyd, struct fy_node *fyn, struct fy_node *fyn_parent); + +void fy_anchor_destroy(struct fy_anchor *fya) +{ + if (!fya) + return; + fy_token_unref(fya->anchor); + free(fya); +} + +struct fy_anchor *fy_anchor_create(struct fy_document *fyd, + struct fy_node *fyn, struct fy_token *anchor) +{ + struct fy_anchor *fya = NULL; + + fya = malloc(sizeof(*fya)); + if (!fya) + return NULL; + + fya->fyn = fyn; + fya->anchor = anchor; + fya->multiple = false; + + return fya; +} + +struct fy_anchor *fy_document_anchor_iterate(struct fy_document *fyd, void **prevp) +{ + struct fy_anchor_list *fyal; + + if (!fyd || !prevp) + return NULL; + + fyal = &fyd->anchors; + + return *prevp = *prevp ? fy_anchor_next(fyal, *prevp) : fy_anchor_list_head(fyal); +} + +#define FYDSAF_COPY FY_BIT(0) +#define FYDSAF_MALLOCED FY_BIT(1) + +static int fy_document_set_anchor_internal(struct fy_document *fyd, struct fy_node *fyn, const char *text, size_t len, + unsigned int flags) +{ + const bool copy = !!(flags & FYDSAF_COPY); + const bool malloced = !!(flags & FYDSAF_MALLOCED); + struct fy_anchor *fya = NULL, *fyam = NULL; + struct fy_input *fyi = NULL; + struct fy_token *fyt = NULL; + struct fy_accel_entry *xle; + struct fy_atom handle; + char *data_copy = NULL; + const char *origtext; + size_t origlen; + int rc; + + if (!fyd || !fyn || fyn->fyd != fyd) + return -1; + + if (text && len == (size_t)-1) + len = strlen(text); + + fya = fy_document_lookup_anchor_by_node(fyd, fyn); + + if (!text) { + /* no anchor, and trying to delete? OK */ + if (fya) + return 0; + /* remove the anchor */ + fy_anchor_list_del(&fyd->anchors, fya); + + if (fy_document_is_accelerated(fyd)) { + xle = fy_accel_entry_lookup_key_value(fyd->axl, fya->anchor, fya); + fy_accel_entry_remove(fyd->axl, xle); + + xle = fy_accel_entry_lookup_key_value(fyd->naxl, fya->fyn, fya); + fy_accel_entry_remove(fyd->naxl, xle); + } + + fy_anchor_destroy(fya); + return 0; + } + + /* trying to add duplicate anchor */ + if (fya) { + origtext = fy_token_get_text(fya->anchor, &origlen); + fyd_error_check(fyd, origtext, err_out, + "fy_token_get_text() failed"); + + FYD_NODE_ERROR(fyd, fyn, FYEM_DOC, + "cannot set anchor %.*s (anchor %.*s already exists)", + (int)len, text, (int)origlen, origtext); + if (malloced && text) + free((void *)text); + fya = NULL; + goto err_out; + } + + if (copy) { + data_copy = malloc(len); + fyd_error_check(fyd, data_copy, err_out, + "malloc() failed"); + memcpy(data_copy, text, len); + fyi = fy_input_from_malloc_data(data_copy, len, &handle, true); + } else if (malloced) + data_copy = (char *)text; + else + data_copy = NULL; + + if (data_copy) + fyi = fy_input_from_malloc_data((void *)text, len, &handle, true); + else + fyi = fy_input_from_data(text, len, &handle, true); + fyd_error_check(fyd, fyi, err_out, + "fy_input_from_data() failed"); + data_copy = NULL; + + /* it must not be something funky */ + if (!handle.valid_anchor) + goto err_out; + + fyt = fy_token_create(FYTT_ANCHOR, &handle); + if (!fyt) + goto err_out; + + fya = fy_anchor_create(fyd, fyn, fyt); + if (!fya) + goto err_out; + + fy_anchor_list_add(&fyd->anchors, fya); + if (fy_document_is_accelerated(fyd)) { + xle = fy_accel_entry_lookup(fyd->axl, fya->anchor); + if (xle) { + fyam = (void *)xle->value; + /* multiple */ + if (!fyam->multiple) + fyam->multiple = true; + fya->multiple = true; + + fyd_notice(fyd, "register anchor %.*s is multiple", (int)len, text); + } + + xle = fy_accel_entry_insert(fyd->axl, fya->anchor, fya); + fyd_error_check(fyd, xle, err_out, + "fy_accel_entry_insert() fyd->axl failed"); + } + + if (fy_document_is_accelerated(fyd)) { + rc = fy_accel_insert(fyd->naxl, fyn, fya); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_accel_insert() fyd->naxl failed"); + } + + /* take away the input reference */ + fy_input_unref(fyi); + + return 0; +err_out: + rc = -1; +err_out_rc: + if (data_copy) + free(data_copy); + fy_anchor_destroy(fya); + fy_token_unref(fyt); + fy_input_unref(fyi); + fyd->diag->on_error = false; + return rc; +} + +int fy_document_set_anchor(struct fy_document *fyd, struct fy_node *fyn, const char *text, size_t len) +{ + return fy_document_set_anchor_internal(fyd, fyn, text, len, 0); +} + +int fy_node_set_anchor(struct fy_node *fyn, const char *text, size_t len) +{ + if (!fyn) + return -1; + return fy_document_set_anchor_internal(fyn->fyd, fyn, text, len, 0); +} + +int fy_node_set_anchor_copy(struct fy_node *fyn, const char *text, size_t len) +{ + if (!fyn) + return -1; + return fy_document_set_anchor_internal(fyn->fyd, fyn, text, len, FYDSAF_COPY); +} + +int fy_node_set_vanchorf(struct fy_node *fyn, const char *fmt, va_list ap) +{ + if (!fyn || !fmt) + return -1; + + return fy_document_set_anchor_internal(fyn->fyd, fyn, alloca_vsprintf(fmt, ap), FY_NT, FYDSAF_COPY); +} + +int fy_node_set_anchorf(struct fy_node *fyn, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = fy_node_set_vanchorf(fyn, fmt, ap); + va_end(ap); + + return ret; +} + +int fy_node_remove_anchor(struct fy_node *fyn) +{ + return fy_node_set_anchor(fyn, NULL, 0); +} + +struct fy_anchor *fy_node_get_anchor(struct fy_node *fyn) +{ + if (!fyn) + return NULL; + + return fy_document_lookup_anchor_by_node(fyn->fyd, fyn); +} + +struct fy_anchor *fy_node_get_nearest_anchor(struct fy_node *fyn) +{ + struct fy_anchor *fya; + struct fy_node *fynt; + + while ((fya = fy_node_get_anchor(fyn)) == NULL && (fynt = fy_node_get_parent(fyn))) + fyn = fynt; + + return fya; +} + +struct fy_node *fy_node_get_nearest_child_of(struct fy_node *fyn_base, + struct fy_node *fyn) +{ + struct fy_node *fynp; + + if (!fyn) + return NULL; + if (!fyn_base) + fyn_base = fy_document_root(fy_node_document(fyn)); + if (!fyn_base) + return NULL; + + /* move up until we hit a node that's a child of fyn_base */ + fynp = fyn; + while (fyn && (fynp = fy_node_get_parent(fyn)) != NULL && fyn_base != fynp) + fyn = fynp; + + return fyn; +} + +void fy_parse_document_destroy(struct fy_parser *fyp, struct fy_document *fyd) +{ + struct fy_node *fyn; + struct fy_anchor *fya; + struct fy_anchor *fyan; + struct fy_accel_entry *xle; + + if (!fyd) + return; + + fy_document_cleanup_path_expr_data(fyd); + + fyn = fyd->root; + fyd->root = NULL; + fy_node_detach_and_free(fyn); + + /* remove all anchors */ + for (fya = fy_anchor_list_head(&fyd->anchors); fya; fya = fyan) { + fyan = fy_anchor_next(&fyd->anchors, fya); + fy_anchor_list_del(&fyd->anchors, fya); + + if (fy_document_is_accelerated(fyd)) { + xle = fy_accel_entry_lookup_key_value(fyd->axl, fya->anchor, fya); + fy_accel_entry_remove(fyd->axl, xle); + + xle = fy_accel_entry_lookup_key_value(fyd->naxl, fya->fyn, fya); + fy_accel_entry_remove(fyd->naxl, xle); + } + + fy_anchor_destroy(fya); + } + + if (fy_document_is_accelerated(fyd)) { + fy_accel_cleanup(fyd->axl); + free(fyd->axl); + + fy_accel_cleanup(fyd->naxl); + free(fyd->naxl); + } + + fy_document_state_unref(fyd->fyds); + + fy_diag_unref(fyd->diag); + + free(fyd); +} + +struct fy_document *fy_parse_document_create(struct fy_parser *fyp, struct fy_eventp *fyep) +{ + struct fy_document *fyd = NULL; + struct fy_document_state *fyds; + struct fy_event *fye = NULL; + int rc; + + if (!fyp || !fyep) + return NULL; + + fye = &fyep->e; + + FYP_TOKEN_ERROR_CHECK(fyp, fy_event_get_token(fye), FYEM_DOC, + fye->type == FYET_DOCUMENT_START, err_out, + "invalid start of event stream"); + + fyd = malloc(sizeof(*fyd)); + fyp_error_check(fyp, fyd, err_out, + "malloc() failed"); + + memset(fyd, 0, sizeof(*fyd)); + + fyd->diag = fy_diag_ref(fyp->diag); + fyd->parse_cfg = fyp->cfg; + + fy_anchor_list_init(&fyd->anchors); + if (fy_document_can_be_accelerated(fyd)) { + fyd->axl = malloc(sizeof(*fyd->axl)); + fyp_error_check(fyp, fyd->axl, err_out, + "malloc() failed"); + + /* start with a very small bucket list */ + rc = fy_accel_setup(fyd->axl, &hd_anchor, fyd, 8); + fyp_error_check(fyp, !rc, err_out, + "fy_accel_setup() failed"); + + fyd->naxl = malloc(sizeof(*fyd->naxl)); + fyp_error_check(fyp, fyd->axl, err_out, + "malloc() failed"); + + /* start with a very small bucket list */ + rc = fy_accel_setup(fyd->naxl, &hd_nanchor, fyd, 8); + fyp_error_check(fyp, !rc, err_out, + "fy_accel_setup() failed"); + } + + fyd->root = NULL; + + fyds = fye->document_start.document_state; + fye->document_start.document_state = NULL; + + /* and we're done with this event */ + fy_parse_eventp_recycle(fyp, fyep); + + /* drop the old reference */ + fy_document_state_unref(fyd->fyds); + + /* note that we keep the reference */ + fyd->fyds = fyds; + + fy_document_list_init(&fyd->children); + + return fyd; + +err_out: + fy_parse_document_destroy(fyp, fyd); + fy_parse_eventp_recycle(fyp, fyep); + fyd->diag->on_error = false; + return NULL; +} + +const struct fy_parse_cfg *fy_document_get_cfg(struct fy_document *fyd) +{ + if (!fyd) + return NULL; + return &fyd->parse_cfg; +} + +struct fy_diag *fy_document_get_diag(struct fy_document *fyd) +{ + if (!fyd || !fyd->diag) + return NULL; + return fy_diag_ref(fyd->diag); +} + +int fy_document_set_diag(struct fy_document *fyd, struct fy_diag *diag) +{ + struct fy_diag_cfg dcfg; + + if (!fyd) + return -1; + + /* default? */ + if (!diag) { + fy_diag_cfg_default(&dcfg); + diag = fy_diag_create(&dcfg); + if (!diag) + return -1; + } + + fy_diag_unref(fyd->diag); + fyd->diag = fy_diag_ref(diag); + + return 0; +} + +struct fy_document *fy_node_document(struct fy_node *fyn) +{ + return fyn ? fyn->fyd : NULL; +} + +static inline struct fy_anchor * +fy_document_accel_lookup_anchor_by_token(struct fy_document *fyd, struct fy_token *fyt) +{ + assert(fyd); + assert(fyd->axl); + return (void *)fy_accel_lookup(fyd->axl, fyt); +} + +static inline struct fy_anchor * +fy_document_accel_lookup_anchor_by_node(struct fy_document *fyd, struct fy_node *fyn) +{ + assert(fyd); + assert(fyd->naxl); + return (void *)fy_accel_lookup(fyd->naxl, fyn); +} + +static inline struct fy_node_pair * +fy_node_accel_lookup_by_node(struct fy_node *fyn, struct fy_node *fyn_key) +{ + assert(fyn); + assert(fyn->xl); + + return (void *)fy_accel_lookup(fyn->xl, (const void *)fyn_key); +} + +struct fy_anchor * +fy_document_lookup_anchor(struct fy_document *fyd, const char *anchor, size_t len) +{ + struct fy_anchor *fya; + struct fy_anchor_list *fyal; + struct fy_input *fyi; + struct fy_atom handle; + struct fy_token *fyt; + const char *text; + size_t text_len; + + if (!fyd || !anchor) + return NULL; + + if (len == (size_t)-1) + len = strlen(anchor); + + if (fy_document_is_accelerated(fyd)) { + fyi = fy_input_from_data(anchor, len, &handle, true); + if (!fyi) + return NULL; + + fyt = fy_token_create(FYTT_ANCHOR, &handle); + + if (!fyt) { + fy_input_unref(fyi); + return NULL; + } + + fya = fy_document_accel_lookup_anchor_by_token(fyd, fyt); + + fy_input_unref(fyi); + fy_token_unref(fyt); + + if (!fya) + return NULL; + + /* single anchor? return it */ + if (!fya->multiple) + return fya; + + /* multiple anchors, fall-through */ + } + + /* note that we're performing the lookup in reverse creation order + * so that we pick the most recent + */ + fyal = &fyd->anchors; + for (fya = fy_anchor_list_tail(fyal); fya; fya = fy_anchor_prev(fyal, fya)) { + text = fy_anchor_get_text(fya, &text_len); + if (!text) + return NULL; + + if (len == text_len && !memcmp(anchor, text, len)) + return fya; + } + + return NULL; +} + +struct fy_anchor * +fy_document_lookup_anchor_by_token(struct fy_document *fyd, + struct fy_token *anchor) +{ + struct fy_anchor *fya, *fya_found, *fya_found2; + struct fy_anchor_list *fyal; + const char *anchor_text, *text; + size_t anchor_len, text_len; + int count; + + if (!fyd || !anchor) + return NULL; + + /* first try direct match (it's faster and the common case) */ + if (fy_document_is_accelerated(fyd)) { + fya = fy_document_accel_lookup_anchor_by_token(fyd, anchor); + if (!fya) + return NULL; + + /* single anchor? return it */ + if (!fya->multiple) + return fya; + + /* multiple anchors, fall-through */ + } + + anchor_text = fy_token_get_text(anchor, &anchor_len); + if (!anchor_text) + return NULL; + + fyal = &fyd->anchors; + + /* first pass, try with a single match */ + count = 0; + fya_found = NULL; + for (fya = fy_anchor_list_head(fyal); fya; fya = fy_anchor_next(fyal, fya)) { + text = fy_anchor_get_text(fya, &text_len); + if (!text) + return NULL; + + if (anchor_len == text_len && !memcmp(anchor_text, text, anchor_len)) { + count++; + fya_found = fya; + } + } + + /* not found */ + if (!count) + return NULL; + + /* single one? fine */ + if (count == 1) + return fya_found; + + /* multiple ones, must pick the one that's the last one before + * the requesting token */ + /* fyd_notice(fyd, "multiple anchors for %.*s", (int)anchor_len, anchor_text); */ + + /* only try the ones on the same input + * we don't try to cover the case where the label is referenced + * by other constructed documents + */ + fya_found2 = NULL; + for (fya = fy_anchor_list_head(fyal); fya; fya = fy_anchor_next(fyal, fya)) { + + /* only on the same input */ + if (fy_token_get_input(fya->anchor) != fy_token_get_input(anchor)) + continue; + + text = fy_anchor_get_text(fya, &text_len); + if (!text) + return NULL; + + if (anchor_len == text_len && !memcmp(anchor_text, text, anchor_len) && + fy_token_start_pos(fya->anchor) < fy_token_start_pos(anchor)) { + fya_found2 = fya; + } + } + + /* just return the one find earlier */ + if (!fya_found2) + return fya_found; + + /* return the one that was the latest */ + return fya_found2; +} + +struct fy_anchor *fy_document_lookup_anchor_by_node(struct fy_document *fyd, struct fy_node *fyn) +{ + struct fy_anchor *fya; + struct fy_anchor_list *fyal; + + if (!fyd || !fyn) + return NULL; + + if (fy_document_is_accelerated(fyd)) { + fya = fy_document_accel_lookup_anchor_by_node(fyd, fyn); + } else { + fyal = &fyd->anchors; + for (fya = fy_anchor_list_head(fyal); fya; fya = fy_anchor_next(fyal, fya)) { + if (fya->fyn == fyn) + break; + } + } + + return fya; +} + +const char *fy_anchor_get_text(struct fy_anchor *fya, size_t *lenp) +{ + if (!fya || !lenp) + return NULL; + return fy_token_get_text(fya->anchor, lenp); +} + +struct fy_node *fy_anchor_node(struct fy_anchor *fya) +{ + if (!fya) + return NULL; + return fya->fyn; +} + +int fy_node_pair_free(struct fy_node_pair *fynp) +{ + int rc, rc_ret = 0; + + if (!fynp) + return 0; + + rc = fy_node_free(fynp->key); + if (rc) + rc_ret = -1; + rc = fy_node_free(fynp->value); + if (rc) + rc_ret = -1; + + free(fynp); + + return rc_ret; +} + +void fy_node_pair_detach_and_free(struct fy_node_pair *fynp) +{ + if (!fynp) + return; + + fy_node_detach_and_free(fynp->key); + fy_node_detach_and_free(fynp->value); + free(fynp); +} + +struct fy_node_pair *fy_node_pair_alloc(struct fy_document *fyd) +{ + struct fy_node_pair *fynp = NULL; + + fynp = malloc(sizeof(*fynp)); + if (!fynp) + return NULL; + + fynp->key = NULL; + fynp->value = NULL; + fynp->fyd = fyd; + fynp->parent = NULL; + return fynp; +} + +int fy_node_free(struct fy_node *fyn) +{ + struct fy_document *fyd; + struct fy_node *fyni; + struct fy_node_pair *fynp; + struct fy_anchor *fya, *fyan; + struct fy_accel_entry_iter xli; + struct fy_accel_entry *xle, *xlen; + + if (!fyn) + return 0; + + /* a document must exist */ + fyd = fyn->fyd; + if (!fyd) + return -1; + + if (fyn->attached) + return -1; + + if (fy_document_is_accelerated(fyd)) { + for (xle = fy_accel_entry_iter_start(&xli, fyd->naxl, fyn); + xle; xle = xlen) { + xlen = fy_accel_entry_iter_next(&xli); + + fya = (void *)xle->value; + + fy_anchor_list_del(&fyd->anchors, fya); + + xle = fy_accel_entry_lookup_key_value(fyd->axl, fya->anchor, fya); + fy_accel_entry_remove(fyd->axl, xle); + + xle = fy_accel_entry_lookup_key_value(fyd->naxl, fya->fyn, fya); + fy_accel_entry_remove(fyd->naxl, xle); + + fy_anchor_destroy(fya); + } + fy_accel_entry_iter_finish(&xli); + } else { + /* remove anchors that are located on this node */ + for (fya = fy_anchor_list_head(&fyd->anchors); fya; fya = fyan) { + fyan = fy_anchor_next(&fyd->anchors, fya); + if (fya->fyn == fyn) { + fy_anchor_list_del(&fyd->anchors, fya); + fy_anchor_destroy(fya); + } + } + } + + /* clear the meta data of this node */ + fy_node_clear_meta(fyn); + + fy_token_unref(fyn->tag); + fyn->tag = NULL; + switch (fyn->type) { + case FYNT_SCALAR: + fy_token_unref(fyn->scalar); + fyn->scalar = NULL; + break; + case FYNT_SEQUENCE: + while ((fyni = fy_node_list_pop(&fyn->sequence)) != NULL) + fy_node_detach_and_free(fyni); + fy_token_unref(fyn->sequence_start); + fy_token_unref(fyn->sequence_end); + fyn->sequence_start = NULL; + fyn->sequence_end = NULL; + break; + case FYNT_MAPPING: + while ((fynp = fy_node_pair_list_pop(&fyn->mapping)) != NULL) { + if (fyn->xl) + fy_accel_remove(fyn->xl, fynp->key); + fy_node_pair_detach_and_free(fynp); + } + fy_token_unref(fyn->mapping_start); + fy_token_unref(fyn->mapping_end); + fyn->mapping_start = NULL; + fyn->mapping_end = NULL; + break; + } + + if (fyn->xl) { + fy_accel_cleanup(fyn->xl); + free(fyn->xl); + } + + fy_node_cleanup_path_expr_data(fyn); + + free(fyn); + + return 0; +} + +void fy_node_detach_and_free(struct fy_node *fyn) +{ + int rc __FY_DEBUG_UNUSED__; + + if (!fyn || !fyn->fyd) + return; + + fyn->attached = false; + + /* it must always succeed */ + rc = fy_node_free(fyn); + assert(!rc); +} + +struct fy_node *fy_node_alloc(struct fy_document *fyd, enum fy_node_type type) +{ + struct fy_node *fyn = NULL; + int rc; + + fyn = malloc(sizeof(*fyn)); + if (!fyn) + return NULL; + + memset(fyn, 0, sizeof(*fyn)); + + fyn->style = FYNS_ANY; + fyn->fyd = fyd; + fyn->type = type; + + switch (fyn->type) { + case FYNT_SCALAR: + break; + + case FYNT_SEQUENCE: + fy_node_list_init(&fyn->sequence); + break; + case FYNT_MAPPING: + fy_node_pair_list_init(&fyn->mapping); + + if (fy_document_is_accelerated(fyd)) { + fyn->xl = malloc(sizeof(*fyn->xl)); + fyd_error_check(fyd, fyn->xl, err_out, + "malloc() failed"); + + /* start with a very small bucket list */ + rc = fy_accel_setup(fyn->xl, &hd_mapping, fyd, 8); + fyd_error_check(fyd, !rc, err_out, + "fy_accel_setup() failed"); + } + break; + } + return fyn; + +err_out: + if (fyn) { + if (fyn->xl) { + fy_accel_cleanup(fyn->xl); + free(fyn->xl); + } + free(fyn); + } + return NULL; +} + +struct fy_token *fy_node_non_synthesized_token(struct fy_node *fyn) +{ + struct fy_token *fyt_start = NULL, *fyt_end = NULL; + struct fy_token *fyt; + struct fy_input *fyi; + struct fy_atom handle; + unsigned int aflags; + const char *s, *e; + size_t size; + + if (!fyn) + return NULL; + + fyi = fy_node_get_input(fyn); + if (!fyi) + return NULL; + + switch (fyn->type) { + case FYNT_SCALAR: + return fy_token_ref(fyn->scalar); + + case FYNT_SEQUENCE: + fyt_start = fyn->sequence_start; + fyt_end = fyn->sequence_end; + break; + + case FYNT_MAPPING: + fyt_start = fyn->mapping_start; + fyt_end = fyn->mapping_end; + break; + + } + + if (!fyt_start || !fyt_end) + return NULL; + + s = fy_input_start(fyi) + fyt_start->handle.start_mark.input_pos; + e = fy_input_start(fyi) + fyt_end->handle.end_mark.input_pos; + size = (size_t)(e - s); + + if (size > 0) + aflags = fy_analyze_scalar_content(s, size, + fy_token_atom_json_mode(fyt_start), + fy_token_atom_lb_mode(fyt_start), + fy_token_atom_flow_ws_mode(fyt_start)); + else + aflags = FYACF_EMPTY | FYACF_FLOW_PLAIN | FYACF_BLOCK_PLAIN; + + memset(&handle, 0, sizeof(handle)); + handle.start_mark = fyt_start->handle.start_mark; + handle.end_mark = fyt_end->handle.end_mark; + + /* if it's plain, all is good */ + if (aflags & FYACF_FLOW_PLAIN) { + handle.storage_hint = size; /* maximum */ + handle.storage_hint_valid = false; + handle.direct_output = !!(aflags & FYACF_JSON_ESCAPE); /* direct only when no json escape */ + handle.style = FYAS_PLAIN; + } else { + handle.storage_hint = 0; /* just calculate */ + handle.storage_hint_valid = false; + handle.direct_output = false; + handle.style = FYAS_DOUBLE_QUOTED_MANUAL; + } + handle.empty = !!(aflags & FYACF_EMPTY); + handle.has_lb = !!(aflags & FYACF_LB); + handle.has_ws = !!(aflags & FYACF_WS); + handle.starts_with_ws = !!(aflags & FYACF_STARTS_WITH_WS); + handle.starts_with_lb = !!(aflags & FYACF_STARTS_WITH_LB); + handle.ends_with_ws = !!(aflags & FYACF_ENDS_WITH_WS); + handle.ends_with_lb = !!(aflags & FYACF_ENDS_WITH_LB); + handle.trailing_lb = !!(aflags & FYACF_TRAILING_LB); + handle.size0 = !!(aflags & FYACF_SIZE0); + handle.valid_anchor = !!(aflags & FYACF_VALID_ANCHOR); + handle.json_mode = false; /* always false */ + handle.lb_mode = fylb_cr_nl; /* always \r\n */ + handle.fws_mode = fyfws_space_tab; /* always space + tab */ + + handle.chomp = FYAC_STRIP; + handle.increment = 0; + handle.fyi = fyi; + handle.tabsize = 0; + + fyt = fy_token_create(FYTT_INPUT_MARKER, &handle); + if (!fyt) + return NULL; + + return fyt; +} + +struct fy_token *fy_node_token(struct fy_node *fyn) +{ + struct fy_atom atom; + struct fy_input *fyi = NULL; + struct fy_token *fyt = NULL; + char *buf = NULL; + + if (!fyn) + return NULL; + + /* if it's non synthetic we can use the node extends */ + if (!fy_node_is_synthetic(fyn)) + return fy_node_non_synthesized_token(fyn); + + /* emit to a string and create the token there */ + buf = fy_emit_node_to_string(fyn, FYECF_MODE_FLOW_ONELINE | FYECF_WIDTH_INF); + if (!buf) + goto err_out; + + fyi = fy_input_from_malloc_data(buf, FY_NT, &atom, true); + if (!fyi) + goto err_out; + + fyt = fy_token_create(FYTT_INPUT_MARKER, &atom); + if (!fyt) + goto err_out; + + /* take away the input reference */ + fy_input_unref(fyi); + + return fyt; + +err_out: + fy_input_unref(fyi); + if (buf) + free(buf); + return NULL; +} + +bool fy_node_uses_single_input_only(struct fy_node *fyn, struct fy_input *fyi) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp; + + if (!fyn || !fyi) + return false; + + switch (fyn->type) { + case FYNT_SCALAR: + return fy_token_get_input(fyn->scalar) == fyi; + + case FYNT_SEQUENCE: + if (fy_token_get_input(fyn->sequence_start) != fyi) + return false; + + for (fyni = fy_node_list_head(&fyn->sequence); fyni; + fyni = fy_node_next(&fyn->sequence, fyni)) { + + if (!fy_node_uses_single_input_only(fyni, fyi)) + return false; + } + + if (fy_token_get_input(fyn->sequence_end) != fyi) + return false; + break; + + case FYNT_MAPPING: + if (fy_token_get_input(fyn->mapping_start) != fyi) + return false; + + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; + fynp = fy_node_pair_next(&fyn->mapping, fynp)) { + + if (fynp->key && !fy_node_uses_single_input_only(fynp->key, fyi)) + return false; + + if (fynp->value && !fy_node_uses_single_input_only(fynp->value, fyi)) + return false; + } + + if (fy_token_get_input(fyn->mapping_end) != fyi) + return false; + + break; + } + + return true; +} + +struct fy_input *fy_node_get_first_input(struct fy_node *fyn) +{ + if (!fyn) + return NULL; + + switch (fyn->type) { + case FYNT_SCALAR: + return fy_token_get_input(fyn->scalar); + + case FYNT_SEQUENCE: + return fy_token_get_input(fyn->sequence_start); + + case FYNT_MAPPING: + return fy_token_get_input(fyn->mapping_start); + } + + /* should never happen */ + return NULL; +} + +/* a node is synthetic if any of it's tokens reside in + * different inputs, or any sequence/mapping has been + * created via the manual sequence/mapping creation methods + */ +bool fy_node_is_synthetic(struct fy_node *fyn) +{ + return fyn && fyn->synthetic; +} + +/* map this node and all of it's parents synthetic */ +void fy_node_mark_synthetic(struct fy_node *fyn) +{ + if (!fyn) + return; + fyn->synthetic = true; + while ((fyn = fy_node_get_document_parent(fyn)) != NULL) + fyn->synthetic = true; +} + +struct fy_input *fy_node_get_input(struct fy_node *fyn) +{ + struct fy_input *fyi = NULL; + + fyi = fy_node_get_first_input(fyn); + if (!fyi) + return NULL; + + return fy_node_uses_single_input_only(fyn, fyi) ? fyi : NULL; +} + +int fy_document_register_anchor(struct fy_document *fyd, + struct fy_node *fyn, struct fy_token *anchor) +{ + struct fy_anchor *fya, *fyam; + struct fy_accel_entry *xle; + const char *text; + size_t text_len; + int rc; + + fya = fy_anchor_create(fyd, fyn, anchor); + fyd_error_check(fyd, fya, err_out, + "fy_anchor_create() failed"); + + fy_anchor_list_add_tail(&fyd->anchors, fya); + if (fy_document_is_accelerated(fyd)) { + xle = fy_accel_entry_lookup(fyd->axl, fya->anchor); + if (xle) { + fyam = (void *)xle->value; + /* multiple */ + if (!fyam->multiple) + fyam->multiple = true; + fya->multiple = true; + + text = fy_anchor_get_text(fya, &text_len); + fyd_notice(fyd, "register anchor %.*s is multiple", (int)text_len, text); + } + + xle = fy_accel_entry_insert(fyd->axl, fya->anchor, fya); + fyd_error_check(fyd, xle, err_out, + "fy_accel_entry_insert() fyd->axl failed"); + } + + if (fy_document_is_accelerated(fyd)) { + rc = fy_accel_insert(fyd->naxl, fyn, fya); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_accel_insert() fyd->naxl failed"); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + fyd->diag->on_error = false; + return rc; +} + +struct fy_node_cmp_arg { + fy_node_scalar_compare_fn cmp_fn; + void *arg; +}; + +static int fy_node_scalar_cmp_default(struct fy_node *fyn_a, + struct fy_node *fyn_b, + void *arg); + +static int fy_node_mapping_sort_cmp_default(const struct fy_node_pair *fynp_a, + const struct fy_node_pair *fynp_b, + void *arg); + +bool fy_node_compare_user(struct fy_node *fyn1, struct fy_node *fyn2, + fy_node_mapping_sort_fn sort_fn, void *sort_fn_arg, + fy_node_scalar_compare_fn cmp_fn, void *cmp_fn_arg) +{ + struct fy_node *fyni1, *fyni2; + struct fy_node_pair *fynp1, *fynp2; + bool ret, null1, null2; + struct fy_node_pair **fynpp1, **fynpp2; + int i, count1, count2; + bool alias1, alias2; + struct fy_node_cmp_arg def_arg; + + if (!cmp_fn) { + cmp_fn = fy_node_scalar_cmp_default; + cmp_fn_arg = NULL; + } + if (!sort_fn) { + sort_fn = fy_node_mapping_sort_cmp_default; + def_arg.cmp_fn = cmp_fn; + def_arg.arg = cmp_fn_arg; + sort_fn_arg = &def_arg; + } else { + def_arg.cmp_fn = NULL; + def_arg.arg = NULL; + } + /* equal pointers? */ + if (fyn1 == fyn2) + return true; + + null1 = !fyn1 || (fyn1->type == FYNT_SCALAR && fy_token_get_text_length(fyn1->scalar) == 0); + null2 = !fyn2 || (fyn2->type == FYNT_SCALAR && fy_token_get_text_length(fyn2->scalar) == 0); + + /* both null */ + if (null1 && null2) + return true; + + /* either is NULL, no match */ + if (null1 || null2) + return false; + + /* types must match */ + if (fyn1->type != fyn2->type) + return false; + + ret = true; + + switch (fyn1->type) { + case FYNT_SEQUENCE: + fyni1 = fy_node_list_head(&fyn1->sequence); + fyni2 = fy_node_list_head(&fyn2->sequence); + while (fyni1 && fyni2) { + + ret = fy_node_compare(fyni1, fyni2); + if (!ret) + break; + + fyni1 = fy_node_next(&fyn1->sequence, fyni1); + fyni2 = fy_node_next(&fyn2->sequence, fyni2); + } + if (ret && fyni1 != fyni2 && (!fyni1 || !fyni2)) + ret = false; + + break; + + case FYNT_MAPPING: + count1 = fy_node_mapping_item_count(fyn1); + count2 = fy_node_mapping_item_count(fyn2); + + /* mapping counts must match */ + if (count1 != count2) { + ret = false; + break; + } + + fynpp1 = alloca(sizeof(*fynpp1) * (count1 + 1)); + fynpp2 = alloca(sizeof(*fynpp2) * (count2 + 1)); + + fy_node_mapping_perform_sort(fyn1, sort_fn, sort_fn_arg, fynpp1, count1); + fy_node_mapping_perform_sort(fyn2, sort_fn, sort_fn_arg, fynpp2, count2); + + for (i = 0; i < count1; i++) { + fynp1 = fynpp1[i]; + fynp2 = fynpp2[i]; + + ret = fy_node_compare(fynp1->key, fynp2->key); + if (!ret) + break; + + ret = fy_node_compare(fynp1->value, fynp2->value); + if (!ret) + break; + } + if (i >= count1) + ret = true; + + break; + + case FYNT_SCALAR: + alias1 = fy_node_is_alias(fyn1); + alias2 = fy_node_is_alias(fyn2); + + /* either both must be aliases or both not */ + if (alias1 != alias2) + return false; + + ret = !cmp_fn(fyn1, fyn2, cmp_fn_arg); + break; + } + + return ret; +} + +bool fy_node_compare(struct fy_node *fyn1, struct fy_node *fyn2) +{ + return fy_node_compare_user(fyn1, fyn2, NULL, NULL, NULL, NULL); +} + +bool fy_node_compare_string(struct fy_node *fyn, const char *str, size_t len) +{ + struct fy_document *fyd = NULL; + bool ret; + + fyd = fy_document_build_from_string(NULL, str, len); + if (!fyd) + return false; + + ret = fy_node_compare(fyn, fy_document_root(fyd)); + + fy_document_destroy(fyd); + + return ret; +} + +bool fy_node_compare_token(struct fy_node *fyn, struct fy_token *fyt) +{ + /* check if there's NULL */ + if (!fyn || !fyt) + return false; + + /* only valid for scalars */ + if (!fy_node_is_scalar(fyn) || fyt->type != FYTT_SCALAR) + return false; + + return fy_token_cmp(fyn->scalar, fyt) == 0; +} + +bool fy_node_compare_text(struct fy_node *fyn, const char *text, size_t len) +{ + const char *textn; + size_t lenn; + + if (!fyn || !text) + return false; + + textn = fy_node_get_scalar(fyn, &lenn); + if (!textn) + return false; + + if (len == FY_NT) + len = strlen(text); + + if (len != lenn) + return false; + + return memcmp(text, textn, len) == 0; +} + +struct fy_node_pair *fy_node_mapping_lookup_pair(struct fy_node *fyn, struct fy_node *fyn_key) +{ + struct fy_node_pair *fynpi, *fynp; + + /* sanity check */ + if (!fy_node_is_mapping(fyn)) + return NULL; + + fynp = NULL; + + + if (fyn->xl) { + fynp = fy_node_accel_lookup_by_node(fyn, fyn_key); + } else { + for (fynpi = fy_node_pair_list_head(&fyn->mapping); fynpi; + fynpi = fy_node_pair_next(&fyn->mapping, fynpi)) { + if (fy_node_compare(fynpi->key, fyn_key)) { + fynp = fynpi; + break; + } + } + } + + return fynp; +} + +int fy_node_mapping_get_pair_index(struct fy_node *fyn, const struct fy_node_pair *fynp) +{ + struct fy_node_pair *fynpi; + int i; + + for (i = 0, fynpi = fy_node_pair_list_head(&fyn->mapping); fynpi; + fynpi = fy_node_pair_next(&fyn->mapping, fynpi), i++) { + + if (fynpi == fynp) + return i; + } + + return -1; +} + +bool fy_node_mapping_key_is_duplicate(struct fy_node *fyn, struct fy_node *fyn_key) +{ + return fy_node_mapping_lookup_pair(fyn, fyn_key) != NULL; +} + +static int +fy_parse_document_load_node(struct fy_parser *fyp, struct fy_document *fyd, + struct fy_eventp *fyep, struct fy_node **fynp, + int *depthp); + +int fy_parse_document_load_alias(struct fy_parser *fyp, struct fy_document *fyd, struct fy_eventp *fyep, struct fy_node **fynp) +{ + *fynp = NULL; + + fyp_doc_debug(fyp, "in %s", __func__); + + /* TODO verify aliases etc */ + fy_parse_eventp_recycle(fyp, fyep); + return 0; +} + +static int +fy_parse_document_load_scalar(struct fy_parser *fyp, struct fy_document *fyd, + struct fy_eventp *fyep, struct fy_node **fynp, + int *depthp) +{ + struct fy_node *fyn = NULL; + struct fy_event *fye; + int rc; + + if (!fyd) + return -1; + + fyp_error_check(fyp, fyep || !fyp->stream_error, err_out, + "no event to process"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC, + fyep, err_out, + "premature end of event stream"); + + fyp_doc_debug(fyp, "in %s [%s]", __func__, fy_event_type_txt[fyep->e.type]); + + *fynp = NULL; + + fye = &fyep->e; + + /* we don't free nodes that often, so no need for recycling */ + fyn = fy_node_alloc(fyd, FYNT_SCALAR); + fyp_error_check(fyp, fyn, err_out, + "fy_node_alloc() failed"); + + if (fye->type == FYET_SCALAR) { + + /* move the tags and value to the node */ + if (fye->scalar.value) + fyn->style = fy_node_style_from_scalar_style(fye->scalar.value->scalar.style); + else + fyn->style = FYNS_PLAIN; + fyn->tag = fye->scalar.tag; + fye->scalar.tag = NULL; + + fyn->scalar = fye->scalar.value; + fye->scalar.value = NULL; + + if (fye->scalar.anchor) { + rc = fy_document_register_anchor(fyd, fyn, fye->scalar.anchor); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_document_register_anchor() failed"); + fye->scalar.anchor = NULL; + } + + } else if (fye->type == FYET_ALIAS) { + fyn->style = FYNS_ALIAS; + fyn->scalar = fye->alias.anchor; + fye->alias.anchor = NULL; + } else + assert(0); + + *fynp = fyn; + fyn = NULL; + + /* everything OK */ + fy_parse_eventp_recycle(fyp, fyep); + return 0; + +err_out: + rc = -1; +err_out_rc: + fy_parse_eventp_recycle(fyp, fyep); + fyd->diag->on_error = false; + return rc; +} + +static int +fy_parse_document_load_sequence(struct fy_parser *fyp, struct fy_document *fyd, + struct fy_eventp *fyep, struct fy_node **fynp, + int *depthp) +{ + struct fy_node *fyn = NULL, *fyn_item = NULL; + struct fy_event *fye = NULL; + struct fy_token *fyt_ss = NULL; + int rc; + + fyp_error_check(fyp, fyep || !fyp->stream_error, err_out, + "no event to process"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC, + fyep, err_out, + "premature end of event stream"); + + fyp_doc_debug(fyp, "in %s [%s]", __func__, fy_event_type_txt[fyep->e.type]); + + *fynp = NULL; + + fye = &fyep->e; + + fyt_ss = fye->sequence_start.sequence_start; + + /* we don't free nodes that often, so no need for recycling */ + fyn = fy_node_alloc(fyd, FYNT_SEQUENCE); + fyp_error_check(fyp, fyn, err_out, + "fy_node_alloc() failed"); + + fyn->style = fyt_ss && fyt_ss->type == FYTT_FLOW_SEQUENCE_START ? FYNS_FLOW : FYNS_BLOCK; + + fyn->tag = fye->sequence_start.tag; + fye->sequence_start.tag = NULL; + + if (fye->sequence_start.anchor) { + rc = fy_document_register_anchor(fyd, fyn, fye->sequence_start.anchor); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_document_register_anchor() failed"); + fye->sequence_start.anchor = NULL; + } + + if (fye->sequence_start.sequence_start) { + fyn->sequence_start = fye->sequence_start.sequence_start; + fye->sequence_start.sequence_start = NULL; + } else + fyn->sequence_start = NULL; + + assert(fyn->sequence_start); + + /* done with this */ + fy_parse_eventp_recycle(fyp, fyep); + fyep = NULL; + + while ((fyep = fy_parse_private(fyp)) != NULL) { + fye = &fyep->e; + if (fye->type == FYET_SEQUENCE_END) + break; + + rc = fy_parse_document_load_node(fyp, fyd, fyep, &fyn_item, depthp); + fyep = NULL; + fyp_error_check(fyp, !rc, err_out_rc, + "fy_parse_document_load_node() failed"); + + fy_node_list_add_tail(&fyn->sequence, fyn_item); + fyn_item->attached = true; + fyn_item = NULL; + } + + if (!fyep) + goto err_out; + + if (fye->sequence_end.sequence_end) { + fyn->sequence_end = fye->sequence_end.sequence_end; + fye->sequence_end.sequence_end = NULL; + } else + fyn->sequence_end = NULL; + + assert(fyn->sequence_end); + + *fynp = fyn; + fyn = NULL; + + fy_parse_eventp_recycle(fyp, fyep); + return 0; + + /* fallthrough */ +err_out: + rc = -1; +err_out_rc: + fy_parse_eventp_recycle(fyp, fyep); + fy_node_detach_and_free(fyn_item); + fy_node_detach_and_free(fyn); + return rc; +} + +static int +fy_parse_document_load_mapping(struct fy_parser *fyp, struct fy_document *fyd, + struct fy_eventp *fyep, struct fy_node **fynp, + int *depthp) +{ + struct fy_node *fyn = NULL, *fyn_key = NULL, *fyn_value = NULL; + struct fy_node_pair *fynp_item = NULL; + struct fy_event *fye = NULL; + struct fy_token *fyt_ms = NULL; + bool duplicate; + int rc; + + fyp_error_check(fyp, fyep || !fyp->stream_error, err_out, + "no event to process"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC, + fyep, err_out, + "premature end of event stream"); + + fyp_doc_debug(fyp, "in %s [%s]", __func__, fy_event_type_txt[fyep->e.type]); + + *fynp = NULL; + + fye = &fyep->e; + + fyt_ms = fye->mapping_start.mapping_start; + + /* we don't free nodes that often, so no need for recycling */ + fyn = fy_node_alloc(fyd, FYNT_MAPPING); + fyp_error_check(fyp, fyn, err_out, + "fy_node_alloc() failed"); + + fyn->style = fyt_ms && fyt_ms->type == FYTT_FLOW_MAPPING_START ? FYNS_FLOW : FYNS_BLOCK; + + fyn->tag = fye->mapping_start.tag; + fye->mapping_start.tag = NULL; + + if (fye->mapping_start.anchor) { + rc = fy_document_register_anchor(fyd, fyn, fye->mapping_start.anchor); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_document_register_anchor() failed"); + fye->mapping_start.anchor = NULL; + } + + if (fye->mapping_start.mapping_start) { + fyn->mapping_start = fye->mapping_start.mapping_start; + fye->mapping_start.mapping_start = NULL; + } + + assert(fyn->mapping_start); + + /* done with this */ + fy_parse_eventp_recycle(fyp, fyep); + fyep = NULL; + + while ((fyep = fy_parse_private(fyp)) != NULL) { + fye = &fyep->e; + if (fye->type == FYET_MAPPING_END) + break; + + fynp_item = fy_node_pair_alloc(fyd); + fyp_error_check(fyp, fynp_item, err_out, + "fy_node_pair_alloc() failed"); + + fyn_key = NULL; + fyn_value = NULL; + + rc = fy_parse_document_load_node(fyp, fyd, + fyep, &fyn_key, depthp); + fyep = NULL; + + assert(fyn_key); + + 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); + + FYP_NODE_ERROR_CHECK(fyp, fyn_key, FYEM_DOC, + !duplicate, err_out, + "duplicate key"); + + fyep = fy_parse_private(fyp); + + fyp_error_check(fyp, fyep || !fyp->stream_error, err_out, + "fy_parse_private() failed"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC, + fyep, err_out, + "missing mapping value"); + + fye = &fyep->e; + + rc = fy_parse_document_load_node(fyp, fyd, + fyep, &fyn_value, depthp); + fyep = NULL; + fyp_error_check(fyp, !rc, err_out_rc, + "fy_parse_document_load_node() failed"); + + assert(fyn_value); + + fynp_item->key = fyn_key; + fynp_item->value = fyn_value; + fy_node_pair_list_add_tail(&fyn->mapping, fynp_item); + if (fyn->xl) { + rc = fy_accel_insert(fyn->xl, fynp_item->key, fynp_item); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_accel_insert() failed"); + } + + if (fynp_item->key) + fynp_item->key->attached = true; + if (fynp_item->value) + fynp_item->value->attached = true; + fynp_item = NULL; + fyn_key = NULL; + fyn_value = NULL; + } + + if (!fyep) + goto err_out; + + if (fye->mapping_end.mapping_end) { + fyn->mapping_end = fye->mapping_end.mapping_end; + fye->mapping_end.mapping_end = NULL; + } + + assert(fyn->mapping_end); + + *fynp = fyn; + fyn = NULL; + + fy_parse_eventp_recycle(fyp, fyep); + + return 0; + +err_out: + rc = -1; +err_out_rc: + fy_parse_eventp_recycle(fyp, fyep); + fy_node_pair_free(fynp_item); + fy_node_detach_and_free(fyn_key); + fy_node_detach_and_free(fyn_value); + fy_node_detach_and_free(fyn); + 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, + int *depthp) +{ + struct fy_event *fye; + enum fy_event_type type; + int ret; + + *fynp = NULL; + + fyp_error_check(fyp, fyep || !fyp->stream_error, err_out, + "no event to process"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC, + fyep, err_out, + "premature end of event stream"); + + fyp_doc_debug(fyp, "in %s [%s]", __func__, fy_event_type_txt[fyep->e.type]); + + fye = &fyep->e; + + type = fye->type; + + FYP_TOKEN_ERROR_CHECK(fyp, fy_event_get_token(fye), FYEM_DOC, + type == FYET_ALIAS || type == FYET_SCALAR || + type == FYET_SEQUENCE_START || type == FYET_MAPPING_START, err_out, + "bad event"); + + (*depthp)++; + + FYP_TOKEN_ERROR_CHECK(fyp, fy_event_get_token(fye), FYEM_DOC, + ((fyp->cfg.flags & FYPCF_DISABLE_DEPTH_LIMIT) || + *depthp <= fy_depth_limit()), err_out, + "depth limit exceeded"); + + switch (type) { + + case FYET_ALIAS: + case FYET_SCALAR: + ret = fy_parse_document_load_scalar(fyp, fyd, + fyep, fynp, depthp); + break; + + case FYET_SEQUENCE_START: + ret = fy_parse_document_load_sequence(fyp, fyd, + fyep, fynp, depthp); + break; + + case FYET_MAPPING_START: + ret = fy_parse_document_load_mapping(fyp, fyd, + fyep, fynp, depthp); + break; + + default: + ret = 0; + break; + } + + --(*depthp); + return ret; + +err_out: + fy_parse_eventp_recycle(fyp, fyep); + return -1; +} + +int fy_parse_document_load_end(struct fy_parser *fyp, struct fy_document *fyd, struct fy_eventp *fyep) +{ + struct fy_event *fye; + int rc; + + fyp_error_check(fyp, fyep || !fyp->stream_error, err_out, + "no event to process"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 0, FYEM_DOC, + fyep, err_out, + "premature end of event stream"); + + fyp_doc_debug(fyp, "in %s [%s]", __func__, fy_event_type_txt[fyep->e.type]); + + fye = &fyep->e; + + FYP_TOKEN_ERROR_CHECK(fyp, fy_event_get_token(fye), FYEM_DOC, + fye->type == FYET_DOCUMENT_END, err_out, + "bad event"); + + /* recycle the document end event */ + fy_parse_eventp_recycle(fyp, fyep); + + return 0; +err_out: + rc = -1; + fy_parse_eventp_recycle(fyp, fyep); + return rc; +} + +struct fy_document *fy_parse_load_document_recursive(struct fy_parser *fyp) +{ + struct fy_document *fyd = NULL; + struct fy_eventp *fyep = NULL; + struct fy_event *fye = NULL; + int rc, depth; + bool was_stream_start; + +again: + was_stream_start = false; + do { + /* get next event */ + fyep = fy_parse_private(fyp); + + /* no more */ + if (!fyep) + return NULL; + + was_stream_start = fyep->e.type == FYET_STREAM_START; + + if (was_stream_start) { + fy_parse_eventp_recycle(fyp, fyep); + fyep = NULL; + } + + } while (was_stream_start); + + fye = &fyep->e; + + /* STREAM_END */ + if (fye->type == FYET_STREAM_END) { + fy_parse_eventp_recycle(fyp, fyep); + + /* final STREAM_END? */ + if (fyp->state == FYPS_END) + return NULL; + + /* multi-stream */ + goto again; + } + + FYP_TOKEN_ERROR_CHECK(fyp, fy_event_get_token(fye), FYEM_DOC, + fye->type == FYET_DOCUMENT_START, err_out, + "bad event"); + + fyd = fy_parse_document_create(fyp, fyep); + fyep = NULL; + + fyp_error_check(fyp, fyd, err_out, + "fy_parse_document_create() failed"); + + fyp_doc_debug(fyp, "calling load_node() for root"); + depth = 0; + rc = fy_parse_document_load_node(fyp, fyd, fy_parse_private(fyp), + &fyd->root, &depth); + fyp_error_check(fyp, !rc, err_out, + "fy_parse_document_load_node() failed"); + + rc = fy_parse_document_load_end(fyp, fyd, fy_parse_private(fyp)); + fyp_error_check(fyp, !rc, err_out, + "fy_parse_document_load_node() failed"); + + /* always resolve parents */ + fy_resolve_parent_node(fyd, fyd->root, NULL); + + if (fyp->cfg.flags & FYPCF_RESOLVE_DOCUMENT) { + rc = fy_document_resolve(fyd); + fyp_error_check(fyp, !rc, err_out, + "fy_document_resolve() failed"); + } + + return fyd; + +err_out: + fy_parse_eventp_recycle(fyp, fyep); + fy_parse_document_destroy(fyp, fyd); + return NULL; +} + +struct fy_document *fy_parse_load_document_with_builder(struct fy_parser *fyp) +{ + struct fy_document *fyd; + int rc; + + if (!fyp) + return NULL; + + if (!fyp->fydb) { + fyp->fydb = fy_document_builder_create(&fyp->cfg); + if (!fyp->fydb) + return NULL; + } + + fyd = fy_document_builder_load_document(fyp->fydb, fyp); + if (!fyd) + return NULL; + + if (fyp->cfg.flags & FYPCF_RESOLVE_DOCUMENT) { + rc = fy_document_resolve(fyd); + if (rc) { + fy_document_destroy(fyd); + fyp->stream_error = true; + return NULL; + } + } + + return fyd; +} + +struct fy_document *fy_parse_load_document(struct fy_parser *fyp) +{ + if (!fyp) + return NULL; + + return !(fyp->cfg.flags & FYPCF_PREFER_RECURSIVE) ? + fy_parse_load_document_with_builder(fyp) : + fy_parse_load_document_recursive(fyp); +} + +struct fy_node *fy_node_copy_internal(struct fy_document *fyd, struct fy_node *fyn_from, + struct fy_node *fyn_parent) +{ + struct fy_document *fyd_from; + struct fy_node *fyn, *fyni, *fynit; + struct fy_node_pair *fynp, *fynpt; + struct fy_anchor *fya, *fya_from; + const char *anchor; + size_t anchor_len; + int rc; + + if (!fyd || !fyn_from || !fyn_from->fyd) + return NULL; + + fyd_from = fyn_from->fyd; + + fyn = fy_node_alloc(fyd, fyn_from->type); + fyd_error_check(fyd, fyn, err_out, + "fy_node_alloc() failed"); + + fyn->tag = fy_token_ref(fyn_from->tag); + fyn->style = fyn_from->style; + fyn->parent = fyn_parent; + + switch (fyn->type) { + case FYNT_SCALAR: + fyn->scalar = fy_token_ref(fyn_from->scalar); + break; + + case FYNT_SEQUENCE: + for (fyni = fy_node_list_head(&fyn_from->sequence); fyni; + fyni = fy_node_next(&fyn_from->sequence, fyni)) { + + fynit = fy_node_copy_internal(fyd, fyni, fyn); + fyd_error_check(fyd, fynit, err_out, + "fy_node_copy_internal() failed"); + + fy_node_list_add_tail(&fyn->sequence, fynit); + fynit->attached = true; + } + + break; + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn_from->mapping); fynp; + fynp = fy_node_pair_next(&fyn_from->mapping, fynp)) { + + fynpt = fy_node_pair_alloc(fyd); + fyd_error_check(fyd, fynpt, err_out, + "fy_node_pair_alloc() failed"); + + fynpt->key = fy_node_copy_internal(fyd, fynp->key, fyn); + fynpt->value = fy_node_copy_internal(fyd, fynp->value, fyn); + fynp->parent = fyn; + + fy_node_pair_list_add_tail(&fyn->mapping, fynpt); + if (fyn->xl) { + rc = fy_accel_insert(fyn->xl, fynpt->key, fynpt); + fyd_error_check(fyd, !rc, err_out, + "fy_accel_insert() failed"); + } + if (fynpt->key) { + fynpt->key->attached = true; + fynpt->key->key_root = true; + } + if (fynpt->value) + fynpt->value->attached = true; + } + break; + } + + /* drop an anchor to the copy */ + for (fya_from = fy_anchor_list_head(&fyd_from->anchors); fya_from; + fya_from = fy_anchor_next(&fyd_from->anchors, fya_from)) { + if (fyn_from == fya_from->fyn) + break; + } + + /* source node has an anchor */ + if (fya_from) { + fya = fy_document_lookup_anchor_by_token(fyd, fya_from->anchor); + if (!fya) { + fyd_doc_debug(fyd, "new anchor"); + /* update the new anchor position */ + rc = fy_document_register_anchor(fyd, fyn, fya_from->anchor); + fyd_error_check(fyd, !rc, err_out, + "fy_document_register_anchor() failed"); + + fy_token_ref(fya_from->anchor); + } else { + anchor = fy_anchor_get_text(fya, &anchor_len); + fyd_error_check(fyd, anchor, err_out, + "fy_anchor_get_text() failed"); + fyd_doc_debug(fyd, "not overwritting anchor %.*s", (int)anchor_len, anchor); + } + } + + return fyn; + +err_out: + return NULL; +} + +struct fy_node *fy_node_copy(struct fy_document *fyd, struct fy_node *fyn_from) +{ + struct fy_node *fyn; + + if (!fyd) + return NULL; + + fyn = fy_node_copy_internal(fyd, fyn_from, NULL); + if (!fyn) { + fyd->diag->on_error = false; + return NULL; + } + + return fyn; +} + +struct fy_document *fy_document_clone(struct fy_document *fydsrc) +{ + struct fy_document *fyd = NULL; + + if (!fydsrc) + return NULL; + + fyd = fy_document_create(&fydsrc->parse_cfg); + if (!fyd) + return NULL; + + /* drop the default document state */ + fy_document_state_unref(fyd->fyds); + /* and use the source document state (and ref it) */ + fyd->fyds = fy_document_state_ref(fydsrc->fyds); + assert(fyd->fyds); + + if (fydsrc->root) { + fyd->root = fy_node_copy(fyd, fydsrc->root); + if (!fyd->root) + goto err_out; + } + + return fyd; +err_out: + fy_document_destroy(fyd); + return NULL; +} + +int fy_node_copy_to_scalar(struct fy_document *fyd, struct fy_node *fyn_to, struct fy_node *fyn_from) +{ + struct fy_node *fyn, *fyni; + struct fy_node_pair *fynp; + + fyn = fy_node_copy(fyd, fyn_from); + if (!fyn) + return -1; + + /* the node is guaranteed to be a scalar */ + fy_token_unref(fyn_to->tag); + fyn_to->tag = NULL; + fy_token_unref(fyn_to->scalar); + fyn_to->scalar = NULL; + + fyn_to->type = fyn->type; + fyn_to->tag = fy_token_ref(fyn->tag); + fyn_to->style = fyn->style; + + switch (fyn->type) { + case FYNT_SCALAR: + fyn_to->scalar = fyn->scalar; + fyn->scalar = NULL; + break; + case FYNT_SEQUENCE: + fy_node_list_init(&fyn_to->sequence); + while ((fyni = fy_node_list_pop(&fyn->sequence)) != NULL) + fy_node_list_add_tail(&fyn_to->sequence, fyni); + break; + case FYNT_MAPPING: + fy_node_pair_list_init(&fyn_to->mapping); + while ((fynp = fy_node_pair_list_pop(&fyn->mapping)) != NULL) { + if (fyn->xl) + fy_accel_remove(fyn->xl, fynp->key); + fy_node_pair_list_add_tail(&fyn_to->mapping, fynp); + if (fyn_to->xl) + fy_accel_insert(fyn_to->xl, fynp->key, fynp); + } + break; + } + + /* and free */ + fy_node_free(fyn); + + return 0; +} + +static int fy_document_node_update_tags(struct fy_document *fyd, struct fy_node *fyn) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi; + struct fy_token *fyt_td; + const char *handle; + size_t handle_size; + int rc; + + if (!fyd || !fyn) + return 0; + + /* replace tag reference with the one that the document contains */ + if (fyn->tag) { + fyd_error_check(fyd, fyn->tag->type == FYTT_TAG, err_out, + "bad node tag"); + + handle = fy_tag_directive_token_handle(fyn->tag->tag.fyt_td, &handle_size); + fyd_error_check(fyd, handle, err_out, + "bad tag directive token"); + + fyt_td = fy_document_state_lookup_tag_directive(fyd->fyds, handle, handle_size); + fyd_error_check(fyd, fyt_td, err_out, + "Missing tag directive with handle=%.*s", (int)handle_size, handle); + + /* need to replace this */ + if (fyt_td != fyn->tag->tag.fyt_td) { + fy_token_unref(fyn->tag->tag.fyt_td); + fyn->tag->tag.fyt_td = fy_token_ref(fyt_td); + + } + } + + + 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)) { + + rc = fy_document_node_update_tags(fyd, fyni); + if (rc) + goto err_out_rc; + } + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + /* the parent of the key is always NULL */ + rc = fy_document_node_update_tags(fyd, fynp->key); + if (rc) + goto err_out_rc; + + rc = fy_document_node_update_tags(fyd, fynp->value); + if (rc) + goto err_out_rc; + } + break; + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_node_insert(struct fy_node *fyn_to, struct fy_node *fyn_from) +{ + struct fy_document *fyd; + struct fy_node *fyn_parent, *fyn_cpy, *fyni, *fyn_prev; + struct fy_node_pair *fynp, *fynpi, *fynpj; + int rc; + + if (!fyn_to || !fyn_to->fyd) + return -1; + + fyd = fyn_to->fyd; + assert(fyd); + + fyn_parent = fy_node_get_document_parent(fyn_to); + fynp = NULL; + if (fyn_parent) { + fyd_error_check(fyd, fyn_parent->type != FYNT_SCALAR, err_out, + "Illegal scalar parent node type"); + + fyd_error_check(fyd, fyn_from, err_out, + "Illegal NULL source node"); + + if (fyn_parent->type == FYNT_MAPPING) { + /* find mapping pair that contains the `to` node */ + for (fynp = fy_node_pair_list_head(&fyn_parent->mapping); fynp; + fynp = fy_node_pair_next(&fyn_parent->mapping, fynp)) { + if (fynp->value == fyn_to) + break; + } + } + } + + /* verify no funkiness on root */ + assert(fyn_parent || fyn_to == fyd->root); + + /* deleting target */ + if (!fyn_from) { + fyn_to->parent = NULL; + + if (!fyn_parent) { + fyd_doc_debug(fyd, "Deleting root node"); + fy_node_detach_and_free(fyn_to); + fyd->root = NULL; + } else if (fyn_parent->type == FYNT_SEQUENCE) { + fyd_doc_debug(fyd, "Deleting sequence node"); + fy_node_list_del(&fyn_parent->sequence, fyn_to); + fy_node_detach_and_free(fyn_to); + } else { + fyd_doc_debug(fyd, "Deleting mapping node"); + /* should never happen, it's checked right above, but play safe */ + assert(fyn_parent->type == FYNT_MAPPING); + + fyd_error_check(fyd, fynp, err_out, + "Illegal mapping node found"); + + fy_node_pair_list_del(&fyn_parent->mapping, fynp); + if (fyn_parent->xl) + fy_accel_remove(fyn_parent->xl, fynp->key); + /* this will also delete fyn_to */ + fy_node_pair_detach_and_free(fynp); + } + return 0; + } + + /* + * from: scalar + * + * to: another-scalar -> scalar + * to: { key: value } -> scalar + * to: [ seq0, seq1 ] -> scalar + * + * from: [ seq2 ] + * to: scalar -> [ seq2 ] + * to: { key: value } -> [ seq2 ] + * to: [ seq0, seq1 ] -> [ seq0, seq1, sec2 ] + * + * from: { another-key: another-value } + * to: scalar -> { another-key: another-value } + * to: { key: value } -> { key: value, another-key: another-value } + * to: [ seq0, seq1 ] -> { another-key: another-value } + * + * from: { key: another-value } + * to: scalar -> { key: another-value } + * to: { key: value } -> { key: another-value } + * to: [ seq0, seq1 ] -> { key: another-value } + * + */ + + /* if types of `from` and `to` differ (or it's a scalar), it's a replace */ + if (fyn_from->type != fyn_to->type || fyn_from->type == FYNT_SCALAR) { + + fyn_cpy = fy_node_copy(fyd, fyn_from); + fyd_error_check(fyd, fyn_cpy, err_out, + "fy_node_copy() failed"); + + if (!fyn_parent) { + fyd_doc_debug(fyd, "Replacing root node"); + fy_node_detach_and_free(fyd->root); + fyd->root = fyn_cpy; + } else if (fyn_parent->type == FYNT_SEQUENCE) { + fyd_doc_debug(fyd, "Replacing sequence node"); + + /* get previous */ + fyn_prev = fy_node_prev(&fyn_parent->sequence, fyn_to); + + /* delete */ + fy_node_list_del(&fyn_parent->sequence, fyn_to); + fy_node_detach_and_free(fyn_to); + + /* if there's no previous insert to head */ + if (!fyn_prev) + fy_node_list_add(&fyn_parent->sequence, fyn_cpy); + else + fy_node_list_insert_after(&fyn_parent->sequence, fyn_prev, fyn_cpy); + } else { + fyd_doc_debug(fyd, "Replacing mapping node value"); + /* should never happen, it's checked right above, but play safe */ + assert(fyn_parent->type == FYNT_MAPPING); + fyd_error_check(fyd, fynp, err_out, + "Illegal mapping node found"); + + fy_node_detach_and_free(fynp->value); + fynp->value = fyn_cpy; + } + + return 0; + } + + /* types match, if it's a sequence append */ + if (fyn_to->type == FYNT_SEQUENCE) { + + fyd_doc_debug(fyd, "Appending to sequence node"); + + for (fyni = fy_node_list_head(&fyn_from->sequence); fyni; + fyni = fy_node_next(&fyn_from->sequence, fyni)) { + + fyn_cpy = fy_node_copy(fyd, fyni); + fyd_error_check(fyd, fyn_cpy, err_out, + "fy_node_copy() failed"); + + fy_node_list_add_tail(&fyn_to->sequence, fyn_cpy); + fyn_cpy->attached = true; + } + } else { + /* only mapping is possible here */ + + /* iterate over all the keys in the `from` */ + for (fynpi = fy_node_pair_list_head(&fyn_from->mapping); fynpi; + fynpi = fy_node_pair_next(&fyn_from->mapping, fynpi)) { + + if (fyn_to->xl) { + fynpj = fy_node_accel_lookup_by_node(fyn_to, fynpi->key); + } else { + /* find whether the key already exists */ + for (fynpj = fy_node_pair_list_head(&fyn_to->mapping); fynpj; + fynpj = fy_node_pair_next(&fyn_to->mapping, fynpj)) { + + if (fy_node_compare(fynpi->key, fynpj->key)) + break; + } + } + + if (!fynpj) { + fyd_doc_debug(fyd, "Appending to mapping node"); + + /* not found? append it */ + fynpj = fy_node_pair_alloc(fyd); + fyd_error_check(fyd, fynpj, err_out, + "fy_node_pair_alloc() failed"); + + fynpj->key = fy_node_copy(fyd, fynpi->key); + fyd_error_check(fyd, !fynpi->key || fynpj->key, err_out, + "fy_node_copy() failed"); + fynpj->value = fy_node_copy(fyd, fynpi->value); + fyd_error_check(fyd, !fynpi->value || fynpj->value, err_out, + "fy_node_copy() failed"); + + fy_node_pair_list_add_tail(&fyn_to->mapping, fynpj); + if (fyn_to->xl) + fy_accel_insert(fyn_to->xl, fynpj->key, fynpj); + + if (fynpj->key) + fynpj->key->attached = true; + if (fynpj->value) + fynpj->value->attached = true; + + } else { + fyd_doc_debug(fyd, "Updating mapping node value (deep merge)"); + + rc = fy_node_insert(fynpj->value, fynpi->value); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_node_insert() failed"); + } + } + } + + /* adjust parents */ + switch (fyn_to->type) { + case FYNT_SCALAR: + break; + + case FYNT_SEQUENCE: + for (fyni = fy_node_list_head(&fyn_to->sequence); fyni; + fyni = fy_node_next(&fyn_to->sequence, fyni)) { + + fyni->parent = fyn_to; + } + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn_to->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn_to->mapping, fynp); + + if (fynp->key) { + fynp->key->parent = fyn_to; + fynp->key->key_root = true; + } + if (fynp->value) + fynp->value->parent = fyn_to; + fynp->parent = fyn_to; + } + break; + } + + /* if the documents differ, merge their states */ + if (fyn_to->fyd != fyn_from->fyd) { + rc = fy_document_state_merge(fyn_to->fyd->fyds, fyn_from->fyd->fyds); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_document_state_merge() failed"); + + rc = fy_document_node_update_tags(fyd, fy_document_root(fyd)); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_document_node_update_tags() failed"); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_document_insert_at(struct fy_document *fyd, + const char *path, size_t pathlen, + struct fy_node *fyn) +{ + int rc; + struct fy_node *fyn2; + + fyn2 = fy_node_by_path(fy_document_root(fyd), path, pathlen, FYNWF_DONT_FOLLOW); + rc = fy_node_insert(fyn2, fyn); + + fy_node_free(fyn); + + return rc; +} + +struct fy_token *fy_document_tag_directive_iterate(struct fy_document *fyd, void **prevp) +{ + struct fy_token_list *fytl; + + if (!fyd || !fyd->fyds || !prevp) + return NULL; + + fytl = &fyd->fyds->fyt_td; + + return *prevp = *prevp ? fy_token_next(fytl, *prevp) : fy_token_list_head(fytl); +} + +struct fy_token *fy_document_tag_directive_lookup(struct fy_document *fyd, const char *handle) +{ + struct fy_token *fyt; + void *iter; + const char *h; + size_t h_size, len; + + if (!fyd || !handle) + return NULL; + len = strlen(handle); + + iter = NULL; + while ((fyt = fy_document_tag_directive_iterate(fyd, &iter)) != NULL) { + h = fy_tag_directive_token_handle(fyt, &h_size); + if (!h) + continue; + if (h_size == len && !memcmp(h, handle, len)) + return fyt; + } + return NULL; +} + +int fy_document_tag_directive_add(struct fy_document *fyd, const char *handle, const char *prefix) +{ + struct fy_token *fyt; + + if (!fyd || !fyd->fyds || !handle || !prefix) + return -1; + + /* it must not exist */ + fyt = fy_document_tag_directive_lookup(fyd, handle); + if (fyt) + return -1; + + return fy_document_state_append_tag(fyd->fyds, handle, prefix, false); +} + +int fy_document_tag_directive_remove(struct fy_document *fyd, const char *handle) +{ + struct fy_token *fyt; + + if (!fyd || !fyd->fyds || !handle) + return -1; + + /* it must not exist */ + fyt = fy_document_tag_directive_lookup(fyd, handle); + if (!fyt || fyt->refs != 1) + return -1; + + fy_token_list_del(&fyd->fyds->fyt_td, fyt); + fy_token_unref(fyt); + + return 0; +} + +static int fy_resolve_alias(struct fy_document *fyd, struct fy_node *fyn) +{ + struct fy_node *fyn_copy = NULL; + int rc; + + fyn_copy = fy_node_resolve_alias(fyn); + FYD_NODE_ERROR_CHECK(fyd, fyn, FYEM_DOC, + fyn_copy, err_out, + "invalid alias"); + + rc = fy_node_copy_to_scalar(fyd, fyn, fyn_copy); + fyd_error_check(fyd, !rc, err_out, + "fy_node_copy_to_scalar() failed"); + + return 0; + +err_out: + fyd->diag->on_error = false; + return -1; +} + +static struct fy_node * +fy_node_follow_alias(struct fy_node *fyn, enum fy_node_walk_flags flags) +{ + enum fy_node_walk_flags ptr_flags; + struct fy_anchor *fya; + const char *anchor_text, *s, *e, *p, *path; + size_t anchor_len, path_len; + struct fy_node *fyn_path_root; + unsigned int marker; + + if (!fyn || !fy_node_is_alias(fyn)) + return NULL; + + ptr_flags = flags & FYNWF_PTR(FYNWF_PTR_MASK); + if (ptr_flags == FYNWF_PTR_YPATH) + return fy_node_alias_resolve_by_ypath(fyn); + + /* try regular label target */ + fya = fy_document_lookup_anchor_by_token(fyn->fyd, fyn->scalar); + if (fya) + return fya->fyn; + + anchor_text = fy_token_get_text(fyn->scalar, &anchor_len); + if (!anchor_text) + return NULL; + + s = anchor_text; + e = s + anchor_len; + + fyn_path_root = NULL; + + if (ptr_flags == FYNWF_PTR_YAML && (p = memchr(s, '/', e - s)) != NULL) { + /* fyd_notice(fyn->fyd, "%s: alias contains a path component %.*s", + __func__, (int)(e - p - 1), p + 1); */ + + if (p > s) { + + fya = fy_document_lookup_anchor(fyn->fyd, s, p - s); + if (!fya) { + /* fyd_notice(fyn->fyd, "%s: unable to resolve alias %.*s @%s", + __func__, (int)(p - s), s, fy_node_get_path(fya->fyn)); */ + return NULL; + } + + /* fyd_notice(fyn->fyd, "%s: alias base %.*s @%s", + __func__, (int)(p - s), s, fy_node_get_path(fya->fyn)); */ + path = ++p; + path_len = e - p; + + fyn_path_root = fya->fyn; + + } else { + /* fyd_notice(fyn->fyd, "%s: absolute %.*s @%s", + __func__, (int)(p - s), s, fy_node_get_path(fya->fyn)); */ + path = s; + path_len = e - s; + + fyn_path_root = fyn->fyd->root; + } + } + + if (!fyn_path_root) + return NULL; + + marker = fy_node_walk_marker_from_flags(flags); + if (marker >= FYNWF_MAX_USER_MARKER) + return NULL; + + /* use the next marker */ + flags &= ~FYNWF_MARKER(FYNWF_MARKER_MASK); + flags |= FYNWF_MARKER(marker + 1); + + return fy_node_by_path_internal(fyn_path_root, path, path_len, flags); +} + +static bool fy_node_pair_is_merge_key(struct fy_node_pair *fynp) +{ + struct fy_node *fyn = fynp->key; + + return fyn && fyn->type == FYNT_SCALAR && fyn->style == FYNS_PLAIN && + fy_plain_atom_streq(fy_token_atom(fyn->scalar), "<<"); +} + +static struct fy_node *fy_alias_get_merge_mapping(struct fy_document *fyd, struct fy_node *fyn) +{ + struct fy_anchor *fya; + + /* must be an alias */ + if (!fy_node_is_alias(fyn)) + return NULL; + + /* anchor must exist */ + fya = fy_document_lookup_anchor_by_token(fyd, fyn->scalar); + if (!fya) + return NULL; + + /* and it must be a mapping */ + if (fya->fyn->type != FYNT_MAPPING) + return NULL; + + return fya->fyn; +} + +static bool fy_node_pair_is_valid_merge_key(struct fy_document *fyd, struct fy_node_pair *fynp) +{ + struct fy_node *fyn, *fyni, *fynm; + + fyn = fynp->value; + + /* value must exist */ + if (!fyn) + return false; + + /* scalar alias */ + fynm = fy_alias_get_merge_mapping(fyd, fyn); + if (fynm) + return true; + + /* it must be a sequence then */ + if (fyn->type != FYNT_SEQUENCE) + return false; + + /* the sequence must only contain valid aliases for mapping */ + for (fyni = fy_node_list_head(&fyn->sequence); fyni; + fyni = fy_node_next(&fyn->sequence, fyni)) { + + /* sequence of aliases only! */ + fynm = fy_alias_get_merge_mapping(fyd, fyni); + if (!fynm) + return false; + + } + + return true; +} + +static int fy_resolve_merge_key_populate(struct fy_document *fyd, struct fy_node *fyn, + struct fy_node_pair *fynp, struct fy_node *fynm) +{ + struct fy_node_pair *fynpi, *fynpn; + + if (!fyd) + return -1; + + fyd_error_check(fyd, + fyn && fynp && fynm && fyn->type == FYNT_MAPPING && fynm->type == FYNT_MAPPING, + err_out, "bad inputs to %s", __func__); + + 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; + + fynpn = fy_node_pair_alloc(fyd); + fyd_error_check(fyd, fynpn, err_out, + "fy_node_pair_alloc() failed"); + + fynpn->key = fy_node_copy(fyd, fynpi->key); + fynpn->value = fy_node_copy(fyd, fynpi->value); + + fy_node_pair_list_insert_after(&fyn->mapping, fynp, fynpn); + if (fyn->xl) + fy_accel_insert(fyn->xl, fynpn->key, fynpn); + } + + return 0; + +err_out: + return -1; +} + +static int fy_resolve_merge_key(struct fy_document *fyd, struct fy_node *fyn, struct fy_node_pair *fynp) +{ + struct fy_node *fynv, *fyni, *fynm; + int rc; + + /* it must be a valid merge key value */ + FYD_NODE_ERROR_CHECK(fyd, fynp->value, FYEM_DOC, + fy_node_pair_is_valid_merge_key(fyd, fynp), err_out, + "invalid merge key value"); + + fynv = fynp->value; + fynm = fy_alias_get_merge_mapping(fyd, fynv); + if (fynm) { + rc = fy_resolve_merge_key_populate(fyd, fyn, fynp, fynm); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_resolve_merge_key_populate() failed"); + + return 0; + } + + /* it must be a sequence then */ + fyd_error_check(fyd, fynv->type == FYNT_SEQUENCE, err_out, + "invalid node type to use for merge key"); + + /* the sequence must only contain valid aliases for mapping */ + for (fyni = fy_node_list_head(&fynv->sequence); fyni; + fyni = fy_node_next(&fynv->sequence, fyni)) { + + fynm = fy_alias_get_merge_mapping(fyd, fyni); + fyd_error_check(fyd, fynm, err_out, + "invalid merge key sequence item (not an alias)"); + + rc = fy_resolve_merge_key_populate(fyd, fyn, fynp, fynm); + fyd_error_check(fyd, !rc, err_out_rc, + "fy_resolve_merge_key_populate() failed"); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +/* the anchors are scalars that have the FYNS_ALIAS style */ +static int fy_resolve_anchor_node(struct fy_document *fyd, struct fy_node *fyn) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi, *fynpit; + int rc, ret_rc = 0; + struct fy_token *fyt; + + if (!fyn) + return 0; + + if (fy_node_is_alias(fyn)) + return fy_resolve_alias(fyd, fyn); + + if (fyn->type == FYNT_SEQUENCE) { + + for (fyni = fy_node_list_head(&fyn->sequence); fyni; + fyni = fy_node_next(&fyn->sequence, fyni)) { + + rc = fy_resolve_anchor_node(fyd, fyni); + if (rc && !ret_rc) + ret_rc = rc; + } + + } else if (fyn->type == FYNT_MAPPING) { + + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + if (fy_node_pair_is_merge_key(fynp)) { + rc = fy_resolve_merge_key(fyd, fyn, fynp); + if (rc && !ret_rc) + ret_rc = rc; + + /* remove this node pair */ + if (!rc) { + fy_node_pair_list_del(&fyn->mapping, fynp); + if (fyn->xl) + fy_accel_remove(fyn->xl, fynp->key); + fy_node_pair_detach_and_free(fynp); + } + + } else { + + rc = fy_resolve_anchor_node(fyd, fynp->key); + + if (!rc) { + + /* check whether the keys are duplicate */ + for (fynpit = fy_node_pair_list_head(&fyn->mapping); fynpit; + fynpit = fy_node_pair_next(&fyn->mapping, fynpit)) { + + /* skip this node pair */ + if (fynpit == fynp) + continue; + + if (!fy_node_compare(fynpit->key, fynp->key)) + continue; + + /* whoops, duplicate key after resolution */ + fyt = NULL; + switch (fyn->type) { + case FYNT_SCALAR: + fyt = fyn->scalar; + break; + case FYNT_SEQUENCE: + fyt = fyn->sequence_start; + break; + case FYNT_MAPPING: + fyt = fyn->mapping_start; + break; + } + + FYD_TOKEN_ERROR_CHECK(fyd, fyt, FYEM_DOC, + false, err_out, + "duplicate key after resolving"); + + } + + } + + if (rc && !ret_rc) + ret_rc = rc; + + rc = fy_resolve_anchor_node(fyd, fynp->value); + if (rc && !ret_rc) + ret_rc = rc; + + } + } + } + + return ret_rc; + +err_out: + return -1; +} + +static void fy_resolve_parent_node(struct fy_document *fyd, struct fy_node *fyn, struct fy_node *fyn_parent) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi; + + if (!fyn) + return; + + fyn->parent = fyn_parent; + + 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)) { + + fy_resolve_parent_node(fyd, fyni, fyn); + } + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + fy_resolve_parent_node(fyd, fynp->key, fyn); + fy_resolve_parent_node(fyd, fynp->value, fyn); + fynp->parent = fyn; + } + break; + } +} + +typedef void (*fy_node_applyf)(struct fy_node *fyn); + +void fy_node_apply(struct fy_node *fyn, fy_node_applyf func) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp; + + if (!fyn || !func) + return; + + (*func)(fyn); + + 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)) + fy_node_apply(fyni, func); + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; + fynp = fy_node_pair_next(&fyn->mapping, fynp)) { + + fy_node_apply(fynp->key, func); + fy_node_apply(fynp->value, func); + } + break; + } +} + +static void clear_system_marks(struct fy_node *fyn) +{ + fyn->marks &= ~FYNWF_SYSTEM_MARKS; +} + +/* clear all the system markers */ +void fy_node_clear_system_marks(struct fy_node *fyn) +{ + fy_node_apply(fyn, clear_system_marks); +} + +int fy_document_resolve(struct fy_document *fyd) +{ + int rc; + bool ret; + + if (!fyd) + return 0; + + fy_node_clear_system_marks(fyd->root); + + /* for resolution to work, no reference loops should exist */ + ret = fy_check_ref_loop(fyd, fyd->root, + FYNWF_MAXDEPTH_DEFAULT | FYNWF_FOLLOW, NULL); + + fy_node_clear_system_marks(fyd->root); + + if (ret) + goto err_out; + + + /* now resolve any anchor nodes */ + rc = fy_resolve_anchor_node(fyd, fyd->root); + if (rc) + goto err_out_rc; + + /* redo parent resolution */ + fy_resolve_parent_node(fyd, fyd->root, NULL); + + return 0; + +err_out: + rc = -1; +err_out_rc: + fyd->diag->on_error = false; + return rc; +} + +void fy_document_free_nodes(struct fy_document *fyd) +{ + struct fy_document *fyd_child; + + for (fyd_child = fy_document_list_first(&fyd->children); fyd_child; + fyd_child = fy_document_next(&fyd->children, fyd_child)) + fy_document_free_nodes(fyd_child); + + fy_node_detach_and_free(fyd->root); + fyd->root = NULL; +} + +void fy_document_destroy(struct fy_document *fyd) +{ + struct fy_document *fyd_child; + + /* both the document and the parser object must exist */ + if (!fyd) + return; + + /* we have to free the nodes first */ + fy_document_free_nodes(fyd); + + /* recursively delete children */ + while ((fyd_child = fy_document_list_pop(&fyd->children)) != NULL) { + fyd_child->parent = NULL; + fy_document_destroy(fyd_child); + } + + fy_parse_document_destroy(NULL, fyd); +} + +int fy_document_set_parent(struct fy_document *fyd, struct fy_document *fyd_child) +{ + + if (!fyd || !fyd_child || fyd_child->parent) + return -1; + + fyd_child->parent = fyd; + fy_document_list_add_tail(&fyd->children, fyd_child); + + return 0; +} + +static const struct fy_parse_cfg doc_parse_default_cfg = { + .flags = FYPCF_DEFAULT_DOC, +}; + +struct fy_document *fy_document_create(const struct fy_parse_cfg *cfg) +{ + struct fy_document *fyd = NULL; + struct fy_diag *diag; + int rc; + + if (!cfg) + cfg = &doc_parse_default_cfg; + + fyd = malloc(sizeof(*fyd)); + if (!fyd) + goto err_out; + + memset(fyd, 0, sizeof(*fyd)); + fyd->parse_cfg = *cfg; + + diag = cfg->diag; + if (!diag) { + diag = fy_diag_create(NULL); + if (!diag) + goto err_out; + } else + fy_diag_ref(diag); + + fyd->diag = diag; + + fy_anchor_list_init(&fyd->anchors); + if (fy_document_is_accelerated(fyd)) { + fyd->axl = malloc(sizeof(*fyd->axl)); + fyd_error_check(fyd, fyd->axl, err_out, + "malloc() failed"); + + /* start with a very small bucket list */ + rc = fy_accel_setup(fyd->axl, &hd_anchor, fyd, 8); + fyd_error_check(fyd, !rc, err_out, + "fy_accel_setup() failed"); + + fyd->naxl = malloc(sizeof(*fyd->naxl)); + fyd_error_check(fyd, fyd->axl, err_out, + "malloc() failed"); + + /* start with a very small bucket list */ + rc = fy_accel_setup(fyd->naxl, &hd_nanchor, fyd, 8); + fyd_error_check(fyd, !rc, err_out, + "fy_accel_setup() failed"); + } + fyd->root = NULL; + + /* we don't do document create version setting, + * perhaps we should in the future + */ + fyd->fyds = fy_document_state_default(NULL, NULL); + fyd_error_check(fyd, fyd->fyds, err_out, + "fy_document_state_default() failed"); + + fy_document_list_init(&fyd->children); + + return fyd; + +err_out: + fy_parse_document_destroy(NULL, fyd); + return NULL; +} + +struct fy_document_build_string_ctx { + const char *str; + size_t len; +}; + +static int parser_setup_from_string(struct fy_parser *fyp, void *user) +{ + struct fy_document_build_string_ctx *ctx = user; + + return fy_parser_set_string(fyp, ctx->str, ctx->len); +} + +struct fy_document_build_malloc_string_ctx { + char *str; + size_t len; +}; + +static int parser_setup_from_malloc_string(struct fy_parser *fyp, void *user) +{ + struct fy_document_build_malloc_string_ctx *ctx = user; + + return fy_parser_set_malloc_string(fyp, ctx->str, ctx->len); +} + +struct fy_document_build_file_ctx { + const char *file; +}; + +static int parser_setup_from_file(struct fy_parser *fyp, void *user) +{ + struct fy_document_build_file_ctx *ctx = user; + + return fy_parser_set_input_file(fyp, ctx->file); +} + +struct fy_document_build_fp_ctx { + const char *name; + FILE *fp; +}; + +static int parser_setup_from_fp(struct fy_parser *fyp, void *user) +{ + struct fy_document_build_fp_ctx *ctx = user; + + return fy_parser_set_input_fp(fyp, ctx->name, ctx->fp); +} + +struct fy_document_vbuildf_ctx { + const char *fmt; + va_list ap; +}; + +static int parser_setup_from_fmt_ap(struct fy_parser *fyp, void *user) +{ + struct fy_document_vbuildf_ctx *vctx = user; + va_list ap, ap_orig; + int size, sizew; + char *buf; + + /* first try without allocating */ + va_copy(ap_orig, vctx->ap); + size = vsnprintf(NULL, 0, vctx->fmt, ap_orig); + va_end(ap_orig); + + fyp_error_check(fyp, size >= 0, err_out, + "vsnprintf() failed"); + + buf = malloc(size + 1); + fyp_error_check(fyp, buf, err_out, + "malloc() failed"); + + va_copy(ap, vctx->ap); + sizew = vsnprintf(buf, size + 1, vctx->fmt, ap); + fyp_error_check(fyp, sizew == size, err_out, + "vsnprintf() failed"); + va_end(ap); + + buf[size] = '\0'; + + return fy_parser_set_malloc_string(fyp, buf, size); + +err_out: + return -1; +} + +static struct fy_document *fy_document_build_internal(const struct fy_parse_cfg *cfg, + int (*parser_setup)(struct fy_parser *fyp, void *user), + void *user) +{ + struct fy_parser fyp_data, *fyp = &fyp_data; + struct fy_document *fyd = NULL; + struct fy_eventp *fyep; + bool got_stream_end; + int rc; + + if (!parser_setup) + return NULL; + + if (!cfg) + cfg = &doc_parse_default_cfg; + + rc = fy_parse_setup(fyp, cfg); + if (rc) + return NULL; + + rc = (*parser_setup)(fyp, user); + fyp_error_check(fyp, !rc, err_out, + "parser_setup() failed"); + + fyd = fy_parse_load_document(fyp); + + /* we're going to handle stream errors from now */ + if (!fyd) + fyp->stream_error = false; + + /* if we collect diagnostics, we can continue */ + fyp_error_check(fyp, fyd || (fyp->cfg.flags & FYPCF_COLLECT_DIAG), err_out, + "fy_parse_load_document() failed"); + + /* no document, but we're collecting diagnostics */ + if (!fyd) { + + fyp_error(fyp, "fy_parse_load_document() failed"); + + fyp->stream_error = false; + fyd = fy_parse_document_create(fyp, NULL); + fyp_error_check(fyp, fyd, err_out, + "fy_parse_document_create() failed"); + fyd->parse_error = true; + + /* XXX */ + goto out; + } + + got_stream_end = false; + while (!got_stream_end && (fyep = fy_parse_private(fyp)) != NULL) { + if (fyep->e.type == FYET_STREAM_END) + got_stream_end = true; + fy_parse_eventp_recycle(fyp, fyep); + } + + if (got_stream_end) { + fyep = fy_parse_private(fyp); + fyp_error_check(fyp, !fyep, err_out, + "more events after stream end"); + fy_parse_eventp_recycle(fyp, fyep); + } + +out: + fy_parse_cleanup(fyp); + return fyd; + +err_out: + fy_document_destroy(fyd); + fy_parse_cleanup(fyp); + return NULL; +} + +struct fy_document *fy_document_build_from_string(const struct fy_parse_cfg *cfg, + const char *str, size_t len) +{ + struct fy_document_build_string_ctx ctx = { + .str = str, + .len = len, + }; + + return fy_document_build_internal(cfg, parser_setup_from_string, &ctx); +} + +struct fy_document *fy_document_build_from_malloc_string(const struct fy_parse_cfg *cfg, + char *str, size_t len) +{ + struct fy_document_build_malloc_string_ctx ctx = { + .str = str, + .len = len, + }; + + return fy_document_build_internal(cfg, parser_setup_from_malloc_string, &ctx); +} + +struct fy_document *fy_document_build_from_file(const struct fy_parse_cfg *cfg, + const char *file) +{ + struct fy_document_build_file_ctx ctx = { + .file = file, + }; + + return fy_document_build_internal(cfg, parser_setup_from_file, &ctx); +} + +struct fy_document *fy_document_build_from_fp(const struct fy_parse_cfg *cfg, + FILE *fp) +{ + struct fy_document_build_fp_ctx ctx = { + .name = NULL, + .fp = fp, + }; + + return fy_document_build_internal(cfg, parser_setup_from_fp, &ctx); +} + +enum fy_node_type fy_node_get_type(struct fy_node *fyn) +{ + /* a NULL is a plain scalar node */ + return fyn ? fyn->type : FYNT_SCALAR; +} + +enum fy_node_style fy_node_get_style(struct fy_node *fyn) +{ + /* a NULL is a plain scalar node */ + return fyn ? fyn->style : FYNS_PLAIN; +} + +bool fy_node_is_null(struct fy_node *fyn) +{ + if (!fyn) + return true; + + if (fyn->type != FYNT_SCALAR) + return false; + + return fyn->scalar == NULL; +} + +bool fy_node_is_attached(struct fy_node *fyn) +{ + return fyn ? fyn->attached : false; +} + +struct fy_node *fy_node_get_parent(struct fy_node *fyn) +{ + return fyn && !fyn->key_root ? fyn->parent : NULL; +} + +struct fy_node *fy_node_get_document_parent(struct fy_node *fyn) +{ + return fyn ? fyn->parent : NULL; +} + +struct fy_token *fy_node_get_tag_token(struct fy_node *fyn) +{ + return fyn ? fyn->tag : NULL; +} + +struct fy_token *fy_node_get_scalar_token(struct fy_node *fyn) +{ + return fyn && fyn->type == FYNT_SCALAR ? fyn->scalar : NULL; +} + +struct fy_node *fy_node_pair_key(struct fy_node_pair *fynp) +{ + return fynp ? fynp->key : NULL; +} + +struct fy_node *fy_node_pair_value(struct fy_node_pair *fynp) +{ + return fynp ? fynp->value : NULL; +} + +int fy_node_pair_set_key(struct fy_node_pair *fynp, struct fy_node *fyn) +{ + struct fy_node *fyn_map; + struct fy_node_pair *fynpi; + + if (!fynp) + return -1; + + /* the node must not be attached */ + if (fyn && fyn->attached) + return -1; + + /* sanity check and duplication check */ + fyn_map = fynp->parent; + if (fyn_map) { + + /* (in)sanity check */ + if (!fy_node_is_mapping(fyn_map)) + return -1; + + if (fyn_map->xl) { + /* either we're already on the parent list (and it's OK) */ + /* or we're not and we have a duplicate key */ + fynpi = fy_node_accel_lookup_by_node(fyn_map, fyn); + if (fynpi && fynpi != fynp) + return -1; + /* remove that key */ + fy_accel_remove(fyn_map->xl, fynp->key); + } else { + /* check whether the key is a duplicate + * skipping ourselves since our key gets replaced + */ + for (fynpi = fy_node_pair_list_head(&fyn_map->mapping); fynpi; + fynpi = fy_node_pair_next(&fyn_map->mapping, fynpi)) { + + if (fynpi != fynp && fy_node_compare(fynpi->key, fyn)) + return -1; + } + } + + fy_node_mark_synthetic(fyn_map); + } + + fy_node_detach_and_free(fynp->key); + fynp->key = fyn; + + if (fyn_map && fyn_map->xl) + fy_accel_insert(fyn_map->xl, fynp->key, fynp); + + fyn->attached = true; + + return 0; +} + +int fy_node_pair_set_value(struct fy_node_pair *fynp, struct fy_node *fyn) +{ + if (!fynp) + return -1; + /* the node must not be attached */ + if (fyn && fyn->attached) + return -1; + fy_node_detach_and_free(fynp->value); + fynp->value = fyn; + fyn->attached = true; + + if (fynp->parent) + fy_node_mark_synthetic(fynp->parent); + + return 0; +} + +struct fy_node *fy_document_root(struct fy_document *fyd) +{ + return fyd->root; +} + +const char *fy_node_get_tag(struct fy_node *fyn, size_t *lenp) +{ + size_t tmplen; + + if (!lenp) + lenp = &tmplen; + + if (!fyn || !fyn->tag) { + *lenp = 0; + return NULL; + } + + return fy_token_get_text(fyn->tag, lenp); +} + +const char *fy_node_get_scalar(struct fy_node *fyn, size_t *lenp) +{ + size_t tmplen; + + if (!lenp) + lenp = &tmplen; + + if (!fyn || fyn->type != FYNT_SCALAR) { + *lenp = 0; + return NULL; + } + + return fy_token_get_text(fyn->scalar, lenp); +} + +const char *fy_node_get_scalar0(struct fy_node *fyn) +{ + if (!fyn || fyn->type != FYNT_SCALAR) + return NULL; + + return fy_token_get_text0(fyn->scalar); +} + +size_t fy_node_get_scalar_length(struct fy_node *fyn) +{ + + if (!fyn || fyn->type != FYNT_SCALAR) + return 0; + + return fy_token_get_text_length(fyn->scalar); +} + +size_t fy_node_get_scalar_utf8_length(struct fy_node *fyn) +{ + + if (!fyn || fyn->type != FYNT_SCALAR) + return 0; + + return fy_token_format_utf8_length(fyn->scalar); +} + +struct fy_node *fy_node_sequence_iterate(struct fy_node *fyn, void **prevp) +{ + if (!fyn || fyn->type != FYNT_SEQUENCE || !prevp) + return NULL; + + return *prevp = *prevp ? fy_node_next(&fyn->sequence, *prevp) : fy_node_list_head(&fyn->sequence); +} + +struct fy_node *fy_node_sequence_reverse_iterate(struct fy_node *fyn, void **prevp) +{ + if (!fyn || fyn->type != FYNT_SEQUENCE || !prevp) + return NULL; + + return *prevp = *prevp ? fy_node_prev(&fyn->sequence, *prevp) : fy_node_list_tail(&fyn->sequence); +} + +int fy_node_sequence_item_count(struct fy_node *fyn) +{ + struct fy_node *fyni; + int count; + + if (!fyn || fyn->type != FYNT_SEQUENCE) + return -1; + + count = 0; + for (fyni = fy_node_list_head(&fyn->sequence); fyni; fyni = fy_node_next(&fyn->sequence, fyni)) + count++; + return count; +} + +bool fy_node_sequence_is_empty(struct fy_node *fyn) +{ + return !fyn || fyn->type != FYNT_SEQUENCE || fy_node_list_empty(&fyn->sequence); +} + +struct fy_node *fy_node_sequence_get_by_index(struct fy_node *fyn, int index) +{ + struct fy_node *fyni; + void *iterp = NULL; + + if (!fyn || fyn->type != FYNT_SEQUENCE) + return NULL; + + if (index >= 0) { + do { + fyni = fy_node_sequence_iterate(fyn, &iterp); + } while (fyni && --index >= 0); + } else { + do { + fyni = fy_node_sequence_reverse_iterate(fyn, &iterp); + } while (fyni && ++index < 0); + } + + return fyni; +} + +struct fy_node_pair *fy_node_mapping_iterate(struct fy_node *fyn, void **prevp) +{ + if (!fyn || fyn->type != FYNT_MAPPING || !prevp) + return NULL; + + return *prevp = *prevp ? fy_node_pair_next(&fyn->mapping, *prevp) : fy_node_pair_list_head(&fyn->mapping); +} + +struct fy_node_pair *fy_node_mapping_reverse_iterate(struct fy_node *fyn, void **prevp) +{ + if (!fyn || fyn->type != FYNT_MAPPING || !prevp) + return NULL; + + return *prevp = *prevp ? fy_node_pair_prev(&fyn->mapping, *prevp) : fy_node_pair_list_tail(&fyn->mapping); +} + +struct fy_node *fy_node_collection_iterate(struct fy_node *fyn, void **prevp) +{ + struct fy_node_pair *fynp; + + if (!fyn || !prevp) + return NULL; + + switch (fyn->type) { + case FYNT_SEQUENCE: + return fy_node_sequence_iterate(fyn, prevp); + + case FYNT_MAPPING: + fynp = fy_node_mapping_iterate(fyn, prevp); + if (!fynp) + return NULL; + return fynp->value; + + case FYNT_SCALAR: + fyn = !*prevp ? fyn : NULL; + *prevp = fyn; + return fyn; + } + + return NULL; +} + + +int fy_node_mapping_item_count(struct fy_node *fyn) +{ + struct fy_node_pair *fynpi; + int count; + + if (!fyn || fyn->type != FYNT_MAPPING) + return -1; + + count = 0; + for (fynpi = fy_node_pair_list_head(&fyn->mapping); fynpi; fynpi = fy_node_pair_next(&fyn->mapping, fynpi)) + count++; + return count; +} + +bool fy_node_mapping_is_empty(struct fy_node *fyn) +{ + return !fyn || fyn->type != FYNT_MAPPING || fy_node_pair_list_empty(&fyn->mapping); +} + +struct fy_node_pair *fy_node_mapping_get_by_index(struct fy_node *fyn, int index) +{ + struct fy_node_pair *fynpi; + void *iterp = NULL; + + if (!fyn || fyn->type != FYNT_MAPPING) + return NULL; + + if (index >= 0) { + do { + fynpi = fy_node_mapping_iterate(fyn, &iterp); + } while (fynpi && --index >= 0); + } else { + do { + fynpi = fy_node_mapping_reverse_iterate(fyn, &iterp); + } while (fynpi && ++index < 0); + } + + return fynpi; +} + +struct fy_node_pair * +fy_node_mapping_lookup_pair_by_simple_key(struct fy_node *fyn, + const char *key, size_t len) +{ + struct fy_node_pair *fynpi; + struct fy_node *fyn_scalar; + + if (!fyn || fyn->type != FYNT_MAPPING || !key) + return NULL; + + if (len == (size_t)-1) + len = strlen(key); + + if (fyn->xl) { + fyn_scalar = fy_node_create_scalar(fyn->fyd, key, len); + if (!fyn_scalar) + return NULL; + + fynpi = fy_node_accel_lookup_by_node(fyn, fyn_scalar); + + fy_node_free(fyn_scalar); + + if (fynpi) + return fynpi; + } else { + for (fynpi = fy_node_pair_list_head(&fyn->mapping); fynpi; + fynpi = fy_node_pair_next(&fyn->mapping, fynpi)) { + + if (!fy_node_is_scalar(fynpi->key) || fy_node_is_alias(fynpi->key)) + continue; + + if (!fynpi->key && len == 0) + return fynpi; + + if (fynpi->key && !fy_token_memcmp(fynpi->key->scalar, key, len)) + return fynpi; + } + } + + return NULL; +} + +struct fy_node * +fy_node_mapping_lookup_value_by_simple_key(struct fy_node *fyn, + const char *key, size_t len) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_lookup_pair_by_simple_key(fyn, key, len); + return fynp ? fy_node_pair_value(fynp) : NULL; +} + +struct fy_node_pair * +fy_node_mapping_lookup_pair_by_null_key(struct fy_node *fyn) +{ + struct fy_node_pair *fynpi; + + if (!fyn || fyn->type != FYNT_MAPPING) + return NULL; + + /* no acceleration for NULLs */ + for (fynpi = fy_node_pair_list_head(&fyn->mapping); fynpi; + fynpi = fy_node_pair_next(&fyn->mapping, fynpi)) { + + if (fy_node_is_null(fynpi->key)) + return fynpi; + } + + return NULL; +} + +struct fy_node * +fy_node_mapping_lookup_value_by_null_key(struct fy_node *fyn) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_lookup_pair_by_null_key(fyn); + return fynp ? fy_node_pair_value(fynp) : NULL; +} + +const char * +fy_node_mapping_lookup_scalar_by_simple_key(struct fy_node *fyn, size_t *lenp, + const char *key, size_t keylen) +{ + struct fy_node *fyn_value; + + fyn_value = fy_node_mapping_lookup_value_by_simple_key(fyn, key, keylen); + if (!fyn_value || !fy_node_is_scalar(fyn_value)) + return NULL; + return fy_node_get_scalar(fyn_value, lenp); +} + +const char * +fy_node_mapping_lookup_scalar0_by_simple_key(struct fy_node *fyn, + const char *key, size_t keylen) +{ + struct fy_node *fyn_value; + + fyn_value = fy_node_mapping_lookup_value_by_simple_key(fyn, key, keylen); + if (!fyn_value || !fy_node_is_scalar(fyn_value)) + return NULL; + return fy_node_get_scalar0(fyn_value); +} + +struct fy_node *fy_node_mapping_lookup_value_by_key(struct fy_node *fyn, struct fy_node *fyn_key) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_lookup_pair(fyn, fyn_key); + return fynp ? fynp->value : NULL; +} + +struct fy_node *fy_node_mapping_lookup_key_by_key(struct fy_node *fyn, struct fy_node *fyn_key) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_lookup_pair(fyn, fyn_key); + return fynp ? fynp->key : NULL; +} + +struct fy_node_pair * +fy_node_mapping_lookup_pair_by_string(struct fy_node *fyn, const char *key, size_t len) +{ + struct fy_document *fyd; + struct fy_node_pair *fynp; + + /* try quick and dirty simple scan */ + if (is_simple_key(key, len)) + return fy_node_mapping_lookup_pair_by_simple_key(fyn, key, len); + + fyd = fy_document_build_from_string(NULL, key, len); + if (!fyd) + return NULL; + + fynp = fy_node_mapping_lookup_pair(fyn, fy_document_root(fyd)); + + fy_document_destroy(fyd); + + return fynp; +} + +struct fy_node * +fy_node_mapping_lookup_by_string(struct fy_node *fyn, + const char *key, size_t len) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_lookup_pair_by_string(fyn, key, len); + return fynp ? fynp->value : NULL; +} + +struct fy_node * +fy_node_mapping_lookup_value_by_string(struct fy_node *fyn, + const char *key, size_t len) +{ + return fy_node_mapping_lookup_by_string(fyn, key, len); +} + +struct fy_node * +fy_node_mapping_lookup_key_by_string(struct fy_node *fyn, + const char *key, size_t len) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_lookup_pair_by_string(fyn, key, len); + return fynp ? fynp->key : NULL; +} + +#define fy_node_walk_ctx_create_a(_max_depth, _mark) \ + ({ \ + unsigned int __max_depth = (_max_depth); \ + struct fy_node_walk_ctx *_ctx; \ + \ + _ctx = alloca(sizeof(*_ctx) + sizeof(struct fy_node *) * __max_depth); \ + _ctx->max_depth = _max_depth; \ + _ctx->next_slot = 0; \ + _ctx->mark = (_mark); \ + _ctx; \ + }) + +static inline void fy_node_walk_mark_start(struct fy_node_walk_ctx *ctx) +{ + ctx->next_slot = 0; +} + +static inline void fy_node_walk_mark_end(struct fy_node_walk_ctx *ctx) +{ + struct fy_node *fyn; + + while (ctx->next_slot > 0) { + fyn = ctx->marked[--ctx->next_slot]; + fyn->marks &= ~ctx->mark; + } +} + +/* fyn is guaranteed to be non NULL and an alias */ +static inline bool fy_node_walk_mark(struct fy_node_walk_ctx *ctx, struct fy_node *fyn) +{ + struct fy_document *fyd = fyn->fyd; + struct fy_token *fyt = NULL; + + switch (fyn->type) { + case FYNT_SCALAR: + fyt = fyn->scalar; + break; + case FYNT_SEQUENCE: + fyt = fyn->sequence_start; + break; + case FYNT_MAPPING: + fyt = fyn->mapping_start; + break; + } + + /* depth error */ + FYD_TOKEN_ERROR_CHECK(fyd, fyt, FYEM_DOC, + ctx->next_slot < ctx->max_depth, err_out, + "max recursion depth exceeded (%u)", ctx->max_depth); + + /* mark found, loop */ + FYD_TOKEN_ERROR_CHECK(fyd, fyt, FYEM_DOC, + !(fyn->marks & ctx->mark), err_out, + "cyclic reference detected"); + + fyn->marks |= ctx->mark; + ctx->marked[ctx->next_slot++] = fyn; + + return true; + +err_out: + return false; +} + +static struct fy_node * +fy_node_follow_aliases(struct fy_node *fyn, enum fy_node_walk_flags flags, bool single) +{ + enum fy_node_walk_flags ptr_flags; + struct fy_ptr_node_list nl; + struct fy_ptr_node *fypn; + + if (!fyn || !fy_node_is_alias(fyn) || !(flags & FYNWF_FOLLOW)) + return fyn; + + ptr_flags = flags & FYNWF_PTR(FYNWF_PTR_MASK); + if (ptr_flags != FYNWF_PTR_YAML && ptr_flags != FYNWF_PTR_YPATH) + return fyn; + + fy_ptr_node_list_init(&nl); + + while (fyn && fy_node_is_alias(fyn)) { + + // fprintf(stderr, "%s: %s\n", __func__, fy_node_get_path_alloca(fyn)); + + /* check for loops */ + if (fy_ptr_node_list_contains(&nl, fyn)) { + fyn = NULL; + break; + } + + /* out of memory? */ + fypn = fy_ptr_node_create(fyn); + if (!fypn) { + fyn = NULL; + break; + } + fy_ptr_node_list_add_tail(&nl, fypn); + + fyn = fy_node_follow_alias(fyn, flags); + + if (single) + break; + } + + /* release */ + while ((fypn = fy_ptr_node_list_pop(&nl)) != NULL) + fy_ptr_node_destroy(fypn); + + return fyn; +} + +struct fy_node *fy_node_resolve_alias(struct fy_node *fyn) +{ + enum fy_node_walk_flags flags; + + if (!fyn) + return NULL; + + flags = FYNWF_FOLLOW | FYNWF_MAXDEPTH_DEFAULT | FYNWF_MARKER_DEFAULT; + if (fyn->fyd->parse_cfg.flags & FYPCF_YPATH_ALIASES) + flags |= FYNWF_PTR_YPATH; + else + flags |= FYNWF_PTR_YAML; + return fy_node_follow_aliases(fyn, flags, false); +} + +struct fy_node *fy_node_dereference(struct fy_node *fyn) +{ + enum fy_node_walk_flags flags; + + if (!fyn || !fy_node_is_alias(fyn)) + return NULL; + + flags = FYNWF_FOLLOW | FYNWF_MAXDEPTH_DEFAULT | FYNWF_MARKER_DEFAULT; + if (fyn->fyd->parse_cfg.flags & FYPCF_YPATH_ALIASES) + flags |= FYNWF_PTR_YPATH; + else + flags |= FYNWF_PTR_YAML; + return fy_node_follow_aliases(fyn, flags, true); +} + +static struct fy_node * +fy_node_by_path_internal(struct fy_node *fyn, + const char *path, size_t pathlen, + enum fy_node_walk_flags flags) +{ + enum fy_node_walk_flags ptr_flags; + struct fy_node *fynt, *fyni; + const char *s, *e, *ss, *ee; + char *end_idx, *json_key, *t, *p, *uri_path; + char c; + int idx, rlen; + size_t len, json_key_len, uri_path_len; + bool has_json_key_esc; + uint8_t code[4]; + int code_length; + bool trailing_slash; + + if (!fyn || !path) + return NULL; + + ptr_flags = flags & FYNWF_PTR(FYNWF_PTR_MASK); + if (ptr_flags == FYNWF_PTR_YPATH) + return fy_node_by_ypath(fyn, path, pathlen); + + s = path; + if (pathlen == (size_t)-1) + pathlen = strlen(path); + e = s + pathlen; + + /* a trailing slash works just like unix and symbolic links + * if it does not exist no symbolic link lookups are performed + * at the end of the operation. + * if it exists they are followed upon resolution + */ + trailing_slash = pathlen > 0 && path[pathlen - 1] == '/'; + + /* and continue on path lookup with the rest */ + + /* skip all prefixed / */ + switch (ptr_flags) { + default: + case FYNWF_PTR_YAML: + while (s < e && *s == '/') + s++; + /* for a last component / always match this one */ + if (s >= e) + goto out; + break; + + case FYNWF_PTR_JSON: + /* "" -> everything here */ + if (s == e) + return fyn; + /* it must have a separator here */ + if (*s != '/') + return NULL; + s++; + break; + + case FYNWF_PTR_RELJSON: + break; + } + + /* fyd_notice(fyn->fyd, "%s:%d following alias @%s \"%.*s\"", + __func__, __LINE__, fy_node_get_path(fyn), (int)(e - s), s); */ + fyn = fy_node_follow_aliases(fyn, flags, true); + + /* scalar can't match (it has no key) */ + if (fy_node_is_scalar(fyn)) { + fyn = NULL; + goto out; + } + + /* for a sequence the only allowed key is [n] where n is the index to follow */ + if (fy_node_is_sequence(fyn)) { + + c = -1; + switch (ptr_flags) { + default: + case FYNWF_PTR_YAML: + while (s < e && isspace(*s)) + s++; + + c = *s; + if (c == '[') + s++; + else if (!isdigit(c) && c != '-') + return NULL; + + idx = (int)strtol(s, &end_idx, 10); + + /* no digits found at all */ + if (idx == 0 && end_idx == s) + return NULL; + + s = end_idx; + + while (s < e && isspace(*s)) + s++; + + if (c == '[' && *s++ != ']') + return NULL; + + while (s < e && isspace(*s)) + s++; + + break; + + case FYNWF_PTR_JSON: + case FYNWF_PTR_RELJSON: + + /* special array end - always fails */ + if (*s == '-') + return NULL; + + idx = (int)strtol(s, &end_idx, 10); + + /* no digits found at all */ + if (idx == 0 && end_idx == s) + return NULL; + + /* no negatives */ + if (idx < 0) + return NULL; + + s = end_idx; + + if (s < e && *s == '/') + s++; + + break; + } + + len = e - s; + + fyn = fy_node_sequence_get_by_index(fyn, idx); + if (trailing_slash) + fyn = fy_node_follow_aliases(fyn, flags, false); + fyn = fy_node_by_path_internal(fyn, s, len, flags); + goto out; + } + + /* be a little bit paranoid */ + assert(fy_node_is_mapping(fyn)); + + path = s; + pathlen = (size_t)(e - s); + + switch (ptr_flags) { + default: + case FYNWF_PTR_YAML: + + /* scan ahead for the end of the path component + * note that we don't do UTF8 here, because all the + * escapes are regular ascii characters, i.e. + * '/', '*', '&', '.', '{', '}', '[', ']' and '\\' + */ + + while (s < e) { + c = *s; + /* end of path component? */ + if (c == '/') + break; + s++; + + if (c == '\\') { + /* it must be a valid escape */ + if (s >= e || !strchr("/*&.{}[]\\", *s)) + return NULL; + s++; + } else if (c == '"') { + while (s < e && *s != '"') { + c = *s++; + if (c == '\\' && (s < e && *s == '"')) + s++; + } + /* not a normal double quote end */ + if (s >= e || *s != '"') + return NULL; + s++; + } else if (c == '\'') { + while (s < e && *s != '\'') { + c = *s++; + if (c == '\'' && (s < e && *s == '\'')) + s++; + } + /* not a normal single quote end */ + if (s >= e || *s != '\'') + return NULL; + s++; + } + } + len = s - path; + + fynt = fyn; + fyn = fy_node_mapping_lookup_by_string(fyn, path, len); + + /* failed! last ditch attempt, is there a merge key? */ + if (!fyn && fynt && (flags & FYNWF_FOLLOW) && ptr_flags == FYNWF_PTR_YAML) { + fyn = fy_node_mapping_lookup_by_string(fynt, "<<", 2); + if (!fyn) + goto out; + + if (fy_node_is_alias(fyn)) { + + /* single alias '<<: *foo' */ + fyn = fy_node_mapping_lookup_by_string( + fy_node_follow_aliases(fyn, flags, false), path, len); + + } else if (fy_node_is_sequence(fyn)) { + + /* multi aliases '<<: [ *foo, *bar ]' */ + fynt = fyn; + for (fyni = fy_node_list_head(&fynt->sequence); fyni; + fyni = fy_node_next(&fynt->sequence, fyni)) { + if (!fy_node_is_alias(fyni)) + continue; + fyn = fy_node_mapping_lookup_by_string( + fy_node_follow_aliases(fyni, flags, false), + path, len); + if (fyn) + break; + } + } else + fyn = NULL; + } + break; + + case FYNWF_PTR_JSON: + case FYNWF_PTR_RELJSON: + + has_json_key_esc = false; + while (s < e) { + c = *s; + /* end of path component? */ + if (c == '/') + break; + s++; + if (c == '~') + has_json_key_esc = true; + } + len = s - path; + + if (has_json_key_esc) { + /* note that the escapes reduce the length, so allocating the + * same size is guaranteed safe */ + json_key = alloca(len + 1); + + ss = path; + ee = s; + t = json_key; + while (ss < ee) { + if (*ss != '~') { + *t++ = *ss++; + continue; + } + /* unterminated ~ escape, or neither ~0, ~1 */ + if (ss + 1 >= ee || (ss[1] < '0' && ss[1] > '1')) + return NULL; + *t++ = ss[1] == '0' ? '~' : '/'; + ss += 2; + } + json_key_len = t - json_key; + + path = json_key; + len = json_key_len; + } + + /* URI encoded escaped */ + if ((flags & FYNWF_URI_ENCODED) && memchr(path, '%', len)) { + /* escapes shrink, so safe to allocate as much */ + uri_path = alloca(len + 1); + + ss = path; + ee = path + len; + t = uri_path; + while (ss < ee) { + /* copy run until '%' or end */ + p = memchr(ss, '%', ee - ss); + rlen = (p ? p : ee) - ss; + memcpy(t, ss, rlen); + ss += rlen; + t += rlen; + + /* if end, break */ + if (!p) + break; + + /* collect a utf8 character sequence */ + code_length = sizeof(code); + ss = fy_uri_esc(ss, ee - ss, code, &code_length); + if (!ss) { + /* bad % escape sequence */ + return NULL; + } + memcpy(t, code, code_length); + t += code_length; + } + uri_path_len = t - uri_path; + + path = uri_path; + len = uri_path_len; + } + + fynt = fyn; + fyn = fy_node_mapping_lookup_value_by_simple_key(fyn, path, len); + break; + } + + len = e - s; + + if (len > 0 && trailing_slash) { + /* fyd_notice(fyn->fyd, "%s:%d following alias @%s \"%.*s\"", + __func__, __LINE__, fy_node_get_path(fyn), (int)(e - s), s); */ + fyn = fy_node_follow_aliases(fyn, flags, true); + } + + fyn = fy_node_by_path_internal(fyn, s, len, flags); + +out: + len = e - s; + + if (len > 0 && trailing_slash) { + /* fyd_notice(fyn->fyd, "%s:%d following alias @%s \"%.*s\"", + __func__, __LINE__, fy_node_get_path(fyn), (int)(e - s), s); */ + fyn = fy_node_follow_aliases(fyn, flags, true); + } + + return fyn; +} + +struct fy_node *fy_node_by_path(struct fy_node *fyn, + const char *path, size_t len, + enum fy_node_walk_flags flags) +{ + struct fy_anchor *fya; + const char *s, *e, *t, *anchor; + size_t alen; + char c; + int idx; + char *end_idx; + + if (!fyn || !path) + return NULL; + + /* if it's a YPATH, just punt to that method */ + if ((flags & FYNWF_PTR(FYNWF_PTR_MASK)) == FYNWF_PTR_YPATH) + return fy_node_by_ypath(fyn, path, len); + + s = path; + if (len == (size_t)-1) + len = strlen(path); + + e = s + len; + + /* fyd_notice(fyn->fyd, "%s: %.*s", __func__, (int)(len), s); */ + + /* first path component may be an alias */ + if ((flags & FYNWF_FOLLOW) && fyn && path) { + while (s < e && isspace(*s)) + s++; + + if (s >= e || *s != '*') + goto regular_path_lookup; + + s++; + + c = -1; + for (t = s; t < e; t++) { + c = *t; + /* it ends on anything non alias */ + if (c == '[' || c == ']' || + c == '{' || c == '}' || + c == ',' || c == ' ' || c == '\t' || + c == '/') + break; + } + + /* bad alias form for path */ + if (c == '[' || c == ']' || c == '{' || c == '}' || c == ',') + return NULL; + + anchor = s; + alen = t - s; + + if (alen) { + /* we must be terminated by '/' or space followed by '/' */ + /* strip until spaces and '/' end */ + while (t < e && (*t == ' ' || *t == '\t')) + t++; + + while (t < e && *t == '/') + t++; + + /* update path */ + path = t; + len = e - t; + + /* fyd_notice(fyn->fyd, "%s: looking up anchor=%.*s", __func__, (int)(alen), anchor); */ + + /* lookup anchor */ + fya = fy_document_lookup_anchor(fyn->fyd, anchor, alen); + if (!fya) { + /* fyd_notice(fyn->fyd, "%s: failed to lookup anchor=%.*s", __func__, (int)(alen), anchor); */ + return NULL; + } + + /* fyd_notice(fyn->fyd, "%s: found anchor=%.*s at %s", + __func__, (int)(alen), anchor, fy_node_get_path(fya->fyn)); */ + + /* nothing more? we're done */ + if (*path == '\0') + return fya->fyn; + + /* anchor found... all good */ + + fyn = fya->fyn; + } else { + /* no anchor it must be of the form *\/ */ + + path = s; + len = e - s; + } + + /* fyd_notice(fyn->fyd, "%s: continuing looking for %.*s", + __func__, (int)(len), path); */ + + } + +regular_path_lookup: + + /* if it's a relative json pointer... */ + if ((flags & FYNWF_PTR(FYNWF_PTR_MASK)) == FYNWF_PTR_RELJSON) { + + /* it must at least be one digit */ + if (len == 0) + return NULL; + + idx = (int)strtol(path, &end_idx, 10); + + /* at least one digit must exist */ + if (idx == 0 && path == end_idx) + return NULL; + + e = path + len; + len = e - end_idx; + path = end_idx; + + /* we don't do the trailing # here */ + if (len == 1 && *path == '#') + return NULL; + + while (idx-- > 0) + fyn = fy_node_get_parent(fyn); + + /* convert to regular json pointer from now on */ + flags &= ~FYNWF_PTR(FYNWF_PTR_MASK); + flags |= FYNWF_PTR_JSON; + } + + return fy_node_by_path_internal(fyn, path, len, flags); +} + +static char * +fy_node_get_reference_internal(struct fy_node *fyn_base, struct fy_node *fyn, bool near) +{ + struct fy_anchor *fya; + const char *path; + char *path2, *path3; + const char *text; + size_t len; + + if (!fyn) + return NULL; + + path2 = NULL; + + /* if the node has an anchor use it (ie return *foo) */ + if (!fyn_base && (fya = fy_node_get_anchor(fyn)) != NULL) { + text = fy_anchor_get_text(fya, &len); + if (!text) + return NULL; + path2 = alloca(1 + len + 1); + path2[0] = '*'; + memcpy(path2 + 1, text, len); + path2[len + 1] = '\0'; + + } else { + + fya = fyn_base ? fy_node_get_anchor(fyn_base) : NULL; + if (!fya && near) + fya = fy_node_get_nearest_anchor(fyn); + if (!fya) { + /* no anchor, direct reference (ie return *\/foo\/bar */ + path = fy_node_get_path_alloca(fyn); + if (!*path) + return NULL; + path2 = alloca(1 + strlen(path) + 1); + path2[0] = '*'; + strcpy(path2 + 1, path); + } else { + text = fy_anchor_get_text(fya, &len); + if (!text) + return NULL; + if (fy_anchor_node(fya) != fyn) { + path = fy_node_get_path_relative_to_alloca(fy_anchor_node(fya), fyn); + if (*path) { + /* we have a relative path */ + path2 = alloca(1 + len + 1 + strlen(path) + 1); + path2[0] = '*'; + memcpy(path2 + 1, text, len); + path2[len + 1] = '/'; + memcpy(1 + path2 + len + 1, path, strlen(path) + 1); + } else { + /* absolute path */ + path = fy_node_get_path_alloca(fyn); + if (!*path) + return NULL; + path2 = alloca(1 + strlen(path) + 1); + path2[0] = '*'; + strcpy(path2 + 1, path); + } + } else { + path2 = alloca(1 + len + 1); + path2[0] = '*'; + memcpy(path2 + 1, text, len); + path2[len + 1] = '\0'; + } + } + } + + if (!path2) + return NULL; + + path3 = strdup(path2); + if (!path3) + return NULL; + + return path3; +} + +char *fy_node_get_reference(struct fy_node *fyn) +{ + return fy_node_get_reference_internal(NULL, fyn, false); +} + +struct fy_node *fy_node_create_reference(struct fy_node *fyn) +{ + struct fy_node *fyn_ref; + char *path, *alias; + + path = fy_node_get_reference(fyn); + if (!path) + return NULL; + + alias = path; + if (*alias == '*') + alias++; + + fyn_ref = fy_node_create_alias_copy(fy_node_document(fyn), alias, FY_NT); + + free(path); + + return fyn_ref; +} + +char *fy_node_get_relative_reference(struct fy_node *fyn_base, struct fy_node *fyn) +{ + return fy_node_get_reference_internal(fyn_base, fyn, false); +} + +struct fy_node *fy_node_create_relative_reference(struct fy_node *fyn_base, struct fy_node *fyn) +{ + struct fy_node *fyn_ref; + char *path, *alias; + + path = fy_node_get_relative_reference(fyn_base, fyn); + if (!path) + return NULL; + + alias = path; + if (*alias == '*') + alias++; + + fyn_ref = fy_node_create_alias_copy(fy_node_document(fyn), alias, FY_NT); + + free(path); + + return fyn_ref; +} + +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) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi; + struct fy_node_walk_ctx *ctxn; + bool ret; + + if (!fyn) + return false; + + /* visited? no need to check */ + if (fyn->marks & FY_BIT(FYNWF_VISIT_MARKER)) + return false; + + /* marked node, it's a loop */ + if (ctx && !fy_node_walk_mark(ctx, fyn)) + return true; + + ret = false; + + switch (fyn->type) { + case FYNT_SCALAR: + + /* if it's not an alias, we're done */ + if (!fy_node_is_alias(fyn)) + break; + + ctxn = ctx; + if (!ctxn) + ctxn = fy_node_walk_ctx_create_a( + fy_node_walk_max_depth_from_flags(flags), FYNWF_REF_MARKER); + + + if (!ctx) { + fy_node_walk_mark_start(ctxn); + + /* mark this node */ + fy_node_walk_mark(ctxn, fyn); + } + + fyni = fy_node_follow_alias(fyn, flags); + + ret = fy_check_ref_loop(fyd, fyni, flags, ctxn); + + if (!ctx) + fy_node_walk_mark_end(ctxn); + + if (ret) + break; + + break; + + case FYNT_SEQUENCE: + for (fyni = fy_node_list_head(&fyn->sequence); fyni; + fyni = fy_node_next(&fyn->sequence, fyni)) { + + ret = fy_check_ref_loop(fyd, fyni, flags, ctx); + if (ret) + break; + } + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + ret = fy_check_ref_loop(fyd, fynp->key, flags, ctx); + if (ret) + break; + + ret = fy_check_ref_loop(fyd, fynp->value, flags, ctx); + if (ret) + break; + } + break; + } + + /* mark as visited */ + fyn->marks |= FY_BIT(FYNWF_VISIT_MARKER); + + return ret; +} + +char *fy_node_get_parent_address(struct fy_node *fyn) +{ + struct fy_node *parent, *fyni; + struct fy_node_pair *fynp; + struct fy_node *fyna; + char *path = NULL; + const char *str; + size_t len; + int idx; + bool is_key_root; + int ret; + const char *fmt; + char *new_path, *old_path; + + if (!fyn) + return NULL; + + parent = fy_node_get_document_parent(fyn); + if (!parent) + return NULL; + + if (fy_node_is_sequence(parent)) { + + /* for a sequence, find the index */ + idx = 0; + for (fyni = fy_node_list_head(&parent->sequence); fyni; + fyni = fy_node_next(&parent->sequence, fyni)) { + if (fyni == fyn) + break; + idx++; + } + + if (!fyni) + return NULL; + + ret = asprintf(&path, "%d", idx); + if (ret == -1) + return NULL; + } + + if (fy_node_is_mapping(parent)) { + + is_key_root = fyn->key_root; + + idx = 0; + fyna = NULL; + for (fynp = fy_node_pair_list_head(&parent->mapping); fynp; + fynp = fy_node_pair_next(&parent->mapping, fynp)) { + + if ((!is_key_root && fynp->value == fyn) || (is_key_root && fynp->key == fyn)) + break; + idx++; + } + + if (!fynp) + return NULL; + + fyna = fynp->key; + if (!fyna) + return NULL; + + /* if key is a plain scalar try to not use a complex style (even for quoted) */ + if (fyna && fy_node_is_scalar(fyna) && !fy_node_is_alias(fyna) && + (str = fy_token_get_scalar_path_key(fyna->scalar, &len)) != NULL) { + + fmt = !is_key_root ? "%.*s" : ".key(%.*s)"; + ret = asprintf(&path, fmt, (int)len, str); + if (ret == -1) + return NULL; + + } else { + + /* something complex, emit it */ + path = fy_emit_node_to_string(fyna, + FYECF_MODE_FLOW_ONELINE | FYECF_WIDTH_INF | + FYECF_STRIP_LABELS | FYECF_STRIP_TAGS | + FYECF_NO_ENDING_NEWLINE); + if (!path) + return NULL; + + if (is_key_root) { + old_path = path; + ret = asprintf(&new_path, ".key(%s)", path); + if (ret == -1) { + free(path); + return NULL; + } + free(old_path); + path = new_path; + } + } + } + + return path; +} + +char *fy_node_get_path(struct fy_node *fyn) +{ + struct path_track { + struct path_track *prev; + char *path; + }; + struct path_track *track, *newtrack; + char *path, *s, *path_mem; + size_t len; + struct fy_node *parent; + + if (!fyn) + return NULL; + + /* easy on the root */ + parent = fy_node_get_document_parent(fyn); + if (!parent) { + path_mem = strdup("/"); + return path_mem; + } + + track = NULL; + len = 0; + while ((path = fy_node_get_parent_address(fyn))) { + newtrack = alloca(sizeof(*newtrack)); + newtrack->prev = track; + newtrack->path = path; + + track = newtrack; + + len += strlen(path) + 1; + + fyn = fy_node_get_document_parent(fyn); + } + len += 2; + + path_mem = malloc(len); + + s = path_mem; + + while (track) { + len = strlen(track->path); + if (s) { + *s++ = '/'; + memcpy(s, track->path, len); + s += len; + } + free(track->path); + track = track->prev; + } + + if (s) + *s = '\0'; + + return path_mem; +} + +char *fy_node_get_path_relative_to(struct fy_node *fyn_parent, struct fy_node *fyn) +{ + char *path, *ppath, *path2, *path_ret; + size_t pathlen, ppathlen; + struct fy_node *ni, *nj; + + if (!fyn) + return NULL; + + /* must be on the same document */ + if (fyn_parent && (fyn_parent->fyd != fyn->fyd)) + return NULL; + + if (!fyn_parent) + fyn_parent = fyn->fyd->root; + + /* verify that it's a parent */ + ni = fyn; + while ((nj = fy_node_get_parent(ni)) != NULL && nj != fyn_parent) + ni = nj; + + /* not a parent, illegal */ + if (!nj) + return NULL; + + /* here we go... */ + path = ""; + pathlen = 0; + + ni = fyn; + while ((nj = fy_node_get_parent(ni)) != NULL) { + ppath = fy_node_get_parent_address(ni); + if (!ppath) + return NULL; + + ppathlen = strlen(ppath); + + if (pathlen > 0) { + path2 = alloca(pathlen + 1 + ppathlen + 1); + memcpy(path2, ppath, ppathlen); + path2[ppathlen] = '/'; + memcpy(path2 + ppathlen + 1, path, pathlen); + path2[ppathlen + 1 + pathlen] = '\0'; + } else { + path2 = alloca(ppathlen + 1); + memcpy(path2, ppath, ppathlen); + path2[ppathlen] = '\0'; + } + + path = path2; + pathlen = strlen(path); + + free(ppath); + ni = nj; + + if (ni == fyn_parent) + break; + } + + path_ret = strdup(path); + return path_ret; +} + +char *fy_node_get_short_path(struct fy_node *fyn) +{ + struct fy_node *fyn_anchor; + struct fy_anchor *fya; + const char *text; + size_t len; + const char *str; + char *path; + + if (!fyn) + return NULL; + + /* get the nearest anchor traversing upwards */ + fya = fy_node_get_nearest_anchor(fyn); + if (!fya) + return fy_node_get_path(fyn); + + fyn_anchor = fy_anchor_node(fya); + + text = fy_anchor_get_text(fya, &len); + if (!text) + return NULL; + + if (fyn_anchor == fyn) + str = alloca_sprintf("*%.*s", (int)len, text); + else + str = alloca_sprintf("*%.*s/%s", (int)len, text, + fy_node_get_path_relative_to_alloca(fyn_anchor, fyn)); + + path = strdup(str); + return path; +} + +static struct fy_node * +fy_document_load_node(struct fy_document *fyd, struct fy_parser *fyp, + struct fy_document_state **fydsp) +{ + struct fy_eventp *fyep = NULL; + struct fy_event *fye = NULL; + struct fy_node *fyn = NULL; + int rc, depth; + bool was_stream_start; + + if (!fyd || !fyp) + return NULL; + + /* only single documents */ + fy_parser_set_next_single_document(fyp); + fy_parser_set_default_document_state(fyp, fyd->fyds); + +again: + was_stream_start = false; + do { + /* get next event */ + fyep = fy_parse_private(fyp); + + /* no more */ + if (!fyep) + return NULL; + + was_stream_start = fyep->e.type == FYET_STREAM_START; + + if (was_stream_start) { + fy_parse_eventp_recycle(fyp, fyep); + fyep = NULL; + } + + } while (was_stream_start); + + fye = &fyep->e; + + /* STREAM_END */ + if (fye->type == FYET_STREAM_END) { + fy_parse_eventp_recycle(fyp, fyep); + + /* final STREAM_END? */ + if (fyp->state == FYPS_END) + return NULL; + + /* multi-stream */ + goto again; + } + + FYD_TOKEN_ERROR_CHECK(fyd, fy_event_get_token(fye), FYEM_DOC, + fye->type == FYET_DOCUMENT_START, err_out, + "bad event"); + + fy_parse_eventp_recycle(fyp, fyep); + fyep = NULL; + fye = NULL; + + fyd_doc_debug(fyd, "calling load_node() for root"); + depth = 0; + rc = fy_parse_document_load_node(fyp, fyd, fy_parse_private(fyp), &fyn, &depth); + fyd_error_check(fyd, !rc, err_out, + "fy_parse_document_load_node() failed"); + + rc = fy_parse_document_load_end(fyp, fyd, fy_parse_private(fyp)); + fyd_error_check(fyd, !rc, err_out, + "fy_parse_document_load_node() failed"); + + /* always resolve parents */ + fy_resolve_parent_node(fyd, fyn, NULL); + + if (fydsp) + *fydsp = fy_document_state_ref(fyp->current_document_state); + + return fyn; + +err_out: + fy_parse_eventp_recycle(fyp, fyep); + fyd->diag->on_error = false; + return NULL; +} + +static struct fy_node * +fy_node_build_internal(struct fy_document *fyd, + int (*parser_setup)(struct fy_parser *fyp, void *user), + void *user) +{ + struct fy_document_state *fyds = NULL; + struct fy_node *fyn = NULL; + struct fy_parser fyp_data, *fyp = &fyp_data; + struct fy_parse_cfg cfg; + struct fy_eventp *fyep; + int rc; + bool got_stream_end; + + if (!fyd || !parser_setup) + return NULL; + + cfg = fyd->parse_cfg; + cfg.diag = fyd->diag; + rc = fy_parse_setup(fyp, &cfg); + if (rc) { + fyd->diag->on_error = false; + return NULL; + } + + rc = (*parser_setup)(fyp, user); + fyd_error_check(fyd, !rc, err_out, + "parser_setup() failed"); + + fyn = fy_document_load_node(fyd, fyp, &fyds); + fyd_error_check(fyd, fyn, err_out, + "fy_document_load_node() failed"); + + got_stream_end = false; + while (!got_stream_end && (fyep = fy_parse_private(fyp)) != NULL) { + if (fyep->e.type == FYET_STREAM_END) + got_stream_end = true; + fy_parse_eventp_recycle(fyp, fyep); + } + + if (got_stream_end) { + fyep = fy_parse_private(fyp); + + FYD_TOKEN_ERROR_CHECK(fyd, fy_event_get_token(&fyep->e), FYEM_DOC, + !fyep, err_out, + "trailing events after the last"); + + fy_parse_eventp_recycle(fyp, fyep); + } + + rc = fy_document_state_merge(fyd->fyds, fyds); + fyd_error_check(fyd, !rc, err_out, + "fy_document_state_merge() failed"); + + fy_document_state_unref(fyds); + + fy_parse_cleanup(fyp); + + return fyn; + +err_out: + fy_node_detach_and_free(fyn); + fy_document_state_unref(fyds); + fy_parse_cleanup(fyp); + fyd->diag->on_error = false; + return NULL; +} + +struct fy_node *fy_node_build_from_string(struct fy_document *fyd, const char *str, size_t len) +{ + struct fy_document_build_string_ctx ctx = { + .str = str, + .len = len, + }; + + return fy_node_build_internal(fyd, parser_setup_from_string, &ctx); +} + +struct fy_node *fy_node_build_from_malloc_string(struct fy_document *fyd, char *str, size_t len) +{ + struct fy_document_build_malloc_string_ctx ctx = { + .str = str, + .len = len, + }; + + return fy_node_build_internal(fyd, parser_setup_from_malloc_string, &ctx); +} + +struct fy_node *fy_node_build_from_file(struct fy_document *fyd, const char *file) +{ + struct fy_document_build_file_ctx ctx = { + .file = file, + }; + + return fy_node_build_internal(fyd, parser_setup_from_file, &ctx); +} + +struct fy_node *fy_node_build_from_fp(struct fy_document *fyd, FILE *fp) +{ + struct fy_document_build_fp_ctx ctx = { + .name = NULL, + .fp = fp, + }; + + return fy_node_build_internal(fyd, parser_setup_from_fp, &ctx); +} + +int fy_document_set_root(struct fy_document *fyd, struct fy_node *fyn) +{ + if (!fyd) + return -1; + + if (fyn && fyn->attached) + return -1; + + fy_node_detach_and_free(fyd->root); + fyd->root = NULL; + + fyn->parent = NULL; + fyd->root = fyn; + + if (fyn) + fyn->attached = true; + + return 0; +} + +#define FYNCSIF_ALIAS FY_BIT(0) +#define FYNCSIF_SIMPLE FY_BIT(1) +#define FYNCSIF_COPY FY_BIT(2) +#define FYNCSIF_MALLOCED FY_BIT(3) + +static struct fy_node * +fy_node_create_scalar_internal(struct fy_document *fyd, const char *data, size_t size, + unsigned int flags) +{ + const bool alias = !!(flags & FYNCSIF_ALIAS); + const bool simple = !!(flags & FYNCSIF_SIMPLE); + const bool copy = !!(flags & FYNCSIF_COPY); + const bool malloced = !!(flags & FYNCSIF_MALLOCED); + struct fy_node *fyn = NULL; + struct fy_input *fyi; + struct fy_atom handle; + enum fy_scalar_style style; + char *data_copy = NULL; + + if (!fyd) + return NULL; + + if (data && size == (size_t)-1) + size = strlen(data); + + fyn = fy_node_alloc(fyd, FYNT_SCALAR); + fyd_error_check(fyd, fyn, err_out, + "fy_node_alloc() failed"); + + if (copy) { + data_copy = malloc(size); + fyd_error_check(fyd, data_copy, err_out, + "malloc() failed"); + memcpy(data_copy, data, size); + fyi = fy_input_from_malloc_data(data_copy, size, &handle, simple); + } else if (malloced) + fyi = fy_input_from_malloc_data((void *)data, size, &handle, simple); + else + fyi = fy_input_from_data(data, size, &handle, simple); + fyd_error_check(fyd, fyi, err_out, + "fy_input_from_data() failed"); + data_copy = NULL; + + if (!alias) { + style = handle.style == FYAS_PLAIN ? FYSS_PLAIN : FYSS_DOUBLE_QUOTED; + fyn->scalar = fy_token_create(FYTT_SCALAR, &handle, style); + } else + fyn->scalar = fy_token_create(FYTT_ALIAS, &handle, NULL); + + fyd_error_check(fyd, fyn->scalar, err_out, + "fy_token_create() failed"); + + fyn->style = !alias ? (style == FYSS_PLAIN ? FYNS_PLAIN : FYNS_DOUBLE_QUOTED) : FYNS_ALIAS; + + /* take away the input reference */ + fy_input_unref(fyi); + + return fyn; + +err_out: + if (data_copy) + free(data_copy); + fy_node_detach_and_free(fyn); + fyd->diag->on_error = false; + return NULL; +} + +struct fy_node *fy_node_create_scalar(struct fy_document *fyd, const char *data, size_t size) +{ + return fy_node_create_scalar_internal(fyd, data, size, 0); +} + +struct fy_node *fy_node_create_alias(struct fy_document *fyd, const char *data, size_t size) +{ + return fy_node_create_scalar_internal(fyd, data, size, FYNCSIF_ALIAS); +} + +struct fy_node *fy_node_create_scalar_copy(struct fy_document *fyd, const char *data, size_t size) +{ + return fy_node_create_scalar_internal(fyd, data, size, FYNCSIF_COPY); +} + +struct fy_node *fy_node_create_alias_copy(struct fy_document *fyd, const char *data, size_t size) +{ + return fy_node_create_scalar_internal(fyd, data, size, FYNCSIF_ALIAS | FYNCSIF_COPY); +} + +struct fy_node *fy_node_create_vscalarf(struct fy_document *fyd, const char *fmt, va_list ap) +{ + if (!fyd || !fmt) + return NULL; + + return fy_node_create_scalar_internal(fyd, alloca_vsprintf(fmt, ap), FY_NT, FYNCSIF_COPY); +} + +struct fy_node *fy_node_create_scalarf(struct fy_document *fyd, const char *fmt, ...) +{ + va_list ap; + struct fy_node *fyn; + + va_start(ap, fmt); + fyn = fy_node_create_vscalarf(fyd, fmt, ap); + va_end(ap); + + return fyn; +} + +int fy_node_set_tag(struct fy_node *fyn, const char *data, size_t len) +{ + struct fy_document *fyd; + struct fy_tag_scan_info info; + int handle_length, uri_length, prefix_length; + const char *handle_start; + int rc; + struct fy_atom handle; + struct fy_input *fyi = NULL; + struct fy_token *fyt = NULL, *fyt_td = NULL; + + if (!fyn || !data || !len || !fyn->fyd) + return -1; + + fyd = fyn->fyd; + + if (len == (size_t)-1) + len = strlen(data); + + memset(&info, 0, sizeof(info)); + + rc = fy_tag_scan(data, len, &info); + if (rc) + goto err_out; + + handle_length = info.handle_length; + uri_length = info.uri_length; + prefix_length = info.prefix_length; + + handle_start = data + prefix_length; + + fyt_td = fy_document_state_lookup_tag_directive(fyd->fyds, + handle_start, handle_length); + if (!fyt_td) + goto err_out; + + fyi = fy_input_from_data(data, len, &handle, true); + if (!fyi) + goto err_out; + + handle.style = FYAS_URI; + handle.direct_output = false; + handle.storage_hint = 0; + handle.storage_hint_valid = false; + + fyt = fy_token_create(FYTT_TAG, &handle, prefix_length, + handle_length, uri_length, fyt_td); + if (!fyt) + goto err_out; + + fy_token_unref(fyn->tag); + fyn->tag = fyt; + + /* take away the input reference */ + fy_input_unref(fyi); + + return 0; +err_out: + fyd->diag->on_error = false; + return -1; +} + +struct fy_node *fy_node_create_sequence(struct fy_document *fyd) +{ + struct fy_node *fyn; + + fyn = fy_node_alloc(fyd, FYNT_SEQUENCE); + if (!fyn) + return NULL; + + return fyn; +} + +struct fy_node *fy_node_create_mapping(struct fy_document *fyd) +{ + struct fy_node *fyn; + + fyn = fy_node_alloc(fyd, FYNT_MAPPING); + if (!fyn) + return NULL; + + return fyn; +} + +static int fy_node_sequence_insert_prepare(struct fy_node *fyn_seq, struct fy_node *fyn) +{ + struct fy_document *fyd; + + if (!fyn_seq || !fyn || fyn_seq->type != FYNT_SEQUENCE) + return -1; + + /* can't insert a node that's attached already */ + if (fyn->attached) + return -1; + + /* a document must be associated with the sequence */ + fyd = fyn_seq->fyd; + if (!fyd) + return -1; + + /* the documents of the nodes must match */ + if (fyn->fyd != fyd) + return -1; + + fyn->parent = fyn_seq; + + return 0; +} + +int fy_node_sequence_append(struct fy_node *fyn_seq, struct fy_node *fyn) +{ + int ret; + + ret = fy_node_sequence_insert_prepare(fyn_seq, fyn); + if (ret) + return ret; + + fy_node_mark_synthetic(fyn_seq); + fy_node_list_add_tail(&fyn_seq->sequence, fyn); + fyn->attached = true; + return 0; +} + +int fy_node_sequence_prepend(struct fy_node *fyn_seq, struct fy_node *fyn) +{ + int ret; + + ret = fy_node_sequence_insert_prepare(fyn_seq, fyn); + if (ret) + return ret; + + fy_node_mark_synthetic(fyn_seq); + fy_node_list_add(&fyn_seq->sequence, fyn); + fyn->attached = true; + return 0; +} + +static bool fy_node_sequence_contains_node(struct fy_node *fyn_seq, struct fy_node *fyn) +{ + struct fy_node *fyni; + + if (!fyn_seq || !fyn || fyn_seq->type != FYNT_SEQUENCE) + return false; + + for (fyni = fy_node_list_head(&fyn_seq->sequence); fyni; fyni = fy_node_next(&fyn_seq->sequence, fyni)) + if (fyni == fyn) + return true; + + return false; +} + +int fy_node_sequence_insert_before(struct fy_node *fyn_seq, + struct fy_node *fyn_mark, struct fy_node *fyn) +{ + int ret; + + if (!fy_node_sequence_contains_node(fyn_seq, fyn_mark)) + return -1; + + ret = fy_node_sequence_insert_prepare(fyn_seq, fyn); + if (ret) + return ret; + + fy_node_mark_synthetic(fyn_seq); + fy_node_list_insert_before(&fyn_seq->sequence, fyn_mark, fyn); + fyn->attached = true; + + return 0; +} + +int fy_node_sequence_insert_after(struct fy_node *fyn_seq, + struct fy_node *fyn_mark, struct fy_node *fyn) +{ + int ret; + + if (!fy_node_sequence_contains_node(fyn_seq, fyn_mark)) + return -1; + + ret = fy_node_sequence_insert_prepare(fyn_seq, fyn); + if (ret) + return ret; + + fy_node_mark_synthetic(fyn_seq); + fy_node_list_insert_after(&fyn_seq->sequence, fyn_mark, fyn); + fyn->attached = true; + + return 0; +} + +struct fy_node *fy_node_sequence_remove(struct fy_node *fyn_seq, struct fy_node *fyn) +{ + if (!fy_node_sequence_contains_node(fyn_seq, fyn)) + return NULL; + + fy_node_list_del(&fyn_seq->sequence, fyn); + fyn->parent = NULL; + fyn->attached = false; + + fy_node_mark_synthetic(fyn_seq); + + return fyn; +} + +static struct fy_node_pair * +fy_node_mapping_pair_insert_prepare(struct fy_node *fyn_map, + struct fy_node *fyn_key, struct fy_node *fyn_value) +{ + struct fy_document *fyd; + struct fy_node_pair *fynp; + + if (!fyn_map || fyn_map->type != FYNT_MAPPING) + return NULL; + + /* a document must be associated with the mapping */ + fyd = fyn_map->fyd; + if (!fyd) + return NULL; + + /* if not NULL, the documents of the nodes must match */ + if ((fyn_key && fyn_key->fyd != fyd) || + (fyn_value && fyn_value->fyd != fyd)) + return NULL; + + /* if not NULL neither the key nor the value must be attached */ + if ((fyn_key && fyn_key->attached) || + (fyn_value && fyn_value->attached)) + return NULL; + + if (fy_node_mapping_key_is_duplicate(fyn_map, fyn_key)) + return NULL; + + fynp = fy_node_pair_alloc(fyd); + if (!fynp) + return NULL; + + if (fyn_key) { + fyn_key->parent = fyn_map; + fyn_key->key_root = true; + } + if (fyn_value) + fyn_value->parent = fyn_map; + + fynp->key = fyn_key; + fynp->value = fyn_value; + fynp->parent = fyn_map; + + return fynp; +} + +int fy_node_mapping_append(struct fy_node *fyn_map, + struct fy_node *fyn_key, struct fy_node *fyn_value) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_pair_insert_prepare(fyn_map, fyn_key, fyn_value); + if (!fynp) + return -1; + + fy_node_pair_list_add_tail(&fyn_map->mapping, fynp); + if (fyn_map->xl) + fy_accel_insert(fyn_map->xl , fyn_key, fynp); + + if (fyn_key) + fyn_key->attached = true; + if (fyn_value) + fyn_value->attached = true; + + fy_node_mark_synthetic(fyn_map); + + return 0; +} + +int fy_node_mapping_prepend(struct fy_node *fyn_map, + struct fy_node *fyn_key, struct fy_node *fyn_value) +{ + struct fy_node_pair *fynp; + + fynp = fy_node_mapping_pair_insert_prepare(fyn_map, fyn_key, fyn_value); + if (!fynp) + return -1; + + if (fyn_key) + fyn_key->attached = true; + if (fyn_value) + fyn_value->attached = true; + fy_node_pair_list_add(&fyn_map->mapping, fynp); + if (fyn_map->xl) + fy_accel_insert(fyn_map->xl, fyn_key, fynp); + + fy_node_mark_synthetic(fyn_map); + + return 0; +} + +bool fy_node_mapping_contains_pair(struct fy_node *fyn_map, struct fy_node_pair *fynp) +{ + struct fy_node_pair *fynpi; + + if (!fyn_map || !fynp || fyn_map->type != FYNT_MAPPING) + return false; + + if (fyn_map->xl) { + fynpi = fy_node_accel_lookup_by_node(fyn_map, fynp->key); + if (fynpi == fynp) + return true; + } else { + for (fynpi = fy_node_pair_list_head(&fyn_map->mapping); fynpi; fynpi = fy_node_pair_next(&fyn_map->mapping, fynpi)) + if (fynpi == fynp) + return true; + } + + return false; +} + +int fy_node_mapping_remove(struct fy_node *fyn_map, struct fy_node_pair *fynp) +{ + if (!fy_node_mapping_contains_pair(fyn_map, fynp)) + return -1; + + fy_node_pair_list_del(&fyn_map->mapping, fynp); + if (fyn_map->xl) + fy_accel_remove(fyn_map->xl, fynp->key); + + if (fynp->key) { + fynp->key->parent = NULL; + fynp->key->attached = false; + } + + if (fynp->value) { + fynp->value->parent = NULL; + fynp->value->attached = false; + } + + fynp->parent = NULL; + + return 0; +} + +/* returns value */ +struct fy_node *fy_node_mapping_remove_by_key(struct fy_node *fyn_map, struct fy_node *fyn_key) +{ + struct fy_node_pair *fynp; + struct fy_node *fyn_value; + + fynp = fy_node_mapping_lookup_pair(fyn_map, fyn_key); + if (!fynp) + return NULL; + + fyn_value = fynp->value; + if (fyn_value) { + fyn_value->parent = NULL; + fyn_value->attached = false; + } + + /* do not free the key if it's the same pointer */ + if (fyn_key != fynp->key) + fy_node_detach_and_free(fyn_key); + fynp->value = NULL; + + fy_node_pair_list_del(&fyn_map->mapping, fynp); + if (fyn_map->xl) + fy_accel_remove(fyn_map->xl, fynp->key); + + fy_node_pair_detach_and_free(fynp); + + fy_node_mark_synthetic(fyn_map); + + return fyn_value; +} + +void *fy_node_mapping_sort_ctx_arg(struct fy_node_mapping_sort_ctx *ctx) +{ + return ctx->arg; +} + +static int fy_node_mapping_sort_cmp( +#ifdef __APPLE__ +void *arg, const void *a, const void *b +#else +const void *a, const void *b, void *arg +#endif +) +{ + struct fy_node_mapping_sort_ctx *ctx = arg; + struct fy_node_pair * const *fynppa = a, * const *fynppb = b; + + assert(fynppa >= ctx->fynpp && fynppa < ctx->fynpp + ctx->count); + assert(fynppb >= ctx->fynpp && fynppb < ctx->fynpp + ctx->count); + + return ctx->key_cmp(*fynppa, *fynppb, ctx->arg); +} + +/* not! thread safe! */ +#if !defined(HAVE_QSORT_R) || !HAVE_QSORT_R +static struct fy_node_mapping_sort_ctx *fy_node_mapping_sort_ctx_no_qsort_r; + +static int fy_node_mapping_sort_cmp_no_qsort_r(const void *a, const void *b) +{ +#ifdef __APPLE__ + return fy_node_mapping_sort_cmp( + fy_node_mapping_sort_ctx_no_qsort_r, + a, b); +#else + return fy_node_mapping_sort_cmp( a, b, + fy_node_mapping_sort_ctx_no_qsort_r); +#endif +} + +#endif + +static int fy_node_scalar_cmp_default(struct fy_node *fyn_a, + struct fy_node *fyn_b, + void *arg) +{ + /* handles NULL cases */ + if (fyn_a == fyn_b) + return 0; + if (!fyn_a) + return 1; + if (!fyn_b) + return -1; + return fy_token_cmp(fyn_a->scalar, fyn_b->scalar); +} + +/* the default sort method */ +static int fy_node_mapping_sort_cmp_default(const struct fy_node_pair *fynp_a, + const struct fy_node_pair *fynp_b, + void *arg) +{ + int idx_a, idx_b; + bool alias_a, alias_b, scalar_a, scalar_b; + struct fy_node_cmp_arg *cmp_arg; + fy_node_scalar_compare_fn cmp_fn; + void *cmp_fn_arg; + + cmp_arg = arg; + cmp_fn = cmp_arg ? cmp_arg->cmp_fn : fy_node_scalar_cmp_default; + cmp_fn_arg = cmp_arg ? cmp_arg->arg : NULL; + + /* order is: maps first, followed by sequences, and last scalars sorted */ + scalar_a = !fynp_a->key || fy_node_is_scalar(fynp_a->key); + scalar_b = !fynp_b->key || fy_node_is_scalar(fynp_b->key); + + /* scalar? perform comparison */ + if (scalar_a && scalar_b) { + + /* if both are aliases, sort skipping the '*' */ + alias_a = fy_node_is_alias(fynp_a->key); + alias_b = fy_node_is_alias(fynp_b->key); + + /* aliases win */ + if (alias_a && !alias_b) + return -1; + + if (!alias_a && alias_b) + return 1; + + return cmp_fn(fynp_a->key, fynp_b->key, cmp_fn_arg); + } + + /* b is scalar, a is not */ + if (!scalar_a && scalar_b) + return -1; + + /* a is scalar, b is not */ + if (scalar_a && !scalar_b) + return 1; + + /* different types, mappings win */ + if (fynp_a->key->type != fynp_b->key->type) + return fynp_a->key->type == FYNT_MAPPING ? -1 : 1; + + /* ok, need to compare indices now */ + idx_a = fy_node_mapping_get_pair_index(fynp_a->parent, fynp_a); + idx_b = fy_node_mapping_get_pair_index(fynp_b->parent, fynp_b); + + 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, + 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; + + 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] = fynpi; + + /* if there's enough space, put down a NULL at the end */ + if (i < count) + fynpp[i++] = NULL; + assert(i == count); + + if (!key_cmp) { + def_arg.cmp_fn = fy_node_scalar_cmp_default; + def_arg.arg = arg; + } else { + def_arg.cmp_fn = NULL; + def_arg.arg = NULL; + } + ctx.key_cmp = key_cmp ? : fy_node_mapping_sort_cmp_default; + ctx.arg = key_cmp ? arg : &def_arg; + ctx.fynpp = fynpp; + ctx.count = count; +#if defined(HAVE_QSORT_R) && HAVE_QSORT_R +#ifdef __APPLE__ + qsort_r(fynpp, count, sizeof(*fynpp), &ctx, fy_node_mapping_sort_cmp); +#else + qsort_r(fynpp, count, sizeof(*fynpp), fy_node_mapping_sort_cmp, &ctx); +#endif +#else + /* caution, not thread safe */ + fy_node_mapping_sort_ctx_no_qsort_r = &ctx; + qsort(fynpp, count, sizeof(*fynpp), fy_node_mapping_sort_cmp_no_qsort_r); + fy_node_mapping_sort_ctx_no_qsort_r = NULL; +#endif +} + +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) +{ + int count; + struct fy_node_pair **fynpp; + + count = fy_node_mapping_item_count(fyn_map); + if (count < 0) + return NULL; + + fynpp = malloc((count + 1) * sizeof(*fynpp)); + if (!fynpp) + return NULL; + + memset(fynpp, 0, (count + 1) * sizeof(*fynpp)); + + fy_node_mapping_perform_sort(fyn_map, key_cmp, arg, fynpp, count); + + if (countp) + *countp = count; + + return fynpp; +} + +void fy_node_mapping_sort_release_array(struct fy_node *fyn_map, struct fy_node_pair **fynpp) +{ + if (!fyn_map || !fynpp) + return; + + free(fynpp); +} + +int fy_node_mapping_sort(struct fy_node *fyn_map, + fy_node_mapping_sort_fn key_cmp, + void *arg) +{ + int count, i; + struct fy_node_pair **fynpp, *fynpi; + + fynpp = fy_node_mapping_sort_array(fyn_map, key_cmp, arg, &count); + if (!fynpp) + return -1; + + fy_node_pair_list_init(&fyn_map->mapping); + for (i = 0; i < count; i++) { + fynpi = fynpp[i]; + fy_node_pair_list_add_tail(&fyn_map->mapping, fynpi); + } + + fy_node_mapping_sort_release_array(fyn_map, fynpp); + + return 0; +} + +int fy_node_sort(struct fy_node *fyn, fy_node_mapping_sort_fn key_cmp, void *arg) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi; + int ret; + + if (!fyn) + return 0; + + 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)) { + + fy_node_sort(fyni, key_cmp, arg); + } + break; + + case FYNT_MAPPING: + ret = fy_node_mapping_sort(fyn, key_cmp, arg); + if (ret) + return ret; + + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + /* the parent of the key is always NULL */ + ret = fy_node_sort(fynp->key, key_cmp, arg); + if (ret) + return ret; + + ret = fy_node_sort(fynp->value, key_cmp, arg); + if (ret) + return ret; + + fynp->parent = fyn; + } + break; + } + + return 0; +} + +struct fy_node *fy_node_vbuildf(struct fy_document *fyd, const char *fmt, va_list ap) +{ + struct fy_document_vbuildf_ctx vctx; + struct fy_node *fyn; + + vctx.fmt = fmt; + va_copy(vctx.ap, ap); + fyn = fy_node_build_internal(fyd, parser_setup_from_fmt_ap, &vctx); + va_end(ap); + + return fyn; +} + +struct fy_node *fy_node_buildf(struct fy_document *fyd, const char *fmt, ...) +{ + struct fy_node *fyn; + va_list ap; + + va_start(ap, fmt); + fyn = fy_node_vbuildf(fyd, fmt, ap); + va_end(ap); + + return fyn; +} + +struct fy_document *fy_document_vbuildf(const struct fy_parse_cfg *cfg, const char *fmt, va_list ap) +{ + struct fy_document *fyd; + struct fy_document_vbuildf_ctx vctx; + + vctx.fmt = fmt; + va_copy(vctx.ap, ap); + fyd = fy_document_build_internal(cfg, parser_setup_from_fmt_ap, &vctx); + va_end(ap); + + return fyd; +} + +struct fy_document *fy_document_buildf(const struct fy_parse_cfg *cfg, const char *fmt, ...) +{ + struct fy_document *fyd; + va_list ap; + + va_start(ap, fmt); + fyd = fy_document_vbuildf(cfg, fmt, ap); + va_end(ap); + + return fyd; +} + +struct flow_reader_container { + struct fy_reader reader; + const struct fy_parse_cfg *cfg; +}; + +static struct fy_diag *flow_reader_get_diag(struct fy_reader *fyr) +{ + struct flow_reader_container *frc = container_of(fyr, struct flow_reader_container, reader); + return frc->cfg ? frc->cfg->diag : NULL; +} + +static const struct fy_reader_ops reader_ops = { + .get_diag = flow_reader_get_diag, +}; + +struct fy_document * +fy_flow_document_build_from_string(const struct fy_parse_cfg *cfg, + const char *str, size_t len, size_t *consumed) +{ + struct flow_reader_container frc; + struct fy_reader *fyr = NULL; + struct fy_parser fyp_data, *fyp = &fyp_data; + struct fy_parse_cfg cfg_data; + struct fy_input *fyi; + struct fy_document *fyd; + struct fy_mark mark; + int rc; + + if (!str) + return NULL; + + if (consumed) + *consumed = 0; + + if (!cfg) { + memset(&cfg_data, 0, sizeof(cfg_data)); + cfg_data.flags = FYPCF_DEFAULT_PARSE; + cfg = &cfg_data; + } + + memset(&frc, 0, sizeof(frc)); + fyr = &frc.reader; + frc.cfg = cfg; + + fy_reader_setup(fyr, &reader_ops); + + rc = fy_parse_setup(fyp, cfg); + if (rc) + goto err_no_parse; + + fyi = fy_input_from_data(str, len, NULL, false); + if (!fyi) + goto err_no_input; + + rc = fy_reader_input_open(fyr, fyi, NULL); + if (rc) + goto err_no_input_open; + + fy_parser_set_reader(fyp, fyr); + fy_parser_set_flow_only_mode(fyp, true); + + fyd = fy_parse_load_document(fyp); + + fy_parse_cleanup(fyp); + + if (fyd && consumed) { + fy_reader_get_mark(fyr, &mark); + *consumed = mark.input_pos; + } + + fy_reader_cleanup(fyr); + fy_input_unref(fyi); + + return fyd; + +err_no_input_open: + fy_input_unref(fyi); +err_no_input: + fy_parse_cleanup(fyp); +err_no_parse: + fy_reader_cleanup(fyr); + return NULL; +} + +int fy_node_vscanf(struct fy_node *fyn, const char *fmt, va_list ap) +{ + size_t len; + char *fmt_cpy, *s, *e, *t, *te, *key, *fmtspec; + const char *value; + char *value0; + size_t value_len, value0_len; + int count, ret; + struct fy_node *fynv; + va_list apt; + + if (!fyn || !fmt) + goto err_out; + + len = strlen(fmt); + fmt_cpy = alloca(len + 1); + memcpy(fmt_cpy, fmt, len + 1); + s = fmt_cpy; + e = s + len; + + /* the format is of the form 'access key' %fmt[...] */ + /* so we search for a (non escaped '%) */ + value0 = NULL; + value0_len = 0; + count = 0; + while (s < e) { + /* a '%' format must exist */ + t = strchr(s, '%'); + if (!t) + goto err_out; + + /* skip escaped % */ + if (t + 1 < e && t[1] == '%') { + s = t + 2; + continue; + } + + /* trim spaces from key */ + while (isspace(*s)) + s++; + te = t; + while (te > s && isspace(te[-1])) + *--te = '\0'; + + key = s; + + /* we have to scan until the next space that's not in char set */ + fmtspec = t; + while (t < e) { + if (isspace(*t)) + break; + /* character set (may include space) */ + if (*t == '[') { + t++; + /* skip caret */ + if (t < e && *t == '^') + t++; + /* if first character in the set is ']' accept it */ + if (t < e && *t == ']') + t++; + /* now skip until end of character set */ + while (t < e && *t != ']') + t++; + continue; + } + t++; + } + if (t < e) + *t++ = '\0'; + + /* find by (relative) path */ + fynv = fy_node_by_path(fyn, key, t - s, FYNWF_DONT_FOLLOW); + if (!fynv || fynv->type != FYNT_SCALAR) + break; + + /* there must be a text */ + value = fy_token_get_text(fynv->scalar, &value_len); + if (!value) + break; + + /* allocate buffer it's smaller than the one we have already */ + if (!value0 || value0_len < value_len) { + value0 = alloca(value_len + 1); + value0_len = value_len; + } + + memcpy(value0, value, value_len); + value0[value_len] = '\0'; + + va_copy(apt, ap); + /* scanf, all arguments are pointers */ + (void)va_arg(ap, void *); /* advance argument pointer */ + + /* pass it to the system's scanf method */ + ret = vsscanf(value0, fmtspec, apt); + + /* since it's a single specifier, it must be one on success */ + if (ret != 1) + break; + + s = t; + count++; + } + + return count; + +err_out: + errno = -EINVAL; + return -1; +} + +int fy_node_scanf(struct fy_node *fyn, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = fy_node_vscanf(fyn, fmt, ap); + va_end(ap); + + return ret; +} + +int fy_document_vscanf(struct fy_document *fyd, const char *fmt, va_list ap) +{ + return fy_node_vscanf(fyd->root, fmt, ap); +} + +int fy_document_scanf(struct fy_document *fyd, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = fy_document_vscanf(fyd, fmt, ap); + va_end(ap); + + return ret; +} + +bool fy_document_has_directives(const struct fy_document *fyd) +{ + struct fy_document_state *fyds; + + if (!fyd) + return false; + + fyds = fyd->fyds; + if (!fyds) + return false; + + return fyds->fyt_vd || !fy_token_list_empty(&fyds->fyt_td); +} + +bool fy_document_has_explicit_document_start(const struct fy_document *fyd) +{ + return fyd ? !fyd->fyds->start_implicit : false; +} + +bool fy_document_has_explicit_document_end(const struct fy_document *fyd) +{ + return fyd ? !fyd->fyds->end_implicit : false; +} + +void *fy_node_get_meta(struct fy_node *fyn) +{ + return fyn && fyn->has_meta ? fyn->meta : NULL; +} + +int fy_node_set_meta(struct fy_node *fyn, void *meta) +{ + struct fy_document *fyd; + + if (!fyn || !fyn->fyd) + return -1; + + fyd = fyn->fyd; + if (fyn->has_meta && fyd->meta_clear_fn) + fyd->meta_clear_fn(fyn, fyn->meta, fyd->meta_user); + fyn->meta = meta; + fyn->has_meta = true; + + return 0; +} + +void fy_node_clear_meta(struct fy_node *fyn) +{ + struct fy_document *fyd; + + if (!fyn || !fyn->has_meta || !fyn->fyd) + return; + + fyd = fyn->fyd; + if (fyd->meta_clear_fn) + fyd->meta_clear_fn(fyn, fyn->meta, fyd->meta_user); + fyn->meta = NULL; + fyn->has_meta = false; +} + +static void fy_node_clear_meta_internal(struct fy_node *fyn) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi; + + if (!fyn) + return; + + 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)) { + + fy_node_clear_meta_internal(fyni); + } + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + fy_node_clear_meta_internal(fynp->key); + fy_node_clear_meta_internal(fynp->value); + } + break; + } + + fy_node_clear_meta(fyn); +} + +int fy_document_register_meta(struct fy_document *fyd, + fy_node_meta_clear_fn clear_fn, + void *user) +{ + if (!fyd || !clear_fn || fyd->meta_clear_fn) + return -1; + + fyd->meta_clear_fn = clear_fn; + fyd->meta_user = user; + + return 0; +} + +void fy_document_unregister_meta(struct fy_document *fyd) +{ + if (!fyd) + return; + + fy_node_clear_meta_internal(fy_document_root(fyd)); + + fyd->meta_clear_fn = NULL; + fyd->meta_user = NULL; +} + +bool fy_node_set_marker(struct fy_node *fyn, unsigned int marker) +{ + unsigned int prev_marks; + + if (!fyn || marker > FYNWF_MAX_USER_MARKER) + return false; + prev_marks = fyn->marks; + fyn->marks |= FY_BIT(marker); + return !!(prev_marks & FY_BIT(marker)); +} + +bool fy_node_clear_marker(struct fy_node *fyn, unsigned int marker) +{ + unsigned int prev_marks; + + if (!fyn || marker > FYNWF_MAX_USER_MARKER) + return false; + prev_marks = fyn->marks; + fyn->marks &= ~FY_BIT(marker); + return !!(prev_marks & FY_BIT(marker)); +} + +bool fy_node_is_marker_set(struct fy_node *fyn, unsigned int marker) +{ + if (!fyn || marker > FYNWF_MAX_USER_MARKER) + return false; + return !!(fyn->marks & FY_BIT(marker)); +} + +FILE *fy_document_get_error_fp(struct fy_document *fyd) +{ + /* just this for now */ + return stderr; +} + +enum fy_parse_cfg_flags fy_document_get_cfg_flags(const struct fy_document *fyd) +{ + if (!fyd) + return fy_parser_get_cfg_flags(NULL); + + return fyd->parse_cfg.flags; +} + +bool fy_document_can_be_accelerated(struct fy_document *fyd) +{ + if (!fyd) + return false; + + return !(fyd->parse_cfg.flags & FYPCF_DISABLE_ACCELERATORS); +} + +bool fy_document_is_accelerated(struct fy_document *fyd) +{ + if (!fyd) + return false; + + return fyd->axl && fyd->naxl; +} + +static int hd_anchor_hash(struct fy_accel *xl, const void *key, void *userdata, void *hash) +{ + struct fy_token *fyt = (void *)key; + unsigned int *hashp = hash; + const char *text; + size_t len; + + text = fy_token_get_text(fyt, &len); + if (!text) + return -1; + + *hashp = XXH32(text, len, 2654435761U); + return 0; +} + +static bool hd_anchor_eq(struct fy_accel *xl, const void *hash, const void *key1, const void *key2, void *userdata) +{ + struct fy_token *fyt1 = (void *)key1, *fyt2 = (void *)key2; + const char *text1, *text2; + size_t len1, len2; + + text1 = fy_token_get_text(fyt1, &len1); + if (!text1) + return false; + text2 = fy_token_get_text(fyt2, &len2); + if (!text2) + return false; + + return len1 == len2 && !memcmp(text1, text2, len1); +} + +static const struct fy_hash_desc hd_anchor = { + .size = sizeof(unsigned int), + .max_bucket_grow_limit = 6, /* TODO allow tuning */ + .hash = hd_anchor_hash, + .eq = hd_anchor_eq, +}; + +static int hd_nanchor_hash(struct fy_accel *xl, const void *key, void *userdata, void *hash) +{ + struct fy_node *fyn = (void *)key; + unsigned int *hashp = hash; + uintptr_t ptr = (uintptr_t)fyn; + + *hashp = XXH32(&ptr, sizeof(ptr), 2654435761U); + + return 0; +} + +static bool hd_nanchor_eq(struct fy_accel *xl, const void *hash, const void *key1, const void *key2, void *userdata) +{ + struct fy_node *fyn1 = (void *)key1, *fyn2 = (void *)key2; + + return fyn1 == fyn2; +} + +static const struct fy_hash_desc hd_nanchor = { + .size = sizeof(unsigned int), + .max_bucket_grow_limit = 6, /* TODO allow tuning */ + .hash = hd_nanchor_hash, + .eq = hd_nanchor_eq, +}; + + +static int hd_mapping_hash(struct fy_accel *xl, const void *key, void *userdata, void *hash) +{ + return fy_node_hash_uint((struct fy_node *)key, hash); +} + +static bool hd_mapping_eq(struct fy_accel *xl, const void *hash, const void *key1, const void *key2, void *userdata) +{ + return fy_node_compare((struct fy_node *)key1, (struct fy_node *)key2); +} + +static const struct fy_hash_desc hd_mapping = { + .size = sizeof(unsigned int), + .max_bucket_grow_limit = 6, /* TODO allow tuning */ + .hash = hd_mapping_hash, + .eq = hd_mapping_eq, +}; + +typedef void (*fy_hash_update_fn)(void *state, const void *ptr, size_t size); + +static int +fy_node_hash_internal(struct fy_node *fyn, fy_hash_update_fn update_fn, void *state) +{ + struct fy_node *fyni; + struct fy_node_pair *fynp; + struct fy_node_pair **fynpp; + struct fy_token_iter iter; + int i, count, rc; + const struct fy_iter_chunk *ic; + + if (!fyn) { + /* NULL */ + update_fn(state, "s", 1); /* as zero length scalar */ + return 0; + } + + switch (fyn->type) { + case FYNT_SEQUENCE: + /* SEQUENCE */ + update_fn(state, "S", 1); + + for (fyni = fy_node_list_head(&fyn->sequence); fyni; + fyni = fy_node_next(&fyn->sequence, fyni)) { + + rc = fy_node_hash_internal(fyni, update_fn, state); + if (rc) + return rc; + } + + break; + + case FYNT_MAPPING: + count = fy_node_mapping_item_count(fyn); + + fynpp = alloca(sizeof(*fynpp) * (count + 1)); + fy_node_mapping_perform_sort(fyn, NULL, NULL, fynpp, count); + + /* MAPPING */ + update_fn(state, "M", 1); + + for (i = 0; i < count; i++) { + fynp = fynpp[i]; + + /* MAPPING KEY */ + update_fn(state, "K", 1); + rc = fy_node_hash_internal(fynp->key, update_fn, state); + if (rc) + return rc; + + /* MAPPING VALUE */ + update_fn(state, "V", 1); + rc = fy_node_hash_internal(fynp->value, update_fn, state); + if (rc) + return rc; + } + + break; + + case FYNT_SCALAR: + update_fn(state, !fy_node_is_alias(fyn) ? "s" : "A", 1); + + fy_token_iter_start(fyn->scalar, &iter); + ic = NULL; + while ((ic = fy_token_iter_chunk_next(&iter, ic, &rc)) != NULL) + update_fn(state, ic->str, ic->len); + fy_token_iter_finish(&iter); + + break; + } + + return 0; +} + +static void update_xx32(void *state, const void *ptr, size_t size) +{ + XXH32_update(state, ptr, size); +} + +int fy_node_hash_uint(struct fy_node *fyn, unsigned int *hashp) +{ + XXH32_state_t state; + int rc; + + XXH32_reset(&state, 2654435761U); + + rc = fy_node_hash_internal(fyn, update_xx32, &state); + if (rc) + return rc; + + *hashp = XXH32_digest(&state); + return 0; +} + +struct fy_document_state *fy_document_get_document_state(struct fy_document *fyd) +{ + return fyd ? fyd->fyds : NULL; +} + +int fy_document_set_document_state(struct fy_document *fyd, struct fy_document_state *fyds) +{ + /* document must exist and not have any contents */ + if (!fyd || fyd->root) + return -1; + + if (!fyds) + fyds = fy_document_state_default(NULL, NULL); + else + fyds = fy_document_state_ref(fyds); + + if (!fyds) + return -1; + + /* drop the previous document state */ + fy_document_state_unref(fyd->fyds); + /* and use the new document state from now on */ + fyd->fyds = fyds; + + 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) +{ + if (!fydb) + return; + + fy_document_builder_reset(fydb); + + 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); + 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; +} + +#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_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: + 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; + } + + 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); + + // 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)); + + 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"); + + 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; + + 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); + fyp_error_check(fyp, 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)); + fyp_error_check(fyp, !rc, err_out, + "fy_document_register_anchor() failed"); + } + fyn->mapping_start = fy_token_ref(fye->mapping_start.mapping_start); + 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); + fyp_error_check(fyp, 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)); + fyp_error_check(fyp, !rc, err_out, + "fy_document_register_anchor() failed"); + } + fyn->sequence_start = fy_token_ref(fye->sequence_start.sequence_start); + break; + + case FYET_SEQUENCE_END: + + 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] : "", + // 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] : ""); + 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 = ""; \ + } 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: != %s\n", __func__, fy_node_get_path_a(fypn2->fyn)); + } + if (!fypn2) { + if (fypn1) + fprintf(stderr, "%s: %s != \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; + + break; + + } + + if (fyn && anchor) { + rc = fy_document_register_anchor(fyd, fyn, fy_token_ref(anchor)); + fyp_error_check(fyp, !rc, err_out, + "fy_document_register_anchor() failed"); + } + + return fyn; + +err_out: + /* NULL OK */ + fy_node_free(fyn); + return NULL; +} + +int +fy_node_update_from_event(struct fy_node *fyn, struct fy_parser *fyp, struct fy_event *fye) +{ + if (!fyn || !fyp || !fye) + return -1; + + switch (fye->type) { + + case FYET_MAPPING_END: + if (!fy_node_is_mapping(fyn)) + return -1; + fy_token_unref(fyn->mapping_end); + fyn->mapping_end = fy_token_ref(fye->mapping_end.mapping_end); + + break; + + case FYET_SEQUENCE_END: + if (!fy_node_is_sequence(fyn)) + return -1; + fy_token_unref(fyn->sequence_end); + fyn->sequence_end = fy_token_ref(fye->sequence_end.sequence_end); + + break; + + default: + return -1; + } + + return 0; +} + +struct fy_node_pair * +fy_node_pair_create_with_key(struct fy_document *fyd, struct fy_node *fyn_parent, struct fy_node *fyn) +{ + struct fy_node_pair *fynp; + bool is_duplicate; + + 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; + } + + fynp = fy_node_pair_alloc(fyd); + fyd_error_check(fyd, fynp, err_out, + "fy_node_pair_alloc() failed"); + + fynp->parent = fyn_parent; + + fynp->key = fyn; + if (fynp->key) + fynp->key->attached = true; + + return fynp; + +err_out: + fy_node_pair_free(fynp); + return NULL; + +} + +int +fy_node_pair_update_with_value(struct fy_node_pair *fynp, struct fy_node *fyn) +{ + struct fy_node *fyn_parent; + int rc; + + /* node pair must exist and value must be NULL */ + if (!fynp || fynp->value || !fynp->parent || !fy_node_is_mapping(fynp->parent) || !fyn->fyd) + return -1; + + fynp->value = fyn; + if (fynp->value) + fynp->value->attached = true; + + fyn_parent = fynp->parent; + + fy_node_pair_list_add_tail(&fyn_parent->mapping, fynp); + if (fyn_parent->xl) { + rc = fy_accel_insert(fyn_parent->xl, fynp->key, fynp); + fyd_error_check(fyn->fyd, !rc, err_out, + "fy_accel_insert() failed"); + } + + return 0; + +err_out: + fy_node_pair_list_del(&fyn_parent->mapping, fynp); + if (fyn) + fyn->attached = false; + fynp->value = NULL; + return -1; +} + +int +fy_node_sequence_add_item(struct fy_node *fyn_parent, struct fy_node *fyn) +{ + /* node pair must exist and value must be NULL */ + if (!fyn_parent || !fyn || !fy_node_is_sequence(fyn_parent) || !fyn->fyd) + return -1; + + fyn->parent = fyn_parent; + fy_node_list_add_tail(&fyn_parent->sequence, fyn); + fyn->attached = true; + return 0; +} diff --git a/src/lib/fy-doc.h b/src/lib/fy-doc.h new file mode 100644 index 0000000..54b29b1 --- /dev/null +++ b/src/lib/fy-doc.h @@ -0,0 +1,315 @@ +/* + * fy-doc.h - YAML document internal header file + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_DOC_H +#define FY_DOC_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-ctype.h" +#include "fy-utf8.h" +#include "fy-list.h" +#include "fy-typelist.h" +#include "fy-types.h" +#include "fy-diag.h" +#include "fy-dump.h" +#include "fy-docstate.h" +#include "fy-accel.h" +#include "fy-walk.h" + +struct fy_eventp; + +FY_TYPE_FWD_DECL_LIST(document); + +struct fy_node; + +struct fy_node_pair { + struct list_head node; + struct fy_node *key; + struct fy_node *value; + struct fy_document *fyd; + struct fy_node *parent; +}; +FY_TYPE_FWD_DECL_LIST(node_pair); +FY_TYPE_DECL_LIST(node_pair); + +FY_TYPE_FWD_DECL_LIST(node); +struct fy_node { + struct list_head node; + struct fy_token *tag; + enum fy_node_style style; + struct fy_node *parent; + struct fy_document *fyd; + unsigned int marks; + enum fy_node_type type : 2; /* 2 bits are enough for 3 types */ + bool has_meta : 1; + bool attached : 1; /* when it's attached somewhere */ + bool synthetic : 1; /* node has been modified programmaticaly */ + bool key_root : 1; /* node is the root of key fy_node_get_parent() will return NULL */ + void *meta; + struct fy_accel *xl; /* mapping access accelerator */ + struct fy_path_expr_node_data *pxnd; + union { + struct fy_token *scalar; + struct fy_node_list sequence; + struct fy_node_pair_list mapping; + }; + union { + struct fy_token *sequence_start; + struct fy_token *mapping_start; + }; + union { + struct fy_token *sequence_end; + struct fy_token *mapping_end; + }; +}; +FY_TYPE_DECL_LIST(node); + +struct fy_node *fy_node_alloc(struct fy_document *fyd, enum fy_node_type type); +struct fy_node_pair *fy_node_pair_alloc(struct fy_document *fyd); +int fy_node_pair_free(struct fy_node_pair *fynp); + +void fy_node_detach_and_free(struct fy_node *fyn); +void fy_node_pair_detach_and_free(struct fy_node_pair *fynp); + +struct fy_anchor { + struct list_head node; + struct fy_node *fyn; + struct fy_token *anchor; + bool multiple : 1; +}; +FY_TYPE_FWD_DECL_LIST(anchor); +FY_TYPE_DECL_LIST(anchor); + +struct fy_document { + struct list_head node; + struct fy_anchor_list anchors; + struct fy_accel *axl; /* name -> anchor access accelerator */ + struct fy_accel *naxl; /* node -> anchor access accelerator */ + struct fy_document_state *fyds; + struct fy_diag *diag; + struct fy_parse_cfg parse_cfg; + struct fy_node *root; + bool parse_error : 1; + + struct fy_document *parent; + struct fy_document_list children; + + fy_node_meta_clear_fn meta_clear_fn; + void *meta_user; + + struct fy_path_expr_document_data *pxdd; +}; +/* only the list declaration/methods */ +FY_TYPE_DECL_LIST(document); + +struct fy_document *fy_parse_document_create(struct fy_parser *fyp, struct fy_eventp *fyep); + +struct fy_node_mapping_sort_ctx { + fy_node_mapping_sort_fn key_cmp; + void *arg; + struct fy_node_pair **fynpp; + int 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_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); + +struct fy_node_walk_ctx { + unsigned int max_depth; + unsigned int next_slot; + unsigned int mark; + struct fy_node *marked[0]; +}; + +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); + +#define FYNWF_VISIT_MARKER (FYNWF_MAX_USER_MARKER + 1) +#define FYNWF_REF_MARKER (FYNWF_MAX_USER_MARKER + 2) + +#define FYNWF_SYSTEM_MARKS (FY_BIT(FYNWF_VISIT_MARKER) | \ + FY_BIT(FYNWF_REF_MARKER)) + +bool fy_node_uses_single_input_only(struct fy_node *fyn, struct fy_input *fyi); +struct fy_input *fy_node_get_first_input(struct fy_node *fyn); +bool fy_node_is_synthetic(struct fy_node *fyn); +void fy_node_mark_synthetic(struct fy_node *fyn); +struct fy_input *fy_node_get_input(struct fy_node *fyn); +int fy_document_register_anchor(struct fy_document *fyd, + struct fy_node *fyn, struct fy_token *anchor); +bool fy_node_mapping_key_is_duplicate(struct fy_node *fyn, struct fy_node *fyn_key); + +struct fy_token *fy_node_non_synthesized_token(struct fy_node *fyn); +struct fy_token *fy_node_token(struct fy_node *fyn); + +FILE *fy_document_get_error_fp(struct fy_document *fyd); +enum fy_parse_cfg_flags fy_document_get_cfg_flags(const struct fy_document *fyd); +bool fy_document_is_accelerated(struct fy_document *fyd); +bool fy_document_can_be_accelerated(struct fy_document *fyd); + +/* 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; + struct fy_node *fyn; + struct fy_node_pair *fynp; /* for mapping */ +}; + +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); + +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 */ +}; + +struct fy_node_iterator_state { + struct fy_node *fyn; + union { + struct fy_node_pair *fynp; /* for map only */ + unsigned int idx; /* for sequence */ + }; +}; + +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]; +}; + +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; \ + }) + +/* indirect node */ +FY_TYPE_FWD_DECL_LIST(ptr_node); +struct fy_ptr_node { + struct list_head node; + struct fy_node *fyn; +}; +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); + +#endif diff --git a/src/lib/fy-docstate.c b/src/lib/fy-docstate.c new file mode 100644 index 0000000..554c6f0 --- /dev/null +++ b/src/lib/fy-docstate.c @@ -0,0 +1,384 @@ +/* + * fy-docstate.c - YAML document state methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-doc.h" + +#include "fy-docstate.h" + +struct fy_document_state *fy_document_state_alloc(void) +{ + struct fy_document_state *fyds; + + fyds = malloc(sizeof(*fyds)); + if (!fyds) + return NULL; + memset(fyds, 0, sizeof(*fyds)); + + fyds->fyt_vd = NULL; + fy_token_list_init(&fyds->fyt_td); + + fyds->refs = 1; + + return fyds; +} + +void fy_document_state_free(struct fy_document_state *fyds) +{ + if (!fyds) + return; + + assert(fyds->refs == 1); + + fy_token_unref(fyds->fyt_vd); + fy_token_list_unref_all(&fyds->fyt_td); + + free(fyds); +} + +struct fy_document_state *fy_document_state_ref(struct fy_document_state *fyds) +{ + if (!fyds) + return NULL; + + assert(fyds->refs + 1 > 0); + + fyds->refs++; + + return fyds; +} + +void fy_document_state_unref(struct fy_document_state *fyds) +{ + if (!fyds) + return; + + assert(fyds->refs > 0); + + if (fyds->refs == 1) + fy_document_state_free(fyds); + else + fyds->refs--; +} + +int fy_document_state_append_tag(struct fy_document_state *fyds, + const char *handle, const char *prefix, + bool is_default) +{ + struct fy_token *fyt = NULL; + struct fy_input *fyi = NULL; + char *data; + size_t size, handle_size, prefix_size; + struct fy_atom atom; + + size = strlen(handle) + 1 + strlen(prefix); + data = malloc(size + 1); + if (!data) + goto err_out; + + snprintf(data, size + 1, "%s %s", handle, prefix); + + fyi = fy_input_from_malloc_data(data, size, &atom, true); + if (!fyi) + goto err_out; + data = NULL; /* ownership now at input */ + + handle_size = strlen(handle); + prefix_size = strlen(prefix); + + fyt = fy_token_create(FYTT_TAG_DIRECTIVE, &atom, + handle_size, prefix_size, + is_default); + if (!fyt) + goto err_out; + + fy_token_list_add_tail(&fyds->fyt_td, fyt); + + if (!fy_tag_is_default_internal(handle, handle_size, prefix, prefix_size)) + fyds->tags_explicit = true; + + /* take away the input reference */ + fy_input_unref(fyi); + + return 0; + +err_out: + fy_token_unref(fyt); + fy_input_unref(fyi); + if (data) + free(data); + return -1; +} + +struct fy_document_state *fy_document_state_default( + const struct fy_version *default_version, + const struct fy_tag * const *default_tags) +{ + struct fy_document_state *fyds = NULL; + const struct fy_tag *fytag; + int i, rc; + + if (!default_version) + default_version = &fy_default_version; + + if (!default_tags) + default_tags = fy_default_tags; + + fyds = fy_document_state_alloc(); + if (!fyds) + goto err_out; + + fyds->version = *default_version; + + fyds->version_explicit = false; + fyds->tags_explicit = false; + fyds->start_implicit = true; + fyds->end_implicit = true; + + memset(&fyds->start_mark, 0, sizeof(fyds->start_mark)); + memset(&fyds->end_mark, 0, sizeof(fyds->end_mark)); + + fyds->fyt_vd = NULL; + fy_token_list_init(&fyds->fyt_td); + + for (i = 0; (fytag = default_tags[i]) != NULL; i++) { + + rc = fy_document_state_append_tag(fyds, fytag->handle, fytag->prefix, true); + if (rc) + goto err_out; + } + + return fyds; +err_out: + fy_document_state_unref(fyds); + return NULL; +} + +struct fy_document_state *fy_document_state_copy(struct fy_document_state *fyds) +{ + struct fy_document_state *fyds_new = NULL; + struct fy_token *fyt_td, *fyt; + + fyds_new = fy_document_state_alloc(); + if (!fyds_new) + goto err_out; + + fyds_new->version = fyds->version; + fyds_new->version_explicit = fyds->version_explicit; + fyds_new->tags_explicit = fyds->tags_explicit; + fyds_new->start_implicit = fyds->start_implicit; + fyds_new->end_implicit = fyds->end_implicit; + + fyds_new->start_mark = fyds->start_mark; + fyds_new->end_mark = fyds->end_mark; + + if (fyds->fyt_vd) { + fyt = fy_token_alloc(); + if (!fyt) + goto err_out; + + fyt->type = FYTT_VERSION_DIRECTIVE; + fyt->handle = fyds->fyt_vd->handle; + fyt->version_directive.vers = fyds->fyt_vd->version_directive.vers; + + /* take reference */ + fy_input_ref(fyt->handle.fyi); + + fyds_new->fyt_vd = fyt; + } + + for (fyt = fy_token_list_first(&fyds->fyt_td); fyt; fyt = fy_token_next(&fyds->fyt_td, fyt)) { + fyt_td = fy_token_alloc(); + if (!fyt_td) + goto err_out; + + fyt_td->type = FYTT_TAG_DIRECTIVE; + fyt_td->tag_directive.tag_length = fyt->tag_directive.tag_length; + 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; + + /* take reference */ + fy_input_ref(fyt_td->handle.fyi); + + /* append to the new document state */ + fy_token_list_add_tail(&fyds_new->fyt_td, fyt_td); + } + + return fyds_new; + +err_out: + fy_document_state_unref(fyds_new); + return NULL; +} + +struct fy_token *fy_document_state_lookup_tag_directive(struct fy_document_state *fyds, + const char *handle, size_t handle_size) +{ + const char *td_handle; + size_t td_handle_size; + struct fy_token *fyt; + + if (!fyds) + return NULL; + + for (fyt = fy_token_list_first(&fyds->fyt_td); fyt; fyt = fy_token_next(&fyds->fyt_td, fyt)) { + + td_handle = fy_tag_directive_token_handle(fyt, &td_handle_size); + assert(td_handle); + + if (handle_size == td_handle_size && !memcmp(handle, td_handle, handle_size)) + return fyt; + + } + + return NULL; +} + +int fy_document_state_merge(struct fy_document_state *fyds, + struct fy_document_state *fydsc) +{ + const char *td_prefix, *tdc_handle, *tdc_prefix; + size_t td_prefix_size, tdc_handle_size, tdc_prefix_size; + struct fy_token *fyt, *fytc_td, *fyt_td; + + if (!fyds || !fydsc) + return -1; + + /* check if there's a duplicate handle (which differs */ + for (fytc_td = fy_token_list_first(&fydsc->fyt_td); fytc_td; + fytc_td = fy_token_next(&fydsc->fyt_td, fytc_td)) { + + tdc_handle = fy_tag_directive_token_handle(fytc_td, &tdc_handle_size); + if (!tdc_handle) + goto err_out; + tdc_prefix = fy_tag_directive_token_prefix(fytc_td, &tdc_prefix_size); + if (!tdc_prefix) + goto err_out; + + fyt_td = fy_document_state_lookup_tag_directive(fyds, tdc_handle, tdc_handle_size); + if (fyt_td) { + /* exists, must check whether the prefixes match */ + td_prefix = fy_tag_directive_token_prefix(fyt_td, &td_prefix_size); + assert(td_prefix); + + /* match? do nothing */ + if (tdc_prefix_size == td_prefix_size && + !memcmp(tdc_prefix, td_prefix, td_prefix_size)) + continue; + + if (!fy_token_tag_directive_is_overridable(fyt_td)) + goto err_out; + + /* override tag directive */ + fy_token_list_del(&fyds->fyt_td, fyt_td); + fy_token_unref(fyt_td); + } + + fyt = fy_token_create(FYTT_TAG_DIRECTIVE, + &fytc_td->handle, + fytc_td->tag_directive.tag_length, + fytc_td->tag_directive.uri_length, + fytc_td->tag_directive.is_default); + if (!fyt) + goto err_out; + + fy_token_list_add_tail(&fyds->fyt_td, fyt); + } + + /* merge other document state */ + fyds->version_explicit |= fydsc->version_explicit; + fyds->tags_explicit |= fydsc->tags_explicit; + + if (fyds->version.major < fydsc->version.major || + (fyds->version.major == fydsc->version.major && + fyds->version.minor < fydsc->version.minor)) + fyds->version = fydsc->version; + + return 0; + +err_out: + return -1; +} + +const struct fy_version * +fy_document_state_version(struct fy_document_state *fyds) +{ + /* return the default if not set */ + return fyds ? &fyds->version : &fy_default_version; +} + +const struct fy_mark *fy_document_state_start_mark(struct fy_document_state *fyds) +{ + return fyds ? &fyds->start_mark : NULL; +} + +const struct fy_mark *fy_document_state_end_mark(struct fy_document_state *fyds) +{ + return fyds ? &fyds->end_mark : NULL; +} + +bool fy_document_state_version_explicit(struct fy_document_state *fyds) +{ + return fyds ? fyds->version_explicit : false; +} + +bool fy_document_state_tags_explicit(struct fy_document_state *fyds) +{ + return fyds ? fyds->tags_explicit : false; +} + +bool fy_document_state_start_implicit(struct fy_document_state *fyds) +{ + return fyds ? fyds->start_implicit : true; +} + +bool fy_document_state_end_implicit(struct fy_document_state *fyds) +{ + return fyds ? fyds->end_implicit : true; +} + +const struct fy_tag * +fy_document_state_tag_directive_iterate(struct fy_document_state *fyds, void **iterp) +{ + struct fy_token *fyt; + const struct fy_tag *tag; + + if (!fyds || !iterp) + return NULL; + + fyt = *iterp; + fyt = !fyt ? fy_token_list_head(&fyds->fyt_td) : fy_token_next(&fyds->fyt_td, fyt); + if (!fyt) + return NULL; + + /* sanity check */ + assert(fyt->type == FYTT_TAG_DIRECTIVE); + + /* always refresh, should be relatively infrequent */ + fyt->tag_directive.tag.handle = fy_tag_directive_token_handle0(fyt); + fyt->tag_directive.tag.prefix = fy_tag_directive_token_prefix0(fyt); + + tag = &fyt->tag_directive.tag; + + *iterp = fyt; + + return tag; +} diff --git a/src/lib/fy-docstate.h b/src/lib/fy-docstate.h new file mode 100644 index 0000000..80cd43d --- /dev/null +++ b/src/lib/fy-docstate.h @@ -0,0 +1,62 @@ +/* + * fy-docstate.h - YAML document state header. + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_DOCSTATE_H +#define FY_DOCSTATE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-ctype.h" +#include "fy-list.h" +#include "fy-typelist.h" +#include "fy-token.h" + +struct fy_document; + +struct fy_document_state { + int refs; + struct fy_version version; + bool version_explicit : 1; + bool tags_explicit : 1; + bool start_implicit : 1; + bool end_implicit : 1; + struct fy_mark start_mark; + struct fy_mark end_mark; + struct fy_token *fyt_vd; /* version directive */ + struct fy_token_list fyt_td; /* tag directives */ +}; + +struct fy_document_state *fy_document_state_alloc(void); +void fy_document_state_free(struct fy_document_state *fyds); +struct fy_document_state *fy_document_state_ref(struct fy_document_state *fyds); +void fy_document_state_unref(struct fy_document_state *fyds); + +int fy_document_state_append_tag(struct fy_document_state *fyds, + const char *handle, const char *prefix, + bool is_default); + +struct fy_document_state *fy_document_state_default( + const struct fy_version *default_version, + const struct fy_tag * const *default_tags); + +struct fy_document_state *fy_document_state_copy(struct fy_document_state *fyds); +int fy_document_state_merge(struct fy_document_state *fyds, + struct fy_document_state *fydsc); + +struct fy_token *fy_document_state_lookup_tag_directive(struct fy_document_state *fyds, + const char *handle, size_t handle_size); + +#endif diff --git a/src/lib/fy-dump.c b/src/lib/fy-dump.c new file mode 100644 index 0000000..b84eea1 --- /dev/null +++ b/src/lib/fy-dump.c @@ -0,0 +1,312 @@ +/* + * fy-dump.c - various debugging methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-ctype.h" +#include "fy-utf8.h" + +const char *fy_token_type_txt[FYTT_COUNT] = { + [FYTT_NONE] = "", + [FYTT_STREAM_START] = "STRM+", + [FYTT_STREAM_END] = "STRM-", + [FYTT_VERSION_DIRECTIVE] = "VRSD", + [FYTT_TAG_DIRECTIVE] = "TAGD", + [FYTT_DOCUMENT_START] = "DOC+", + [FYTT_DOCUMENT_END] = "DOC-", + [FYTT_BLOCK_SEQUENCE_START] = "BSEQ+", + [FYTT_BLOCK_MAPPING_START] = "BMAP+", + [FYTT_BLOCK_END] = "BEND", + [FYTT_FLOW_SEQUENCE_START] = "FSEQ+", + [FYTT_FLOW_SEQUENCE_END] = "FSEQ-", + [FYTT_FLOW_MAPPING_START] = "FMAP+", + [FYTT_FLOW_MAPPING_END] = "FMAP-", + [FYTT_BLOCK_ENTRY] = "BENTR", + [FYTT_FLOW_ENTRY] = "FENTR", + [FYTT_KEY] = "KEY", + [FYTT_SCALAR] = "SCLR", + [FYTT_VALUE] = "VAL", + [FYTT_ALIAS] = "ALIAS", + [FYTT_ANCHOR] = "ANCHR", + [FYTT_TAG] = "TAG", + [FYTT_INPUT_MARKER] = "INPUT_MARKER", + + [FYTT_PE_SLASH] = "PE_SLASH", + [FYTT_PE_ROOT] = "PE_ROOT", + [FYTT_PE_THIS] = "PE_THIS", + [FYTT_PE_PARENT] = "PE_PARENT", + [FYTT_PE_MAP_KEY] = "PE_MAP_KEY", + [FYTT_PE_SEQ_INDEX] = "PE_SEQ_INDEX", + [FYTT_PE_SEQ_SLICE] = "PE_SEQ_SLICE", + [FYTT_PE_SCALAR_FILTER] = "PE_SCALAR_FILTER", + [FYTT_PE_COLLECTION_FILTER] = "PE_COLLECTION_FILTER", + [FYTT_PE_SEQ_FILTER] = "PE_SEQ_FILTER", + [FYTT_PE_MAP_FILTER] = "PE_MAP_FILTER", + [FYTT_PE_UNIQUE_FILTER] = "PE_UNIQUE_FILTER", + [FYTT_PE_EVERY_CHILD] = "PE_EVERY_CHILD", + [FYTT_PE_EVERY_CHILD_R] = "PE_EVERY_CHILD_R", + [FYTT_PE_ALIAS] = "PE_ALIAS", + [FYTT_PE_SIBLING] = "PE_SIBLING", + [FYTT_PE_COMMA] = "PE_COMMA", + [FYTT_PE_BARBAR] = "PE_BARBAR", + [FYTT_PE_AMPAMP] = "PE_AMPAMP", + [FYTT_PE_LPAREN] = "PE_LPAREN", + [FYTT_PE_RPAREN] = "PE_RPAREN", + + [FYTT_PE_EQEQ] = "PE_EQEQ", + [FYTT_PE_NOTEQ] = "PE_NOTEQ", + [FYTT_PE_LT] = "PE_LT", + [FYTT_PE_GT] = "PE_GT", + [FYTT_PE_LTE] = "PE_LTE", + [FYTT_PE_GTE] = "PE_GTE", + + [FYTT_SE_PLUS] = "SE_PLUS", + [FYTT_SE_MINUS] = "SE_MINUS", + [FYTT_SE_MULT] = "SE_MULT", + [FYTT_SE_DIV] = "SE_DIV", + + [FYTT_PE_METHOD] = "PE_METHOD", + [FYTT_SE_METHOD] = "SE_METHOD", +}; + +char *fy_token_dump_format(struct fy_token *fyt, char *buf, size_t bufsz) +{ + const char *typetxt, *text; + size_t size; + enum fy_token_type type; + const char *pfx, *sfx; + + if (fyt && (unsigned int)fyt->type < sizeof(fy_token_type_txt)/ + sizeof(fy_token_type_txt[0])) { + typetxt = fy_token_type_txt[fyt->type]; + type = fyt->type; + } else { + typetxt = ""; + type = FYTT_NONE; + } + + size = 0; + switch (type) { + case FYTT_SCALAR: + case FYTT_ALIAS: + case FYTT_ANCHOR: + text = fy_token_get_text(fyt, &size); + break; + default: + text = NULL; + break; + } + + if (!text) { + snprintf(buf, bufsz, "%s", typetxt); + return buf; + } + + pfx = typetxt; + sfx = ""; + switch (type) { + case FYTT_SCALAR: + + pfx = "\""; + + /* not too large */ + if (size > 20) + size = 20; + text = fy_utf8_format_text_a(text, size, fyue_doublequote); + size = strlen(text); + if (size > 10) { + sfx = "...\""; + size = 7; + } else { + sfx = "\""; + } + break; + case FYTT_ALIAS: + case FYTT_ANCHOR: + sfx = type == FYTT_ALIAS ? "*" : "&"; + if (size > 10) { + sfx = "..."; + size = 7; + } else + sfx = ""; + break; + + default: + break; + } + + snprintf(buf, bufsz, "%s%.*s%s", pfx, (int)size, text, sfx); + + return buf; +} + +char *fy_token_list_dump_format(struct fy_token_list *fytl, + struct fy_token *fyt_highlight, char *buf, size_t bufsz) +{ + char *s, *e; + struct fy_token *fyt; + + s = buf; + e = buf + bufsz - 1; + for (fyt = fy_token_list_first(fytl); fyt; fyt = fy_token_next(fytl, fyt)) { + + if (s >= (e - 1)) + break; + + s += snprintf(s, e - s, "%s%s", + fyt != fy_token_list_first(fytl) ? "," : "", + fyt_highlight == fyt ? "*" : ""); + + fy_token_dump_format(fyt, s, e - s); + + s += strlen(s); + } + *s = '\0'; + + return buf; +} + +char *fy_simple_key_dump_format(struct fy_parser *fyp, struct fy_simple_key *fysk, char *buf, size_t bufsz) +{ + char tbuf[80]; + + if (!fysk) { + if (bufsz > 0) + *buf = '\0'; + return buf; + } + + fy_token_dump_format(fysk->token, tbuf, sizeof(tbuf)); + + snprintf(buf, bufsz, "%s/%c%c/%d/<%d-%d,%d-%d>", tbuf, + fysk->required ? 'R' : '-', + fysk->implicit_complex ? 'C' : '-', + fysk->flow_level, + fysk->mark.line, fysk->mark.column, + fysk->end_mark.line, fysk->end_mark.column); + return buf; +} + +char *fy_simple_key_list_dump_format(struct fy_parser *fyp, struct fy_simple_key_list *fyskl, + struct fy_simple_key *fysk_highlight, char *buf, size_t bufsz) +{ + char *s, *e; + struct fy_simple_key *fysk; + + s = buf; + e = buf + bufsz - 1; + for (fysk = fy_simple_key_list_first(fyskl); fysk; fysk = fy_simple_key_next(fyskl, fysk)) { + + if (s >= (e - 1)) + break; + + s += snprintf(s, e - s, "%s%s", + fysk != fy_simple_key_list_first(fyskl) ? "," : "", + fysk_highlight == fysk ? "*" : ""); + + fy_simple_key_dump_format(fyp, fysk, s, e - s); + + s += strlen(s); + } + *s = '\0'; + + return buf; +} + +#ifndef NDEBUG + +void fyp_debug_dump_token_list(struct fy_parser *fyp, struct fy_token_list *fytl, + struct fy_token *fyt_highlight, const char *banner) +{ + char buf[4096]; + + if (!fyp || !fyp->diag || FYET_DEBUG < fyp->diag->cfg.level) + return; + + fyp_scan_debug(fyp, "%s%s\n", banner, + fy_token_list_dump_format(fytl, fyt_highlight, buf, sizeof(buf))); +} + +void fyp_debug_dump_token(struct fy_parser *fyp, struct fy_token *fyt, const char *banner) +{ + char buf[80]; + + if (!fyp || !fyp->diag || FYET_DEBUG < fyp->diag->cfg.level) + return; + + fyp_scan_debug(fyp, "%s%s\n", banner, + fy_token_dump_format(fyt, buf, sizeof(buf))); +} + +void fyp_debug_dump_simple_key_list(struct fy_parser *fyp, struct fy_simple_key_list *fyskl, + struct fy_simple_key *fysk_highlight, const char *banner) +{ + char buf[4096]; + + if (!fyp || !fyp->diag || FYET_DEBUG < fyp->diag->cfg.level) + return; + + fyp_scan_debug(fyp, "%s%s\n", banner, + fy_simple_key_list_dump_format(fyp, fyskl, fysk_highlight, buf, sizeof(buf))); +} + +void fyp_debug_dump_simple_key(struct fy_parser *fyp, struct fy_simple_key *fysk, const char *banner) +{ + char buf[80]; + + if (!fyp || !fyp->diag || FYET_DEBUG < fyp->diag->cfg.level) + return; + + fyp_scan_debug(fyp, "%s%s\n", banner, + fy_simple_key_dump_format(fyp, fysk, buf, sizeof(buf))); +} + +void fyp_debug_dump_input(struct fy_parser *fyp, const struct fy_input_cfg *fyic, + const char *banner) +{ + switch (fyic->type) { + case fyit_file: + fyp_scan_debug(fyp, "%s: filename=\"%s\"\n", banner, + fyic->file.filename); + break; + case fyit_stream: + fyp_scan_debug(fyp, "%s: stream=\"%s\" fileno=%d chunk=%zu\n", banner, + fyic->stream.name, fileno(fyic->stream.fp), + fyic->stream.chunk); + break; + case fyit_memory: + fyp_scan_debug(fyp, "%s: start=%p size=%zu\n", banner, + fyic->memory.data, fyic->memory.size); + break; + case fyit_alloc: + fyp_scan_debug(fyp, "%s: start=%p size=%zu\n", banner, + fyic->alloc.data, fyic->alloc.size); + break; + default: + break; + } +} + +#endif diff --git a/src/lib/fy-dump.h b/src/lib/fy-dump.h new file mode 100644 index 0000000..a95fe1f --- /dev/null +++ b/src/lib/fy-dump.h @@ -0,0 +1,92 @@ +/* + * fy-dump.h - dumps for various internal structures + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_DUMP_H +#define FY_DUMP_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-list.h" +#include "fy-diag.h" + +struct fy_parser; +struct fy_token; +struct fy_token_list; +struct fy_simple_key; +struct fy_simple_key_list; +struct fy_input_cfg; + +extern const char *fy_token_type_txt[]; + +char *fy_token_dump_format(struct fy_token *fyt, char *buf, size_t bufsz); +char *fy_token_list_dump_format(struct fy_token_list *fytl, + struct fy_token *fyt_highlight, char *buf, size_t bufsz); + +char *fy_simple_key_dump_format(struct fy_parser *fyp, struct fy_simple_key *fysk, char *buf, size_t bufsz); +char *fy_simple_key_list_dump_format(struct fy_parser *fyp, struct fy_simple_key_list *fyskl, + struct fy_simple_key *fysk_highlight, char *buf, size_t bufsz); + +#ifndef NDEBUG + +void fyp_debug_dump_token_list(struct fy_parser *fyp, struct fy_token_list *fytl, + struct fy_token *fyt_highlight, const char *banner); +void fyp_debug_dump_token(struct fy_parser *fyp, struct fy_token *fyt, const char *banner); + +void fyp_debug_dump_simple_key_list(struct fy_parser *fyp, struct fy_simple_key_list *fyskl, + struct fy_simple_key *fysk_highlight, const char *banner); +void fyp_debug_dump_simple_key(struct fy_parser *fyp, struct fy_simple_key *fysk, const char *banner); + +void fyp_debug_dump_input(struct fy_parser *fyp, const struct fy_input_cfg *fyic, + const char *banner); + +#else + +static inline void +fyp_debug_dump_token_list(struct fy_parser *fyp, struct fy_token_list *fytl, + struct fy_token *fyt_highlight, const char *banner) +{ + /* nothing */ +} + +static inline void +fyp_debug_dump_token(struct fy_parser *fyp, struct fy_token *fyt, const char *banner) +{ + /* nothing */ +} + +static inline void +fyp_debug_dump_simple_key_list(struct fy_parser *fyp, struct fy_simple_key_list *fyskl, + struct fy_simple_key *fysk_highlight, const char *banner) +{ + /* nothing */ +} + +static inline void +fyp_debug_dump_simple_key(struct fy_parser *fyp, struct fy_simple_key *fysk, const char *banner) +{ + /* nothing */ +} + +static inline void +fy_debug_dump_input(struct fy_parser *fyp, const struct fy_input_cfg *fyic, + const char *banner) +{ + /* nothing */ +} + +#endif + +#endif diff --git a/src/lib/fy-emit-accum.h b/src/lib/fy-emit-accum.h new file mode 100644 index 0000000..fd9bb67 --- /dev/null +++ b/src/lib/fy-emit-accum.h @@ -0,0 +1,383 @@ +/* + * fy-emit-accum.h - internal YAML emitter accumulator header + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_EMIT_ACCUM_H +#define FY_EMIT_ACCUM_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-utf8.h" +#include "fy-event.h" + +struct fy_emit_accum { + char *accum; + size_t alloc; + size_t next; + char *inplace; + size_t inplacesz; + int col, row; + int ts; + enum fy_lb_mode lb_mode; +}; + +static inline void +fy_emit_accum_init(struct fy_emit_accum *ea, + void *inplace, size_t inplacesz, + int ts, enum fy_lb_mode lb_mode) +{ + memset(ea, 0, sizeof(*ea)); + + ea->inplace = inplace; + ea->inplacesz = inplacesz; + ea->accum = ea->inplace; + ea->alloc = ea->inplacesz; + ea->ts = ts ? ts : 8; + ea->lb_mode = lb_mode; +} + +static inline void +fy_emit_accum_reset(struct fy_emit_accum *ea) +{ + ea->next = 0; + ea->col = 0; + ea->row = 0; +} + +static inline void +fy_emit_accum_cleanup(struct fy_emit_accum *ea) +{ + if (ea->accum && ea->accum != ea->inplace) + free(ea->accum); + ea->accum = ea->inplace; + ea->alloc = ea->inplacesz; + fy_emit_accum_reset(ea); +} + +static inline void +fy_emit_accum_start(struct fy_emit_accum *ea, int col, enum fy_lb_mode lb_mode) +{ + fy_emit_accum_reset(ea); + ea->col = col; + ea->lb_mode = lb_mode; +} + +static inline void +fy_emit_accum_finish(struct fy_emit_accum *ea) +{ + fy_emit_accum_reset(ea); +} + +static inline int +fy_emit_accum_grow(struct fy_emit_accum *ea, size_t need) +{ + size_t atleast, asz; + char *new_accum; + + atleast = ea->alloc + need; + asz = ea->alloc; + /* minimum buffer is 32 */ + if (asz < 32) + asz = 32; + do { + asz *= 2; + } while (asz < atleast); + assert(asz > ea->inplacesz); + new_accum = realloc(ea->accum == ea->inplace ? NULL : ea->accum, asz); + if (!new_accum) /* out of memory */ + return -1; + if (ea->accum && ea->accum == ea->inplace) + memcpy(new_accum, ea->accum, ea->next); + ea->alloc = asz; + ea->accum = new_accum; + + return 0; +} + +static inline int +fy_emit_accum_utf8_put_raw(struct fy_emit_accum *ea, int c) +{ + size_t w, avail; + int ret; + + /* grow if needed */ + w = fy_utf8_width(c); + if (w > (avail = (ea->alloc - ea->next))) { + ret = fy_emit_accum_grow(ea, w - avail); + if (ret != 0) + return ret; + } + (void)fy_utf8_put_unchecked(ea->accum + ea->next, c); + ea->next += w; + + return 0; +} + +static inline int +fy_emit_accum_put_raw(struct fy_emit_accum *ea, int c) +{ + int ret; + + /* only lower ascii please */ + if (c >= 0x80) + return -1; + + /* grow if needed */ + if (ea->next >= ea->alloc) { + ret = fy_emit_accum_grow(ea, 1); + if (ret != 0) + return ret; + } + *(ea->accum + ea->next) = (char)c; + ea->next++; + + return 0; +} + +static inline int +fy_emit_accum_utf8_put(struct fy_emit_accum *ea, int c) +{ + int ret; + + if (!fy_utf8_is_valid(c)) + return -1; + + if (fy_is_lb_m(c, ea->lb_mode)) { + ret = fy_emit_accum_put_raw(ea, '\n'); + if (ret) + return ret; + ea->col = 0; + ea->row++; + } else if (fy_is_tab(c)) { + ret = fy_emit_accum_put_raw(ea, '\t'); + if (ret) + return ret; + ea->col += (ea->ts - (ea->col % ea->ts)); + } else { + if (c < 0x80) { + ret = fy_emit_accum_put_raw(ea, c); + if (ret) + return ret; + } else { + ret = fy_emit_accum_utf8_put_raw(ea, c); + } + ea->col++; + } + + return 0; +} + +static inline int +fy_emit_accum_utf8_write_raw(struct fy_emit_accum *ea, const void *data, size_t len) +{ + size_t avail; + int ret; + + /* grow if needed */ + if (len > (avail = (ea->alloc - ea->next))) { + ret = fy_emit_accum_grow(ea, len - avail); + if (ret != 0) + return ret; + } + memcpy(ea->accum + ea->next, data, len); + ea->next += len; + + return 0; +} + +static inline int +fy_emit_accum_utf8_write(struct fy_emit_accum *ea, const void *data, size_t len) +{ + const char *s, *e; + int c, w, ret; + + for (s = data, e = s + len; (c = fy_utf8_get(s, (e - s), &w)) >= 0; s += w) { + ret = fy_emit_accum_utf8_put(ea, c); + if (ret) + break; + } + return c == FYUG_EOF ? 0 : -1; +} + +static inline int +fy_emit_accum_utf8_printf_raw(struct fy_emit_accum *ea, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); + +static inline int +fy_emit_accum_utf8_printf_raw(struct fy_emit_accum *ea, const char *fmt, ...) +{ + va_list ap; + size_t avail, len; + int ret; + + /* get the size of the string */ + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + /* grow if needed */ + if ((len + 1) > (avail = (ea->alloc - ea->next))) { + ret = fy_emit_accum_grow(ea, (len + 1) - avail); + if (ret != 0) + return ret; + } + + va_start(ap, fmt); + (void)vsnprintf(ea->accum + ea->next, len + 1, fmt, ap); + va_end(ap); + + ea->next += len; + + return 0; +} + +static inline const char * +fy_emit_accum_get(struct fy_emit_accum *ea, size_t *lenp) +{ + *lenp = ea->next; + if (!ea->next) { + return ""; + } + return ea->accum; +} + +static inline int +fy_emit_accum_make_0_terminated(struct fy_emit_accum *ea) +{ + int ret; + + /* the empty case is special cased */ + if (!ea->next) + return 0; + + /* grow if needed for the '\0' */ + if (ea->next >= ea->alloc) { + ret = fy_emit_accum_grow(ea, 1); + if (ret != 0) + return ret; + } + assert(ea->next < ea->alloc); + *(ea->accum + ea->next) = '\0'; + return 0; +} + +static inline const char * +fy_emit_accum_get0(struct fy_emit_accum *ea) +{ + int ret; + + ret = fy_emit_accum_make_0_terminated(ea); + if (ret) + return NULL; + return ea->accum; +} + +static inline char * +fy_emit_accum_steal(struct fy_emit_accum *ea, size_t *lenp) +{ + int ret; + char *buf; + + /* empty, return a malloc'ed buffer to "" */ + if (!ea->next) { + buf = strdup(""); + if (!buf) { + *lenp = 0; + return NULL; + } + *lenp = ea->next; + } else if (ea->inplace && ea->accum == ea->inplace) { + buf = malloc(ea->next + 1); + if (!buf) { + *lenp = 0; + return NULL; + } + memcpy(buf, ea->accum, ea->next); + buf[ea->next] = '\0'; + *lenp = ea->next; + } else { + ret = fy_emit_accum_make_0_terminated(ea); + if (ret) { + *lenp = 0; + return NULL; + } + assert(ea->accum && ea->accum != ea->inplace); + buf = ea->accum; + *lenp = ea->next; + /* reset to inplace */ + ea->accum = ea->inplace; + ea->alloc = ea->inplacesz; + } + + fy_emit_accum_cleanup(ea); + return buf; +} + +static inline char * +fy_emit_accum_steal0(struct fy_emit_accum *ea) +{ + size_t len; + + return fy_emit_accum_steal(ea, &len); +} + +static inline bool +fy_emit_accum_empty(struct fy_emit_accum *ea) +{ + return ea->next == 0; +} + +static inline int +fy_emit_accum_size(struct fy_emit_accum *ea) +{ + return ea->next; +} + +static inline int +fy_emit_accum_column(struct fy_emit_accum *ea) +{ + return ea->col; +} + +static inline int +fy_emit_accum_row(struct fy_emit_accum *ea) +{ + return ea->row; +} + +struct fy_emit_accum_state { + int col; + int row; + size_t next; +}; + +static inline void +fy_emit_accum_get_state(struct fy_emit_accum *ea, struct fy_emit_accum_state *s) +{ + s->col = ea->col; + s->row = ea->row; + s->next = ea->next; +} + +static inline void +fy_emit_accum_rewind_state(struct fy_emit_accum *ea, const struct fy_emit_accum_state *s) +{ + /* we can only go back */ + assert(s->next <= ea->next); + ea->col = s->col; + ea->row = s->row; + ea->next = s->next; +} + +#endif diff --git a/src/lib/fy-emit.c b/src/lib/fy-emit.c new file mode 100644 index 0000000..c66b451 --- /dev/null +++ b/src/lib/fy-emit.c @@ -0,0 +1,3131 @@ +/* + * fy-emit.c - Internal YAML emitter methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-emit.h" + +/* fwd decl */ +void fy_emit_write(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int len); +void fy_emit_printf(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +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); + + return flags == FYECF_MODE_JSON || flags == FYECF_MODE_JSON_TP || flags == FYECF_MODE_JSON_ONELINE; +} + +static inline bool fy_emit_is_flow_mode(const struct fy_emitter *emit) +{ + enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK); + + return flags == FYECF_MODE_FLOW || flags == FYECF_MODE_FLOW_ONELINE; +} + +static inline bool fy_emit_is_block_mode(const struct fy_emitter *emit) +{ + enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK); + + return flags == FYECF_MODE_BLOCK || flags == FYECF_MODE_DEJSON; +} + +static inline bool fy_emit_is_oneline(const struct fy_emitter *emit) +{ + enum fy_emitter_cfg_flags flags = emit->cfg.flags & FYECF_MODE(FYECF_MODE_MASK); + + return flags == FYECF_MODE_FLOW_ONELINE || flags == FYECF_MODE_JSON_ONELINE; +} + +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_DEJSON; +} + +static inline int fy_emit_indent(struct fy_emitter *emit) +{ + int indent; + + indent = (emit->cfg.flags & FYECF_INDENT(FYECF_INDENT_MASK)) >> FYECF_INDENT_SHIFT; + return indent ? indent : 2; +} + +static inline int fy_emit_width(struct fy_emitter *emit) +{ + int width; + + width = (emit->cfg.flags & FYECF_WIDTH(FYECF_WIDTH_MASK)) >> FYECF_WIDTH_SHIFT; + if (width == 0) + return 80; + if (width == FYECF_WIDTH_MASK) + return INT_MAX; + return width; +} + +static inline bool fy_emit_output_comments(struct fy_emitter *emit) +{ + return !!(emit->cfg.flags & FYECF_OUTPUT_COMMENTS); +} + +static int fy_emit_node_check_json(struct fy_emitter *emit, struct fy_node *fyn) +{ + struct fy_document *fyd; + struct fy_node *fyni; + struct fy_node_pair *fynp, *fynpi; + int ret; + + if (!fyn) + return 0; + + fyd = fyn->fyd; + + switch (fyn->type) { + case FYNT_SCALAR: + FYD_TOKEN_ERROR_CHECK(fyd, fyn->scalar, FYEM_INTERNAL, + !fy_node_is_alias(fyn), err_out, + "aliases not allowed in JSON emit mode"); + break; + + case FYNT_SEQUENCE: + for (fyni = fy_node_list_head(&fyn->sequence); fyni; + fyni = fy_node_next(&fyn->sequence, fyni)) { + ret = fy_emit_node_check_json(emit, fyni); + if (ret) + return ret; + } + break; + + case FYNT_MAPPING: + for (fynp = fy_node_pair_list_head(&fyn->mapping); fynp; fynp = fynpi) { + + fynpi = fy_node_pair_next(&fyn->mapping, fynp); + + ret = fy_emit_node_check_json(emit, fynp->key); + if (ret) + return ret; + ret = fy_emit_node_check_json(emit, fynp->value); + if (ret) + return ret; + } + break; + } + return 0; +err_out: + return -1; +} + +static int fy_emit_node_check(struct fy_emitter *emit, struct fy_node *fyn) +{ + int ret; + + if (!fyn) + return 0; + + if (fy_emit_is_json_mode(emit)) { + ret = fy_emit_node_check_json(emit, fyn); + if (ret) + return ret; + } + + return 0; +} + +void fy_emit_node_internal(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent, bool is_key); +void fy_emit_scalar(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent, bool is_key); +void fy_emit_sequence(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent); +void fy_emit_mapping(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent); + +void fy_emit_write(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int len) +{ + int c, w; + const char *m, *e; + int outlen; + + if (!len) + return; + + outlen = emit->cfg.output(emit, type, str, len, emit->cfg.userdata); + if (outlen != len) + emit->output_error = true; + + e = str + len; + while ((c = fy_utf8_get(str, (e - str), &w)) >= 0) { + + /* special handling for MSDOS */ + if (c == '\r' && (e - str) > 1 && str[1] == '\n') { + str += 2; + emit->column = 0; + emit->line++; + continue; + } + + /* regular line break */ + if (fy_is_lb_r_n(c)) { + emit->column = 0; + emit->line++; + str += w; + continue; + } + + /* completely ignore ANSI color escape sequences */ + if (c == '\x1b' && (e - str) > 2 && str[1] == '[' && + (m = memchr(str, 'm', e - str)) != NULL) { + str = m + 1; + continue; + } + + emit->column++; + str += w; + } +} + +void fy_emit_puts(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str) +{ + fy_emit_write(emit, type, str, strlen(str)); +} + +void fy_emit_putc(struct fy_emitter *emit, enum fy_emitter_write_type type, int c) +{ + char buf[FY_UTF8_FORMAT_BUFMIN]; + + fy_utf8_format(c, buf, fyue_none); + fy_emit_puts(emit, type, buf); +} + +void fy_emit_vprintf(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *fmt, va_list ap) +{ + char *str; + int size; + va_list ap2; + + va_copy(ap2, ap); + + size = vsnprintf(NULL, 0, fmt, ap); + if (size < 0) + return; + + str = alloca(size + 1); + size = vsnprintf(str, size + 1, fmt, ap2); + if (size < 0) + return; + + fy_emit_write(emit, type, str, size); +} + +void fy_emit_printf(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_emit_vprintf(emit, type, fmt, ap); + va_end(ap); +} + +void fy_emit_write_ws(struct fy_emitter *emit) +{ + fy_emit_putc(emit, fyewt_whitespace, ' '); + emit->flags |= FYEF_WHITESPACE; +} + +void fy_emit_write_indent(struct fy_emitter *emit, int indent) +{ + int len; + char *ws; + + indent = indent > 0 ? indent : 0; + + if (!fy_emit_indentation(emit) || emit->column > indent || + (emit->column == indent && !fy_emit_whitespace(emit))) + fy_emit_putc(emit, fyewt_linebreak, '\n'); + + if (emit->column < indent) { + len = indent - emit->column; + ws = alloca(len + 1); + memset(ws, ' ', len); + ws[len] = '\0'; + fy_emit_write(emit, fyewt_indent, ws, len); + } + + emit->flags |= FYEF_WHITESPACE | FYEF_INDENTATION; +} + +enum document_indicator { + di_question_mark, + di_colon, + di_dash, + di_left_bracket, + di_right_bracket, + di_left_brace, + di_right_brace, + di_comma, + di_bar, + di_greater, + di_single_quote_start, + di_single_quote_end, + di_double_quote_start, + di_double_quote_end, + di_ambersand, + di_star, +}; + +void fy_emit_write_indicator(struct fy_emitter *emit, + enum document_indicator indicator, + int flags, int indent, + enum fy_emitter_write_type wtype) +{ + switch (indicator) { + + case di_question_mark: + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, '?'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_OPEN_ENDED); + break; + + case di_colon: + if (!(flags & DDNF_SIMPLE)) { + if (!emit->flow_level && !fy_emit_is_oneline(emit)) + fy_emit_write_indent(emit, indent); + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + } + fy_emit_putc(emit, wtype, ':'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_OPEN_ENDED); + break; + + case di_dash: + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, '-'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_OPEN_ENDED); + break; + + case di_left_bracket: + case di_left_brace: + emit->flow_level++; + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, indicator == di_left_bracket ? '[' : '{'); + emit->flags |= FYEF_WHITESPACE; + emit->flags &= ~(FYEF_INDENTATION | FYEF_OPEN_ENDED); + break; + + case di_right_bracket: + case di_right_brace: + emit->flow_level--; + fy_emit_putc(emit, wtype, indicator == di_right_bracket ? ']' : '}'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION | FYEF_OPEN_ENDED); + break; + + case di_comma: + fy_emit_putc(emit, wtype, ','); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION | FYEF_OPEN_ENDED); + break; + + case di_bar: + case di_greater: + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, indicator == di_bar ? '|' : '>'); + emit->flags &= ~(FYEF_INDENTATION | FYEF_WHITESPACE | FYEF_OPEN_ENDED); + break; + + case di_single_quote_start: + case di_double_quote_start: + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, indicator == di_single_quote_start ? '\'' : '"'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION | FYEF_OPEN_ENDED); + break; + + case di_single_quote_end: + case di_double_quote_end: + fy_emit_putc(emit, wtype, indicator == di_single_quote_end ? '\'' : '"'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION | FYEF_OPEN_ENDED); + break; + + case di_ambersand: + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, '&'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION); + break; + + case di_star: + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + fy_emit_putc(emit, wtype, '*'); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION); + break; + } +} + +int fy_emit_increase_indent(struct fy_emitter *emit, int flags, int indent) +{ + if (indent < 0) + return (flags & DDNF_FLOW) ? fy_emit_indent(emit) : 0; + + if (!(flags & DDNF_INDENTLESS)) + return indent + fy_emit_indent(emit); + + return indent; +} + +void fy_emit_write_comment(struct fy_emitter *emit, int flags, int indent, const char *str, size_t len, struct fy_atom *handle) +{ + const char *s, *e, *sr; + int c, w; + bool breaks; + + if (!str || !len) + return; + + if (len == (size_t)-1) + len = strlen(str); + + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + indent = emit->column; + + s = str; + e = str + len; + + sr = s; /* start of normal output run */ + breaks = false; + while (s < e && (c = fy_utf8_get(s, e - s, &w)) > 0) { + + if (fy_is_lb_m(c, fy_atom_lb_mode(handle))) { + + /* output run */ + fy_emit_write(emit, fyewt_comment, sr, s - sr); + sr = s + w; + fy_emit_write_indent(emit, indent); + emit->flags |= FYEF_INDENTATION; + breaks = true; + } else { + + if (breaks) { + fy_emit_write(emit, fyewt_comment, sr, s - sr); + sr = s; + fy_emit_write_indent(emit, indent); + } + emit->flags &= ~FYEF_INDENTATION; + breaks = false; + } + + s += w; + } + + /* dump what's remaining */ + fy_emit_write(emit, fyewt_comment, sr, s - sr); + + emit->flags |= (FYEF_WHITESPACE | FYEF_INDENTATION); +} + +struct fy_atom *fy_emit_token_comment_handle(struct fy_emitter *emit, struct fy_token *fyt, enum fy_comment_placement placement) +{ + struct fy_atom *handle; + + handle = fy_token_comment_handle(fyt, placement, false); + return handle && fy_atom_is_set(handle) ? handle : NULL; +} + +struct fy_token *fy_node_value_token(struct fy_node *fyn) +{ + struct fy_token *fyt; + + if (!fyn) + return NULL; + + switch (fyn->type) { + case FYNT_SCALAR: + fyt = fyn->scalar; + break; + case FYNT_SEQUENCE: + fyt = fyn->sequence_start; + break; + case FYNT_MAPPING: + fyt = fyn->mapping_start; + break; + default: + fyt = NULL; + break; + } + + return fyt; +} + +bool fy_emit_token_has_comment(struct fy_emitter *emit, struct fy_token *fyt, enum fy_comment_placement placement) +{ + return fy_emit_token_comment_handle(emit, fyt, placement) ? true : false; +} + +bool fy_emit_node_has_comment(struct fy_emitter *emit, struct fy_node *fyn, enum fy_comment_placement placement) +{ + return fy_emit_token_has_comment(emit, fy_node_value_token(fyn), placement); +} + +void fy_emit_token_comment(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent, + enum fy_comment_placement placement) +{ + struct fy_atom *handle; + char *text; + const char *t; + int len; + + handle = fy_emit_token_comment_handle(emit, fyt, placement); + if (!handle) + return; + + len = fy_atom_format_text_length(handle); + if (len < 0) + return; + + text = alloca(len + 1); + + if (placement == fycp_top || placement == fycp_bottom) { + fy_emit_write_indent(emit, indent); + emit->flags |= FYEF_WHITESPACE; + } + + t = fy_atom_format_text(handle, text, len + 1); + + fy_emit_write_comment(emit, flags, indent, t, len, handle); + + emit->flags &= ~FYEF_INDENTATION; + + if (placement == fycp_top || placement == fycp_bottom) { + fy_emit_write_indent(emit, indent); + emit->flags |= FYEF_WHITESPACE; + } +} + +void fy_emit_node_comment(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent, + enum fy_comment_placement placement) +{ + struct fy_token *fyt; + + if (!fy_emit_output_comments(emit) || (unsigned int)placement >= fycp_max) + return; + + fyt = fy_node_value_token(fyn); + if (!fyt) + return; + + fy_emit_token_comment(emit, fyt, flags, indent, placement); +} + +void fy_emit_common_node_preamble(struct fy_emitter *emit, + struct fy_token *fyt_anchor, + struct fy_token *fyt_tag, + int flags, int indent) +{ + const char *anchor = NULL; + const char *tag = NULL; + const char *td_prefix __FY_DEBUG_UNUSED__; + const char *td_handle; + size_t td_prefix_size, td_handle_size; + size_t tag_len = 0, anchor_len = 0; + bool json_mode = false; + + json_mode = fy_emit_is_json_mode(emit); + + if (!json_mode) { + if (!(emit->cfg.flags & FYECF_STRIP_LABELS)) { + if (fyt_anchor) + anchor = fy_token_get_text(fyt_anchor, &anchor_len); + } + + if (!(emit->cfg.flags & FYECF_STRIP_TAGS)) { + if (fyt_tag) + tag = fy_token_get_text(fyt_tag, &tag_len); + } + + if (anchor) { + fy_emit_write_indicator(emit, di_ambersand, flags, indent, fyewt_anchor); + fy_emit_write(emit, fyewt_anchor, anchor, anchor_len); + } + + if (tag) { + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + + td_handle = fy_tag_token_get_directive_handle(fyt_tag, &td_handle_size); + assert(td_handle); + td_prefix = fy_tag_token_get_directive_prefix(fyt_tag, &td_prefix_size); + assert(td_prefix); + + if (!td_handle_size) + fy_emit_printf(emit, fyewt_tag, "!<%.*s>", (int)tag_len, tag); + else + fy_emit_printf(emit, fyewt_tag, "%.*s%.*s", + (int)td_handle_size, td_handle, + (int)(tag_len - td_prefix_size), tag + td_prefix_size); + + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION); + } + } + + /* content for root always starts on a new line */ + if ((flags & DDNF_ROOT) && emit->column != 0 && + !(emit->flags & FYEF_HAD_DOCUMENT_START)) { + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } +} + +void fy_emit_node_internal(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent, bool is_key) +{ + enum fy_node_type type; + struct fy_anchor *fya; + struct fy_token *fyt_anchor = NULL; + + if (!(emit->cfg.flags & FYECF_STRIP_LABELS)) { + fya = fy_document_lookup_anchor_by_node(emit->fyd, fyn); + if (fya) + fyt_anchor = fya->anchor; + } + + fy_emit_common_node_preamble(emit, fyt_anchor, fyn->tag, flags, indent); + + type = fyn ? fyn->type : FYNT_SCALAR; + + if (type != FYNT_SCALAR && (flags & DDNF_ROOT) && emit->column != 0) { + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + + switch (type) { + case FYNT_SCALAR: + fy_emit_scalar(emit, fyn, flags, indent, is_key); + break; + case FYNT_SEQUENCE: + FYD_TOKEN_ERROR_CHECK(fyn->fyd, fyn->sequence_start, FYEM_INTERNAL, + !is_key || !fy_emit_is_json_mode(emit), err_out, + "JSON does not allow sequences as keys"); + fy_emit_sequence(emit, fyn, flags, indent); + break; + case FYNT_MAPPING: + FYD_TOKEN_ERROR_CHECK(fyn->fyd, fyn->mapping_start, FYEM_INTERNAL, + !is_key || !fy_emit_is_json_mode(emit), err_out, + "JSON does not allow mappings as keys"); + fy_emit_mapping(emit, fyn, flags, indent); + break; + } +err_out: + /* nothing */ + return; +} + +void fy_emit_token_write_plain(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent) +{ + bool allow_breaks, should_indent, spaces, breaks; + int c; + enum fy_emitter_write_type wtype; + const char *str = NULL; + size_t len = 0; + struct fy_atom *atom; + struct fy_atom_iter iter; + + /* null and not json mode */ + if (!fyt && !fy_emit_is_json_mode(emit)) + goto out; + + wtype = (flags & DDNF_SIMPLE_SCALAR_KEY) ? fyewt_plain_scalar_key : fyewt_plain_scalar; + + atom = fy_token_atom(fyt); + + /* null and json mode */ + if (fy_emit_is_json_mode(emit) && (!fyt || !atom || atom->size0)) { + fy_emit_puts(emit, wtype, "null"); + goto out; + } + + /* simple case first (90% of cases) */ + str = fy_token_get_direct_output(fyt, &len); + if (str && fy_token_atom_style(fyt) == FYAS_PLAIN) { + fy_emit_write(emit, wtype, str, len); + goto out; + } + + if (!atom) + goto out; + + allow_breaks = !(flags & DDNF_SIMPLE) && !fy_emit_is_json_mode(emit) && !fy_emit_is_oneline(emit); + + spaces = false; + breaks = false; + + fy_atom_iter_start(atom, &iter); + fy_emit_accum_start(&emit->ea, emit->column, fy_token_atom_lb_mode(fyt)); + while ((c = fy_atom_iter_utf8_get(&iter)) > 0) { + + if (fy_is_ws(c)) { + + should_indent = allow_breaks && !spaces && + fy_emit_accum_column(&emit->ea) > fy_emit_width(emit); + + if (should_indent && !fy_is_ws(fy_atom_iter_utf8_peek(&iter))) { + fy_emit_output_accum(emit, wtype, &emit->ea); + emit->flags &= ~FYEF_INDENTATION; + fy_emit_write_indent(emit, indent); + } else + fy_emit_accum_utf8_put(&emit->ea, c); + + spaces = true; + + } else if (fy_is_lb_m(c, fy_token_atom_lb_mode(fyt))) { + + /* blergh */ + if (!allow_breaks) + break; + + /* output run */ + if (!breaks) { + fy_emit_output_accum(emit, wtype, &emit->ea); + fy_emit_write_indent(emit, indent); + } + + emit->flags &= ~FYEF_INDENTATION; + fy_emit_write_indent(emit, indent); + + breaks = true; + + } else { + + if (breaks) + fy_emit_write_indent(emit, indent); + + fy_emit_accum_utf8_put(&emit->ea, c); + + emit->flags &= ~FYEF_INDENTATION; + + spaces = false; + breaks = false; + } + } + fy_emit_output_accum(emit, wtype, &emit->ea); + fy_emit_accum_finish(&emit->ea); + fy_atom_iter_finish(&iter); + +out: + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION); +} + +void fy_emit_token_write_alias(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent) +{ + const char *str = NULL; + size_t len = 0; + struct fy_atom_iter iter; + int c; + + if (!fyt) + return; + + fy_emit_write_indicator(emit, di_star, flags, indent, fyewt_alias); + + /* try direct output first (99% of cases) */ + str = fy_token_get_direct_output(fyt, &len); + if (str) { + fy_emit_write(emit, fyewt_alias, str, len); + return; + } + + /* corner case, use iterator */ + fy_atom_iter_start(fy_token_atom(fyt), &iter); + fy_emit_accum_start(&emit->ea, emit->column, fy_token_atom_lb_mode(fyt)); + while ((c = fy_atom_iter_utf8_get(&iter)) > 0) + fy_emit_accum_utf8_put(&emit->ea, c); + fy_emit_output_accum(emit, fyewt_alias, &emit->ea); + fy_emit_accum_finish(&emit->ea); + fy_atom_iter_finish(&iter); +} + +void fy_emit_token_write_quoted(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent, char qc) +{ + bool allow_breaks, spaces, breaks; + int c, i, w, digit; + enum fy_emitter_write_type wtype; + const char *str = NULL; + size_t len = 0; + bool should_indent, done_esc; + struct fy_atom *atom; + struct fy_atom_iter iter; + enum fy_atom_style target_style; + uint32_t hi_surrogate, lo_surrogate; + uint8_t non_utf8[4]; + size_t non_utf8_len, k; + + wtype = qc == '\'' ? + ((flags & DDNF_SIMPLE_SCALAR_KEY) ? + fyewt_single_quoted_scalar_key : fyewt_single_quoted_scalar) : + ((flags & DDNF_SIMPLE_SCALAR_KEY) ? + fyewt_double_quoted_scalar_key : fyewt_double_quoted_scalar); + + fy_emit_write_indicator(emit, + qc == '\'' ? di_single_quote_start : di_double_quote_start, + flags, indent, wtype); + + /* XXX check whether this is ever the case */ + if (!fyt) + goto out; + + /* note that if the original target style and the target differ + * we can note use direct output + */ + target_style = qc == '"' ? FYAS_DOUBLE_QUOTED : FYAS_SINGLE_QUOTED; + + /* simple case of direct output (large amount of cases) */ + str = fy_token_get_direct_output(fyt, &len); + if (str && fy_token_atom_style(fyt) == target_style) { + fy_emit_write(emit, wtype, str, len); + goto out; + } + + /* no atom? i.e. empty */ + atom = fy_token_atom(fyt); + if (!atom) + goto out; + + allow_breaks = !(flags & DDNF_SIMPLE) && !fy_emit_is_json_mode(emit) && !fy_emit_is_oneline(emit); + + spaces = false; + breaks = false; + + fy_atom_iter_start(atom, &iter); + fy_emit_accum_start(&emit->ea, emit->column, fy_token_atom_lb_mode(fyt)); + for (;;) { + non_utf8_len = sizeof(non_utf8); + c = fy_atom_iter_utf8_quoted_get(&iter, &non_utf8_len, non_utf8); + if (c < 0) + break; + + if (c == 0 && non_utf8_len > 0) { + for (k = 0; k < non_utf8_len; k++) { + c = (int)non_utf8[k] & 0xff; + fy_emit_accum_utf8_put(&emit->ea, '\\'); + fy_emit_accum_utf8_put(&emit->ea, 'x'); + digit = ((unsigned int)c >> 4) & 15; + fy_emit_accum_utf8_put(&emit->ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + digit = (unsigned int)c & 15; + fy_emit_accum_utf8_put(&emit->ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + continue; + } + + if (fy_is_space(c) || (qc == '\'' && fy_is_ws(c))) { + should_indent = allow_breaks && !spaces && + fy_emit_accum_column(&emit->ea) > fy_emit_width(emit); + + if (should_indent && + ((qc == '\'' && fy_is_ws(fy_atom_iter_utf8_peek(&iter))) || + qc == '"')) { + fy_emit_output_accum(emit, wtype, &emit->ea); + + if (qc == '"' && fy_is_ws(fy_atom_iter_utf8_peek(&iter))) + fy_emit_putc(emit, wtype, '\\'); + + emit->flags &= ~FYEF_INDENTATION; + fy_emit_write_indent(emit, indent); + } else + fy_emit_accum_utf8_put(&emit->ea, c); + + spaces = true; + breaks = false; + + } else if (qc == '\'' && fy_is_lb_m(c, fy_token_atom_lb_mode(fyt))) { + + /* blergh */ + if (!allow_breaks) + break; + + /* output run */ + if (!breaks) { + fy_emit_output_accum(emit, wtype, &emit->ea); + fy_emit_write_indent(emit, indent); + } + + emit->flags &= ~FYEF_INDENTATION; + fy_emit_write_indent(emit, indent); + + breaks = true; + } else { + /* output run */ + if (breaks) { + fy_emit_output_accum(emit, wtype, &emit->ea); + fy_emit_write_indent(emit, indent); + } + + /* escape */ + if (qc == '\'' && c == '\'') { + fy_emit_accum_utf8_put(&emit->ea, '\''); + fy_emit_accum_utf8_put(&emit->ea, '\''); + } else if (qc == '"' && + ((!fy_is_printq(c) || c == '"' || c == '\\') || + (fy_emit_is_json_mode(emit) && !fy_is_json_unescaped(c)))) { + + fy_emit_accum_utf8_put(&emit->ea, '\\'); + + /* common YAML and JSON escapes */ + done_esc = false; + switch (c) { + case '\b': + fy_emit_accum_utf8_put(&emit->ea, 'b'); + done_esc = true; + break; + case '\f': + fy_emit_accum_utf8_put(&emit->ea, 'f'); + done_esc = true; + break; + case '\n': + fy_emit_accum_utf8_put(&emit->ea, 'n'); + done_esc = true; + break; + case '\r': + fy_emit_accum_utf8_put(&emit->ea, 'r'); + done_esc = true; + break; + case '\t': + fy_emit_accum_utf8_put(&emit->ea, 't'); + done_esc = true; + break; + case '"': + fy_emit_accum_utf8_put(&emit->ea, '"'); + done_esc = true; + break; + case '\\': + fy_emit_accum_utf8_put(&emit->ea, '\\'); + done_esc = true; + break; + } + + if (done_esc) + goto done; + + if (!fy_emit_is_json_mode(emit)) { + switch (c) { + case '\0': + fy_emit_accum_utf8_put(&emit->ea, '0'); + break; + case '\a': + fy_emit_accum_utf8_put(&emit->ea, 'a'); + break; + case '\v': + fy_emit_accum_utf8_put(&emit->ea, 'v'); + break; + case '\e': + fy_emit_accum_utf8_put(&emit->ea, 'e'); + break; + case 0x85: + fy_emit_accum_utf8_put(&emit->ea, 'N'); + break; + case 0xa0: + fy_emit_accum_utf8_put(&emit->ea, '_'); + break; + case 0x2028: + fy_emit_accum_utf8_put(&emit->ea, 'L'); + break; + case 0x2029: + fy_emit_accum_utf8_put(&emit->ea, 'P'); + break; + default: + if ((unsigned int)c <= 0xff) { + fy_emit_accum_utf8_put(&emit->ea, 'x'); + w = 2; + } else if ((unsigned int)c <= 0xffff) { + fy_emit_accum_utf8_put(&emit->ea, 'u'); + w = 4; + } else if ((unsigned int)c <= 0xffffffff) { + fy_emit_accum_utf8_put(&emit->ea, 'U'); + w = 8; + } + + for (i = w - 1; i >= 0; i--) { + digit = ((unsigned int)c >> (i * 4)) & 15; + fy_emit_accum_utf8_put(&emit->ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + break; + } + + } else { + /* JSON escapes all others in \uXXXX and \uXXXX\uXXXX */ + w = 4; + if ((unsigned int)c <= 0xffff) { + fy_emit_accum_utf8_put(&emit->ea, 'u'); + for (i = w - 1; i >= 0; i--) { + digit = ((unsigned int)c >> (i * 4)) & 15; + fy_emit_accum_utf8_put(&emit->ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + } else { + hi_surrogate = 0xd800 | ((((c >> 16) & 0x1f) - 1) << 6) | ((c >> 10) & 0x3f); + lo_surrogate = 0xdc00 | (c & 0x3ff); + + fy_emit_accum_utf8_put(&emit->ea, 'u'); + for (i = w - 1; i >= 0; i--) { + digit = ((unsigned int)hi_surrogate >> (i * 4)) & 15; + fy_emit_accum_utf8_put(&emit->ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + + fy_emit_accum_utf8_put(&emit->ea, '\\'); + fy_emit_accum_utf8_put(&emit->ea, 'u'); + for (i = w - 1; i >= 0; i--) { + digit = ((unsigned int)lo_surrogate >> (i * 4)) & 15; + fy_emit_accum_utf8_put(&emit->ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + } + } + } else + fy_emit_accum_utf8_put(&emit->ea, c); +done: + emit->flags &= ~FYEF_INDENTATION; + spaces = false; + breaks = false; + } + } + fy_emit_output_accum(emit, wtype, &emit->ea); + fy_emit_accum_finish(&emit->ea); + fy_atom_iter_finish(&iter); + +out: + fy_emit_write_indicator(emit, + qc == '\'' ? di_single_quote_end : di_double_quote_end, + flags, indent, wtype); +} + +bool fy_emit_token_write_block_hints(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent, char *chompp) +{ + char chomp = '\0'; + bool explicit_chomp = false; + struct fy_atom *atom; + + atom = fy_token_atom(fyt); + if (!atom) { + emit->flags &= ~FYEF_OPEN_ENDED; + chomp = '-'; + goto out; + } + + if (atom->starts_with_ws || atom->starts_with_lb) { + fy_emit_putc(emit, fyewt_indicator, '0' + fy_emit_indent(emit)); + explicit_chomp = true; + } + + if (!atom->ends_with_lb) { + emit->flags &= ~FYEF_OPEN_ENDED; + chomp = '-'; + goto out; + } + + if (atom->trailing_lb) { + emit->flags |= FYEF_OPEN_ENDED; + chomp = '+'; + goto out; + } + emit->flags &= ~FYEF_OPEN_ENDED; + +out: + if (chomp) + fy_emit_putc(emit, fyewt_indicator, chomp); + *chompp = chomp; + return explicit_chomp; +} + +void fy_emit_token_write_literal(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent) +{ + bool breaks; + int c; + char chomp; + struct fy_atom *atom; + struct fy_atom_iter iter; + + fy_emit_write_indicator(emit, di_bar, flags, indent, fyewt_indicator); + + fy_emit_token_write_block_hints(emit, fyt, flags, indent, &chomp); + if (flags & DDNF_ROOT) + indent += fy_emit_indent(emit); + + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags |= FYEF_WHITESPACE | FYEF_INDENTATION; + + atom = fy_token_atom(fyt); + if (!atom) + goto out; + + breaks = true; + + fy_atom_iter_start(atom, &iter); + fy_emit_accum_start(&emit->ea, emit->column, fy_token_atom_lb_mode(fyt)); + while ((c = fy_atom_iter_utf8_get(&iter)) > 0) { + + if (breaks) { + fy_emit_write_indent(emit, indent); + breaks = false; + } + + if (fy_is_lb_m(c, fy_token_atom_lb_mode(fyt))) { + fy_emit_output_accum(emit, fyewt_literal_scalar, &emit->ea); + emit->flags &= ~FYEF_INDENTATION; + breaks = true; + } else + fy_emit_accum_utf8_put(&emit->ea, c); + } + fy_emit_output_accum(emit, fyewt_literal_scalar, &emit->ea); + fy_emit_accum_finish(&emit->ea); + fy_atom_iter_finish(&iter); + +out: + emit->flags &= ~FYEF_INDENTATION; +} + +void fy_emit_token_write_folded(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent) +{ + bool leading_spaces, breaks; + int c, nrbreaks, nrbreakslim; + char chomp; + struct fy_atom *atom; + struct fy_atom_iter iter; + + fy_emit_write_indicator(emit, di_greater, flags, indent, fyewt_indicator); + + fy_emit_token_write_block_hints(emit, fyt, flags, indent, &chomp); + if (flags & DDNF_ROOT) + indent += fy_emit_indent(emit); + + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags |= FYEF_WHITESPACE | FYEF_INDENTATION; + + atom = fy_token_atom(fyt); + if (!atom) + return; + + breaks = true; + leading_spaces = true; + + fy_atom_iter_start(atom, &iter); + fy_emit_accum_start(&emit->ea, emit->column, fy_token_atom_lb_mode(fyt)); + while ((c = fy_atom_iter_utf8_get(&iter)) > 0) { + + if (fy_is_lb_m(c, fy_token_atom_lb_mode(fyt))) { + + /* output run */ + if (!fy_emit_accum_empty(&emit->ea)) { + fy_emit_output_accum(emit, fyewt_literal_scalar, &emit->ea); + /* do not output a newline (indent) if at the end or + * this is a leading spaces line */ + if (!fy_is_z(fy_atom_iter_utf8_peek(&iter)) && !leading_spaces) + fy_emit_write_indent(emit, indent); + } + + /* count the number of consecutive breaks */ + nrbreaks = 1; + while (fy_is_lb_m((c = fy_atom_iter_utf8_peek(&iter)), fy_token_atom_lb_mode(fyt))) { + nrbreaks++; + (void)fy_atom_iter_utf8_get(&iter); + } + + /* NOTE: Because the number of indents is tricky + * if it's a non blank, non end, it's the number of breaks + * if it's a blank, it's the number of breaks minus 1 + * if it's the end, it's the number of breaks minus 2 + */ + nrbreakslim = fy_is_z(c) ? 2 : fy_is_blank(c) ? 1 : 0; + while (nrbreaks-- > nrbreakslim) { + emit->flags &= ~FYEF_INDENTATION; + fy_emit_write_indent(emit, indent); + } + + breaks = true; + + } else { + + /* if we had a break, output an indent */ + if (breaks) { + fy_emit_write_indent(emit, indent); + + /* if this line starts with whitespace we need to know */ + leading_spaces = fy_is_ws(c); + } + + if (!breaks && fy_is_space(c) && + !fy_is_space(fy_atom_iter_utf8_peek(&iter)) && + fy_emit_accum_column(&emit->ea) > fy_emit_width(emit)) { + fy_emit_output_accum(emit, fyewt_folded_scalar, &emit->ea); + emit->flags &= ~FYEF_INDENTATION; + fy_emit_write_indent(emit, indent); + } else + fy_emit_accum_utf8_put(&emit->ea, c); + + breaks = false; + } + } + fy_emit_output_accum(emit, fyewt_folded_scalar, &emit->ea); + fy_emit_accum_finish(&emit->ea); + fy_atom_iter_finish(&iter); +} + +static enum fy_node_style +fy_emit_token_scalar_style(struct fy_emitter *emit, struct fy_token *fyt, + int flags, int indent, enum fy_node_style style, + struct fy_token *fyt_tag) +{ + const char *value = NULL; + size_t len = 0; + bool json, flow, is_json_plain; + struct fy_atom *atom; + int aflags = -1; + const char *tag; + size_t tag_len; + + atom = fy_token_atom(fyt); + + flow = fy_emit_is_flow_mode(emit) || (flags & DDNF_FLOW); + + /* check if style is allowed (i.e. no block styles in flow context) */ + if (flow && (style == FYNS_LITERAL || style == FYNS_FOLDED)) + style = FYNS_ANY; + + json = fy_emit_is_json_mode(emit); + + /* literal in JSON mode is output as quoted */ + 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)) && + (!atom || atom->size0 || + !fy_atom_strcmp(atom, "false") || + !fy_atom_strcmp(atom, "true") || + !fy_atom_strcmp(atom, "null") || + fy_atom_is_number(atom)); + + if (is_json_plain) { + tag = fy_token_get_text(fyt_tag, &tag_len); + + /* XXX hardcoded string tag resultion */ + if (tag && tag_len && + ((tag_len == 1 && *tag == '!') || + (tag_len == 21 && !memcmp(tag, "tag:yaml.org,2002:str", 21)))) + return FYNS_DOUBLE_QUOTED; + } + + /* 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) + return FYNS_PLAIN; + + if (json) + return FYNS_DOUBLE_QUOTED; + + aflags = fy_token_text_analyze(fyt); + + if (flow && (style == FYNS_ANY || style == FYNS_LITERAL || style == FYNS_FOLDED)) { + + if (fyt && !value) + value = fy_token_get_text(fyt, &len); + + /* if there's a linebreak, use double quoted style */ + if (fy_find_any_lb(value, len)) { + style = FYNS_DOUBLE_QUOTED; + goto out; + } + + /* check if there's a non printable */ + if (!fy_find_non_print(value, len)) { + style = FYNS_SINGLE_QUOTED; + goto out; + } + + /* anything not empty is double quoted here */ + style = !(aflags & FYTTAF_EMPTY) ? FYNS_PLAIN : FYNS_DOUBLE_QUOTED; + } + + 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)) + style = FYNS_PLAIN; + } + +out: + if (style == FYNS_ANY) { + if (fyt) + value = fy_token_get_text(fyt, &len); + + style = (aflags & FYTTAF_CAN_BE_PLAIN) ? + FYNS_PLAIN : FYNS_DOUBLE_QUOTED; + } + + /* special handling for plains on start of line */ + if ((aflags & FYTTAF_QUOTE_AT_0) && indent == 0 && style == FYNS_PLAIN) + style = FYNS_DOUBLE_QUOTED; + + return style; +} + +void fy_emit_token_scalar(struct fy_emitter *emit, struct fy_token *fyt, int flags, int indent, + enum fy_node_style style, struct fy_token *fyt_tag) +{ + assert(style != FYNS_FLOW && style != FYNS_BLOCK); + + indent = fy_emit_increase_indent(emit, flags, indent); + + if (!fy_emit_whitespace(emit)) + fy_emit_write_ws(emit); + + style = fy_emit_token_scalar_style(emit, fyt, flags, indent, style, fyt_tag); + + switch (style) { + case FYNS_ALIAS: + fy_emit_token_write_alias(emit, fyt, flags, indent); + break; + case FYNS_PLAIN: + fy_emit_token_write_plain(emit, fyt, flags, indent); + break; + case FYNS_DOUBLE_QUOTED: + fy_emit_token_write_quoted(emit, fyt, flags, indent, '"'); + break; + case FYNS_SINGLE_QUOTED: + fy_emit_token_write_quoted(emit, fyt, flags, indent, '\''); + break; + case FYNS_LITERAL: + fy_emit_token_write_literal(emit, fyt, flags, indent); + break; + case FYNS_FOLDED: + fy_emit_token_write_folded(emit, fyt, flags, indent); + break; + default: + break; + } +} + +void fy_emit_scalar(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent, bool is_key) +{ + enum fy_node_style style; + + /* default style */ + style = fyn ? fyn->style : FYNS_ANY; + + /* all JSON keys are double quoted */ + if (fy_emit_is_json_mode(emit) && is_key) + style = FYNS_DOUBLE_QUOTED; + + fy_emit_token_scalar(emit, + fyn ? fyn->scalar : NULL, + flags, indent, + style, fyn->tag); +} + +static void fy_emit_sequence_prolog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc) +{ + bool json = fy_emit_is_json_mode(emit); + bool oneline = fy_emit_is_oneline(emit); + + sc->old_indent = sc->indent; + if (!json) { + if (fy_emit_is_block_mode(emit)) + sc->flow = sc->empty; + else + sc->flow = fy_emit_is_flow_mode(emit) || emit->flow_level || sc->flow_token || sc->empty; + + if (sc->flow) { + if (!emit->flow_level) { + sc->indent = fy_emit_increase_indent(emit, sc->flags, sc->indent); + sc->old_indent = sc->indent; + } + + sc->flags = (sc->flags | DDNF_FLOW) | (sc->flags & ~DDNF_INDENTLESS); + fy_emit_write_indicator(emit, di_left_bracket, sc->flags, sc->indent, fyewt_indicator); + } else { + sc->flags = (sc->flags & ~DDNF_FLOW); + } + } else { + sc->flags = (sc->flags | DDNF_FLOW) | (sc->flags & ~DDNF_INDENTLESS); + 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); + + sc->flags &= ~DDNF_ROOT; +} + +static void fy_emit_sequence_epilog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc) +{ + if (sc->flow || fy_emit_is_json_mode(emit)) { + if (!fy_emit_is_oneline(emit) && !sc->empty) + fy_emit_write_indent(emit, sc->old_indent); + fy_emit_write_indicator(emit, di_right_bracket, sc->flags, sc->old_indent, fyewt_indicator); + } +} + +static void fy_emit_sequence_item_prolog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc, + struct fy_token *fyt_value) +{ + int tmp_indent; + + sc->flags |= DDNF_SEQ; + + if (!fy_emit_is_oneline(emit)) + fy_emit_write_indent(emit, sc->indent); + + if (!sc->flow && !fy_emit_is_json_mode(emit)) + fy_emit_write_indicator(emit, di_dash, sc->flags, sc->indent, fyewt_indicator); + + tmp_indent = sc->indent; + if (fy_emit_token_has_comment(emit, fyt_value, fycp_top)) { + if (!sc->flow && !fy_emit_is_json_mode(emit)) + tmp_indent = fy_emit_increase_indent(emit, sc->flags, sc->indent); + fy_emit_token_comment(emit, fyt_value, sc->flags, tmp_indent, fycp_top); + } +} + +static void fy_emit_sequence_item_epilog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc, + bool last, struct fy_token *fyt_value) +{ + if ((sc->flow || fy_emit_is_json_mode(emit)) && !last) + fy_emit_write_indicator(emit, di_comma, sc->flags, sc->indent, fyewt_indicator); + + fy_emit_token_comment(emit, fyt_value, sc->flags, sc->indent, fycp_right); + + if (last && (sc->flow || fy_emit_is_json_mode(emit)) && !fy_emit_is_oneline(emit) && !sc->empty) + fy_emit_write_indent(emit, sc->old_indent); + + sc->flags &= ~DDNF_SEQ; +} + +void fy_emit_sequence(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent) +{ + struct fy_node *fyni, *fynin; + struct fy_token *fyt_value; + bool last; + struct fy_emit_save_ctx sct, *sc = &sct; + + memset(sc, 0, sizeof(*sc)); + + sc->flags = flags; + sc->indent = indent; + sc->empty = fy_node_list_empty(&fyn->sequence); + sc->flow_token = fyn->style == FYNS_FLOW; + sc->flow = !!(flags & DDNF_FLOW); + sc->old_indent = sc->indent; + + fy_emit_sequence_prolog(emit, sc); + + for (fyni = fy_node_list_head(&fyn->sequence); fyni; fyni = fynin) { + + fynin = fy_node_next(&fyn->sequence, fyni); + last = !fynin; + 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_sequence_item_epilog(emit, sc, last, fyt_value); + } + + fy_emit_sequence_epilog(emit, sc); +} + +static void fy_emit_mapping_prolog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc) +{ + bool json = fy_emit_is_json_mode(emit); + bool oneline = fy_emit_is_oneline(emit); + + sc->old_indent = sc->indent; + if (!json) { + if (fy_emit_is_block_mode(emit)) + sc->flow = sc->empty; + else + sc->flow = fy_emit_is_flow_mode(emit) || emit->flow_level || sc->flow_token || sc->empty; + + if (sc->flow) { + if (!emit->flow_level) { + sc->indent = fy_emit_increase_indent(emit, sc->flags, sc->indent); + sc->old_indent = sc->indent; + } + + sc->flags = (sc->flags | DDNF_FLOW) | (sc->flags & ~DDNF_INDENTLESS); + fy_emit_write_indicator(emit, di_left_brace, sc->flags, sc->indent, fyewt_indicator); + } else { + sc->flags &= ~(DDNF_FLOW | DDNF_INDENTLESS); + } + } else { + sc->flags = (sc->flags | DDNF_FLOW) | (sc->flags & ~DDNF_INDENTLESS); + fy_emit_write_indicator(emit, di_left_brace, sc->flags, sc->indent, fyewt_indicator); + } + + if (!oneline && !sc->empty) + sc->indent = fy_emit_increase_indent(emit, sc->flags, sc->indent); + + sc->flags &= ~DDNF_ROOT; +} + +static void fy_emit_mapping_epilog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc) +{ + if (sc->flow || fy_emit_is_json_mode(emit)) { + if (!fy_emit_is_oneline(emit) && !sc->empty) + fy_emit_write_indent(emit, sc->old_indent); + fy_emit_write_indicator(emit, di_right_brace, sc->flags, sc->old_indent, fyewt_indicator); + } +} + +static void fy_emit_mapping_key_prolog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc, + struct fy_token *fyt_key, bool simple_key) +{ + sc->flags = DDNF_MAP | (sc->flags & DDNF_FLOW); + + if (simple_key) { + sc->flags |= DDNF_SIMPLE; + if (fyt_key && fyt_key->type == FYTT_SCALAR) + sc->flags |= DDNF_SIMPLE_SCALAR_KEY; + } else { + /* do not emit the ? in flow modes at all */ + if (fy_emit_is_flow_mode(emit)) + sc->flags |= DDNF_SIMPLE; + } + + if (!fy_emit_is_oneline(emit)) + fy_emit_write_indent(emit, sc->indent); + + /* complex? */ + if (!(sc->flags & DDNF_SIMPLE)) + fy_emit_write_indicator(emit, di_question_mark, sc->flags, sc->indent, fyewt_indicator); +} + +static void fy_emit_mapping_key_epilog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc, + struct fy_token *fyt_key) +{ + int tmp_indent; + + /* if the key is an alias, always output an extra whitespace */ + if (fyt_key && fyt_key->type == FYTT_ALIAS) + fy_emit_write_ws(emit); + + sc->flags &= ~DDNF_MAP; + + fy_emit_write_indicator(emit, di_colon, sc->flags, sc->indent, fyewt_indicator); + + tmp_indent = sc->indent; + if (fy_emit_token_has_comment(emit, fyt_key, fycp_right)) { + + if (!sc->flow && !fy_emit_is_json_mode(emit)) + tmp_indent = fy_emit_increase_indent(emit, sc->flags, sc->indent); + + fy_emit_token_comment(emit, fyt_key, sc->flags, tmp_indent, fycp_right); + fy_emit_write_indent(emit, tmp_indent); + } + + sc->flags = DDNF_MAP | (sc->flags & DDNF_FLOW); +} + +static void fy_emit_mapping_value_prolog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc, + struct fy_token *fyt_value) +{ + /* nothing */ +} + +static void fy_emit_mapping_value_epilog(struct fy_emitter *emit, struct fy_emit_save_ctx *sc, + bool last, struct fy_token *fyt_value) +{ + if ((sc->flow || fy_emit_is_json_mode(emit)) && !last) + fy_emit_write_indicator(emit, di_comma, sc->flags, sc->indent, fyewt_indicator); + + fy_emit_token_comment(emit, fyt_value, sc->flags, sc->indent, fycp_right); + + if (last && (sc->flow || fy_emit_is_json_mode(emit)) && !fy_emit_is_oneline(emit) && !sc->empty) + fy_emit_write_indent(emit, sc->old_indent); + + sc->flags &= ~DDNF_MAP; +} + +void fy_emit_mapping(struct fy_emitter *emit, struct fy_node *fyn, int flags, int indent) +{ + struct fy_node_pair *fynp, *fynpn, **fynpp = NULL; + struct fy_token *fyt_key, *fyt_value; + bool last, simple_key; + int aflags, i; + struct fy_emit_save_ctx sct, *sc = &sct; + + memset(sc, 0, sizeof(*sc)); + + sc->flags = flags; + sc->indent = indent; + sc->empty = fy_node_pair_list_empty(&fyn->mapping); + sc->flow_token = fyn->style == FYNS_FLOW; + sc->flow = !!(flags & DDNF_FLOW); + sc->old_indent = sc->indent; + + fy_emit_mapping_prolog(emit, sc); + + if (!(emit->cfg.flags & FYECF_SORT_KEYS)) { + fynp = fy_node_pair_list_head(&fyn->mapping); + fynpp = NULL; + } else { + fynpp = fy_node_mapping_sort_array(fyn, NULL, NULL, NULL); + i = 0; + fynp = fynpp[i]; + } + + for (; fynp; fynp = fynpn) { + + if (!fynpp) + fynpn = fy_node_pair_next(&fyn->mapping, fynp); + else + fynpn = fynpp[++i]; + + last = !fynpn; + fyt_key = fy_node_value_token(fynp->key); + fyt_value = fy_node_value_token(fynp->value); + + FYD_NODE_ERROR_CHECK(fynp->fyd, fynp->key, FYEM_INTERNAL, + !fy_emit_is_json_mode(emit) || + (fynp->key && fynp->key->type == FYNT_SCALAR), + err_out, "Non scalar keys are not allowed in JSON emit mode"); + + simple_key = false; + if (fynp->key) { + switch (fynp->key->type) { + case FYNT_SCALAR: + aflags = fy_token_text_analyze(fynp->key->scalar); + simple_key = fy_emit_is_json_mode(emit) || + !!(aflags & FYTTAF_CAN_BE_SIMPLE_KEY); + break; + case FYNT_SEQUENCE: + simple_key = fy_node_list_empty(&fynp->key->sequence); + break; + case FYNT_MAPPING: + simple_key = fy_node_pair_list_empty(&fynp->key->mapping); + break; + } + } + + 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_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_mapping_value_epilog(emit, sc, last, fyt_value); + } + + if (fynpp) + fy_node_mapping_sort_release_array(fyn, fynpp); + + fy_emit_mapping_epilog(emit, sc); + +err_out: + return; +} + +int fy_emit_common_document_start(struct fy_emitter *emit, + struct fy_document_state *fyds, + bool root_tag_or_anchor) +{ + struct fy_token *fyt_chk; + const char *td_handle, *td_prefix; + size_t td_handle_size, td_prefix_size; + enum fy_emitter_cfg_flags flags = emit->cfg.flags; + enum fy_emitter_cfg_flags vd_flags = flags & FYECF_VERSION_DIR(FYECF_VERSION_DIR_MASK); + enum fy_emitter_cfg_flags td_flags = flags & FYECF_TAG_DIR(FYECF_TAG_DIR_MASK); + enum fy_emitter_cfg_flags dsm_flags = flags & FYECF_DOC_START_MARK(FYECF_DOC_START_MARK_MASK); + bool vd, td, dsm; + bool had_non_default_tag = false; + + if (!emit || !fyds || emit->fyds) + return -1; + + emit->fyds = fyds; + + vd = ((vd_flags == FYECF_VERSION_DIR_AUTO && fyds->version_explicit) || + vd_flags == FYECF_VERSION_DIR_ON) && + !(emit->cfg.flags & FYECF_STRIP_DOC); + td = ((td_flags == FYECF_TAG_DIR_AUTO && fyds->tags_explicit) || + td_flags == FYECF_TAG_DIR_ON) && + !(emit->cfg.flags & FYECF_STRIP_DOC); + + /* if either a version or directive tags exist, and no previous + * explicit document end existed, output one now + */ + if (!fy_emit_is_json_mode(emit) && (vd || td) && !(emit->flags & FYEF_HAD_DOCUMENT_END)) { + 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_END; + } + } + + if (!fy_emit_is_json_mode(emit) && vd) { + if (emit->column) + fy_emit_putc(emit, fyewt_linebreak, '\n'); + fy_emit_printf(emit, fyewt_version_directive, "%%YAML %d.%d", + fyds->version.major, fyds->version.minor); + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + + if (!fy_emit_is_json_mode(emit) && td) { + + for (fyt_chk = fy_token_list_first(&fyds->fyt_td); fyt_chk; fyt_chk = fy_token_next(&fyds->fyt_td, fyt_chk)) { + + td_handle = fy_tag_directive_token_handle(fyt_chk, &td_handle_size); + td_prefix = fy_tag_directive_token_prefix(fyt_chk, &td_prefix_size); + assert(td_handle && td_prefix); + + if (fy_tag_is_default_internal(td_handle, td_handle_size, td_prefix, td_prefix_size)) + continue; + + had_non_default_tag = true; + + if (emit->column) + fy_emit_putc(emit, fyewt_linebreak, '\n'); + fy_emit_printf(emit, fyewt_tag_directive, "%%TAG %.*s %.*s", + (int)td_handle_size, td_handle, + (int)td_prefix_size, td_prefix); + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + } + + /* always output document start indicator: + * - was explicit + * - document has tags + * - document has an explicit version + * - root exists & has a tag or an anchor + */ + dsm = (dsm_flags == FYECF_DOC_START_MARK_AUTO && + (!fyds->start_implicit || + fyds->tags_explicit || fyds->version_explicit || + had_non_default_tag)) || + dsm_flags == FYECF_DOC_START_MARK_ON; + + /* if there was previous output without document end */ + if (!dsm && (emit->flags & FYEF_HAD_DOCUMENT_OUTPUT) && + !(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; + + /* clear that in any case */ + emit->flags &= ~FYEF_HAD_DOCUMENT_END; + + return 0; +} + +int fy_emit_document_start(struct fy_emitter *emit, struct fy_document *fyd, + struct fy_node *fyn_root) +{ + struct fy_node *root; + bool root_tag_or_anchor; + int ret; + + if (!emit || !fyd || !fyd->fyds) + return -1; + + root = fyn_root ? : fy_document_root(fyd); + + root_tag_or_anchor = root && (root->tag || fy_document_lookup_anchor_by_node(fyd, root)); + + ret = fy_emit_common_document_start(emit, fyd->fyds, root_tag_or_anchor); + if (ret) + return ret; + + emit->fyd = fyd; + + return 0; +} + +int fy_emit_common_document_end(struct fy_emitter *emit) +{ + 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; + + if (!emit || !emit->fyds) + return -1; + + fyds = emit->fyds; + + dem = ((dem_flags == FYECF_DOC_END_MARK_AUTO && !fyds->end_implicit) || + dem_flags == FYECF_DOC_END_MARK_ON) && + !(emit->cfg.flags & FYECF_STRIP_DOC); + + if (!(emit->cfg.flags & FYECF_NO_ENDING_NEWLINE)) { + if (emit->column != 0) { + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + + if (!fy_emit_is_json_mode(emit) && dem) { + fy_emit_puts(emit, fyewt_document_indicator, "..."); + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + emit->flags |= FYEF_HAD_DOCUMENT_END; + } else + emit->flags &= ~FYEF_HAD_DOCUMENT_END; + } else { + if (!fy_emit_is_json_mode(emit) && dem) { + if (emit->column != 0) { + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + fy_emit_puts(emit, fyewt_document_indicator, "..."); + emit->flags &= ~(FYEF_WHITESPACE | FYEF_INDENTATION); + emit->flags |= FYEF_HAD_DOCUMENT_END; + } else + emit->flags &= ~FYEF_HAD_DOCUMENT_END; + } + + /* mark that we did output a document earlier */ + emit->flags |= FYEF_HAD_DOCUMENT_OUTPUT; + + /* stop our association with the document */ + emit->fyds = NULL; + + return 0; +} + +int fy_emit_document_end(struct fy_emitter *emit) +{ + int ret; + + ret = fy_emit_common_document_end(emit); + if (ret) + return ret; + + emit->fyd = NULL; + return 0; +} + +int fy_emit_common_explicit_document_end(struct fy_emitter *emit) +{ + if (!emit) + return -1; + + if (emit->column != 0) { + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + + if (!fy_emit_is_json_mode(emit)) { + fy_emit_puts(emit, fyewt_document_indicator, "..."); + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + emit->flags |= FYEF_HAD_DOCUMENT_END; + } else + emit->flags &= ~FYEF_HAD_DOCUMENT_END; + + /* mark that we did output a document earlier */ + emit->flags |= FYEF_HAD_DOCUMENT_OUTPUT; + + /* stop our association with the document */ + emit->fyds = NULL; + + return 0; +} + +int fy_emit_explicit_document_end(struct fy_emitter *emit) +{ + int ret; + + ret = fy_emit_common_explicit_document_end(emit); + if (ret) + return ret; + + emit->fyd = NULL; + return 0; +} + +void fy_emit_reset(struct fy_emitter *emit, bool reset_events) +{ + struct fy_eventp *fyep; + + emit->line = 0; + emit->column = 0; + emit->flow_level = 0; + emit->output_error = 0; + /* start as if there was a previous document with an explicit end */ + /* this allows implicit documents start without an indicator */ + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION | FYEF_HAD_DOCUMENT_END; + + emit->state = FYES_NONE; + + /* reset the accumulator */ + fy_emit_accum_reset(&emit->ea); + + /* streaming mode indent */ + emit->s_indent = -1; + /* streaming mode flags */ + emit->s_flags = DDNF_ROOT; + + emit->state_stack_top = 0; + emit->sc_stack_top = 0; + + /* and release any queued events */ + if (reset_events) { + while ((fyep = fy_eventp_list_pop(&emit->queued_events)) != NULL) + fy_eventp_release(fyep); + } +} + +int fy_emit_setup(struct fy_emitter *emit, const struct fy_emitter_cfg *cfg) +{ + struct fy_diag *diag; + + if (!cfg) + return -1; + + memset(emit, 0, sizeof(*emit)); + + emit->cfg = *cfg; + if (!emit->cfg.output) + emit->cfg.output = fy_emitter_default_output; + + diag = cfg->diag; + + if (!diag) { + diag = fy_diag_create(NULL); + if (!diag) + return -1; + } else + fy_diag_ref(diag); + + emit->diag = diag; + + fy_emit_accum_init(&emit->ea, emit->ea_inplace_buf, sizeof(emit->ea_inplace_buf), 0, fylb_cr_nl); + fy_eventp_list_init(&emit->queued_events); + + emit->state_stack = emit->state_stack_inplace; + emit->state_stack_alloc = sizeof(emit->state_stack_inplace)/sizeof(emit->state_stack_inplace[0]); + + emit->sc_stack = emit->sc_stack_inplace; + emit->sc_stack_alloc = sizeof(emit->sc_stack_inplace)/sizeof(emit->sc_stack_inplace[0]); + + fy_eventp_list_init(&emit->recycled_eventp); + fy_token_list_init(&emit->recycled_token); + + fy_emit_reset(emit, false); + + return 0; +} + +void fy_emit_cleanup(struct fy_emitter *emit) +{ + struct fy_eventp *fyep; + struct fy_token *fyt; + + while ((fyt = fy_token_list_pop(&emit->recycled_token)) != NULL) + fy_token_free(fyt); + + fy_emit_eventp_vacuum(emit); + + if (!emit->fyd && emit->fyds) + fy_document_state_unref(emit->fyds); + + fy_emit_accum_cleanup(&emit->ea); + + while ((fyep = fy_eventp_list_pop(&emit->queued_events)) != NULL) + fy_eventp_release(fyep); + + if (emit->state_stack && emit->state_stack != emit->state_stack_inplace) + free(emit->state_stack); + + if (emit->sc_stack && emit->sc_stack != emit->sc_stack_inplace) + free(emit->sc_stack); + + fy_diag_unref(emit->diag); +} + +int fy_emit_node(struct fy_emitter *emit, struct fy_node *fyn) +{ + int ret; + + ret = fy_emit_node_check(emit, fyn); + if (ret) + return ret; + + if (fyn) + fy_emit_node_internal(emit, fyn, DDNF_ROOT, -1, false); + return 0; +} + +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; + + /* top comment first */ + fy_emit_node_comment(emit, fyn, DDNF_ROOT, -1, fycp_top); + + fy_emit_node_internal(emit, fyn, DDNF_ROOT, -1, false); + + /* right comment next */ + fy_emit_node_comment(emit, fyn, DDNF_ROOT, -1, fycp_right); + + /* bottom comment last */ + fy_emit_node_comment(emit, fyn, DDNF_ROOT, -1, fycp_bottom); + + return 0; +} + +int fy_emit_document(struct fy_emitter *emit, struct fy_document *fyd) +{ + int rc; + + rc = fy_emit_document_start(emit, fyd, NULL); + if (rc) + return rc; + + rc = fy_emit_root_node(emit, fyd->root); + if (rc) + return rc; + + rc = fy_emit_document_end(emit); + + return rc; +} + +struct fy_emitter *fy_emitter_create(const struct fy_emitter_cfg *cfg) +{ + struct fy_emitter *emit; + int rc; + + if (!cfg) + return NULL; + + emit = malloc(sizeof(*emit)); + if (!emit) + return NULL; + + rc = fy_emit_setup(emit, cfg); + if (rc) { + free(emit); + return NULL; + } + + return emit; +} + +void fy_emitter_destroy(struct fy_emitter *emit) +{ + if (!emit) + return; + + fy_emit_cleanup(emit); + + free(emit); +} + +const struct fy_emitter_cfg *fy_emitter_get_cfg(struct fy_emitter *emit) +{ + if (!emit) + return NULL; + + return &emit->cfg; +} + +struct fy_diag *fy_emitter_get_diag(struct fy_emitter *emit) +{ + if (!emit || !emit->diag) + return NULL; + return fy_diag_ref(emit->diag); +} + +int fy_emitter_set_diag(struct fy_emitter *emit, struct fy_diag *diag) +{ + struct fy_diag_cfg dcfg; + + if (!emit) + return -1; + + /* default? */ + if (!diag) { + fy_diag_cfg_default(&dcfg); + diag = fy_diag_create(&dcfg); + if (!diag) + return -1; + } + + fy_diag_unref(emit->diag); + emit->diag = fy_diag_ref(diag); + + return 0; +} + +struct fy_emit_buffer_state { + char *buf; + int size; + int pos; + int need; + bool grow; +}; + +static int do_buffer_output(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int len, void *userdata) +{ + struct fy_emit_buffer_state *state = emit->cfg.userdata; + int left; + int pagesize = 0; + int size; + char *bufnew; + + state->need += len; + left = state->size - state->pos; + if (left < len) { + if (!state->grow) + return 0; + + pagesize = sysconf(_SC_PAGESIZE); + size = state->need + pagesize - 1; + size = size - size % pagesize; + + bufnew = realloc(state->buf, size); + if (!bufnew) + return -1; + state->buf = bufnew; + state->size = size; + left = state->size - state->pos; + + } + + if (len > left) + len = left; + if (state->buf) + memcpy(state->buf + state->pos, str, len); + state->pos += len; + + 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) +{ + struct fy_emitter emit_state, *emit = &emit_state; + struct fy_emitter_cfg emit_cfg; + struct fy_emit_buffer_state state; + int rc = -1; + + memset(&emit_cfg, 0, sizeof(emit_cfg)); + memset(&state, 0, sizeof(state)); + + emit_cfg.output = do_buffer_output; + 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); + + if (rc) + goto out_err; + + /* terminating zero */ + rc = do_buffer_output(emit, fyewt_terminating_zero, "\0", 1, emit->cfg.userdata); + + if (rc != 1) { + rc = -1; + goto out_err; + } + + *sizep = state.need; + + if (!grow) + return 0; + + *bufp = realloc(state.buf, *sizep); + if (!*bufp) { + rc = -1; + goto out_err; + } + + return 0; + +out_err: + if (grow && state.buf) + free(state.buf); + *bufp = NULL; + *sizep = 0; + + return rc; +} + +int fy_emit_document_to_buffer(struct fy_document *fyd, enum fy_emitter_cfg_flags flags, char *buf, int size) +{ + int rc; + + rc = fy_emit_str_internal(fyd, flags, NULL, &buf, &size, false); + if (rc != 0) + return -1; + return size; +} + +char *fy_emit_document_to_string(struct fy_document *fyd, enum fy_emitter_cfg_flags flags) +{ + char *buf = NULL; + int rc, 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) +{ + FILE *fp = userdata; + + return fwrite(str, 1, len, fp); +} + +int fy_emit_document_to_fp(struct fy_document *fyd, enum fy_emitter_cfg_flags flags, + FILE *fp) +{ + struct fy_emitter emit_state, *emit = &emit_state; + struct fy_emitter_cfg emit_cfg; + int rc; + + if (!fp) + return -1; + + memset(&emit_cfg, 0, sizeof(emit_cfg)); + emit_cfg.output = do_file_output; + emit_cfg.userdata = fp; + emit_cfg.flags = flags; + fy_emit_setup(emit, &emit_cfg); + rc = fy_emit_document(emit, fyd); + fy_emit_cleanup(emit); + + return rc ? rc : 0; +} + +int fy_emit_document_to_file(struct fy_document *fyd, + enum fy_emitter_cfg_flags flags, + const char *filename) +{ + FILE *fp; + int rc; + + fp = filename ? fopen(filename, "wa") : stdout; + if (!fp) + return -1; + + rc = fy_emit_document_to_fp(fyd, flags, fp); + + if (fp != stdout) + fclose(fp); + + return rc ? rc : 0; +} + +int fy_emit_node_to_buffer(struct fy_node *fyn, enum fy_emitter_cfg_flags flags, char *buf, int size) +{ + int rc; + + rc = fy_emit_str_internal(NULL, flags, fyn, &buf, &size, false); + if (rc != 0) + return -1; + return size; +} + +char *fy_emit_node_to_string(struct fy_node *fyn, enum fy_emitter_cfg_flags flags) +{ + char *buf = NULL; + int rc, size = 0; + + rc = fy_emit_str_internal(NULL, flags, fyn, &buf, &size, true); + if (rc != 0) + return NULL; + return buf; +} + +static bool fy_emit_ready(struct fy_emitter *emit) +{ + struct fy_eventp *fyep; + int need, count, level; + + /* no events in the list, not ready */ + fyep = fy_eventp_list_head(&emit->queued_events); + if (!fyep) + return false; + + /* some events need more than one */ + switch (fyep->e.type) { + case FYET_DOCUMENT_START: + need = 1; + break; + case FYET_SEQUENCE_START: + need = 2; + break; + case FYET_MAPPING_START: + need = 3; + break; + default: + need = 0; + break; + } + + /* if we don't need any more, that's enough */ + if (!need) + return true; + + level = 0; + count = 0; + for (; fyep; fyep = fy_eventp_next(&emit->queued_events, fyep)) { + count++; + + if (count > need) + return true; + + switch (fyep->e.type) { + case FYET_STREAM_START: + case FYET_DOCUMENT_START: + case FYET_SEQUENCE_START: + case FYET_MAPPING_START: + level++; + break; + case FYET_STREAM_END: + case FYET_DOCUMENT_END: + case FYET_SEQUENCE_END: + case FYET_MAPPING_END: + level--; + break; + default: + break; + } + + if (!level) + return true; + } + + return false; +} + +extern const char *fy_event_type_txt[]; + +const char *fy_emitter_state_txt[] = { + [FYES_NONE] = "NONE", + [FYES_STREAM_START] = "STREAM_START", + [FYES_FIRST_DOCUMENT_START] = "FIRST_DOCUMENT_START", + [FYES_DOCUMENT_START] = "DOCUMENT_START", + [FYES_DOCUMENT_CONTENT] = "DOCUMENT_CONTENT", + [FYES_DOCUMENT_END] = "DOCUMENT_END", + [FYES_SEQUENCE_FIRST_ITEM] = "SEQUENCE_FIRST_ITEM", + [FYES_SEQUENCE_ITEM] = "SEQUENCE_ITEM", + [FYES_MAPPING_FIRST_KEY] = "MAPPING_FIRST_KEY", + [FYES_MAPPING_KEY] = "MAPPING_KEY", + [FYES_MAPPING_SIMPLE_VALUE] = "MAPPING_SIMPLE_VALUE", + [FYES_MAPPING_VALUE] = "MAPPING_VALUE", + [FYES_END] = "END", +}; + +struct fy_eventp * +fy_emit_next_event(struct fy_emitter *emit) +{ + if (!fy_emit_ready(emit)) + return NULL; + + return fy_eventp_list_pop(&emit->queued_events); +} + +struct fy_eventp * +fy_emit_peek_next_event(struct fy_emitter *emit) +{ + if (!fy_emit_ready(emit)) + return NULL; + + return fy_eventp_list_head(&emit->queued_events); +} + +bool fy_emit_streaming_sequence_empty(struct fy_emitter *emit) +{ + struct fy_eventp *fyepn; + struct fy_event *fyen; + + fyepn = fy_emit_peek_next_event(emit); + fyen = fyepn ? &fyepn->e : NULL; + + return !fyen || fyen->type == FYET_SEQUENCE_END; +} + +bool fy_emit_streaming_mapping_empty(struct fy_emitter *emit) +{ + struct fy_eventp *fyepn; + struct fy_event *fyen; + + fyepn = fy_emit_peek_next_event(emit); + fyen = fyepn ? &fyepn->e : NULL; + + return !fyen || fyen->type == FYET_MAPPING_END; +} + +static void fy_emit_goto_state(struct fy_emitter *emit, enum fy_emitter_state state) +{ + if (emit->state == state) + return; + + emit->state = state; +} + +static int fy_emit_push_state(struct fy_emitter *emit, enum fy_emitter_state state) +{ + enum fy_emitter_state *states; + + if (emit->state_stack_top >= emit->state_stack_alloc) { + states = realloc(emit->state_stack == emit->state_stack_inplace ? NULL : emit->state_stack, + sizeof(emit->state_stack[0]) * emit->state_stack_alloc * 2); + if (!states) + return -1; + + if (emit->state_stack == emit->state_stack_inplace) + memcpy(states, emit->state_stack, sizeof(emit->state_stack[0]) * emit->state_stack_top); + emit->state_stack = states; + emit->state_stack_alloc *= 2; + } + emit->state_stack[emit->state_stack_top++] = state; + + return 0; +} + +enum fy_emitter_state fy_emit_pop_state(struct fy_emitter *emit) +{ + if (!emit->state_stack_top) + return FYES_NONE; + + return emit->state_stack[--emit->state_stack_top]; +} + +int fy_emit_push_sc(struct fy_emitter *emit, struct fy_emit_save_ctx *sc) +{ + struct fy_emit_save_ctx *scs; + + if (emit->sc_stack_top >= emit->sc_stack_alloc) { + scs = realloc(emit->sc_stack == emit->sc_stack_inplace ? NULL : emit->sc_stack, + sizeof(emit->sc_stack[0]) * emit->sc_stack_alloc * 2); + if (!scs) + return -1; + + if (emit->sc_stack == emit->sc_stack_inplace) + memcpy(scs, emit->sc_stack, sizeof(emit->sc_stack[0]) * emit->sc_stack_top); + emit->sc_stack = scs; + emit->sc_stack_alloc *= 2; + } + emit->sc_stack[emit->sc_stack_top++] = *sc; + + return 0; +} + +int fy_emit_pop_sc(struct fy_emitter *emit, struct fy_emit_save_ctx *sc) +{ + if (!emit->sc_stack_top) + return -1; + + *sc = emit->sc_stack[--emit->sc_stack_top]; + + return 0; +} + +static int fy_emit_streaming_node(struct fy_emitter *emit, struct fy_eventp *fyep, int flags) +{ + struct fy_event *fye = &fyep->e; + struct fy_emit_save_ctx *sc = &emit->s_sc; + enum fy_node_style style; + int ret, s_flags, s_indent; + + if (fye->type != FYET_ALIAS && fye->type != FYET_SCALAR && + (emit->s_flags & DDNF_ROOT) && emit->column != 0) { + fy_emit_putc(emit, fyewt_linebreak, '\n'); + emit->flags = FYEF_WHITESPACE | FYEF_INDENTATION; + } + + emit->s_flags = flags; + + switch (fye->type) { + case FYET_ALIAS: + fy_emit_token_write_alias(emit, fye->alias.anchor, emit->s_flags, emit->s_indent); + fy_emit_goto_state(emit, fy_emit_pop_state(emit)); + break; + + case FYET_SCALAR: + 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) : + FYNS_PLAIN; + fy_emit_token_scalar(emit, fye->scalar.value, emit->s_flags, emit->s_indent, style, fye->scalar.tag); + fy_emit_goto_state(emit, fy_emit_pop_state(emit)); + break; + + case FYET_SEQUENCE_START: + + /* save this context */ + ret = fy_emit_push_sc(emit, sc); + if (ret) + return ret; + + s_flags = emit->s_flags; + s_indent = emit->s_indent; + + fy_emit_common_node_preamble(emit, fye->sequence_start.anchor, fye->sequence_start.tag, emit->s_flags, emit->s_indent); + + /* create new context */ + memset(sc, 0, sizeof(*sc)); + sc->flags = DDNF_SEQ | (emit->s_flags & DDNF_ROOT); + sc->indent = emit->s_indent; + sc->empty = fy_emit_streaming_sequence_empty(emit); + sc->flow_token = fye->sequence_start.sequence_start && + fye->sequence_start.sequence_start->type == FYTT_FLOW_SEQUENCE_START; + sc->flow = !!(s_flags & DDNF_FLOW); + sc->old_indent = sc->indent; + sc->s_flags = s_flags; + sc->s_indent = s_indent; + sc->s_flags = s_flags; + sc->s_indent = s_indent; + + fy_emit_sequence_prolog(emit, sc); + + emit->s_flags = sc->flags; + emit->s_indent = sc->indent; + + fy_emit_goto_state(emit, FYES_SEQUENCE_FIRST_ITEM); + break; + + case FYET_MAPPING_START: + /* save this context */ + ret = fy_emit_push_sc(emit, sc); + if (ret) + return ret; + + s_flags = emit->s_flags; + s_indent = emit->s_indent; + + fy_emit_common_node_preamble(emit, fye->mapping_start.anchor, fye->mapping_start.tag, emit->s_flags, emit->s_indent); + + /* create new context */ + memset(sc, 0, sizeof(*sc)); + sc->flags = DDNF_MAP | (emit->s_flags & DDNF_ROOT); + sc->indent = emit->s_indent; + sc->empty = fy_emit_streaming_mapping_empty(emit); + sc->flow_token = fye->mapping_start.mapping_start && + fye->mapping_start.mapping_start->type == FYTT_FLOW_MAPPING_START; + sc->flow = !!(s_flags & DDNF_FLOW); + sc->old_indent = sc->indent; + sc->s_flags = s_flags; + sc->s_indent = s_indent; + sc->s_flags = s_flags; + sc->s_indent = s_indent; + + fy_emit_mapping_prolog(emit, sc); + + emit->s_flags = sc->flags; + emit->s_indent = sc->indent; + + fy_emit_goto_state(emit, FYES_MAPPING_FIRST_KEY); + break; + + default: + fy_error(emit->diag, "%s: expected ALIAS|SCALAR|SEQUENCE_START|MAPPING_START", __func__); + return -1; + } + + return 0; +} + +static int fy_emit_handle_stream_start(struct fy_emitter *emit, struct fy_eventp *fyep) +{ + struct fy_event *fye = &fyep->e; + + if (fye->type != FYET_STREAM_START) { + fy_error(emit->diag, "%s: expected FYET_STREAM_START", __func__); + return -1; + } + + fy_emit_reset(emit, false); + + fy_emit_goto_state(emit, FYES_FIRST_DOCUMENT_START); + + return 0; +} + +static int fy_emit_handle_document_start(struct fy_emitter *emit, struct fy_eventp *fyep, bool first) +{ + struct fy_event *fye = &fyep->e; + struct fy_document_state *fyds; + + if (fye->type != FYET_DOCUMENT_START && + fye->type != FYET_STREAM_END) { + fy_error(emit->diag, "%s: expected FYET_DOCUMENT_START|FYET_STREAM_END", __func__); + return -1; + } + + if (fye->type == FYET_STREAM_END) { + fy_emit_goto_state(emit, FYES_END); + return 0; + } + + /* transfer ownership to the emitter */ + fyds = fye->document_start.document_state; + fye->document_start.document_state = NULL; + + 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; + struct fy_event *fye = &fyep->e; + int ret; + + if (fye->type != FYET_DOCUMENT_END) { + fy_error(emit->diag, "%s: expected FYET_DOCUMENT_END", __func__); + return -1; + } + + fyds = emit->fyds; + + ret = fy_emit_common_document_end(emit); + if (ret) + return ret; + + fy_document_state_unref(fyds); + + fy_emit_reset(emit, false); + fy_emit_goto_state(emit, FYES_DOCUMENT_START); + return 0; +} + +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_emit_save_ctx *sc = &emit->s_sc; + struct fy_token *fyt_item = NULL; + int ret; + + fy_token_unref_rl(&emit->recycled_token, sc->fyt_last_value); + sc->fyt_last_value = NULL; + + switch (fye->type) { + case FYET_SEQUENCE_END: + fy_emit_sequence_item_epilog(emit, sc, true, sc->fyt_last_value); + + /* emit epilog */ + fy_emit_sequence_epilog(emit, sc); + /* pop state */ + ret = fy_emit_pop_sc(emit, sc); + /* pop state */ + fy_emit_goto_state(emit, fy_emit_pop_state(emit)); + + /* restore indent and flags */ + emit->s_indent = sc->s_indent; + emit->s_flags = sc->s_flags; + return ret; + + case FYET_ALIAS: + fyt_item = fye->alias.anchor; + break; + case FYET_SCALAR: + fyt_item = fye->scalar.value; + break; + case FYET_SEQUENCE_START: + fyt_item = fye->sequence_start.sequence_start; + break; + case FYET_MAPPING_START: + fyt_item = fye->mapping_start.mapping_start; + break; + default: + fy_error(emit->diag, "%s: expected SEQUENCE_END|ALIAS|SCALAR|SEQUENCE_START|MAPPING_START", __func__); + return -1; + } + + ret = fy_emit_push_state(emit, FYES_SEQUENCE_ITEM); + if (ret) + return ret; + + /* reset indent and flags for each item */ + emit->s_indent = sc->indent; + emit->s_flags = sc->flags; + + if (!first) + fy_emit_sequence_item_epilog(emit, sc, false, sc->fyt_last_value); + + sc->fyt_last_value = fyt_item; + + fy_emit_sequence_item_prolog(emit, sc, fyt_item); + + ret = fy_emit_streaming_node(emit, fyep, sc->flags); + + switch (fye->type) { + case FYET_ALIAS: + fye->alias.anchor = NULL; /* take ownership */ + break; + case FYET_SCALAR: + fye->scalar.value = NULL; /* take ownership */ + break; + case FYET_SEQUENCE_START: + fye->sequence_start.sequence_start = NULL; /* take ownership */ + break; + case FYET_MAPPING_START: + fye->mapping_start.mapping_start = NULL; /* take ownership */ + break; + default: + break; + } + + return ret; +} + +static int fy_emit_handle_mapping_key(struct fy_emitter *emit, struct fy_eventp *fyep, bool first) +{ + struct fy_event *fye = &fyep->e; + struct fy_emit_save_ctx *sc = &emit->s_sc; + struct fy_token *fyt_key = NULL; + int ret, aflags; + bool simple_key; + + fy_token_unref_rl(&emit->recycled_token, sc->fyt_last_key); + sc->fyt_last_key = NULL; + fy_token_unref_rl(&emit->recycled_token, sc->fyt_last_value); + sc->fyt_last_value = NULL; + + simple_key = false; + + switch (fye->type) { + case FYET_MAPPING_END: + fy_emit_mapping_value_epilog(emit, sc, true, sc->fyt_last_value); + + /* emit epilog */ + fy_emit_mapping_epilog(emit, sc); + /* pop state */ + ret = fy_emit_pop_sc(emit, sc); + /* pop state */ + fy_emit_goto_state(emit, fy_emit_pop_state(emit)); + + /* restore indent and flags */ + emit->s_indent = sc->s_indent; + emit->s_flags = sc->s_flags; + return ret; + + case FYET_ALIAS: + fyt_key = fye->alias.anchor; + simple_key = true; + break; + case FYET_SCALAR: + fyt_key = fye->scalar.value; + aflags = fy_token_text_analyze(fyt_key); + simple_key = !!(aflags & FYTTAF_CAN_BE_SIMPLE_KEY); + break; + case FYET_SEQUENCE_START: + fyt_key = fye->sequence_start.sequence_start; + simple_key = fy_emit_streaming_sequence_empty(emit); + break; + case FYET_MAPPING_START: + fyt_key = fye->mapping_start.mapping_start; + simple_key = fy_emit_streaming_mapping_empty(emit); + break; + default: + fy_error(emit->diag, "%s: expected MAPPING_END|ALIAS|SCALAR|SEQUENCE_START|MAPPING_START", __func__); + return -1; + } + + ret = fy_emit_push_state(emit, FYES_MAPPING_VALUE); + if (ret) + return ret; + + /* reset indent and flags for each key/value pair */ + emit->s_indent = sc->indent; + emit->s_flags = sc->flags; + + if (!first) + fy_emit_mapping_value_epilog(emit, sc, false, sc->fyt_last_value); + + sc->fyt_last_key = fyt_key; + + fy_emit_mapping_key_prolog(emit, sc, fyt_key, simple_key); + + ret = fy_emit_streaming_node(emit, fyep, sc->flags); + + switch (fye->type) { + case FYET_ALIAS: + fye->alias.anchor = NULL; /* take ownership */ + break; + case FYET_SCALAR: + fye->scalar.value = NULL; /* take ownership */ + break; + case FYET_SEQUENCE_START: + fye->sequence_start.sequence_start = NULL; /* take ownership */ + break; + case FYET_MAPPING_START: + fye->mapping_start.mapping_start = NULL; /* take ownership */ + break; + default: + break; + } + + return ret; +} + +static int fy_emit_handle_mapping_value(struct fy_emitter *emit, struct fy_eventp *fyep, bool simple) +{ + struct fy_event *fye = &fyep->e; + struct fy_emit_save_ctx *sc = &emit->s_sc; + struct fy_token *fyt_value = NULL; + int ret; + + switch (fye->type) { + case FYET_ALIAS: + fyt_value = fye->alias.anchor; + break; + case FYET_SCALAR: + fyt_value = fye->scalar.value; /* take ownership */ + break; + case FYET_SEQUENCE_START: + fyt_value = fye->sequence_start.sequence_start; + break; + case FYET_MAPPING_START: + fyt_value = fye->mapping_start.mapping_start; + break; + default: + fy_error(emit->diag, "%s: expected ALIAS|SCALAR|SEQUENCE_START|MAPPING_START", __func__); + return -1; + } + + ret = fy_emit_push_state(emit, FYES_MAPPING_KEY); + if (ret) + return ret; + + fy_emit_mapping_key_epilog(emit, sc, sc->fyt_last_key); + + sc->fyt_last_value = fyt_value; + + fy_emit_mapping_value_prolog(emit, sc, fyt_value); + + ret = fy_emit_streaming_node(emit, fyep, sc->flags); + + switch (fye->type) { + case FYET_ALIAS: + fye->alias.anchor = NULL; /* take ownership */ + break; + case FYET_SCALAR: + fye->scalar.value = NULL; /* take ownership */ + break; + case FYET_SEQUENCE_START: + fye->sequence_start.sequence_start = NULL; /* take ownership */ + break; + case FYET_MAPPING_START: + fye->mapping_start.mapping_start = NULL; /* take ownership */ + break; + default: + break; + } + + return ret; +} + +int fy_emit_event_from_parser(struct fy_emitter *emit, struct fy_parser *fyp, struct fy_event *fye) +{ + struct fy_eventp *fyep; + int ret; + + if (!emit || !fye) + return -1; + + /* we're using the raw emitter interface, now mark first state */ + if (emit->state == FYES_NONE) + emit->state = FYES_STREAM_START; + + fyep = container_of(fye, struct fy_eventp, e); + + fy_eventp_list_add_tail(&emit->queued_events, fyep); + + ret = 0; + while ((fyep = fy_emit_next_event(emit)) != NULL) { + + switch (emit->state) { + case FYES_STREAM_START: + ret = fy_emit_handle_stream_start(emit, fyep); + break; + + case FYES_FIRST_DOCUMENT_START: + case FYES_DOCUMENT_START: + ret = fy_emit_handle_document_start(emit, fyep, + emit->state == FYES_FIRST_DOCUMENT_START); + break; + + case FYES_DOCUMENT_CONTENT: + ret = fy_emit_handle_document_content(emit, fyep); + break; + + case FYES_DOCUMENT_END: + ret = fy_emit_handle_document_end(emit, fyep); + break; + + case FYES_SEQUENCE_FIRST_ITEM: + case FYES_SEQUENCE_ITEM: + ret = fy_emit_handle_sequence_item(emit, fyep, + emit->state == FYES_SEQUENCE_FIRST_ITEM); + break; + + case FYES_MAPPING_FIRST_KEY: + case FYES_MAPPING_KEY: + ret = fy_emit_handle_mapping_key(emit, fyep, + emit->state == FYES_MAPPING_FIRST_KEY); + break; + + case FYES_MAPPING_SIMPLE_VALUE: + case FYES_MAPPING_VALUE: + ret = fy_emit_handle_mapping_value(emit, fyep, + emit->state == FYES_MAPPING_SIMPLE_VALUE); + break; + + case FYES_END: + ret = -1; + break; + + default: + assert(1); /* Invalid state. */ + } + + /* always release the event */ + if (!fyp) + fy_eventp_release(fyep); + else + fy_parse_eventp_recycle(fyp, fyep); + + if (ret) + break; + } + + return ret; +} + +int fy_emit_event(struct fy_emitter *emit, struct fy_event *fye) +{ + return fy_emit_event_from_parser(emit, NULL, fye); +} + +struct fy_document_state * +fy_emitter_get_document_state(struct fy_emitter *emit) +{ + return emit ? emit->fyds : NULL; +} + +int fy_emitter_default_output(struct fy_emitter *fye, enum fy_emitter_write_type type, const char *str, int len, void *userdata) +{ + struct fy_emitter_default_output_data d_local, *d; + FILE *fp; + int ret, w; + const char *color = NULL; + const char *s, *e; + + d = userdata; + if (!d) { + /* kinda inneficient but should not matter */ + d = &d_local; + d->fp = stdout; + d->colorize = isatty(STDOUT_FILENO); + d->visible = false; + } + fp = d->fp; + + s = str; + e = str + len; + if (d->colorize) { + switch (type) { + case fyewt_document_indicator: + color = "\x1b[36m"; + break; + case fyewt_tag_directive: + case fyewt_version_directive: + color = "\x1b[33m"; + break; + case fyewt_indent: + if (d->visible) { + fputs("\x1b[32m", fp); + while (s < e && (w = fy_utf8_width_by_first_octet(((uint8_t)*s))) > 0) { + /* open box - U+2423 */ + fputs("\xe2\x90\xa3", fp); + s += w; + } + fputs("\x1b[0m", fp); + return len; + } + break; + case fyewt_indicator: + if (len == 1 && (str[0] == '\'' || str[0] == '"')) + color = "\x1b[33m"; + else if (len == 1 && str[0] == '&') + color = "\x1b[32;1m"; + else + color = "\x1b[35m"; + break; + case fyewt_whitespace: + if (d->visible) { + fputs("\x1b[32m", fp); + while (s < e && (w = fy_utf8_width_by_first_octet(((uint8_t)*s))) > 0) { + /* symbol for space - U+2420 */ + /* symbol for interpunct - U+00B7 */ + fputs("\xc2\xb7", fp); + s += w; + } + fputs("\x1b[0m", fp); + return len; + } + break; + case fyewt_plain_scalar: + color = "\x1b[37;1m"; + break; + case fyewt_single_quoted_scalar: + case fyewt_double_quoted_scalar: + color = "\x1b[33m"; + break; + case fyewt_literal_scalar: + case fyewt_folded_scalar: + color = "\x1b[33m"; + break; + case fyewt_anchor: + case fyewt_tag: + case fyewt_alias: + color = "\x1b[32;1m"; + break; + case fyewt_linebreak: + if (d->visible) { + fputs("\x1b[32m", fp); + while (s < e && (w = fy_utf8_width_by_first_octet(((uint8_t)*s))) > 0) { + /* symbol for space - ^M */ + /* fprintf(fp, "^M\n"); */ + /* down arrow - U+2193 */ + fputs("\xe2\x86\x93\n", fp); + s += w; + } + fputs("\x1b[0m", fp); + return len; + } + color = NULL; + break; + case fyewt_terminating_zero: + color = NULL; + break; + case fyewt_plain_scalar_key: + case fyewt_single_quoted_scalar_key: + case fyewt_double_quoted_scalar_key: + color = "\x1b[36;1m"; + break; + case fyewt_comment: + color = "\x1b[34;1m"; + break; + } + } + + /* don't output the terminating zero */ + if (type == fyewt_terminating_zero) + return len; + + if (color) + fputs(color, fp); + + ret = fwrite(str, 1, len, fp); + + if (color) + fputs("\x1b[0m", fp); + + return ret; +} + +int fy_document_default_emit_to_fp(struct fy_document *fyd, FILE *fp) +{ + struct fy_emitter fye_local, *fye = &fye_local; + struct fy_emitter_cfg ecfg_local, *ecfg = &ecfg_local; + struct fy_emitter_default_output_data d_local, *d = &d_local; + int rc; + + memset(d, 0, sizeof(*d)); + d->fp = fp; + d->colorize = isatty(fileno(fp)); + d->visible = false; + + memset(ecfg, 0, sizeof(*ecfg)); + ecfg->diag = fyd->diag; + ecfg->userdata = d; + + rc = fy_emit_setup(fye, ecfg); + if (rc) + goto err_setup; + + rc = fy_emit_document(fye, fyd); + if (rc) + goto err_emit; + + fy_emit_cleanup(fye); + + return 0; + +err_emit: + fy_emit_cleanup(fye); +err_setup: + return -1; +} diff --git a/src/lib/fy-emit.h b/src/lib/fy-emit.h new file mode 100644 index 0000000..a01ee50 --- /dev/null +++ b/src/lib/fy-emit.h @@ -0,0 +1,140 @@ +/* + * fy-emit.h - internal YAML emitter header + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_EMIT_H +#define FY_EMIT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-utf8.h" +#include "fy-event.h" +#include "fy-emit-accum.h" + +#define FYEF_WHITESPACE 0x0001 +#define FYEF_INDENTATION 0x0002 +#define FYEF_OPEN_ENDED 0x0004 +#define FYEF_HAD_DOCUMENT_START 0x0008 +#define FYEF_HAD_DOCUMENT_END 0x0010 +#define FYEF_HAD_DOCUMENT_OUTPUT 0x0020 + +struct fy_document; +struct fy_emitter; +struct fy_document_state; + +enum fy_emitter_state { + FYES_NONE, /* when not using the raw emitter interface */ + FYES_STREAM_START, + FYES_FIRST_DOCUMENT_START, + FYES_DOCUMENT_START, + FYES_DOCUMENT_CONTENT, + FYES_DOCUMENT_END, + FYES_SEQUENCE_FIRST_ITEM, + FYES_SEQUENCE_ITEM, + FYES_MAPPING_FIRST_KEY, + FYES_MAPPING_KEY, + FYES_MAPPING_SIMPLE_VALUE, + FYES_MAPPING_VALUE, + FYES_END, +}; + +struct fy_emit_save_ctx { + bool flow_token : 1; + bool flow : 1; + bool empty : 1; + int old_indent; + int flags; + int indent; + struct fy_token *fyt_last_key; + struct fy_token *fyt_last_value; + int s_flags; + int s_indent; +}; + +/* internal flags */ +#define DDNF_ROOT 0x0001 +#define DDNF_SEQ 0x0002 +#define DDNF_MAP 0x0004 +#define DDNF_SIMPLE 0x0008 +#define DDNF_FLOW 0x0010 +#define DDNF_INDENTLESS 0x0020 +#define DDNF_SIMPLE_SCALAR_KEY 0x0040 + +struct fy_emitter { + int line; + int column; + int flow_level; + unsigned int flags; + bool output_error : 1; + /* current document */ + struct fy_emitter_cfg cfg; /* yeah, it isn't worth just to save a few bytes */ + struct fy_document *fyd; + struct fy_document_state *fyds; /* fyd->fyds when fyd != NULL */ + struct fy_emit_accum ea; + char ea_inplace_buf[256]; /* the in place accumulator buffer before allocating */ + struct fy_diag *diag; + + /* streaming event mode */ + enum fy_emitter_state state; + enum fy_emitter_state *state_stack; + unsigned int state_stack_alloc; + unsigned int state_stack_top; + enum fy_emitter_state state_stack_inplace[64]; + struct fy_eventp_list queued_events; + int s_indent; + int s_flags; + struct fy_emit_save_ctx s_sc; + struct fy_emit_save_ctx *sc_stack; + unsigned int sc_stack_alloc; + unsigned int sc_stack_top; + struct fy_emit_save_ctx sc_stack_inplace[16]; + + /* recycled */ + struct fy_eventp_list recycled_eventp; + struct fy_token_list recycled_token; +}; + +int fy_emit_setup(struct fy_emitter *emit, const struct fy_emitter_cfg *cfg); +void fy_emit_cleanup(struct fy_emitter *emit); + +void fy_emit_write(struct fy_emitter *emit, enum fy_emitter_write_type type, const char *str, int len); + +static inline bool fy_emit_whitespace(struct fy_emitter *emit) +{ + return !!(emit->flags & FYEF_WHITESPACE); +} + +static inline bool fy_emit_indentation(struct fy_emitter *emit) +{ + return !!(emit->flags & FYEF_INDENTATION); +} + +static inline bool fy_emit_open_ended(struct fy_emitter *emit) +{ + return !!(emit->flags & FYEF_OPEN_ENDED); +} + +static inline void +fy_emit_output_accum(struct fy_emitter *emit, enum fy_emitter_write_type type, struct fy_emit_accum *ea) +{ + const char *text; + size_t len; + + text = fy_emit_accum_get(ea, &len); + if (text && len > 0) + fy_emit_write(emit, type, text, len); + fy_emit_accum_reset(ea); +} + +#endif diff --git a/src/lib/fy-event.c b/src/lib/fy-event.c new file mode 100644 index 0000000..231ed04 --- /dev/null +++ b/src/lib/fy-event.c @@ -0,0 +1,858 @@ +/* + * fy-event.c - YAML event methods + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-emit.h" + +#include "fy-ctype.h" +#include "fy-utf8.h" +#include "fy-utils.h" + +#include "fy-event.h" + +struct fy_eventp *fy_eventp_alloc(void) +{ + struct fy_eventp *fyep; + + fyep = malloc(sizeof(*fyep)); + if (!fyep) + return NULL; + + memset(fyep, 0, sizeof(*fyep)); + + fyep->e.type = FYET_NONE; + + return fyep; +} + +void fy_eventp_clean_rl(struct fy_token_list *fytl, struct fy_eventp *fyep) +{ + struct fy_event *fye; + + if (!fyep) + return; + + fye = &fyep->e; + switch (fye->type) { + case FYET_NONE: + break; + case FYET_STREAM_START: + fy_token_unref_rl(fytl, fye->stream_start.stream_start); + break; + case FYET_STREAM_END: + fy_token_unref_rl(fytl, fye->stream_end.stream_end); + break; + case FYET_DOCUMENT_START: + fy_token_unref_rl(fytl, fye->document_start.document_start); + fy_document_state_unref(fye->document_start.document_state); + break; + case FYET_DOCUMENT_END: + fy_token_unref_rl(fytl, fye->document_end.document_end); + break; + case FYET_MAPPING_START: + fy_token_unref_rl(fytl, fye->mapping_start.anchor); + fy_token_unref_rl(fytl, fye->mapping_start.tag); + fy_token_unref_rl(fytl, fye->mapping_start.mapping_start); + break; + case FYET_MAPPING_END: + fy_token_unref_rl(fytl, fye->mapping_end.mapping_end); + break; + case FYET_SEQUENCE_START: + fy_token_unref_rl(fytl, fye->sequence_start.anchor); + fy_token_unref_rl(fytl, fye->sequence_start.tag); + fy_token_unref_rl(fytl, fye->sequence_start.sequence_start); + break; + case FYET_SEQUENCE_END: + fy_token_unref_rl(fytl, fye->sequence_end.sequence_end); + break; + case FYET_SCALAR: + fy_token_unref_rl(fytl, fye->scalar.anchor); + fy_token_unref_rl(fytl, fye->scalar.tag); + fy_token_unref_rl(fytl, fye->scalar.value); + break; + case FYET_ALIAS: + fy_token_unref_rl(fytl, fye->alias.anchor); + break; + } + + fye->type = FYET_NONE; +} + +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); +} + +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); +} + +void fy_eventp_free(struct fy_eventp *fyep) +{ + if (!fyep) + return; + + /* clean, safe to do */ + fy_eventp_clean_rl(NULL, fyep); + + free(fyep); +} + +void fy_eventp_release(struct fy_eventp *fyep) +{ + fy_eventp_free(fyep); +} + +struct fy_eventp *fy_parse_eventp_alloc(struct fy_parser *fyp) +{ + struct fy_eventp *fyep = NULL; + + if (!fyp) + return NULL; + + if (!fyp->suppress_recycling) + fyep = fy_eventp_list_pop(&fyp->recycled_eventp); + if (!fyep) + fyep = fy_eventp_alloc(); + if (!fyep) + return NULL; + + fyep->e.type = FYET_NONE; + + return fyep; +} + +void fy_parse_eventp_recycle(struct fy_parser *fyp, struct fy_eventp *fyep) +{ + if (!fyp || !fyep) + return; + + /* clean, safe to do */ + 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); + 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; + + if (!fyp || !fye) + return; + + fyep = container_of(fye, struct fy_eventp, e); + + fy_parse_eventp_recycle(fyp, fyep); +} + +void fy_emit_eventp_recycle(struct fy_emitter *emit, struct fy_eventp *fyep) +{ + if (!emit || !fyep) + return; + + /* 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); +} + +void fy_emit_event_free(struct fy_emitter *emit, struct fy_event *fye) +{ + struct fy_eventp *fyep; + + if (!emit || !fye) + return; + + fyep = container_of(fye, struct fy_eventp, e); + + 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) +{ + struct fy_eventp *fyep = NULL; + struct fy_event *fye = NULL; + struct fy_document_state *fyds_new = NULL; + const struct fy_version *vers; + const struct fy_tag *tag, * const *tagp; + struct fy_token *fyt; + enum fy_token_type ttype; + int rc, tag_count = 0; + enum fy_node_style style; + enum fy_scalar_style sstyle; + struct fy_token **fyt_anchorp = NULL, **fyt_tagp = NULL; + struct fy_input *fyi = NULL; + struct fy_atom handle; + const char *value; + size_t len; + char *data = NULL; + struct fy_tag_scan_info info; + struct fy_token *fyt_td; + + /* try the recycled list first */ + if (recycled_list) + fyep = fy_eventp_list_pop(recycled_list); + /* if not there yet, allocate a fresh one */ + if (!fyep) + fyep = fy_eventp_alloc(); + if (!fyep) + return NULL; + + fye = &fyep->e; + + fye->type = type; + + switch (type) { + case FYET_NONE: + break; + case FYET_STREAM_START: + fye->stream_start.stream_start = NULL; + break; + case FYET_STREAM_END: + fye->stream_end.stream_end = NULL; + break; + case FYET_DOCUMENT_START: + fye->document_start.document_start = NULL; + fyds_new = fy_document_state_default(fy_document_state_version(fyds), NULL); /* start with the default state */ + if (!fyds_new) { + fy_error(diag, "fy_document_state_alloc() failed\n"); + goto err_out; + } + fye->document_start.implicit = va_arg(ap, int); + vers = va_arg(ap, const struct fy_version *); + if (vers) { + fyds_new->version = *vers; + fyds_new->version_explicit = true; + } + fyds_new->start_implicit = fye->document_start.implicit; + fyds_new->end_implicit = false; /* this is not used right now */ + tag_count = 0; + tagp = va_arg(ap, const struct fy_tag * const *); + if (tagp) { + while ((tag = tagp[tag_count]) != NULL) { + tag_count++; + rc = fy_document_state_append_tag(fyds_new, tag->handle, tag->prefix, false); + if (rc) { + fy_error(diag, "fy_document_state_append_tag() failed on handle='%s' prefix='%s'\n", + tag->handle, tag->prefix); + goto err_out; + } + } + } + if (tag_count) + fyds_new->tags_explicit = true; + fye->document_start.document_state = fyds_new; + fyds_new = NULL; + break; + case FYET_DOCUMENT_END: + fye->document_end.document_end = NULL; + fye->document_end.implicit = va_arg(ap, int); + break; + case FYET_MAPPING_START: + case FYET_SEQUENCE_START: + style = va_arg(ap, enum fy_node_style); + ttype = FYTT_NONE; + + if (style != FYNS_ANY && style != FYNS_FLOW && style != FYNS_BLOCK) { + fy_error(diag, "illegal style for %s_START\n", + type == FYET_MAPPING_START ? "MAPPING" : "SEQUENCE"); + goto err_out; + } + + if (style != FYNS_ANY) { + if (style == FYNS_FLOW) + ttype = type == FYET_MAPPING_START ? + FYTT_FLOW_MAPPING_START : + FYTT_FLOW_SEQUENCE_START; + else + ttype = type == FYET_MAPPING_START ? + FYTT_BLOCK_MAPPING_START : + FYTT_BLOCK_SEQUENCE_START; + fyt = fy_token_create(ttype, NULL); + if (!fyt) { + fy_error(diag, "fy_token_create() failed for %s_START\n", + type == FYET_MAPPING_START ? "MAPPING" : "SEQUENCE"); + goto err_out; + } + } else + fyt = NULL; + + if (type == FYET_MAPPING_START) { + fye->mapping_start.mapping_start = fyt; + fye->mapping_start.anchor = NULL; + fye->mapping_start.tag = NULL; + fyt_anchorp = &fye->mapping_start.anchor; + fyt_tagp = &fye->mapping_start.tag; + } else { + fye->sequence_start.sequence_start = fyt; + fye->sequence_start.anchor = NULL; + fye->sequence_start.tag = NULL; + fyt_anchorp = &fye->sequence_start.anchor; + fyt_tagp = &fye->sequence_start.tag; + } + fyt = NULL; + break; + case FYET_MAPPING_END: + fye->mapping_end.mapping_end = NULL; + break; + case FYET_SEQUENCE_END: + fye->sequence_end.sequence_end = NULL; + break; + + case FYET_SCALAR: + case FYET_ALIAS: + + if (type == FYET_SCALAR) { + sstyle = va_arg(ap, enum fy_scalar_style); + value = va_arg(ap, const char *); + len = va_arg(ap, size_t); + if (!value && len) { + fy_error(diag, "NULL value with len > 0, illegal SCALAR\n"); + goto err_out; + } + if (len == FY_NT) + len = strlen(value); + } else { + sstyle = FYSS_PLAIN; + value = va_arg(ap, const char *); + if (!value) { + fy_error(diag, "NULL value, illegal ALIAS\n"); + goto err_out; + } + len = strlen(value); + } + + fyt = NULL; + fyi = NULL; + + data = malloc(len + 1); + if (!data) { + fy_error(diag, "malloc() failed\n"); + goto err_out; + } + memcpy(data, value, len); + /* always NULL terminate */ + data[len] = '\0'; + fyi = fy_input_from_malloc_data(data, len, &handle, sstyle == FYSS_PLAIN); + if (!fyi) { + fy_error(diag, "fy_input_from_malloc_data() failed\n"); + goto err_out; + } + data = NULL; + + if (type == FYET_SCALAR) { + fyt = fy_token_create(FYTT_SCALAR, &handle, sstyle); + if (!fyt) { + fy_error(diag, "fy_token_create() failed for %s\n", + "SCALAR"); + goto err_out; + } + + fye->scalar.value = fyt; + fyt = NULL; + + fye->scalar.anchor = NULL; + fye->scalar.tag = NULL; + fyt_anchorp = &fye->scalar.anchor; + fyt_tagp = &fye->scalar.tag; + } else { + fyt = fy_token_create(FYTT_ALIAS, &handle, NULL); + if (!fyt) { + fy_error(diag, "fy_token_create() failed for %s\n", + "ALIAS"); + goto err_out; + } + + fye->alias.anchor = fyt; + fyt = NULL; + } + fy_input_unref(fyi); + fyi = NULL; + break; + } + + if (fyt_anchorp && (value = va_arg(ap, const char *)) != NULL) { + + len = strlen(value); + data = malloc(len + 1); + if (!data) { + fy_error(diag, "malloc() failed\n"); + goto err_out; + } + memcpy(data, value, len); + /* always NULL terminate */ + data[len] = '\0'; + + fyi = fy_input_from_malloc_data(data, len, &handle, true); + if (!fyi) { + fy_error(diag, "fy_input_from_malloc_data() failed\n"); + goto err_out; + } + data = NULL; + + /* make sure the input as valid as an anchor */ + if (!handle.valid_anchor) { + fy_error(diag, "input was not valid as anchor\n"); + goto err_out; + } + + fyt = fy_token_create(FYTT_ANCHOR, &handle); + if (!fyt) { + fy_error(diag, "fy_token_create() failed\n"); + goto err_out; + } + *fyt_anchorp = fyt; + fyt = NULL; + fy_input_unref(fyi); + fyi = NULL; + } + + if (fyt_tagp && (value = va_arg(ap, const char *)) != NULL) { + + len = strlen(value); + data = malloc(len + 1); + if (!data) { + fy_error(diag, "malloc() failed\n"); + goto err_out; + } + memcpy(data, value, len); + /* always NULL terminate */ + data[len] = '\0'; + + rc = fy_tag_scan(data, len, &info); + if (rc) { + fy_error(diag, "invalid tag %s (tag_scan)\n", value); + goto err_out; + } + + fyt_td = fy_document_state_lookup_tag_directive(fyds, data + info.prefix_length, info.handle_length); + if (!fyt_td) { + fy_error(diag, "invalid tag %s (lookup tag directive)\n", value); + goto err_out; + } + + fyi = fy_input_from_data(data, len, &handle, true); + if (!fyi) + goto err_out; + data = NULL; + + handle.style = FYAS_URI; + handle.direct_output = false; + handle.storage_hint = 0; + handle.storage_hint_valid = false; + + fyt = fy_token_create(FYTT_TAG, &handle, info.prefix_length, + info.handle_length, info.uri_length, fyt_td); + if (!fyt) { + fy_error(diag, "fy_token_create() failed\n"); + goto err_out; + } + *fyt_tagp = fyt; + fyt = NULL; + fy_input_unref(fyi); + fyi = NULL; + } + + return fyep; + +err_out: + fy_input_unref(fyi); + if (data) + free(data); + fy_document_state_unref(fyds_new); + /* don't bother with recycling on error */ + fy_eventp_free(fyep); + return NULL; +} + +struct fy_eventp * +fy_eventp_create_internal(struct fy_eventp_list *recycled_list, struct fy_diag *diag, + struct fy_document_state *fyds, + enum fy_event_type type, ...) +{ + struct fy_eventp *fyep; + va_list ap; + + va_start(ap, type); + fyep = fy_eventp_vcreate_internal(recycled_list, diag, fyds, type, ap); + va_end(ap); + + return fyep; +} + +struct fy_event * +fy_emit_event_vcreate(struct fy_emitter *emit, enum fy_event_type type, va_list ap) +{ + struct fy_eventp *fyep; + + if (!emit) + return NULL; + + fyep = fy_eventp_vcreate_internal(&emit->recycled_eventp, emit->diag, emit->fyds, type, ap); + if (!fyep) + return NULL; + + return &fyep->e; +} + +struct fy_event * +fy_emit_event_create(struct fy_emitter *emit, enum fy_event_type type, ...) +{ + struct fy_event *fye; + va_list ap; + + va_start(ap, type); + fye = fy_emit_event_vcreate(emit, type, ap); + va_end(ap); + + return fye; +} + +struct fy_event * +fy_parse_event_vcreate(struct fy_parser *fyp, enum fy_event_type type, va_list ap) +{ + struct fy_eventp *fyep; + + if (!fyp) + return NULL; + + fyep = fy_eventp_vcreate_internal(&fyp->recycled_eventp, fyp->diag, fyp->current_document_state, type, ap); + if (!fyep) + return NULL; + + return &fyep->e; +} + +struct fy_event * +fy_parse_event_create(struct fy_parser *fyp, enum fy_event_type type, ...) +{ + struct fy_event *fye; + va_list ap; + + va_start(ap, type); + fye = fy_parse_event_vcreate(fyp, type, ap); + va_end(ap); + + return fye; +} + +bool fy_event_is_implicit(struct fy_event *fye) +{ + /* NULL event is implicit */ + if (!fye) + return true; + + switch (fye->type) { + + case FYET_DOCUMENT_START: + return fye->document_start.implicit; + + case FYET_DOCUMENT_END: + return fye->document_end.implicit; + + case FYET_MAPPING_START: + case FYET_MAPPING_END: + case FYET_SEQUENCE_START: + case FYET_SEQUENCE_END: + return fy_event_get_node_style(fye) == FYNS_BLOCK; + + default: + break; + } + + return false; +} + +bool fy_document_event_is_implicit(const struct fy_event *fye) +{ + if (fye->type == FYET_DOCUMENT_START) + return fye->document_start.implicit; + + if (fye->type == FYET_DOCUMENT_END) + return fye->document_end.implicit; + + return false; +} + +struct fy_token *fy_event_get_token(struct fy_event *fye) +{ + if (!fye) + return NULL; + + switch (fye->type) { + case FYET_NONE: + break; + + case FYET_STREAM_START: + return fye->stream_start.stream_start; + + case FYET_STREAM_END: + return fye->stream_end.stream_end; + + case FYET_DOCUMENT_START: + return fye->document_start.document_start; + + case FYET_DOCUMENT_END: + return fye->document_end.document_end; + + case FYET_MAPPING_START: + return fye->mapping_start.mapping_start; + + case FYET_MAPPING_END: + return fye->mapping_end.mapping_end; + + case FYET_SEQUENCE_START: + return fye->sequence_start.sequence_start; + + case FYET_SEQUENCE_END: + return fye->sequence_end.sequence_end; + + case FYET_SCALAR: + return fye->scalar.value; + + case FYET_ALIAS: + return fye->alias.anchor; + + } + + return NULL; +} + +struct fy_token *fy_event_get_anchor_token(struct fy_event *fye) +{ + if (!fye) + return NULL; + + switch (fye->type) { + case FYET_MAPPING_START: + return fye->mapping_start.anchor; + case FYET_SEQUENCE_START: + return fye->sequence_start.anchor; + case FYET_SCALAR: + return fye->scalar.anchor; + default: + break; + } + + return NULL; +} + +struct fy_token *fy_event_get_tag_token(struct fy_event *fye) +{ + if (!fye) + return NULL; + + switch (fye->type) { + case FYET_MAPPING_START: + return fye->mapping_start.tag; + case FYET_SEQUENCE_START: + return fye->sequence_start.tag; + case FYET_SCALAR: + return fye->scalar.tag; + default: + break; + } + + return NULL; +} + +const struct fy_mark *fy_event_start_mark(struct fy_event *fye) +{ + if (!fye) + return NULL; + + switch (fye->type) { + case FYET_NONE: + break; + + case FYET_STREAM_START: + return fy_token_start_mark(fye->stream_start.stream_start); + + case FYET_STREAM_END: + return fy_token_start_mark(fye->stream_end.stream_end); + + case FYET_DOCUMENT_START: + return fy_token_start_mark(fye->document_start.document_start); + + case FYET_DOCUMENT_END: + return fy_token_start_mark(fye->document_end.document_end); + + case FYET_MAPPING_START: + return fy_token_start_mark(fye->mapping_start.mapping_start); + + case FYET_MAPPING_END: + return fy_token_start_mark(fye->mapping_end.mapping_end); + + case FYET_SEQUENCE_START: + return fy_token_start_mark(fye->sequence_start.sequence_start); + + case FYET_SEQUENCE_END: + return fy_token_start_mark(fye->sequence_end.sequence_end); + + case FYET_SCALAR: + return fy_token_start_mark(fye->scalar.value); + + case FYET_ALIAS: + return fy_token_start_mark(fye->alias.anchor); + + } + + return NULL; +} + +const struct fy_mark *fy_event_end_mark(struct fy_event *fye) +{ + if (!fye) + return NULL; + + switch (fye->type) { + case FYET_NONE: + break; + + case FYET_STREAM_START: + return fy_token_end_mark(fye->stream_start.stream_start); + + case FYET_STREAM_END: + return fy_token_end_mark(fye->stream_end.stream_end); + + case FYET_DOCUMENT_START: + return fy_token_end_mark(fye->document_start.document_start); + + case FYET_DOCUMENT_END: + return fy_token_end_mark(fye->document_end.document_end); + + case FYET_MAPPING_START: + return fy_token_end_mark(fye->mapping_start.mapping_start); + + case FYET_MAPPING_END: + return fy_token_end_mark(fye->mapping_end.mapping_end); + + case FYET_SEQUENCE_START: + return fy_token_end_mark(fye->sequence_start.sequence_start); + + case FYET_SEQUENCE_END: + return fy_token_end_mark(fye->sequence_end.sequence_end); + + case FYET_SCALAR: + return fy_token_end_mark(fye->scalar.value); + + case FYET_ALIAS: + return fy_token_end_mark(fye->alias.anchor); + + } + + return NULL; +} + +enum fy_node_style +fy_event_get_node_style(struct fy_event *fye) +{ + struct fy_token *fyt; + + fyt = fy_event_get_token(fye); + if (!fyt) + return FYNS_ANY; + + switch (fye->type) { + /* unstyled events */ + case FYET_NONE: + case FYET_STREAM_START: + case FYET_STREAM_END: + case FYET_DOCUMENT_START: + case FYET_DOCUMENT_END: + return FYNS_ANY; + + case FYET_MAPPING_START: + return fyt && fyt->type == FYTT_FLOW_MAPPING_START ? FYNS_FLOW : FYNS_BLOCK; + + case FYET_MAPPING_END: + return fyt && fyt->type == FYTT_FLOW_MAPPING_END ? FYNS_FLOW : FYNS_BLOCK; + + case FYET_SEQUENCE_START: + return fyt && fyt->type == FYTT_FLOW_SEQUENCE_START ? FYNS_FLOW : FYNS_BLOCK; + + case FYET_SEQUENCE_END: + return fyt && fyt->type == FYTT_FLOW_SEQUENCE_END ? FYNS_FLOW : FYNS_BLOCK; + + case FYET_SCALAR: + return fyt ? fy_node_style_from_scalar_style(fyt->scalar.style) : FYNS_PLAIN; + + case FYET_ALIAS: + return FYNS_ALIAS; + + } + + return FYNS_ANY; +} + +const struct fy_version * +fy_document_start_event_version(struct fy_event *fye) +{ + /* return the default if not set */ + if (!fye || fye->type != FYET_DOCUMENT_START) + return &fy_default_version; + return fy_document_state_version(fye->document_start.document_state); +} + diff --git a/src/lib/fy-event.h b/src/lib/fy-event.h new file mode 100644 index 0000000..3153f8c --- /dev/null +++ b/src/lib/fy-event.h @@ -0,0 +1,45 @@ +/* + * fy-event.h - YAML parser private event definition + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_EVENT_H +#define FY_EVENT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "fy-list.h" +#include "fy-typelist.h" + +/* private event type */ +FY_TYPE_FWD_DECL_LIST(eventp); +struct fy_eventp { + struct list_head node; + struct fy_event e; +}; +FY_TYPE_DECL_LIST(eventp); +FY_PARSE_TYPE_DECL_ALLOC(eventp); + +struct fy_eventp *fy_eventp_alloc(void); +void fy_eventp_free(struct fy_eventp *fyep); + +/* called from internal emitter */ +void fy_eventp_release(struct fy_eventp *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); + +#endif diff --git a/src/lib/fy-input.c b/src/lib/fy-input.c new file mode 100644 index 0000000..29b1945 --- /dev/null +++ b/src/lib/fy-input.c @@ -0,0 +1,905 @@ +/* + * fy-input.c - YAML input methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-ctype.h" + +#include "fy-input.h" + +struct fy_input *fy_input_alloc(void) +{ + struct fy_input *fyi; + + fyi = malloc(sizeof(*fyi)); + if (!fyi) + return NULL; + memset(fyi, 0, sizeof(*fyi)); + + fyi->state = FYIS_NONE; + fyi->refs = 1; + + return fyi; +} + +void fy_input_free(struct fy_input *fyi) +{ + if (!fyi) + return; + + assert(fyi->refs == 1); + + switch (fyi->state) { + case FYIS_NONE: + case FYIS_QUEUED: + /* nothing to do */ + break; + case FYIS_PARSE_IN_PROGRESS: + case FYIS_PARSED: + fy_input_close(fyi); + break; + } + + /* always release the memory of the alloc memory */ + switch (fyi->cfg.type) { + case fyit_alloc: + free(fyi->cfg.alloc.data); + break; + + default: + break; + } + if (fyi->name) + free(fyi->name); + + free(fyi); +} + +const char *fy_input_get_filename(struct fy_input *fyi) +{ + if (!fyi) + return NULL; + + return fyi->name; +} + +static void fy_input_from_data_setup(struct fy_input *fyi, + struct fy_atom *handle, bool simple) +{ + const char *data; + size_t size; + unsigned int aflags; + + /* this is an internal method, you'd better to pass garbage */ + data = fy_input_start(fyi); + size = fy_input_size(fyi); + + fyi->buffer = NULL; + fyi->allocated = 0; + fyi->read = 0; + fyi->chunk = 0; + fyi->fp = NULL; + + if (!handle) + goto out; + + memset(handle, 0, sizeof(*handle)); + + if (size > 0) + 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; + + handle->start_mark.input_pos = 0; + handle->start_mark.line = 0; + handle->start_mark.column = 0; + handle->end_mark.input_pos = size; + handle->end_mark.line = 0; + handle->end_mark.column = fy_utf8_count(data, size); + /* if it's plain, all is good */ + if (simple || (aflags & FYACF_FLOW_PLAIN)) { + handle->storage_hint = size; /* maximum */ + handle->storage_hint_valid = false; + handle->direct_output = !!(aflags & FYACF_JSON_ESCAPE); + handle->style = FYAS_PLAIN; + } else { + handle->storage_hint = 0; /* just calculate */ + handle->storage_hint_valid = false; + handle->direct_output = false; + handle->style = FYAS_DOUBLE_QUOTED_MANUAL; + } + handle->empty = !!(aflags & FYACF_EMPTY); + handle->has_lb = !!(aflags & FYACF_LB); + handle->has_ws = !!(aflags & FYACF_WS); + handle->starts_with_ws = !!(aflags & FYACF_STARTS_WITH_WS); + handle->starts_with_lb = !!(aflags & FYACF_STARTS_WITH_LB); + handle->ends_with_ws = !!(aflags & FYACF_ENDS_WITH_WS); + handle->ends_with_lb = !!(aflags & FYACF_ENDS_WITH_LB); + handle->trailing_lb = !!(aflags & FYACF_TRAILING_LB); + handle->size0 = !!(aflags & FYACF_SIZE0); + handle->valid_anchor = !!(aflags & FYACF_VALID_ANCHOR); + + handle->chomp = FYAC_STRIP; + handle->increment = 0; + handle->fyi = fyi; + handle->fyi_generation = fyi->generation; + handle->tabsize = 0; + handle->json_mode = false; /* XXX hardcoded */ + handle->lb_mode = fylb_cr_nl; + handle->fws_mode = fyfws_space_tab; +out: + fyi->state = FYIS_PARSED; +} + +struct fy_input *fy_input_from_data(const char *data, size_t size, + struct fy_atom *handle, bool simple) +{ + struct fy_input *fyi; + + if (data && size == (size_t)-1) + size = strlen(data); + + fyi = fy_input_alloc(); + if (!fyi) + return NULL; + + fyi->cfg.type = fyit_memory; + fyi->cfg.userdata = NULL; + fyi->cfg.memory.data = data; + fyi->cfg.memory.size = size; + + fy_input_from_data_setup(fyi, handle, simple); + + return fyi; +} + +struct fy_input *fy_input_from_malloc_data(char *data, size_t size, + struct fy_atom *handle, bool simple) +{ + struct fy_input *fyi; + + if (data && size == (size_t)-1) + size = strlen(data); + + fyi = fy_input_alloc(); + if (!fyi) + return NULL; + + fyi->cfg.type = fyit_alloc; + fyi->cfg.userdata = NULL; + fyi->cfg.alloc.data = data; + fyi->cfg.alloc.size = size; + + fy_input_from_data_setup(fyi, handle, simple); + + return fyi; +} + +void fy_input_close(struct fy_input *fyi) +{ + if (!fyi) + return; + + switch (fyi->cfg.type) { + case fyit_file: + if (fyi->file.fd != -1) { + close(fyi->file.fd); + fyi->file.fd = -1; + } + if (fyi->addr && fyi->addr != MAP_FAILED) { + munmap(fyi->addr, fyi->file.length); + fyi->addr = NULL; + } + if (fyi->buffer) { + free(fyi->buffer); + fyi->buffer = NULL; + } + if (fyi->fp) { + fclose(fyi->fp); + fyi->fp = NULL; + } + break; + + case fyit_stream: + case fyit_callback: + if (fyi->buffer) { + free(fyi->buffer); + fyi->buffer = NULL; + } + break; + + case fyit_memory: + /* nothing */ + break; + + case fyit_alloc: + /* nothing */ + break; + + default: + break; + } +} + +struct fy_diag *fy_reader_get_diag(struct fy_reader *fyr) +{ + if (fyr && fyr->ops && fyr->ops->get_diag) + return fyr->ops->get_diag(fyr); + + return NULL; +} + +int fy_reader_file_open(struct fy_reader *fyr, const char *filename) +{ + if (!fyr || !filename) + return -1; + + if (fyr->ops && fyr->ops->file_open) + return fyr->ops->file_open(fyr, filename); + + return open(filename, O_RDONLY); +} + +void fy_reader_reset(struct fy_reader *fyr) +{ + const struct fy_reader_ops *ops; + struct fy_diag *diag; + + if (!fyr) + return; + + ops = fyr->ops; + diag = fyr->diag; + + fy_input_unref(fyr->current_input); + + memset(fyr, 0, sizeof(*fyr)); + + /* by default we're always in yaml mode */ + fyr->mode = fyrm_yaml; + fyr->ops = ops; + fyr->diag = diag; + fyr->current_c = -1; +} + +void fy_reader_setup(struct fy_reader *fyr, const struct fy_reader_ops *ops) +{ + if (!fyr) + return; + + fyr->ops = ops; + fyr->diag = fy_reader_get_diag(fyr); + fyr->current_input = NULL; + fy_reader_reset(fyr); +} + +void fy_reader_cleanup(struct fy_reader *fyr) +{ + if (!fyr) + return; + + fy_input_unref(fyr->current_input); + fyr->current_input = NULL; + fy_reader_reset(fyr); +} + +int fy_reader_input_open(struct fy_reader *fyr, struct fy_input *fyi, const struct fy_reader_input_cfg *icfg) +{ + struct stat sb; + int rc; + + if (!fyi) + return -1; + + /* unref any previous input */ + fy_input_unref(fyr->current_input); + fyr->current_input = fy_input_ref(fyi); + + fy_reader_apply_mode_to_input(fyr); + + if (!icfg) + memset(&fyr->current_input_cfg, 0, sizeof(fyr->current_input_cfg)); + else + fyr->current_input_cfg = *icfg; + + /* reset common data */ + fyi->buffer = NULL; + fyi->allocated = 0; + fyi->read = 0; + fyi->chunk = 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); + + rc = fstat(fyi->file.fd, &sb); + fyr_error_check(fyr, rc != -1, err_out, + "failed to fstat %s", fyi->cfg.file.filename); + + fyi->file.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); + + /* convert from MAP_FAILED to NULL */ + 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) + 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; + + /* 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; + break; + + case fyit_memory: + /* nothing to do for memory */ + break; + + case fyit_alloc: + /* nothing to do for 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: + assert(0); + break; + } + + fyr->current_input_pos = 0; + fyr->line = 0; + fyr->column = 0; + fyr->current_c = -1; + fyr->current_ptr = NULL; + fyr->current_w = 0; + fyr->current_left = 0; + + fyi->state = FYIS_PARSE_IN_PROGRESS; + + return 0; + +err_out: + fy_input_close(fyi); + return -1; +} + +int fy_reader_input_done(struct fy_reader *fyr) +{ + struct fy_input *fyi; + void *buf; + + if (!fyr) + return -1; + + fyi = fyr->current_input; + if (!fyi) + return 0; + + switch (fyi->cfg.type) { + case fyit_file: + if (fyi->addr) + break; + + /* fall-through */ + + case fyit_stream: + case fyit_callback: + /* chop extra buffer */ + buf = realloc(fyi->buffer, fyr->current_input_pos); + fyr_error_check(fyr, buf || !fyr->current_input_pos, err_out, + "realloc() failed"); + + fyi->buffer = buf; + fyi->allocated = fyr->current_input_pos; + /* increate input generation; required for direct input to work */ + fyi->generation++; + break; + + default: + break; + + } + + fyi->state = FYIS_PARSED; + fy_input_unref(fyi); + fyr->current_input = NULL; + + return 0; + +err_out: + return -1; +} + +const void *fy_reader_ptr_slow_path(struct fy_reader *fyr, size_t *leftp) +{ + struct fy_input *fyi; + const void *p; + int left; + + if (fyr->current_ptr) { + if (leftp) + *leftp = fyr->current_left; + return fyr->current_ptr; + } + + fyi = fyr->current_input; + if (!fyi) + return NULL; + + /* tokens cannot cross boundaries */ + switch (fyi->cfg.type) { + case fyit_file: + if (fyi->addr) { + left = fyi->file.length - fyr->current_input_pos; + p = fyi->addr + fyr->current_input_pos; + break; + } + + /* fall-through */ + + case fyit_stream: + case fyit_callback: + left = fyi->read - fyr->current_input_pos; + p = fyi->buffer + fyr->current_input_pos; + break; + + case fyit_memory: + left = fyi->cfg.memory.size - fyr->current_input_pos; + p = fyi->cfg.memory.data + fyr->current_input_pos; + break; + + case fyit_alloc: + left = fyi->cfg.alloc.size - fyr->current_input_pos; + p = fyi->cfg.alloc.data + fyr->current_input_pos; + break; + + + default: + assert(0); /* no streams */ + p = NULL; + left = 0; + break; + } + + if (leftp) + *leftp = left; + + fyr->current_ptr = p; + fyr->current_left = left; + fyr->current_c = fy_utf8_get(fyr->current_ptr, fyr->current_left, &fyr->current_w); + + return p; +} + +const void *fy_reader_input_try_pull(struct fy_reader *fyr, struct fy_input *fyi, + size_t pull, size_t *leftp) +{ + const void *p; + size_t left, pos, size, nread, nreadreq, missing; + ssize_t snread; + size_t space __FY_DEBUG_UNUSED__; + void *buf; + + if (!fyr || !fyi) { + if (leftp) + *leftp = 0; + return NULL; + } + + p = NULL; + left = 0; + pos = fyr->current_input_pos; + + switch (fyi->cfg.type) { + case fyit_file: + + if (fyi->addr) { + assert(fyi->file.length >= pos); + + left = fyi->file.length - pos; + if (!left) { + fyr_debug(fyr, "file input exhausted"); + break; + } + p = fyi->addr + pos; + break; + } + + /* fall-through */ + + case fyit_stream: + case fyit_callback: + + assert(fyi->read >= pos); + + left = fyi->read - pos; + p = fyi->buffer + pos; + + /* enough to satisfy directly */ + if (left >= pull) + break; + + /* no more */ + if (fyi->eof) { + if (!left) { + fyr_debug(fyr, "input exhausted (EOF)"); + p = NULL; + } + break; + } + + space = fyi->allocated - pos; + + /* if we're missing more than the buffer space */ + missing = pull - left; + + fyr_debug(fyr, "input: allocated=%zu read=%zu pos=%zu pull=%zu left=%zu space=%zu missing=%zu", + fyi->allocated, fyi->read, pos, pull, left, space, missing); + + if (pos + pull > fyi->allocated) { + + /* align size to chunk */ + size = fyi->allocated + missing + fyi->chunk - 1; + size = size - size % fyi->chunk; + + fyr_debug(fyr, "input buffer missing %zu bytes (pull=%zu)", missing, pull); + + buf = realloc(fyi->buffer, size); + if (!buf) { + fyr_error(fyr, "realloc() failed"); + goto err_out; + } + + fyr_debug(fyr, "input read allocated=%zu new-size=%zu", fyi->allocated, size); + + fyi->buffer = buf; + fyi->allocated = size; + fyi->generation++; + + space = fyi->allocated - pos; + p = fyi->buffer + pos; + } + + /* always try to read up to the allocated space */ + do { + nreadreq = fyi->allocated - fyi->read; + assert(nreadreq > 0); + + if (fyi->cfg.type == fyit_callback) { + + fyr_debug(fyr, "performing callback request of %zu", nreadreq); + + nread = fyi->cfg.callback.input(fyi->cfg.userdata, fyi->buffer + fyi->read, nreadreq); + + fyr_debug(fyr, "callback returned %zu", nread); + + if (nread <= 0) { + if (!nread) { + fyi->eof = true; + fyr_debug(fyr, "callback got EOF"); + } else { + fyi->err = true; + fyr_debug(fyr, "callback got error"); + } + break; + } + + } else { + if (!fyi->cfg.stream.ignore_stdio) { + + fyr_debug(fyr, "performing fread request of %zu", nreadreq); + + nread = fread(fyi->buffer + fyi->read, 1, nreadreq, fyi->fp); + + 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; + } + + } else { + + fyr_debug(fyr, "performing read request of %zu", nreadreq); + + do { + snread = read(fileno(fyi->fp), fyi->buffer + fyi->read, nreadreq); + } while (snread == -1 && errno == EAGAIN); + + fyr_debug(fyr, "read returned %zd", snread); + + if (snread == -1) { + fyi->err = true; + fyi->eof = true; + fyr_error(fyr, "read() failed"); + goto err_out; + } + + if (!snread) { + fyi->eof = true; + fyr_error(fyr, "read() failed"); + nread = 0; + break; + } + + nread = snread; + } + } + + assert(nread > 0); + + fyi->read += nread; + left = fyi->read - pos; + + } while (left < pull); + + /* no more, move it to parsed input chunk list */ + if (!left) { + fyr_debug(fyr, "input exhausted"); + p = NULL; + } + break; + + case fyit_memory: + assert(fyi->cfg.memory.size >= pos); + + left = fyi->cfg.memory.size - pos; + if (!left) { + fyr_debug(fyr, "memory input exhausted"); + break; + } + p = fyi->cfg.memory.data + pos; + break; + + case fyit_alloc: + assert(fyi->cfg.alloc.size >= pos); + + left = fyi->cfg.alloc.size - pos; + if (!left) { + fyr_debug(fyr, "alloc input exhausted"); + break; + } + p = fyi->cfg.alloc.data + pos; + break; + + + default: + assert(0); + break; + } + + if (leftp) + *leftp = left; + return p; + +err_out: + if (leftp) + *leftp = 0; + return NULL; +} + +void +fy_reader_advance_slow_path(struct fy_reader *fyr, int c) +{ + bool is_line_break = false; + size_t w; + + /* skip this character (optimize case of being the current) */ + w = c == fyr->current_c ? (size_t)fyr->current_w : fy_utf8_width(c); + fy_reader_advance_octets(fyr, w); + + /* first check for CR/LF */ + if (c == '\r' && fy_reader_peek(fyr) == '\n') { + fy_reader_advance_octets(fyr, 1); + is_line_break = true; + } else if (fy_reader_is_lb(fyr, c)) + is_line_break = true; + + if (is_line_break) { + fyr->column = 0; + fyr->line++; + } else if (fyr->tabsize && fy_is_tab(c)) + fyr->column += (fyr->tabsize - (fyr->column % fyr->tabsize)); + else + fyr->column++; +} + +struct fy_input *fy_input_create(const struct fy_input_cfg *fyic) +{ + struct fy_input *fyi = NULL; + int ret; + + fyi = fy_input_alloc(); + if (!fyi) + return NULL; + fyi->cfg = *fyic; + + /* copy filename pointers and switch */ + switch (fyic->type) { + case fyit_file: + fyi->name = strdup(fyic->file.filename); + break; + case fyit_stream: + if (fyic->stream.name) + fyi->name = strdup(fyic->stream.name); + else if (fyic->stream.fp == stdin) + fyi->name = strdup(""); + else { + ret = asprintf(&fyi->name, "", + fileno(fyic->stream.fp)); + if (ret == -1) + fyi->name = NULL; + } + break; + case fyit_memory: + ret = asprintf(&fyi->name, "", + fyic->memory.data, fyic->memory.data + fyic->memory.size - 1); + if (ret == -1) + fyi->name = NULL; + break; + case fyit_alloc: + ret = asprintf(&fyi->name, "", + fyic->memory.data, fyic->memory.data + fyic->memory.size - 1); + if (ret == -1) + fyi->name = NULL; + break; + case fyit_callback: + ret = asprintf(&fyi->name, ""); + if (ret == -1) + fyi->name = NULL; + break; + default: + assert(0); + break; + } + if (!fyi->name) + goto err_out; + + fyi->buffer = NULL; + fyi->allocated = 0; + fyi->read = 0; + fyi->chunk = 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; + } + + /* default modes */ + fyi->lb_mode = fylb_cr_nl; + fyi->fws_mode = fyfws_space_tab; + + return fyi; + +err_out: + fy_input_unref(fyi); + return NULL; +} + +/* ensure that there are at least size octets available */ +const void *fy_reader_ensure_lookahead_slow_path(struct fy_reader *fyr, size_t size, size_t *leftp) +{ + const void *p; + size_t left; + + if (!leftp) + leftp = &left; + + p = fy_reader_ptr(fyr, leftp); + if (!p || *leftp < size) { + + fyr_debug(fyr, "ensure lookahead size=%zd left=%zd (%s - %zu)", + size, *leftp, + fy_input_get_filename(fyr->current_input), + fyr->current_input_pos); + + p = fy_reader_input_try_pull(fyr, fyr->current_input, size, leftp); + if (!p || *leftp < size) + return NULL; + + fyr->current_ptr = p; + fyr->current_left = *leftp; + fyr->current_c = fy_utf8_get(fyr->current_ptr, fyr->current_left, &fyr->current_w); + } + return p; +} + diff --git a/src/lib/fy-input.h b/src/lib/fy-input.h new file mode 100644 index 0000000..61316d2 --- /dev/null +++ b/src/lib/fy-input.h @@ -0,0 +1,669 @@ +/* + * fy-input.h - YAML input methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_INPUT_H +#define FY_INPUT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "fy-typelist.h" +#include "fy-ctype.h" + +#ifndef NDEBUG +#define __FY_DEBUG_UNUSED__ /* nothing */ +#else +#define __FY_DEBUG_UNUSED__ __attribute__((__unused__)) +#endif + +struct fy_atom; +struct fy_parser; + +enum fy_input_type { + fyit_file, + fyit_stream, + fyit_memory, + fyit_alloc, + fyit_callback, +}; + +struct fy_input_cfg { + enum fy_input_type type; + void *userdata; + union { + struct { + const char *filename; + } file; + struct { + const char *name; + FILE *fp; + size_t chunk; + bool ignore_stdio; + } stream; + struct { + const void *data; + size_t size; + } memory; + struct { + void *data; + size_t size; + } alloc; + struct { + /* negative return is error, 0 is EOF */ + ssize_t (*input)(void *user, void *buf, size_t count); + } callback; + }; +}; + +enum fy_input_state { + FYIS_NONE, + FYIS_QUEUED, + FYIS_PARSE_IN_PROGRESS, + FYIS_PARSED, +}; + +FY_TYPE_FWD_DECL_LIST(input); +struct fy_input { + struct list_head node; + enum fy_input_state state; + struct fy_input_cfg cfg; + 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; + void *addr; /* mmaped for files, allocated for streams */ + bool eof : 1; /* got EOF */ + bool err : 1; /* got an error */ + + /* propagated */ + 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); + +static inline const void *fy_input_start(const struct fy_input *fyi) +{ + const void *ptr = NULL; + + switch (fyi->cfg.type) { + case fyit_file: + if (fyi->addr) { + ptr = fyi->addr; + break; + } + /* fall-through */ + + case fyit_stream: + case fyit_callback: + ptr = fyi->buffer; + break; + + case fyit_memory: + ptr = fyi->cfg.memory.data; + break; + + case fyit_alloc: + ptr = fyi->cfg.alloc.data; + break; + + default: + break; + } + assert(ptr); + return ptr; +} + +static inline size_t fy_input_size(const struct fy_input *fyi) +{ + size_t size; + + switch (fyi->cfg.type) { + case fyit_file: + if (fyi->addr) { + size = fyi->file.length; + break; + } + /* fall-through */ + + case fyit_stream: + case fyit_callback: + size = fyi->read; + break; + + case fyit_memory: + size = fyi->cfg.memory.size; + break; + + case fyit_alloc: + size = fyi->cfg.alloc.size; + break; + + default: + size = 0; + break; + } + return size; +} + +struct fy_input *fy_input_alloc(void); +void fy_input_free(struct fy_input *fyi); + +static inline enum fy_input_state fy_input_get_state(struct fy_input *fyi) +{ + return fyi->state; +} + +struct fy_input *fy_input_create(const struct fy_input_cfg *fyic); + +const char *fy_input_get_filename(struct fy_input *fyi); + +struct fy_input *fy_input_from_data(const char *data, size_t size, + struct fy_atom *handle, bool simple); +struct fy_input *fy_input_from_malloc_data(char *data, size_t size, + struct fy_atom *handle, bool simple); + +void fy_input_close(struct fy_input *fyi); + +static inline struct fy_input * +fy_input_ref(struct fy_input *fyi) +{ + if (!fyi) + return NULL; + + + assert(fyi->refs + 1 > 0); + + fyi->refs++; + + return fyi; +} + +static inline void +fy_input_unref(struct fy_input *fyi) +{ + if (!fyi) + return; + + assert(fyi->refs > 0); + + if (fyi->refs == 1) + fy_input_free(fyi); + else + fyi->refs--; +} + +struct fy_reader; + +enum fy_reader_mode { + fyrm_yaml, + fyrm_json, + fyrm_yaml_1_1, /* yaml 1.1 mode */ +}; + +struct fy_reader_ops { + struct fy_diag *(*get_diag)(struct fy_reader *fyr); + int (*file_open)(struct fy_reader *fyr, const char *filename); +}; + +struct fy_reader_input_cfg { + bool disable_mmap_opt; +}; + +struct fy_reader { + const struct fy_reader_ops *ops; + enum fy_reader_mode mode; + + struct fy_reader_input_cfg current_input_cfg; + struct fy_input *current_input; + + 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 current_w; /* current utf8 character width */ + size_t current_left; /* currently left characters into the buffer */ + + int line; /* always on input */ + int column; + + int tabsize; /* very experimental tab size for indent purposes */ + + struct fy_diag *diag; +}; + +void fy_reader_reset(struct fy_reader *fyr); +void fy_reader_setup(struct fy_reader *fyr, const struct fy_reader_ops *ops); +void fy_reader_cleanup(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); + +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) +{ + if (!fyr || !fyr->current_input) + return; + + /* 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; + break; + } +} + +static inline enum fy_reader_mode +fy_reader_get_mode(const struct fy_reader *fyr) +{ + if (!fyr) + return fyrm_yaml; + return fyr->mode; +} + +static inline void +fy_reader_set_mode(struct fy_reader *fyr, enum fy_reader_mode mode) +{ + if (!fyr) + return; + + fyr->mode = mode; + fy_reader_apply_mode_to_input(fyr); +} + +static inline struct fy_input * +fy_reader_current_input(const struct fy_reader *fyr) +{ + if (!fyr) + return NULL; + return fyr->current_input; +} + +static inline uint64_t +fy_reader_current_input_generation(const struct fy_reader *fyr) +{ + if (!fyr || !fyr->current_input) + return 0; + return fyr->current_input->generation; +} + +static inline int +fy_reader_column(const struct fy_reader *fyr) +{ + if (!fyr) + return -1; + return fyr->column; +} + +static inline int +fy_reader_tabsize(const struct fy_reader *fyr) +{ + if (!fyr) + return -1; + return fyr->tabsize; +} + +static inline int +fy_reader_line(const struct fy_reader *fyr) +{ + if (!fyr) + return -1; + 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; + + /* force new line */ + if (fyr->column) { + fyr->column = 0; + fyr->line++; + } +} + +static inline void +fy_reader_get_mark(struct fy_reader *fyr, struct fy_mark *fym) +{ + assert(fyr); + fym->input_pos = fyr->current_input_pos; + fym->line = fyr->line; + fym->column = fyr->column; +} + +static inline const void * +fy_reader_ptr(struct fy_reader *fyr, size_t *leftp) +{ + if (fyr->current_ptr) { + if (leftp) + *leftp = fyr->current_left; + return fyr->current_ptr; + } + + return fy_reader_ptr_slow_path(fyr, leftp); +} + +static inline bool fy_reader_json_mode(const struct fy_reader *fyr) +{ + return fyr && fyr->mode == fyrm_json; +} + +static 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; +} + +static 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; +} + +static 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + return fy_reader_is_flow_ws(fyr, c); /* same */ +} + +static 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 * +fy_reader_ensure_lookahead(struct fy_reader *fyr, size_t size, size_t *leftp) +{ + if (fyr->current_ptr && fyr->current_left >= size) { + if (leftp) + *leftp = fyr->current_left; + return fyr->current_ptr; + } + return fy_reader_ensure_lookahead_slow_path(fyr, size, leftp); +} + +/* compare string at the current point (n max) */ +static inline int +fy_reader_strncmp(struct fy_reader *fyr, const char *str, size_t n) +{ + const char *p; + int ret; + + p = fy_reader_ensure_lookahead(fyr, n, NULL); + if (!p) + return -1; + ret = strncmp(p, str, n); + return ret ? 1 : 0; +} + +static inline int +fy_reader_peek_at_offset(struct fy_reader *fyr, size_t offset) +{ + const uint8_t *p; + size_t left; + int w; + + if (offset == 0 && fyr->current_c >= 0) + return fyr->current_c; + + /* ensure that the first octet at least is pulled in */ + p = fy_reader_ensure_lookahead(fyr, offset + 1, &left); + if (!p) + return FYUG_EOF; + + /* get width by first octet */ + w = fy_utf8_width_by_first_octet(p[offset]); + if (!w) + return FYUG_INV; + + /* make sure that there's enough to cover the utf8 width */ + if (offset + w > left) { + p = fy_reader_ensure_lookahead(fyr, offset + w, &left); + if (!p) + return FYUG_PARTIAL; + } + + return fy_utf8_get(p + offset, left - offset, &w); +} + +static inline int +fy_reader_peek_at_internal(struct fy_reader *fyr, int pos, ssize_t *offsetp) +{ + int i, c; + size_t offset; + + 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); + if (c < 0) + return c; + } + } else + offset = (size_t)*offsetp; + + c = fy_reader_peek_at_offset(fyr, offset); + + if (offsetp) + *offsetp = offset + fy_utf8_width(c); + + return c; +} + +static 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 +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 +fy_reader_peek_at(struct fy_reader *fyr, int pos) +{ + return fy_reader_peek_at_internal(fyr, pos, NULL); +} + +static inline int +fy_reader_peek(struct fy_reader *fyr) +{ + if (fyr->current_c >= 0) + return fyr->current_c; + + return fy_reader_peek_at_offset(fyr, 0); +} + +static inline const void * +fy_reader_peek_block(struct fy_reader *fyr, size_t *lenp) +{ + const void *p; + + /* try to pull at least one utf8 character usually */ + p = fy_reader_ensure_lookahead(fyr, 4, lenp); + + /* not a utf8 character available? try a single byte */ + if (!p) + p = fy_reader_ensure_lookahead(fyr, 1, lenp); + if (!*lenp) + p = NULL; + return p; +} + +static inline void +fy_reader_advance_octets(struct fy_reader *fyr, size_t advance) +{ + assert(fyr->current_left >= advance); + + fyr->current_input_pos += advance; + fyr->current_ptr += advance; + fyr->current_left -= advance; + + fyr->current_c = fy_utf8_get(fyr->current_ptr, fyr->current_left, &fyr->current_w); +} + +void fy_reader_advance_slow_path(struct fy_reader *fyr, int c); + +static inline void +fy_reader_advance_printable_ascii(struct fy_reader *fyr, int c) +{ + fy_reader_advance_octets(fyr, 1); + fyr->column++; +} + +static inline void +fy_reader_advance(struct fy_reader *fyr, int c) +{ + if (fy_utf8_is_printable_ascii(c)) + fy_reader_advance_printable_ascii(fyr, c); + else + fy_reader_advance_slow_path(fyr, c); +} + +static inline void +fy_reader_advance_ws(struct fy_reader *fyr, int c) +{ + /* skip this character */ + fy_reader_advance_octets(fyr, fy_utf8_width(c)); + + if (fyr->tabsize && fy_is_tab(c)) + fyr->column += (fyr->tabsize - (fyr->column % fyr->tabsize)); + else + fyr->column++; +} + +static inline void +fy_reader_advance_space(struct fy_reader *fyr) +{ + fy_reader_advance_octets(fyr, 1); + fyr->column++; +} + +static inline int +fy_reader_get(struct fy_reader *fyr) +{ + int value; + + value = fy_reader_peek(fyr); + if (value < 0) + return value; + + fy_reader_advance(fyr, value); + + return value; +} + +static inline int +fy_reader_advance_by(struct fy_reader *fyr, int count) +{ + int i, c; + + for (i = 0; i < count; i++) { + c = fy_reader_get(fyr); + if (c < 0) + break; + } + return i ? i : -1; +} + +/* compare string at the current point */ +static inline bool +fy_reader_strcmp(struct fy_reader *fyr, const char *str) +{ + return fy_reader_strncmp(fyr, str, strlen(str)); +} + +#endif diff --git a/src/lib/fy-list.h b/src/lib/fy-list.h new file mode 100644 index 0000000..1a0b5f9 --- /dev/null +++ b/src/lib/fy-list.h @@ -0,0 +1,705 @@ +/* + * fy-list.h - slightly modified Linux kernel list.h + * + * All copyrights owned by their respective holders. + * + * SPDX-License-Identifier: GPL-2.0 + */ +#ifndef _FY_LIST_H +#define _FY_LIST_H + +#include + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define LIST_POISON1 NULL +#define LIST_POISON2 NULL + +#ifndef ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCH +static inline void prefetch(const void *x) {;} +#endif + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} + +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +static inline void list_replace_init(struct list_head *old, + struct list_head *new) +{ + list_replace(old, new); + INIT_LIST_HEAD(old); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_last(const struct list_head *list, + const struct list_head *head) +{ + return list->next == head; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +/** + * list_empty_careful - tests whether a list is empty and not being modified + * @head: the list to test + * + * Description: + * tests whether a list is empty _and_ checks that no other CPU might be + * in the process of modifying either member (next or prev) + * + * NOTE: using list_empty_careful() without synchronization + * can only be safe if the only activity that can happen + * to the list entry is list_del_init(). Eg. it cannot be used + * if another CPU could re-list_add() it. + */ +static inline int list_empty_careful(const struct list_head *head) +{ + struct list_head *next = head->next; + return (next == head) && (next == head->prev); +} + +/** + * list_is_singular - tests whether a list has just one entry. + * @head: the list to test. + */ +static inline int list_is_singular(const struct list_head *head) +{ + return !list_empty(head) && (head->next == head->prev); +} + +static inline void __list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + struct list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + if (list_empty(head)) + return; + if (list_is_singular(head) && + (head->next != entry && head != entry)) + return; + if (entry == head) + INIT_LIST_HEAD(list); + else + __list_cut_position(list, head, entry); +} + +static inline void __list_splice(const struct list_head *list, + struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice - join two lists, this is designed for stacks + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(const struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice_tail(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head->prev, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head, head->next); + INIT_LIST_HEAD(list); + } +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void list_splice_tail_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head->prev, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/** + * list_last_entry - get the last element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; prefetch(pos->next), pos != (head); \ + pos = pos->next) + +/** + * __list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + * + * This variant differs from list_for_each() in that it's the + * simplest possible list iteration code, no prefetching is done. + * Use this for code that knows the list to be very short (empty + * or 1 entry) most of the time. + */ +#define __list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_prev_safe(pos, n, head) \ + for (pos = (head)->prev, n = pos->prev; \ + prefetch(pos->prev), pos != (head); \ + pos = n, n = pos->prev) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ + prefetch(pos->member.prev), &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() + * @pos: the type * to use as a start point + * @head: the head of the list + * @member: the name of the list_struct within the struct. + * + * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). + */ +#define list_prepare_entry(pos, head, member) \ + ((pos) ? : list_entry(head, typeof(*pos), member)) + +/** + * list_for_each_entry_continue - continue iteration over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Continue to iterate over list of given type, continuing after + * the current position. + */ +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = list_entry(pos->member.next, typeof(*pos), member); \ + prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_continue_reverse - iterate backwards from the given point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Start to iterate over list of given type backwards, continuing after + * the current position. + */ +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ + prefetch(pos->member.prev), &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_for_each_entry_from - iterate over list of given type from the current point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing from current position. + */ +#define list_for_each_entry_from(pos, head, member) \ + for (; prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_continue + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = list_entry(pos->member.next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_from + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define list_for_each_entry_safe_from(pos, n, head, member) \ + for (n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_reverse + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define list_for_each_entry_safe_reverse(pos, n, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member), \ + n = list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.prev, typeof(*n), member)) + +/* + * Double linked lists with a single pointer list head. + * Mostly useful for hash tables where the two pointer list head is + * too wasteful. + * You lose the ability to access the tail in O(1). + */ + +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +#define HLIST_HEAD_INIT { .first = NULL } +#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +static inline void INIT_HLIST_NODE(struct hlist_node *h) +{ + h->next = NULL; + h->pprev = NULL; +} + +static inline int hlist_unhashed(const struct hlist_node *h) +{ + return !h->pprev; +} + +static inline int hlist_empty(const struct hlist_head *h) +{ + return !h->first; +} + +static inline void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + *pprev = next; + if (next) + next->pprev = pprev; +} + +static inline void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = LIST_POISON1; + n->pprev = LIST_POISON2; +} + +static inline void hlist_del_init(struct hlist_node *n) +{ + if (!hlist_unhashed(n)) { + __hlist_del(n); + INIT_HLIST_NODE(n); + } +} + +static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + if (first) + first->pprev = &n->next; + h->first = n; + n->pprev = &h->first; +} + +/* next must be != NULL */ +static inline void hlist_add_before(struct hlist_node *n, + struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +static inline void hlist_add_after(struct hlist_node *n, + struct hlist_node *next) +{ + next->next = n->next; + n->next = next; + next->pprev = &n->next; + + if(next->next) + next->next->pprev = &next->next; +} + +#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + +#define hlist_for_each(pos, head) \ + for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ + pos = pos->next) + +#define hlist_for_each_safe(pos, n, head) \ + for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ + pos = n) + +/** + * hlist_for_each_entry - iterate over list of given type + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry(tpos, pos, head, member) \ + for (pos = (head)->first; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_continue - iterate over a hlist continuing after current point + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_continue(tpos, pos, member) \ + for (pos = (pos)->next; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_from - iterate over a hlist continuing from current point + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_from(tpos, pos, member) \ + for (; pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @n: another &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ + for (pos = (head)->first; \ + pos && ({ n = pos->next; 1; }) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = n) + +#endif diff --git a/src/lib/fy-parse.c b/src/lib/fy-parse.c new file mode 100644 index 0000000..3f59fe7 --- /dev/null +++ b/src/lib/fy-parse.c @@ -0,0 +1,6500 @@ +/* + * fy-parse.c - Internal parse interface + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" + +#include "fy-utils.h" + +/* only check atom sizes on debug */ +#ifndef NDEBUG +#define ATOM_SIZE_CHECK +#endif + +const char *fy_library_version(void) +{ +#ifndef VERSION +#warn No version defined + return "UNKNOWN"; +#else + return VERSION; +#endif +} + +int fy_parse_input_append(struct fy_parser *fyp, const struct fy_input_cfg *fyic) +{ + struct fy_input *fyi = NULL; + + fyi = fy_input_create(fyic); + fyp_error_check(fyp, fyp != NULL, err_out, + "fy_parse_input_create() failed!"); + + fyi->state = FYIS_QUEUED; + fy_input_list_add_tail(&fyp->queued_inputs, fyi); + + return 0; + +err_out: + fy_input_unref(fyi); + return -1; +} + +bool fy_parse_have_more_inputs(struct fy_parser *fyp) +{ + return !fy_input_list_empty(&fyp->queued_inputs); +} + +int fy_parse_get_next_input(struct fy_parser *fyp) +{ + const char *s; + struct fy_reader_input_cfg icfg; + struct fy_input *fyi; + int rc; + bool json_mode; + enum fy_reader_mode rdmode; + + assert(fyp); + + if (fy_reader_current_input(fyp->reader)) { + fyp_scan_debug(fyp, "get next input: already exists"); + return 1; + } + + /* get next queued input */ + fyi = fy_input_list_pop(&fyp->queued_inputs); + + /* none left? we're done */ + if (!fyi) { + fyp_scan_debug(fyp, "get next input: all inputs exhausted"); + return 0; + } + + json_mode = false; + if ((fyp->cfg.flags & (FYPCF_JSON_MASK << FYPCF_JSON_SHIFT)) == FYPCF_JSON_AUTO) { + /* detection only works for filenames (sucks) */ + if (fyi->cfg.type == fyit_file) { + s = fyi->cfg.file.filename; + if (s) + s = strrchr(s, '.'); + json_mode = s && !strcmp(s, ".json"); + } + } else if ((fyp->cfg.flags & (FYPCF_JSON_MASK << FYPCF_JSON_SHIFT)) == FYPCF_JSON_FORCE) + json_mode = true; + + /* set the initial reader mode according to json option and default version */ + if (!json_mode) + rdmode = fy_version_compare(&fyp->default_version, fy_version_make(1, 1)) <= 0 ? fyrm_yaml_1_1 : fyrm_yaml; + else + rdmode = fyrm_json; + + fy_reader_set_mode(fyp->reader, rdmode); + + memset(&icfg, 0, sizeof(icfg)); + icfg.disable_mmap_opt = !!(fyp->cfg.flags & FYPCF_DISABLE_MMAP_OPT); + + rc = fy_reader_input_open(fyp->reader, fyi, &icfg); + fyp_error_check(fyp, !rc, err_out, + "failed to open input"); + + /* take off the reference; reader now owns */ + fy_input_unref(fyi); + + fyp_scan_debug(fyp, "get next input: new input - %s mode", json_mode ? "JSON" : "YAML"); + + return 1; + +err_out: + fy_input_unref(fyi); + return -1; +} + +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); + 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: "); + return fyt; +} + +struct fy_token *fy_token_queue_internal(struct fy_parser *fyp, struct fy_token_list *fytl, + enum fy_token_type type, ...) +{ + va_list ap; + struct fy_token *fyt; + + va_start(ap, type); + fyt = fy_token_vqueue_internal(fyp, fytl, type, ap); + va_end(ap); + + return fyt; +} + +struct fy_token *fy_token_vqueue(struct fy_parser *fyp, enum fy_token_type type, va_list ap) +{ + struct fy_token *fyt; + + fyt = fy_token_vqueue_internal(fyp, &fyp->queued_tokens, type, ap); + if (fyt) + fyp->token_activity_counter++; + return fyt; +} + +struct fy_token *fy_token_queue(struct fy_parser *fyp, enum fy_token_type type, ...) +{ + va_list ap; + struct fy_token *fyt; + + va_start(ap, type); + fyt = fy_token_vqueue(fyp, type, ap); + va_end(ap); + + return fyt; +} + +const struct fy_version fy_default_version = { + .major = 1, + .minor = 2 +}; + +int fy_version_compare(const struct fy_version *va, const struct fy_version *vb) +{ + unsigned int vanum, vbnum; + + if (!va) + va = &fy_default_version; + if (!vb) + vb = &fy_default_version; + +#define FY_VERSION_UINT(_major, _minor) \ + ((((unsigned int)(_major) & 0xff) << 8) | ((unsigned int)((_minor) & 0xff))) + + vanum = FY_VERSION_UINT(va->major, va->minor); + vbnum = FY_VERSION_UINT(vb->major, vb->minor); + +#undef FY_VERSION_UINT + + return vanum == vbnum ? 0 : + vanum < vbnum ? -1 : 1; +} + +const struct fy_version * +fy_version_default(void) +{ + return &fy_default_version; +} + +static const struct fy_version * const fy_map_option_to_version[] = { + [FYPCF_DEFAULT_VERSION_AUTO >> FYPCF_DEFAULT_VERSION_SHIFT] = &fy_default_version, + [FYPCF_DEFAULT_VERSION_1_1 >> FYPCF_DEFAULT_VERSION_SHIFT] = fy_version_make(1, 1), + [FYPCF_DEFAULT_VERSION_1_2 >> FYPCF_DEFAULT_VERSION_SHIFT] = fy_version_make(1, 2), + [FYPCF_DEFAULT_VERSION_1_3 >> FYPCF_DEFAULT_VERSION_SHIFT] = fy_version_make(1, 3), +}; + +bool fy_version_is_supported(const struct fy_version *vers) +{ + unsigned int i; + const struct fy_version *vers_chk; + + if (!vers) + return true; /* NULL means default, which is supported */ + + for (i = 0; i < sizeof(fy_map_option_to_version)/sizeof(fy_map_option_to_version[0]); i++) { + + vers_chk = fy_map_option_to_version[i]; + if (!vers_chk) + continue; + + if (fy_version_compare(vers, vers_chk) == 0) + return true; + } + + return false; +} + +static const struct fy_version * +fy_parse_cfg_to_version(enum fy_parse_cfg_flags flags) +{ + unsigned int idx; + + idx = (flags >> FYPCF_DEFAULT_VERSION_SHIFT) & FYPCF_DEFAULT_VERSION_MASK; + + if (idx >= sizeof(fy_map_option_to_version)/sizeof(fy_map_option_to_version[0])) + return NULL; + + return fy_map_option_to_version[idx]; +} + +const struct fy_version *fy_version_supported_iterate(void **prevp) +{ + const struct fy_version * const *versp; + const struct fy_version *vers; + unsigned int idx; + + if (!prevp) + return NULL; + + versp = (const struct fy_version * const *)*prevp; + if (!versp) { + /* we skip over the first (which is the default) */ + versp = fy_map_option_to_version; + } + + versp++; + + idx = versp - fy_map_option_to_version; + if (idx >= sizeof(fy_map_option_to_version)/sizeof(fy_map_option_to_version[0])) + return NULL; + + vers = *versp; + *prevp = (void **)versp; + + return vers; +} + +const struct fy_tag * const fy_default_tags[] = { + &(struct fy_tag) { .handle = "!", .prefix = "!", }, + &(struct fy_tag) { .handle = "!!", .prefix = "tag:yaml.org,2002:", }, + &(struct fy_tag) { .handle = "", .prefix = "", }, + NULL +}; + +bool fy_tag_handle_is_default(const char *handle, size_t handle_size) +{ + int i; + const struct fy_tag *fytag; + + if (handle_size == (size_t)-1) + handle_size = strlen(handle); + + for (i = 0; (fytag = fy_default_tags[i]) != NULL; i++) { + + if (handle_size == strlen(fytag->handle) && + !memcmp(handle, fytag->handle, handle_size)) + return true; + + } + return false; +} + +bool fy_tag_is_default_internal(const char *handle, size_t handle_size, + const char *prefix, size_t prefix_size) +{ + int i; + const struct fy_tag *fytag; + + if (handle_size == (size_t)-1) + handle_size = strlen(handle); + + if (prefix_size == (size_t)-1) + prefix_size = strlen(prefix); + + for (i = 0; (fytag = fy_default_tags[i]) != NULL; i++) { + + if (handle_size == strlen(fytag->handle) && + !memcmp(handle, fytag->handle, handle_size) && + prefix_size == strlen(fytag->prefix) && + !memcmp(prefix, fytag->prefix, prefix_size)) + return true; + + } + return false; +} + +bool fy_document_state_tag_is_default(struct fy_document_state *fyds, const struct fy_tag *tag) +{ + struct fy_token *fyt_td; + + /* default tag, but it might be overriden */ + fyt_td = fy_document_state_lookup_tag_directive(fyds, tag->handle, strlen(tag->handle)); + if (!fyt_td) + return false; /* Huh? */ + + return fyt_td->tag_directive.is_default; +} + +bool fy_token_tag_directive_is_overridable(struct fy_token *fyt_td) +{ + const struct fy_tag *fytag; + const char *handle, *prefix; + size_t handle_size, prefix_size; + int i; + + if (!fyt_td) + return false; + + handle = fy_tag_directive_token_handle(fyt_td, &handle_size); + prefix = fy_tag_directive_token_prefix(fyt_td, &prefix_size); + if (!handle || !prefix) + return false; + + for (i = 0; (fytag = fy_default_tags[i]) != NULL; i++) { + + if (handle_size == strlen(fytag->handle) && + !memcmp(handle, fytag->handle, handle_size) && + prefix_size == strlen(fytag->prefix) && + !memcmp(prefix, fytag->prefix, prefix_size)) + return true; + + } + return false; +} + +int fy_reset_document_state(struct fy_parser *fyp) +{ + struct fy_document_state *fyds_new = NULL; + + fyp_scan_debug(fyp, "resetting document state"); + + if (!fyp->default_document_state) { + fyds_new = fy_document_state_default(&fyp->default_version, NULL); + fyp_error_check(fyp, fyds_new, err_out, + "fy_document_state_default() failed"); + } else { + fyds_new = fy_document_state_copy(fyp->default_document_state); + fyp_error_check(fyp, fyds_new, err_out, + "fy_document_state_copy() failed"); + } + + if (fyp->current_document_state) + fy_document_state_unref(fyp->current_document_state); + fyp->current_document_state = fyds_new; + + /* TODO check when cleaning flow lists */ + fyp->flow_level = 0; + fyp->flow = FYFT_NONE; + fy_parse_flow_list_recycle_all(fyp, &fyp->flow_stack); + + return 0; + +err_out: + return -1; +} + +int fy_parser_set_default_document_state(struct fy_parser *fyp, + struct fy_document_state *fyds) +{ + if (!fyp) + return -1; + + /* only in a safe state */ + if (fyp->state != FYPS_NONE && fyp->state != FYPS_END) + return -1; + + if (fyp->default_document_state != fyds) { + if (fyp->default_document_state) { + fy_document_state_unref(fyp->default_document_state); + fyp->default_document_state = NULL; + } + + if (fyds) + fyp->default_document_state = fy_document_state_ref(fyds); + } + + fy_reset_document_state(fyp); + + return 0; +} + +void fy_parser_set_next_single_document(struct fy_parser *fyp) +{ + if (!fyp) + return; + + fyp->next_single_document = true; +} + +int fy_check_document_version(struct fy_parser *fyp) +{ + int major, minor; + + major = fyp->current_document_state->version.major; + minor = fyp->current_document_state->version.minor; + + /* we only support YAML version 1.x */ + if (major == 1) { + /* 1.1 is supported without warnings */ + if (minor == 1) + goto ok; + + if (minor == 2 || minor == 3) + goto experimental; + } + + return -1; + +experimental: + fyp_scan_debug(fyp, "Experimental support for version %d.%d", + major, minor); +ok: + return 0; +} + +int fy_parse_version_directive(struct fy_parser *fyp, struct fy_token *fyt, bool scan_mode) +{ + struct fy_document_state *fyds; + const char *vs; + size_t vs_len; + char *vs0; + char *s, *e; + long v; + int rc; + + fyp_error_check(fyp, fyt && fyt->type == FYTT_VERSION_DIRECTIVE, err_out, + "illegal token (or missing) version directive token"); + + fyds = fyp->current_document_state; + fyp_error_check(fyp, fyds, err_out, + "no current document state error"); + + if (!scan_mode) { + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyds->fyt_vd, err_out, + "duplicate version directive"); + } else { + /* in scan mode, we just override everything */ + fy_token_unref_rl(fy_parse_recycled_token(fyp), fyds->fyt_vd); + fyds->fyt_vd = NULL; + } + + /* version directive of the form: MAJ.MIN */ + vs = fy_token_get_text(fyt, &vs_len); + fyp_error_check(fyp, vs, err_out, + "fy_token_get_text() failed"); + vs0 = alloca(vs_len + 1); + memcpy(vs0, vs, vs_len); + vs0[vs_len] = '\0'; + + /* parse version numbers */ + v = strtol(vs0, &e, 10); + fyp_error_check(fyp, e > vs0 && v >= 0 && v <= INT_MAX, err_out, + "illegal major version number (%s)", vs0); + fyp_error_check(fyp, *e == '.', err_out, + "illegal version separator"); + fyds->version.major = (int)v; + + s = e + 1; + v = strtol(s, &e, 10); + fyp_error_check(fyp, e > s && v >= 0 && v <= INT_MAX, err_out, + "illegal minor version number"); + fyp_error_check(fyp, *e == '\0', err_out, + "garbage after version number"); + fyds->version.minor = (int)v; + + fyp_scan_debug(fyp, "document parsed YAML version: %d.%d", + fyds->version.major, + fyds->version.minor); + + rc = fy_check_document_version(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "unsupport version number %d.%d", + fyds->version.major, + fyds->version.minor); + + fyds->version_explicit = true; + fyds->fyt_vd = fyt; + + return 0; +err_out: + rc = -1; +err_out_rc: + fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt); + return rc; +} + +int fy_parse_tag_directive(struct fy_parser *fyp, struct fy_token *fyt, bool scan_mode) +{ + struct fy_document_state *fyds; + struct fy_token *fyt_td; + const char *handle, *prefix; + size_t handle_size, prefix_size; + bool can_override; + + fyds = fyp->current_document_state; + fyp_error_check(fyp, fyds, err_out, + "no current document state error"); + + handle = fy_tag_directive_token_handle(fyt, &handle_size); + fyp_error_check(fyp, handle, err_out, + "bad tag directive token (handle)"); + + prefix = fy_tag_directive_token_prefix(fyt, &prefix_size); + fyp_error_check(fyp, prefix, err_out, + "bad tag directive token (prefix)"); + + fyt_td = fy_document_state_lookup_tag_directive(fyds, handle, handle_size); + + can_override = fyt_td && (fy_token_tag_directive_is_overridable(fyt_td) || scan_mode); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyt_td || can_override, err_out, + "duplicate tag directive"); + + 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); + /* when we override a default tag the tags are explicit */ + fyds->tags_explicit = true; + } + + fy_token_list_add_tail(&fyds->fyt_td, fyt); + fyt = NULL; + + fyp_scan_debug(fyp, "document parsed tag directive with handle=%.*s", + (int)handle_size, handle); + + if (!fy_tag_is_default_internal(handle, handle_size, prefix, prefix_size)) + fyds->tags_explicit = true; + + return 0; +err_out: + fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt); + return -1; +} + +static const struct fy_parse_cfg default_parse_cfg = { + .flags = FYPCF_DEFAULT_PARSE, +}; + +static struct fy_diag *fy_parser_reader_get_diag(struct fy_reader *fyr) +{ + struct fy_parser *fyp = container_of(fyr, struct fy_parser, builtin_reader); + return fyp->diag; +} + +static int fy_parser_reader_file_open(struct fy_reader *fyr, const char *name) +{ + struct fy_parser *fyp = container_of(fyr, struct fy_parser, builtin_reader); + char *sp, *s, *e, *t, *newp; + size_t len, maxlen; + int fd; + + if (!fyp || !name || name[0] == '\0') + return -1; + + /* for a full path, or no search path, open directly */ + if (name[0] == '/' || !fyp->cfg.search_path || !fyp->cfg.search_path[0]) { + fd = open(name, O_RDONLY); + if (fd == -1) + fyp_scan_debug(fyp, "failed to open file %s\n", name); + else + fyp_scan_debug(fyp, "opened file %s\n", name); + return fd; + } + + len = strlen(fyp->cfg.search_path); + sp = alloca(len + 1); + memcpy(sp, fyp->cfg.search_path, len + 1); + + /* allocate the maximum possible so that we don't deal with reallocations */ + maxlen = len + 1 + strlen(name); + newp = malloc(maxlen + 1); + if (!newp) + return -1; + + s = sp; + e = sp + strlen(s); + while (s < e) { + /* skip completely empty */ + if (*s == ':') { + s++; + continue; + } + + t = strchr(s, ':'); + if (t) + *t++ = '\0'; + else + t = e; + + len = strlen(s) + 1 + strlen(name) + 1; + snprintf(newp, maxlen, "%s/%s", s, name); + + /* try opening */ + fd = open(newp, O_RDONLY); + if (fd != -1) { + fyp_scan_debug(fyp, "opened file %s at %s", name, newp); + free(newp); + return fd; + } + + s = t; + } + + if (newp) + free(newp); + return -1; +} + +static const struct fy_reader_ops fy_parser_reader_ops = { + .get_diag = fy_parser_reader_get_diag, + .file_open = fy_parser_reader_file_open, +}; + +int fy_parse_setup(struct fy_parser *fyp, const struct fy_parse_cfg *cfg) +{ + struct fy_diag *diag; + struct fy_diag_cfg dcfg; + const struct fy_version *vers; + int rc; + + if (!fyp) + return -1; + + memset(fyp, 0, sizeof(*fyp)); + + diag = cfg ? cfg->diag : NULL; + fyp->cfg = cfg ? *cfg : default_parse_cfg; + + /* supported version? */ + vers = fy_parse_cfg_to_version(fyp->cfg.flags); + if (!vers) + return -1; + + if (!diag) { + fy_diag_cfg_default(&dcfg); + diag = fy_diag_create(&dcfg); + if (!diag) + return -1; + } else + fy_diag_ref(diag); + + fyp->diag = diag; + + fy_reader_setup(&fyp->builtin_reader, &fy_parser_reader_ops); + fyp->reader = &fyp->builtin_reader; + + fyp->default_version = *vers; + + fy_indent_list_init(&fyp->indent_stack); + fy_indent_list_init(&fyp->recycled_indent); + fyp->indent = -2; + fyp->indent_line = -1; + fyp->generated_block_map = false; + fyp->last_was_comma = false; + + fy_simple_key_list_init(&fyp->simple_keys); + fy_simple_key_list_init(&fyp->recycled_simple_key); + + fy_token_list_init(&fyp->queued_tokens); + + fy_input_list_init(&fyp->queued_inputs); + + fyp->state = FYPS_NONE; + fy_parse_state_log_list_init(&fyp->state_stack); + fy_parse_state_log_list_init(&fyp->recycled_parse_state_log); + + fy_eventp_list_init(&fyp->recycled_eventp); + fy_token_list_init(&fyp->recycled_token); + + fy_flow_list_init(&fyp->flow_stack); + fyp->flow = FYFT_NONE; + fy_flow_list_init(&fyp->recycled_flow); + + fyp->pending_complex_key_column = -1; + fyp->last_block_mapping_key_line = -1; + + fyp->suppress_recycling = !!(fyp->cfg.flags & FYPCF_DISABLE_RECYCLING) || + (getenv("FY_VALGRIND") && + !getenv("FY_VALGRIND_RECYCLING")); + + if (fyp->suppress_recycling) + fyp_parse_debug(fyp, "Suppressing recycling"); + + fyp->current_document_state = NULL; + + rc = fy_reset_document_state(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_reset_document_state() failed"); + return 0; + +err_out_rc: + return rc; +} + +void fy_parse_cleanup(struct fy_parser *fyp) +{ + struct fy_input *fyi, *fyin; + struct fy_token *fyt; + + fy_composer_destroy(fyp->fyc); + fy_document_builder_destroy(fyp->fydb); + + fy_parse_indent_list_recycle_all(fyp, &fyp->indent_stack); + fy_parse_simple_key_list_recycle_all(fyp, &fyp->simple_keys); + fy_token_list_unref_all(&fyp->queued_tokens); + + 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_document_state_unref(fyp->current_document_state); + fy_document_state_unref(fyp->default_document_state); + + for (fyi = fy_input_list_head(&fyp->queued_inputs); fyi; fyi = fyin) { + fyin = fy_input_next(&fyp->queued_inputs, fyi); + fy_input_unref(fyi); + } + + /* clean the builtin reader */ + fy_reader_cleanup(&fyp->builtin_reader); + + /* and vacuum (free everything) */ + 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); + + /* and the recycled tokens */ + while ((fyt = fy_token_list_pop(&fyp->recycled_token)) != NULL) + fy_token_free(fyt); + + fy_diag_unref(fyp->diag); +} + +static const char *state_txt[] __FY_DEBUG_UNUSED__ = { + [FYPS_NONE] = "NONE", + [FYPS_STREAM_START] = "STREAM_START", + [FYPS_IMPLICIT_DOCUMENT_START] = "IMPLICIT_DOCUMENT_START", + [FYPS_DOCUMENT_START] = "DOCUMENT_START", + [FYPS_DOCUMENT_CONTENT] = "DOCUMENT_CONTENT", + [FYPS_DOCUMENT_END] = "DOCUMENT_END", + [FYPS_BLOCK_NODE] = "BLOCK_NODE", + [FYPS_BLOCK_SEQUENCE_FIRST_ENTRY] = "BLOCK_SEQUENCE_FIRST_ENTRY", + [FYPS_BLOCK_SEQUENCE_ENTRY] = "BLOCK_SEQUENCE_ENTRY", + [FYPS_INDENTLESS_SEQUENCE_ENTRY] = "INDENTLESS_SEQUENCE_ENTRY", + [FYPS_BLOCK_MAPPING_FIRST_KEY] = "BLOCK_MAPPING_FIRST_KEY", + [FYPS_BLOCK_MAPPING_KEY] = "BLOCK_MAPPING_KEY", + [FYPS_BLOCK_MAPPING_VALUE] = "BLOCK_MAPPING_VALUE", + [FYPS_FLOW_SEQUENCE_FIRST_ENTRY] = "FLOW_SEQUENCE_FIRST_ENTRY", + [FYPS_FLOW_SEQUENCE_ENTRY] = "FLOW_SEQUENCE_ENTRY", + [FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_KEY] = "FLOW_SEQUENCE_ENTRY_MAPPING_KEY", + [FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE] = "FLOW_SEQUENCE_ENTRY_MAPPING_VALUE", + [FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END] = "FLOW_SEQUENCE_ENTRY_MAPPING_END", + [FYPS_FLOW_MAPPING_FIRST_KEY] = "FLOW_MAPPING_FIRST_KEY", + [FYPS_FLOW_MAPPING_KEY] = "FLOW_MAPPING_KEY", + [FYPS_FLOW_MAPPING_VALUE] = "FLOW_MAPPING_VALUE", + [FYPS_FLOW_MAPPING_EMPTY_VALUE] = "FLOW_MAPPING_EMPTY_VALUE", + [FYPS_SINGLE_DOCUMENT_END] = "SINGLE_DOCUMENT_END", + [FYPS_END] = "END" +}; + +int fy_scan_comment(struct fy_parser *fyp, struct fy_atom *handle, bool single_line) +{ + int c, column, start_column, lines, scan_ahead; + bool has_ws; + + c = fy_parse_peek(fyp); + if (c != '#') + return -1; + + /* if it's no comment parsing is enabled just consume it */ + if (!(fyp->cfg.flags & FYPCF_PARSE_COMMENTS) || !handle) { + fy_advance(fyp, c); + while (!(fyp_is_lbz(fyp, c = fy_parse_peek(fyp)))) + fy_advance(fyp, c); + return 0; + } + + if (handle->fyi) + fy_input_unref(handle->fyi); + + memset(handle, 0, sizeof(*handle)); + + fy_fill_atom_start(fyp, handle); + + lines = 0; + start_column = fyp_column(fyp); + column = fyp_column(fyp); + scan_ahead = 0; + + has_ws = false; + + /* continuation must be a # on the same column */ + while (c == '#' && column == start_column) { + + lines++; + if (c == '#') { + /* chomp until line break */ + fy_advance(fyp, c); + while (!(fyp_is_lbz(fyp, c = fy_parse_peek(fyp)))) { + if (fy_is_ws(c)) + has_ws = true; + fy_advance(fyp, c); + } + + /* end of input break */ + if (fy_is_z(c)) + break; + } + + if (fy_is_ws(c)) + has_ws = true; + + if (!fyp_is_lb(fyp, c)) + break; + + column = 0; + + scan_ahead = 1; /* skipping over lb */ + while (fy_is_blank(c = fy_parse_peek_at(fyp, scan_ahead))) { + scan_ahead++; + column++; + } + + if (fy_is_z(c) || single_line) + break; + + if (c == '#' && column == start_column) { + fy_advance_by(fyp, scan_ahead); + c = fy_parse_peek(fyp); + } + } + + fy_fill_atom_end(fyp, handle); + handle->style = FYAS_COMMENT; + handle->direct_output = false; + handle->storage_hint = 0; + handle->storage_hint_valid = false; + handle->empty = false; + handle->has_lb = true; + handle->has_ws = has_ws; + handle->starts_with_ws = false; /* no-one cares for those */ + handle->starts_with_lb = false; + handle->ends_with_ws = false; + handle->ends_with_lb = false; + handle->trailing_lb = false; + handle->size0 = lines > 0; + handle->valid_anchor = false; + + /* and take the ref */ + fy_input_ref(handle->fyi); + + return 0; +} + +int fy_attach_comments_if_any(struct fy_parser *fyp, struct fy_token *fyt) +{ + struct fy_atom *handle; + struct fy_mark fym; + int c, rc; + + if (!fyp || !fyt) + return -1; + + if (!(fyp->cfg.flags & FYPCF_PARSE_COMMENTS)) + return 0; + + /* if a last comment exists and is valid */ + if (fy_atom_is_set(&fyp->last_comment) && + (handle = fy_token_comment_handle(fyt, fycp_top, true)) != NULL) { + assert (!fy_atom_is_set(handle)); + *handle = fyp->last_comment; + /* erase last comment */ + fy_atom_reset(&fyp->last_comment); + } + + /* right hand comment */ + + /* skip white space */ + while (fy_is_ws(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + if (c == '#') { + fy_get_mark(fyp, &fym); + + /* it's a right comment only if it's on the same line */ + if (fym.line == fyt->handle.end_mark.line) + handle = fy_token_comment_handle(fyt, fycp_right, true); + else + handle = &fyp->last_comment; /* otherwise, last comment */ + + rc = fy_scan_comment(fyp, handle, false); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_comment() failed"); + } + return 0; + +err_out_rc: + return rc; +} + +int fy_scan_to_next_token(struct fy_parser *fyp) +{ + int c, c_after_ws, i, rc = 0; + bool tabs_allowed; + ssize_t offset; + struct fy_atom *handle; + struct fy_reader *fyr; + + fyr = fyp->reader; + + /* skip BOM at the start of the stream */ + if (fyr->current_input_pos == 0 && (c = fy_parse_peek(fyp)) == FY_UTF8_BOM) { + + fy_advance(fyp, c); + /* reset column */ + fyr->column = 0; + } + + /* json does not have comments or tab handling... */ + if (fyp_json_mode(fyp)) { + fy_reader_skip_ws_cr_nl(fyr); + goto done; + } + + for (;;) { + + tabs_allowed = fyp->flow_level || !fyp->simple_key_allowed; + + /* 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) { + /* 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 */ + 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++; + + /* flow start marker after spaces? allow tabs */ + if (c_after_ws == '{' || c_after_ws == '[') { + fy_advance_by(fyp, i); + c = fy_parse_peek(fyp); + } + } + } else { + fy_reader_skip_ws(fyr); + c = fy_parse_peek(fyp); + } + + /* comment? */ + if (c == '#') { + + handle = NULL; + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) + handle = &fyp->last_comment; + + rc = fy_scan_comment(fyp, handle, false); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_comment() failed"); + } + + c = fy_parse_peek(fyp); + + /* not linebreak? we're done */ + if (!fyp_is_lb(fyp, c)) + goto done; + + /* line break */ + fy_advance(fyp, c); + + /* may start simple key (in block ctx) */ + if (!fyp->flow_level) { + fyp->simple_key_allowed = true; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + } + } + + fyp_scan_debug(fyp, "%s: no-next-token", __func__); + +err_out_rc: + return rc; + +done: + fyp_scan_debug(fyp, "%s: next token starts with c='%s'", __func__, + fy_utf8_format_a(fy_parse_peek(fyp), fyue_singlequote)); + return 0; +} + +static void fy_purge_required_simple_key_report(struct fy_parser *fyp, + struct fy_token *fyt, enum fy_token_type next_type) +{ + bool is_anchor, is_tag; + + is_anchor = fyt && fyt->type == FYTT_ANCHOR; + is_tag = fyt && fyt->type == FYTT_TAG; + + if (is_anchor || is_tag) { + if ((fyp->state == FYPS_BLOCK_MAPPING_VALUE || + fyp->state == FYPS_BLOCK_MAPPING_FIRST_KEY) && + next_type == FYTT_BLOCK_ENTRY) { + + FYP_TOKEN_ERROR(fyp, fyt, FYEM_SCAN, + "invalid %s indent for sequence", + is_anchor ? "anchor" : "tag"); + return; + } + + if (fyp->state == FYPS_BLOCK_MAPPING_VALUE && next_type == FYTT_SCALAR) { + FYP_TOKEN_ERROR(fyp, fyt, FYEM_SCAN, + "invalid %s indent for mapping", + is_anchor ? "anchor" : "tag"); + return; + } + } + + if (fyt) + FYP_TOKEN_ERROR(fyp, fyt, FYEM_SCAN, + "could not find expected ':'"); + else + FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN, + "could not find expected ':'"); +} + +static int fy_purge_stale_simple_keys(struct fy_parser *fyp, bool *did_purgep, + enum fy_token_type next_type) +{ + struct fy_simple_key *fysk; + bool purge; + int line; + + *did_purgep = false; + while ((fysk = fy_simple_key_list_head(&fyp->simple_keys)) != NULL) { + + fyp_scan_debug(fyp, "purge-check: flow_level=%d fysk->flow_level=%d fysk->mark.line=%d line=%d", + fyp->flow_level, fysk->flow_level, + fysk->mark.line, fyp_line(fyp)); + + fyp_debug_dump_simple_key(fyp, fysk, "purge-check: "); + + line = fysk->mark.line; + + /* in non-flow context we purge keys that are on different line */ + /* in flow context we purge only those with higher flow level */ + if (!fyp->flow_level) { + purge = fyp_line(fyp) > line; + } else { + purge = fyp->flow_level < fysk->flow_level; + /* also purge implicit complex keys on a different line */ + if (!purge && fysk->implicit_complex) { + purge = fyp_line(fyp) > line; + } + } + + if (!purge) + break; + + if (fysk->required) { + fy_purge_required_simple_key_report(fyp, fysk->token, next_type); + goto err_out; + } + + fyp_debug_dump_simple_key(fyp, fysk, "purging: "); + + fy_simple_key_list_del(&fyp->simple_keys, fysk); + fy_parse_simple_key_recycle(fyp, fysk); + + *did_purgep = true; + } + + if (*did_purgep && fy_simple_key_list_empty(&fyp->simple_keys)) + fyp_scan_debug(fyp, "(purge) simple key list is now empty!"); + + return 0; + +err_out: + return -1; +} + +int fy_push_indent(struct fy_parser *fyp, int indent, bool generated_block_map, int indent_line) +{ + struct fy_indent *fyit; + + fyit = fy_parse_indent_alloc(fyp); + fyp_error_check(fyp, fyit != NULL, err_out, + "fy_indent_alloc() failed"); + + fyit->indent = fyp->indent; + fyit->indent_line = fyp->indent_line; + fyit->generated_block_map = fyp->generated_block_map; + + /* push */ + fy_indent_list_push(&fyp->indent_stack, fyit); + + /* update current state */ + fyp->parent_indent = fyp->indent; + fyp->indent = indent; + fyp->indent_line = indent_line; + fyp->generated_block_map = generated_block_map; + + fyp_scan_debug(fyp, "push_indent %d -> %d - generated_block_map=%s\n", + fyp->parent_indent, fyp->indent, + fyp->generated_block_map ? "true" : "false"); + + return 0; + +err_out: + return -1; +} + +int fy_pop_indent(struct fy_parser *fyp) +{ + struct fy_indent *fyit; + int prev_indent __FY_DEBUG_UNUSED__; + + fyit = fy_indent_list_pop(&fyp->indent_stack); + if (!fyit) + return -1; + + prev_indent = fyp->indent; + + /* pop the indent and update */ + fyp->indent = fyit->indent; + fyp->generated_block_map = fyit->generated_block_map; + fyp->indent_line = fyit->indent_line; + + /* pop and recycle */ + fy_parse_indent_recycle(fyp, fyit); + + /* update the parent indent */ + fyit = fy_indent_list_head(&fyp->indent_stack); + fyp->parent_indent = fyit ? fyit->indent : -2; + + fyp_scan_debug(fyp, "pop indent %d -> %d (parent %d) - generated_block_map=%s\n", + prev_indent, fyp->indent, fyp->parent_indent, + fyp->generated_block_map ? "true" : "false"); + + return 0; +} + +int fy_parse_unroll_indent(struct fy_parser *fyp, int column) +{ + struct fy_token *fyt; + int rc; + + /* do nothing in flow context */ + if (fyp->flow_level) + return 0; + + /* pop while indentation level greater than argument */ + while (fyp->indent > column) { + + 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)); + fyp_error_check(fyp, fyt, err_out, + "fy_token_queue() failed"); + + rc = fy_pop_indent(fyp); + fyp_error_check(fyp, !rc, err_out, + "fy_pop_indent() failed"); + + /* the ident line has now moved */ + fyp->indent_line = fyp_line(fyp); + } + return 0; +err_out: + return -1; +} + +void fy_remove_all_simple_keys(struct fy_parser *fyp) +{ + struct fy_simple_key *fysk; + + fyp_scan_debug(fyp, "SK: removing all"); + + while ((fysk = fy_simple_key_list_pop(&fyp->simple_keys)) != NULL) + fy_parse_simple_key_recycle(fyp, fysk); + + fyp->simple_key_allowed = true; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); +} + +struct fy_simple_key *fy_would_remove_required_simple_key(struct fy_parser *fyp) +{ + struct fy_simple_key *fysk; + + /* no simple key? */ + for (fysk = fy_simple_key_list_head(&fyp->simple_keys); + fysk && fysk->flow_level >= fyp->flow_level; + fysk = fy_simple_key_next(&fyp->simple_keys, fysk)) { + if (fysk->required) + return fysk; + } + + return NULL; +} + +int fy_remove_simple_key(struct fy_parser *fyp, enum fy_token_type next_type) +{ + struct fy_simple_key *fysk; + + /* no simple key? */ + while ((fysk = fy_simple_key_list_first(&fyp->simple_keys)) != NULL && + fysk->flow_level >= fyp->flow_level) { + + fyp_debug_dump_simple_key(fyp, fysk, "removing: "); + + /* remove it from the list */ + fy_simple_key_list_del(&fyp->simple_keys, fysk); + + if (fysk->required) { + fy_purge_required_simple_key_report(fyp, fysk->token, next_type); + goto err_out; + } + + fy_parse_simple_key_recycle(fyp, fysk); + } + + return 0; + +err_out: + fy_parse_simple_key_recycle(fyp, fysk); + return -1; +} + +struct fy_simple_key *fy_simple_key_find(struct fy_parser *fyp, const struct fy_token *fyt) +{ + struct fy_simple_key *fysk; + + if (!fyt) + return NULL; + + /* no simple key? */ + for (fysk = fy_simple_key_list_head(&fyp->simple_keys); fysk; + fysk = fy_simple_key_next(&fyp->simple_keys, fysk)) + if (fysk->token == fyt) + return fysk; + + return NULL; +} + +int fy_save_simple_key(struct fy_parser *fyp, struct fy_mark *mark, struct fy_mark *end_mark, + struct fy_token *fyt, bool required, int flow_level, + enum fy_token_type next_type) +{ + struct fy_simple_key *fysk; + bool did_purge; + int rc; + + 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 no simple key is allowed, don't save */ + if (!fyp->simple_key_allowed) { + fyp_scan_debug(fyp, "not saving simple key; not allowed"); + return 0; + } + + /* remove pending complex key mark if in non flow context and a new line */ + if (!fyp->flow_level && fyp->pending_complex_key_column >= 0 && + mark->line > fyp->pending_complex_key_mark.line && + mark->column <= fyp->pending_complex_key_mark.column ) { + + fyp_scan_debug(fyp, "resetting pending_complex_key mark->line=%d line=%d\n", + mark->line, fyp->pending_complex_key_mark.line); + + fyp->pending_complex_key_column = -1; + fyp_scan_debug(fyp, "pending_complex_key_column -> %d", + fyp->pending_complex_key_column); + } + + fysk = fy_simple_key_list_head(&fyp->simple_keys); + + /* create new simple key if it does not exist or if has flow level less */ + if (!fysk || fysk->flow_level < fyp->flow_level) { + + fysk = fy_parse_simple_key_alloc(fyp); + fyp_error_check(fyp, fysk != NULL, err_out, + "fy_simple_key_alloc()"); + + fyp_scan_debug(fyp, "new simple key"); + + fy_simple_key_list_push(&fyp->simple_keys, fysk); + + } else { + fyp_error_check(fyp, !fysk->required, err_out, + "cannot save simple key, top is required"); + + if (fysk == fy_simple_key_list_tail(&fyp->simple_keys)) + fyp_scan_debug(fyp, "(reuse) simple key list is now empty!"); + + fyp_scan_debug(fyp, "reusing simple key"); + + } + + fysk->mark = *mark; + fysk->end_mark = *end_mark; + + fysk->required = required; + fysk->token = fyt; + fysk->flow_level = flow_level; + + /* if this is a an implicit flow collection key */ + fysk->implicit_complex = fyp->pending_complex_key_column < 0 && + (fyt->type == FYTT_FLOW_MAPPING_START || fyt->type == FYTT_FLOW_SEQUENCE_START); + + + fyp_debug_dump_simple_key_list(fyp, &fyp->simple_keys, fysk, "fyp->simple_keys (saved): "); + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +struct fy_simple_key_mark { + struct fy_mark mark; + bool required; + int flow_level; +}; + +void fy_get_simple_key_mark(struct fy_parser *fyp, struct fy_simple_key_mark *fyskm) +{ + fy_get_mark(fyp, &fyskm->mark); + fyskm->flow_level = fyp->flow_level; + fyskm->required = !fyp->flow_level && fyp->indent == fyp_column(fyp); +} + +int fy_save_simple_key_mark(struct fy_parser *fyp, + struct fy_simple_key_mark *fyskm, + enum fy_token_type next_type, + struct fy_mark *end_markp) +{ + struct fy_mark end_mark; + + if (!end_markp) { + fy_get_mark(fyp, &end_mark); + end_markp = &end_mark; + } + + return fy_save_simple_key(fyp, &fyskm->mark, end_markp, + fy_token_list_last(&fyp->queued_tokens), + fyskm->required, fyskm->flow_level, + next_type); +} + +int fy_parse_flow_push(struct fy_parser *fyp) +{ + struct fy_flow *fyf; + + fyf = fy_parse_flow_alloc(fyp); + fyp_error_check(fyp, fyf != NULL, err_out, + "fy_flow_alloc() failed!"); + fyf->flow = fyp->flow; + + fyf->pending_complex_key_column = fyp->pending_complex_key_column; + fyf->pending_complex_key_mark = fyp->pending_complex_key_mark; + + fyp_scan_debug(fyp, "flow_push: flow=%d pending_complex_key_column=%d", + (int)fyf->flow, + fyf->pending_complex_key_column); + + fy_flow_list_push(&fyp->flow_stack, fyf); + + if (fyp->pending_complex_key_column >= 0) { + fyp->pending_complex_key_column = -1; + fyp_scan_debug(fyp, "pending_complex_key_column -> %d", + fyp->pending_complex_key_column); + } + + return 0; +err_out: + return -1; +} + +int fy_parse_flow_pop(struct fy_parser *fyp) +{ + struct fy_flow *fyf; + + fyf = fy_flow_list_pop(&fyp->flow_stack); + fyp_error_check(fyp, fyf, err_out, + "no flow to pop"); + + fyp->flow = fyf->flow; + fyp->pending_complex_key_column = fyf->pending_complex_key_column; + fyp->pending_complex_key_mark = fyf->pending_complex_key_mark; + + fy_parse_flow_recycle(fyp, fyf); + + fyp_scan_debug(fyp, "flow_pop: flow=%d pending_complex_key_column=%d", + (int)fyp->flow, + fyp->pending_complex_key_column); + + return 0; + +err_out: + return -1; +} + + +int fy_fetch_stream_start(struct fy_parser *fyp) +{ + struct fy_token *fyt; + + /* simple key is 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)); + fyp_error_check(fyp, fyt, err_out, + "fy_token_queue() failed"); + return 0; + +err_out: + return -1; +} + +int fy_fetch_stream_end(struct fy_parser *fyp) +{ + struct fy_token *fyt; + int rc; + + /* only reset the stream in regular mode */ + if (!fyp->parse_flow_only) + fy_reader_stream_end(fyp->reader); + + 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"); + + 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"); + + return 0; + +err_out_rc: + return rc; +} + +int fy_scan_tag_uri_length(struct fy_parser *fyp, int start) +{ + int c, cn, length; + ssize_t offset, offset1; + + /* first find the utf8 length of the uri */ + length = 0; + offset = -1; + while (fy_is_uri(c = fy_parse_peek_at_internal(fyp, start + length, &offset))) { + + offset1 = offset; + cn = fy_parse_peek_at_internal(fyp, start + length + 1, &offset1); + + /* special handling for detecting URIs ending in ,}] */ + if (fyp_is_blankz(fyp, cn) && fy_utf8_strchr(",}]", c)) + break; + + length++; + } + + return length; +} + +bool fy_scan_tag_uri_is_valid(struct fy_parser *fyp, int start, int length) +{ + int i, j, k, width, c, w; + uint8_t octet, esc_octets[4]; + ssize_t offset; + + offset = -1; + for (i = 0; i < length; i++) { + c = fy_parse_peek_at_internal(fyp, start + i, &offset); + if (c != '%') + continue; + /* reset cursor */ + offset = -1; + + width = 0; + k = 0; + do { + /* % escape */ + FYP_PARSE_ERROR_CHECK(fyp, start + i, 1, FYEM_SCAN, + (length - i) >= 3, err_out, + "short URI escape"); + + if (width > 0) { + c = fy_parse_peek_at(fyp, start + i); + + FYP_PARSE_ERROR_CHECK(fyp, start + i, 1, FYEM_SCAN, + c == '%', err_out, + "missing URI escape"); + } + + octet = 0; + + for (j = 0; j < 2; j++) { + c = fy_parse_peek_at(fyp, start + i + 1 + j); + + FYP_PARSE_ERROR_CHECK(fyp, start + i + 1 + j, 1, FYEM_SCAN, + fy_is_hex(c), err_out, + "non hex URI escape"); + octet <<= 4; + if (c >= '0' && c <= '9') + octet |= c - '0'; + else if (c >= 'a' && c <= 'f') + octet |= 10 + c - 'a'; + else + octet |= 10 + c - 'A'; + } + if (!width) { + width = fy_utf8_width_by_first_octet(octet); + + FYP_PARSE_ERROR_CHECK(fyp, start + i + 1 + j, 1, FYEM_SCAN, + width >= 1 && width <= 4, err_out, + "bad width for hex URI escape"); + k = 0; + } + esc_octets[k++] = octet; + + /* skip over the 3 character escape */ + i += 3; + + } while (--width > 0); + + /* now convert to utf8 */ + c = fy_utf8_get(esc_octets, k, &w); + + FYP_PARSE_ERROR_CHECK(fyp, start + i, 1 + j, FYEM_SCAN, + c >= 0, err_out, + "bad utf8 URI escape"); + } + return true; +err_out: + return false; +} + +int fy_scan_tag_handle_length(struct fy_parser *fyp, int start) +{ + int c, length, i, width; + ssize_t offset; + uint8_t octet; + bool first, was_esc; + + length = 0; + + offset = -1; + c = fy_parse_peek_at_internal(fyp, start + length, &offset); + + FYP_PARSE_ERROR_CHECK(fyp, start + length, 1, FYEM_SCAN, + c == '!', err_out, + "invalid tag handle start"); + length++; + + /* get first character of the tag */ + c = fy_parse_peek_at_internal(fyp, start + length, &offset); + + if (fy_is_ws(c)) + return length; + + /* if first character is !, empty handle */ + if (c == '!') { + length++; + return length; + } + + first = true; + was_esc = false; + + /* now loop while it's alphanumeric */ + for (;;) { + if (c == '%') { + + octet = 0; + + for (i = 0; i < 2; i++) { + c = fy_parse_peek_at_internal(fyp, start + length + 1 + i, &offset); + FYP_PARSE_ERROR_CHECK(fyp, start + length + 1 + i, 1, FYEM_SCAN, + fy_is_hex(c), err_out, + "non hex URI escape"); + octet <<= 4; + if (c >= '0' && c <= '9') + octet |= c - '0'; + else if (c >= 'a' && c <= 'f') + octet |= 10 + c - 'a'; + else + octet |= 10 + c - 'A'; + } + + width = fy_utf8_width_by_first_octet(octet); + FYP_PARSE_ERROR_CHECK(fyp, start + length, 3, FYEM_SCAN, + width == 1, err_out, + "Illegal non 1 byte utf8 tag handle character"); + c = octet; + was_esc = true; + + } else + was_esc = false; + + if ((first && fy_is_first_alnum(c)) || (!first && fy_is_alnum(c))) + length += was_esc ? 3 : 1; + else + break; + + first = false; + c = fy_parse_peek_at_internal(fyp, start + length, &offset); + } + + /* if last character is !, copy it */ + if (c == '!') + length++; + + return length; + +err_out: + return -1; +} + +int fy_scan_yaml_version(struct fy_parser *fyp, struct fy_version *vers) +{ + int c, length, start_length, num; + ssize_t offset; + + memset(vers, 0, sizeof(*vers)); + + /* now loop while it's numeric */ + length = 0; + offset = -1; + num = 0; + while (fy_is_num(c = fy_parse_peek_at_internal(fyp, length, &offset))) { + length++; + num = num * 10; + num += c - '0'; + } + vers->major = num; + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + length > 0, err_out, + "version directive missing major number"); + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + c == '.', err_out, + "version directive missing dot separator"); + length++; + + start_length = length; + num = 0; + while (fy_is_num(c = fy_parse_peek_at_internal(fyp, length, &offset))) { + length++; + num = num * 10; + num += c - '0'; + } + vers->minor = num; + + /* note that the version is not checked for validity here */ + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + length > start_length, err_out, + "version directive missing minor number"); + + return length; + +err_out: + return -1; +} + +int fy_scan_tag_handle(struct fy_parser *fyp, bool is_directive, + struct fy_atom *handle) +{ + int length; + + length = fy_scan_tag_handle_length(fyp, 0); + fyp_error_check(fyp, length > 0, err_out, + "fy_scan_tag_handle_length() failed"); + + fy_fill_atom(fyp, length, handle); + + return 0; + +err_out: + return -1; +} + + +int fy_scan_tag_uri(struct fy_parser *fyp, bool is_directive, + struct fy_atom *handle) +{ + int length; + bool is_valid; + + length = fy_scan_tag_uri_length(fyp, 0); + fyp_error_check(fyp, length > 0, err_out, + "fy_scan_tag_uri_length() failed"); + + is_valid = fy_scan_tag_uri_is_valid(fyp, 0, length); + fyp_error_check(fyp, is_valid, err_out, + "tag URI is invalid"); + + fy_fill_atom(fyp, length, handle); + handle->style = FYAS_URI; /* this is a URI, need to handle URI escapes */ + + return 0; + +err_out: + return -1; +} + +int fy_scan_directive(struct fy_parser *fyp) +{ + int c, advance, version_length, tag_length, uri_length; + struct fy_version vers; + enum fy_reader_mode rdmode; + enum fy_token_type type = FYTT_NONE; + struct fy_atom handle; + bool is_uri_valid; + struct fy_token *fyt; + int i, lastc; + + if (!fy_parse_strcmp(fyp, "YAML")) { + advance = 4; + type = FYTT_VERSION_DIRECTIVE; + } else if (!fy_parse_strcmp(fyp, "TAG")) { + advance = 3; + type = FYTT_TAG_DIRECTIVE; + } else { + /* skip until linebreak (or #) */ + i = 0; + lastc = -1; + while ((c = fy_parse_peek_at(fyp, i)) != -1 && !fyp_is_lb(fyp, c)) { + if (fy_is_ws(lastc) && c == '#') + break; + lastc = c; + i++; + } + + FYP_PARSE_WARNING(fyp, 0, i, FYEM_SCAN, + "Unsupported directive"); + + if (fy_is_ws(lastc) && c == '#') { + while ((c = fy_parse_peek_at(fyp, i)) != -1 && !fyp_is_lb(fyp, c)) + i++; + } + + fy_advance_by(fyp, i); + + /* skip over linebreak too */ + if (fyp_is_lb(fyp, c)) + fy_advance(fyp, c); + + /* bump activity counter */ + fyp->token_activity_counter++; + + return 0; + } + + fyp_error_check(fyp, type != FYTT_NONE, err_out, + "neither YAML|TAG found"); + + /* 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_fill_atom_start(fyp, &handle); + + /* for version directive, parse it */ + if (type == FYTT_VERSION_DIRECTIVE) { + + version_length = fy_scan_yaml_version(fyp, &vers); + fyp_error_check(fyp, version_length > 0, err_out, + "fy_scan_yaml_version() failed"); + + /* set the reader's mode according to the version just scanned */ + rdmode = fy_version_compare(&vers, fy_version_make(1, 1)) <= 0 ? fyrm_yaml_1_1 : fyrm_yaml; + fy_reader_set_mode(fyp->reader, rdmode); + + fy_advance_by(fyp, version_length); + + fy_fill_atom_end(fyp, &handle); + + fyt = fy_token_queue(fyp, FYTT_VERSION_DIRECTIVE, &handle, &vers); + fyp_error_check(fyp, fyt, err_out, + "fy_token_queue() failed"); + + } else { + + tag_length = fy_scan_tag_handle_length(fyp, 0); + fyp_error_check(fyp, tag_length > 0, err_out, + "fy_scan_tag_handle_length() failed"); + + fy_advance_by(fyp, tag_length); + + c = fy_parse_peek(fyp); + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_is_ws(c), err_out, + "missing whitespace after TAG"); + + /* skip white space */ + while (fy_is_ws(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + uri_length = fy_scan_tag_uri_length(fyp, 0); + fyp_error_check(fyp, uri_length > 0, err_out, + "fy_scan_tag_uri_length() failed"); + + is_uri_valid = fy_scan_tag_uri_is_valid(fyp, 0, uri_length); + fyp_error_check(fyp, is_uri_valid, err_out, + "tag URI is invalid"); + + fy_advance_by(fyp, uri_length); + + fy_fill_atom_end(fyp, &handle); + handle.style = FYAS_URI; + + fyt = fy_token_queue(fyp, FYTT_TAG_DIRECTIVE, &handle, tag_length, uri_length, false); + fyp_error_check(fyp, fyt, err_out, + "fy_token_queue() failed"); + } + + /* skip until linebreak (or #) */ + i = 0; + lastc = -1; + while ((c = fy_parse_peek_at(fyp, i)) != -1 && !fyp_is_lb(fyp, c)) { + if (fy_is_ws(lastc) && c == '#') + break; + + FYP_PARSE_ERROR_CHECK(fyp, i, 1, FYEM_SCAN, + fy_is_ws(c) || fyp_is_lb(fyp, c), err_out, + "garbage after %s directive", + type == FYTT_VERSION_DIRECTIVE ? "version" : "tag"); + lastc = c; + i++; + } + + fy_advance_by(fyp, i); + + /* skip over linebreak */ + if (fyp_is_lb(fyp, c)) + fy_advance(fyp, c); + + return 0; +err_out: + return -1; +} + +int fy_fetch_directive(struct fy_parser *fyp) +{ + int 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"); + + rc = fy_scan_directive(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_directive() failed"); + + return 0; + +err_out_rc: + return rc; +} + +int fy_fetch_document_indicator(struct fy_parser *fyp, enum fy_token_type type) +{ + int rc, c; + struct fy_token *fyt; + + 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"); + + 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"); + + /* skip whitespace after the indicator */ + while (fy_is_ws(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + return 0; + +err_out_rc: + return rc; +} + +static inline bool fy_flow_indent_check(struct fy_parser *fyp) +{ + return (!fyp->flow_level || fyp_column(fyp) > fyp->indent) || + ((fyp->cfg.flags & FYPCF_SLOPPY_FLOW_INDENTATION) && fyp->flow_level); +} + +static inline bool fy_block_indent_check(struct fy_parser *fyp) +{ + return fyp->flow_level > 0 || fyp_column(fyp) > fyp->indent; +} + +int fy_fetch_flow_collection_mark_start(struct fy_parser *fyp, int c) +{ + enum fy_token_type type; + struct fy_simple_key_mark skm; + const char *typestr; + int rc = -1; + struct fy_token *fyt; + + if (c == '[') { + type = FYTT_FLOW_SEQUENCE_START; + typestr = "sequence"; + } else { + type = FYTT_FLOW_MAPPING_START; + typestr = "mapping"; + } + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented %s start in flow mode", typestr); + + 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"); + + rc = fy_save_simple_key_mark(fyp, &skm, type, NULL); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_save_simple_key_mark() failed"); + + /* increase flow level */ + fyp->flow_level++; + fyp_error_check(fyp, fyp->flow_level, err_out, + "overflow for the flow level counter"); + + /* push the current flow to the stack */ + rc = fy_parse_flow_push(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_parse_flow_push() failed"); + /* set the current flow mode */ + fyp->flow = c == '[' ? FYFT_SEQUENCE : FYFT_MAP; + + fyp->simple_key_allowed = true; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + /* the comment indicator must have at least a space */ + c = fy_parse_peek(fyp); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c != '#', err_out, + "invalid comment after %s start", typestr); + return 0; + +err_out: + rc = -1; + +err_out_rc: + return rc; +} + +int fy_fetch_flow_collection_mark_end(struct fy_parser *fyp, int c) +{ + enum fy_token_type type = FYTT_NONE; + enum fy_flow_type flow; + const char *typestr, *markerstr; + int i, rc; + bool did_purge; + struct fy_mark mark; + struct fy_token *fyt; + + fy_get_mark(fyp, &mark); + + if (c == ']') { + flow = FYFT_SEQUENCE; + type = FYTT_FLOW_SEQUENCE_END; + typestr = "sequence"; + markerstr = "bracket"; + } else { + flow = FYFT_MAP; + type = FYTT_FLOW_MAPPING_END; + typestr = "mapping"; + markerstr = "brace"; + } + + FYP_MARK_ERROR_CHECK(fyp, &fyp->last_comma_mark, &fyp->last_comma_mark, FYEM_SCAN, + !fyp_json_mode(fyp) || !fyp->last_was_comma, err_out, + "JSON disallows trailing comma before closing %s", markerstr); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented %s end in flow mode", typestr); + + rc = fy_remove_simple_key(fyp, type); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_remove_simple_key() failed"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fyp->flow_level, err_out, + "flow %s with invalid extra closing %s", + typestr, markerstr); + + fyp->flow_level--; + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fyp->flow == flow, err_out, + "mismatched flow %s end", typestr); + + /* pop the flow type */ + rc = fy_parse_flow_pop(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_parse_flow_pop() 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, 1)); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + if (fyp->parse_flow_only && fyp->flow_level == 0) { + rc = fy_fetch_stream_end(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_stream_end() failed"); + return 0; + } + + /* the comment indicator must have at least a space */ + c = fy_parse_peek(fyp); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c != '#', err_out, + "invalid comment after end of flow %s", typestr); + + /* due to the weirdness with simple keys and multiline flow keys scan forward + * until a linebreak, ';', or anything else */ + for (i = 0; ; i++) { + c = fy_parse_peek_at(fyp, i); + if (c < 0 || c == ':' || fyp_is_lb(fyp, c) || !fy_is_ws(c)) + break; + } + + /* 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 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; + } + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_fetch_flow_collection_entry(struct fy_parser *fyp, int c) +{ + enum fy_token_type type = FYTT_NONE; + struct fy_token *fyt, *fyt_last; + struct fy_atom *handle; + int rc; + + type = FYTT_FLOW_ENTRY; + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented entry seperator in flow mode"); + + /* transform '? a,' to '? a: ,' */ + if (fyp->pending_complex_key_column >= 0) { + + fyt = fy_token_queue(fyp, FYTT_VALUE, fy_fill_atom_a(fyp, 0)); + fyp_error_check(fyp, fyt, err_out, + "fy_token_queue() failed"); + + fyp->pending_complex_key_column = -1; + + } + + rc = fy_remove_simple_key(fyp, type); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_remove_simple_key() failed"); + + fyp->simple_key_allowed = true; + 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"); + + /* the comment indicator must have at least a space */ + c = fy_parse_peek(fyp); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c != '#', err_out, + "invalid comment after comma"); + + /* skip white space */ + while (fy_is_ws(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + if (c == '#') { + if (fyt_last) + fyt = fyt_last; + + handle = NULL; + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) + handle = fy_token_comment_handle(fyt, fycp_right, true); + + rc = fy_scan_comment(fyp, handle, true); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_comment() failed"); + } + + return 0; +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_fetch_block_entry(struct fy_parser *fyp, int c) +{ + int rc; + struct fy_mark mark; + struct fy_simple_key *fysk; + struct fy_token *fyt; + + fyp_error_check(fyp, c == '-', err_out, + "illegal block entry"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + (!fyp->flow_level || (fyp_column(fyp) + 2) > fyp->indent) || + ((fyp->cfg.flags & FYPCF_SLOPPY_FLOW_INDENTATION) && fyp->flow_level), err_out, + "wrongly indented block sequence in flow mode"); + + if (!(fyp->flow_level || fyp->simple_key_allowed)) { + if (!fyp->simple_key_allowed && fyp->state == FYPS_BLOCK_MAPPING_VALUE) + FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN, + "block sequence on the same line as a mapping key"); + else if (fyp->state == FYPS_BLOCK_SEQUENCE_FIRST_ENTRY || + fyp->state == FYPS_BLOCK_SEQUENCE_ENTRY) + FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN, + "block sequence on the same line as a previous item"); + else + FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN, + "block sequence entries not allowed in this context"); + goto err_out; + } + + /* we have to save the start mark */ + fy_get_mark(fyp, &mark); + + if (!fyp->flow_level && 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"); + } + + if (c == '-' && fyp->flow_level) { + /* this is an error, but we let the parser catch it */ + ; + } + + fysk = fy_would_remove_required_simple_key(fyp); + + if (fysk) { + if (fysk->token) { + if (fysk->token->type == FYTT_ANCHOR || fysk->token->type == FYTT_TAG) + FYP_TOKEN_ERROR(fyp, fysk->token, FYEM_SCAN, + "invalid %s indent for sequence", + fysk->token->type == FYTT_ANCHOR ? + "anchor" : "tag"); + else + FYP_TOKEN_ERROR(fyp, fysk->token, FYEM_SCAN, + "missing ':'"); + } else + FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN, + "missing ':'"); + goto err_out; + } + + rc = fy_remove_simple_key(fyp, FYTT_BLOCK_ENTRY); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_remove_simple_key() failed"); + + 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"); + + /* special case for allowing whitespace (including tabs) after - */ + if (fy_is_ws(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_fetch_key(struct fy_parser *fyp, int c) +{ + int rc; + struct fy_mark mark; + struct fy_simple_key_mark skm; + bool target_simple_key_allowed; + struct fy_token *fyt; + struct fy_atom *handle; + + fyp_error_check(fyp, c == '?', err_out, + "illegal block entry or key mark"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented mapping key in flow mode"); + + fy_get_simple_key_mark(fyp, &skm); + + /* we have to save the start mark */ + fy_get_mark(fyp, &mark); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + 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)) { + + /* 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"); + } + + rc = fy_remove_simple_key(fyp, FYTT_KEY); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_remove_simple_key() failed"); + + target_simple_key_allowed = !fyp->flow_level; + + fyp->pending_complex_key_column = fyp_column(fyp); + fyp->pending_complex_key_mark = mark; + 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); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + fyp->simple_key_allowed = target_simple_key_allowed; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + /* eat whitespace */ + while (fy_is_blank(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + /* comment? */ + if (c == '#') { + + handle = NULL; + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) + handle = fy_token_comment_handle(fyt, fycp_right, true); + + rc = fy_scan_comment(fyp, handle, false); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_comment() failed"); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_fetch_value(struct fy_parser *fyp, int c) +{ + struct fy_token_list sk_tl; + 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__; + struct fy_atom *chandle; + int rc; + + fyp_error_check(fyp, c == ':', err_out, + "illegal value mark"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp) || fyp->flow == FYFT_MAP, err_out, + "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) == ':'; + + fy_get_mark(fyp, &mark); + + fy_token_list_init(&sk_tl); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + 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"); + + /* get the simple key (if available) for the value */ + fysk = fy_simple_key_list_head(&fyp->simple_keys); + if (fysk && fysk->flow_level == fyp->flow_level) + fy_simple_key_list_del(&fyp->simple_keys, fysk); + else + fysk = NULL; + + if (!fysk) { + fyp_scan_debug(fyp, "no simple key flow_level=%d", fyp->flow_level); + + fyt_insert = fy_token_list_tail(&fyp->queued_tokens); + mark_insert = mark; + mark_end_insert = mark; + } else { + assert(fysk->flow_level == fyp->flow_level); + fyt_insert = fysk->token; + mark_insert = fysk->mark; + mark_end_insert = fysk->end_mark; + + fyp_scan_debug(fyp, "have simple key flow_level=%d", fyp->flow_level); + } + + fyp_scan_debug(fyp, "flow_level=%d, column=%d parse_indent=%d", + fyp->flow_level, mark_insert.column, fyp->indent); + + is_complex = fyp->pending_complex_key_column >= 0; + final_complex_key = is_complex && (fyp->flow_level || fyp_column(fyp) <= fyp->pending_complex_key_mark.column); + is_multiline = mark_end_insert.line < fyp_line(fyp); + has_bmap = fyp->generated_block_map; + push_bmap_start = (!fyp->flow_level && mark_insert.column > fyp->indent); + push_key_only = (!is_complex && (fyp->flow_level || has_bmap)) || + (is_complex && !final_complex_key); + + fyp_scan_debug(fyp, "mark_insert.line=%d/%d mark_end_insert.line=%d/%d fyp->line=%d", + mark_insert.line, mark_insert.column, + mark_end_insert.line, mark_end_insert.column, + fyp_line(fyp)); + + fyp_scan_debug(fyp, "simple_key_allowed=%s is_complex=%s final_complex_key=%s is_multiline=%s has_bmap=%s push_bmap_start=%s push_key_only=%s", + fyp->simple_key_allowed ? "true" : "false", + is_complex ? "true" : "false", + final_complex_key ? "true" : "false", + is_multiline ? "true" : "false", + has_bmap ? "true" : "false", + push_bmap_start ? "true" : "false", + push_key_only ? "true" : "false"); + + if (!is_complex && is_multiline && (!fyp->flow_level || fyp->flow != FYFT_MAP)) { + FYP_PARSE_ERROR(fyp, 0, 1, FYEM_SCAN, "Illegal placement of ':' indicator"); + goto err_out; + } + + if (push_bmap_start) { + + assert(!fyp->flow_level); + + fyp_scan_debug(fyp, "--- parse_roll"); + + /* push the new indent level */ + rc = fy_push_indent(fyp, mark_insert.column, true, mark_insert.line); + 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; + + /* 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"); + } + + 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"); + + } + + fyp_debug_dump_token(fyp, fyt_insert, "insert-token: "); + fyp_debug_dump_token_list(fyp, &fyp->queued_tokens, fyt_insert, "fyp->queued_tokens (before): "); + fyp_debug_dump_token_list(fyp, &sk_tl, NULL, "sk_tl: "); + + if (fyt_insert) { + + if (fysk) + fy_token_list_splice_before(&fyp->queued_tokens, fyt_insert, &sk_tl); + else + fy_token_list_splice_after(&fyp->queued_tokens, fyt_insert, &sk_tl); + } else + fy_token_lists_splice(&fyp->queued_tokens, &sk_tl); + + fyp_debug_dump_token_list(fyp, &fyp->queued_tokens, fyt_insert, "fyp->queued_tokens (after): "); + + 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"); + + fyp->simple_key_allowed = target_simple_key_allowed; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + if (fysk) + fy_parse_simple_key_recycle(fyp, fysk); + + if (final_complex_key) { + fyp->pending_complex_key_column = -1; + fyp_scan_debug(fyp, "pending_complex_key_column -> %d", + fyp->pending_complex_key_column); + } + + if (fyt_insert) { + /* eat whitespace */ + while (fy_is_blank(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + /* comment? */ + if (c == '#') { + chandle = NULL; + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) + chandle = fy_token_comment_handle(fyt_insert, fycp_right, true); + + rc = fy_scan_comment(fyp, chandle, false); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_comment() failed"); + } + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + fy_parse_simple_key_recycle(fyp, fysk); + return rc; +} + +int fy_fetch_anchor_or_alias(struct fy_parser *fyp, int c) +{ + struct fy_atom handle; + enum fy_token_type type; + int i = 0, rc = -1, length; + struct fy_simple_key_mark skm; + struct fy_token *fyt; + const char *typestr; + + fyp_error_check(fyp, c == '*' || c == '&', err_out, + "illegal anchor mark (not '*' or '&')"); + + if (c == '*') { + type = FYTT_ALIAS; + typestr = "alias"; + } else { + type = FYTT_ANCHOR; + typestr = "anchor"; + } + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented %s in flow mode", typestr); + + /* we have to save the start mark (including the anchor/alias start) */ + fy_get_simple_key_mark(fyp, &skm); + + /* skip over the anchor mark */ + fy_advance(fyp, c); + + /* start mark */ + fy_fill_atom_start(fyp, &handle); + + length = 0; + + while ((c = fy_parse_peek(fyp)) >= 0) { + if (fyp_is_blankz(fyp, c) || fy_is_flow_indicator(c) || + fy_is_unicode_control(c) || fy_is_unicode_space(c)) + break; + fy_advance(fyp, c); + length++; + } + + if (!fyp_is_blankz(fyp, c) && !fy_is_flow_indicator(c)) { + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + fy_is_unicode_control(c), err_out, + "illegal unicode control character in %s", typestr); + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + fy_is_unicode_space(c), err_out, + "illegal unicode space character in %s", typestr); + } + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + c != FYUG_INV, err_out, + "invalid character in %s", typestr); + + FYP_PARSE_ERROR_CHECK(fyp, length, 1, FYEM_SCAN, + c != FYUG_PARTIAL, err_out, + "partial character in %s", typestr); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + length > 0, err_out, + "invalid %s detected", typestr); + + fy_fill_atom_end(fyp, &handle); + + handle.storage_hint = length; + handle.storage_hint_valid = true; + handle.direct_output = true; + handle.empty = false; + handle.has_lb = false; + handle.has_ws = false; + handle.starts_with_ws = false; + handle.starts_with_lb = false; + handle.ends_with_ws = false; + handle.ends_with_lb = false; + handle.trailing_lb = false; + handle.size0 = false; + handle.valid_anchor = true; + + if (type == FYTT_ALIAS) + fyt = fy_token_queue(fyp, type, &handle, NULL); + else + fyt = fy_token_queue(fyp, type, &handle); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + /* scan forward for '-' block sequence indicator */ + if (type == FYTT_ANCHOR && !fyp->flow_level) { + for (i = 0; ; i++) { + c = fy_parse_peek_at(fyp, i); + if (c < 0 || fyp_is_lb(fyp, c) || !fy_is_ws(c)) + break; + } + + /* if it's '-' followed by ws we have a problem */ + FYP_PARSE_ERROR_CHECK(fyp, i, 1, FYEM_SCAN, + !(c == '-' && fy_is_ws(fy_parse_peek_at(fyp, i + 1))), err_out, + "illegal block sequence on the same line as anchor"); + } + + + rc = fy_save_simple_key_mark(fyp, &skm, type, NULL); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_save_simple_key_mark() failed"); + + fyp->simple_key_allowed = false; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_fetch_tag(struct fy_parser *fyp, int c) +{ + struct fy_atom handle; + int rc = -1, total_length, handle_length, uri_length, i, prefix_length, suffix_length; + const char *handlep; + bool is_valid; + struct fy_simple_key_mark skm; + struct fy_document_state *fyds; + struct fy_token *fyt_td; + struct fy_token *fyt; + + fyp_error_check(fyp, c == '!', err_out, + "illegal tag mark (not '!')"); + + FYP_PARSE_ERROR_CHECK(fyp, 0 ,1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented tag in flow mode"); + + fyds = fyp->current_document_state; + + fy_get_simple_key_mark(fyp, &skm); + + if (fy_parse_peek_at(fyp, 1) == '<') { + /* skip over '!<' and '>' */ + prefix_length = 2; + suffix_length = 1; + } else + prefix_length = suffix_length = 0; + + if (prefix_length) + handle_length = 0; /* set the handle to '' */ + else { + /* either !suffix or !handle!suffix */ + /* we scan back to back, and split handle/suffix */ + handle_length = fy_scan_tag_handle_length(fyp, prefix_length); + fyp_error_check(fyp, handle_length > 0, err_out, + "fy_scan_tag_handle_length() failed"); + } + + uri_length = fy_scan_tag_uri_length(fyp, prefix_length + handle_length); + fyp_error_check(fyp, uri_length >= 0, err_out, + "fy_scan_tag_uri_length() failed"); + + /* a handle? */ + if (!prefix_length && (handle_length == 0 || fy_parse_peek_at(fyp, handle_length - 1) != '!')) { + /* special case, '!', handle set to '' and suffix to '!' */ + if (handle_length == 1 && uri_length == 0) { + handle_length = 0; + uri_length = 1; + } else { + uri_length = handle_length - 1 + uri_length; + handle_length = 1; + } + } + + is_valid = fy_scan_tag_uri_is_valid(fyp, prefix_length + handle_length, uri_length); + fyp_error_check(fyp, is_valid, err_out, + "tag URI is invalid"); + + if (suffix_length > 0) { + c = fy_parse_peek_at(fyp, prefix_length + handle_length + uri_length); + + FYP_PARSE_ERROR_CHECK(fyp, prefix_length + handle_length + uri_length, 1, FYEM_SCAN, + c == '>', err_out, + "missing '>' uri terminator"); + } + + total_length = prefix_length + handle_length + uri_length + suffix_length; + fy_fill_atom(fyp, total_length, &handle); + handle.style = FYAS_URI; /* this is a URI, need to handle URI escapes */ + + c = fy_parse_peek(fyp); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fyp_is_blankz(fyp, c) || fy_utf8_strchr(",}]", c), err_out, + "invalid tag terminator"); + + handlep = fy_atom_data(&handle) + prefix_length; + + fyt_td = fy_document_state_lookup_tag_directive(fyds, handlep, handle_length); + + FYP_MARK_ERROR_CHECK(fyp, &handle.start_mark, &handle.end_mark, FYEM_PARSE, + fyt_td, err_out, + "undefined tag prefix"); + + fyt = fy_token_queue(fyp, FYTT_TAG, &handle, prefix_length, handle_length, uri_length, fyt_td); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + /* scan forward for '-' block sequence indicator */ + if (!fyp->flow_level) { + for (i = 0; ; i++) { + c = fy_parse_peek_at(fyp, i); + if (c < 0 || fyp_is_lb(fyp, c) || !fy_is_ws(c)) + break; + } + + /* if it's '-' followed by ws we have a problem */ + FYP_PARSE_ERROR_CHECK(fyp, i ,1, FYEM_SCAN, + !(c == '-' && fy_is_ws(fy_parse_peek_at(fyp, i + 1))), err_out, + "illegal block sequence on the same line as the tag"); + } + + rc = fy_save_simple_key_mark(fyp, &skm, FYTT_TAG, NULL); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_save_simple_key_mark() failed"); + + fyp->simple_key_allowed = false; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +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 c, max_indent = 0, min_indent, break_length; + + *breaks = 0; + *breaks_length = 0; + *presentation_breaks_length = 0; + *first_break_length = 0; + + /* minimum indent is 0 for zero indent scalars */ + min_indent = fyp->document_first_content_token ? 0 : 1; + + /* scan over the indentation spaces */ + /* we don't format content for display */ + for (;;) { + + /* skip over indentation */ + + if (!fyp_tabsize(fyp)) { + while ((c = fy_parse_peek(fyp)) == ' ' && + (!indent || fyp_column(fyp) < indent)) + 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"); + } else { + while (fy_is_ws((c = fy_parse_peek(fyp))) && + (!indent || fyp_column(fyp) < indent)) + fy_advance(fyp, c); + } + + if (fyp_column(fyp) > max_indent) + max_indent = fyp_column(fyp); + + /* non-empty line? */ + if (!fyp_is_lb(fyp, c)) + break; + + fy_advance(fyp, c); + + break_length = fy_utf8_width(c); + + (*breaks)++; + (*breaks_length) += 1; + + if (fy_is_lb_LS_PS(c)) + (*presentation_breaks_length) += break_length; + + if (!*first_break_length) + *first_break_length = break_length; + } + + if (!indent) { + indent = max_indent; + if (indent < fyp->indent) + indent = fyp->indent; + if (indent < min_indent) + indent = min_indent; + } + + return indent; + +err_out: + return -1; +} + +int fy_fetch_block_scalar(struct fy_parser *fyp, bool is_literal, int c) +{ + struct fy_atom handle; + enum fy_atom_chomp chomp = FYAC_CLIP; /* default */ + int lastc, rc, increment = 0, current_indent, new_indent, indent = 0; + 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; + struct fy_token *fyt; + size_t length, line_length, trailing_ws, trailing_breaks_length; + size_t leading_ws; + size_t prefix_length, suffix_length; + unsigned int chomp_amt; + int actual_lb_length, pending_lb_length; + struct fy_mark indicator_mark; + bool generated_indent; +#ifdef ATOM_SIZE_CHECK + size_t tlength; +#endif + + fyp_error_check(fyp, c == '|' || c == '>', err_out, + "bad start of block scalar ('%s')", + fy_utf8_format_a(c, fyue_singlequote)); + + fy_get_mark(fyp, &indicator_mark); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented block scalar in flow mode"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_block_indent_check(fyp), err_out, + "wrongly indented block scalar in block mode"); + + rc = fy_remove_simple_key(fyp, FYTT_SCALAR); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_remove_simple_key() failed"); + + fyp->simple_key_allowed = true; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + /* skip over block scalar start */ + fy_advance(fyp, c); + + /* intentation indicator (either [-+] or [-+] */ + c = fy_parse_peek(fyp); + if (c == '+' || c == '-') { + + chomp = c == '+' ? FYAC_KEEP : FYAC_STRIP; + + fy_advance(fyp, c); + + c = fy_parse_peek(fyp); + if (fy_is_num(c)) { + increment = c - '0'; + fyp_error_check(fyp, increment != 0, err_out, + "indentation indicator 0"); + fy_advance(fyp, c); + } + } else if (fy_is_num(c)) { + + increment = c - '0'; + fyp_error_check(fyp, increment != 0, err_out, + "indentation indicator 0"); + fy_advance(fyp, c); + + c = fy_parse_peek(fyp); + if (c == '+' || c == '-') { + chomp = c == '+' ? FYAC_KEEP : FYAC_STRIP; + fy_advance(fyp, c); + } + } + + /* the comment indicator must have at least a space */ + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c != '#', err_out, + "invalid comment without whitespace after block scalar indicator"); + + /* eat whitespace */ + while (fy_is_blank(c = fy_parse_peek(fyp))) + fy_advance(fyp, c); + + /* comment? */ + if (c == '#') { + /* XXX just ignore this one */ + rc = fy_scan_comment(fyp, NULL, true); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_scan_comment() failed"); + } + + c = fy_parse_peek(fyp); + + /* end of the line? */ + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fyp_is_lbz(fyp, c), err_out, + "block scalar no linebreak found"); + + /* if the block scalar indicator is on a different line we need a new indent */ + generated_indent = false; + if (!increment && indicator_mark.line != fyp->indent_line) { + fyp_scan_debug(fyp, "generating indent %d/%d\n", indicator_mark.line, fyp->indent_line); + rc = fy_push_indent(fyp, indicator_mark.column, false, indicator_mark.line); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_push_indent() failed"); + generated_indent = true; + } + + /* advance */ + fy_advance(fyp, c); + + fy_fill_atom_start(fyp, &handle); + + current_indent = fyp->indent >= 0 ? fyp->indent : 0; + indent = increment ? current_indent + increment : 0; + + length = 0; + trailing_breaks_length = 0; + + empty = true; + has_ws = false; + has_lb = false; + starts_with_ws = false; + starts_with_lb = false; + ends_with_ws = false; + 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); + 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; + prev_empty_line = true; + + prefix_length = 0; + suffix_length = 0; + + prev_indented = false; + first = true; + pending_nl = false; + pending_lb_length = 0; + + 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; + + if (first) { + if (fy_is_ws(c)) + starts_with_ws = true; + else if (fyp_is_lb(fyp, c)) + starts_with_lb = true; + } + + /* consume the list */ + line_length = 0; + trailing_ws = 0; + empty_line = true; + leading_ws = 0; + + indented = fy_is_ws(fy_parse_peek(fyp)); + + while (!(fyp_is_lbz(fyp, c = fy_parse_peek(fyp)))) { + + lastc = c; + + if (fyp_column(fyp) == 0 && + (!fy_parse_strncmp(fyp, "...", 3) || + !fy_parse_strncmp(fyp, "---", 3)) && + fy_is_blankz_at_offset(fyp, 3)) { + doc_start_end_detected = true; + break; + } + + if (!fy_is_space(c)) { + empty = false; + empty_line = false; + trailing_ws = 0; + if (chomp_amt == (unsigned int)-1) + chomp_amt = fyp_column(fyp); + } else { + has_ws = true; + if (empty_line) + leading_ws++; + trailing_ws++; + } + + fy_advance(fyp, c); + + line_length += fy_utf8_width(c); + } + + if (doc_start_end_detected) + break; + + if (!fy_is_z(c)) { + /* eat line break */ + actual_lb_length = fy_utf8_width(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); + fyp_error_check(fyp, new_indent >= 0, err_out, + "fy_scan_block_scalar_indent() failed"); + if (fy_is_lb_LS_PS(c)) + presentation_breaks_length += actual_lb_length; + } else { + has_lb = false; + new_indent = indent; + chomp = FYAC_STRIP; + + breaks = 0; + breaks_length = 0; + presentation_breaks_length = 0; + first_break_length = 0; + + actual_lb_length = 0; + } + + if (is_literal) { + + prefix_length = 0; + + if (pending_nl) { + pending_nl = false; + prefix_length += pending_lb_length; + pending_lb_length = 0; + } + + prefix_length += trailing_breaks_length; + trailing_breaks_length = 0; + + suffix_length = 0; + + if (fy_is_lb_LS_PS(c)) { + trailing_breaks_length += breaks_length; + trailing_breaks_length += presentation_breaks_length; + + if (actual_lb_length > 1) + presentation_breaks_length -= actual_lb_length; + + pending_nl = true; + pending_lb_length = 0; + } else { + trailing_breaks_length += breaks_length; + trailing_breaks_length += presentation_breaks_length; + + pending_nl = !empty_line || indented; + pending_lb_length = pending_nl ? 1 : 0; + } + + } else { + + prefix_length = 0; + + if (!trailing_breaks_length) { + if (prev_indented || (prev_empty_line && !first) || indented) { + /* previous line was indented or empty, force output newline */ + if (pending_nl) { + pending_nl = false; + prefix_length += 1; // pending_lb_length; + pending_lb_length = 0; + } + } else if (!prev_empty_line && !prev_indented && !indented && !empty_line) { + /* previous line was not empty and not indented + * while this is not indented and not empty need sep */ + if (pending_nl) { + pending_nl = false; + prefix_length += 1; // pending_lb_length; + pending_lb_length = 0; + } + } + } else { + prefix_length += trailing_breaks_length; + if (prev_indented || indented) + prefix_length++; + } + pending_nl = true; + pending_lb_length = actual_lb_length; + + trailing_breaks_length = 0; + + suffix_length = 0; + trailing_breaks_length += breaks_length; + trailing_breaks_length += presentation_breaks_length; + } + + + length += prefix_length + line_length + suffix_length; + + indent = new_indent; + + prev_empty_line = empty_line; + prev_indented = indented; + + prefix_length = 0; + suffix_length = 0; + + first = false; + } + + if (empty) { + trailing_breaks_length = breaks_length; + trailing_breaks_length += presentation_breaks_length; + length = 0; + } + + /* end... */ + fy_fill_atom_end(fyp, &handle); + + if (c == FYUG_INV || c == FYUG_PARTIAL) { + FYP_MARK_ERROR(fyp, &handle.start_mark, &handle.end_mark, FYEM_SCAN, + "block scalar is malformed UTF8"); + goto err_out; + } + + /* 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, + "block scalar with wrongly indented line after spaces only"); + goto err_out; + } + + if (empty && c == '#' && fyp_column(fyp) > fyp->indent) { + FYP_MARK_ERROR(fyp, &handle.start_mark, &handle.end_mark, FYEM_SCAN, + "empty block scalar with wrongly indented comment line after spaces only"); + goto err_out; + } + + if (chomp_amt == (unsigned int)-1) + chomp_amt = current_indent; + + switch (chomp) { + case FYAC_CLIP: + if (pending_nl) { + if (actual_lb_length <= 2) + length += 1; + else + length += actual_lb_length; + + ends_with_lb = true; + ends_with_ws = false; + } else { + if (trailing_breaks_length > 0) + ends_with_lb = true; + else if (fy_is_ws(lastc)) + ends_with_ws = true; + } + break; + case FYAC_KEEP: { + length += (pending_nl ? actual_lb_length : 0) + breaks + presentation_breaks_length; + + trailing_lb = trailing_breaks_length > 0; + if (pending_nl || 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; + if (fy_is_ws(lastc)) + ends_with_ws = true; + break; + } + + /* need to process to present */ + handle.style = is_literal ? FYAS_LITERAL : FYAS_FOLDED; + handle.chomp = chomp; + handle.increment = increment ? (unsigned int)(current_indent + increment) : chomp_amt; + + /* no point in trying to do direct output in a block scalar */ + /* TODO maybe revisit in the future */ + handle.direct_output = false; + handle.empty = empty; + handle.has_lb = has_lb; + handle.has_ws = has_ws; + handle.starts_with_ws = starts_with_ws; + handle.starts_with_lb = starts_with_lb; + handle.ends_with_ws = ends_with_ws; + handle.ends_with_lb = ends_with_lb; + handle.trailing_lb = trailing_lb; + handle.size0 = length == 0; + handle.valid_anchor = false; + handle.json_mode = fyp_json_mode(fyp); + handle.lb_mode = fyp_lb_mode(fyp); + handle.fws_mode = fyp_fws_mode(fyp); + handle.tabsize = fyp_tabsize(fyp); + +#ifdef ATOM_SIZE_CHECK + tlength = fy_atom_format_text_length(&handle); + if (tlength != length) { + fyp_warning(fyp, "%s: storage hint calculation failed real %zu != hint %zu - \"%s\"", __func__, + tlength, length, + fy_utf8_format_text_a(fy_atom_data(&handle), fy_atom_size(&handle), fyue_doublequote)); + length = tlength; + } +#endif + + handle.storage_hint = length; + handle.storage_hint_valid = true; + + fyt = fy_token_queue(fyp, FYTT_SCALAR, &handle, is_literal ? FYSS_LITERAL : FYSS_FOLDED); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) { + rc = fy_attach_comments_if_any(fyp, fyt); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_attach_right_hand_comment() failed"); + } + + if (generated_indent) { + rc = fy_pop_indent(fyp); + fyp_error_check(fyp, !rc, err_out, + "fy_pop_indent() failed"); + + /* the ident line has now moved */ + fyp->indent_line = fyp_line(fyp); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_reader_fetch_flow_scalar_handle(struct fy_reader *fyr, int c, int indent, struct fy_atom *handle, bool sloppy_indent) +{ + 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_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; + bool first, starts_with_ws, starts_with_lb, ends_with_ws, ends_with_lb, trailing_lb = false; + bool unicode_esc, is_json_unesc, has_json_esc; + int last_esc_lb, break_length, presentation_breaks_length; + struct fy_mark mark, mark2; + char escbuf[1 + FY_UTF8_FORMAT_BUFMIN]; + size_t escbuf_len; + enum fy_utf8_escape esc_mode; + const char *ep; +#ifdef ATOM_SIZE_CHECK + size_t tlength; +#endif + + (void)last_esc_lb; + + is_single = c == '\''; + end_c = c; + + fyr_error_check(fyr, c == '\'' || c == '"', err_out, + "bad start of flow scalar ('%s')", + fy_utf8_format_a(c, fyue_singlequote)); + + fy_reader_get_mark(fyr, &mark); + + /* skip over block scalar start */ + fy_reader_advance(fyr, c); + + fy_reader_fill_atom_start(fyr, handle); + + length = 0; + breaks_found = 0; + breaks_found_length = 0; + first_break_length = 0; + presentation_breaks_length = 0; + blanks_found = 0; + esc_lb = false; + last_esc_lb = -1; + ws_lb_only = true; + has_ws = false; + has_lb = false; + starts_with_ws = false; + starts_with_lb = false; + ends_with_ws = false; + ends_with_lb = false; + has_esc = false; + break_run = 0; + first = true; + has_json_esc = false; + + esc_mode = fy_reader_json_mode(fyr) ? fyue_doublequote_json : + fy_reader_lb_mode(fyr) == fylb_cr_nl ? fyue_doublequote : fyue_doublequote_yaml_1_1; + + last_line = -1; + lastc = -1; + for (;;) { + if (!fy_reader_json_mode(fyr)) { + /* no document indicators please */ + FYR_PARSE_ERROR_CHECK(fyr, 0, 3, FYEM_SCAN, + !(fy_reader_column(fyr) == 0 && + (!fy_reader_strncmp(fyr, "---", 3) || + !fy_reader_strncmp(fyr, "...", 3)) && + fy_reader_is_blankz_at_offset(fyr, 3)), err_out, + "invalid document-%s marker in %s scalar", + c == '-' ? "start" : "end", + is_single ? "single-quoted" : "double-quoted"); + } + + /* no EOF either */ + c = fy_reader_peek(fyr); + + if (c <= 0) { + fy_reader_get_mark(fyr, &mark); + + if (!c || c == FYUG_EOF) + FYR_MARK_ERROR(fyr, &handle->start_mark, &mark, FYEM_SCAN, + "%s scalar without closing quote", + is_single ? "single-quoted" : "double-quoted"); + else + FYR_MARK_ERROR(fyr, &handle->start_mark, &mark, FYEM_SCAN, + "%s scalar is malformed UTF8", + is_single ? "single-quoted" : "double-quoted"); + goto err_out; + } + + if (first) { + if (fy_reader_is_flow_ws(fyr, c)) + starts_with_ws = true; + else if (fy_reader_is_lb(fyr, c)) + starts_with_lb = true; + } + + while (!fy_reader_is_flow_blankz(fyr, c = fy_reader_peek(fyr))) { + + if (ws_lb_only && !(fy_reader_is_flow_ws(fyr, c) || fy_reader_is_lb(fyr, c)) && c != end_c) + ws_lb_only = false; + + esc_lb = false; + last_esc_lb = -1; + /* track line change (and first non blank) */ + if (last_line != fy_reader_line(fyr)) { + last_line = fy_reader_line(fyr); + + if ((indent >= 0 && fy_reader_column(fyr) <= indent) && !sloppy_indent) { + + fy_reader_advance(fyr, c); + fy_reader_get_mark(fyr, &mark2); + FYR_MARK_ERROR(fyr, &mark, &mark2, FYEM_SCAN, + "wrongly indented %s scalar", + is_single ? "single-quoted" : "double-quoted"); + goto err_out; + } + } + + if (breaks_found) { + length += breaks_found > 1 ? (breaks_found_length - first_break_length) : 1; + length += presentation_breaks_length; + breaks_found = 0; + blanks_found = 0; + presentation_breaks_length = 0; + } else if (blanks_found) { + length += blanks_found; + lastc = ' '; + blanks_found = 0; + } + + if (c >= 0 && c <= 0x7f && (fy_utf8_low_ascii_flags[c] & F_SIMPLE_SCALAR)) { + size_t len, consumed; + const char *p, *s, *e; + int8_t cc; + int run; + + run = 0; + while ((p = fy_reader_ensure_lookahead(fyr, 1, &len)) != NULL) { + + s = p; + e = s + len; + + while (s < e && (cc = (int8_t)*s) >= 0 && (fy_utf8_low_ascii_flags[cc] & F_SIMPLE_SCALAR)) + s++; + + consumed = s - p; + if (consumed) { + fy_reader_advance_octets(fyr, consumed); + fyr->column += consumed; + lastc = (int)cc; + } + run += consumed; + + /* we're done if stopped earlier */ + if (s < e) + break; + } + length += run; + break_run = 0; + continue; + } + + /* escaped single quote? */ + if (is_single && c == '\'' && fy_reader_peek_at(fyr, 1) == '\'') { + length++; + fy_reader_advance_by(fyr, 2); + break_run = 0; + lastc = '\''; + continue; + } + + /* right quote? */ + if (c == end_c) + break; + + /* escaped line break (any linebreak will do) */ + if (!is_single && c == '\\' && fy_reader_is_lb(fyr, fy_reader_peek_at(fyr, 1))) { + + esc_lb = true; + last_esc_lb = fy_reader_peek_at(fyr, 1); + + fy_reader_advance_by(fyr, 2); + + c = fy_reader_peek(fyr); + break_run = 0; + lastc = c; + + has_esc = true; + + break; + } + + /* escaped sequence? */ + if (!is_single && c == '\\') { + + /* note we don't generate formatted output */ + /* we are merely checking for validity */ + c = fy_reader_peek_at(fyr, 1); + + /* hex, unicode marks - json only supports u */ + unicode_esc = !fy_reader_json_mode(fyr) ? + (c == 'x' || c == 'u' || c == 'U') : + c == 'u'; + if (unicode_esc) { + + total_code_length = 0; + total_digits = 0; + j = 0; + hi_surrogate = lo_surrogate = 0; + for (;;) { + total_code_length += 2; + + code_length = c == 'x' ? 2 : + c == 'u' ? 4 : 8; + value = 0; + for (i = 0; i < code_length; i++) { + c = fy_reader_peek_at(fyr, total_code_length + i); + + FYR_PARSE_ERROR_CHECK(fyr, 0, total_code_length + i + 1, FYEM_SCAN, + fy_is_hex(c), err_out, + "double-quoted scalar has invalid hex escape"); + + value <<= 4; + if (c >= '0' && c <= '9') + value |= c - '0'; + else if (c >= 'a' && c <= 'f') + value |= 10 + c - 'a'; + else + value |= 10 + c - 'A'; + } + + total_code_length += code_length; + total_digits += code_length; + j++; + + /* 0x10000 + (HI - 0xd800) * 0x400 + (LO - 0xdc00) */ + + /* high surrogate */ + if (j == 1 && code_length == 4 && value >= 0xd800 && value <= 0xdbff && + fy_reader_peek_at(fyr, total_code_length) == '\\' && + fy_reader_peek_at(fyr, total_code_length + 1) == 'u') { + hi_surrogate = value; + c = 'u'; + continue; + } + + if (j == 2 && code_length == 4 && hi_surrogate) { + + FYR_PARSE_ERROR_CHECK(fyr, total_code_length - 6, 6, FYEM_SCAN, + value >= 0xdc00 && value <= 0xdfff, err_out, + "Invalid low surrogate value"); + + lo_surrogate = value; + value = 0x10000 + (hi_surrogate - 0xd800) * 0x400 + (lo_surrogate - 0xdc00); + } + + break; + } + + /* check for validity */ + FYR_PARSE_ERROR_CHECK(fyr, 0, total_code_length, FYEM_SCAN, + !(value < 0 || (value >= 0xd800 && value <= 0xdfff) || + value > 0x10ffff), err_out, + "double-quoted scalar has invalid UTF8 escape"); + + fy_reader_advance_by(fyr, total_code_length); + + } else { + escbuf[0] = '\\'; + fy_utf8_put_unchecked(escbuf + 1, c); + escbuf_len = 1 + fy_utf8_width(c); + + ep = escbuf; + + value = fy_utf8_parse_escape(&ep, escbuf_len, esc_mode); + FYR_PARSE_ERROR_CHECK(fyr, 0, 2, FYEM_SCAN, + value >= 0, err_out, + "invalid escape '%s' in %s string", + fy_utf8_format_a(c, fyue_singlequote), + is_single ? "single-quoted" : "double-quoted"); + + fy_reader_advance_by(fyr, 2); + } + + length += fy_utf8_width(value); + + lastc = value; + + if (lastc == '\n') + break_run++; + + has_esc = true; + + continue; + } + + /* check whether we have a JSON unescaped character */ + is_json_unesc = fy_is_json_unescaped_range_only(c); + if (!is_json_unesc) + has_json_esc = true; + + if (!is_single && fy_reader_json_mode(fyr) && has_json_esc) { + FYR_PARSE_ERROR(fyr, 0, 2, FYEM_SCAN, + "Invalid JSON unescaped character"); + goto err_out; + } + + lastc = c; + + /* regular character */ + fy_reader_advance(fyr, c); + + length += fy_utf8_width(c); + break_run = 0; + } + + /* end of scalar */ + if (c == end_c) + break; + + /* consume blanks */ + breaks_found = 0; + breaks_found_length = 0; + blanks_found = 0; + while (fy_reader_is_flow_blank(fyr, c = fy_reader_peek(fyr)) || fy_reader_is_lb(fyr, c)) { + + if (!has_json_esc && !fy_is_json_unescaped(c)) + has_json_esc = true; + + break_run = 0; + + fy_reader_advance(fyr, c); + + if (fy_reader_is_lb(fyr, c)) { + + if (!fy_is_lb_LS_PS(c)) { + break_length = 1; + } else { + break_length = fy_utf8_width(c); + presentation_breaks_length += break_length; + } + + has_lb = true; + if (!breaks_found) + first_break_length = break_length; + breaks_found++; + breaks_found_length += break_length; + blanks_found = 0; + esc_lb = false; + } else { + has_ws = true; + if (!esc_lb) + blanks_found++; + } + } + first = false; + } + + if (break_run > 0) + ends_with_lb = true; + else if (fy_reader_is_flow_ws(fyr, lastc)) + ends_with_ws = true; + trailing_lb = break_run > 1; + + /* end... */ + fy_reader_fill_atom_end(fyr, handle); + + is_multiline = handle->end_mark.line > handle->start_mark.line; + + /* need to process to present */ + handle->style = is_single ? FYAS_SINGLE_QUOTED : FYAS_DOUBLE_QUOTED; + handle->direct_output = !is_multiline && !has_esc && !has_json_esc && + fy_atom_size(handle) == length; + handle->empty = ws_lb_only; + handle->has_lb = has_lb; + handle->has_ws = has_ws; + handle->starts_with_ws = starts_with_ws; + handle->starts_with_lb = starts_with_lb; + handle->ends_with_ws = ends_with_ws; + handle->ends_with_lb = ends_with_lb; + handle->trailing_lb = trailing_lb; + handle->size0 = length == 0; + handle->tabsize = fy_reader_tabsize(fyr); + + /* skip over block scalar end */ + fy_reader_advance_by(fyr, 1); + +#ifdef ATOM_SIZE_CHECK + tlength = fy_atom_format_text_length(handle); + if (tlength != length) { + fyr_warning(fyr, "%s: storage hint calculation failed real %zu != hint %zu - \"%s\"", __func__, + tlength, length, + fy_utf8_format_text_a(fy_atom_data(handle), fy_atom_size(handle), fyue_doublequote)); + length = tlength; + } +#endif + + handle->storage_hint = length; + handle->storage_hint_valid = true; + + FYR_MARK_ERROR_CHECK(fyr, &handle->start_mark, &handle->end_mark, FYEM_SCAN, + !fy_reader_json_mode(fyr) || !is_multiline, err_out, + "Multi line double quoted scalars not supported in JSON mode"); + + return 0; + +err_out: + return -1; +} + +int fy_reader_fetch_plain_scalar_handle(struct fy_reader *fyr, int c, int indent, int flow_level, struct fy_atom *handle, bool directive0) +{ + size_t length; + int rc = -1, run, nextc, lastc, breaks_found, blanks_found; + int breaks_found_length, first_break_length, break_length, presentation_breaks_length; + bool has_leading_blanks; + bool last_ptr; + struct fy_mark mark, last_mark; + bool is_multiline, has_lb, has_ws; + bool has_json_esc; +#ifdef ATOM_SIZE_CHECK + size_t tlength; +#endif + + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_SCAN, + !fy_reader_is_blankz(fyr, c), err_out, + "plain scalar cannot start with blank or zero"); + + /* may not start with any of ,[]{}#&*!|>'\"%@` */ + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_SCAN, + !fy_utf8_strchr(",[]{}#&*!|>'\"%@`", c), err_out, + "plain scalar cannot start with '%c'", c); + + /* may not start with - not followed by blankz */ + FYR_PARSE_ERROR_CHECK(fyr, 0, 2, FYEM_SCAN, + c != '-' || !fy_reader_is_blank_at_offset(fyr, 1), err_out, + "plain scalar cannot start with '%c' followed by blank", c); + + /* may not start with -?: not followed by blankz (in block context) */ + FYR_PARSE_ERROR_CHECK(fyr, 0, 2, FYEM_SCAN, + 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); + + fy_reader_get_mark(fyr, &mark); + + fy_reader_fill_atom_start(fyr, handle); + + has_leading_blanks = false; + has_lb = false; + has_ws = false; + has_json_esc = false; + + length = 0; + breaks_found = 0; + breaks_found_length = 0; + first_break_length = 0; + presentation_breaks_length = 0; + blanks_found = 0; + last_ptr = false; + memset(&last_mark, 0, sizeof(last_mark)); + c = FYUG_EOF; + lastc = FYUG_EOF; + + for (;;) { + /* break for document indicators */ + if (fy_reader_column(fyr) == 0 && + ((!fy_reader_strncmp(fyr, "---", 3) || !fy_reader_strncmp(fyr, "...", 3)) && + fy_reader_is_blankz_at_offset(fyr, 3))) + break; + + c = fy_reader_peek(fyr); + if (c == '#') + break; + + /* for YAML 1.1 check % directive break */ + if (directive0 && fy_reader_column(fyr) == 0 && c == '%') + break; + + /* quickly deal with runs */ + run = 0; + if (c >= 0 && c <= 0x7f && (fy_utf8_low_ascii_flags[c] & F_SIMPLE_SCALAR)) { + size_t len, consumed; + const char *p, *s, *e; + int8_t cc; + + while ((p = fy_reader_ensure_lookahead(fyr, 1, &len)) != NULL) { + + s = p; + e = s + len; + + while (s < e && (cc = (int8_t)*s) >= 0 && (fy_utf8_low_ascii_flags[cc] & F_SIMPLE_SCALAR)) + s++; + + consumed = s - p; + if (consumed) { + fy_reader_advance_octets(fyr, consumed); + fyr->column += consumed; + } + run += consumed; + + /* we're done if stopped earlier */ + if (s < e) + break; + } + + } + if (run > 0) { + length += run; + if (breaks_found) { + /* minimum 1 sep, or more for consecutive */ + length += breaks_found > 1 ? (breaks_found_length - first_break_length) : 1; + length += presentation_breaks_length; + breaks_found = 0; + blanks_found = 0; + presentation_breaks_length = 0; + } else if (blanks_found) { + /* just the blanks mam' */ + length += blanks_found; + blanks_found = 0; + } + } + + while (!fy_reader_is_blankz(fyr, c = fy_reader_peek(fyr))) { + + + if (c == ':') { + + nextc = fy_reader_peek_at(fyr, 1); + + /* ':' followed by space terminates */ + if (fy_reader_is_blankz(fyr, nextc)) { + /* super rare case :: not followed by space */ + /* :: not followed by space */ + if (lastc != ':' || fy_is_ws(nextc)) + break; + } + + /* in flow context ':' followed by flow markers */ + if (flow_level > 0 && fy_utf8_strchr(",[]{}", nextc)) + break; + } + + /* in flow context any or , [ ] { } */ + if (flow_level > 0 && (c == ',' || c == '[' || c == ']' || c == '{' || c == '}')) + break; + + if (breaks_found) { + /* minimum 1 sep, or more for consecutive */ + length += breaks_found > 1 ? (breaks_found_length - first_break_length) : 1; + length += presentation_breaks_length; + breaks_found = 0; + blanks_found = 0; + presentation_breaks_length = 0; + } else if (blanks_found) { + /* just the blanks mam' */ + length += blanks_found; + blanks_found = 0; + } + + /* check whether we have a JSON unescaped character */ + if (!has_json_esc && !fy_is_json_unescaped(c)) + has_json_esc = true; + + fy_reader_advance(fyr, c); + run++; + + length += fy_utf8_width(c); + + lastc = c; + } + + /* save end mark if we processed more than one non-blank */ + if (run > 0) { + /* fyp_scan_debug(fyp, "saving mark"); */ + last_ptr = true; + fy_reader_get_mark(fyr, &last_mark); + } + + /* end? */ + if (!(fy_is_blank(c) || fy_reader_is_lb(fyr, c))) + break; + + has_json_esc = true; + + /* consume blanks */ + breaks_found = 0; + breaks_found_length = 0; + first_break_length = 0; + blanks_found = 0; + do { + fy_reader_advance(fyr, c); + + if (!fy_reader_tabsize(fyr)) { + /* check for tab */ + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_SCAN, + c != '\t' || !has_leading_blanks || indent < 0 || fy_reader_column(fyr) >= (indent + 1), err_out, + "invalid tab used as indentation"); + } + + nextc = fy_reader_peek(fyr); + + /* if it's a break */ + if (fy_reader_is_lb(fyr, c)) { + + if (!fy_is_lb_LS_PS(c)) { + break_length = 1; + } else { + break_length = fy_utf8_width(c); + presentation_breaks_length += break_length; + } + + /* first break, turn on leading blanks */ + if (!has_leading_blanks) + has_leading_blanks = true; + if (!breaks_found) + first_break_length = break_length; + breaks_found++; + breaks_found_length += break_length; + blanks_found = 0; + has_lb = true; + } else { + blanks_found++; + has_ws = true; + } + + c = nextc; + + } while (fy_is_blank(c) || fy_reader_is_lb(fyr, c)); + + /* break out if indentation is less */ + if (flow_level <= 0 && indent >= 0 && fy_reader_column(fyr) < (indent + 1)) + break; + } + + /* end... */ + if (!last_ptr) + fy_reader_fill_atom_end(fyr, handle); + else + fy_reader_fill_atom_end_at(fyr, handle, &last_mark); + + if (c == FYUG_INV || c == FYUG_PARTIAL) { + FYR_MARK_ERROR(fyr, &handle->start_mark, &handle->end_mark, FYEM_SCAN, + "plain scalar is malformed UTF8"); + goto err_out; + } + + is_multiline = handle->end_mark.line > handle->start_mark.line; + + handle->style = FYAS_PLAIN; + handle->chomp = FYAC_STRIP; + handle->direct_output = !is_multiline && !has_json_esc && fy_atom_size(handle) == length; + handle->empty = false; + handle->has_lb = has_lb; + handle->has_ws = has_ws; + handle->starts_with_ws = false; + handle->starts_with_lb = false; + handle->ends_with_ws = false; + handle->ends_with_lb = false; + handle->trailing_lb = false; + 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); + +#ifdef ATOM_SIZE_CHECK + tlength = fy_atom_format_text_length(handle); + if (tlength != length) { + fyr_warning(fyr, "%s: storage hint calculation failed real %zu != hint %zu - \"%s\"", __func__, + tlength, length, + fy_utf8_format_text_a(fy_atom_data(handle), fy_atom_size(handle), fyue_doublequote)); + length = tlength; + } +#endif + + handle->storage_hint = length; + handle->storage_hint_valid = true; + + /* extra check in json mode */ + if (fy_reader_json_mode(fyr)) { + FYR_MARK_ERROR_CHECK(fyr, &handle->start_mark, &handle->end_mark, FYEM_SCAN, + !is_multiline, err_out, + "Multi line plain scalars not supported in JSON mode"); + + FYR_MARK_ERROR_CHECK(fyr, &handle->start_mark, &handle->end_mark, FYEM_SCAN, + !fy_atom_strcmp(handle, "false") || + !fy_atom_strcmp(handle, "true") || + !fy_atom_strcmp(handle, "null") || + fy_atom_is_number(handle), err_out, + "Invalid JSON plain scalar"); + } + + return 0; + +err_out: + rc = -1; + return rc; +} + + +int fy_fetch_flow_scalar(struct fy_parser *fyp, int c) +{ + struct fy_atom handle; + bool is_single, is_complex, is_multiline; + struct fy_mark mark; + struct fy_simple_key_mark skm; + struct fy_token *fyt; + int i = 0, rc = -1; + + is_single = c == '\''; + + fyp_error_check(fyp, c == '\'' || c == '"', err_out, + "bad start of flow scalar ('%s')", + fy_utf8_format_a(c, fyue_singlequote)); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented %s scalar in flow mode", + is_single ? "single-quoted" : "double-quoted"); + + fy_get_mark(fyp, &mark); + fy_get_simple_key_mark(fyp, &skm); + + /* errors are generated by reader */ + rc = fy_reader_fetch_flow_scalar_handle(fyp->reader, c, fyp->indent, &handle, !!(fyp->cfg.flags & FYPCF_SLOPPY_FLOW_INDENTATION)); + if (rc) { + fyp->stream_error = true; + goto err_out_rc; + } + + /* and we're done */ + fyt = fy_token_queue(fyp, FYTT_SCALAR, &handle, is_single ? FYSS_SINGLE_QUOTED : FYSS_DOUBLE_QUOTED); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + if (fyp->parse_flow_only && fyp->flow_level == 0) { + rc = fy_fetch_stream_end(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_stream_end() failed"); + return 0; + } + + is_complex = fyp->pending_complex_key_column >= 0; + is_multiline = handle.end_mark.line > handle.start_mark.line; + + if (!fyp->flow_level) { + /* due to the weirdness with simple keys scan forward + * until a linebreak, ';', or anything else */ + for (i = 0; ; i++) { + c = fy_parse_peek_at(fyp, i); + if (c < 0 || c == ':' || fyp_is_lb(fyp, c) || !fyp_is_flow_ws(fyp, c)) + break; + } + + /* if we're a multiline key that's bad */ + FYP_MARK_ERROR_CHECK(fyp, &mark, &mark, FYEM_SCAN, + !(is_multiline && !is_complex && c == ':'), err_out, + "invalid multiline %s scalar used as key", + is_single ? "single-quoted" : "double-quoted"); + + FYP_PARSE_ERROR_CHECK(fyp, i, 1, FYEM_SCAN, + c < 0 || c == ':' || c == '#' || fyp_is_lb(fyp, c), err_out, + "invalid trailing content after %s scalar", + is_single ? "single-quoted" : "double-quoted"); + } + + /* a plain scalar could be simple key */ + rc = fy_save_simple_key_mark(fyp, &skm, FYTT_SCALAR, &handle.end_mark); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_save_simple_key_mark() failed"); + + /* cannot follow a flow scalar */ + fyp->simple_key_allowed = false; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + /* make sure that no comment follows directly afterwards */ + c = fy_parse_peek(fyp); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c != '#', err_out, + "invalid comment without whitespace after %s scalar", + is_single ? "single-quoted" : "double-quoted"); + + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) { + rc = fy_attach_comments_if_any(fyp, fyt); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_attach_right_hand_comment() failed"); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +void fy_reader_skip_ws_cr_nl(struct fy_reader *fyr) +{ + const char *p, *s, *e; + char cc; + size_t len; + int line, column; + + assert(fyr); + + column = fyr->column; + line = fyr->line; + while ((p = fy_reader_ensure_lookahead(fyr, 1, &len)) != NULL) { + + s = p; + e = s + len; + + while (s < e) { + cc = *s; + if (cc == ' ') { + column++; + } else if (cc == '\n') { + column = 0; + line++; + } else if (cc == '\t') { + if (fyr->tabsize) + column += (fyr->tabsize - (column % fyr->tabsize)); + else + column++; + } else if (cc == '\r') { + column = 0; + line++; + + if (s + 1 > e) { + /* we have a dangling cr at the end of a block */ + + /* advance up to the point here */ + fy_reader_advance_octets(fyr, s - p); + + /* try again (should return enough or NULL) */ + p = fy_reader_ensure_lookahead(fyr, 1, &len); + + /* if we couldn't pull enough we're done */ + if (!p || len < 1) + goto done; + + s = p; + e = s + len; + + if (*s == '\n') + s++; + } + /* \n followed, gulp it down */ + if (*s == '\n') + s++; + } else { + if (s > p) + fy_reader_advance_octets(fyr, s - p); + goto done; + } + + s++; + } + + fy_reader_advance_octets(fyr, s - p); + } + +done: + fyr->line = line; + fyr->column = column; +} + +void fy_reader_skip_ws(struct fy_reader *fyr) +{ + const char *p, *s, *e; + size_t len, consumed; + int column; + + assert(fyr); + + while ((p = fy_reader_ensure_lookahead(fyr, 1, &len)) != NULL) { + + s = p; + e = s + len; + + column = fyr->column; + if (!fyr->tabsize) { + while (s < e && fy_is_ws(*s)) { + column++; + s++; + } + } else { + while (s < e && fy_is_ws(*s)) { + if (fy_is_tab(*s)) + column += fyr->tabsize - (column % fyr->tabsize); + else + column++; + s++; + } + } + + consumed = s - p; + if (consumed) { + fy_reader_advance_octets(fyr, consumed); + fyr->column = column; + } + + /* we're done if stopped earlier */ + if (s < e) + break; + } +} + +void fy_reader_skip_space(struct fy_reader *fyr) +{ + const char *p, *s, *e; + size_t len, consumed; + + assert(fyr); + + while ((p = fy_reader_ensure_lookahead(fyr, 1, &len)) != NULL) { + + s = p; + e = s + len; + + while (s < e && fy_is_space(*s)) + s++; + + consumed = s - p; + if (consumed) { + fy_reader_advance_octets(fyr, consumed); + fyr->column += consumed; + } + + if (s < e) + break; + } +} + +void fy_reader_skip_ws_lb(struct fy_reader *fyr) +{ + const char *p, *s, *e; + size_t len, consumed; + int line, column, c, w; + bool dangling_cr; + enum fy_lb_mode lb_mode; + + assert(fyr); + + /* punt to json mode */ + lb_mode = fy_reader_lb_mode(fyr); + + if (fy_reader_json_mode(fyr) || lb_mode == fylb_cr_nl) { + fy_reader_skip_ws_cr_nl(fyr); + return; + } + + column = fyr->column; + line = fyr->line; + dangling_cr = false; + while ((p = fy_reader_ensure_lookahead(fyr, 1, &len)) != NULL) { + + s = p; + e = s + len; + + if (dangling_cr) { + if (*s == '\n') + s++; + dangling_cr = false; + } + + while (s < e) { + c = (int)*s; + + /* single byte utf8? */ + if (c < 0x80) { + if (c == ' ') { + column++; + } else if (c == '\n') { + column = 0; + line++; + } else if (c == '\t') { + if (fyr->tabsize) + column += (fyr->tabsize - (column % fyr->tabsize)); + else + column++; + } else if (c == '\r') { + column = 0; + line++; + /* check for '\n' following */ + if (s < e) { + if (*s == '\n') + s++; + } else { + /* we have a dangling cr at the end of a block */ + dangling_cr = true; + } + } else { + consumed = s - p; + if (consumed) + fy_reader_advance_octets(fyr, consumed); + goto done; + } + s++; + } else { + c = fy_utf8_get(s, (int)(e - s), &w); + + if (c == FYUG_PARTIAL) { + /* get the width (from the first octet */ + w = fy_utf8_width_by_first_octet((uint8_t)*s); + /* copy the partial utf8 in the buffer */ + + /* advance up to the point here */ + consumed = s - p; + if (consumed) + fy_reader_advance_octets(fyr, consumed); + + /* try again (should return enough or NULL) */ + p = fy_reader_ensure_lookahead(fyr, w, &len); + if (!p) + break; + + /* if we couldn't pull enough we're done */ + if (len < (size_t)w) + goto done; + + continue; + } + + if (lb_mode == fylb_cr_nl_N_L_P && fy_is_unicode_lb(c)) { + column = 0; + line++; + } else { + consumed = s - p; + if (consumed) + fy_reader_advance_octets(fyr, consumed); + goto done; + } + + s += w; + } + } + + consumed = s - p; + if (consumed) + fy_reader_advance_octets(fyr, consumed); + } + +done: + fyr->line = line; + fyr->column = column; +} + +int fy_fetch_plain_scalar(struct fy_parser *fyp, int c) +{ + struct fy_atom handle; + struct fy_simple_key_mark skm; + struct fy_token *fyt; + bool is_multiline, is_complex; + 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"); + + /* check indentation */ + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + fy_flow_indent_check(fyp), err_out, + "wrongly indented flow %s", + fyp->flow == FYFT_SEQUENCE ? "sequence" : "mapping"); + + fy_get_simple_key_mark(fyp, &skm); + + rc = fy_reader_fetch_plain_scalar_handle(fyp->reader, c, fyp->indent, fyp->flow_level, &handle, + fy_document_state_version_compare(fyp->current_document_state, fy_version_make(1, 1)) <= 0); + if (rc) { + fyp->stream_error = true; + goto err_out_rc; + } + + is_multiline = handle.end_mark.line > handle.start_mark.line; + is_complex = fyp->pending_complex_key_column >= 0; + + /* and we're done */ + fyt = fy_token_queue(fyp, FYTT_SCALAR, &handle, FYSS_PLAIN); + fyp_error_check(fyp, fyt, err_out_rc, + "fy_token_queue() failed"); + + if (fyp->parse_flow_only && fyp->flow_level == 0) { + rc = fy_fetch_stream_end(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_stream_end() failed"); + return 0; + } + + if (is_multiline && !fyp->flow_level && !is_complex) { + /* due to the weirdness with simple keys scan forward + * 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)) || + fyp_is_lb(fyp, c) || !fy_is_ws(c)) + break; + } + + /* 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"); + goto err_out; + } + } + + rc = fy_save_simple_key_mark(fyp, &skm, FYTT_SCALAR, &handle.end_mark); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_save_simple_key_mark() failed"); + + fyp->simple_key_allowed = handle.has_lb; + fyp_scan_debug(fyp, "simple_key_allowed -> %s\n", fyp->simple_key_allowed ? "true" : "false"); + + if (fyp->cfg.flags & FYPCF_PARSE_COMMENTS) { + rc = fy_attach_comments_if_any(fyp, fyt); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_attach_right_hand_comment() failed"); + } + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +int fy_fetch_tokens(struct fy_parser *fyp) +{ + struct fy_mark m; + bool was_double_colon; + int c, rc; + + /* do not fetch any more when stream end is reached */ + if (fyp->stream_end_reached) + return 0; + + if (!fyp->stream_start_produced) { + rc = fy_parse_get_next_input(fyp); + fyp_error_check(fyp, rc >= 0, err_out_rc, + "fy_parse_get_next_input() failed"); + + if (rc > 0) { + rc = fy_fetch_stream_start(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_stream_start() failed"); + } + return 0; + } + + fyp_scan_debug(fyp, "-------------------------------------------------"); + rc = fy_scan_to_next_token(fyp); + 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"); + + c = fy_parse_peek(fyp); + if (c < 0 || c == '\0') { + + fyp->stream_end_reached = true; + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp) || c != '\0', err_out, + "JSON disallows '\\0' in the input stream"); + + if (c >= 0) + fy_advance(fyp, c); + rc = fy_fetch_stream_end(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_stream_end() failed"); + return 0; + } + + if (fyp_column(fyp) == 0 && c == '%') { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "directives not supported in JSON mode"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp->bare_document_only, err_out, + "invalid directive in bare document mode"); + + fy_advance(fyp, c); + rc = fy_fetch_directive(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_directive() failed"); + goto out; + } + + /* probable document start/end indicator */ + if (fyp_column(fyp) == 0 && + (!fy_parse_strncmp(fyp, "---", 3) || + !fy_parse_strncmp(fyp, "...", 3)) && + fy_is_blankz_at_offset(fyp, 3)) { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 3, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "document %s indicator not supported in JSON mode", + c == '-' ? "start" : "end"); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 3, FYEM_SCAN, + !fyp->bare_document_only, err_out, + "invalid document %s indicator in bare document mode", + c == '-' ? "start" : "end"); + + rc = fy_fetch_document_indicator(fyp, + c == '-' ? FYTT_DOCUMENT_START : + FYTT_DOCUMENT_END); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_document_indicator() failed"); + + fyp->indent_line = fyp_line(fyp); + + /* for document end, nothing must follow except whitespace and comment */ + if (c == '.') { + c = fy_parse_peek(fyp); + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c == -1 || c == '#' || fyp_is_lb(fyp, c), err_out, + "invalid content after document end marker"); + } + + goto out; + } + + fyp_scan_debug(fyp, "indent=%d, parent indent=%d\n", + fyp->indent, fyp->parent_indent); + + if (c == '[' || c == '{') { + + fyp->indent_line = fyp_line(fyp); + + fyp_scan_debug(fyp, "calling fy_fetch_flow_collection_mark_start(%c)", c); + rc = fy_fetch_flow_collection_mark_start(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_flow_collection_mark_start() failed"); + goto out; + } + + if (c == ']' || c == '}') { + + fyp->indent_line = fyp_line(fyp); + + fyp_scan_debug(fyp, "fy_fetch_flow_collection_mark_end(%c)", c); + rc = fy_fetch_flow_collection_mark_end(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_flow_collection_mark_end() failed"); + goto out; + } + + + if (c == ',') { + + fyp->indent_line = fyp_line(fyp); + + fy_get_mark(fyp, &m); + + fyp_scan_debug(fyp, "fy_fetch_flow_collection_entry(%c)", c); + rc = fy_fetch_flow_collection_entry(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_flow_collection_entry() failed"); + + fyp->last_was_comma = true; + fyp->last_comma_mark = m; + + goto out; + } + + if (c == '-' && fy_is_blankz_at_offset(fyp, 1)) { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "block entries not supported in JSON mode"); + + fyp->indent_line = fyp_line(fyp); + + fyp_scan_debug(fyp, "fy_fetch_block_entry(%c)", c); + rc = fy_fetch_block_entry(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_block_entry() failed"); + goto out; + } + + if (c == '?' && fy_is_blankz_at_offset(fyp, 1)) { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "complex keys not supported in JSON mode"); + + fyp->indent_line = fyp_line(fyp); + + fyp_scan_debug(fyp, "fy_fetch_key(%c)", c); + rc = fy_fetch_key(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_key() failed"); + goto out; + } + + if (c == ':') { + was_double_colon = c == ':' && fyp->colon_follows_colon && fyp->flow_level > 0; + fyp->colon_follows_colon = false; + + if (((fyp->flow_level && !fyp->simple_key_allowed) || fy_is_blankz_at_offset(fyp, 1)) && + !was_double_colon) { + + fyp->indent_line = fyp_line(fyp); + + fyp_scan_debug(fyp, "fy_fetch_value(%c)", c); + rc = fy_fetch_value(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_value() failed"); + goto out; + } + } + + if (c == '*' || c == '&') { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "%s not supported in JSON mode", + c == '&' ? "anchor" : "alias"); + + fyp_scan_debug(fyp, "fy_fetch_anchor_or_alias(%c)", c); + rc = fy_fetch_anchor_or_alias(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_anchor_or_alias() failed"); + goto out; + } + + if (c == '!') { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "tag not supported in JSON mode"); + + fyp_scan_debug(fyp, "fy_fetch_tag(%c)", c); + rc = fy_fetch_tag(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_tag() failed"); + goto out; + } + + if (!fyp->flow_level && (c == '|' || c == '>')) { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + !fyp_json_mode(fyp), err_out, + "block scalars not supported in JSON mode"); + + fyp_scan_debug(fyp, "fy_fetch_block_scalar(%c)", c); + rc = fy_fetch_block_scalar(fyp, c == '|', c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_block_scalar() failed"); + goto out; + } + + if (c == '\'' || c == '"') { + + FYP_PARSE_ERROR_CHECK(fyp, 0, 1, FYEM_SCAN, + c == '"' || !fyp_json_mode(fyp), err_out, + "single quoted scalars not supported in JSON mode"); + + fyp_scan_debug(fyp, "fy_fetch_flow_scalar(%c)", c); + rc = fy_fetch_flow_scalar(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_flow_scalar() failed"); + goto out; + } + + fyp_scan_debug(fyp, "fy_fetch_plain_scalar(%c)", c); + rc = fy_fetch_plain_scalar(fyp, c); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_fetch_plain_scalar() failed"); + +out: + if (c != ',' && fyp->last_was_comma) + fyp->last_was_comma = false; + + return 0; + +err_out: + rc = -1; +err_out_rc: + return rc; +} + +struct fy_token *fy_scan_peek(struct fy_parser *fyp) +{ + struct fy_token *fyt; + int rc, last_token_activity_counter; + bool have_simple_keys; + + /* nothing if stream end produced (and no stream end token in queue) */ + if (fyp->stream_end_produced) { + fyt = fy_token_list_head(&fyp->queued_tokens); + if (fyt && fyt->type == FYTT_STREAM_END) + return fyt; + + /* OK, we're done, flush everything */ + fy_token_list_unref_all(&fyp->queued_tokens); + + /* try to get the next input */ + rc = fy_parse_get_next_input(fyp); + fyp_error_check(fyp, rc >= 0, err_out, + "fy_parse_get_next_input() failed"); + + /* no more inputs */ + if (rc == 0) { + fyp_scan_debug(fyp, "token stream ends"); + return NULL; + } + + fyp_scan_debug(fyp, "starting new token stream"); + + fyp->stream_start_produced = false; + fyp->stream_end_produced = false; + fyp->stream_end_reached = false; + } + + /* we loop until we have a token and the simple key list is empty */ + for (;;) { + fyt = fy_token_list_head(&fyp->queued_tokens); + have_simple_keys = !fy_simple_key_list_empty(&fyp->simple_keys); + + /* we can produce a token when: + * a) one exists + * b) no simple keys exist at all + */ + if (fyt && !have_simple_keys) + break; + + /* on stream error we're done */ + if (fyp->stream_error) + return NULL; + + /* keep track of token activity, if it didn't change + * after the fetch tokens call, the state machine is stuck + */ + last_token_activity_counter = fyp->token_activity_counter; + + /* fetch more then */ + rc = fy_fetch_tokens(fyp); + fyp_error_check(fyp, !rc, err_out, + "fy_fetch_tokens() failed"); + + fyp_error_check(fyp, last_token_activity_counter != fyp->token_activity_counter, err_out, + "out of tokens and failed to produce anymore"); + } + + switch (fyt->type) { + case FYTT_STREAM_START: + fyp_scan_debug(fyp, "setting stream_start_produced to true"); + fyp->stream_start_produced = true; + break; + case FYTT_STREAM_END: + fyp_scan_debug(fyp, "setting stream_end_produced to true"); + fyp->stream_end_produced = true; + + if (!fyp->parse_flow_only) { + rc = fy_reader_input_done(fyp->reader); + fyp_error_check(fyp, !rc, err_out, + "fy_parse_input_done() failed"); + } + break; + default: + break; + } + + return fyt; + +err_out: + return NULL; +} + +struct fy_token *fy_scan_remove(struct fy_parser *fyp, struct fy_token *fyt) +{ + if (!fyp || !fyt) + return NULL; + + fy_token_list_del(&fyp->queued_tokens, fyt); + + return fyt; +} + +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)); + + return fy_scan_peek(fyp); +} + +struct fy_token *fy_scan(struct fy_parser *fyp) +{ + struct fy_token *fyt; + + fyt = fy_scan_remove(fyp, fy_scan_peek(fyp)); + + if (fyt && (fyt->type == FYTT_VERSION_DIRECTIVE || fyt->type == FYTT_TAG_DIRECTIVE)) { + + /* + * NOTE: we need to update the document state with the contents of + * directives, so that tags etc, work correctly. + * This is arguably a big hack, but so is using the scanner in such + * a low level. + * + * This is not very good because we don't keep track of parser state + * so tag directives in the middle of the document are AOK. + * But we don't really care, if you care about stream validity do + * a proper parse. + */ + + /* we take a reference because the parse methods take ownership */ + fy_token_ref(fyt); + + /* we ignore errors, because... they are parse errors, not scan errors */ + + if (fyt->type == FYTT_VERSION_DIRECTIVE) + (void)fy_parse_version_directive(fyp, fyt, true); + else + (void)fy_parse_tag_directive(fyp, fyt, true); + } + + if (fyt) + fyp_debug_dump_token(fyp, fyt, "producing: "); + return fyt; +} + +void fy_scan_token_free(struct fy_parser *fyp, struct fy_token *fyt) +{ + fy_token_unref_rl(fy_parse_recycled_token(fyp), fyt); +} + +int fy_parse_state_push(struct fy_parser *fyp, enum fy_parser_state state) +{ + struct fy_parse_state_log *fypsl; + + fypsl = fy_parse_parse_state_log_alloc(fyp); + fyp_error_check(fyp, fypsl != NULL, err_out, + "fy_parse_state_log_alloc() failed!"); + fypsl->state = state; + fy_parse_state_log_list_push(&fyp->state_stack, fypsl); + + return 0; +err_out: + return -1; +} + +enum fy_parser_state fy_parse_state_pop(struct fy_parser *fyp) +{ + struct fy_parse_state_log *fypsl; + enum fy_parser_state state; + + fypsl = fy_parse_state_log_list_pop(&fyp->state_stack); + if (!fypsl) + return FYPS_NONE; + + state = fypsl->state; + + fy_parse_parse_state_log_recycle(fyp, fypsl); + + return state; +} + +void fy_parse_state_set(struct fy_parser *fyp, enum fy_parser_state state) +{ + fyp_parse_debug(fyp, "state %s -> %s\n", state_txt[fyp->state], state_txt[state]); + fyp->state = state; +} + +enum fy_parser_state fy_parse_state_get(struct fy_parser *fyp) +{ + return fyp->state; +} + +static struct fy_eventp * +fy_parse_node(struct fy_parser *fyp, struct fy_token *fyt, bool is_block) +{ + struct fy_eventp *fyep = NULL; + struct fy_event *fye = NULL; + struct fy_document_state *fyds = NULL; + struct fy_token *anchor = NULL, *tag = NULL; + const char *handle; + size_t handle_size; + struct fy_atom atom; + struct fy_token *fyt_td; + + fyds = fyp->current_document_state; + assert(fyds); + + fyp_parse_debug(fyp, "parse_node: is_block=%s - fyt %s", + is_block ? "true" : "false", + fy_token_type_txt[fyt->type]); + + if (fyt->type == FYTT_ALIAS) { + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_ALIAS; + fye->alias.anchor = fy_scan_remove(fyp, fyt); + + goto return_ok; + } + + while ((!anchor && fyt->type == FYTT_ANCHOR) || (!tag && fyt->type == FYTT_TAG)) { + if (fyt->type == FYTT_ANCHOR) + anchor = fy_scan_remove(fyp, fyt); + else + tag = fy_scan_remove(fyp, fyt); + + fyt = fy_scan_peek(fyp); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + + fyp_parse_debug(fyp, "parse_node: ANCHOR|TAG got - fyt %s", + fy_token_type_txt[fyt->type]); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyt->type != FYTT_ALIAS, err_out, + "unexpected alias"); + } + + /* check tag prefix */ + if (tag && tag->tag.handle_length) { + handle = fy_atom_data(&tag->handle) + tag->tag.skip; + handle_size = tag->tag.handle_length; + + fyt_td = fy_document_state_lookup_tag_directive(fyds, handle, handle_size); + + FYP_TOKEN_ERROR_CHECK(fyp, tag, FYEM_PARSE, + fyt_td, err_out, + "undefined tag prefix '%.*s'", (int)handle_size, handle); + } + + if ((fyp->state == FYPS_BLOCK_MAPPING_VALUE || + fyp->state == FYPS_BLOCK_MAPPING_FIRST_KEY) + && fyt->type == FYTT_BLOCK_ENTRY) { + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SEQUENCE_START; + 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!"); + + fy_parse_state_set(fyp, FYPS_INDENTLESS_SEQUENCE_ENTRY); + goto return_ok; + } + + if (fyt->type == FYTT_SCALAR) { + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SCALAR; + fye->scalar.anchor = anchor; + fye->scalar.tag = tag; + fye->scalar.value = fy_scan_remove(fyp, fyt); + goto return_ok; + } + + if (fyt->type == FYTT_FLOW_SEQUENCE_START) { + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SEQUENCE_START; + fye->sequence_start.anchor = anchor; + fye->sequence_start.tag = tag; + fye->sequence_start.sequence_start = fy_scan_remove(fyp, fyt); + fy_parse_state_set(fyp, FYPS_FLOW_SEQUENCE_FIRST_ENTRY); + goto return_ok; + } + + if (fyt->type == FYTT_FLOW_MAPPING_START) { + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_MAPPING_START; + fye->mapping_start.anchor = anchor; + fye->mapping_start.tag = tag; + fye->mapping_start.mapping_start = fy_scan_remove(fyp, fyt); + fy_parse_state_set(fyp, FYPS_FLOW_MAPPING_FIRST_KEY); + goto return_ok; + } + + if (is_block && fyt->type == FYTT_BLOCK_SEQUENCE_START) { + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SEQUENCE_START; + fye->sequence_start.anchor = anchor; + fye->sequence_start.tag = tag; + fye->sequence_start.sequence_start = fy_scan_remove(fyp, fyt); + fy_parse_state_set(fyp, FYPS_BLOCK_SEQUENCE_FIRST_ENTRY); + goto return_ok; + } + + if (is_block && fyt->type == FYTT_BLOCK_MAPPING_START) { + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_MAPPING_START; + fye->mapping_start.anchor = anchor; + fye->mapping_start.tag = tag; + fye->mapping_start.mapping_start = fy_scan_remove(fyp, fyt); + fy_parse_state_set(fyp, FYPS_BLOCK_MAPPING_FIRST_KEY); + goto return_ok; + } + + if (!anchor && !tag) { + + if (fyt->type == FYTT_FLOW_ENTRY && + (fyp->state == FYPS_FLOW_SEQUENCE_FIRST_ENTRY || + fyp->state == FYPS_FLOW_SEQUENCE_ENTRY)) + + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "flow sequence with invalid %s", + fyp->state == FYPS_FLOW_SEQUENCE_FIRST_ENTRY ? + "comma in the beginning" : "extra comma"); + + else if ((fyt->type == FYTT_DOCUMENT_START || fyt->type == FYTT_DOCUMENT_END) && + (fyp->state == FYPS_FLOW_SEQUENCE_FIRST_ENTRY || + fyp->state == FYPS_FLOW_SEQUENCE_ENTRY)) + + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "invalid document %s indicator in a flow sequence", + fyt->type == FYTT_DOCUMENT_START ? + "start" : "end"); + else + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "did not find expected node content"); + + goto err_out; + } + + fyp_parse_debug(fyp, "parse_node: empty scalar..."); + + /* empty scalar */ + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SCALAR; + fye->scalar.anchor = anchor; + fye->scalar.tag = tag; + fye->scalar.value = NULL; + +return_ok: + fyp_parse_debug(fyp, "parse_node: > %s", + fy_event_type_txt[fye->type]); + + 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_parse_eventp_recycle(fyp, fyep); + + return NULL; +} + +static struct fy_eventp * +fy_parse_empty_scalar(struct fy_parser *fyp) +{ + struct fy_eventp *fyep; + struct fy_event *fye; + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SCALAR; + fye->scalar.anchor = NULL; + fye->scalar.tag = NULL; + fye->scalar.value = NULL; + return fyep; +err_out: + return NULL; +} + +int fy_parse_stream_start(struct fy_parser *fyp) +{ + fyp->indent = -2; + fyp->indent_line = -1; + fyp->generated_block_map = false; + fyp->last_was_comma = false; + fyp->flow = FYFT_NONE; + fyp->pending_complex_key_column = -1; + + fy_parse_indent_list_recycle_all(fyp, &fyp->indent_stack); + fy_parse_simple_key_list_recycle_all(fyp, &fyp->simple_keys); + 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); + 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); + fyp->stream_end_token = NULL; + + return 0; +} + +static struct fy_eventp *fy_parse_internal(struct fy_parser *fyp) +{ + struct fy_eventp *fyep = NULL; + struct fy_event *fye = NULL; + struct fy_token *fyt = NULL; + struct fy_document_state *fyds = NULL; + bool is_block, is_seq, is_value, is_first, had_doc_end, had_directives; + 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; + char tbuf[16] __FY_DEBUG_UNUSED__; + int rc; + + version_directive = NULL; + fy_token_list_init(&tag_directives); + + /* are we done? */ + if (fyp->stream_error || fyp->state == FYPS_END) + return NULL; + + fyt = fy_scan_peek(fyp); + + /* special case without an error message for start */ + if (!fyt && fyp->state == FYPS_NONE) + return NULL; + + /* keep a copy of stream end */ + if (fyt && fyt->type == FYTT_STREAM_END && !fyp->stream_end_token) { + fyp->stream_end_token = fy_token_ref(fyt); + fyp_parse_debug(fyp, "kept copy of STRM-"); + } + + /* keep on producing STREAM_END */ + if (!fyt && fyp->stream_end_token) { + fyt = fyp->stream_end_token; + fy_token_list_add_tail(&fyp->queued_tokens, fyt); + + fyp_parse_debug(fyp, "generated copy of STRM-"); + } + + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + + assert(fyt->handle.fyi); + + fyp_parse_debug(fyp, "[%s] <- %s", state_txt[fyp->state], + fy_token_dump_format(fyt, tbuf, sizeof(tbuf))); + + is_first = false; + had_doc_end = false; + + fyep = NULL; + fye = NULL; + + orig_state = fyp->state; + switch (fyp->state) { + case FYPS_NONE: + fy_parse_state_set(fyp, FYPS_STREAM_START); + /* fallthrough */ + + case FYPS_STREAM_START: + + fyp_error_check(fyp, fyt->type == FYTT_STREAM_START, err_out, + "failed to get valid stream start token"); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_STREAM_START; + + fye->stream_start.stream_start = fy_scan_remove(fyp, fyt); + + rc = fy_parse_stream_start(fyp); + fyp_error_check(fyp, !rc, err_out, + "stream start failed"); + + fy_parse_state_set(fyp, FYPS_IMPLICIT_DOCUMENT_START); + + fyp->stream_has_content = false; + + return fyep; + + case FYPS_IMPLICIT_DOCUMENT_START: + + /* fallthrough */ + + case FYPS_DOCUMENT_START: + + had_doc_end = false; + + if (!fyp->stream_has_content && fyt->type != FYTT_STREAM_END) + fyp->stream_has_content = true; + + /* remove all extra document end indicators */ + while (fyt->type == FYTT_DOCUMENT_END) { + + /* reset document has content flag */ + fyp->document_has_content = false; + fyp->document_first_content_token = true; + + /* explicit end indicator, no more directives checking */ + fyp->had_directives = false; + + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + had_doc_end = true; + } + + if (!fyp->current_document_state) { + + rc = fy_reset_document_state(fyp); + fyp_error_check(fyp, !rc, err_out, + "fy_reset_document_state() failed"); + } + + fyds = fyp->current_document_state; + fyp_error_check(fyp, fyds, err_out, + "no current document state error"); + + /* process directives */ + had_directives = false; + while (fyt->type == FYTT_VERSION_DIRECTIVE || + fyt->type == FYTT_TAG_DIRECTIVE) { + + had_directives = true; + fyp->had_directives = true; + + if (fyt->type == FYTT_VERSION_DIRECTIVE) { + + rc = fy_parse_version_directive(fyp, fy_scan_remove(fyp, fyt), false); + fyt = NULL; + fyp_error_check(fyp, !rc, err_out, + "failed to fy_parse_version_directive()"); + } else { + rc = fy_parse_tag_directive(fyp, fy_scan_remove(fyp, fyt), false); + fyt = NULL; + + fyp_error_check(fyp, !rc, err_out, + "failed to fy_parse_tag_directive()"); + } + + fyt = fy_scan_peek(fyp); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + } + + /* the end */ + if (fyt->type == FYTT_STREAM_END) { + + /* empty content is not allowed in JSON mode */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp) || + fyp->stream_has_content, err_out, + "JSON does not allow empty root content"); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp->had_directives || fyp->document_has_content || + !fyds->start_implicit, err_out, + "stream with directives without content"); + + rc = fy_parse_stream_end(fyp); + fyp_error_check(fyp, !rc, err_out, + "stream end failed"); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_STREAM_END; + fye->stream_end.stream_end = fy_scan_remove(fyp, fyt); + + fy_parse_state_set(fyp, + fy_parse_have_more_inputs(fyp) ? FYPS_NONE : FYPS_END); + + return fyep; + } + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + /* document start */ + fye->type = FYET_DOCUMENT_START; + fye->document_start.document_start = NULL; + fye->document_start.document_state = NULL; + + if (!(fyp->state == FYPS_IMPLICIT_DOCUMENT_START || had_doc_end || fyt->type == FYTT_DOCUMENT_START)) { + fyds = fyp->current_document_state; + + /* not BLOCK_MAPPING_START */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyt->type == FYTT_BLOCK_MAPPING_START, err_out, + "missing document start"); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyds->start_implicit || + fyds->start_mark.line != fy_token_start_line(fyt), err_out, + "invalid mapping starting at --- line"); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + false, err_out, + "invalid mapping in plain multiline"); + } + + fym = fy_token_start_mark(fyt); + if (fym) + fyds->start_mark = *fym; + else + memset(&fyds->start_mark, 0, sizeof(fyds->start_mark)); + + if (fyt->type != FYTT_DOCUMENT_START) { + fye->document_start.document_start = NULL; + + fyds->start_implicit = true; + fyp_parse_debug(fyp, "document_start_implicit=true"); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyt->type != FYTT_DOCUMENT_END || !had_directives, err_out, + "directive(s) without a document"); + + fy_parse_state_set(fyp, FYPS_BLOCK_NODE); + } else { + fye->document_start.document_start = fy_scan_remove(fyp, fyt); + + fyds->start_implicit = false; + fyp_parse_debug(fyp, "document_start_implicit=false"); + + fy_parse_state_set(fyp, FYPS_DOCUMENT_CONTENT); + } + + rc = fy_parse_state_push(fyp, FYPS_DOCUMENT_END); + fyp_error_check(fyp, !rc, err_out, + "failed to fy_parse_state_push()"); + + fye->document_start.document_state = fy_document_state_ref(fyds); + fye->document_start.implicit = fyds->start_implicit; + + return fyep; + + case FYPS_DOCUMENT_END: + + fyds = fyp->current_document_state; + fyp_error_check(fyp, fyds, err_out, + "no current document state error"); + + if (fyt && (fyt->type == FYTT_VERSION_DIRECTIVE || + fyt->type == FYTT_TAG_DIRECTIVE)) { + int cmpval = fy_document_state_version_compare(fyds, fy_version_make(1, 1)); + + fyp_scan_debug(fyp, "version %d.%d %s %d.%d\n", + fyds->version.major, fyds->version.minor, + cmpval == 0 ? "=" : cmpval > 0 ? ">" : "<", + 1, 1); + + /* YAML 1.1 allows directives without document end */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + cmpval <= 0, err_out, + "missing explicit document end marker before directive(s)"); + + } + + fym = fy_token_end_mark(fyt); + if (fym) + fyds->end_mark = *fym; + else + memset(&fyds->end_mark, 0, sizeof(fyds->end_mark)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + /* document end */ + fye->type = FYET_DOCUMENT_END; + if (fyt->type == FYTT_DOCUMENT_END) { + /* TODO pull the document end token and deliver */ + fye->document_end.document_end = NULL; + fyds->end_implicit = false; + + /* reset document has content flag */ + fyp->document_has_content = false; + fyp->document_first_content_token = true; + + /* reset directives */ + fyp->had_directives = false; + + } else { + fye->document_end.document_end = NULL; + fyds->end_implicit = true; + } + + fye->document_end.implicit = fyds->end_implicit; + + if (!fyp->next_single_document) { + /* multi document mode */ + fy_parse_state_set(fyp, FYPS_DOCUMENT_START); + fyp->had_directives = false; + + /* and reset document state */ + rc = fy_reset_document_state(fyp); + fyp_error_check(fyp, !rc, err_out, + "fy_reset_document_state() failed"); + } else { + /* single document mode */ + fyp->next_single_document = false; + + fy_parse_state_set(fyp, FYPS_SINGLE_DOCUMENT_END); + } + + return fyep; + + case FYPS_DOCUMENT_CONTENT: + + if (fyt->type == FYTT_VERSION_DIRECTIVE || + fyt->type == FYTT_TAG_DIRECTIVE || + fyt->type == FYTT_DOCUMENT_START || + fyt->type == FYTT_DOCUMENT_END || + fyt->type == FYTT_STREAM_END) { + + if (fyt->type == FYTT_DOCUMENT_START || + fyt->type == FYTT_DOCUMENT_END) { + fyp->document_has_content = false; + fyp->document_first_content_token = true; + fyp->had_directives = false; + } + + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + } + + fyp->document_has_content = true; + fyp_parse_debug(fyp, "document has content now"); + /* fallthrough */ + + case FYPS_BLOCK_NODE: + + fyep = fy_parse_node(fyp, fyt, + fyp->state == FYPS_BLOCK_NODE || + fyp->state == FYPS_DOCUMENT_CONTENT); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + + case FYPS_BLOCK_SEQUENCE_FIRST_ENTRY: + is_first = true; + /* fallthrough */ + + case FYPS_BLOCK_SEQUENCE_ENTRY: + case FYPS_INDENTLESS_SEQUENCE_ENTRY: + + if ((fyp->state == FYPS_BLOCK_SEQUENCE_ENTRY || + fyp->state == FYPS_BLOCK_SEQUENCE_FIRST_ENTRY) && + !(fyt->type == FYTT_BLOCK_ENTRY || + fyt->type == FYTT_BLOCK_END)) { + + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !(fyt->type == FYTT_SCALAR), err_out, + "invalid scalar at the end of block sequence"); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !(fyt->type == FYTT_BLOCK_SEQUENCE_START), err_out, + "wrongly indented sequence item"); + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + false, err_out, + "did not find expected '-' indicator"); + } + + if (fyt->type == FYTT_BLOCK_ENTRY) { + + /* BLOCK entry */ + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + /* check whether it's a sequence entry or not */ + is_seq = fyt->type != FYTT_BLOCK_ENTRY && fyt->type != FYTT_BLOCK_END; + if (!is_seq && fyp->state == FYPS_INDENTLESS_SEQUENCE_ENTRY) + is_seq = fyt->type != FYTT_KEY && fyt->type != FYTT_VALUE; + + if (is_seq) { + rc = fy_parse_state_push(fyp, fyp->state); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, true); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + fy_parse_state_set(fyp, FYPS_BLOCK_SEQUENCE_ENTRY); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + } + + /* FYTT_BLOCK_END */ + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + 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!"); + } else + fye->sequence_end.sequence_end = fy_scan_remove(fyp, fyt); + + return fyep; + + case FYPS_BLOCK_MAPPING_FIRST_KEY: + is_first = true; + /* fallthrough */ + + case FYPS_BLOCK_MAPPING_KEY: + + if (!(fyt->type == FYTT_KEY || fyt->type == FYTT_BLOCK_END || fyt->type == FYTT_STREAM_END)) { + + if (fyt->type == FYTT_SCALAR) + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + !fyp->simple_key_allowed && !fyp->flow_level && fy_parse_peek(fyp) == ':' ? + "invalid block mapping key on same line as previous key" : + "invalid value after mapping"); + else if (fyt->type == FYTT_BLOCK_SEQUENCE_START) + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "wrong indendation in sequence while in mapping"); + else if (fyt->type == FYTT_ANCHOR) + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "two anchors for a single value while in mapping"); + else if (fyt->type == FYTT_BLOCK_MAPPING_START) + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + !fyp->flow_level && fyp->last_block_mapping_key_line == fy_token_start_line(fyt) ? + "invalid nested block mapping on the same line" : + "invalid indentation in mapping"); + else if (fyt->type == FYTT_ALIAS) + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "invalid combination of anchor plus alias"); + else + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "did not find expected key"); + goto err_out; + } + + if (fyt->type == FYTT_KEY) { + + fyp->last_block_mapping_key_line = fy_token_end_line(fyt); + + /* KEY entry */ + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + /* check whether it's a block entry or not */ + is_block = fyt->type != FYTT_KEY && fyt->type != FYTT_VALUE && + fyt->type != FYTT_BLOCK_END; + + if (is_block) { + rc = fy_parse_state_push(fyp, FYPS_BLOCK_MAPPING_VALUE); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, true); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + fy_parse_state_set(fyp, FYPS_BLOCK_MAPPING_VALUE); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + } + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + /* FYTT_BLOCK_END */ + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + fye->type = FYET_MAPPING_END; + fye->mapping_end.mapping_end = fy_scan_remove(fyp, fyt); + return fyep; + + case FYPS_BLOCK_MAPPING_VALUE: + + if (fyt->type == FYTT_VALUE) { + + /* VALUE entry */ + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + /* check whether it's a block entry or not */ + is_value = fyt->type != FYTT_KEY && fyt->type != FYTT_VALUE && + fyt->type != FYTT_BLOCK_END; + + if (is_value) { + rc = fy_parse_state_push(fyp, FYPS_BLOCK_MAPPING_KEY); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, true); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + } + + fy_parse_state_set(fyp, FYPS_BLOCK_MAPPING_KEY); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + + case FYPS_FLOW_SEQUENCE_FIRST_ENTRY: + is_first = true; + /* fallthrough */ + + case FYPS_FLOW_SEQUENCE_ENTRY: + + if (fyt->type != FYTT_FLOW_SEQUENCE_END && + fyt->type != FYTT_STREAM_END) { + + if (!is_first) { + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyt->type == FYTT_FLOW_ENTRY, err_out, + "missing comma in flow %s", + fyp->state == FYPS_FLOW_SEQUENCE_ENTRY ? + "sequence" : "mapping"); + + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + } + + if (fyt->type == FYTT_KEY) { + fy_parse_state_set(fyp, FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_KEY); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + /* convert KEY token to either block or flow mapping start */ + if (!fyt->key.flow_level) + fyt->type = FYTT_BLOCK_MAPPING_START; + else + fyt->type = FYTT_FLOW_MAPPING_START; + + fye->type = FYET_MAPPING_START; + fye->mapping_start.anchor = NULL; + fye->mapping_start.tag = NULL; + fye->mapping_start.mapping_start = fy_scan_remove(fyp, fyt); + return fyep; + } + + if (fyt->type != FYTT_FLOW_SEQUENCE_END) { + rc = fy_parse_state_push(fyp, FYPS_FLOW_SEQUENCE_ENTRY); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, false); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + } + + if (fyt->type == FYTT_STREAM_END && fyp->flow_level) { + FYP_TOKEN_ERROR(fyp, fyt, FYEM_PARSE, + "flow sequence without a closing bracket"); + goto err_out; + } + + /* FYTT_FLOW_SEQUENCE_END */ + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_SEQUENCE_END; + fye->sequence_end.sequence_end = fy_scan_remove(fyp, fyt); + return fyep; + + case FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_KEY: + if (fyt->type != FYTT_VALUE && fyt->type != FYTT_FLOW_ENTRY && + fyt->type != FYTT_FLOW_SEQUENCE_END) { + rc = fy_parse_state_push(fyp, FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, false); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + + /* empty keys are not allowed in JSON mode */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp), err_out, + "JSON does not allow empty keys of a mapping"); + + fy_parse_state_set(fyp, FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + + case FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE: + if (fyt->type == FYTT_VALUE) { + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + if (fyt->type != FYTT_FLOW_ENTRY && fyt->type != FYTT_FLOW_SEQUENCE_END) { + rc = fy_parse_state_push(fyp, FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, false); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + } + + /* empty values are not allowed in JSON mode */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp), err_out, + "JSON does not allow empty values in a mapping"); + + fy_parse_state_set(fyp, FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + + case FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END: + fy_parse_state_set(fyp, FYPS_FLOW_SEQUENCE_ENTRY); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + 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!"); + + return fyep; + + case FYPS_FLOW_MAPPING_FIRST_KEY: + is_first = true; + /* fallthrough */ + + case FYPS_FLOW_MAPPING_KEY: + if (fyt->type != FYTT_FLOW_MAPPING_END) { + + if (!is_first) { + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyt->type == FYTT_FLOW_ENTRY, err_out, + "missing comma in flow %s", + fyp->state == FYPS_FLOW_SEQUENCE_ENTRY ? + "sequence" : "mapping"); + + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + } + + if (fyt->type == FYTT_KEY) { + /* next token */ + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + /* JSON key checks */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp) || fyt->type != FYTT_VALUE, + err_out, "JSON does not allow empty keys"); + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp) || + (fyt->type == FYTT_SCALAR && + fyt->scalar.style == FYSS_DOUBLE_QUOTED), + err_out, "JSON only allows double quoted scalar keys"); + + if (fyt->type != FYTT_VALUE && + fyt->type != FYTT_FLOW_ENTRY && + fyt->type != FYTT_FLOW_MAPPING_END) { + + rc = fy_parse_state_push(fyp, FYPS_FLOW_MAPPING_VALUE); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, false); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + + fy_parse_state_set(fyp, FYPS_FLOW_MAPPING_VALUE); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + } + + if (fyt->type != FYTT_FLOW_MAPPING_END) { + + /* empty values are not allowed in JSON mode */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp), err_out, + "JSON does not allow empty values in a mapping"); + + rc = fy_parse_state_push(fyp, FYPS_FLOW_MAPPING_EMPTY_VALUE); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, false); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + } + + /* FYTT_FLOW_MAPPING_END */ + fy_parse_state_set(fyp, fy_parse_state_pop(fyp)); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_MAPPING_END; + fye->mapping_end.mapping_end = fy_scan_remove(fyp, fyt); + + return fyep; + + case FYPS_FLOW_MAPPING_VALUE: + if (fyt->type == FYTT_VALUE) { + /* next token */ + fyt = fy_scan_remove_peek(fyp, fyt); + fyp_error_check(fyp, fyt, err_out, + "failed to peek token"); + fyp_debug_dump_token(fyp, fyt, "next: "); + + if (fyt->type != FYTT_FLOW_ENTRY && + fyt->type != FYTT_FLOW_MAPPING_END) { + + rc = fy_parse_state_push(fyp, FYPS_FLOW_MAPPING_KEY); + fyp_error_check(fyp, !rc, err_out, + "failed to push state"); + + fyep = fy_parse_node(fyp, fyt, false); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_node() failed"); + return fyep; + } + } + + /* empty values are not allowed in JSON mode */ + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + !fyp_json_mode(fyp), err_out, + "JSON does not allow empty values in a mapping"); + + fy_parse_state_set(fyp, FYPS_FLOW_MAPPING_KEY); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + + case FYPS_FLOW_MAPPING_EMPTY_VALUE: + fy_parse_state_set(fyp, FYPS_FLOW_MAPPING_KEY); + + fyep = fy_parse_empty_scalar(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_parse_empty_scalar() failed"); + return fyep; + + case FYPS_SINGLE_DOCUMENT_END: + + FYP_TOKEN_ERROR_CHECK(fyp, fyt, FYEM_PARSE, + fyt->type == FYTT_STREAM_END, err_out, + "Did not find expected stream end"); + + rc = fy_parse_stream_end(fyp); + fyp_error_check(fyp, !rc, err_out, + "stream end failed"); + + fyep = fy_parse_eventp_alloc(fyp); + fyp_error_check(fyp, fyep, err_out, + "fy_eventp_alloc() failed!"); + fye = &fyep->e; + + fye->type = FYET_STREAM_END; + fye->stream_end.stream_end = fy_scan_remove(fyp, fyt); + + fy_parse_state_set(fyp, + fy_parse_have_more_inputs(fyp) ? FYPS_NONE : FYPS_END); + + return fyep; + + case FYPS_END: + /* should never happen */ + assert(0); + break; + } + +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_parse_eventp_recycle(fyp, fyep); + fyp->stream_error = true; + return NULL; +} + +const char *fy_event_type_txt[] = { + [FYET_NONE] = "NONE", + [FYET_STREAM_START] = "+STR", + [FYET_STREAM_END] = "-STR", + [FYET_DOCUMENT_START] = "+DOC", + [FYET_DOCUMENT_END] = "-DOC", + [FYET_MAPPING_START] = "+MAP", + [FYET_MAPPING_END] = "-MAP", + [FYET_SEQUENCE_START] = "+SEQ", + [FYET_SEQUENCE_END] = "-SEQ", + [FYET_SCALAR] = "=VAL", + [FYET_ALIAS] = "=ALI", +}; + +const char *fy_event_type_get_text(enum fy_event_type type) +{ + if ((unsigned int)type >= ARRAY_SIZE(fy_event_type_txt)) + return "*BAD"; + return fy_event_type_txt[type]; +} + +struct fy_eventp *fy_parse_private(struct fy_parser *fyp) +{ + struct fy_eventp *fyep = NULL; + + fyep = fy_parse_internal(fyp); + fyp_parse_debug(fyp, "> %s", fyep ? fy_event_type_txt[fyep->e.type] : "NULL"); + + return fyep; +} + +struct fy_parser *fy_parser_create(const struct fy_parse_cfg *cfg) +{ + struct fy_parser *fyp; + int rc; + + if (!cfg) + return NULL; + + fyp = malloc(sizeof(*fyp)); + if (!fyp) + return NULL; + + rc = fy_parse_setup(fyp, cfg); + if (rc) { + free(fyp); + return NULL; + } + + return fyp; +} + +void fy_parser_destroy(struct fy_parser *fyp) +{ + if (!fyp) + return; + + fy_parse_cleanup(fyp); + + free(fyp); +} + +const struct fy_parse_cfg *fy_parser_get_cfg(struct fy_parser *fyp) +{ + if (!fyp) + return NULL; + return &fyp->cfg; +} + +struct fy_diag *fy_parser_get_diag(struct fy_parser *fyp) +{ + if (!fyp || !fyp->diag) + return NULL; + return fy_diag_ref(fyp->diag); +} + +int fy_parser_set_diag(struct fy_parser *fyp, struct fy_diag *diag) +{ + struct fy_diag_cfg dcfg; + + if (!fyp) + return -1; + + /* default? */ + if (!diag) { + fy_diag_cfg_default(&dcfg); + diag = fy_diag_create(&dcfg); + if (!diag) + return -1; + } + + fy_diag_unref(fyp->diag); + fyp->diag = fy_diag_ref(diag); + + return 0; +} + +static void fy_parse_input_reset(struct fy_parser *fyp) +{ + struct fy_input *fyi, *fyin; + + for (fyi = fy_input_list_head(&fyp->queued_inputs); fyi; fyi = fyin) { + fyin = fy_input_next(&fyp->queued_inputs, fyi); + fy_input_unref(fyi); + } + + fy_parse_parse_state_log_list_recycle_all(fyp, &fyp->state_stack); + + fyp->stream_start_produced = false; + fyp->stream_end_produced = false; + fyp->stream_end_reached = false; + fyp->state = FYPS_NONE; + + fyp->pending_complex_key_column = -1; + fyp->last_block_mapping_key_line = -1; +} + +int fy_parser_set_input_file(struct fy_parser *fyp, const char *file) +{ + struct fy_input_cfg fyic; + int rc; + + if (!fyp || !file) + return -1; + + memset(&fyic, 0, sizeof(fyic)); + + if (!strcmp(file, "-")) { + 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; + } + + /* 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_string(struct fy_parser *fyp, const char *str, size_t len) +{ + struct fy_input_cfg fyic; + int rc; + + if (!fyp || !str) + return -1; + + if (len == (size_t)-1) + len = strlen(str); + + memset(&fyic, 0, sizeof(fyic)); + + fyic.type = fyit_memory; + fyic.memory.data = str; + fyic.memory.size = len; + + /* 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_malloc_string(struct fy_parser *fyp, char *str, size_t len) +{ + struct fy_input_cfg fyic; + int rc; + + if (!fyp || !str) + return -1; + + if (len == (size_t)-1) + len = strlen(str); + + memset(&fyic, 0, sizeof(fyic)); + + fyic.type = fyit_alloc; + fyic.alloc.data = str; + fyic.alloc.size = len; + + /* 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_fp(struct fy_parser *fyp, const char *name, FILE *fp) +{ + struct fy_input_cfg fyic; + int rc; + + if (!fyp || !fp) + return -1; + + memset(&fyic, 0, sizeof(fyic)); + + fyic.type = fyit_stream; + fyic.stream.name = name ? : ""; + fyic.stream.fp = fp; + fyic.stream.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_callback(struct fy_parser *fyp, void *user, + ssize_t (*callback)(void *user, void *buf, size_t count)) +{ + struct fy_input_cfg fyic; + int rc; + + if (!fyp || !callback) + return -1; + + memset(&fyic, 0, sizeof(fyic)); + + fyic.type = fyit_callback; + fyic.userdata = user; + fyic.callback.input = callback; + + /* 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_reset(struct fy_parser *fyp) +{ + int rc; + + if (!fyp) + return -1; + + fy_parse_input_reset(fyp); + + fy_reader_reset(fyp->reader); + + fyp->next_single_document = false; + fyp->stream_error = false; + fyp->generated_block_map = false; + fyp->last_was_comma = false; + fyp->document_has_content = false; + fyp->document_first_content_token = false; + fyp->bare_document_only = false; + fyp->stream_has_content = false; + fyp->had_directives = false; + + assert(fyp->diag); + fyp->diag->on_error = false; + + rc = fy_reset_document_state(fyp); + fyp_error_check(fyp, !rc, err_out_rc, + "fy_parse_input_reset() failed"); + + return 0; +err_out_rc: + return rc; +} + +struct fy_event *fy_parser_parse(struct fy_parser *fyp) +{ + struct fy_eventp *fyep; + enum fy_composer_return ret; + + if (!fyp) + return NULL; + + fyep = fy_parse_private(fyp); + if (!fyep) + return NULL; + + if (fyp->fyc) { + ret = fy_composer_process_event(fyp->fyc, fyp, &fyep->e); + if (ret == FYCR_ERROR) { + fyp->stream_error = true; + fy_parse_eventp_recycle(fyp, fyep); + return NULL; + } + /* note that the stop should be handled by + * an out of band mechanism */ + } + + return &fyep->e; +} + +bool fy_parser_get_stream_error(struct fy_parser *fyp) +{ + if (!fyp) + return true; + + return fyp->stream_error; +} + +enum fy_parse_cfg_flags fy_parser_get_cfg_flags(const struct fy_parser *fyp) +{ + if (!fyp) + return 0; + + return fyp->cfg.flags; +} + +struct fy_document_state *fy_parser_get_document_state(struct fy_parser *fyp) +{ + return fyp ? fyp->current_document_state : NULL; +} + +static enum fy_composer_return +parse_process_event(struct fy_composer *fyc, struct fy_path *path, struct fy_parser *fyp, struct fy_event *fye) +{ + if (!fyp->fyc_cb) + return 0; + + return fyp->fyc_cb(fyp, fye, path, fy_composer_get_cfg_userdata(fyc)); +} + +static const struct fy_composer_ops parser_composer_ops = { + .process_event = parse_process_event, +}; + +int fy_parse_set_composer(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata) +{ + struct fy_composer_cfg ccfg; + + if (!fyp) + return -1; + + /* must not be in the middle of something */ + fyp_error_check(fyp, fyp->state == FYPS_NONE || fyp->state == FYPS_END, + err_out, "cannot change composer state at state '%s'", + state_txt[fyp->state]); + + /* clear */ + if (!cb) { + if (fyp->fyc) { + fy_composer_destroy(fyp->fyc); + fyp->fyc = NULL; + } + fyp->fyc_cb = NULL; + return 0; + } + + /* already exists */ + if (fyp->fyc) { + fyp->fyc_cb = cb; + return 0; + } + + /* prepare the composer configuration */ + memset(&ccfg, 0, sizeof(ccfg)); + ccfg.ops = &parser_composer_ops; + ccfg.userdata = userdata; + 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; + + return 0; +err_out: + return -1; +} + +int fy_parse_compose(struct fy_parser *fyp, fy_parse_composer_cb cb, void *userdata) +{ + struct fy_eventp *fyep; + enum fy_composer_return ret; + int rc; + + 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"); + + /* insane but check anyway */ + assert(fyp->fyc); + + /* pump events */ + rc = 0; + while ((fyep = fy_parse_private(fyp)) != NULL) { + + /* call the composer */ + ret = fy_composer_process_event(fyp->fyc, fyp, &fyep->e); + fy_parse_eventp_recycle(fyp, fyep); + + /* on error stop */ + if (ret == FYCR_ERROR) { + fyp->stream_error = true; + rc = -1; + break; + } + + /* on normal requested stop, stop */ + if (ret == FYCR_OK_STOP) + break; + } + + /* reset the parser; the composer clear must always succeed */ + fy_parser_reset(fyp); + + /* clear composer */ + rc = fy_parse_set_composer(fyp, NULL, NULL); + fyp_error_check(fyp, !rc, err_out, + "fy_parse_set_composer() failed\n"); + + return rc; + +err_out: + return -1; +} diff --git a/src/lib/fy-parse.h b/src/lib/fy-parse.h new file mode 100644 index 0000000..19ff7dd --- /dev/null +++ b/src/lib/fy-parse.h @@ -0,0 +1,585 @@ +/* + * fy-parse.h - YAML parser internal header file + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_PARSE_H +#define FY_PARSE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-ctype.h" +#include "fy-utf8.h" +#include "fy-list.h" +#include "fy-typelist.h" +#include "fy-types.h" +#include "fy-diag.h" +#include "fy-dump.h" +#include "fy-atom.h" +#include "fy-input.h" +#include "fy-ctype.h" +#include "fy-token.h" +#include "fy-event.h" +#include "fy-docstate.h" +#include "fy-doc.h" +#include "fy-emit.h" +#include "fy-accel.h" +#include "fy-emit-accum.h" +#include "fy-path.h" +#include "fy-composer.h" + +struct fy_parser; +struct fy_input; + +enum fy_flow_type { + FYFT_NONE, + FYFT_MAP, + FYFT_SEQUENCE, +}; + +struct fy_flow { + struct list_head node; + enum fy_flow_type flow; + int pending_complex_key_column; + struct fy_mark pending_complex_key_mark; + int parent_indent; +}; +FY_PARSE_TYPE_DECL(flow); + +struct fy_indent { + struct list_head node; + int indent; + int indent_line; + bool generated_block_map : 1; +}; +FY_PARSE_TYPE_DECL(indent); + +struct fy_token; + +struct fy_simple_key { + struct list_head node; + struct fy_mark mark; + struct fy_mark end_mark; + struct fy_token *token; /* associated token */ + int flow_level; + bool required : 1; + bool implicit_complex : 1; +}; +FY_PARSE_TYPE_DECL(simple_key); + +struct fy_document_state; + +enum fy_parser_state { + /** none state */ + FYPS_NONE, + /** Expect STREAM-START. */ + FYPS_STREAM_START, + /** Expect the beginning of an implicit document. */ + FYPS_IMPLICIT_DOCUMENT_START, + /** Expect DOCUMENT-START. */ + FYPS_DOCUMENT_START, + /** Expect the content of a document. */ + FYPS_DOCUMENT_CONTENT, + /** Expect DOCUMENT-END. */ + FYPS_DOCUMENT_END, + /** Expect a block node. */ + FYPS_BLOCK_NODE, + /** Expect the first entry of a block sequence. */ + FYPS_BLOCK_SEQUENCE_FIRST_ENTRY, + /** Expect an entry of a block sequence. */ + FYPS_BLOCK_SEQUENCE_ENTRY, + /** Expect an entry of an indentless sequence. */ + FYPS_INDENTLESS_SEQUENCE_ENTRY, + /** Expect the first key of a block mapping. */ + FYPS_BLOCK_MAPPING_FIRST_KEY, + /** Expect a block mapping key. */ + FYPS_BLOCK_MAPPING_KEY, + /** Expect a block mapping value. */ + FYPS_BLOCK_MAPPING_VALUE, + /** Expect the first entry of a flow sequence. */ + FYPS_FLOW_SEQUENCE_FIRST_ENTRY, + /** Expect an entry of a flow sequence. */ + FYPS_FLOW_SEQUENCE_ENTRY, + /** Expect a key of an ordered mapping. */ + FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_KEY, + /** Expect a value of an ordered mapping. */ + FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE, + /** Expect the and of an ordered mapping entry. */ + FYPS_FLOW_SEQUENCE_ENTRY_MAPPING_END, + /** Expect the first key of a flow mapping. */ + FYPS_FLOW_MAPPING_FIRST_KEY, + /** Expect a key of a flow mapping. */ + FYPS_FLOW_MAPPING_KEY, + /** Expect a value of a flow mapping. */ + FYPS_FLOW_MAPPING_VALUE, + /** Expect an empty value of a flow mapping. */ + FYPS_FLOW_MAPPING_EMPTY_VALUE, + /** Expect only stream end */ + FYPS_SINGLE_DOCUMENT_END, + /** Expect nothing. */ + FYPS_END +}; + +struct fy_parse_state_log { + struct list_head node; + enum fy_parser_state state; +}; +FY_PARSE_TYPE_DECL(parse_state_log); + +struct fy_parser { + struct fy_parse_cfg cfg; + + struct fy_input_list queued_inputs; /* all the inputs queued */ + struct fy_reader builtin_reader; /* the builtin reader */ + struct fy_reader *reader; /* the external reader, or ptr to builtin_reader */ + + struct fy_version default_version; + bool suppress_recycling : 1; + bool stream_start_produced : 1; + bool stream_end_produced : 1; + bool stream_end_reached : 1; + bool simple_key_allowed : 1; + bool stream_error : 1; + bool generated_block_map : 1; + bool last_was_comma : 1; + bool document_has_content : 1; + bool document_first_content_token : 1; + bool bare_document_only : 1; /* no document start indicators allowed, no directives */ + bool stream_has_content : 1; + bool parse_flow_only : 1; /* document is in flow form, and stop parsing at the end */ + bool colon_follows_colon : 1; /* "foo"::bar -> "foo": :bar */ + bool had_directives : 1; /* document had directives */ + int flow_level; + int pending_complex_key_column; + struct fy_mark pending_complex_key_mark; + int last_block_mapping_key_line; + struct fy_mark last_comma_mark; + + /* copy of stream_end token */ + struct fy_token *stream_end_token; + + /* produced tokens, but not yet consumed */ + struct fy_token_list queued_tokens; + int token_activity_counter; + + /* last comment */ + struct fy_atom last_comment; + + /* indent stack */ + struct fy_indent_list indent_stack; + int indent; + int parent_indent; + int indent_line; + /* simple key stack */ + struct fy_simple_key_list simple_keys; + /* state stack */ + enum fy_parser_state state; + struct fy_parse_state_log_list state_stack; + + /* current parse document */ + struct fy_document_state *current_document_state; + struct fy_document_state *default_document_state; + bool next_single_document; + + /* flow stack */ + enum fy_flow_type flow; + struct fy_flow_list flow_stack; + + /* recycling lists */ + struct fy_indent_list recycled_indent; + struct fy_simple_key_list recycled_simple_key; + struct fy_parse_state_log_list recycled_parse_state_log; + struct fy_eventp_list recycled_eventp; + struct fy_flow_list recycled_flow; + struct fy_token_list recycled_token; + + /* the diagnostic object */ + struct fy_diag *diag; + + int err_term_width; + int err_term_height; + + /* for when using the built-in document builder */ + struct fy_document_builder *fydb; + + /* when using the composer interface */ + struct fy_composer *fyc; + fy_parse_composer_cb fyc_cb; +}; + +static inline struct fy_input * +fyp_current_input(const struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_current_input(fyp->reader); +} + +static inline uint64_t +fyp_current_input_generation(const struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_current_input_generation(fyp->reader); +} + +static inline int fyp_column(const struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_column(fyp->reader); +} + +static inline int fyp_line(const struct fy_parser *fyp) +{ + return fy_reader_line(fyp->reader); +} + +static inline int fyp_tabsize(const struct fy_parser *fyp) +{ + return fy_reader_tabsize(fyp->reader); +} + +static inline bool fyp_json_mode(const struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_json_mode(fyp->reader); +} + +static inline enum fy_lb_mode fyp_lb_mode(const struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_lb_mode(fyp->reader); +} + +static inline enum fy_flow_ws_mode fyp_fws_mode(const struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_flow_ws_mode(fyp->reader); +} + +static inline bool fyp_is_lb(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_lb(fyp->reader, c); +} + +static inline bool fyp_is_lbz(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_lbz(fyp->reader, c); +} + +static inline bool fyp_is_blankz(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_blankz(fyp->reader, c); +} + +static inline bool fyp_is_generic_lb(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_generic_lb(fyp->reader, c); +} + +static inline bool fyp_is_generic_lbz(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_generic_lbz(fyp->reader, c); +} + +static inline bool fyp_is_generic_blankz(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_generic_blankz(fyp->reader, c); +} + +static inline bool fyp_is_flow_ws(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_flow_ws(fyp->reader, c); +} + +static inline bool fyp_is_flow_blank(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_flow_blank(fyp->reader, c); +} + +static inline bool fyp_is_flow_blankz(const struct fy_parser *fyp, int c) +{ + assert(fyp); + return fy_reader_is_flow_blankz(fyp->reader, c); +} + +static inline const void * +fy_ptr_slow_path(struct fy_parser *fyp, size_t *leftp) +{ + assert(fyp); + return fy_reader_ptr_slow_path(fyp->reader, leftp); +} + +static inline const void * +fy_ensure_lookahead_slow_path(struct fy_parser *fyp, size_t size, size_t *leftp) +{ + assert(fyp); + return fy_reader_ensure_lookahead_slow_path(fyp->reader, size, leftp); +} + +/* only allowed if input does not update */ +static inline void +fy_get_mark(struct fy_parser *fyp, struct fy_mark *fym) +{ + assert(fyp); + return fy_reader_get_mark(fyp->reader, fym); +} + +static inline const void * +fy_ptr(struct fy_parser *fyp, size_t *leftp) +{ + assert(fyp); + return fy_reader_ptr(fyp->reader, leftp); +} + +static inline const void * +fy_ensure_lookahead(struct fy_parser *fyp, size_t size, size_t *leftp) +{ + assert(fyp); + return fy_reader_ensure_lookahead(fyp->reader, size, leftp); +} + +/* advance the given number of ascii characters, not utf8 */ +static inline void +fy_advance_octets(struct fy_parser *fyp, size_t advance) +{ + assert(fyp); + return fy_reader_advance_octets(fyp->reader, advance); +} + +/* compare string at the current point (n max) */ +static inline int +fy_parse_strncmp(struct fy_parser *fyp, const char *str, size_t n) +{ + assert(fyp); + return fy_reader_strncmp(fyp->reader, str, n); +} + +static 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 +fy_parse_peek_at_internal(struct fy_parser *fyp, int pos, ssize_t *offsetp) +{ + assert(fyp); + return fy_reader_peek_at_internal(fyp->reader, pos, offsetp); +} + +static inline bool +fy_is_blank_at_offset(struct fy_parser *fyp, size_t offset) +{ + assert(fyp); + return fy_is_blank(fy_reader_peek_at_offset(fyp->reader, offset)); +} + +static inline bool +fy_is_blankz_at_offset(struct fy_parser *fyp, size_t offset) +{ + assert(fyp); + return fy_reader_is_blankz(fyp->reader, fy_reader_peek_at_offset(fyp->reader, offset)); +} + +static inline bool +fy_is_generic_blankz_at_offset(struct fy_parser *fyp, size_t offset) +{ + assert(fyp); + return fy_reader_is_generic_blankz(fyp->reader, fy_reader_peek_at_offset(fyp->reader, offset)); +} + +static 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 +fy_parse_peek(struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_peek(fyp->reader); +} + +static inline void +fy_advance(struct fy_parser *fyp, int c) +{ + assert(fyp); + fy_reader_advance(fyp->reader, c); +} + +static inline void +fy_advance_ws(struct fy_parser *fyp, int c) +{ + assert(fyp); + fy_reader_advance_ws(fyp->reader, c); +} + +static inline void +fy_advance_space(struct fy_parser *fyp) +{ + assert(fyp); + fy_reader_advance_space(fyp->reader); +} + +static inline int +fy_parse_get(struct fy_parser *fyp) +{ + assert(fyp); + return fy_reader_get(fyp->reader); +} + +static inline int +fy_advance_by(struct fy_parser *fyp, int count) +{ + assert(fyp); + return fy_reader_advance_by(fyp->reader, count); +} + +/* compare string at the current point */ +static inline bool +fy_parse_strcmp(struct fy_parser *fyp, const char *str) +{ + assert(fyp); + return fy_reader_strcmp(fyp->reader, str); +} + +static inline void +fy_fill_atom_start(struct fy_parser *fyp, struct fy_atom *handle) +{ + assert(fyp); + fy_reader_fill_atom_start(fyp->reader, handle); +} + +static inline void +fy_fill_atom_end_at(struct fy_parser *fyp, struct fy_atom *handle, struct fy_mark *end_mark) +{ + assert(fyp); + fy_reader_fill_atom_end_at(fyp->reader, handle, end_mark); +} + +static inline void +fy_fill_atom_end(struct fy_parser *fyp, struct fy_atom *handle) +{ + assert(fyp); + fy_reader_fill_atom_end(fyp->reader, handle); +} + +static inline struct fy_atom * +fy_fill_atom(struct fy_parser *fyp, int advance, struct fy_atom *handle) +{ + assert(fyp); + return fy_reader_fill_atom(fyp->reader, advance, handle); +} + +static inline struct fy_atom * +fy_fill_atom_mark(struct fy_parser *fyp, const struct fy_mark *start_mark, + const struct fy_mark *end_mark, struct fy_atom *handle) +{ + assert(fyp); + return fy_reader_fill_atom_mark(fyp->reader, start_mark, end_mark, handle); +} + +static inline struct fy_atom * +fy_fill_atom_at(struct fy_parser *fyp, int advance, int count, struct fy_atom *handle) +{ + assert(fyp); + return fy_reader_fill_atom_at(fyp->reader, advance, count, handle); +} + +static inline void +fy_parser_set_reader(struct fy_parser *fyp, struct fy_reader *fyr) +{ + if (!fyp) + return; + fyp->reader = fyr ? : &fyp->builtin_reader; +} + +static inline void +fy_parser_set_flow_only_mode(struct fy_parser *fyp, bool flow_only_mode) +{ + fyp->parse_flow_only = flow_only_mode; +} + +#define fy_fill_atom_a(_fyp, _advance) \ + fy_fill_atom((_fyp), (_advance), alloca(sizeof(struct fy_atom))) + +struct fy_token *fy_token_vqueue(struct fy_parser *fyp, enum fy_token_type type, va_list ap); +struct fy_token *fy_token_queue(struct fy_parser *fyp, enum fy_token_type type, ...); + +struct fy_token * +fy_token_vqueue_internal(struct fy_parser *fyp, struct fy_token_list *fytl, + enum fy_token_type type, va_list ap); +struct fy_token * +fy_token_queue_internal(struct fy_parser *fyp, struct fy_token_list *fytl, + enum fy_token_type type, ...); + +int fy_parse_setup(struct fy_parser *fyp, const struct fy_parse_cfg *cfg); +void fy_parse_cleanup(struct fy_parser *fyp); + +int fy_parse_input_append(struct fy_parser *fyp, const struct fy_input_cfg *fyic); + +struct fy_eventp *fy_parse_private(struct fy_parser *fyp); + +extern const char *fy_event_type_txt[]; + +enum fy_parse_cfg_flags fy_parser_get_cfg_flags(const struct fy_parser *fyp); + +extern const struct fy_tag * const fy_default_tags[]; + +extern const struct fy_version fy_default_version; /* usually highest stable */ + +bool fy_tag_handle_is_default(const char *handle, size_t handle_size); +bool fy_tag_is_default_internal(const char *handle, size_t handle_size, + const char *prefix, size_t prefix_size); +bool fy_token_tag_directive_is_overridable(struct fy_token *fyt_td); + +int fy_parser_set_default_document_state(struct fy_parser *fyp, + struct fy_document_state *fyds); +void fy_parser_set_next_single_document(struct fy_parser *fyp); + +void *fy_alloc_default(void *userdata, size_t size); +void fy_free_default(void *userdata, void *ptr); +void *fy_realloc_default(void *userdata, void *ptr, size_t size); + +int fy_reader_fetch_flow_scalar_handle(struct fy_reader *fyr, int c, int indent, struct fy_atom *handle, bool sloppy_indent); +int fy_reader_fetch_plain_scalar_handle(struct fy_reader *fyr, int c, int indent, int flow_level, struct fy_atom *handle, bool directive0); + +void fy_reader_skip_ws_cr_nl(struct fy_reader *fyr); + +void fy_reader_skip_ws(struct fy_reader *fyr); +void fy_reader_skip_space(struct fy_reader *fyr); + +static inline int fy_document_state_version_compare(struct fy_document_state *fyds, const struct fy_version *vb) +{ + return fy_version_compare(fy_document_state_version(fyds), vb); +} + +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 diff --git a/src/lib/fy-path.c b/src/lib/fy-path.c new file mode 100644 index 0000000..948b1c7 --- /dev/null +++ b/src/lib/fy-path.c @@ -0,0 +1,552 @@ +/* + * fy-path.c - Internal ypath support + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-doc.h" + +#include "fy-utils.h" + +#undef DBG +// #define DBG fyp_notice +#define DBG fyp_scan_debug + +static int fy_path_setup(struct fy_path *fypp) +{ + memset(fypp, 0, sizeof(*fypp)); + + fy_path_component_list_init(&fypp->recycled_component); + fy_path_component_list_init(&fypp->components); + + return 0; +} + +static void fy_path_cleanup(struct fy_path *fypp) +{ + struct fy_path_component *fypc; + + if (!fypp) + return; + + if (fypp->fydb) { + fy_document_builder_destroy(fypp->fydb); + fypp->fydb = NULL; + } + + while ((fypc = fy_path_component_list_pop(&fypp->components)) != NULL) + fy_path_component_free(fypc); + + while ((fypc = fy_path_component_list_pop(&fypp->recycled_component)) != NULL) + fy_path_component_free(fypc); +} + +struct fy_path *fy_path_create(void) +{ + struct fy_path *fypp; + int rc; + + fypp = malloc(sizeof(*fypp)); + if (!fypp) + return NULL; + + rc = fy_path_setup(fypp); + if (rc) + return NULL; + + return fypp; +} + +void fy_path_destroy(struct fy_path *fypp) +{ + if (!fypp) + return; + + fy_path_cleanup(fypp); + + free(fypp); +} + +void fy_path_reset(struct fy_path *fypp) +{ + struct fy_path_component *fypc; + + if (!fypp) + return; + + while ((fypc = fy_path_component_list_pop(&fypp->components)) != NULL) + fy_path_component_free(fypc); +} + +struct fy_path_component *fy_path_component_alloc(struct fy_path *fypp) +{ + struct fy_path_component *fypc; + + if (!fypp) + return NULL; + + fypc = fy_path_component_list_pop(&fypp->recycled_component); + if (!fypc) { + fypc = malloc(sizeof(*fypc)); + if (!fypc) + return NULL; + memset(fypc, 0, sizeof(*fypc)); + } + + /* not yet instantiated */ + fypc->type = FYPCT_NONE; + + return fypc; +} + +void fy_path_component_clear_state(struct fy_path_component *fypc) +{ + if (!fypc) + return; + + switch (fypc->type) { + case FYPCT_NONE: + /* nothing */ + break; + + case FYPCT_MAP: + if (fypc->map.has_key) { + if (fypc->map.is_complex_key) { + if (fypc->map.complex_key_complete) + 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; + } + } + fypc->map.has_key = false; + fypc->map.await_key = true; + fypc->map.is_complex_key = false; + fypc->map.accumulating_complex_key = false; + fypc->map.complex_key_complete = false; + break; + + case FYPCT_SEQ: + fypc->seq.idx = -1; + break; + } +} + +void fy_path_component_cleanup(struct fy_path_component *fypc) +{ + if (!fypc) + return; + + fy_path_component_clear_state(fypc); + fypc->type = FYPCT_NONE; +} + +void fy_path_component_free(struct fy_path_component *fypc) +{ + if (!fypc) + return; + + fy_path_component_cleanup(fypc); + free(fypc); +} + +void fy_path_component_destroy(struct fy_path_component *fypc) +{ + if (!fypc) + return; + + fy_path_component_cleanup(fypc); + fy_path_component_free(fypc); +} + +void fy_path_component_recycle(struct fy_path *fypp, struct fy_path_component *fypc) +{ + if (!fypc) + return; + + fy_path_component_cleanup(fypc); + + if (!fypp) + fy_path_component_free(fypc); + else + fy_path_component_list_push(&fypp->recycled_component, fypc); +} + +struct fy_path_component *fy_path_component_create_mapping(struct fy_path *fypp) +{ + struct fy_path_component *fypc; + + if (!fypp) + return NULL; + + fypc = fy_path_component_alloc(fypp); + if (!fypc) + return NULL; + + fypc->type = FYPCT_MAP; + + fypc->map.await_key = true; + fypc->map.is_complex_key = false; + fypc->map.accumulating_complex_key = false; + fypc->map.complex_key_complete = false; + + return fypc; +} + +struct fy_path_component *fy_path_component_create_sequence(struct fy_path *fypp) +{ + struct fy_path_component *fypc; + + if (!fypp) + return NULL; + + fypc = fy_path_component_alloc(fypp); + if (!fypc) + return NULL; + + fypc->type = FYPCT_SEQ; + + fypc->seq.idx = -1; + + return fypc; +} + +bool fy_path_component_is_mapping(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_MAP; +} + +int fy_path_component_sequence_get_index(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_SEQ ? fypc->seq.idx : -1; +} + +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; +} + +struct fy_document *fy_path_component_mapping_get_complex_key(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_MAP && + fypc->map.has_key && fypc->map.is_complex_key ? fypc->map.complex_key : NULL; +} + +bool fy_path_component_is_sequence(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_SEQ; +} + +static int fy_path_get_text_internal(struct fy_emit_accum *ea, struct fy_path *fypp) +{ + struct fy_path_component *fypc; + struct fy_document *fyd; + char *doctxt; + const char *text; + size_t len; + bool local_key = false; + int rc, count; + + if (fypp->parent) { + rc = fy_path_get_text_internal(ea, fypp->parent); + assert(!rc); + if (rc) + return -1; + } + + /* OK, we have to iterate and rebuild the paths */ + for (fypc = fy_path_component_list_head(&fypp->components), count = 0; fypc; + fypc = fy_path_component_next(&fypp->components, fypc), count++) { + + fy_emit_accum_utf8_put_raw(ea, '/'); + + switch (fypc->type) { + case FYPCT_NONE: + abort(); + + case FYPCT_MAP: + + if (!fypc->map.has_key) + break; + + /* key reference ? wrap in .key(X)*/ + local_key = false; + if (fypc->map.await_key) + local_key = true; + + if (local_key) + fy_emit_accum_utf8_write_raw(ea, ".key(", 5); + + if (!fypc->map.is_complex_key) { + + 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) + fy_emit_accum_utf8_put_raw(ea, '*'); + fy_emit_accum_utf8_write_raw(ea, text, len); + } else { + fy_emit_accum_utf8_write_raw(ea, ".null()", 7); + } + } else { + if (fypc->map.complex_key) + fyd = fypc->map.complex_key; + else + fyd = fy_document_builder_peek_document(fypp->fydb); + + /* complex key */ + if (fyd) { + doctxt = fy_emit_document_to_string(fyd, + FYECF_WIDTH_INF | FYECF_INDENT_DEFAULT | + FYECF_MODE_FLOW_ONELINE | FYECF_NO_ENDING_NEWLINE); + } else + doctxt = NULL; + + if (doctxt) { + fy_emit_accum_utf8_write_raw(ea, doctxt, strlen(doctxt)); + free(doctxt); + } else { + fy_emit_accum_utf8_write_raw(ea, "", 3); + } + } + + if (local_key) + fy_emit_accum_utf8_put_raw(ea, ')'); + + break; + + case FYPCT_SEQ: + + /* not started filling yet */ + if (fypc->seq.idx < 0) + break; + + fy_emit_accum_utf8_printf_raw(ea, "%d", fypc->seq.idx); + break; + } + } + + return 0; +} + +char *fy_path_get_text(struct fy_path *fypp) +{ + struct fy_emit_accum ea; /* use an emit accumulator */ + char *path = 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_get_text_internal(&ea, fypp); + if (rc) + goto err_out; + + if (fy_emit_accum_empty(&ea)) + fy_emit_accum_utf8_printf_raw(&ea, "/"); + + fy_emit_accum_make_0_terminated(&ea); + + path = fy_emit_accum_steal(&ea, &len); + +err_out: + fy_emit_accum_cleanup(&ea); + + return path; +} + +int fy_path_depth(struct fy_path *fypp) +{ + struct fy_path_component *fypc; + int depth; + + if (!fypp) + return 0; + + depth = fy_path_depth(fypp->parent); + for (fypc = fy_path_component_list_head(&fypp->components); fypc; + fypc = fy_path_component_next(&fypp->components, fypc)) { + + depth++; + } + + return depth; +} + +struct fy_path *fy_path_parent(struct fy_path *fypp) +{ + if (!fypp) + return NULL; + return fypp->parent; +} + +struct fy_path_component * +fy_path_last_component(struct fy_path *fypp) +{ + return fy_path_component_list_tail(&fypp->components); +} + +struct fy_path_component * +fy_path_last_not_collection_root_component(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + fypc_last = fy_path_component_list_tail(&fypp->components); + if (!fypc_last) + return NULL; + + if (!fy_path_component_is_collection_root(fypc_last)) + return fypc_last; + + fypc_last = fy_path_component_prev(&fypp->components, fypc_last); + if (fypc_last) + return fypc_last; + + if (fypp->parent) + return fy_path_component_list_tail(&fypp->parent->components); + + return NULL; +} + +bool fy_path_in_root(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + if (!fypp) + return true; + + fypc_last = fy_path_last_not_collection_root_component(fypp); + return fypc_last == NULL; +} + + +bool fy_path_in_mapping(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + if (!fypp) + return false; + + fypc_last = fy_path_last_not_collection_root_component(fypp); + if (!fypc_last) + return false; + + return fypc_last->type == FYPCT_MAP; +} + +bool fy_path_in_sequence(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + if (!fypp) + return false; + + fypc_last = fy_path_last_not_collection_root_component(fypp); + if (!fypc_last) + return false; + + return fypc_last->type == FYPCT_SEQ; +} + +bool fy_path_in_mapping_key(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + if (!fypp) + return false; + + fypc_last = fy_path_last_not_collection_root_component(fypp); + if (!fypc_last) + return false; + + return fypc_last->type == FYPCT_MAP && fypc_last->map.await_key; +} + +bool fy_path_in_mapping_value(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + if (!fypp) + return false; + + fypc_last = fy_path_last_not_collection_root_component(fypp); + if (!fypc_last) + return false; + + return fypc_last->type == FYPCT_MAP && !fypc_last->map.await_key; +} + +bool fy_path_is_collection_root(struct fy_path *fypp) +{ + struct fy_path_component *fypc_last; + + if (!fypp) + return false; + + fypc_last = fy_path_component_list_tail(&fypp->components); + if (!fypc_last) + return false; + + return fy_path_component_is_collection_root(fypc_last); +} + +void *fy_path_component_get_mapping_user_data(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_MAP ? fypc->user_data : NULL; +} + +void *fy_path_component_get_mapping_key_user_data(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_MAP ? fypc->map.key_user_data : NULL; +} + +void *fy_path_component_get_sequence_user_data(struct fy_path_component *fypc) +{ + return fypc && fypc->type == FYPCT_SEQ ? fypc->user_data : NULL; +} + +void fy_path_component_set_mapping_user_data(struct fy_path_component *fypc, void *data) +{ + if (!fypc || fypc->type != FYPCT_MAP) + return; + + fypc->user_data = data; +} + +void fy_path_component_set_mapping_key_user_data(struct fy_path_component *fypc, void *data) +{ + if (!fypc || fypc->type != FYPCT_MAP) + return; + + fypc->map.key_user_data = data; +} + +void fy_path_component_set_sequence_user_data(struct fy_path_component *fypc, void *data) +{ + if (!fypc || fypc->type != FYPCT_SEQ) + return; + + fypc->user_data = data; +} diff --git a/src/lib/fy-path.h b/src/lib/fy-path.h new file mode 100644 index 0000000..73157f9 --- /dev/null +++ b/src/lib/fy-path.h @@ -0,0 +1,109 @@ +/* + * fy-path.h - YAML parser private path definitions + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_PATH_H +#define FY_PATH_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "fy-list.h" +#include "fy-typelist.h" + +#include "fy-emit-accum.h" + +FY_TYPE_FWD_DECL_LIST(path_component); + +enum fy_path_component_type { + FYPCT_NONE, /* not yet instantiated */ + FYPCT_MAP, /* it's a mapping */ + FYPCT_SEQ, /* it's a sequence */ +}; + +/* fwd declaration */ +struct fy_document; +struct fy_document_builder; + +#define FY_PATH_MAPPING_SHORT_KEY 32 + +struct fy_path_mapping_state { + bool await_key : 1; + bool accumulating_complex_key : 1; + bool has_key : 1; /* has a key */ + bool is_complex_key : 1; + bool complex_key_complete : 1; + union { + struct fy_token *scalar_key; + struct fy_document *complex_key; + }; + void *key_user_data; +}; + +struct fy_path_sequence_state { + int idx; +}; + +struct fy_path_component { + struct list_head node; + enum fy_path_component_type type; + union { + struct fy_path_mapping_state map; + struct fy_path_sequence_state seq; + }; + void *user_data; +}; +FY_TYPE_DECL_LIST(path_component); + +static inline bool +fy_path_component_is_collection_root(struct fy_path_component *fypc) +{ + if (!fypc) + return false; + + switch (fypc->type) { + case FYPCT_NONE: + break; + 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 false; +} + +FY_TYPE_FWD_DECL_LIST(path); +struct fy_path { + struct list_head node; + struct fy_path_component_list recycled_component; + struct fy_path_component_list components; + struct fy_document_builder *fydb; /* for complex keys */ + struct fy_path *parent; /* when we have a parent */ +}; +FY_TYPE_DECL_LIST(path); + +struct fy_path *fy_path_create(void); +void fy_path_destroy(struct fy_path *fypp); + +void fy_path_reset(struct fy_path *fypp); + +struct fy_path_component *fy_path_component_alloc(struct fy_path *fypp); +void fy_path_component_cleanup(struct fy_path_component *fypc); +void fy_path_component_free(struct fy_path_component *fypc); +void fy_path_component_destroy(struct fy_path_component *fypc); +void fy_path_component_recycle(struct fy_path *fypp, struct fy_path_component *fypc); +void fy_path_component_clear_state(struct fy_path_component *fypc); + +struct fy_path_component *fy_path_component_create_mapping(struct fy_path *fypp); +struct fy_path_component *fy_path_component_create_sequence(struct fy_path *fypp); + +#endif diff --git a/src/lib/fy-token.c b/src/lib/fy-token.c new file mode 100644 index 0000000..984fec0 --- /dev/null +++ b/src/lib/fy-token.c @@ -0,0 +1,1908 @@ +/* + * fy-token.c - YAML token methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" + +#include "fy-ctype.h" +#include "fy-utf8.h" +#include "fy-emit-accum.h" + +#include "fy-walk.h" + +#include "fy-token.h" + +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; +} + +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; +} + +void fy_token_clean_rl(struct fy_token_list *fytl, struct fy_token *fyt) +{ + int i; + + if (!fyt) + return; + + /* release reference */ + fy_input_unref(fyt->handle.fyi); + + /* release comment references */ + if (fyt->comment) { + for (i = 0; i < fycp_max; i++) + fy_input_unref(fyt->comment[i].fyi); + free(fyt->comment); + } + + switch (fyt->type) { + case FYTT_TAG: + fy_token_unref(fyt->tag.fyt_td); + if (fyt->tag.handle0) + free(fyt->tag.handle0); + if (fyt->tag.suffix0) + free(fyt->tag.suffix0); + fyt->tag.fyt_td = NULL; + fyt->tag.handle0 = NULL; + fyt->tag.suffix0 = NULL; + break; + + case FYTT_TAG_DIRECTIVE: + if (fyt->tag_directive.prefix0) + free(fyt->tag_directive.prefix0); + if (fyt->tag_directive.handle0) + free(fyt->tag_directive.handle0); + fyt->tag_directive.prefix0 = NULL; + fyt->tag_directive.handle0 = NULL; + break; + + case FYTT_PE_MAP_KEY: + fy_document_destroy(fyt->map_key.fyd); + fyt->map_key.fyd = NULL; + break; + + case FYTT_SCALAR: + if (fyt->scalar.path_key_storage) + free(fyt->scalar.path_key_storage); + fyt->scalar.path_key_storage = NULL; + break; + + case FYTT_ALIAS: + if (fyt->alias.expr) + fy_path_expr_free(fyt->alias.expr); + fyt->alias.expr = NULL; + break; + + default: + break; + } + + if (fyt->text0) + free(fyt->text0); + + 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) +{ + struct fy_token *fyt; + + while ((fyt = fy_token_list_pop(fytl_tofree)) != NULL) + fy_token_unref_rl(fytl, fyt); +} + +static bool fy_token_text_needs_rebuild(struct fy_token *fyt) +{ + const struct fy_atom *fya; + + if (!fy_token_text_is_direct(fyt)) + return false; + + fya = fy_token_atom(fyt); + if (!fya || !fya->fyi) + return false; + + return fya->fyi_generation != fya->fyi->generation; +} + +static int fy_tag_token_format_internal(const struct fy_token *fyt, void *out, size_t *outszp) +{ + char *o = NULL, *oe = NULL; + size_t outsz; + const char *handle, *suffix; + size_t handle_size, suffix_size; + int len, code_length, rlen; + uint8_t code[4]; + const char *t, *s, *e; + + if (!fyt || fyt->type != FYTT_TAG) + return 0; + + if (out && *outszp <= 0) + return 0; + + if (out) { + outsz = *outszp; + o = out; + oe = out + outsz; + } + + if (!fyt->tag.fyt_td) + return -1; + + handle = fy_tag_directive_token_prefix(fyt->tag.fyt_td, &handle_size); + if (!handle) + return -1; + + suffix = fy_atom_data(&fyt->handle) + fyt->tag.skip + fyt->tag.handle_length; + suffix_size = fyt->tag.suffix_length; + +#define O_CPY(_src, _len) \ + do { \ + int _l = (_len); \ + if (o && _l) { \ + int _cl = _l; \ + if (_cl > (oe - o)) \ + _cl = oe - o; \ + memcpy(o, (_src), _cl); \ + o += _cl; \ + } \ + len += _l; \ + } while(0) + + len = 0; + O_CPY(handle, handle_size); + + /* escape suffix as a URI */ + s = suffix; + e = s + suffix_size; + while (s < e) { + /* find next escape */ + t = memchr(s, '%', e - s); + rlen = (t ? t : e) - s; + O_CPY(s, rlen); + + /* end of string */ + if (!t) + break; + s = t; + + code_length = sizeof(code); + t = fy_uri_esc(s, e - s, code, &code_length); + if (!t) + break; + + /* output escaped utf8 */ + O_CPY(code, code_length); + s = t; + } + +#undef O_CPY + return len; + +} + +int fy_tag_token_format_text_length(const struct fy_token *fyt) +{ + return fy_tag_token_format_internal(fyt, NULL, NULL); +} + +const char *fy_tag_token_format_text(const struct fy_token *fyt, char *buf, size_t maxsz) +{ + fy_tag_token_format_internal(fyt, buf, &maxsz); + return buf; +} + +static int fy_tag_directive_token_format_internal(const struct fy_token *fyt, + void *out, size_t *outszp) +{ + char *o = NULL, *oe = NULL; + size_t outsz; + int len; + const char *handle, *prefix; + size_t handle_size, prefix_size; + + if (!fyt || fyt->type != FYTT_TAG_DIRECTIVE) + return 0; + + if (out && *outszp <= 0) + return 0; + + if (out) { + outsz = *outszp; + o = out; + oe = out + outsz; + } + +#define O_CPY(_src, _len) \ + do { \ + int _l = (_len); \ + if (o && _l) { \ + int _cl = _l; \ + if (_cl > (oe - o)) \ + _cl = oe - o; \ + memcpy(o, (_src), _cl); \ + o += _cl; \ + } \ + len += _l; \ + } while(0) + + len = 0; + + handle = fy_atom_data(&fyt->handle); + handle_size = fy_atom_size(&fyt->handle); + + prefix = handle + handle_size - fyt->tag_directive.uri_length; + prefix_size = fyt->tag_directive.uri_length; + handle_size = fyt->tag_directive.tag_length; + + if (handle_size) + O_CPY(handle, handle_size); + else + O_CPY("!<", 2); + O_CPY(prefix, prefix_size); + if (!handle_size) + O_CPY(">", 1); + +#undef O_CPY + return len; + +} + +int fy_tag_directive_token_format_text_length(const struct fy_token *fyt) +{ + return fy_tag_directive_token_format_internal(fyt, NULL, NULL); +} + +const char *fy_tag_directive_token_format_text(const struct fy_token *fyt, char *buf, size_t maxsz) +{ + fy_tag_directive_token_format_internal(fyt, buf, &maxsz); + return buf; +} + +const char *fy_tag_directive_token_prefix(struct fy_token *fyt, size_t *lenp) +{ + const char *ptr; + size_t len; + + if (!fyt || fyt->type != FYTT_TAG_DIRECTIVE) { + *lenp = 0; + return NULL; + } + ptr = fy_atom_data(&fyt->handle); + len = fy_atom_size(&fyt->handle); + ptr = ptr + len - fyt->tag_directive.uri_length; + *lenp = fyt->tag_directive.uri_length; + + return ptr; +} + +const char *fy_tag_directive_token_prefix0(struct fy_token *fyt) +{ + char *text0; + const char *text; + size_t len; + + if (!fyt || fyt->type != FYTT_TAG_DIRECTIVE) + return NULL; + + /* use the cache if it's there (and doesn't need a rebuild) */ + if (fyt->tag_directive.prefix0 && !fy_token_text_needs_rebuild(fyt)) + return fyt->tag_directive.prefix0; + + if (fyt->tag_directive.prefix0) { + free(fyt->tag_directive.prefix0); + fyt->tag_directive.prefix0 = NULL; + } + + text = fy_tag_directive_token_prefix(fyt, &len); + if (!text) + return NULL; + + text0 = malloc(len + 1); + if (!text0) + return NULL; + memcpy(text0, text, len); + text0[len] = '\0'; + + fyt->tag_directive.prefix0 = text0; + + return fyt->tag_directive.prefix0; +} + +const char *fy_tag_directive_token_handle(struct fy_token *fyt, size_t *lenp) +{ + const char *ptr; + + if (!fyt || fyt->type != FYTT_TAG_DIRECTIVE) { + *lenp = 0; + return NULL; + } + ptr = fy_atom_data(&fyt->handle); + *lenp = fyt->tag_directive.tag_length; + return ptr; +} + +const char *fy_tag_directive_token_handle0(struct fy_token *fyt) +{ + char *text0; + const char *text; + size_t len; + + if (!fyt || fyt->type != FYTT_TAG_DIRECTIVE) + return NULL; + + /* use the cache if it's there (and doesn't need a rebuild) */ + if (fyt->tag_directive.handle0 && !fy_token_text_needs_rebuild(fyt)) + return fyt->tag_directive.handle0; + + if (fyt->tag_directive.handle0) { + free(fyt->tag_directive.handle0); + fyt->tag_directive.handle0 = NULL; + } + + text = fy_tag_directive_token_handle(fyt, &len); + if (!text) + return NULL; + + text0 = malloc(len + 1); + if (!text0) + return NULL; + memcpy(text0, text, len); + text0[len] = '\0'; + + fyt->tag_directive.handle0 = text0; + + return fyt->tag_directive.handle0; +} + +struct fy_token *fy_token_vcreate_rl(struct fy_token_list *fytl, enum fy_token_type type, va_list ap) +{ + struct fy_token *fyt = NULL; + struct fy_atom *handle; + struct fy_token *fyt_td; + + if ((unsigned int)type >= FYTT_COUNT) + goto err_out; + + fyt = fy_token_alloc_rl(fytl); + if (!fyt) + goto err_out; + fyt->type = type; + + handle = va_arg(ap, struct fy_atom *); + if (handle) + fyt->handle = *handle; + else + memset(&fyt->handle, 0, sizeof(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; + break; + case FYTT_SCALAR: + fyt->scalar.style = va_arg(ap, enum fy_scalar_style); + if ((unsigned int)fyt->scalar.style >= FYSS_MAX) + goto err_out; + fyt->scalar.path_key = NULL; + fyt->scalar.path_key_len = 0; + fyt->scalar.path_key_storage = NULL; + break; + case FYTT_TAG: + fyt->tag.skip = va_arg(ap, unsigned int); + fyt->tag.handle_length = va_arg(ap, unsigned int); + fyt->tag.suffix_length = va_arg(ap, unsigned int); + + fyt_td = va_arg(ap, struct fy_token *); + if (!fyt_td) + goto err_out; + fyt->tag.fyt_td = fy_token_ref(fyt_td); + break; + + case FYTT_VERSION_DIRECTIVE: + fyt->version_directive.vers = *va_arg(ap, struct fy_version *); + break; + + case FYTT_ALIAS: + fyt->alias.expr = va_arg(ap, struct fy_path_expr *); + break; + + case FYTT_KEY: + fyt->key.flow_level = va_arg(ap, int); + break; + + case FYTT_PE_MAP_KEY: + fyt->map_key.fyd = va_arg(ap, struct fy_document *); + break; + + case FYTT_PE_SEQ_INDEX: + fyt->seq_index.index = va_arg(ap, int); + break; + + case FYTT_PE_SEQ_SLICE: + fyt->seq_slice.start_index = va_arg(ap, int); + fyt->seq_slice.end_index = va_arg(ap, int); + break; + + case FYTT_NONE: + goto err_out; + + default: + break; + } + + if (fyt->handle.fyi) + fy_input_ref(fyt->handle.fyi); + + return fyt; + +err_out: + fy_token_unref(fyt); + + return NULL; +} + +struct fy_token *fy_token_create_rl(struct fy_token_list *fytl, enum fy_token_type type, ...) +{ + struct fy_token *fyt; + va_list ap; + + va_start(ap, type); + fyt = fy_token_vcreate_rl(fytl, type, ap); + va_end(ap); + + return fyt; +} + +struct fy_token *fy_token_vcreate(enum fy_token_type type, va_list ap) +{ + return fy_token_vcreate_rl(NULL, type, ap); +} + +struct fy_token *fy_token_create(enum fy_token_type type, ...) +{ + struct fy_token *fyt; + va_list ap; + + va_start(ap, type); + fyt = fy_token_vcreate_rl(NULL, type, ap); + va_end(ap); + + return fyt; +} + +struct fy_token *fy_parse_token_create(struct fy_parser *fyp, enum fy_token_type type, ...) +{ + struct fy_token *fyt; + va_list ap; + + if (!fyp) + return NULL; + + va_start(ap, type); + fyt = fy_token_vcreate_rl(&fyp->recycled_token, type, ap); + va_end(ap); + + return fyt; +} + +int fy_token_format_text_length(struct fy_token *fyt) +{ + int length; + + if (!fyt) + return 0; + + switch (fyt->type) { + + case FYTT_TAG: + return fy_tag_token_format_text_length(fyt); + + case FYTT_TAG_DIRECTIVE: + return fy_tag_directive_token_format_text_length(fyt); + + default: + break; + } + + length = fy_atom_format_text_length(&fyt->handle); + + return length; +} + +const char *fy_token_format_text(struct fy_token *fyt, char *buf, size_t maxsz) +{ + const char *str; + + if (maxsz == 0) + return buf; + + if (!fyt) { + if (maxsz > 0) + buf[0] = '\0'; + return buf; + } + + switch (fyt->type) { + + case FYTT_TAG: + return fy_tag_token_format_text(fyt, buf, maxsz); + + case FYTT_TAG_DIRECTIVE: + return fy_tag_directive_token_format_text(fyt, buf, maxsz); + + default: + break; + } + + str = fy_atom_format_text(&fyt->handle, buf, maxsz); + + return str; +} + +int fy_token_format_utf8_length(struct fy_token *fyt) +{ + const char *str; + size_t len; + + if (!fyt) + return 0; + + switch (fyt->type) { + + case FYTT_TAG: + case FYTT_TAG_DIRECTIVE: + str = fy_token_get_text(fyt, &len); + if (!str) + return 0; + return fy_utf8_count(str, len); + + default: + break; + } + + return fy_atom_format_utf8_length(&fyt->handle); +} + + +struct fy_atom *fy_token_atom(struct fy_token *fyt) +{ + return fyt ? &fyt->handle : NULL; +} + +const struct fy_mark *fy_token_start_mark(struct fy_token *fyt) +{ + const struct fy_atom *atom; + + atom = fy_token_atom(fyt); + if (atom) + return &atom->start_mark; + + /* something we don't track */ + return NULL; +} + +const struct fy_mark *fy_token_end_mark(struct fy_token *fyt) +{ + const struct fy_atom *atom; + + atom = fy_token_atom(fyt); + if (atom) + return &atom->end_mark; + + /* something we don't track */ + return NULL; +} + +int fy_token_text_analyze(struct fy_token *fyt) +{ + const char *s, *e; + const char *value = NULL; + enum fy_atom_style style; + int c, w, cn, cp, col; + size_t len; + int flags; + + if (!fyt) + return FYTTAF_CAN_BE_SIMPLE_KEY | FYTTAF_DIRECT_OUTPUT | + FYTTAF_EMPTY | FYTTAF_CAN_BE_DOUBLE_QUOTED; + + if (fyt->analyze_flags) + return fyt->analyze_flags; + + /* only tokens that can generate text */ + if (fyt->type != FYTT_SCALAR && + fyt->type != FYTT_TAG && + fyt->type != FYTT_ANCHOR && + fyt->type != FYTT_ALIAS) { + flags = FYTTAF_NO_TEXT_TOKEN; + fyt->analyze_flags = flags; + return flags; + } + + flags = FYTTAF_TEXT_TOKEN; + + style = fy_token_atom_style(fyt); + + /* can this token be a simple key initial condition */ + if (!fy_atom_style_is_block(style) && style != FYAS_URI) + flags |= FYTTAF_CAN_BE_SIMPLE_KEY; + + /* can this token be directly output initial condition */ + if (!fy_atom_style_is_block(style)) + flags |= FYTTAF_DIRECT_OUTPUT; + + /* get value */ + value = fy_token_get_text(fyt, &len); + if (!value || len == 0) { + flags |= FYTTAF_EMPTY | FYTTAF_CAN_BE_DOUBLE_QUOTED | FYTTAF_CAN_BE_UNQUOTED_PATH_KEY; + fyt->analyze_flags = flags; + return flags; + } + + flags |= FYTTAF_CAN_BE_PLAIN | + FYTTAF_CAN_BE_SINGLE_QUOTED | + FYTTAF_CAN_BE_DOUBLE_QUOTED | + FYTTAF_CAN_BE_LITERAL | + FYTTAF_CAN_BE_LITERAL | + FYTTAF_CAN_BE_FOLDED | + FYTTAF_CAN_BE_PLAIN_FLOW | + FYTTAF_CAN_BE_UNQUOTED_PATH_KEY; + + /* start with document indicators must be quoted at indent 0 */ + if (len >= 3 && (!memcmp(value, "---", 3) || !memcmp(value, "...", 3))) + flags |= FYTTAF_QUOTE_AT_0; + + s = value; + e = value + len; + + col = 0; + + /* get first character */ + cn = fy_utf8_get(s, e - s, &w); + s += w; + col = fy_token_is_lb(fyt, cn) ? 0 : (col + 1); + + /* disable folded right off the bat, it's a pain */ + flags &= ~FYTTAF_CAN_BE_FOLDED; + + /* plain scalars can't start with any indicator (or space/lb) */ + if ((flags & (FYTTAF_CAN_BE_PLAIN | FYTTAF_CAN_BE_PLAIN_FLOW)) && + (fy_is_indicator(cn) || fy_token_is_lb(fyt, cn) || fy_is_ws(cn))) + flags &= ~(FYTTAF_CAN_BE_PLAIN | + FYTTAF_CAN_BE_PLAIN_FLOW); + + /* plain scalars in flow mode can't start with a flow indicator */ + if ((flags & FYTTAF_CAN_BE_PLAIN_FLOW) && + fy_is_flow_indicator(cn)) + flags &= ~FYTTAF_CAN_BE_PLAIN_FLOW; + + /* plain unquoted path keys can only start with [a-zA-Z_] */ + if ((flags & FYTTAF_CAN_BE_UNQUOTED_PATH_KEY) && + !fy_is_first_alpha(cn)) + flags &= ~FYTTAF_CAN_BE_UNQUOTED_PATH_KEY; + + cp = -1; + for (c = cn; c >= 0; s += w, cp = c, c = cn) { + + /* can be -1 on end */ + cn = fy_utf8_get(s, e - s, &w); + + /* zero can't be output, only in double quoted mode */ + if (c == 0) { + flags &= ~(FYTTAF_DIRECT_OUTPUT | + FYTTAF_CAN_BE_PLAIN | + FYTTAF_CAN_BE_SINGLE_QUOTED | + FYTTAF_CAN_BE_LITERAL | + FYTTAF_CAN_BE_FOLDED | + FYTTAF_CAN_BE_PLAIN_FLOW | + FYTTAF_CAN_BE_UNQUOTED_PATH_KEY); + flags |= FYTTAF_CAN_BE_DOUBLE_QUOTED; + + } else if (fy_is_ws(c)) { + + flags |= FYTTAF_HAS_WS; + if (fy_is_ws(cn)) + flags |= FYTTAF_HAS_CONSECUTIVE_WS; + + } else if (fy_token_is_lb(fyt, c)) { + + flags |= FYTTAF_HAS_LB; + if (fy_token_is_lb(fyt, cn)) + flags |= FYTTAF_HAS_CONSECUTIVE_LB; + + /* only non linebreaks can be simple keys */ + flags &= ~FYTTAF_CAN_BE_SIMPLE_KEY; + + /* anything with linebreaks, can't be direct */ + flags &= ~FYTTAF_DIRECT_OUTPUT; + } + + if ((flags & FYTTAF_CAN_BE_UNQUOTED_PATH_KEY) && !fy_is_alnum(c)) + flags &= ~FYTTAF_CAN_BE_UNQUOTED_PATH_KEY; + + /* illegal plain combination */ + if ((flags & FYTTAF_CAN_BE_PLAIN) && + ((c == ':' && fy_is_blankz_m(cn, fy_token_atom_lb_mode(fyt))) || + (fy_is_blankz_m(c, fy_token_atom_lb_mode(fyt)) && cn == '#') || + (cp < 0 && c == '#' && cn < 0) || + !fy_is_print(c))) { + flags &= ~(FYTTAF_CAN_BE_PLAIN | + FYTTAF_CAN_BE_PLAIN_FLOW); + } + + /* illegal plain flow combination */ + if ((flags & FYTTAF_CAN_BE_PLAIN_FLOW) && + (fy_is_flow_indicator(c) || (c == ':' && fy_is_flow_indicator(cn)))) + flags &= ~FYTTAF_CAN_BE_PLAIN_FLOW; + + /* non printable characters, turn off these styles */ + if ((flags & (FYTTAF_CAN_BE_SINGLE_QUOTED | + FYTTAF_CAN_BE_LITERAL | + FYTTAF_CAN_BE_FOLDED)) && !fy_is_print(c)) + flags &= ~(FYTTAF_CAN_BE_SINGLE_QUOTED | + FYTTAF_CAN_BE_LITERAL | + FYTTAF_CAN_BE_FOLDED); + + /* if there's an escape, it can't be direct */ + if ((flags & FYTTAF_DIRECT_OUTPUT) && + ((style == FYAS_URI && c == '%') || + (style == FYAS_SINGLE_QUOTED && c == '\'') || + (style == FYAS_DOUBLE_QUOTED && c == '\\'))) + flags &= ~FYTTAF_DIRECT_OUTPUT; + + col = fy_token_is_lb(fyt, c) ? 0 : (col + 1); + + /* last character */ + if (cn < 0) { + /* if ends with whitespace or linebreak, can't be plain */ + if (fy_is_ws(cn) || fy_token_is_lb(fyt, cn)) + flags &= ~(FYTTAF_CAN_BE_PLAIN | + FYTTAF_CAN_BE_PLAIN_FLOW); + } + } + + fyt->analyze_flags = flags; + return flags; +} + +const char *fy_tag_token_get_directive_handle(struct fy_token *fyt, size_t *td_handle_sizep) +{ + if (!fyt || fyt->type != FYTT_TAG || !fyt->tag.fyt_td) + return NULL; + + return fy_tag_directive_token_handle(fyt->tag.fyt_td, td_handle_sizep); +} + +const char *fy_tag_token_get_directive_prefix(struct fy_token *fyt, size_t *td_prefix_sizep) +{ + if (!fyt || fyt->type != FYTT_TAG || !fyt->tag.fyt_td) + return NULL; + + return fy_tag_directive_token_prefix(fyt->tag.fyt_td, td_prefix_sizep); +} + +const char *fy_token_get_direct_output(struct fy_token *fyt, size_t *sizep) +{ + const struct fy_atom *fya; + + fya = fy_token_atom(fyt); + if (!fya || !fya->direct_output || + (fyt->type == FYTT_TAG || fyt->type == FYTT_TAG_DIRECTIVE) ) { + *sizep = 0; + return NULL; + } + *sizep = fy_atom_size(fya); + return fy_atom_data(fya); +} + +const char *fy_tag_token_handle(struct fy_token *fyt, size_t *lenp) +{ + return fy_tag_token_get_directive_handle(fyt, lenp); +} + +const char *fy_tag_token_suffix(struct fy_token *fyt, size_t *lenp) +{ + const char *tag, *prefix, *handle, *suffix; + size_t tag_len, prefix_len, handle_len, suffix_len; + + if (!fyt || fyt->type != FYTT_TAG) { + *lenp = 0; + return NULL; + } + + tag = fy_token_get_text(fyt, &tag_len); + if (!tag) + return NULL; + prefix = fy_tag_token_get_directive_prefix(fyt, &prefix_len); + if (!prefix) + return NULL; + handle = fy_tag_token_handle(fyt, &handle_len); + if (!handle || !handle_len) { + suffix = tag; + suffix_len = tag_len; + } else { + assert(prefix_len <= tag_len); + assert(tag_len >= prefix_len); + suffix = tag + prefix_len; + suffix_len = tag_len - prefix_len; + } + *lenp = suffix_len; + return suffix; +} + +const char *fy_tag_token_handle0(struct fy_token *fyt) +{ + char *text0; + const char *text; + size_t len; + + if (!fyt || fyt->type != FYTT_TAG) + return NULL; + + /* use the cache if it's there (and doesn't need a rebuild) */ + if (fyt->tag.handle0 && !fy_token_text_needs_rebuild(fyt)) + return fyt->tag.handle0; + + if (fyt->tag.handle0) { + free(fyt->tag.handle0); + fyt->tag.handle0 = NULL; + } + + text = fy_tag_token_handle(fyt, &len); + if (!text) + return NULL; + + text0 = malloc(len + 1); + if (!text0) + return NULL; + memcpy(text0, text, len); + text0[len] = '\0'; + + fyt->tag.handle0 = text0; + + return fyt->tag.handle0; +} + +const char *fy_tag_token_suffix0(struct fy_token *fyt) +{ + char *text0; + const char *text; + size_t len; + + if (!fyt || fyt->type != FYTT_TAG) + return NULL; + + /* use the cache if it's there (and doesn't need a rebuild) */ + if (fyt->tag.suffix0 && !fy_token_text_needs_rebuild(fyt)) + return fyt->tag.suffix0; + + if (fyt->tag.suffix0) { + free(fyt->tag.suffix0); + fyt->tag.suffix0 = NULL; + } + + text = fy_tag_token_suffix(fyt, &len); + if (!text) + return NULL; + + text0 = malloc(len + 1); + if (!text0) + return NULL; + memcpy(text0, text, len); + text0[len] = '\0'; + + fyt->tag.suffix0 = text0; + + return fyt->tag.suffix0; +} + +const struct fy_version * fy_version_directive_token_version(struct fy_token *fyt) +{ + if (!fyt || fyt->type != FYTT_VERSION_DIRECTIVE) + return NULL; + return &fyt->version_directive.vers; +} + +static void fy_token_prepare_text(struct fy_token *fyt) +{ + int ret; + + assert(fyt); + + /* get text length of this token */ + ret = fy_token_format_text_length(fyt); + + /* no text on this token? */ + if (ret == -1) { + fyt->text_len = 0; + fyt->text = fyt->text0 = strdup(""); + return; + } + + fyt->text0 = malloc(ret + 1); + if (!fyt->text0) { + fyt->text_len = 0; + fyt->text = fyt->text0 = strdup(""); + return; + } + + fyt->text0[0] = '\0'; + + fyt->text_len = ret; + + fy_token_format_text(fyt, fyt->text0, ret + 1); + fyt->text0[ret] = '\0'; + + fyt->text_len = ret; + fyt->text = fyt->text0; +} + +const char *fy_token_get_text(struct fy_token *fyt, size_t *lenp) +{ + /* return empty */ + if (!fyt) { + *lenp = 0; + return ""; + } + + /* already found something */ + if (fyt->text && !fy_token_text_needs_rebuild(fyt)) { + *lenp = fyt->text_len; + return fyt->text; + } + + /* try direct output first */ + fyt->text = fy_token_get_direct_output(fyt, &fyt->text_len); + if (!fyt->text) + fy_token_prepare_text(fyt); + + *lenp = fyt->text_len; + return fyt->text; +} + +const char *fy_token_get_text0(struct fy_token *fyt) +{ + /* return empty */ + if (!fyt) + return ""; + + /* created text is always zero terminated */ + if (!fyt->text0) + fy_token_prepare_text(fyt); + + return fyt->text0; +} + +size_t fy_token_get_text_length(struct fy_token *fyt) +{ + return fy_token_format_text_length(fyt); +} + +enum comment_out_state { + cos_normal, + cos_lastnl, + cos_lastnlhash, + cos_lastnlhashspc, +}; + +const char *fy_token_get_comment(struct fy_token *fyt, char *buf, size_t maxsz, + enum fy_comment_placement which) +{ + struct fy_atom *handle; + struct fy_atom_iter iter; + const struct fy_iter_chunk *ic; + char *s, *e; + const char *ss, *ee; + int c, w, ret; + enum comment_out_state state; + bool output; + + if (!buf || maxsz == 0 || (unsigned int)which >= fycp_max) + return NULL; + + /* return empty? */ + handle = fy_token_comment_handle(fyt, which, false); + if (!handle || !fy_atom_is_set(handle)) + return NULL; + + /* start expecting # */ + state = cos_lastnl; + + s = buf; + e = s + maxsz; + fy_atom_iter_start(handle, &iter); + ic = NULL; + while ((ic = fy_atom_iter_chunk_next(&iter, ic, &ret)) != NULL) { + ss = ic->str; + ee = ss + ic->len; + + while ((c = fy_utf8_get(ss, ee - ss, &w)) > 0) { + + output = true; + switch (state) { + case cos_normal: + if (fy_is_lb_m(c, handle->lb_mode)) + state = cos_lastnl; + break; + + case cos_lastnl: + if (c == '#') { + state = cos_lastnlhash; + output = false; + break; + } + state = cos_normal; + break; + + case cos_lastnlhash: + if (c == ' ') { + state = cos_lastnlhashspc; + output = false; + break; + } + state = cos_normal; + break; + + case cos_lastnlhashspc: + state = cos_normal; + break; + } + + if (output) { + s = fy_utf8_put(s, (size_t)(e - s), c); + if (!s) + return NULL; + } + + ss += w; + } + } + fy_atom_iter_finish(&iter); + + if (ret != 0 || s >= e) + return NULL; + *s = '\0'; + + return buf; +} + +const char *fy_token_get_scalar_path_key(struct fy_token *fyt, size_t *lenp) +{ + struct fy_atom *atom; + struct fy_atom_iter iter; + struct fy_emit_accum ea; /* use an emit accumulator */ + uint8_t non_utf8[4]; + size_t non_utf8_len, k; + int c, i, w, digit; + int aflags; + + if (!fyt || fyt->type != FYTT_SCALAR) { + *lenp = 0; + return NULL; + } + + /* was it cached? return */ + if (fyt->scalar.path_key) { + *lenp = fyt->scalar.path_key_len; + return fyt->scalar.path_key; + } + + /* analyze the token */ + aflags = fy_token_text_analyze(fyt); + + /* simple one? perfect */ + if ((aflags & FYTTAF_CAN_BE_UNQUOTED_PATH_KEY) == FYTTAF_CAN_BE_UNQUOTED_PATH_KEY) { + fyt->scalar.path_key = fy_token_get_text(fyt, &fyt->scalar.path_key_len); + *lenp = fyt->scalar.path_key_len; + return fyt->scalar.path_key; + } + + /* not possible, need to quote (and escape) */ + + /* no atom? i.e. empty */ + atom = fy_token_atom(fyt); + if (!atom) { + fyt->scalar.path_key = ""; + fyt->scalar.path_key_len = 0; + *lenp = 0; + return fyt->scalar.path_key; + } + + /* no inplace buffer; we will need the malloc'ed contents anyway */ + fy_emit_accum_init(&ea, NULL, 0, 0, fylb_cr_nl); + + fy_atom_iter_start(atom, &iter); + fy_emit_accum_start(&ea, 0, fy_token_atom_lb_mode(fyt)); + + /* output in quoted form */ + fy_emit_accum_utf8_put(&ea, '"'); + + for (;;) { + non_utf8_len = sizeof(non_utf8); + c = fy_atom_iter_utf8_quoted_get(&iter, &non_utf8_len, non_utf8); + if (c < 0) + break; + + if (c == 0 && non_utf8_len > 0) { + for (k = 0; k < non_utf8_len; k++) { + c = (int)non_utf8[k] & 0xff; + fy_emit_accum_utf8_put(&ea, '\\'); + fy_emit_accum_utf8_put(&ea, 'x'); + digit = ((unsigned int)c >> 4) & 15; + fy_emit_accum_utf8_put(&ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + digit = (unsigned int)c & 15; + fy_emit_accum_utf8_put(&ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + continue; + } + + if (!fy_is_printq(c) || c == '"' || c == '\\') { + + fy_emit_accum_utf8_put(&ea, '\\'); + + switch (c) { + + /* common YAML & JSON escapes */ + case '\b': + fy_emit_accum_utf8_put(&ea, 'b'); + break; + case '\f': + fy_emit_accum_utf8_put(&ea, 'f'); + break; + case '\n': + fy_emit_accum_utf8_put(&ea, 'n'); + break; + case '\r': + fy_emit_accum_utf8_put(&ea, 'r'); + break; + case '\t': + fy_emit_accum_utf8_put(&ea, 't'); + break; + case '"': + fy_emit_accum_utf8_put(&ea, '"'); + break; + case '\\': + fy_emit_accum_utf8_put(&ea, '\\'); + break; + + /* YAML only escapes */ + case '\0': + fy_emit_accum_utf8_put(&ea, '0'); + break; + case '\a': + fy_emit_accum_utf8_put(&ea, 'a'); + break; + case '\v': + fy_emit_accum_utf8_put(&ea, 'v'); + break; + case '\e': + fy_emit_accum_utf8_put(&ea, 'e'); + break; + case 0x85: + fy_emit_accum_utf8_put(&ea, 'N'); + break; + case 0xa0: + fy_emit_accum_utf8_put(&ea, '_'); + break; + case 0x2028: + fy_emit_accum_utf8_put(&ea, 'L'); + break; + case 0x2029: + fy_emit_accum_utf8_put(&ea, 'P'); + break; + + default: + /* any kind of binary value */ + if ((unsigned int)c <= 0xff) { + fy_emit_accum_utf8_put(&ea, 'x'); + w = 2; + } else if ((unsigned int)c <= 0xffff) { + fy_emit_accum_utf8_put(&ea, 'u'); + w = 4; + } else if ((unsigned int)c <= 0xffffffff) { + fy_emit_accum_utf8_put(&ea, 'U'); + w = 8; + } + + for (i = w - 1; i >= 0; i--) { + digit = ((unsigned int)c >> (i * 4)) & 15; + fy_emit_accum_utf8_put(&ea, + digit <= 9 ? ('0' + digit) : ('A' + digit - 10)); + } + break; + } + + continue; + } + + /* regular character */ + fy_emit_accum_utf8_put(&ea, c); + } + + fy_atom_iter_finish(&iter); + + /* closing quote */ + fy_emit_accum_utf8_put(&ea, '"'); + + fy_emit_accum_make_0_terminated(&ea); + + /* get the output (note it's now NULL terminated) */ + fyt->scalar.path_key_storage = fy_emit_accum_steal(&ea, &fyt->scalar.path_key_len); + fyt->scalar.path_key = fyt->scalar.path_key_storage; + fy_emit_accum_cleanup(&ea); + + *lenp = fyt->scalar.path_key_len; + + return fyt->scalar.path_key; +} + +size_t fy_token_get_scalar_path_key_length(struct fy_token *fyt) +{ + const char *text; + size_t len; + + text = fy_token_get_scalar_path_key(fyt, &len); + if (!text) + return 0; + return len; +} + +const char *fy_token_get_scalar_path_key0(struct fy_token *fyt) +{ + const char *text; + size_t len; + + if (!fyt || fyt->type != FYTT_SCALAR) { + return NULL; + } + + /* storage is \0 terminated */ + if (fyt->scalar.path_key_storage) + return fyt->scalar.path_key_storage; + + text = fyt->scalar.path_key; + len = fyt->scalar.path_key_len; + if (!text) + text = fy_token_get_scalar_path_key(fyt, &len); + + /* something is catastrophically wrong */ + if (!text) + return NULL; + + if (fyt->scalar.path_key_storage) + return fyt->scalar.path_key_storage; + + fyt->scalar.path_key_storage = malloc(len + 1); + if (!fyt->scalar.path_key_storage) + return NULL; + + memcpy(fyt->scalar.path_key_storage, text, len); + fyt->scalar.path_key_storage[len] = '\0'; + + return fyt->scalar.path_key_storage; +} + +unsigned int fy_analyze_scalar_content(const char *data, size_t size, + bool json_mode, enum fy_lb_mode lb_mode, enum fy_flow_ws_mode fws_mode) +{ + const char *s, *e; + int c, lastc, nextc, w, ww, col, break_run; + unsigned int flags; + bool first; + + flags = FYACF_EMPTY | FYACF_BLOCK_PLAIN | FYACF_FLOW_PLAIN | + FYACF_PRINTABLE | FYACF_SINGLE_QUOTED | FYACF_DOUBLE_QUOTED | + FYACF_SIZE0 | FYACF_VALID_ANCHOR; + + s = data; + e = data + size; + + col = 0; + first = true; + lastc = -1; + break_run = 0; + while (s < e && (c = fy_utf8_get(s, e - s, &w)) >= 0) { + + flags &= ~FYACF_SIZE0; + + lastc = c; + + if (first) { + if (fy_is_ws(c)) + flags |= FYACF_STARTS_WITH_WS; + else if (fy_is_generic_lb_m(c, lb_mode)) + flags |= FYACF_STARTS_WITH_LB; + /* scalars starting with & or * must be quoted */ + if (c == '&' || c == '*') + flags &= ~(FYACF_BLOCK_PLAIN | FYACF_FLOW_PLAIN); + first = false; + } + nextc = fy_utf8_get(s + w, e - (s + w), &ww); + + /* anything other than white space or linebreak */ + if ((flags & FYACF_EMPTY) && + !fy_is_ws(c) && !fy_is_generic_lb_m(c, lb_mode)) + flags &= ~FYACF_EMPTY; + + if ((flags & FYACF_VALID_ANCHOR) && + (fy_utf8_strchr(",[]{}&*:", c) || fy_is_ws(c) || + fy_is_any_lb(c) || fy_is_unicode_control(c) || + fy_is_unicode_space(c))) + flags &= ~FYACF_VALID_ANCHOR; + + /* linebreak */ + if (fy_is_generic_lb_m(c, lb_mode)) { + flags |= FYACF_LB; + if (!(flags & FYACF_CONSECUTIVE_LB) && + fy_is_generic_lb_m(nextc, lb_mode)) + flags |= FYACF_CONSECUTIVE_LB; + break_run++; + } else + break_run = 0; + + /* white space */ + if (!(flags & FYACF_WS) && fy_is_ws(c)) { + flags |= FYACF_WS; + flags &= ~FYACF_VALID_ANCHOR; + } + + /* anything not printable (or \r, \n) */ + if ((flags & FYACF_PRINTABLE) && + !fy_is_printq(c)) { + flags &= ~FYACF_PRINTABLE; + flags &= ~(FYACF_BLOCK_PLAIN | FYACF_FLOW_PLAIN | + FYACF_SINGLE_QUOTED | FYACF_VALID_ANCHOR); + } + + /* check for document indicators (at column 0) */ + if (!(flags & FYACF_DOC_IND) && + ((col == 0 && (e - s) >= 3 && + (!strncmp(s, "---", 3) || !strncmp(s, "...", 3))))) { + flags |= FYACF_DOC_IND; + flags &= ~(FYACF_BLOCK_PLAIN | FYACF_FLOW_PLAIN | FYACF_VALID_ANCHOR); + } + + /* comment indicator can't be present after a space or lb */ + /* : followed by blank can't be any plain */ + if (flags & (FYACF_BLOCK_PLAIN | FYACF_FLOW_PLAIN) && + (((fy_is_blank(c) || fy_is_generic_lb_m(c, lb_mode)) && nextc == '#') || + (c == ':' && fy_is_blankz_m(nextc, lb_mode)))) + flags &= ~(FYACF_BLOCK_PLAIN | FYACF_FLOW_PLAIN); + + /* : followed by flow markers can't be a plain in flow context */ + if ((flags & FYACF_FLOW_PLAIN) && + (fy_utf8_strchr(",[]{}", c) || (c == ':' && fy_utf8_strchr(",[]{}", nextc)))) + flags &= ~FYACF_FLOW_PLAIN; + + if (!(flags & FYACF_JSON_ESCAPE) && !fy_is_json_unescaped(c)) + flags |= FYACF_JSON_ESCAPE; + + if (fy_is_generic_lb_m(c, lb_mode)) + col = 0; + else + col++; + + s += w; + } + + /* this contains arbitrary binany values, mark it as such */ + if (s < e) + return FYACF_DOUBLE_QUOTED; + + if (fy_is_ws(lastc)) + flags |= FYACF_ENDS_WITH_WS; + else if (fy_is_generic_lb_m(lastc, lb_mode)) + flags |= FYACF_ENDS_WITH_LB; + + if (break_run > 1) + flags |= FYACF_TRAILING_LB; + + return flags; +} + +char *fy_token_debug_text(struct fy_token *fyt) +{ + const char *typetxt; + const char *text; + char *buf; + size_t length; + int wlen; + int rc __FY_DEBUG_UNUSED__; + + if (!fyt || !fy_token_type_is_valid(fyt->type)) { + typetxt = ""; + goto out; + } + typetxt = fy_token_type_txt[fyt->type]; + + /* should never happen really */ + assert(typetxt); + +out: + text = fy_token_get_text(fyt, &length); + + wlen = length > 8 ? 8 : length; + + rc = asprintf(&buf, "%s:%.*s%s", typetxt, wlen, text, wlen < (int)length ? "..." : ""); + assert(rc != -1); + + return buf; +} + +int fy_token_memcmp(struct fy_token *fyt, const void *ptr, size_t len) +{ + const char *value = NULL; + size_t tlen = 0; + + /* special zero length handling */ + if (len == 0 && fyt && fy_token_get_text_length(fyt) == 0) + return 0; + + /* handle NULL cases */ + if (!fyt && (!ptr || !len)) + return 0; + + if (!fyt && (ptr || len)) + return -1; + + if (fyt && (!ptr || !len)) + return 1; + + /* those two are special */ + if (fyt->type == FYTT_TAG || fyt->type == FYTT_TAG_DIRECTIVE) { + value = fy_token_get_text(fyt, &tlen); + if (!value) + return -1; + return tlen == len ? memcmp(value, ptr, tlen) : tlen < len ? -1 : 1; + } + + return fy_atom_memcmp(fy_token_atom(fyt), ptr, len); +} + +int fy_token_strcmp(struct fy_token *fyt, const char *str) +{ + size_t len; + + len = str ? strlen(str) : 0; + + return fy_token_memcmp(fyt, str, len); +} + +int fy_token_cmp(struct fy_token *fyt1, struct fy_token *fyt2) +{ + const char *t1, *t2; + size_t l1, l2, l; + int ret; + + /* handles both NULL */ + if (fyt1 == fyt2) + return 0; + + /* fyt1 is null, 2 wins */ + if (!fyt1 && fyt2) + return -1; + + /* fyt2 is null, 1 wins */ + if (fyt1 && !fyt2) + return 1; + + /* tokens with different types can't be equal */ + if (fyt1->type != fyt2->type) + return fyt2->type > fyt1->type ? -1 : 1; + + /* special case, these can't use the atom comparisons */ + if (fyt1->type == FYTT_TAG || fyt1->type == FYTT_TAG_DIRECTIVE) { + t1 = fy_token_get_text(fyt1, &l1); + t2 = fy_token_get_text(fyt2, &l2); + l = l1 > l2 ? l2 : l1; + ret = memcmp(t1, t2, l); + if (ret) + return ret; + return l1 == l2 ? 0 : l2 > l1 ? -1 : 1; + } + + /* just pass it to the atom comparison methods */ + return fy_atom_cmp(fy_token_atom(fyt1), fy_token_atom(fyt2)); +} + +void fy_token_iter_start(struct fy_token *fyt, struct fy_token_iter *iter) +{ + if (!iter) + return; + + memset(iter, 0, sizeof(*iter)); + + iter->unget_c = -1; + + if (!fyt) + return; + + iter->fyt = fyt; + + /* TAG or TAG_DIRECTIVE may only work by getting the text */ + if (fyt->type == FYTT_TAG || fyt->type == FYTT_TAG_DIRECTIVE) + iter->ic.str = fy_token_get_text(fyt, &iter->ic.len); + else /* try the direct output next */ + iter->ic.str = fy_token_get_direct_output(fyt, &iter->ic.len); + + /* got it */ + if (iter->ic.str) { + memset(&iter->atom_iter, 0, sizeof(iter->atom_iter)); + return; + } + + assert(fyt->type != FYTT_TAG && fyt->type != FYTT_TAG_DIRECTIVE); + + /* fall back to the atom iterator */ + fy_atom_iter_start(fy_token_atom(fyt), &iter->atom_iter); +} + +void fy_token_iter_finish(struct fy_token_iter *iter) +{ + if (!iter) + return; + + if (!iter->ic.str) + fy_atom_iter_finish(&iter->atom_iter); +} + +struct fy_token_iter * +fy_token_iter_create(struct fy_token *fyt) +{ + struct fy_token_iter *iter; + + iter = malloc(sizeof(*iter)); + if (!iter) + return NULL; + fy_token_iter_start(fyt, iter); + return iter; +} + +void fy_token_iter_destroy(struct fy_token_iter *iter) +{ + if (!iter) + return; + + fy_token_iter_finish(iter); + free(iter); +} + +const struct fy_iter_chunk *fy_token_iter_peek_chunk(struct fy_token_iter *iter) +{ + if (!iter) + return NULL; + + /* direct mode? */ + if (iter->ic.str) + return &iter->ic; + + /* fallback to the atom iterator */ + return fy_atom_iter_peek_chunk(&iter->atom_iter); +} + +void fy_token_iter_advance(struct fy_token_iter *iter, size_t len) +{ + if (!iter) + return; + + /* direct mode? */ + if (iter->ic.str) { + if (len > iter->ic.len) + len = iter->ic.len; + iter->ic.str += len; + iter->ic.len -= len; + return; + } + + /* fallback to the atom iterator */ + fy_atom_iter_advance(&iter->atom_iter, len); +} + +const struct fy_iter_chunk * +fy_token_iter_chunk_next(struct fy_token_iter *iter, const struct fy_iter_chunk *curr, int *errp) +{ + if (!iter) + return NULL; + + if (errp) + *errp = 0; + + /* first time in */ + if (!curr) { + if (iter->ic.str) + return iter->ic.len ? &iter->ic : NULL; + return fy_atom_iter_chunk_next(&iter->atom_iter, NULL, errp); + } + + /* direct, all consumed */ + if (curr == &iter->ic) { + iter->ic.str += iter->ic.len; + iter->ic.len = 0; + return NULL; + } + + /* fallback */ + return fy_atom_iter_chunk_next(&iter->atom_iter, curr, errp); +} + +ssize_t fy_token_iter_read(struct fy_token_iter *iter, void *buf, size_t count) +{ + if (!iter || !buf) + return -1; + + /* direct mode */ + if (iter->ic.str) { + if (count > iter->ic.len) + count = iter->ic.len; + memcpy(buf, iter->ic.str, count); + iter->ic.str += count; + iter->ic.len -= count; + return count; + } + + return fy_atom_iter_read(&iter->atom_iter, buf, count); +} + +int fy_token_iter_getc(struct fy_token_iter *iter) +{ + int c; + + if (!iter) + return -1; + + /* first try the pushed ungetc */ + if (iter->unget_c != -1) { + c = iter->unget_c; + iter->unget_c = -1; + return c; + } + + /* direct mode */ + if (iter->ic.str) { + if (!iter->ic.len) + return -1; + c = *iter->ic.str++; + iter->ic.len--; + return c; + } + + return fy_atom_iter_getc(&iter->atom_iter); +} + +int fy_token_iter_ungetc(struct fy_token_iter *iter, int c) +{ + if (iter->unget_c != -1) + return -1; + if (c == -1) { + iter->unget_c = -1; + return 0; + } + iter->unget_c = c & 0xff; + return c & 0xff; +} + +int fy_token_iter_peekc(struct fy_token_iter *iter) +{ + int c; + + c = fy_token_iter_getc(iter); + if (c == -1) + return -1; + + return fy_token_iter_ungetc(iter, c); +} + +int fy_token_iter_utf8_get(struct fy_token_iter *iter) +{ + int c, w, w1; + + /* first try the pushed ungetc */ + if (iter->unget_c != -1) { + c = iter->unget_c; + iter->unget_c = -1; + return c; + } + + /* direct */ + if (iter->ic.str) { + + /* not even 1 octet */ + if (!iter->ic.len) + return -1; + + /* get width by the first octet */ + w = fy_utf8_width_by_first_octet((uint8_t)*iter->ic.str); + if (!w || (unsigned int)w > iter->ic.len) + return -1; + + /* get the next character */ + c = fy_utf8_get(iter->ic.str, w, &w1); + + iter->ic.str += w; + iter->ic.len -= w; + + return c; + } + + return fy_atom_iter_utf8_get(&iter->atom_iter); +} + +int fy_token_iter_utf8_unget(struct fy_token_iter *iter, int c) +{ + if (iter->unget_c != -1) + return -1; + + if (c == -1) { + iter->unget_c = -1; + return 0; + } + + iter->unget_c = c; + return c; +} + +int fy_token_iter_utf8_peek(struct fy_token_iter *iter) +{ + int c; + + c = fy_token_iter_utf8_get(iter); + if (c == -1) + return -1; + + return fy_token_iter_utf8_unget(iter, c); +} + +enum fy_scalar_style +fy_scalar_token_get_style(struct fy_token *fyt) +{ + if (!fyt || fyt->type != FYTT_SCALAR) + return FYSS_ANY; + return fyt->scalar.style; +} + +const struct fy_tag *fy_tag_token_tag(struct fy_token *fyt) +{ + if (!fyt || fyt->type != FYTT_TAG) + return NULL; + + /* always refresh, should be relatively infrequent */ + fyt->tag.tag.handle = fy_tag_token_handle0(fyt); + fyt->tag.tag.prefix = fy_tag_token_suffix0(fyt); + + return &fyt->tag.tag; +} + +const struct fy_tag * +fy_tag_directive_token_tag(struct fy_token *fyt) +{ + if (!fyt || fyt->type != FYTT_TAG_DIRECTIVE) + return NULL; + + /* always refresh, should be relatively infrequent */ + fyt->tag_directive.tag.handle = fy_tag_directive_token_handle0(fyt); + fyt->tag_directive.tag.prefix = fy_tag_directive_token_prefix0(fyt); + + return &fyt->tag_directive.tag; +} + +struct fy_atom *fy_token_comment_handle(struct fy_token *fyt, enum fy_comment_placement placement, bool alloc) +{ + struct fy_atom *handle; + size_t size; + + if (!fyt || (unsigned int)placement >= fycp_max) + return NULL; + + if (!fyt->comment) { + if (!alloc) + return NULL; + + size = sizeof(*fyt->comment) * fycp_max; + fyt->comment = malloc(size); + if (!fyt->comment) + return NULL; + memset(fyt->comment, 0, size); + } + handle = &fyt->comment[placement]; + + return handle; +} + +bool fy_token_has_any_comment(struct fy_token *fyt) +{ + struct fy_atom *handle; + enum fy_comment_placement placement; + + if (!fyt || !fyt->comment) + return false; + + for (placement = fycp_top; placement <= fycp_bottom; placement++) { + handle = &fyt->comment[placement]; + if (fy_atom_is_set(handle)) + return true; + } + return false; +} diff --git a/src/lib/fy-token.h b/src/lib/fy-token.h new file mode 100644 index 0000000..3281204 --- /dev/null +++ b/src/lib/fy-token.h @@ -0,0 +1,464 @@ +/* + * fy-token.h - YAML token methods header + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_TOKEN_H +#define FY_TOKEN_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include "fy-atom.h" + +extern const char *fy_token_type_txt[FYTT_COUNT]; + +struct fy_document; +struct fy_path_expr; + +static inline bool fy_token_type_is_sequence_start(enum fy_token_type type) +{ + return type == FYTT_BLOCK_SEQUENCE_START || type == FYTT_FLOW_SEQUENCE_START; +} + +static inline bool fy_token_type_is_sequence_end(enum fy_token_type type) +{ + return type == FYTT_BLOCK_SEQUENCE_START || type == FYTT_FLOW_SEQUENCE_START; +} + +static inline bool fy_token_type_is_sequence_marker(enum fy_token_type type) +{ + return fy_token_type_is_sequence_start(type) || fy_token_type_is_sequence_end(type); +} + +static inline bool fy_token_type_is_mapping_start(enum fy_token_type type) +{ + return type == FYTT_BLOCK_MAPPING_START || type == FYTT_FLOW_MAPPING_START; +} + +static inline bool fy_token_type_is_mapping_end(enum fy_token_type type) +{ + return type == FYTT_BLOCK_MAPPING_START || type == FYTT_FLOW_MAPPING_START; +} + +static inline bool fy_token_type_is_mapping_marker(enum fy_token_type type) +{ + return fy_token_type_is_mapping_start(type) || fy_token_type_is_mapping_end(type); +} + +/* analyze content flags */ +#define FYACF_EMPTY 0x000001 /* is empty (only ws & lb) */ +#define FYACF_LB 0x000002 /* has a linebreak */ +#define FYACF_BLOCK_PLAIN 0x000004 /* can be a plain scalar in block context */ +#define FYACF_FLOW_PLAIN 0x000008 /* can be a plain scalar in flow context */ +#define FYACF_PRINTABLE 0x000010 /* every character is printable */ +#define FYACF_SINGLE_QUOTED 0x000020 /* can be a single quoted scalar */ +#define FYACF_DOUBLE_QUOTED 0x000040 /* can be a double quoted scalar */ +#define FYACF_CONTAINS_ZERO 0x000080 /* contains a zero */ +#define FYACF_DOC_IND 0x000100 /* contains document indicators */ +#define FYACF_CONSECUTIVE_LB 0x000200 /* has consecutive linebreaks */ +#define FYACF_SIMPLE_KEY 0x000400 /* can be a simple key */ +#define FYACF_WS 0x000800 /* has at least one whitespace */ +#define FYACF_STARTS_WITH_WS 0x001000 /* starts with whitespace */ +#define FYACF_STARTS_WITH_LB 0x002000 /* starts with whitespace */ +#define FYACF_ENDS_WITH_WS 0x004000 /* ends with whitespace */ +#define FYACF_ENDS_WITH_LB 0x008000 /* ends with linebreak */ +#define FYACF_TRAILING_LB 0x010000 /* ends with trailing lb > 1 */ +#define FYACF_SIZE0 0x020000 /* contains absolutely nothing */ +#define FYACF_VALID_ANCHOR 0x040000 /* contains valid anchor (without & prefix) */ +#define FYACF_JSON_ESCAPE 0x080000 /* contains a character that JSON escapes */ + +FY_TYPE_FWD_DECL_LIST(token); +struct fy_token { + struct list_head node; + enum fy_token_type type; + int refs; /* when on document, we switch to reference counting */ + int analyze_flags; /* cache of the analysis flags */ + size_t text_len; + const char *text; + char *text0; /* this is allocated */ + struct fy_atom handle; + struct fy_atom *comment; /* only when enabled */ + union { + struct { + unsigned int tag_length; /* from start */ + unsigned int uri_length; /* from end */ + char *prefix0; + char *handle0; + struct fy_tag tag; + bool is_default; /* true when default */ + } tag_directive; + struct { + enum fy_scalar_style style; + /* path key (if requested only) */ + const char *path_key; + size_t path_key_len; + char *path_key_storage; /* if this is not null, it's \0 terminated */ + } scalar; + struct { + unsigned int skip; + unsigned int handle_length; + unsigned int suffix_length; + struct fy_token *fyt_td; + char *handle0; /* zero terminated and allocated, only used by binding */ + char *suffix0; + struct fy_tag tag; /* prefix is now suffix */ + } tag; + struct { + struct fy_version vers; /* parsed version number */ + } version_directive; + /* path expressions */ + struct { + struct fy_document *fyd; /* when key is complex */ + } map_key; + struct { + int index; + } seq_index; + struct { + int start_index; + int end_index; + } seq_slice; + struct { + struct fy_path_expr *expr; + } alias; + struct { + int flow_level; + } key; + }; +}; +FY_TYPE_DECL_LIST(token); + +static inline bool fy_token_text_is_direct(struct fy_token *fyt) +{ + if (!fyt || !fyt->text) + return false; + 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 +fy_token_unref_rl(struct fy_token_list *fytl, struct fy_token *fyt) +{ + if (!fyt) + return; + + assert(fyt->refs > 0); + + if (--fyt->refs == 0) + fy_token_free_rl(fytl, fyt); +} + +static inline struct fy_token * +fy_token_alloc(void) +{ + return fy_token_alloc_rl(NULL); +} + +static inline void +fy_token_clean(struct fy_token *fyt) +{ + return fy_token_clean_rl(NULL, fyt); +} + +static inline void +fy_token_free(struct fy_token *fyt) +{ + return fy_token_free_rl(NULL, fyt); +} + +static inline struct fy_token * +fy_token_ref(struct fy_token *fyt) +{ + /* take care of overflow */ + if (!fyt) + return NULL; + assert(fyt->refs + 1 > 0); + fyt->refs++; + + return fyt; +} + +static inline void +fy_token_unref(struct fy_token *fyt) +{ + return fy_token_unref_rl(NULL, fyt); +} + +static inline void +fy_token_list_unref_all(struct fy_token_list *fytl_tofree) +{ + return fy_token_list_unref_all_rl(NULL, fytl_tofree); +} + +/* recycling aware */ +struct fy_token *fy_token_vcreate_rl(struct fy_token_list *fytl, enum fy_token_type type, va_list ap); +struct fy_token *fy_token_create_rl(struct fy_token_list *fytl, enum fy_token_type type, ...); + +struct fy_token *fy_token_vcreate(enum fy_token_type type, va_list ap); +struct fy_token *fy_token_create(enum fy_token_type type, ...); + +static inline struct fy_token * +fy_token_list_vqueue(struct fy_token_list *fytl, enum fy_token_type type, va_list ap) +{ + struct fy_token *fyt; + + fyt = fy_token_vcreate(type, ap); + if (!fyt) + return NULL; + fy_token_list_add_tail(fytl, fyt); + return fyt; +} + +static inline struct fy_token * +fy_token_list_queue(struct fy_token_list *fytl, enum fy_token_type type, ...) +{ + va_list ap; + struct fy_token *fyt; + + va_start(ap, type); + fyt = fy_token_list_vqueue(fytl, type, ap); + va_end(ap); + + return fyt; +} + +int fy_tag_token_format_text_length(const struct fy_token *fyt); +const char *fy_tag_token_format_text(const struct fy_token *fyt, char *buf, size_t maxsz); +int fy_token_format_utf8_length(struct fy_token *fyt); + +int fy_token_format_text_length(struct fy_token *fyt); +const char *fy_token_format_text(struct fy_token *fyt, char *buf, size_t maxsz); + +/* non-parser token methods */ +struct fy_atom *fy_token_atom(struct fy_token *fyt); + +static inline size_t fy_token_start_pos(struct fy_token *fyt) +{ + const struct fy_mark *start_mark; + + if (!fyt) + return (size_t)-1; + + start_mark = fy_token_start_mark(fyt); + return start_mark ? start_mark->input_pos : (size_t)-1; +} + +static inline size_t fy_token_end_pos(struct fy_token *fyt) +{ + const struct fy_mark *end_mark; + + if (!fyt) + return (size_t)-1; + + end_mark = fy_token_end_mark(fyt); + return end_mark ? end_mark->input_pos : (size_t)-1; +} + +static inline int fy_token_start_line(struct fy_token *fyt) +{ + const struct fy_mark *start_mark; + + if (!fyt) + return -1; + + start_mark = fy_token_start_mark(fyt); + return start_mark ? start_mark->line : -1; +} + +static inline int fy_token_start_column(struct fy_token *fyt) +{ + const struct fy_mark *start_mark; + + if (!fyt) + return -1; + + start_mark = fy_token_start_mark(fyt); + return start_mark ? start_mark->column : -1; +} + +static inline int fy_token_end_line(struct fy_token *fyt) +{ + const struct fy_mark *end_mark; + + if (!fyt) + return -1; + + end_mark = fy_token_end_mark(fyt); + return end_mark ? end_mark->line : -1; +} + +static inline int fy_token_end_column(struct fy_token *fyt) +{ + const struct fy_mark *end_mark; + + if (!fyt) + return -1; + + end_mark = fy_token_end_mark(fyt); + return end_mark ? end_mark->column : -1; +} + +static inline bool fy_token_is_multiline(struct fy_token *fyt) +{ + const struct fy_mark *start_mark, *end_mark; + + if (!fyt) + return false; + + start_mark = fy_token_start_mark(fyt); + end_mark = fy_token_end_mark(fyt); + return start_mark && end_mark ? end_mark->line > start_mark->line : false; +} + +const char *fy_token_get_direct_output(struct fy_token *fyt, size_t *sizep); + +static inline struct fy_input *fy_token_get_input(struct fy_token *fyt) +{ + return fyt ? fyt->handle.fyi : NULL; +} + +static inline enum fy_atom_style fy_token_atom_style(struct fy_token *fyt) +{ + if (!fyt) + return FYAS_PLAIN; + + if (fyt->type == FYTT_TAG) + return FYAS_URI; + + return fyt->handle.style; +} + +static inline bool fy_token_atom_json_mode(struct fy_token *fyt) +{ + if (!fyt) + return false; + + return fy_atom_json_mode(&fyt->handle); +} + +static inline enum fy_lb_mode fy_token_atom_lb_mode(struct fy_token *fyt) +{ + if (!fyt) + return fylb_cr_nl; + + return fy_atom_lb_mode(&fyt->handle); +} + +static inline enum fy_flow_ws_mode fy_token_atom_flow_ws_mode(struct fy_token *fyt) +{ + if (!fyt) + return fyfws_space_tab; + + return fy_atom_flow_ws_mode(&fyt->handle); +} + +static inline bool fy_token_is_lb(struct fy_token *fyt, int c) +{ + if (!fyt) + return false; + + return fy_atom_is_lb(&fyt->handle, c); +} + +static inline bool fy_token_is_flow_ws(struct fy_token *fyt, int c) +{ + if (!fyt) + return false; + + return fy_atom_is_flow_ws(&fyt->handle, c); +} + +#define FYTTAF_HAS_LB FY_BIT(0) +#define FYTTAF_HAS_WS FY_BIT(1) +#define FYTTAF_HAS_CONSECUTIVE_LB FY_BIT(2) +#define FYTTAF_HAS_CONSECUTIVE_WS FY_BIT(4) +#define FYTTAF_EMPTY FY_BIT(5) +#define FYTTAF_CAN_BE_SIMPLE_KEY FY_BIT(6) +#define FYTTAF_DIRECT_OUTPUT FY_BIT(7) +#define FYTTAF_NO_TEXT_TOKEN FY_BIT(8) +#define FYTTAF_TEXT_TOKEN FY_BIT(9) +#define FYTTAF_CAN_BE_PLAIN FY_BIT(10) +#define FYTTAF_CAN_BE_SINGLE_QUOTED FY_BIT(11) +#define FYTTAF_CAN_BE_DOUBLE_QUOTED FY_BIT(12) +#define FYTTAF_CAN_BE_LITERAL FY_BIT(13) +#define FYTTAF_CAN_BE_FOLDED FY_BIT(14) +#define FYTTAF_CAN_BE_PLAIN_FLOW FY_BIT(15) +#define FYTTAF_QUOTE_AT_0 FY_BIT(16) +#define FYTTAF_CAN_BE_UNQUOTED_PATH_KEY FY_BIT(17) + +int fy_token_text_analyze(struct fy_token *fyt); + +unsigned int fy_analyze_scalar_content(const char *data, size_t size, + bool json_mode, enum fy_lb_mode lb_mode, enum fy_flow_ws_mode fws_mode); + +/* must be freed */ +char *fy_token_debug_text(struct fy_token *fyt); + +#define fy_token_debug_text_a(_fyt) \ + ({ \ + struct fy_token *__fyt = (_fyt); \ + char *_buf, *_rbuf = ""; \ + size_t _len; \ + _buf = fy_token_debug_text(__fyt); \ + if (_buf) { \ + _len = strlen(_buf); \ + _rbuf = alloca(_len + 1); \ + memcpy(_rbuf, _buf, _len + 1); \ + free(_buf); \ + } \ + _rbuf; \ + }) + +int fy_token_memcmp(struct fy_token *fyt, const void *ptr, size_t len); +int fy_token_strcmp(struct fy_token *fyt, const char *str); +int fy_token_cmp(struct fy_token *fyt1, struct fy_token *fyt2); + +struct fy_token_iter { + struct fy_token *fyt; + struct fy_iter_chunk ic; /* direct mode */ + struct fy_atom_iter atom_iter; + int unget_c; +}; + +void fy_token_iter_start(struct fy_token *fyt, struct fy_token_iter *iter); +void fy_token_iter_finish(struct fy_token_iter *iter); + +const char *fy_tag_token_get_directive_handle(struct fy_token *fyt, size_t *td_handle_sizep); +const char *fy_tag_token_get_directive_prefix(struct fy_token *fyt, size_t *td_prefix_sizep); + +static inline bool fy_token_is_number(struct fy_token *fyt) +{ + struct fy_atom *atom; + + if (!fyt || fyt->type != FYTT_SCALAR || fyt->scalar.style != FYSS_PLAIN) + return false; + atom = fy_token_atom(fyt); + if (!atom) + return false; + return fy_atom_is_number(atom); +} + +struct fy_atom *fy_token_comment_handle(struct fy_token *fyt, enum fy_comment_placement placement, bool alloc); +bool fy_token_has_any_comment(struct fy_token *fyt); + +const char *fy_token_get_scalar_path_key(struct fy_token *fyt, size_t *lenp); +size_t fy_token_get_scalar_path_key_length(struct fy_token *fyt); +const char *fy_token_get_scalar_path_key0(struct fy_token *fyt); + +struct fy_atom *fy_token_comment_handle(struct fy_token *fyt, enum fy_comment_placement placement, bool alloc); + +#endif diff --git a/src/lib/fy-typelist.h b/src/lib/fy-typelist.h new file mode 100644 index 0000000..7fd9148 --- /dev/null +++ b/src/lib/fy-typelist.h @@ -0,0 +1,163 @@ +/* + * fy-typelist.h - typed list method builders + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_TYPELIST_H +#define FY_TYPELIST_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-list.h" + +/* declare type methods */ + +#define FY_TYPE_FWD_DECL_LIST(_type) \ +/* type safe list wrapper */ \ +struct fy_ ## _type ## _list { struct list_head _lh; }; \ +\ +struct __useless_struct_to_allow_semicolon + +#define FY_TYPE_DECL_LIST(_type) \ +static inline void fy_ ## _type ## _list_init(struct fy_ ## _type ## _list *_l) \ +{ \ + INIT_LIST_HEAD(&_l->_lh); \ +} \ +static inline void fy_ ## _type ## _list_add(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (_l && _n) \ + list_add(&_n->node, &_l->_lh); \ +} \ +static inline void fy_ ## _type ## _list_add_tail(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (_l && _n) \ + list_add_tail(&_n->node, &_l->_lh); \ +} \ +static inline void fy_ ## _type ## _list_push(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (_l && _n) \ + fy_ ## _type ## _list_add(_l, _n); \ +} \ +static inline void fy_ ## _type ## _list_push_tail(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (_l && _n) \ + fy_ ## _type ## _list_add_tail(_l, _n); \ +} \ +static inline bool fy_ ## _type ## _list_empty(struct fy_ ## _type ## _list *_l) \ +{ \ + return _l ? list_empty(&_l->_lh) : true; \ +} \ +static inline bool fy_ ## _type ## _list_is_singular(struct fy_ ## _type ## _list *_l) \ +{ \ + return _l ? list_is_singular(&_l->_lh) : true; \ +} \ +static inline void fy_ ## _type ## _list_del(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (_l && _n) { \ + list_del(&_n->node); \ + INIT_LIST_HEAD(&_n->node); \ + } \ +} \ +static inline void fy_ ## _type ## _list_insert_after(struct fy_ ## _type ## _list *_l, \ + struct fy_ ## _type *_p, struct fy_ ## _type *_n) \ +{ \ + if (_l && _p && _n) \ + list_add(&_n->node, &_p->node); \ +} \ +static inline void fy_ ## _type ## _list_insert_before(struct fy_ ## _type ## _list *_l, \ + struct fy_ ## _type *_p, struct fy_ ## _type *_n) \ +{ \ + if (_l && _p && _n) \ + list_add_tail(&_n->node, &_p->node); \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _list_head(struct fy_ ## _type ## _list *_l) \ +{ \ + return !fy_ ## _type ## _list_empty(_l) ? list_first_entry(&_l->_lh, struct fy_ ## _type, node) : NULL; \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _list_tail(struct fy_ ## _type ## _list *_l) \ +{ \ + return !fy_ ## _type ## _list_empty(_l) ? list_last_entry(&_l->_lh, struct fy_ ## _type, node) : NULL; \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _list_first(struct fy_ ## _type ## _list *_l) \ +{ \ + return fy_ ## _type ## _list_head(_l); \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _list_last(struct fy_ ## _type ## _list *_l) \ +{ \ + return fy_ ## _type ## _list_tail(_l); \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _list_pop(struct fy_ ## _type ## _list *_l) \ +{ \ + struct fy_ ## _type *_n; \ + \ + _n = fy_ ## _type ## _list_head(_l); \ + if (!_n) \ + return NULL; \ + fy_ ## _type ## _list_del(_l, _n); \ + return _n; \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _list_pop_tail(struct fy_ ## _type ## _list *_l) \ +{ \ + struct fy_ ## _type *_n; \ + \ + _n = fy_ ## _type ## _list_tail(_l); \ + if (!_n) \ + return NULL; \ + fy_ ## _type ## _list_del(_l, _n); \ + return _n; \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _next(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (!_n || !_l || _n->node.next == &_l->_lh) \ + return NULL; \ + return list_entry(_n->node.next, struct fy_ ## _type, node); \ +} \ +static inline struct fy_ ## _type *fy_ ## _type ## _prev(struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n) \ +{ \ + if (!_n || !_l || _n->node.prev == &_l->_lh) \ + return NULL; \ + return list_entry(_n->node.prev, struct fy_ ## _type, node); \ +} \ +static inline void fy_ ## _type ## _lists_splice( \ + struct fy_ ## _type ## _list *_l, \ + struct fy_ ## _type ## _list *_lfrom) \ +{ \ + /* check arguments for sanity and lists are not empty */ \ + if (!_l || !_lfrom || \ + fy_ ## _type ## _list_empty(_lfrom)) \ + return; \ + list_splice(&_lfrom->_lh, &_l->_lh); \ +} \ +static inline void fy_ ## _type ## _list_splice_after( \ + struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n, \ + struct fy_ ## _type ## _list *_lfrom) \ +{ \ + /* check arguments for sanity and lists are not empty */ \ + if (!_l || !_n || !_lfrom || \ + fy_ ## _type ## _list_empty(_lfrom)) \ + return; \ + list_splice(&_lfrom->_lh, &_n->node); \ +} \ +static inline void fy_ ## _type ## _list_splice_before( \ + struct fy_ ## _type ## _list *_l, struct fy_ ## _type *_n, \ + struct fy_ ## _type ## _list *_lfrom) \ +{ \ + /* check arguments for sanity and lists are not empty */ \ + if (!_l || !_n || !_lfrom || \ + fy_ ## _type ## _list_empty(_lfrom)) \ + return; \ + list_splice(&_lfrom->_lh, _n->node.prev); \ +} \ +struct __useless_struct_to_allow_semicolon + +#endif diff --git a/src/lib/fy-types.c b/src/lib/fy-types.c new file mode 100644 index 0000000..fd34fab --- /dev/null +++ b/src/lib/fy-types.c @@ -0,0 +1,33 @@ +/* + * fy-types.c - types definition + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" + +/* parse only types */ +FY_PARSE_TYPE_DEFINE_SIMPLE(indent); +FY_PARSE_TYPE_DEFINE_SIMPLE(simple_key); +FY_PARSE_TYPE_DEFINE_SIMPLE(parse_state_log); +FY_PARSE_TYPE_DEFINE_SIMPLE(flow); diff --git a/src/lib/fy-types.h b/src/lib/fy-types.h new file mode 100644 index 0000000..6bddda3 --- /dev/null +++ b/src/lib/fy-types.h @@ -0,0 +1,143 @@ +/* + * fy-types.h - common types builder + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_TYPES_H +#define FY_TYPES_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-list.h" + +struct fy_parser; + +/* define type methods */ +#define FY_ALLOC_TYPE_DEFINE(_type) \ +\ +struct fy_ ## _type *fy_ ## _type ## _alloc_simple_internal( \ + struct fy_ ## _type ## _list *_rl) \ +{ \ + struct fy_ ## _type *_n; \ + \ + _n = fy_ ## _type ## _list_pop(_rl); \ + if (_n) \ + return _n; \ + _n = malloc(sizeof(*_n)); \ + if (_n) \ + INIT_LIST_HEAD(&_n->node); \ + return _n; \ +} \ +\ +void fy_ ## _type ## _recycle_internal(struct fy_ ## _type ## _list *_rl, \ + struct fy_ ## _type *_n) \ +{ \ + if (_n) \ + fy_ ## _type ## _list_push(_rl, _n); \ +} \ +\ +void fy_ ## _type ## _vacuum_internal(struct fy_ ## _type ## _list *_rl) \ +{ \ + struct fy_ ## _type *_n; \ + \ + while ((_n = fy_ ## _type ## _list_pop(_rl)) != NULL) \ + free(_n); \ +} \ +\ +struct __useless_struct_to_allow_semicolon + +/* declarations for alloc */ + +#define FY_ALLOC_TYPE_ALLOC(_type) \ +struct fy_ ## _type *fy_ ## _type ## _alloc_simple_internal( \ + struct fy_ ## _type ## _list *_rl); \ +void fy_ ## _type ## _recycle_internal(struct fy_ ## _type ## _list *_rl, \ + struct fy_ ## _type *_n); \ +void fy_ ## _type ## _vacuum_internal(struct fy_ ## _type ## _list *_rl); \ +struct __useless_struct_to_allow_semicolon + +/* parser type methods */ +#define FY_PARSE_TYPE_DECL_ALLOC(_type) \ +\ +struct fy_ ## _type *fy_parse_ ## _type ## _alloc(struct fy_parser *fyp); \ +void fy_parse_ ## _type ## _vacuum(struct fy_parser *fyp); \ +void fy_parse_ ## _type ## _recycle(struct fy_parser *fyp, struct fy_ ## _type *_n); \ +void fy_parse_ ## _type ## _list_recycle_all(struct fy_parser *fyp, struct fy_ ## _type ## _list *_l); \ +\ +struct __useless_struct_to_allow_semicolon + +#define FY_PARSE_TYPE_DECL(_type) \ +FY_TYPE_FWD_DECL_LIST(_type); \ +FY_TYPE_DECL_LIST(_type); \ +FY_PARSE_TYPE_DECL_ALLOC(_type); \ +struct __useless_struct_to_allow_semicolon + +#define FY_PARSE_TYPE_DECL_AFTER_FWD(_type) \ +FY_TYPE_DECL_LIST(_type); \ +FY_PARSE_TYPE_DECL_ALLOC(_type); \ +struct __useless_struct_to_allow_semicolon + +/* define type methods */ +#define FY_PARSE_TYPE_DEFINE(_type) \ +\ +struct fy_ ## _type *fy_parse_ ## _type ## _alloc_simple(struct fy_parser *fyp) \ +{ \ + return fy_ ## _type ## _alloc_simple_internal(&fyp->recycled_ ## _type); \ +} \ +\ +void fy_parse_ ## _type ## _vacuum(struct fy_parser *fyp) \ +{ \ + fy_ ## _type ## _vacuum_internal(&fyp->recycled_ ## _type); \ +} \ +\ +void fy_parse_ ## _type ## _list_recycle_all(struct fy_parser *fyp, struct fy_ ## _type ## _list *_l) \ +{ \ + struct fy_ ## _type *_n; \ + \ + while ((_n = fy_ ## _type ## _list_pop(_l)) != NULL) \ + fy_parse_ ## _type ## _recycle(fyp, _n); \ +} \ +\ +void fy_parse_ ## _type ## _recycle_simple(struct fy_parser *fyp, struct fy_ ## _type *_n) \ +{ \ + if (!fyp->suppress_recycling) \ + fy_ ## _type ## _recycle_internal(&fyp->recycled_ ## _type, _n); \ + else \ + free(_n); \ +} \ +\ +struct __useless_struct_to_allow_semicolon + +#define FY_PARSE_TYPE_DEFINE_ALLOC_SIMPLE(_type) \ +struct fy_ ## _type *fy_parse_ ## _type ## _alloc(struct fy_parser *_fyp) \ +{ \ + return fy_parse_ ## _type ## _alloc_simple(_fyp); \ +} \ +\ +void fy_parse_ ## _type ## _recycle(struct fy_parser *_fyp, struct fy_ ## _type *_n) \ +{ \ + if (_n) \ + fy_parse_ ## _type ## _recycle_simple(_fyp, _n); \ +} \ +\ +struct __useless_struct_to_allow_semicolon + +#define FY_PARSE_TYPE_DEFINE_SIMPLE(_type) \ +\ +FY_ALLOC_TYPE_DEFINE(_type); \ +FY_PARSE_TYPE_DEFINE(_type); \ +FY_PARSE_TYPE_DEFINE_ALLOC_SIMPLE(_type); \ +\ +struct __useless_struct_to_allow_semicolon + +#endif diff --git a/src/lib/fy-utf8.c b/src/lib/fy-utf8.c new file mode 100644 index 0000000..8cb5b07 --- /dev/null +++ b/src/lib/fy-utf8.c @@ -0,0 +1,540 @@ +/* + * fy-utf8.c - utf8 handling methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-utf8.h" + +int fy_utf8_get_generic(const void *ptr, int left, int *widthp) +{ + const uint8_t *p = ptr; + int i, width, value; + + if (left < 1) + return FYUG_EOF; + + /* this is the slow path */ + width = fy_utf8_width_by_first_octet(p[0]); + if (!width) + return FYUG_INV; + if (width > left) + return FYUG_PARTIAL; + + /* initial value */ + value = *p++ & (0x7f >> width); + for (i = 1; i < width; i++) { + if ((*p & 0xc0) != 0x80) + return FYUG_INV; + value = (value << 6) | (*p++ & 0x3f); + } + + /* check for validity */ + if ((width == 4 && value < 0x10000) || + (width == 3 && value < 0x800) || + (width == 2 && value < 0x80) || + (value >= 0xd800 && value <= 0xdfff) || value >= 0x110000) + return FYUG_INV; + + *widthp = width; + + return value; +} + +int fy_utf8_get_right_generic(const void *ptr, int left, int *widthp) +{ + const uint8_t *p, *s, *e; + + if (left < 1) + return FYUG_EOF; + + s = ptr; + e = s + left; + p = e - 1; + while (p >= s && (e - p) <= 4) { + if ((*p & 0xc0) != 0x80) + return fy_utf8_get(p, e - p, widthp); + p--; + } + + return FYUG_PARTIAL; +} + +struct fy_utf8_fmt_esc_map { + const int *ch; + const int *map; +}; + +static const struct fy_utf8_fmt_esc_map esc_all = { + .ch = (const int []){ '\\', '\0', '\b', '\r', '\t', '\f', '\n', '\v', '\a', '\e', 0x85, 0xa0, 0x2028, 0x2029, -1 }, + .map = (const int []){ '\\', '0', 'b', 'r', 't', 'f', 'n', 'v', 'a', 'e', 'N', '_', 'L', 'P', 0 } +}; + +static inline int esc_map(const struct fy_utf8_fmt_esc_map *esc_map, int c) +{ + const int *ch; + int cc; + + ch = esc_map->ch; + while ((cc = *ch++) >= 0) { + if (cc == c) + return esc_map->map[(ch - esc_map->ch) - 1]; + } + return -1; +} + +static inline int fy_utf8_esc_map(int c, enum fy_utf8_escape esc) +{ + if (esc == fyue_none) + return -1; + if (esc == fyue_singlequote && c == '\'') + return '\''; + if (fy_utf8_escape_is_any_doublequote(esc) && c == '"') + return '"'; + return esc_map(&esc_all, c); +} + +int fy_utf8_format_text_length(const char *buf, size_t len, + enum fy_utf8_escape esc) +{ + int c, w, l; + const char *s, *e; + + s = buf; + e = buf + len; + l = 0; + while (s < e) { + c = fy_utf8_get(s, e - s, &w); + if (!w || c < 0) + break; + s += w; + if (fy_utf8_esc_map(c, esc)) + w = 2; + l += w; + } + return l + 1; +} + +char *fy_utf8_format_text(const char *buf, size_t len, + char *out, size_t maxsz, + enum fy_utf8_escape esc) +{ + int c, w, cc; + const char *s, *e; + char *os, *oe; + + s = buf; + e = buf + len; + os = out; + oe = out + maxsz - 1; + while (s < e) { + c = fy_utf8_get(s, e - s, &w); + if (!w || c < 0) + break; + s += w; + + if ((cc = fy_utf8_esc_map(c, esc)) > 0) { + if (os + 2 > oe) + break; + *os++ = '\\'; + *os++ = cc; + continue; + } + + if (os + w > oe) + break; + + os = fy_utf8_put_unchecked(os, c); + } + *os++ = '\0'; + return out; +} + +char *fy_utf8_format(int c, char *buf, enum fy_utf8_escape esc) +{ + int cc; + char *s; + + if (!fy_utf8_is_valid(c)) { + *buf = '\0'; + return buf; + } + + s = buf; + if ((cc = fy_utf8_esc_map(c, esc)) > 0) { + *s++ = '\\'; + *s++ = cc; + } else + s = fy_utf8_put_unchecked(s, c); + *s = '\0'; + return buf; +} + +char *fy_utf8_format_text_alloc(const char *buf, size_t len, enum fy_utf8_escape esc) +{ + int outsz; + char *out; + + outsz = fy_utf8_format_text_length(buf, len, esc); + if (outsz < 0) + return NULL; + out = malloc(outsz); + if (!out) + return NULL; + fy_utf8_format_text(buf, len, out, outsz, esc); + + return out; +} + +const void *fy_utf8_memchr_generic(const void *s, int c, size_t n) +{ + int cc, w; + const void *e; + + e = s + n; + while (s < e && (cc = fy_utf8_get(s, e - s, &w)) >= 0) { + if (c == cc) + return s; + s += w; + } + + return NULL; +} + +/* parse an escape and return utf8 value */ +int fy_utf8_parse_escape(const char **strp, size_t len, enum fy_utf8_escape esc) +{ + const char *s, *e; + char c; + int i, value, code_length, cc, w; + unsigned int hi_surrogate, lo_surrogate; + + /* why do you bother us? */ + if (esc == fyue_none) + return -1; + + if (!strp || !*strp || len < 2) + return -1; + + value = -1; + + s = *strp; + e = s + len; + + c = *s++; + + if (esc == fyue_singlequote) { + if (c != '\'') + goto out; + c = *s++; + if (c != '\'') + goto out; + + value = '\''; + goto out; + } + + /* get '\\' */ + if (c != '\\') + goto out; + + c = *s++; + + /* common YAML & JSON escapes */ + switch (c) { + case 'b': + value = '\b'; + break; + case 'f': + value = '\f'; + break; + case 'n': + value = '\n'; + break; + case 'r': + value = '\r'; + break; + case 't': + value = '\t'; + break; + case '"': + value = '"'; + break; + case '/': + value = '/'; + break; + case '\\': + value = '\\'; + break; + default: + break; + } + + if (value >= 0) + goto out; + + if (esc == fyue_doublequote || esc == fyue_doublequote_yaml_1_1) { + switch (c) { + case '0': + value = '\0'; + break; + case 'a': + value = '\a'; + break; + case '\t': + value = '\t'; + break; + case 'v': + value = '\v'; + break; + case 'e': + value = '\e'; + break; + case ' ': + value = ' '; + break; + case 'N': + value = 0x85; /* NEL */ + break; + case '_': + value = 0xa0; + break; + case 'L': + value = 0x2028; /* LS */ + break; + case 'P': /* PS 0x2029 */ + value = 0x2029; /* PS */ + break; + default: + /* weird unicode escapes */ + if ((uint8_t)c >= 0x80) { + /* in non yaml-1.1 mode we don't allow this craziness */ + if (esc == fyue_doublequote) + goto out; + + cc = fy_utf8_get(s - 1, e - (s - 1), &w); + switch (cc) { + case 0x2028: + case 0x2029: + case 0x85: + case 0xa0: + value = cc; + break; + default: + break; + } + } + break; + } + if (value >= 0) + goto out; + } + + /* finally try the unicode escapes */ + code_length = 0; + + if (esc == fyue_doublequote || esc == fyue_doublequote_yaml_1_1) { + switch (c) { + case 'x': + code_length = 2; + break; + case 'u': + code_length = 4; + break; + case 'U': + code_length = 8; + break; + default: + return -1; + } + } else if (esc == fyue_doublequote_json && c == 'u') + code_length = 4; + + if (!code_length || code_length > (e - s)) + goto out; + + value = 0; + for (i = 0; i < code_length; i++) { + c = *s++; + value <<= 4; + if (c >= '0' && c <= '9') + value |= c - '0'; + else if (c >= 'a' && c <= 'f') + value |= 10 + c - 'a'; + else if (c >= 'A' && c <= 'F') + value |= 10 + c - 'A'; + else + goto out; + } + + /* hi/lo surrogate pair */ + if (code_length == 4 && value >= 0xd800 && value <= 0xdbff && + (e - s) >= 6 && s[0] == '\\' && s[1] == 'u') { + hi_surrogate = value; + + s += 2; + + value = 0; + for (i = 0; i < code_length; i++) { + c = *s++; + value <<= 4; + if (c >= '0' && c <= '9') + value |= c - '0'; + else if (c >= 'a' && c <= 'f') + value |= 10 + c - 'a'; + else if (c >= 'A' && c <= 'F') + value |= 10 + c - 'A'; + else + return -1; + } + lo_surrogate = value; + value = 0x10000 + (hi_surrogate - 0xd800) * 0x400 + (lo_surrogate - 0xdc00); + } + +out: + *strp = s; + + return value; +} + +uint8_t fy_utf8_low_ascii_flags[0x80] = { + [0x00] = F_NON_PRINT, // NUL '\0' (null character) + [0x01] = F_NON_PRINT, // SOH (start of heading) + [0x02] = F_NON_PRINT, // STX (start of text) + [0x03] = F_NON_PRINT, // ETX (end of text) + [0x04] = F_NON_PRINT, // EOT (end of transmission) + [0x05] = F_NON_PRINT, // ENQ (enquiry) + [0x06] = F_NON_PRINT, // ACK (acknowledge) + [0x07] = F_NON_PRINT | F_QUOTE_ESC, // BEL '\a' (bell) + [0x08] = F_NON_PRINT | F_QUOTE_ESC, // BS '\b' (backspace) + [0x09] = F_NON_PRINT | F_QUOTE_ESC | F_WS, // HT '\t' (horizontal tab) + [0x0A] = F_NON_PRINT | F_QUOTE_ESC | F_LB, // LF '\n' (new line) + [0x0B] = F_NON_PRINT | F_QUOTE_ESC, // VT '\v' (vertical tab) + [0x0C] = F_NON_PRINT | F_QUOTE_ESC, // FF '\f' (form feed) + [0x0D] = F_NON_PRINT | F_QUOTE_ESC | F_LB, // CR '\r' (carriage ret) + [0x0E] = F_NON_PRINT, // SO (shift out) + [0x0F] = F_NON_PRINT, // SI (shift in) + [0x10] = F_NON_PRINT, // DLE (data link escape) + [0x11] = F_NON_PRINT, // DC1 (device control 1) + [0x12] = F_NON_PRINT, // DC2 (device control 2) + [0x13] = F_NON_PRINT, // DC3 (device control 3) + [0x14] = F_NON_PRINT, // DC4 (device control 4) + [0x15] = F_NON_PRINT, // NAK (negative ack.) + [0x16] = F_NON_PRINT, // SYN (synchronous idle) + [0x17] = F_NON_PRINT, // ETB (end of trans. blk) + [0x18] = F_NON_PRINT, // CAN (cancel) + [0x19] = F_NON_PRINT, // EM (end of medium) + [0x1A] = F_NON_PRINT, // SUB (substitute) + [0x1B] = F_NON_PRINT, // ESC (escape) + [0x1C] = F_NON_PRINT, // FS (file separator) + [0x1D] = F_NON_PRINT, // GS (group separator) + [0x1E] = F_NON_PRINT, // RS (record separator) + [0x1F] = F_NON_PRINT, // US (unit separator) + [' '] = F_WS, + ['!'] = F_PUNCT, + ['"'] = F_PUNCT, + ['#'] = F_PUNCT, + ['$'] = F_PUNCT, + ['%'] = F_PUNCT, + ['&'] = F_PUNCT, + ['\''] = F_PUNCT, + ['('] = F_PUNCT, + [')'] = F_PUNCT, + ['*'] = F_PUNCT, + ['+'] = F_PUNCT, + [','] = F_PUNCT, + ['-'] = F_PUNCT, + ['.'] = F_PUNCT, + ['/'] = F_PUNCT, + ['0'] = F_DIGIT | F_SIMPLE_SCALAR, + ['1'] = F_DIGIT | F_SIMPLE_SCALAR, + ['2'] = F_DIGIT | F_SIMPLE_SCALAR, + ['3'] = F_DIGIT | F_SIMPLE_SCALAR, + ['4'] = F_DIGIT | F_SIMPLE_SCALAR, + ['5'] = F_DIGIT | F_SIMPLE_SCALAR, + ['6'] = F_DIGIT | F_SIMPLE_SCALAR, + ['7'] = F_DIGIT | F_SIMPLE_SCALAR, + ['8'] = F_DIGIT | F_SIMPLE_SCALAR, + ['9'] = F_DIGIT | F_SIMPLE_SCALAR, + [':'] = F_PUNCT, + [';'] = F_PUNCT, + ['<'] = F_PUNCT, + ['='] = F_PUNCT, + ['>'] = F_PUNCT, + ['?'] = F_PUNCT, + ['@'] = F_PUNCT, + ['A'] = F_LETTER | F_SIMPLE_SCALAR, + ['B'] = F_LETTER | F_SIMPLE_SCALAR, + ['C'] = F_LETTER | F_SIMPLE_SCALAR, + ['D'] = F_LETTER | F_SIMPLE_SCALAR, + ['E'] = F_LETTER | F_SIMPLE_SCALAR, + ['F'] = F_LETTER | F_SIMPLE_SCALAR, + ['G'] = F_LETTER | F_SIMPLE_SCALAR, + ['H'] = F_LETTER | F_SIMPLE_SCALAR, + ['I'] = F_LETTER | F_SIMPLE_SCALAR, + ['J'] = F_LETTER | F_SIMPLE_SCALAR, + ['K'] = F_LETTER | F_SIMPLE_SCALAR, + ['L'] = F_LETTER | F_SIMPLE_SCALAR, + ['M'] = F_LETTER | F_SIMPLE_SCALAR, + ['N'] = F_LETTER | F_SIMPLE_SCALAR, + ['O'] = F_LETTER | F_SIMPLE_SCALAR, + ['P'] = F_LETTER | F_SIMPLE_SCALAR, + ['Q'] = F_LETTER | F_SIMPLE_SCALAR, + ['R'] = F_LETTER | F_SIMPLE_SCALAR, + ['S'] = F_LETTER | F_SIMPLE_SCALAR, + ['T'] = F_LETTER | F_SIMPLE_SCALAR, + ['U'] = F_LETTER | F_SIMPLE_SCALAR, + ['V'] = F_LETTER | F_SIMPLE_SCALAR, + ['W'] = F_LETTER | F_SIMPLE_SCALAR, + ['X'] = F_LETTER | F_SIMPLE_SCALAR, + ['Y'] = F_LETTER | F_SIMPLE_SCALAR, + ['Z'] = F_LETTER | F_SIMPLE_SCALAR, + ['['] = F_PUNCT, + ['\\'] = F_PUNCT, // '\\' + [']'] = F_PUNCT, + ['^'] = F_PUNCT, + ['_'] = F_PUNCT | F_SIMPLE_SCALAR, + ['`'] = F_PUNCT, + ['a'] = F_LETTER | F_SIMPLE_SCALAR, + ['b'] = F_LETTER | F_SIMPLE_SCALAR, + ['c'] = F_LETTER | F_SIMPLE_SCALAR, + ['d'] = F_LETTER | F_SIMPLE_SCALAR, + ['e'] = F_LETTER | F_SIMPLE_SCALAR, + ['f'] = F_LETTER | F_SIMPLE_SCALAR, + ['g'] = F_LETTER | F_SIMPLE_SCALAR, + ['h'] = F_LETTER | F_SIMPLE_SCALAR, + ['i'] = F_LETTER | F_SIMPLE_SCALAR, + ['j'] = F_LETTER | F_SIMPLE_SCALAR, + ['k'] = F_LETTER | F_SIMPLE_SCALAR, + ['l'] = F_LETTER | F_SIMPLE_SCALAR, + ['m'] = F_LETTER | F_SIMPLE_SCALAR, + ['n'] = F_LETTER | F_SIMPLE_SCALAR, + ['o'] = F_LETTER | F_SIMPLE_SCALAR, + ['p'] = F_LETTER | F_SIMPLE_SCALAR, + ['q'] = F_LETTER | F_SIMPLE_SCALAR, + ['r'] = F_LETTER | F_SIMPLE_SCALAR, + ['s'] = F_LETTER | F_SIMPLE_SCALAR, + ['t'] = F_LETTER | F_SIMPLE_SCALAR, + ['u'] = F_LETTER | F_SIMPLE_SCALAR, + ['v'] = F_LETTER | F_SIMPLE_SCALAR, + ['w'] = F_LETTER | F_SIMPLE_SCALAR, + ['x'] = F_LETTER | F_SIMPLE_SCALAR, + ['y'] = F_LETTER | F_SIMPLE_SCALAR, + ['z'] = F_LETTER | F_SIMPLE_SCALAR, + ['{'] = F_PUNCT, + ['|'] = F_PUNCT, + ['}'] = F_PUNCT, + ['~'] = F_PUNCT, + [0x7F] = F_NON_PRINT, // DEL +}; diff --git a/src/lib/fy-utf8.h b/src/lib/fy-utf8.h new file mode 100644 index 0000000..8f99aca --- /dev/null +++ b/src/lib/fy-utf8.h @@ -0,0 +1,219 @@ +/* + * fy-utf8.h - UTF-8 methods + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_UTF8_H +#define FY_UTF8_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +static inline int +fy_utf8_width_by_first_octet(uint8_t c) +{ + return (c & 0x80) == 0x00 ? 1 : + (c & 0xe0) == 0xc0 ? 2 : + (c & 0xf0) == 0xe0 ? 3 : + (c & 0xf8) == 0xf0 ? 4 : 0; +} + +/* assumes valid utf8 character */ +static inline size_t +fy_utf8_width(int c) +{ + return c < 0x80 ? 1 : + c < 0x800 ? 2 : + c < 0x10000 ? 3 : 4; +} + +static inline bool +fy_utf8_is_valid(int c) +{ + return c >= 0 && !((c >= 0xd800 && c <= 0xdfff) || c >= 0x110000); +} + +static inline bool +fy_utf8_is_printable_ascii(int c) +{ + return c >= 0x20 && c <= 0x7e; +} + +/* generic utf8 decoder (not inlined) */ +int fy_utf8_get_generic(const void *ptr, int left, int *widthp); + +/* -1 for end of input, -2 for invalid character, -3 for partial */ +#define FYUG_EOF -1 +#define FYUG_INV -2 +#define FYUG_PARTIAL -3 + +static inline int fy_utf8_get(const void *ptr, int left, int *widthp) +{ + const uint8_t *p = ptr; + + /* single byte (hot path) */ + if (left <= 0) { + *widthp = 0; + return FYUG_EOF; + } + + if (!(p[0] & 0x80)) { + *widthp = 1; + return p[0] & 0x7f; + } + return fy_utf8_get_generic(ptr, left, widthp); +} + +int fy_utf8_get_right_generic(const void *ptr, int left, int *widthp); + +static inline int fy_utf8_get_right(const void *ptr, int left, int *widthp) +{ + const uint8_t *p = ptr + left; + + /* single byte (hot path) */ + if (left > 0 && !(p[-1] & 0x80)) { + if (widthp) + *widthp = 1; + return p[-1] & 0x7f; + } + return fy_utf8_get_right_generic(ptr, left, widthp); +} + + +/* for when you _know_ that there's enough room and c is valid */ +static inline void *fy_utf8_put_unchecked(void *ptr, int c) +{ + uint8_t *s = ptr; + + assert(c >= 0); + if (c < 0x80) + *s++ = c; + else if (c < 0x800) { + *s++ = (c >> 6) | 0xc0; + *s++ = (c & 0x3f) | 0x80; + } else if (c < 0x10000) { + *s++ = (c >> 12) | 0xe0; + *s++ = ((c >> 6) & 0x3f) | 0x80; + *s++ = (c & 0x3f) | 0x80; + } else { + *s++ = (c >> 18) | 0xf0; + *s++ = ((c >> 12) & 0x3f) | 0x80; + *s++ = ((c >> 6) & 0x3f) | 0x80; + *s++ = (c & 0x3f) | 0x80; + } + return s; +} + +static inline void *fy_utf8_put(void *ptr, size_t left, int c) +{ + if (!fy_utf8_is_valid(c) || fy_utf8_width(c) > left) + return NULL; + + return fy_utf8_put_unchecked(ptr, c); +} + +/* buffer must contain at least 5 characters */ +#define FY_UTF8_FORMAT_BUFMIN 5 +enum fy_utf8_escape { + fyue_none, + fyue_singlequote, + fyue_doublequote, + fyue_doublequote_json, + fyue_doublequote_yaml_1_1, +}; + +static inline bool fy_utf8_escape_is_any_doublequote(enum fy_utf8_escape esc) +{ + return esc >= fyue_doublequote && esc <= fyue_doublequote_yaml_1_1; +} + +char *fy_utf8_format(int c, char *buf, enum fy_utf8_escape esc); + +#define fy_utf8_format_a(_c, _esc) \ + ({ \ + char *_buf = alloca(FY_UTF8_FORMAT_BUFMIN); \ + fy_utf8_format((_c), _buf, _esc); \ + }) + +int fy_utf8_format_text_length(const char *buf, size_t len, + enum fy_utf8_escape esc); +char *fy_utf8_format_text(const char *buf, size_t len, + char *out, size_t maxsz, + enum fy_utf8_escape esc); + +#define fy_utf8_format_text_a(_buf, _len, _esc) \ + ({ \ + const char *__buf = (_buf); \ + size_t __len = (_len); \ + enum fy_utf8_escape __esc = (_esc); \ + size_t _outsz = fy_utf8_format_text_length(__buf, __len, __esc); \ + char *_out = alloca(_outsz + 1); \ + fy_utf8_format_text(__buf, __len, _out, _outsz, __esc); \ + }) + +char *fy_utf8_format_text_alloc(const char *buf, size_t len, enum fy_utf8_escape esc); + +const void *fy_utf8_memchr_generic(const void *s, int c, size_t n); + +static inline const void *fy_utf8_memchr(const void *s, int c, size_t n) +{ + if (c < 0 || !n) + return NULL; + if (c < 0x80) + return memchr(s, c, n); + return fy_utf8_memchr_generic(s, c, n); +} + +static inline const void *fy_utf8_strchr(const void *s, int c) +{ + if (c < 0) + return NULL; + if (c < 0x80) + return strchr(s, c); + return fy_utf8_memchr_generic(s, c, strlen(s)); +} + +static inline int fy_utf8_count(const void *ptr, size_t len) +{ + const uint8_t *s = ptr, *e = ptr + len; + int w, count; + + count = 0; + while (s < e) { + w = fy_utf8_width_by_first_octet(*s); + + /* malformed? */ + if (!w || s + w > e) + break; + s += w; + + count++; + } + + return count; +} + +int fy_utf8_parse_escape(const char **strp, size_t len, enum fy_utf8_escape esc); + +#define F_NONE 0 +#define F_NON_PRINT FY_BIT(0) /* non printable */ +#define F_SIMPLE_SCALAR FY_BIT(1) /* part of simple scalar */ +#define F_QUOTE_ESC FY_BIT(2) /* escape form, i.e \n */ +#define F_LB FY_BIT(3) /* is a linebreak */ +#define F_WS FY_BIT(4) /* is a whitespace */ +#define F_PUNCT FY_BIT(5) /* is a punctuation mark */ +#define F_LETTER FY_BIT(6) /* is a letter a..z A..Z */ +#define F_DIGIT FY_BIT(7) /* is a digit 0..9 */ + +extern uint8_t fy_utf8_low_ascii_flags[0x80]; + +#endif diff --git a/src/lib/fy-utils.c b/src/lib/fy-utils.c new file mode 100644 index 0000000..3707110 --- /dev/null +++ b/src/lib/fy-utils.c @@ -0,0 +1,393 @@ +/* + * fy-utils.c - Generic utilities for functionality that's missing + * from platforms. + * + * For now only used to implement memstream for Apple platforms. + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "fy-utf8.h" +#include "fy-ctype.h" +#include "fy-utils.h" + +#if defined(__APPLE__) && (_POSIX_C_SOURCE < 200809L) + +/* + * adapted from http://piumarta.com/software/memstream/ + * + * Under the MIT license. + */ + +/* + * ---------------------------------------------------------------------------- + * + * OPEN_MEMSTREAM(3) BSD and Linux Library Functions OPEN_MEMSTREAM(3) + * + * SYNOPSIS + * #include "memstream.h" + * + * FILE *open_memstream(char **bufp, size_t *sizep); + * + * DESCRIPTION + * The open_memstream() function opens a stream for writing to a buffer. + * The buffer is dynamically allocated (as with malloc(3)), and + * automatically grows as required. After closing the stream, the caller + * should free(3) this buffer. + * + * When the stream is closed (fclose(3)) or flushed (fflush(3)), the + * locations pointed to by bufp and sizep are updated to contain, + * respectively, a pointer to the buffer and the current size of the + * buffer. These values remain valid only as long as the caller performs + * no further output on the stream. If further output is performed, then + * the stream must again be flushed before trying to access these + * variables. + * + * A null byte is maintained at the end of the buffer. This byte is not + * included in the size value stored at sizep. + * + * The stream's file position can be changed with fseek(3) or fseeko(3). + * Moving the file position past the end of the data already written fills + * the intervening space with zeros. + * + * RETURN VALUE + * Upon successful completion open_memstream() returns a FILE pointer. + * Otherwise, NULL is returned and errno is set to indicate the error. + * + * CONFORMING TO + * POSIX.1-2008 + * + * ---------------------------------------------------------------------------- + */ + +#ifndef min +#define min(X, Y) (((X) < (Y)) ? (X) : (Y)) +#endif + +struct memstream { + size_t position; + size_t size; + size_t capacity; + char *contents; + char **ptr; + size_t *sizeloc; +}; + +static int memstream_grow(struct memstream *ms, size_t minsize) +{ + size_t newcap; + char *newcontents; + + newcap = ms->capacity * 2; + while (newcap <= minsize + 1) + newcap *= 2; + newcontents = realloc(ms->contents, newcap); + if (!newcontents) + return -1; + ms->contents = newcontents; + memset(ms->contents + ms->capacity, 0, newcap - ms->capacity); + ms->capacity = newcap; + *ms->ptr = ms->contents; + return 0; +} + +static int memstream_read(void *cookie, char *buf, int count) +{ + struct memstream *ms = cookie; + size_t n; + + n = min(ms->size - ms->position, (size_t)count); + if (n < 1) + return 0; + memcpy(buf, ms->contents, n); + ms->position += n; + return n; +} + +static int memstream_write(void *cookie, const char *buf, int count) +{ + struct memstream *ms = cookie; + + if (ms->capacity <= ms->position + (size_t)count && + memstream_grow(ms, ms->position + (size_t)count) < 0) + return -1; + memcpy(ms->contents + ms->position, buf, count); + ms->position += count; + ms->contents[ms->position] = '\0'; + if (ms->size < ms->position) + *ms->sizeloc = ms->size = ms->position; + + return count; +} + +static fpos_t memstream_seek(void *cookie, fpos_t offset, int whence) +{ + struct memstream *ms = cookie; + fpos_t pos= 0; + + switch (whence) { + case SEEK_SET: + pos = offset; + break; + case SEEK_CUR: + pos = ms->position + offset; + break; + case SEEK_END: + pos = ms->size + offset; + break; + default: + errno= EINVAL; + return -1; + } + if (pos >= (fpos_t)ms->capacity && memstream_grow(ms, pos) < 0) + return -1; + ms->position = pos; + if (ms->size < ms->position) + *ms->sizeloc = ms->size = ms->position; + return pos; +} + +static int memstream_close(void *cookie) +{ + struct memstream *ms = cookie; + + ms->size = min(ms->size, ms->position); + *ms->ptr = ms->contents; + *ms->sizeloc = ms->size; + ms->contents[ms->size]= 0; + /* ms->contents is what's returned */ + free(ms); + return 0; +} + +FILE *open_memstream(char **ptr, size_t *sizeloc) +{ + struct memstream *ms; + FILE *fp; + + if (!ptr || !sizeloc) { + errno= EINVAL; + goto err_out; + } + + ms = calloc(1, sizeof(struct memstream)); + if (!ms) + goto err_out; + + ms->position = ms->size= 0; + ms->capacity = 4096; + ms->contents = calloc(ms->capacity, 1); + if (!ms->contents) + goto err_free_ms; + ms->ptr = ptr; + ms->sizeloc = sizeloc; + fp= funopen(ms, memstream_read, memstream_write, + memstream_seek, memstream_close); + if (!fp) + goto err_free_all; + *ptr = ms->contents; + *sizeloc = ms->size; + return fp; + +err_free_all: + free(ms->contents); +err_free_ms: + free(ms); +err_out: + return NULL; +} + +#endif /* __APPLE__ && _POSIX_C_SOURCE < 200809L */ + +bool fy_tag_uri_is_valid(const char *data, size_t len) +{ + const char *s, *e; + int w, j, k, width, c; + uint8_t octet, esc_octets[4]; + + s = data; + e = s + len; + + while ((c = fy_utf8_get(s, e - s, &w)) >= 0) { + if (c != '%') { + s += w; + continue; + } + + width = 0; + k = 0; + do { + /* short URI escape */ + if ((e - s) < 3) + return false; + + if (width > 0) { + c = fy_utf8_get(s, e - s, &w); + if (c != '%') + return false; + } + + s += w; + + octet = 0; + + for (j = 0; j < 2; j++) { + c = fy_utf8_get(s, e - s, &w); + if (!fy_is_hex(c)) + return false; + s += w; + + octet <<= 4; + if (c >= '0' && c <= '9') + octet |= c - '0'; + else if (c >= 'a' && c <= 'f') + octet |= 10 + c - 'a'; + else + octet |= 10 + c - 'A'; + } + if (!width) { + width = fy_utf8_width_by_first_octet(octet); + + if (width < 1 || width > 4) + return false; + k = 0; + } + esc_octets[k++] = octet; + + } while (--width > 0); + + /* now convert to utf8 */ + c = fy_utf8_get(esc_octets, k, &w); + + if (c < 0) + return false; + } + + return true; +} + +int fy_tag_handle_length(const char *data, size_t len) +{ + const char *s, *e; + int c, w; + + s = data; + e = s + len; + + c = fy_utf8_get(s, e - s, &w); + if (c != '!') + return -1; + s += w; + + c = fy_utf8_get(s, e - s, &w); + if (fy_is_ws(c)) + return s - data; + /* if first character is !, empty handle */ + if (c == '!') { + s += w; + return s - data; + } + if (!fy_is_first_alpha(c)) + return -1; + s += w; + while (fy_is_alnum(c = fy_utf8_get(s, e - s, &w))) + s += w; + if (c == '!') + s += w; + + return s - data; +} + +int fy_tag_uri_length(const char *data, size_t len) +{ + const char *s, *e; + int c, w, cn, wn, uri_length; + + s = data; + e = s + len; + + while (fy_is_uri(c = fy_utf8_get(s, e - s, &w))) { + cn = fy_utf8_get(s + w, e - (s + w), &wn); + if ((fy_is_z(cn) || fy_is_blank(cn) || fy_is_any_lb(cn)) && fy_utf8_strchr(",}]", c)) + break; + s += w; + } + uri_length = s - data; + + if (!fy_tag_uri_is_valid(data, uri_length)) + return -1; + + return uri_length; +} + +int fy_tag_scan(const char *data, size_t len, struct fy_tag_scan_info *info) +{ + const char *s, *e; + int total_length, handle_length, uri_length, prefix_length, suffix_length; + int c, cn, w, wn; + + s = data; + e = s + len; + + prefix_length = 0; + + /* it must start with '!' */ + c = fy_utf8_get(s, e - s, &w); + if (c != '!') + return -1; + cn = fy_utf8_get(s + w, e - (s + w), &wn); + if (cn == '<') { + prefix_length = 2; + suffix_length = 1; + } else + prefix_length = suffix_length = 0; + + if (prefix_length) { + handle_length = 0; /* set the handle to '' */ + s += prefix_length; + } else { + /* either !suffix or !handle!suffix */ + /* we scan back to back, and split handle/suffix */ + handle_length = fy_tag_handle_length(s, e - s); + if (handle_length <= 0) + return -1; + s += handle_length; + } + + uri_length = fy_tag_uri_length(s, e - s); + if (uri_length < 0) + return -1; + + /* a handle? */ + if (!prefix_length && (handle_length == 0 || data[handle_length - 1] != '!')) { + /* special case, '!', handle set to '' and suffix to '!' */ + if (handle_length == 1 && uri_length == 0) { + handle_length = 0; + uri_length = 1; + } else { + uri_length = handle_length - 1 + uri_length; + handle_length = 1; + } + } + total_length = prefix_length + handle_length + uri_length + suffix_length; + + if (total_length != (int)len) + return -1; + + info->total_length = total_length; + info->handle_length = handle_length; + info->uri_length = uri_length; + info->prefix_length = prefix_length; + info->suffix_length = suffix_length; + + return 0; +} diff --git a/src/lib/fy-utils.h b/src/lib/fy-utils.h new file mode 100644 index 0000000..4840550 --- /dev/null +++ b/src/lib/fy-utils.h @@ -0,0 +1,41 @@ +/* + * fy-utils.h - internal utilities header file + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifndef FY_UTILS_H +#define FY_UTILS_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#if defined(__APPLE__) && (_POSIX_C_SOURCE < 200809L) +FILE *open_memstream(char **ptr, size_t *sizeloc); +#endif + +int fy_tag_handle_length(const char *data, size_t len); +bool fy_tag_uri_is_valid(const char *data, size_t len); +int fy_tag_uri_length(const char *data, size_t len); + +struct fy_tag_scan_info { + int total_length; + int handle_length; + int uri_length; + int prefix_length; + int suffix_length; +}; + +int fy_tag_scan(const char *data, size_t len, struct fy_tag_scan_info *info); + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) ((sizeof(x)/sizeof((x)[0]))) +#endif + +#endif diff --git a/src/lib/fy-walk.c b/src/lib/fy-walk.c new file mode 100644 index 0000000..ad108f1 --- /dev/null +++ b/src/lib/fy-walk.c @@ -0,0 +1,5228 @@ +/* + * fy-walk.c - path walker + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-parse.h" +#include "fy-doc.h" +#include "fy-walk.h" + +#include "fy-utils.h" + +#undef DEBUG_EXPR +// #define DEBUG_EXPR + +const char *fy_walk_result_type_txt[FWRT_COUNT] = { + [fwrt_none] = "none", + [fwrt_node_ref] = "node-ref", + [fwrt_number] = "number", + [fwrt_string] = "string", + [fwrt_doc] = "doc", + [fwrt_refs] = "refs", +}; + +void fy_walk_result_dump(struct fy_walk_result *fwr, struct fy_diag *diag, enum fy_error_type errlevel, int level, + const char *fmt, ...); + +void fy_walk_result_vdump(struct fy_walk_result *fwr, struct fy_diag *diag, enum fy_error_type errlevel, int level, + const char *fmt, va_list ap) +{ + struct fy_walk_result *fwr2; + char *banner; + char *texta = NULL; + const char *text = ""; + size_t len; + bool save_on_error; + char buf[30]; + int rc __FY_DEBUG_UNUSED__; + + if (!diag) + return; + + if (errlevel < diag->cfg.level) + return; + + save_on_error = diag->on_error; + diag->on_error = true; + + if (fmt) { + banner = NULL; + rc = vasprintf(&banner, fmt, ap); + assert(rc != -1); + assert(banner); + fy_diag_diag(diag, errlevel, "%-*s%s", level*2, "", banner); + free(banner); + } + if (!fwr) + goto out; + + switch (fwr->type) { + case fwrt_none: + text=""; + break; + case fwrt_node_ref: + texta = fy_node_get_path(fwr->fyn); + assert(texta); + text = texta; + break; + case fwrt_number: + snprintf(buf, sizeof(buf), "%f", fwr->number); + text = buf; + break; + case fwrt_string: + text = fwr->string; + break; + case fwrt_doc: + texta = fy_emit_document_to_string(fwr->fyd, FYECF_WIDTH_INF | FYECF_INDENT_DEFAULT | FYECF_MODE_FLOW_ONELINE); + assert(texta); + text = texta; + break; + case fwrt_refs: + text=""; + break; + } + + len = strlen(text); + + fy_diag_diag(diag, errlevel, "%-*s%s%s%.*s", + (level + 1) * 2, "", + fy_walk_result_type_txt[fwr->type], + len ? " " : "", + (int)len, text); + + if (texta) + free(texta); + + if (fwr->type == fwrt_refs) { + for (fwr2 = fy_walk_result_list_head(&fwr->refs); fwr2; fwr2 = fy_walk_result_next(&fwr->refs, fwr2)) + fy_walk_result_dump(fwr2, diag, errlevel, level + 1, NULL); + } +out: + diag->on_error = save_on_error; +} + +void fy_walk_result_dump(struct fy_walk_result *fwr, struct fy_diag *diag, enum fy_error_type errlevel, int level, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fy_walk_result_vdump(fwr, diag, errlevel, level, fmt, ap); + va_end(ap); +} + +/* NOTE that walk results do not take references and it is invalid to + * use _any_ call that modifies the document structure + */ +struct fy_walk_result *fy_walk_result_alloc_rl(struct fy_walk_result_list *fwrl) +{ + struct fy_walk_result *fwr = NULL; + + if (fwrl) + fwr = fy_walk_result_list_pop(fwrl); + + if (!fwr) { + fwr = malloc(sizeof(*fwr)); + if (!fwr) + return NULL; + memset(fwr, 0, sizeof(*fwr)); + } + fwr->type = fwrt_none; + return fwr; +} + +struct fy_walk_result *fy_walk_result_clone_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result *fwr) +{ + struct fy_walk_result *fwrn = NULL, *fwrn2 = NULL, *fwrn3; + + if (!fwr) + return NULL; + + fwrn = fy_walk_result_alloc_rl(fwrl); + if (!fwrn) + return NULL; + + fwrn->type = fwr->type; + switch (fwr->type) { + case fwrt_none: + break; + case fwrt_node_ref: + fwrn->fyn = fwr->fyn; + break; + case fwrt_number: + fwrn->number = fwr->number; + break; + case fwrt_string: + fwrn->string = strdup(fwr->string); + if (!fwrn->string) + goto err_out; + break; + case fwrt_doc: + fwrn->fyd = fy_document_clone(fwr->fyd); + if (!fwrn->fyd) + goto err_out; + break; + case fwrt_refs: + + fy_walk_result_list_init(&fwrn->refs); + + for (fwrn2 = fy_walk_result_list_head(&fwr->refs); fwrn2; + fwrn2 = fy_walk_result_next(&fwr->refs, fwrn2)) { + + fwrn3 = fy_walk_result_clone_rl(fwrl, fwrn2); + if (!fwrn3) + goto err_out; + + fy_walk_result_list_add_tail(&fwrn->refs, fwrn3); + } + break; + } + return fwrn; +err_out: + if (fwrn) + fy_walk_result_free_rl(fwrl, fwrn); + return NULL; +} + +struct fy_walk_result *fy_walk_result_clone(struct fy_walk_result *fwr) +{ + struct fy_walk_result_list *fwrl; + + if (!fwr) + return NULL; + + fwrl = fy_path_exec_walk_result_rl(fwr->fypx); + return fy_walk_result_clone_rl(fwrl, fwr); +} + +void fy_walk_result_clean_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result *fwr) +{ + struct fy_walk_result *fwrn; + + if (!fwr) + return; + + switch (fwr->type) { + case fwrt_none: + break; + case fwrt_node_ref: + case fwrt_number: + break; + case fwrt_string: + if (fwr->string) + free(fwr->string); + break; + case fwrt_doc: + if (fwr->fyd) + fy_document_destroy(fwr->fyd); + break; + case fwrt_refs: + while ((fwrn = fy_walk_result_list_pop(&fwr->refs)) != NULL) + fy_walk_result_free_rl(fwrl, fwrn); + break; + } + + fwr->type = fwrt_none; +} + +void fy_walk_result_clean(struct fy_walk_result *fwr) +{ + struct fy_walk_result_list *fwrl; + + if (!fwr) + return; + + fwrl = fy_path_exec_walk_result_rl(fwr->fypx); + fy_walk_result_clean_rl(fwrl, fwr); +} + +void fy_walk_result_free_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result *fwr) +{ + struct fy_path_exec *fypx; + + if (!fwr) + return; + + fypx = fwr->fypx; + + fy_walk_result_clean_rl(fwrl, fwr); + + if (fwrl) + fy_walk_result_list_push(fwrl, fwr); + else + free(fwr); + + fy_path_exec_unref(fypx); /* NULL is OK */ +} + +void fy_walk_result_free(struct fy_walk_result *fwr) +{ + struct fy_walk_result_list *fwrl; + + if (!fwr) + return; + + fwrl = fy_path_exec_walk_result_rl(fwr->fypx); + fy_walk_result_free_rl(fwrl, fwr); +} + +void fy_walk_result_list_free_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result_list *results) +{ + struct fy_walk_result *fwr; + + while ((fwr = fy_walk_result_list_pop(results)) != NULL) + fy_walk_result_free_rl(fwrl, fwr); +} + +struct fy_walk_result *fy_walk_result_vcreate_rl(struct fy_walk_result_list *fwrl, enum fy_walk_result_type type, va_list ap) +{ + struct fy_walk_result *fwr = NULL; + + if ((unsigned int)type >= FWRT_COUNT) + goto err_out; + + fwr = fy_walk_result_alloc_rl(fwrl); + if (!fwr) + goto err_out; + + fwr->type = type; + + switch (fwr->type) { + case fwrt_none: + break; + case fwrt_node_ref: + fwr->fyn = va_arg(ap, struct fy_node *); + break; + case fwrt_number: + fwr->number = va_arg(ap, double); + break; + case fwrt_string: + fwr->string = strdup(va_arg(ap, const char *)); + if (!fwr->string) + goto err_out; + break; + case fwrt_doc: + fwr->fyd = va_arg(ap, struct fy_document *); + break; + case fwrt_refs: + fy_walk_result_list_init(&fwr->refs); + break; + } + + return fwr; + +err_out: + fy_walk_result_free_rl(fwrl, fwr); + + return NULL; +} + +struct fy_walk_result *fy_walk_result_create_rl(struct fy_walk_result_list *fwrl, enum fy_walk_result_type type, ...) +{ + struct fy_walk_result *fwr; + va_list ap; + + va_start(ap, type); + fwr = fy_walk_result_vcreate_rl(fwrl, type, ap); + va_end(ap); + + return fwr; +} + +void fy_walk_result_flatten_internal(struct fy_walk_result *fwr, struct fy_walk_result *fwrf) +{ + struct fy_walk_result *fwr2, *fwr2n; + + if (!fwr || !fwrf || fwr->type != fwrt_refs) + return; + + for (fwr2 = fy_walk_result_list_head(&fwr->refs); fwr2; fwr2 = fwr2n) { + + fwr2n = fy_walk_result_next(&fwr->refs, fwr2); + + if (fwr2->type != fwrt_refs) { + fy_walk_result_list_del(&fwr->refs, fwr2); + fy_walk_result_list_add_tail(&fwrf->refs, fwr2); + continue; + } + fy_walk_result_flatten_internal(fwr2, fwrf); + } +} + +bool fy_walk_result_has_leaves_only(struct fy_walk_result *fwr) +{ + struct fy_walk_result *fwrn; + + if (!fwr || fwr->type != fwrt_refs) + return false; + + if (fy_walk_result_list_empty(&fwr->refs)) + return false; + + for (fwrn = fy_walk_result_list_head(&fwr->refs); fwrn; + fwrn = fy_walk_result_next(&fwr->refs, fwrn)) { + + if (fwrn->type == fwrt_refs) + return false; + } + + return true; +} + +struct fy_walk_result * +fy_walk_result_flatten_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result *fwr) +{ + struct fy_walk_result *fwrf; + + if (!fwr) + return NULL; + + fwrf = fy_walk_result_create_rl(fwrl, fwrt_refs); + assert(fwrf); + + fy_walk_result_flatten_internal(fwr, fwrf); + fy_walk_result_free_rl(fwrl, fwr); + return fwrf; +} + +struct fy_walk_result * +fy_walk_result_flatten(struct fy_walk_result *fwr) +{ + struct fy_walk_result_list *fwrl; + + if (!fwr) + return NULL; + + fwrl = fy_path_exec_walk_result_rl(fwr->fypx); + return fy_walk_result_flatten_rl(fwrl, fwr); +} + +struct fy_node * +fy_walk_result_node_iterate(struct fy_walk_result *fwr, void **prevp) +{ + struct fy_walk_result *fwrn; + + if (!fwr || !prevp) + return NULL; + + switch (fwr->type) { + case fwrt_node_ref: + if (!*prevp) { + *prevp = fwr; + return fwr->fyn; + } + *prevp = NULL; + return NULL; + + case fwrt_refs: + if (!*prevp) + fwrn = fy_walk_result_list_head(&fwr->refs); + else + fwrn = fy_walk_result_next(&fwr->refs, *prevp); + + /* skip over any non node refs */ + while (fwrn && fwrn->type != fwrt_node_ref) + fwrn = fy_walk_result_next(&fwr->refs, fwrn); + *prevp = fwrn; + return fwrn ? fwrn->fyn : NULL; + + default: + break; + } + + return NULL; +} + +const char *fy_path_expr_type_txt[FPET_COUNT] = { + [fpet_none] = "none", + /* */ + [fpet_root] = "root", + [fpet_this] = "this", + [fpet_parent] = "parent", + [fpet_every_child] = "every-child", + [fpet_every_child_r] = "every-child-recursive", + [fpet_filter_collection] = "filter-collection", + [fpet_filter_scalar] = "filter-scalar", + [fpet_filter_sequence] = "filter-sequence", + [fpet_filter_mapping] = "filter-mapping", + [fpet_filter_unique] = "filter-unique", + [fpet_seq_index] = "seq-index", + [fpet_seq_slice] = "seq-slice", + [fpet_alias] = "alias", + + [fpet_map_key] = "map-key", + + [fpet_multi] = "multi", + [fpet_chain] = "chain", + [fpet_logical_or] = "logical-or", + [fpet_logical_and] = "logical-and", + + [fpet_eq] = "equals", + [fpet_neq] = "not-equals", + [fpet_lt] = "less-than", + [fpet_gt] = "greater-than", + [fpet_lte] = "less-or-equal-than", + [fpet_gte] = "greater-or-equal-than", + + [fpet_scalar] = "scalar", + + [fpet_plus] = "plus", + [fpet_minus] = "minus", + [fpet_mult] = "multiply", + [fpet_div] = "divide", + + [fpet_lparen] = "left-parentheses", + [fpet_rparen] = "right-parentheses", + [fpet_method] = "method", + + [fpet_scalar_expr] = "scalar-expression", + [fpet_path_expr] = "path-expression", + [fpet_arg_separator] = "argument-separator", +}; + +struct fy_path_expr *fy_path_expr_alloc(void) +{ + struct fy_path_expr *expr = NULL; + + expr = malloc(sizeof(*expr)); + if (!expr) + return NULL; + memset(expr, 0, sizeof(*expr)); + fy_path_expr_list_init(&expr->children); + + return expr; +} + +void fy_path_expr_free(struct fy_path_expr *expr) +{ + struct fy_path_expr *exprn; + + if (!expr) + return; + + while ((exprn = fy_path_expr_list_pop(&expr->children)) != NULL) + fy_path_expr_free(exprn); + + fy_token_unref(expr->fyt); + + free(expr); +} + +struct fy_path_expr *fy_path_expr_alloc_recycle(struct fy_path_parser *fypp) +{ + struct fy_path_expr *expr = NULL; + + if (!fypp || fypp->suppress_recycling) + expr = fy_path_expr_alloc(); + + if (!expr) { + expr = fy_path_expr_list_pop(&fypp->expr_recycle); + if (expr) { + memset(expr, 0, sizeof(*expr)); + fy_path_expr_list_init(&expr->children); + } else + expr = fy_path_expr_alloc(); + } + + if (!expr) + return NULL; + + expr->expr_mode = fypp->expr_mode; + + return expr; +} + +void fy_path_expr_free_recycle(struct fy_path_parser *fypp, struct fy_path_expr *expr) +{ + struct fy_path_expr *exprn; + + if (!fypp || fypp->suppress_recycling) { + fy_path_expr_free(expr); + return; + } + + while ((exprn = fy_path_expr_list_pop(&expr->children)) != NULL) + fy_path_expr_free_recycle(fypp, exprn); + + if (expr->fyt) { + fy_token_unref(expr->fyt); + expr->fyt = NULL; + } + fy_path_expr_list_add_tail(&fypp->expr_recycle, expr); +} + +void fy_expr_stack_setup(struct fy_expr_stack *stack) +{ + if (!stack) + return; + + memset(stack, 0, sizeof(*stack)); + stack->items = stack->items_static; + stack->alloc = ARRAY_SIZE(stack->items_static); +} + +void fy_expr_stack_cleanup(struct fy_expr_stack *stack) +{ + if (!stack) + return; + + while (stack->top > 0) + fy_path_expr_free(stack->items[--stack->top]); + + if (stack->items != stack->items_static) + free(stack->items); + stack->items = stack->items_static; + stack->alloc = ARRAY_SIZE(stack->items_static); +} + +void fy_expr_stack_dump(struct fy_diag *diag, struct fy_expr_stack *stack) +{ + struct fy_path_expr *expr; + unsigned int i; + + if (!stack) + return; + + if (!stack->top) + return; + + i = stack->top; + do { + expr = stack->items[--i]; + fy_path_expr_dump(expr, diag, FYET_NOTICE, 0, NULL); + } while (i > 0); +} + +int fy_expr_stack_size(struct fy_expr_stack *stack) +{ + if (!stack || stack->top >= (unsigned int)INT_MAX) + return -1; + return (int)stack->top; +} + +int fy_expr_stack_push(struct fy_expr_stack *stack, struct fy_path_expr *expr) +{ + struct fy_path_expr **items_new; + unsigned int alloc; + size_t size; + + if (!stack || !expr) + return -1; + + assert(stack->items); + assert(stack->alloc > 0); + + assert(expr->fyt); + + /* grow the stack if required */ + if (stack->top >= stack->alloc) { + alloc = stack->alloc; + size = alloc * sizeof(*items_new); + + if (stack->items == stack->items_static) { + items_new = malloc(size * 2); + if (items_new) + memcpy(items_new, stack->items_static, size); + } else + items_new = realloc(stack->items, size * 2); + + if (!items_new) + return -1; + + stack->alloc = alloc * 2; + stack->items = items_new; + } + + stack->items[stack->top++] = expr; + + return 0; +} + +struct fy_path_expr *fy_expr_stack_peek_at(struct fy_expr_stack *stack, unsigned int pos) +{ + if (!stack || stack->top <= pos) + return NULL; + return stack->items[stack->top - 1 - pos]; +} + +struct fy_path_expr *fy_expr_stack_peek(struct fy_expr_stack *stack) +{ + return fy_expr_stack_peek_at(stack, 0); +} + +struct fy_path_expr *fy_expr_stack_pop(struct fy_expr_stack *stack) +{ + if (!stack || !stack->top) + return NULL; + + return stack->items[--stack->top]; +} + +bool fy_token_type_can_be_path_expr(enum fy_token_type type) +{ + return type == FYTT_NONE || + type == FYTT_PE_LPAREN || + type == FYTT_PE_RPAREN || + type == FYTT_PE_EQEQ || + type == FYTT_PE_NOTEQ || + type == FYTT_PE_GT || + type == FYTT_PE_LT || + type == FYTT_PE_GTE || + type == FYTT_PE_LTE || + type == FYTT_PE_METHOD; +} + +bool fy_token_type_can_be_before_negative_number(enum fy_token_type type) +{ + return type == FYTT_NONE || + type == FYTT_PE_LPAREN || + type == FYTT_PE_RPAREN || + type == FYTT_PE_EQEQ || + type == FYTT_PE_NOTEQ || + type == FYTT_PE_GT || + type == FYTT_PE_LT || + type == FYTT_PE_GTE || + type == FYTT_PE_LTE || + type == FYTT_SE_PLUS || + type == FYTT_SE_MINUS || + type == FYTT_SE_MULT || + type == FYTT_SE_DIV || + + type == FYTT_SE_METHOD; +} + +const char *fy_expr_mode_txt[FYEM_COUNT] = { + [fyem_none] = "none", + [fyem_path] = "path", + [fyem_scalar] = "scalar", +}; + +static struct fy_diag *fy_path_parser_reader_get_diag(struct fy_reader *fyr) +{ + struct fy_path_parser *fypp = container_of(fyr, struct fy_path_parser, reader); + return fypp->cfg.diag; +} + +static const struct fy_reader_ops fy_path_parser_reader_ops = { + .get_diag = fy_path_parser_reader_get_diag, +}; + +void fy_path_parser_setup(struct fy_path_parser *fypp, const struct fy_path_parse_cfg *pcfg) +{ + if (!fypp) + return; + + memset(fypp, 0, sizeof(*fypp)); + if (pcfg) + fypp->cfg = *pcfg; + fy_reader_setup(&fypp->reader, &fy_path_parser_reader_ops); + fy_token_list_init(&fypp->queued_tokens); + fypp->last_queued_token_type = FYTT_NONE; + + fy_expr_stack_setup(&fypp->operators); + fy_expr_stack_setup(&fypp->operands); + + fy_path_expr_list_init(&fypp->expr_recycle); + fypp->suppress_recycling = (fypp->cfg.flags & FYPPCF_DISABLE_RECYCLING) || getenv("FY_VALGRIND"); + + fypp->expr_mode = fyem_path; + fypp->paren_nest_level = 0; +} + +void fy_path_parser_cleanup(struct fy_path_parser *fypp) +{ + struct fy_path_expr *expr; + + if (!fypp) + return; + + fy_expr_stack_cleanup(&fypp->operands); + fy_expr_stack_cleanup(&fypp->operators); + + fy_reader_cleanup(&fypp->reader); + fy_token_list_unref_all(&fypp->queued_tokens); + + while ((expr = fy_path_expr_list_pop(&fypp->expr_recycle)) != NULL) + fy_path_expr_free(expr); + + fypp->last_queued_token_type = FYTT_NONE; + fypp->stream_start_produced = false; + fypp->stream_end_produced = false; + fypp->stream_error = false; + fypp->token_activity_counter = 0; + fypp->paren_nest_level = 0; +} + +int fy_path_parser_open(struct fy_path_parser *fypp, + struct fy_input *fyi, const struct fy_reader_input_cfg *icfg) +{ + int ret; + if (!fypp) + return -1; + + ret = fy_reader_input_open(&fypp->reader, fyi, icfg); + if (ret) + return ret; + /* take a reference to the input */ + fypp->fyi = fy_input_ref(fyi); + return 0; +} + +void fy_path_parser_close(struct fy_path_parser *fypp) +{ + if (!fypp) + return; + + fy_input_unref(fypp->fyi); + + fy_reader_input_done(&fypp->reader); +} + +struct fy_token *fy_path_token_vqueue(struct fy_path_parser *fypp, enum fy_token_type type, va_list ap) +{ + struct fy_token *fyt; + + fyt = fy_token_list_vqueue(&fypp->queued_tokens, type, ap); + if (fyt) { + fypp->token_activity_counter++; + fypp->last_queued_token_type = type; + } + return fyt; +} + +struct fy_token *fy_path_token_queue(struct fy_path_parser *fypp, enum fy_token_type type, ...) +{ + va_list ap; + struct fy_token *fyt; + + va_start(ap, type); + fyt = fy_path_token_vqueue(fypp, type, ap); + va_end(ap); + + return fyt; +} + +int fy_path_fetch_seq_index_or_slice(struct fy_path_parser *fypp, int c) +{ + struct fy_reader *fyr; + struct fy_token *fyt; + bool neg; + int i, j, val, nval, digits, indices[2]; + + fyr = &fypp->reader; + + /* verify that the called context is correct */ + assert(fy_is_num(c) || (c == '-' && fy_is_num(fy_reader_peek_at(fyr, 1)))); + + i = 0; + indices[0] = indices[1] = -1; + + j = 0; + while (j < 2) { + + neg = false; + if (c == '-') { + neg = true; + i++; + } + + digits = 0; + val = 0; + while (fy_is_num((c = fy_reader_peek_at(fyr, i)))) { + nval = (val * 10) | (c - '0'); + FYR_PARSE_ERROR_CHECK(fyr, 0, i, FYEM_SCAN, + nval >= val && nval >= 0, err_out, + "illegal sequence index (overflow)"); + val = nval; + i++; + digits++; + } + FYR_PARSE_ERROR_CHECK(fyr, 0, i, FYEM_SCAN, + (val == 0 && digits == 1) || (val > 0), err_out, + "bad number"); + if (neg) + val = -val; + + indices[j] = val; + + /* continue only on slice : */ + if (c == ':') { + c = fy_reader_peek_at(fyr, i + 1); + if (fy_is_num(c) || (c == '-' && fy_is_num(fy_reader_peek_at(fyr, i + 2)))) { + i++; + j++; + continue; + } + } + + break; + } + + if (j >= 1) + fyt = fy_path_token_queue(fypp, FYTT_PE_SEQ_SLICE, fy_reader_fill_atom_a(fyr, i), indices[0], indices[1]); + else + fyt = fy_path_token_queue(fypp, FYTT_PE_SEQ_INDEX, fy_reader_fill_atom_a(fyr, i), indices[0]); + + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + +err_out: + fypp->stream_error = true; + return -1; +} + +int fy_path_fetch_plain_or_method(struct fy_path_parser *fypp, int c, + enum fy_token_type fytt_plain, + enum fy_token_type fytt_method) +{ + struct fy_reader *fyr; + struct fy_token *fyt; + struct fy_atom *handlep; + int i; + enum fy_token_type type; + + fyr = &fypp->reader; + + assert(fy_is_first_alpha(c)); + + type = fytt_plain; + + i = 1; + while (fy_is_alnum(fy_reader_peek_at(fyr, i))) + i++; + + if (fy_reader_peek_at(fyr, i) == '(') + type = fytt_method; + + handlep = fy_reader_fill_atom_a(fyr, i); + if (type == FYTT_SCALAR) { + fyt = fy_path_token_queue(fypp, FYTT_SCALAR, handlep, FYSS_PLAIN, NULL); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + } else { + fyt = fy_path_token_queue(fypp, type, handlep, NULL); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + } + + return 0; + +err_out: + fypp->stream_error = true; + return -1; +} + +int fy_path_fetch_dot_method(struct fy_path_parser *fypp, int c, enum fy_token_type fytt) +{ + struct fy_reader *fyr; + struct fy_token *fyt; + struct fy_atom *handlep; + int i; + + fyr = &fypp->reader; + + assert(c == '.'); + fy_reader_advance(fyr, c); + c = fy_reader_peek(fyr); + assert(fy_is_first_alpha(c)); + + /* verify that the called context is correct */ + i = 1; + while (fy_is_alnum(fy_reader_peek_at(fyr, i))) + i++; + + handlep = fy_reader_fill_atom_a(fyr, i); + + fyt = fy_path_token_queue(fypp, fytt, handlep, NULL); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + +err_out: + fypp->stream_error = true; + return -1; +} + +int fy_path_fetch_flow_document(struct fy_path_parser *fypp, int c, enum fy_token_type fytt) +{ + struct fy_reader *fyr; + struct fy_token *fyt; + struct fy_document *fyd; + struct fy_atom handle; + struct fy_parser fyp_data, *fyp = &fyp_data; + struct fy_parse_cfg cfg_data, *cfg = NULL; + int rc; + + fyr = &fypp->reader; + + /* verify that the called context is correct */ + assert(fy_is_path_flow_key_start(c)); + + fy_reader_fill_atom_start(fyr, &handle); + + cfg = &cfg_data; + memset(cfg, 0, sizeof(*cfg)); + cfg->flags = FYPCF_DEFAULT_PARSE; + cfg->diag = fypp->cfg.diag; + + rc = fy_parse_setup(fyp, cfg); + fyr_error_check(fyr, !rc, err_out, "fy_parse_setup() failed\n"); + + /* associate with reader and set flow mode */ + fy_parser_set_reader(fyp, fyr); + fy_parser_set_flow_only_mode(fyp, true); + + fyd = fy_parse_load_document(fyp); + + /* cleanup the parser no matter what */ + fy_parse_cleanup(fyp); + + fyr_error_check(fyr, fyd, err_out, "fy_parse_load_document() failed\n"); + + fy_reader_fill_atom_end(fyr, &handle); + + /* document is NULL, is a simple key */ + fyt = fy_path_token_queue(fypp, fytt, &handle, fyd); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + +err_out: + fypp->stream_error = true; + return -1; +} + +int fy_path_fetch_flow_map_key(struct fy_path_parser *fypp, int c) +{ + return fy_path_fetch_flow_document(fypp, c, FYTT_PE_MAP_KEY); +} + +int fy_path_fetch_flow_scalar(struct fy_path_parser *fypp, int c) +{ + struct fy_reader *fyr; + struct fy_token *fyt; + struct fy_atom handle; + bool is_single; + int rc = -1; + + fyr = &fypp->reader; + + /* verify that the called context is correct */ + assert(fy_is_path_flow_scalar_start(c)); + + is_single = c == '\''; + + rc = fy_reader_fetch_flow_scalar_handle(fyr, c, 0, &handle, false); + if (rc) + goto err_out_rc; + + /* document is NULL, is a simple key */ + fyt = fy_path_token_queue(fypp, FYTT_SCALAR, &handle, is_single ? FYSS_SINGLE_QUOTED : FYSS_DOUBLE_QUOTED); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + +err_out: + rc = -1; +err_out_rc: + fypp->stream_error = true; + return rc; +} + +int fy_path_fetch_number(struct fy_path_parser *fypp, int c) +{ + struct fy_reader *fyr; + struct fy_token *fyt; + int i, digits; + + fyr = &fypp->reader; + + /* verify that the called context is correct */ + assert(fy_is_num(c) || (c == '-' && fy_is_num(fy_reader_peek_at(fyr, 1)))); + + i = 0; + if (c == '-') + i++; + + digits = 0; + while (fy_is_num((c = fy_reader_peek_at(fyr, i)))) { + i++; + digits++; + } + FYR_PARSE_ERROR_CHECK(fyr, 0, i, FYEM_SCAN, + digits > 0, err_out, + "bad number"); + + fyt = fy_path_token_queue(fypp, FYTT_SCALAR, fy_reader_fill_atom_a(fyr, i), FYSS_PLAIN); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + +err_out: + fypp->stream_error = true; + return -1; +} + +int fy_path_fetch_tokens(struct fy_path_parser *fypp) +{ + enum fy_token_type type; + struct fy_token *fyt; + struct fy_reader *fyr; + int c, cn, rc, simple_token_count; + + fyr = &fypp->reader; + if (!fypp->stream_start_produced) { + + fyt = fy_path_token_queue(fypp, FYTT_STREAM_START, fy_reader_fill_atom_a(fyr, 0)); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + fypp->stream_start_produced = true; + return 0; + } + + /* XXX scan to next token? */ + + c = fy_reader_peek(fyr); + + if (fy_is_z(c)) { + + if (c >= 0) + fy_reader_advance(fyr, c); + + /* produce stream end continuously */ + fyt = fy_path_token_queue(fypp, FYTT_STREAM_END, fy_reader_fill_atom_a(fyr, 0)); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + } + + fyt = NULL; + type = FYTT_NONE; + simple_token_count = 0; + + /* first do the common tokens */ + switch (c) { + case ',': + type = FYTT_PE_COMMA; + simple_token_count = 1; + break; + + case '|': + if (fy_reader_peek_at(fyr, 1) == '|') { + type = FYTT_PE_BARBAR; + simple_token_count = 2; + break; + } + break; + + case '&': + if (fy_reader_peek_at(fyr, 1) == '&') { + type = FYTT_PE_AMPAMP; + simple_token_count = 2; + break; + } + break; + + case '(': + type = FYTT_PE_LPAREN; + simple_token_count = 1; + break; + + case ')': + type = FYTT_PE_RPAREN; + simple_token_count = 1; + break; + + case '=': + cn = fy_reader_peek_at(fyr, 1); + if (cn == '=') { + type = FYTT_PE_EQEQ; + simple_token_count = 2; + break; + } + break; + + case '>': + cn = fy_reader_peek_at(fyr, 1); + if (cn == '=') { + type = FYTT_PE_GTE; + simple_token_count = 2; + break; + } + type = FYTT_PE_GT; + simple_token_count = 1; + break; + + case '<': + cn = fy_reader_peek_at(fyr, 1); + if (cn == '=') { + type = FYTT_PE_LTE; + simple_token_count = 2; + break; + } + type = FYTT_PE_LT; + simple_token_count = 1; + break; + + case '!': + cn = fy_reader_peek_at(fyr, 1); + if (cn == '=') { + type = FYTT_PE_NOTEQ; + simple_token_count = 2; + break; + } + /* may still be something else */ + break; + + default: + break; + } + + if (type != FYTT_NONE) + goto do_token; + +again: + + switch (fypp->expr_mode) { + case fyem_none: + assert(0); /* should never happen */ + break; + + case fyem_path: + + switch (c) { + case '/': + type = FYTT_PE_SLASH; + simple_token_count = 1; + break; + + case '^': + type = FYTT_PE_ROOT; + simple_token_count = 1; + break; + + case ':': + type = FYTT_PE_SIBLING; + simple_token_count = 1; + break; + + case '$': + type = FYTT_PE_SCALAR_FILTER; + simple_token_count = 1; + break; + + case '%': + type = FYTT_PE_COLLECTION_FILTER; + simple_token_count = 1; + break; + + case '[': + if (fy_reader_peek_at(fyr, 1) == ']') { + type = FYTT_PE_SEQ_FILTER; + simple_token_count = 2; + } + break; + + case '{': + if (fy_reader_peek_at(fyr, 1) == '}') { + type = FYTT_PE_MAP_FILTER; + simple_token_count = 2; + } + break; + + + case '.': + cn = fy_reader_peek_at(fyr, 1); + if (cn == '.') { + type = FYTT_PE_PARENT; + simple_token_count = 2; + } else if (!fy_is_first_alpha(cn)) { + type = FYTT_PE_THIS; + simple_token_count = 1; + } + break; + + case '*': + if (fy_reader_peek_at(fyr, 1) == '*') { + type = FYTT_PE_EVERY_CHILD_R; + simple_token_count = 2; + } else if (!fy_is_first_alpha(fy_reader_peek_at(fyr, 1))) { + type = FYTT_PE_EVERY_CHILD; + simple_token_count = 1; + } else { + type = FYTT_PE_ALIAS; + simple_token_count = 2; + while (fy_is_alnum(fy_reader_peek_at(fyr, simple_token_count))) + simple_token_count++; + } + break; + + case '!': + cn = fy_reader_peek_at(fyr, 1); + if (cn == '=') { + type = FYTT_PE_NOTEQ; + simple_token_count = 2; + break; + } + type = FYTT_PE_UNIQUE_FILTER; + simple_token_count = 1; + break; + + default: + break; + } + break; + + case fyem_scalar: + + + /* it is possible for the expression to be a path + * we only detect a few cases (doing all too complex) + * (/ , (./ , (* + */ + if (fy_token_type_can_be_path_expr(fypp->last_queued_token_type)) { + cn = fy_reader_peek_at(fyr, 1); + if (c == '/' || + (c == '.' && (cn == '/' || cn == ')' || cn == '>' || cn == '<' || cn == '!' || cn == '='))) { + fypp->expr_mode = fyem_path; +#ifdef DEBUG_EXPR + fyr_notice(fyr, "switching to path expr\n"); +#endif + goto again; + } + } + + switch (c) { + case '+': + type = FYTT_SE_PLUS; + simple_token_count = 1; + break; + + case '-': + cn = fy_reader_peek_at(fyr, 1); + if (fy_is_num(cn) && + fy_token_type_can_be_before_negative_number(fypp->last_queued_token_type)) + break; + + type = FYTT_SE_MINUS; + simple_token_count = 1; + break; + + case '*': + type = FYTT_SE_MULT; + simple_token_count = 1; + break; + + case '/': + type = FYTT_SE_DIV; + simple_token_count = 1; + break; + + default: + break; + } + break; + } + +do_token: + /* simple tokens */ + if (simple_token_count > 0) { + fyt = fy_path_token_queue(fypp, type, fy_reader_fill_atom_a(fyr, simple_token_count)); + fyr_error_check(fyr, fyt, err_out, "fy_path_token_queue() failed\n"); + + return 0; + } + + switch (fypp->expr_mode) { + case fyem_none: + assert(0); /* should never happen */ + break; + + case fyem_path: + if (fy_is_first_alpha(c)) + return fy_path_fetch_plain_or_method(fypp, c, FYTT_PE_MAP_KEY, FYTT_PE_METHOD); + + if (fy_is_path_flow_key_start(c)) + return fy_path_fetch_flow_map_key(fypp, c); + + if (fy_is_num(c) || (c == '-' && fy_is_num(fy_reader_peek_at(fyr, 1)))) + return fy_path_fetch_seq_index_or_slice(fypp, c); + + if (c == '.' && fy_is_first_alpha(fy_reader_peek_at(fyr, 1))) + return fy_path_fetch_dot_method(fypp, c, FYTT_PE_METHOD); + + break; + + case fyem_scalar: + + if (fy_is_first_alpha(c)) + return fy_path_fetch_plain_or_method(fypp, c, FYTT_SCALAR, FYTT_SE_METHOD); + + if (fy_is_path_flow_scalar_start(c)) + return fy_path_fetch_flow_scalar(fypp, c); + + if (fy_is_num(c) || (c == '-' && fy_is_num(fy_reader_peek_at(fyr, 1)))) + return fy_path_fetch_number(fypp, c); + +#if 0 + if (c == '.' && fy_is_first_alpha(fy_reader_peek_at(fyr, 1))) + return fy_path_fetch_dot_method(fypp, c, FYTT_SE_METHOD); +#endif + + break; + } + + FYR_PARSE_ERROR(fyr, 0, 1, FYEM_SCAN, "bad path expression starts here c=%d", c); + +err_out: + fypp->stream_error = true; + rc = -1; + return rc; +} + +struct fy_token *fy_path_scan_peek(struct fy_path_parser *fypp, struct fy_token *fyt_prev) +{ + struct fy_token *fyt; + struct fy_reader *fyr; + int rc, last_token_activity_counter; + + fyr = &fypp->reader; + + /* nothing if stream end produced (and no stream end token in queue) */ + if (!fyt_prev && fypp->stream_end_produced && fy_token_list_empty(&fypp->queued_tokens)) { + + fyt = fy_token_list_head(&fypp->queued_tokens); + if (fyt && fyt->type == FYTT_STREAM_END) + return fyt; + + return NULL; + } + + for (;;) { + if (!fyt_prev) + fyt = fy_token_list_head(&fypp->queued_tokens); + else + fyt = fy_token_next(&fypp->queued_tokens, fyt_prev); + if (fyt) + break; + + /* on stream error we're done */ + if (fypp->stream_error) + return NULL; + + /* keep track of token activity, if it didn't change + * after the fetch tokens call, the state machine is stuck + */ + last_token_activity_counter = fypp->token_activity_counter; + + /* fetch more then */ + rc = fy_path_fetch_tokens(fypp); + if (rc) { + fy_error(fypp->cfg.diag, "fy_path_fetch_tokens() failed\n"); + goto err_out; + } + if (last_token_activity_counter == fypp->token_activity_counter) { + fy_error(fypp->cfg.diag, "out of tokens and failed to produce anymore"); + goto err_out; + } + } + + switch (fyt->type) { + case FYTT_STREAM_START: + fypp->stream_start_produced = true; + break; + case FYTT_STREAM_END: + fypp->stream_end_produced = true; + + rc = fy_reader_input_done(fyr); + if (rc) { + fy_error(fypp->cfg.diag, "fy_parse_input_done() failed"); + goto err_out; + } + break; + default: + break; + } + + return fyt; + +err_out: + fypp->stream_error = true; + return NULL; +} + +struct fy_token *fy_path_scan_remove(struct fy_path_parser *fypp, struct fy_token *fyt) +{ + if (!fypp || !fyt) + return NULL; + + fy_token_list_del(&fypp->queued_tokens, fyt); + + return fyt; +} + +struct fy_token *fy_path_scan_remove_peek(struct fy_path_parser *fypp, struct fy_token *fyt) +{ + fy_token_unref(fy_path_scan_remove(fypp, fyt)); + + return fy_path_scan_peek(fypp, NULL); +} + +struct fy_token *fy_path_scan(struct fy_path_parser *fypp) +{ + return fy_path_scan_remove(fypp, fy_path_scan_peek(fypp, NULL)); +} + +void fy_path_expr_dump(struct fy_path_expr *expr, struct fy_diag *diag, enum fy_error_type errlevel, int level, const char *banner) +{ + struct fy_path_expr *expr2; + const char *style = ""; + const char *text; + size_t len; + bool save_on_error; + + if (errlevel < diag->cfg.level) + return; + + save_on_error = diag->on_error; + diag->on_error = true; + + if (banner) + fy_diag_diag(diag, errlevel, "%-*s%s", level*2, "", banner); + + text = fy_token_get_text(expr->fyt, &len); + + style = ""; + if (expr->type == fpet_scalar) { + switch (fy_scalar_token_get_style(expr->fyt)) { + case FYSS_SINGLE_QUOTED: + style = "'"; + break; + case FYSS_DOUBLE_QUOTED: + style = "\""; + break; + default: + style = ""; + break; + } + } + + fy_diag_diag(diag, errlevel, "> %-*s%s:%s %s%.*s%s", + level*2, "", + fy_path_expr_type_txt[expr->type], + fy_expr_mode_txt[expr->expr_mode], + style, (int)len, text, style); + + for (expr2 = fy_path_expr_list_head(&expr->children); expr2; expr2 = fy_path_expr_next(&expr->children, expr2)) + fy_path_expr_dump(expr2, diag, errlevel, level + 1, NULL); + + diag->on_error = save_on_error; +} + +static struct fy_node * +fy_path_expr_to_node_internal(struct fy_document *fyd, struct fy_path_expr *expr) +{ + struct fy_path_expr *expr2; + const char *style = ""; + const char *text; + size_t len; + struct fy_node *fyn = NULL, *fyn2, *fyn_seq = NULL; + int rc; + + text = fy_token_get_text(expr->fyt, &len); + + /* by default use double quoted style */ + style = "\""; + switch (expr->type) { + case fpet_scalar: + switch (fy_scalar_token_get_style(expr->fyt)) { + case FYSS_SINGLE_QUOTED: + style = "'"; + break; + case FYSS_DOUBLE_QUOTED: + style = "\""; + break; + default: + style = ""; + break; + } + break; + + case fpet_map_key: + /* no styles for complex map keys */ + if (expr->fyt->map_key.fyd) + style = ""; + break; + + default: + break; + } + + /* list is empty this is a terminal */ + if (fy_path_expr_list_empty(&expr->children) && + expr->type != fpet_method) { + + fyn = fy_node_buildf(fyd, "%s: %s%.*s%s", + fy_path_expr_type_txt[expr->type], + style, (int)len, text, style); + if (!fyn) + return NULL; + + return fyn; + } + + fyn = fy_node_create_mapping(fyd); + if (!fyn) + goto err_out; + + fyn_seq = fy_node_create_sequence(fyd); + if (!fyn_seq) + goto err_out; + + for (expr2 = fy_path_expr_list_head(&expr->children); expr2; expr2 = fy_path_expr_next(&expr->children, expr2)) { + fyn2 = fy_path_expr_to_node_internal(fyd, expr2); + if (!fyn2) + goto err_out; + rc = fy_node_sequence_append(fyn_seq, fyn2); + if (rc) + goto err_out; + } + + if (expr->type != fpet_method) { + rc = fy_node_mapping_append(fyn, + fy_node_create_scalar(fyd, fy_path_expr_type_txt[expr->type], FY_NT), + fyn_seq); + } else { + rc = fy_node_mapping_append(fyn, + fy_node_create_scalarf(fyd, "%s()", expr->fym->name), + fyn_seq); + } + if (rc) + goto err_out; + + return fyn; + +err_out: + fy_node_free(fyn_seq); + fy_node_free(fyn); + return NULL; +} + +struct fy_document *fy_path_expr_to_document(struct fy_path_expr *expr) +{ + struct fy_document *fyd = NULL; + + if (!expr) + return NULL; + + fyd = fy_document_create(NULL); + if (!fyd) + return NULL; + + fyd->root = fy_path_expr_to_node_internal(fyd, expr); + if (!fyd->root) + goto err_out; + + return fyd; + +err_out: + fy_document_destroy(fyd); + return NULL; +} + +enum fy_path_expr_type fy_map_token_to_path_expr_type(enum fy_token_type type, enum fy_expr_mode mode) +{ + switch (type) { + case FYTT_PE_ROOT: + return fpet_root; + case FYTT_PE_THIS: + return fpet_this; + case FYTT_PE_PARENT: + case FYTT_PE_SIBLING: /* sibling maps to a chain of fpet_parent */ + return fpet_parent; + case FYTT_PE_MAP_KEY: + return fpet_map_key; + case FYTT_PE_SEQ_INDEX: + return fpet_seq_index; + case FYTT_PE_SEQ_SLICE: + return fpet_seq_slice; + case FYTT_PE_EVERY_CHILD: + return fpet_every_child; + case FYTT_PE_EVERY_CHILD_R: + return fpet_every_child_r; + case FYTT_PE_ALIAS: + return fpet_alias; + case FYTT_PE_SCALAR_FILTER: + return fpet_filter_scalar; + case FYTT_PE_COLLECTION_FILTER: + return fpet_filter_collection; + case FYTT_PE_SEQ_FILTER: + return fpet_filter_sequence; + case FYTT_PE_MAP_FILTER: + return fpet_filter_mapping; + case FYTT_PE_UNIQUE_FILTER: + return fpet_filter_unique; + case FYTT_PE_COMMA: + return mode == fyem_path ? fpet_multi : fpet_arg_separator; + case FYTT_PE_SLASH: + return fpet_chain; + case FYTT_PE_BARBAR: + return fpet_logical_or; + case FYTT_PE_AMPAMP: + return fpet_logical_and; + + case FYTT_PE_EQEQ: + return fpet_eq; + case FYTT_PE_NOTEQ: + return fpet_neq; + case FYTT_PE_LT: + return fpet_lt; + case FYTT_PE_GT: + return fpet_gt; + case FYTT_PE_LTE: + return fpet_lte; + case FYTT_PE_GTE: + return fpet_gte; + + case FYTT_SCALAR: + return fpet_scalar; + + case FYTT_SE_PLUS: + return fpet_plus; + case FYTT_SE_MINUS: + return fpet_minus; + case FYTT_SE_MULT: + return fpet_mult; + case FYTT_SE_DIV: + return fpet_div; + + case FYTT_PE_LPAREN: + return fpet_lparen; + case FYTT_PE_RPAREN: + return fpet_rparen; + + case FYTT_SE_METHOD: + case FYTT_PE_METHOD: + return fpet_method; + + default: + /* note parentheses do not have an expression */ + assert(0); + break; + } + return fpet_none; +} + +bool fy_token_type_is_operand(enum fy_token_type type) +{ + return type == FYTT_PE_ROOT || + type == FYTT_PE_THIS || + type == FYTT_PE_PARENT || + type == FYTT_PE_MAP_KEY || + type == FYTT_PE_SEQ_INDEX || + type == FYTT_PE_SEQ_SLICE || + type == FYTT_PE_EVERY_CHILD || + type == FYTT_PE_EVERY_CHILD_R || + type == FYTT_PE_ALIAS || + + type == FYTT_SCALAR; +} + +bool fy_token_type_is_operator(enum fy_token_type type) +{ + return type == FYTT_PE_SLASH || + type == FYTT_PE_SCALAR_FILTER || + type == FYTT_PE_COLLECTION_FILTER || + type == FYTT_PE_SEQ_FILTER || + type == FYTT_PE_MAP_FILTER || + type == FYTT_PE_UNIQUE_FILTER || + type == FYTT_PE_SIBLING || + type == FYTT_PE_COMMA || + type == FYTT_PE_BARBAR || + type == FYTT_PE_AMPAMP || + type == FYTT_PE_LPAREN || + type == FYTT_PE_RPAREN || + + type == FYTT_PE_EQEQ || + type == FYTT_PE_NOTEQ || + type == FYTT_PE_LT || + type == FYTT_PE_GT || + type == FYTT_PE_LTE || + type == FYTT_PE_GTE || + + type == FYTT_SE_PLUS || + type == FYTT_SE_MINUS || + type == FYTT_SE_MULT || + type == FYTT_SE_DIV; +} + +bool fy_token_type_is_operand_or_operator(enum fy_token_type type) +{ + return fy_token_type_is_operand(type) || + fy_token_type_is_operator(type); +} + +int fy_path_expr_type_prec(enum fy_path_expr_type type) +{ + switch (type) { + default: + return -1; /* terminals */ + case fpet_filter_collection: + case fpet_filter_scalar: + case fpet_filter_sequence: + case fpet_filter_mapping: + case fpet_filter_unique: + return 5; + case fpet_logical_or: + case fpet_logical_and: + return 4; + case fpet_multi: + return 11; + case fpet_eq: + case fpet_neq: + case fpet_lt: + case fpet_gt: + case fpet_lte: + case fpet_gte: + return 7; + case fpet_mult: + case fpet_div: + return 9; + case fpet_plus: + case fpet_minus: + return 8; + case fpet_chain: + return 10; + case fpet_lparen: + case fpet_rparen: + case fpet_method: + return 1000; + case fpet_arg_separator: + return 1; /* lowest */ + } + return -1; +} + +static inline void +dump_operand_stack(struct fy_path_parser *fypp) +{ + return fy_expr_stack_dump(fypp->cfg.diag, &fypp->operands); +} + +static inline int +push_operand(struct fy_path_parser *fypp, struct fy_path_expr *expr) +{ + return fy_expr_stack_push(&fypp->operands, expr); +} + +static inline 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 * +peek_operand(struct fy_path_parser *fypp) +{ + return fy_expr_stack_peek(&fypp->operands); +} + +static inline struct fy_path_expr * +pop_operand(struct fy_path_parser *fypp) +{ + return fy_expr_stack_pop(&fypp->operands); +} + +#define PREFIX 0 +#define INFIX 1 +#define SUFFIX 2 + +int fy_token_type_operator_placement(enum fy_token_type type) +{ + switch (type) { + case FYTT_PE_SLASH: /* SLASH is special at the start of the expression */ + case FYTT_PE_COMMA: + case FYTT_PE_BARBAR: + case FYTT_PE_AMPAMP: + case FYTT_PE_EQEQ: + case FYTT_PE_NOTEQ: + case FYTT_PE_LT: + case FYTT_PE_GT: + case FYTT_PE_LTE: + case FYTT_PE_GTE: + case FYTT_SE_PLUS: + case FYTT_SE_MINUS: + case FYTT_SE_MULT: + case FYTT_SE_DIV: + return INFIX; + case FYTT_PE_SCALAR_FILTER: + case FYTT_PE_COLLECTION_FILTER: + case FYTT_PE_SEQ_FILTER: + case FYTT_PE_MAP_FILTER: + case FYTT_PE_UNIQUE_FILTER: + return SUFFIX; + case FYTT_PE_SIBLING: + return PREFIX; + default: + break; + } + return -1; +} + +const struct fy_mark *fy_path_expr_start_mark(struct fy_path_expr *expr) +{ + if (!expr) + return NULL; + + return fy_token_start_mark(expr->fyt); +} + +const struct fy_mark *fy_path_expr_end_mark(struct fy_path_expr *expr) +{ + if (!expr) + return NULL; + + return fy_token_end_mark(expr->fyt); +} + +struct fy_token * +expr_to_token_mark(struct fy_path_expr *expr, struct fy_input *fyi) +{ + const struct fy_mark *ms, *me; + struct fy_atom handle; + + if (!expr || !fyi) + return NULL; + + ms = fy_path_expr_start_mark(expr); + assert(ms); + me = fy_path_expr_end_mark(expr); + assert(me); + + memset(&handle, 0, sizeof(handle)); + handle.start_mark = *ms; + handle.end_mark = *me; + handle.fyi = fyi; + handle.style = FYAS_PLAIN; + handle.chomp = FYAC_CLIP; + + return fy_token_create(FYTT_INPUT_MARKER, &handle); +} + +struct fy_token * +expr_lr_to_token_mark(struct fy_path_expr *exprl, struct fy_path_expr *exprr, struct fy_input *fyi) +{ + const struct fy_mark *ms, *me; + struct fy_atom handle; + + if (!exprl || !exprr || !fyi) + return NULL; + + ms = fy_path_expr_start_mark(exprl); + assert(ms); + me = fy_path_expr_end_mark(exprr); + assert(me); + + memset(&handle, 0, sizeof(handle)); + handle.start_mark = *ms; + handle.end_mark = *me; + handle.fyi = fyi; + handle.style = FYAS_PLAIN; + handle.chomp = FYAC_CLIP; + + return fy_token_create(FYTT_INPUT_MARKER, &handle); +} + +int +fy_path_expr_order(struct fy_path_expr *expr1, struct fy_path_expr *expr2) +{ + const struct fy_mark *m1 = NULL, *m2 = NULL; + + if (expr1) + m1 = fy_path_expr_start_mark(expr1); + + if (expr2) + m2 = fy_path_expr_start_mark(expr2); + + if (m1 == m2) + return 0; + + if (!m1) + return -1; + + if (!m2) + return 1; + + return m1->input_pos == m2->input_pos ? 0 : + m1->input_pos < m2->input_pos ? -1 : 1; +} + +int push_operand_lr(struct fy_path_parser *fypp, + enum fy_path_expr_type type, + struct fy_path_expr *exprl, struct fy_path_expr *exprr, + bool optimize) +{ + struct fy_reader *fyr; + struct fy_path_expr *expr = NULL, *exprt; + const struct fy_mark *ms = NULL, *me = NULL; + struct fy_atom handle; + int ret; + + optimize = false; + assert(exprl || exprr); + + fyr = &fypp->reader; + +#if 0 + fyr_notice(fyr, ">>> %s <%s> l=<%s> r=<%s>\n", __func__, + fy_path_expr_type_txt[type], + exprl ?fy_path_expr_type_txt[exprl->type] : "NULL", + exprr ?fy_path_expr_type_txt[exprr->type] : "NULL"); +#endif + + expr = fy_path_expr_alloc_recycle(fypp); + fyr_error_check(fyr, expr, err_out, + "fy_path_expr_alloc_recycle() failed\n"); + + expr->type = type; + expr->fyt = NULL; + + if (exprl) { + assert(exprl->fyt); + ms = fy_token_start_mark(exprl->fyt); + assert(ms); + } else { + ms = fy_token_start_mark(exprr->fyt); + assert(ms); + } + + if (exprr) { + assert(exprr->fyt); + me = fy_token_end_mark(exprr->fyt); + assert(me); + } else { + me = fy_token_end_mark(exprr->fyt); + assert(me); + } + + assert(ms && me); + + memset(&handle, 0, sizeof(handle)); + handle.start_mark = *ms; + handle.end_mark = *me; + handle.fyi = fypp->fyi; + handle.style = FYAS_PLAIN; + handle.chomp = FYAC_CLIP; + + if (exprl) { + if (type == exprl->type && fy_path_expr_type_is_mergeable(type)) { + while ((exprt = fy_path_expr_list_pop(&exprl->children)) != NULL) { + fy_path_expr_list_add_tail(&expr->children, exprt); + exprt->parent = expr; + } + fy_path_expr_free_recycle(fypp, exprl); + } else { + fy_path_expr_list_add_tail(&expr->children, exprl); + exprl->parent = expr; + } + exprl = NULL; + } + + if (exprr) { + if (type == exprr->type && fy_path_expr_type_is_mergeable(type)) { + while ((exprt = fy_path_expr_list_pop(&exprr->children)) != NULL) { + fy_path_expr_list_add_tail(&expr->children, exprt); + exprt->parent = expr; + } + fy_path_expr_free_recycle(fypp, exprr); + } else { + fy_path_expr_list_add_tail(&expr->children, exprr); + exprr->parent = expr; + } + exprr = NULL; + } + + expr->fyt = fy_token_create(FYTT_INPUT_MARKER, &handle); + fyr_error_check(fyr, expr->fyt, err_out, + "expr_to_token_mark() failed\n"); + + ret = push_operand(fypp, expr); + fyr_error_check(fyr, !ret, err_out, + "push_operand() failed\n"); + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, expr->fyt, + FYDF_NOTICE, FYEM_PARSE, "pushed operand lr"); +#endif + + return 0; +err_out: + fy_path_expr_free(expr); + fy_path_expr_free(exprl); + fy_path_expr_free(exprr); + return -1; +} + +enum fy_method_idx { + fymi_test, + fymi_sum, + fymi_this, + fymi_parent, + fymi_root, + fymi_any, + fymi_all, + fymi_select, + fymi_key, + fymi_value, + fymi_index, + fymi_null, +}; + +static struct fy_walk_result * +common_builtin_ref_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs); + +static struct fy_walk_result * +common_builtin_collection_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs); + + +static struct fy_walk_result * +test_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs); + +static struct fy_walk_result * +sum_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs); + +static const struct fy_method fy_methods[] = { + [fymi_test] = { + .name = "test", + .len = 4, + .mode = fyem_scalar, + .nargs = 1, + .exec = test_exec, + }, + [fymi_sum] = { + .name = "sum", + .len = 3, + .mode = fyem_scalar, + .nargs = 2, + .exec = sum_exec, + }, + [fymi_this] = { + .name = "this", + .len = 4, + .mode = fyem_path, + .nargs = 0, + .exec = common_builtin_ref_exec, + }, + [fymi_parent] = { + .name = "parent", + .len = 6, + .mode = fyem_path, + .nargs = 0, + .exec = common_builtin_ref_exec, + }, + [fymi_root] = { + .name = "root", + .len = 4, + .mode = fyem_path, + .nargs = 0, + .exec = common_builtin_ref_exec, + }, + [fymi_any] = { + .name = "any", + .len = 3, + .mode = fyem_path, + .nargs = 1, + .exec = common_builtin_collection_exec, + }, + [fymi_all] = { + .name = "all", + .len = 3, + .mode = fyem_path, + .nargs = 1, + .exec = common_builtin_collection_exec, + }, + [fymi_select] = { + .name = "select", + .len = 6, + .mode = fyem_path, + .nargs = 1, + .exec = common_builtin_collection_exec, + }, + [fymi_key] = { + .name = "key", + .len = 3, + .mode = fyem_path, + .nargs = 1, + .exec = common_builtin_ref_exec, + }, + [fymi_value] = { + .name = "value", + .len = 5, + .mode = fyem_path, + .nargs = 1, + .exec = common_builtin_ref_exec, + }, + [fymi_index] = { + .name = "index", + .len = 5, + .mode = fyem_path, + .nargs = 1, + .exec = common_builtin_ref_exec, + }, + [fymi_null] = { + .name = "null", + .len = 4, + .mode = fyem_path, + .nargs = 0, + .exec = common_builtin_ref_exec, + }, +}; + +static inline int fy_method_to_builtin_idx(const struct fy_method *fym) +{ + if (!fym || fym < fy_methods || fym >= &fy_methods[ARRAY_SIZE(fy_methods)]) + return -1; + return fym - fy_methods; +} + +static struct fy_walk_result * +common_builtin_ref_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs) +{ + enum fy_method_idx midx; + struct fy_walk_result *output = NULL; + struct fy_walk_result *fwr, *fwrn; + struct fy_node *fyn, *fynt; + int i; + + if (!fypx || !input) + goto out; + + i = fy_method_to_builtin_idx(fym); + if (i < 0) + goto out; + midx = (enum fy_method_idx)i; + + switch (midx) { + case fymi_key: + case fymi_value: + if (!args || nargs != 1 || !args[0] || args[0]->type != fwrt_string) + goto out; + break; + case fymi_index: + if (!args || nargs != 1 || !args[0] || args[0]->type != fwrt_number) + goto out; + break; + case fymi_root: + case fymi_parent: + case fymi_this: + case fymi_null: + if (nargs != 0) + goto out; + break; + default: + goto out; + } + + output = fy_path_exec_walk_result_create(fypx, fwrt_refs); + assert(output); + + for (fwr = fy_walk_result_iter_start(input); fwr; + fwr = fy_walk_result_iter_next(input, fwr)) { + + if (fwr->type != fwrt_node_ref || !fwr->fyn) + continue; + + fynt = fwr->fyn; + + switch (midx) { + case fymi_key: + case fymi_value: + case fymi_index: + case fymi_this: + case fymi_null: + /* dereference alias */ + if (fy_node_is_alias(fynt)) { + // fprintf(stderr, "%s: %s calling fy_node_alias_resolve_by_ypath()\n", __func__, fy_node_get_path_alloca(fyn)); + fynt = fy_node_alias_resolve_by_ypath(fynt); + } + break; + default: + break; + } + + fyn = NULL; + switch (midx) { + case fymi_key: + if (!fy_node_is_mapping(fynt)) + break; + fyn = fy_node_mapping_lookup_key_by_string(fynt, args[0]->string, FY_NT); + break; + + case fymi_value: + if (!fy_node_is_mapping(fynt)) + break; + fyn = fy_node_mapping_lookup_by_string(fynt, args[0]->string, FY_NT); + break; + + case fymi_index: + if (!fy_node_is_sequence(fynt)) + break; + fyn = fy_node_sequence_get_by_index(fynt, (int)args[0]->number); + break; + + case fymi_root: + fyn = fy_document_root(fy_node_document(fynt)); + break; + + case fymi_parent: + fyn = fy_node_get_parent(fynt); + break; + + case fymi_null: + if (!fy_node_is_mapping(fynt)) + break; + fyn = fy_node_mapping_lookup_value_by_null_key(fynt); + break; + + case fymi_this: + fyn = fynt; + break; + + default: + break; + } + + if (!fyn) + continue; + + fwrn = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fyn); + assert(fwrn); + + fy_walk_result_list_add_tail(&output->refs, fwrn); + } + + /* output convert zero to NULL, singular to node_ref */ + if (output && output->type == fwrt_refs) { + if (fy_walk_result_list_empty(&output->refs)) { + fy_walk_result_free(output); + output = NULL; + } else if (fy_walk_result_list_is_singular(&output->refs)) { + fwr = fy_walk_result_list_pop(&output->refs); + assert(fwr); + fy_walk_result_free(output); + output = fwr; + } + } + +out: + fy_walk_result_free(input); + if (args) { + for (i = 0; i < nargs; i++) + fy_walk_result_free(args[i]); + } + return output; +} + +static struct fy_walk_result * +common_builtin_collection_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs) +{ + enum fy_method_idx midx; + struct fy_walk_result *output = NULL; + struct fy_walk_result *fwr, *fwrn, *fwrt; + struct fy_path_expr *expr_arg; + bool match, done; + int input_count, match_count; + int i; + + if (!fypx || !input) + goto out; + + i = fy_method_to_builtin_idx(fym); + if (i < 0) + goto out; + midx = (enum fy_method_idx)i; + + switch (midx) { + case fymi_any: + case fymi_all: + case fymi_select: + if (!args || nargs != 1 || !args[0]) + goto out; + break; + default: + goto out; + } + + expr_arg = fy_path_expr_list_head(&expr->children); + assert(expr_arg); + + /* only handle inputs of node and refs */ + if (input->type != fwrt_node_ref && input->type != fwrt_refs) + goto out; + + output = NULL; + + switch (midx) { + case fymi_select: + output = fy_path_exec_walk_result_create(fypx, fwrt_refs); + assert(output); + break; + default: + break; + } + + + done = false; + match_count = input_count = 0; + for (fwr = fy_walk_result_iter_start(input); fwr && !done; fwr = fy_walk_result_iter_next(input, fwr)) { + + input_count++; + + fwrt = fy_walk_result_clone(fwr); + assert(fwrt); + + fwrn = fy_path_expr_execute(fypx, level + 1, expr_arg, fwrt, expr->type); + + match = fwrn != NULL; + if (match) + match_count++; + + switch (midx) { + case fymi_any: + /* on any match, we're done */ + if (match) + done = true; + break; + + case fymi_all: + /* on any non match, we're done */ + if (!match) + done = true; + break; + + case fymi_select: + /* select only works on node refs */ + if (fwr->type != fwrt_node_ref) + break; + if (match) { + fwrt = fy_walk_result_clone(fwr); + assert(fwrt); + fy_walk_result_list_add_tail(&output->refs, fwrt); + } + break; + + default: + break; + } + + if (fwrn) + fy_walk_result_free(fwrn); + } + + switch (midx) { + case fymi_any: + if (input_count > 0 && match_count <= input_count) { + output = input; + input = NULL; + } + break; + case fymi_all: + if (input_count > 0 && match_count == input_count) { + output = input; + input = NULL; + } + break; + + default: + break; + } + + /* output convert zero to NULL, singular to node_ref */ + if (output && output->type == fwrt_refs) { + if (fy_walk_result_list_empty(&output->refs)) { + fy_walk_result_free(output); + output = NULL; + } else if (fy_walk_result_list_is_singular(&output->refs)) { + fwr = fy_walk_result_list_pop(&output->refs); + assert(fwr); + fy_walk_result_free(output); + output = fwr; + } + } + +out: + if (input) + fy_walk_result_free(input); + if (args) { + for (i = 0; i < nargs; i++) + fy_walk_result_free(args[i]); + } + + return output; +} + +static struct fy_walk_result * +test_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs) +{ + int i; + struct fy_walk_result *output = NULL; + + if (!fypx || !args || nargs != 1) + goto out; + + /* require a single number argument */ + if (!args[0] || args[0]->type != fwrt_number) + goto out; + + /* reuse argument */ + output = args[0]; + args[0] = NULL; + + /* add 1 to the number */ + output->number += 1; + +out: + fy_walk_result_free(input); + if (args) { + for (i = 0; i < nargs; i++) + fy_walk_result_free(args[i]); + } + return output; +} + +static struct fy_walk_result * +sum_exec(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs) +{ + int i; + struct fy_walk_result *output = NULL; + + if (!fypx || !args || nargs != 2) + goto out; + + /* require two number argument */ + if (!args[0] || args[0]->type != fwrt_number || + !args[1] || args[1]->type != fwrt_number) + goto out; + + /* reuse argument */ + output = args[0]; + args[0] = NULL; + + /* add 1 to the number */ + output->number += args[1]->number; + +out: + fy_walk_result_free(input); + if (args) { + for (i = 0; i < nargs; i++) + fy_walk_result_free(args[i]); + } + return output; +} + +int evaluate_method(struct fy_path_parser *fypp, struct fy_path_expr *exprm, + struct fy_path_expr *exprl, struct fy_path_expr *exprr) +{ + struct fy_reader *fyr; + struct fy_path_expr *exprt; + struct fy_token *fyt; + const char *text; + size_t len; + const struct fy_method *fym; + unsigned int i, count; + int ret; + + fyr = &fypp->reader; + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, exprm->fyt, + FYDF_NOTICE, FYEM_PARSE, "evaluating method"); +#endif + + text = fy_token_get_text(exprm->fyt, &len); + fyr_error_check(fyr, text, err_out, + "fy_token_get_text() failed\n"); + + for (i = 0, fym = fy_methods; i < ARRAY_SIZE(fy_methods); i++, fym++) { + if (fym->len == len && !memcmp(text, fym->name, len)) + break; + } + + FYR_TOKEN_ERROR_CHECK(fyr, exprm->fyt, FYEM_PARSE, + i < ARRAY_SIZE(fy_methods), err_out, + "invalid method %.*s\n", (int)len, text); + + /* reuse exprm */ + count = 0; + while ((exprt = fy_expr_stack_peek(&fypp->operands)) != NULL && + fy_path_expr_order(exprm, exprt) < 0) { + + exprt = fy_expr_stack_pop(&fypp->operands); + assert(exprt); + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, exprt->fyt, + FYDF_NOTICE, FYEM_PARSE, "poped argument %d", count); +#endif + + /* add in reverse order */ + fy_path_expr_list_add(&exprm->children, exprt); + exprt->parent = exprm; + count++; + + } + + if (exprr) { + fyt = expr_lr_to_token_mark(exprm, exprr, fypp->fyi); + fyr_error_check(fyr, fyt, err_out, + "expr_lr_to_token_mark() failed\n"); + + fy_token_unref(exprm->fyt); + exprm->fyt = fyt; + } + + FYR_TOKEN_ERROR_CHECK(fyr, exprm->fyt, FYEM_PARSE, + fym->nargs == count, err_out, + "too %s argument for method %s, expected %d, got %d\n", + fym->nargs < count ? "many" : "few", + fym->name, fym->nargs, count); + + exprm->fym = fym; + + if (exprl) + fy_path_expr_free_recycle(fypp, exprl); + if (exprr) + fy_path_expr_free_recycle(fypp, exprr); + + /* and push as an operand */ + ret = push_operand(fypp, exprm); + fyr_error_check(fyr, !ret, err_out, + "push_operand() failed\n"); + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, exprm->fyt, + FYDF_NOTICE, FYEM_PARSE, "pushed operand evaluate_method"); +#endif + return 0; + +err_out: + /* we don't need the parentheses operators */ + fy_path_expr_free_recycle(fypp, exprm); + if (exprl) + fy_path_expr_free_recycle(fypp, exprl); + if (exprr) + fy_path_expr_free_recycle(fypp, exprr); + + return -1; +} + +int evaluate_new(struct fy_path_parser *fypp) +{ + struct fy_reader *fyr; + struct fy_path_expr *expr = NULL, *expr_peek, *exprt; + struct fy_path_expr *exprl = NULL, *exprr = NULL, *chain = NULL, *exprm = NULL; + struct fy_path_expr *parent = NULL; + struct fy_token *fyt; + enum fy_path_expr_type type, etype; + int ret; + + fyr = &fypp->reader; + + expr = fy_expr_stack_pop(&fypp->operators); + fyr_error_check(fyr, expr, err_out, + "pop_operator() failed to find token operator to evaluate\n"); + + assert(expr->fyt); + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, expr->fyt, + FYDF_NOTICE, FYEM_PARSE, "poped operator expression"); +#endif + + exprl = NULL; + exprr = NULL; + type = expr->type; + switch (type) { + + case fpet_chain: + + /* dump_operand_stack(fypp); */ + /* dump_operator_stack(fypp); */ + + /* peek the next operator */ + expr_peek = fy_expr_stack_peek(&fypp->operators); + + /* pop the top in either case */ + exprr = fy_expr_stack_pop(&fypp->operands); + if (!exprr) { + // fyr_notice(fyr, "ROOT value (with no arguments)\n"); + + /* conver to root and push to operands */ + expr->type = fpet_root; + + ret = push_operand(fypp, expr); + fyr_error_check(fyr, !ret, err_out, + "push_operand() failed\n"); + return 0; + } + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, exprr->fyt, + FYDF_NOTICE, FYEM_PARSE, "exprr"); +#endif + + /* expression is to the left, that means it's a root chain */ + if (fy_path_expr_order(expr, exprr) < 0 && + (!(exprl = fy_expr_stack_peek(&fypp->operands)) || + (expr_peek && fy_path_expr_order(exprl, expr_peek) <= 0))) { + + // fyr_notice(fyr, "ROOT operator (with arguments)\n"); + + exprl = fy_path_expr_alloc_recycle(fypp); + fyr_error_check(fyr, exprl, err_out, + "fy_path_expr_alloc_recycle() failed\n"); + exprl->type = fpet_root; + + /* move token to the root */ + exprl->fyt = expr->fyt; + expr->fyt = NULL; + + } else if (!(exprl = fy_expr_stack_pop(&fypp->operands))) { + + // fyr_notice(fyr, "COLLECTION operator\n"); + + exprl = exprr; + + exprr = fy_path_expr_alloc_recycle(fypp); + fyr_error_check(fyr, exprr, err_out, + "fy_path_expr_alloc_recycle() failed\n"); + exprr->type = fpet_filter_collection; + + /* move token to the filter collection */ + exprr->fyt = expr->fyt; + expr->fyt = NULL; + + } else { + assert(exprr && exprl); + + // fyr_notice(fyr, "CHAIN operator\n"); + } + + /* we don't need the chain operator now */ + fy_path_expr_free_recycle(fypp, expr); + expr = NULL; + + ret = push_operand_lr(fypp, fpet_chain, exprl, exprr, true); + fyr_error_check(fyr, !ret, err_out, + "push_operand_lr() failed\n"); + return 0; + + case fpet_multi: + case fpet_logical_or: + case fpet_logical_and: + + case fpet_eq: + case fpet_neq: + case fpet_lt: + case fpet_gt: + case fpet_lte: + case fpet_gte: + + case fpet_plus: + case fpet_minus: + case fpet_mult: + case fpet_div: + + exprl = NULL; + exprr = NULL; + exprt = fy_expr_stack_peek(&fypp->operators); + + // fyr_error(fyr, "mode=%s top-mode=%s\n", + // fy_expr_mode_txt[fypp->expr_mode], + // exprt ? fy_expr_mode_txt[exprt->expr_mode] : ""); + +#if 0 + exprr = fy_expr_stack_peek(&fypp->operands); + if (exprr && exprt && fy_path_expr_order(exprr, exprt) <= 0) + exprr = NULL; + else +#endif + exprr = fy_expr_stack_pop(&fypp->operands); + fyr_error_check(fyr, exprr, err_out, + "fy_expr_stack_pop() failed for exprr\n"); + +#if 0 + exprl = fy_expr_stack_peek_at(&fypp->operands, 1); + if (exprl && exprt && fy_path_expr_order(exprl, exprt) <= 0) + exprl = NULL; + else +#endif + exprl = fy_expr_stack_pop(&fypp->operands); + fyr_error_check(fyr, exprl, err_out, + "fy_expr_stack_pop() failed for exprl\n"); + + /* we don't need the operator now */ + fy_path_expr_free_recycle(fypp, expr); + expr = NULL; + + ret = push_operand_lr(fypp, type, exprl, exprr, true); + fyr_error_check(fyr, !ret, err_out, + "push_operand_lr() failed\n"); + + break; + + case fpet_filter_collection: + case fpet_filter_scalar: + case fpet_filter_sequence: + case fpet_filter_mapping: + case fpet_filter_unique: + + exprl = fy_expr_stack_pop(&fypp->operands); + FYR_TOKEN_ERROR_CHECK(fyr, expr->fyt, FYEM_PARSE, + exprl, err_out, + "filter operator without argument"); + + exprr = fy_path_expr_alloc_recycle(fypp); + fyr_error_check(fyr, exprr, err_out, + "fy_path_expr_alloc_recycle() failed\n"); + exprr->type = type; + + /* move token to the filter collection */ + exprr->fyt = expr->fyt; + expr->fyt = NULL; + + /* we don't need the operator now */ + fy_path_expr_free_recycle(fypp, expr); + expr = NULL; + + /* push as a chain */ + ret = push_operand_lr(fypp, fpet_chain, exprl, exprr, true); + fyr_error_check(fyr, !ret, err_out, + "push_operand_lr() failed\n"); + + break; + + case fpet_lparen: + abort(); + assert(0); + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, expr->fyt, + FYDF_NOTICE, FYEM_PARSE, "("); +#endif + + return 0; + + case fpet_arg_separator: + + /* separator is right hand side of the expression now */ + exprr = expr; + expr = NULL; + + /* evaluate until we hit a match to the rparen */ + exprl = fy_expr_stack_peek(&fypp->operators); + + if (!fy_path_expr_type_is_lparen(exprl->type)) { + ret = evaluate_new(fypp); + if (ret) + goto err_out; + } + exprl = NULL; + + fy_path_expr_free_recycle(fypp, exprr); + exprr = NULL; + + break; + + case fpet_rparen: + + /* rparen is right hand side of the expression now */ + exprr = expr; + expr = NULL; + + /* evaluate until we hit a match to the rparen */ + while ((exprl = fy_expr_stack_peek(&fypp->operators)) != NULL) { + + if (fy_path_expr_type_is_lparen(exprl->type)) + break; + + ret = evaluate_new(fypp); + if (ret) + goto err_out; + } + + FYR_TOKEN_ERROR_CHECK(fyr, exprr->fyt, FYEM_PARSE, + exprl, err_out, + "missing matching left parentheses"); + + exprl = fy_expr_stack_pop(&fypp->operators); + assert(exprl); + + exprt = fy_expr_stack_peek(&fypp->operands); + + etype = exprl->expr_mode == fyem_scalar ? fpet_scalar_expr : fpet_path_expr; + + /* already is an expression, reuse */ + if (exprt && exprt->type == etype) { + + fyt = expr_lr_to_token_mark(exprl, exprr, fypp->fyi); + fyr_error_check(fyr, fyt, err_out, + "expr_lr_to_token_mark() failed\n"); + fy_token_unref(exprt->fyt); + exprt->fyt = fyt; + exprt->expr_mode = exprl->expr_mode; + + /* we don't need the parentheses operators */ + fy_path_expr_free_recycle(fypp, exprl); + exprl = NULL; + fy_path_expr_free_recycle(fypp, exprr); + exprr = NULL; + + return 0; + } + + /* if it's method, evaluate */ + exprm = fy_expr_stack_peek(&fypp->operators); + if (exprm && exprm->type == fpet_method) { + + exprm = fy_expr_stack_pop(&fypp->operators); + assert(exprm); + + return evaluate_method(fypp, exprm, exprl, exprr); + } + + expr = fy_path_expr_alloc_recycle(fypp); + fyr_error_check(fyr, expr, err_out, + "fy_path_expr_alloc_recycle() failed\n"); + expr->type = etype; + expr->expr_mode = exprl->expr_mode; + + expr->fyt = expr_lr_to_token_mark(exprl, exprr, fypp->fyi); + + exprt = fy_expr_stack_pop(&fypp->operands); + + FYR_TOKEN_ERROR_CHECK(fyr, exprr->fyt, FYEM_PARSE, + exprt, err_out, + "empty expression in parentheses"); + + fy_path_expr_list_add_tail(&expr->children, exprt); + exprt->parent = expr; + + /* pop all operands that after exprl */ + while ((exprt = fy_expr_stack_peek(&fypp->operands)) != NULL && + fy_path_expr_order(exprt, exprl) >= 0) { +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, exprt->fyt, + FYDF_NOTICE, FYEM_PARSE, "discarding argument"); +#endif + fy_path_expr_free_recycle(fypp, fy_expr_stack_pop(&fypp->operands)); + } + + if (exprl->expr_mode != fyem_none) { + fypp->expr_mode = exprl->expr_mode; +#ifdef DEBUG_EXPR + fyr_notice(fyr, "poping expr_mode %s\n", fy_expr_mode_txt[fypp->expr_mode]); +#endif + } + + /* we don't need the parentheses operators */ + fy_path_expr_free_recycle(fypp, exprl); + exprl = NULL; + fy_path_expr_free_recycle(fypp, exprr); + exprr = NULL; + + ret = push_operand(fypp, expr); + fyr_error_check(fyr, !ret, err_out, + "push_operand() failed\n"); + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, expr->fyt, + FYDF_NOTICE, FYEM_PARSE, "pushed operand evaluate_new"); +#endif + return 0; + + case fpet_method: + return evaluate_method(fypp, expr, NULL, NULL); + + /* shoud never */ + case fpet_scalar_expr: + case fpet_path_expr: + assert(0); + abort(); + + default: + fyr_error(fyr, "Unknown expression %s\n", fy_path_expr_type_txt[expr->type]); + goto err_out; + } + + return 0; + +err_out: + +#ifdef DEBUG_EXPR + if (expr) + fy_path_expr_dump(expr, fypp->cfg.diag, FYET_NOTICE, 0, "expr:"); + if (exprl) + fy_path_expr_dump(exprl, fypp->cfg.diag, FYET_NOTICE, 0, "exprl:"); + if (exprr) + fy_path_expr_dump(exprr, fypp->cfg.diag, FYET_NOTICE, 0, "exprr:"); + if (chain) + fy_path_expr_dump(chain, fypp->cfg.diag, FYET_NOTICE, 0, "chain:"); + if (parent) + fy_path_expr_dump(parent, fypp->cfg.diag, FYET_NOTICE, 0, "parent:"); + + fy_notice(fypp->cfg.diag, "operator stack\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operators); + fy_notice(fypp->cfg.diag, "operand stack\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operands); +#endif + + fy_path_expr_free(expr); + fy_path_expr_free(exprl); + fy_path_expr_free(exprr); + fy_path_expr_free(chain); + fy_path_expr_free(parent); + + return -1; +} + +int fy_path_check_expression_alias(struct fy_path_parser *fypp, struct fy_path_expr *expr) +{ + struct fy_reader *fyr; + struct fy_path_expr *exprn; + int rc; + + if (!expr) + return 0; + + fyr = &fypp->reader; + + /* an alias with a parent.. must be the first one */ + if (expr->type == fpet_alias && expr->parent) { + + exprn = fy_path_expr_list_head(&expr->parent->children); + + /* an alias may only be the first of a path expression */ + FYR_TOKEN_ERROR_CHECK(fyr, expr->fyt, FYEM_PARSE, + expr == exprn, err_out, + "alias is not first in the path expresion"); + } + + for (exprn = fy_path_expr_list_head(&expr->children); exprn; + exprn = fy_path_expr_next(&expr->children, exprn)) { + + rc = fy_path_check_expression_alias(fypp, exprn); + if (rc) + return rc; + } + + return 0; + +err_out: + return -1; +} + +/* check expression for validity */ +int fy_path_check_expression(struct fy_path_parser *fypp, struct fy_path_expr *expr) +{ + int rc; + + rc = fy_path_check_expression_alias(fypp, expr); + if (rc) + return rc; + + return 0; +} + +struct fy_path_expr * +fy_path_parse_expression(struct fy_path_parser *fypp) +{ + struct fy_reader *fyr; + struct fy_token *fyt = NULL; + enum fy_token_type fytt; + struct fy_path_expr *expr, *expr_top, *exprt; + enum fy_expr_mode old_scan_mode, prev_scan_mode; + int ret, rc; + + /* the parser must be in the correct state */ + if (!fypp || fy_expr_stack_size(&fypp->operators) > 0 || fy_expr_stack_size(&fypp->operands) > 0) + return NULL; + + fyr = &fypp->reader; + + /* find stream start */ + fyt = fy_path_scan_peek(fypp, NULL); + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_PARSE, + fyt && fyt->type == FYTT_STREAM_START, err_out, + "no tokens available or start without stream start"); + + /* remove stream start */ + fy_token_unref(fy_path_scan_remove(fypp, fyt)); + fyt = NULL; + + prev_scan_mode = fypp->expr_mode; + + while ((fyt = fy_path_scan_peek(fypp, NULL)) != NULL) { + + if (fyt->type == FYTT_STREAM_END) + break; + +#ifdef DEBUG_EXPR + FYR_TOKEN_DIAG(fyr, fyt, FYET_NOTICE, FYEM_PARSE, "next token %s", fy_token_debug_text_a(fyt)); +#endif + fytt = fyt->type; + + /* create an expression in either operator/operand case */ + expr = fy_path_expr_alloc_recycle(fypp); + fyr_error_check(fyr, expr, err_out, + "fy_path_expr_alloc_recycle() failed\n"); + + expr->fyt = fy_path_scan_remove(fypp, fyt); + /* this it the first attempt, it might not be the final one */ + expr->type = fy_map_token_to_path_expr_type(fyt->type, fypp->expr_mode); + fyt = NULL; + +#ifdef DEBUG_EXPR + fy_path_expr_dump(expr, fypp->cfg.diag, FYET_NOTICE, 0, "-> expr"); +#endif + + if (prev_scan_mode != fypp->expr_mode) { +#ifdef DEBUG_EXPR + fyr_warning(fyr, "switched expr_mode %s -> %s\n", + fy_expr_mode_txt[prev_scan_mode], + fy_expr_mode_txt[fypp->expr_mode]); +#endif + expr_top = fy_expr_stack_peek(&fypp->operators); + +#ifdef DEBUG_EXPR + if (expr_top) + fy_path_expr_dump(expr_top, fypp->cfg.diag, FYET_NOTICE, 0, NULL); +#endif + + if (expr_top && fy_path_expr_type_is_lparen(expr_top->type) && + expr_top->expr_mode != fypp->expr_mode) { +#ifdef DEBUG_EXPR + fyr_warning(fyr, "switched top lparen expr_mode %s -> %s\n", + fy_expr_mode_txt[expr_top->expr_mode], + fy_expr_mode_txt[fypp->expr_mode]); + expr_top->expr_mode = fypp->expr_mode; +#endif + } + } + + prev_scan_mode = fypp->expr_mode; + + /* if it's an operand convert it to expression and push */ + if (fy_token_type_is_operand(fytt)) { + + ret = fy_expr_stack_push(&fypp->operands, expr); + fyr_error_check(fyr, !ret, err_out, "push_operand() failed\n"); + expr = NULL; + + continue; + } + + /* specials for SLASH */ + + if (expr->fyt->type == FYTT_PE_SLASH) { + + /* try to get next token */ + fyt = fy_path_scan_peek(fypp, NULL); + if (!fyt) { + if (!fypp->stream_error) { + (void)fy_path_fetch_tokens(fypp); + fyt = fy_path_scan_peek(fypp, NULL); + } + } + + /* last token, it means it's a collection filter (or a root) */ + if (!fyt || fyt->type == FYTT_STREAM_END || fyt->type == FYTT_PE_RPAREN) { + + exprt = fy_expr_stack_peek(&fypp->operands); + + /* if no argument exists it's a root */ + if (!exprt) { + expr->type = fpet_root; + + ret = fy_expr_stack_push(&fypp->operands, expr); + fyr_error_check(fyr, !ret, err_out, "push_operand() failed\n"); + expr = NULL; + continue; + } + + expr->type = fpet_filter_collection; + } + } + +#ifdef DEBUG_EXPR + fy_notice(fypp->cfg.diag, "operator stack (before)\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operators); + fy_notice(fypp->cfg.diag, "operand stack (before)\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operands); +#endif + + old_scan_mode = fypp->expr_mode; + + /* for rparen, need to push before */ + if (expr->type == fpet_rparen) { + + FYR_TOKEN_ERROR_CHECK(fyr, expr->fyt, FYEM_PARSE, + fypp->paren_nest_level > 0, err_out, + "Mismatched right parentheses"); + + fypp->paren_nest_level--; + + ret = fy_expr_stack_push(&fypp->operators, expr); + fyr_error_check(fyr, !ret, err_out, "push_operator() failed\n"); + expr = NULL; + + ret = evaluate_new(fypp); + /* evaluate will print diagnostic on error */ + if (ret < 0) + goto err_out; + + } else if (fy_path_expr_type_is_lparen(expr->type)) { + + expr->expr_mode = fypp->expr_mode; + fypp->expr_mode = fyem_scalar; + + fypp->paren_nest_level++; + + /* push the operator */ + ret = fy_expr_stack_push(&fypp->operators, expr); + fyr_error_check(fyr, !ret, err_out, "push_operator() failed\n"); + expr = NULL; + +#ifdef DEBUG_EXPR + if (old_scan_mode != fypp->expr_mode) + fyr_notice(fyr, "expr_mode %s -> %s\n", + fy_expr_mode_txt[old_scan_mode], + fy_expr_mode_txt[fypp->expr_mode]); +#endif + } else { + switch (fypp->expr_mode) { + case fyem_none: + assert(0); /* should never happen */ + break; + + case fyem_path: + if (fy_path_expr_type_is_conditional(expr->type)) { + /* switch to scalar mode */ + fypp->expr_mode = fyem_scalar; + break; + } + break; + case fyem_scalar: + if (expr->type == fpet_root) { + fypp->expr_mode = fyem_path; + break; + } + + /* div out of parentheses, it's a chain */ + if (expr->type == fpet_div && fypp->paren_nest_level == 0) { + expr->type = fpet_chain; + fypp->expr_mode = fyem_path; + + /* mode change means evaluate */ + ret = evaluate_new(fypp); + /* evaluate will print diagnostic on error */ + if (ret < 0) + goto err_out; + + break; + } + break; + } + + if (old_scan_mode != fypp->expr_mode) { +#ifdef DEBUG_EXPR + fyr_notice(fyr, "expr_mode %s -> %s\n", + fy_expr_mode_txt[old_scan_mode], + fy_expr_mode_txt[fypp->expr_mode]); +#endif + } + + ret = -1; + while ((expr_top = fy_expr_stack_peek(&fypp->operators)) != NULL && + fy_path_expr_type_prec(expr->type) <= fy_path_expr_type_prec(expr_top->type) && + !fy_path_expr_type_is_lparen(expr_top->type)) { + + ret = evaluate_new(fypp); + /* evaluate will print diagnostic on error */ + if (ret < 0) + goto err_out; + } + + /* push the operator */ + ret = fy_expr_stack_push(&fypp->operators, expr); + fyr_error_check(fyr, !ret, err_out, "push_operator() failed\n"); + expr = NULL; + } + +#ifdef DEBUG_EXPR + fy_notice(fypp->cfg.diag, "operator stack (after)\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operators); + fy_notice(fypp->cfg.diag, "operand stack (after)\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operands); +#endif + + prev_scan_mode = fypp->expr_mode; + } + + if (fypp->stream_error) + goto err_out; + + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_PARSE, + fypp->stream_error || (fyt && fyt->type == FYTT_STREAM_END), err_out, + "stream ended without STREAM_END"); + + /* remove stream end */ + fy_token_unref(fy_path_scan_remove(fypp, fyt)); + fyt = NULL; + +#if 0 + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_PARSE, + fypp->paren_nest_level == 0, err_out, + "Missing right parenthesis"); +#endif + + /* drain */ + while ((expr_top = fy_expr_stack_peek(&fypp->operators)) != NULL && + !fy_path_expr_type_is_lparen(expr_top->type)) { + + ret = evaluate_new(fypp); + /* evaluate will print diagnostic on error */ + if (ret < 0) + goto err_out; + + } + +#ifdef DEBUG_EXPR + expr_top = fy_expr_stack_peek(&fypp->operators); + if (expr_top) + fy_path_expr_dump(expr_top, fypp->cfg.diag, FYET_NOTICE, 0, "operator top left"); +#endif + + expr = fy_expr_stack_pop(&fypp->operands); + + FYR_PARSE_ERROR_CHECK(fyr, 0, 1, FYEM_PARSE, + expr != NULL, err_out, + "No operands left on operand stack"); + + FYR_TOKEN_ERROR_CHECK(fyr, expr->fyt, FYEM_PARSE, + fy_expr_stack_size(&fypp->operands) == 0, err_out, + "Operand stack contains more than 1 value at end"); + + /* check the expression for validity */ + rc = fy_path_check_expression(fypp, expr); + if (rc) { + fy_path_expr_free(expr); + expr = NULL; + } + + return expr; + +err_out: +#ifdef DEBUG_EXPR + fy_notice(fypp->cfg.diag, "operator stack (error)\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operators); + fy_notice(fypp->cfg.diag, "operand stack (error)\n"); + fy_expr_stack_dump(fypp->cfg.diag, &fypp->operands); +#endif + fypp->stream_error = true; + return NULL; +} + +static struct fy_node * +fy_path_expr_execute_single_result(struct fy_diag *diag, struct fy_path_expr *expr, struct fy_node *fyn) +{ + struct fy_token *fyt; + struct fy_anchor *fya; + const char *text; + size_t len; + + assert(expr); + + switch (expr->type) { + case fpet_root: + return fyn->fyd->root; + + case fpet_this: + if (fy_node_is_alias(fyn)) { + // fprintf(stderr, "%s:%d %s calling fy_node_alias_resolve_by_ypath()\n", __func__, __LINE__, fy_node_get_path_alloca(fyn)); + fyn = fy_node_alias_resolve_by_ypath(fyn); + } + + return fyn; + + case fpet_parent: + return fy_node_get_parent(fyn); + + case fpet_alias: + fyt = expr->fyt; + assert(fyt); + assert(fyt->type == FYTT_PE_ALIAS); + + text = fy_token_get_text(fyt, &len); + if (!text || len < 1) + break; + + if (*text == '*') { + text++; + len--; + } + fya = fy_document_lookup_anchor(fyn->fyd, text, len); + if (!fya) + break; + return fya->fyn; + + case fpet_seq_index: + fyt = expr->fyt; + assert(fyt); + assert(fyt->type == FYTT_PE_SEQ_INDEX); + + if (fy_node_is_alias(fyn)) { + // fprintf(stderr, "%s:%d %s calling fy_node_alias_resolve_by_ypath()\n", __func__, __LINE__, fy_node_get_path_alloca(fyn)); + fyn = fy_node_alias_resolve_by_ypath(fyn); + } + + /* only on sequence */ + if (!fy_node_is_sequence(fyn)) + break; + + return fy_node_sequence_get_by_index(fyn, fyt->seq_index.index); + + case fpet_map_key: + fyt = expr->fyt; + assert(fyt); + assert(fyt->type == FYTT_PE_MAP_KEY); + + if (fy_node_is_alias(fyn)) { + // fprintf(stderr, "%s:%d %s calling fy_node_alias_resolve_by_ypath()\n", __func__, __LINE__, fy_node_get_path_alloca(fyn)); + fyn = fy_node_alias_resolve_by_ypath(fyn); + } + + if (!fy_node_is_mapping(fyn)) + break; + + if (!fyt->map_key.fyd) { + /* simple key */ + text = fy_token_get_text(fyt, &len); + if (!text || len < 1) + break; + return fy_node_mapping_lookup_value_by_simple_key(fyn, text, len); + } + + return fy_node_mapping_lookup_value_by_key(fyn, fyt->map_key.fyd->root); + + case fpet_filter_scalar: + if (!(fy_node_is_scalar(fyn) || fy_node_is_alias(fyn))) + break; + return fyn; + + case fpet_filter_collection: + + if (fy_node_is_alias(fyn)) { + // fprintf(stderr, "%s:%d %s calling fy_node_alias_resolve_by_ypath()\n", __func__, __LINE__, fy_node_get_path_alloca(fyn)); + fyn = fy_node_alias_resolve_by_ypath(fyn); + } + + if (!(fy_node_is_mapping(fyn) || fy_node_is_sequence(fyn))) + break; + return fyn; + + case fpet_filter_sequence: + + if (fy_node_is_alias(fyn)) { + // fprintf(stderr, "%s:%d %s calling fy_node_alias_resolve_by_ypath()\n", __func__, __LINE__, fy_node_get_path_alloca(fyn)); + fyn = fy_node_alias_resolve_by_ypath(fyn); + } + + if (!fy_node_is_sequence(fyn)) + break; + return fyn; + + case fpet_filter_mapping: + + if (fy_node_is_alias(fyn)) { + // fprintf(stderr, "%s:%d %s calling fy_node_alias_resolve_by_ypath()\n", __func__, __LINE__, fy_node_get_path_alloca(fyn)); + fyn = fy_node_alias_resolve_by_ypath(fyn); + } + + if (!fy_node_is_mapping(fyn)) + break; + return fyn; + + default: + break; + } + + return NULL; +} + +static double +token_number(struct fy_token *fyt) +{ + const char *value; + + if (!fyt || fyt->type != FYTT_SCALAR || (value = fy_token_get_text0(fyt)) == NULL) + return NAN; + return strtod(value, NULL); +} + +void fy_path_exec_cleanup(struct fy_path_exec *fypx) +{ + if (!fypx) + return; + + fy_walk_result_free(fypx->result); + fypx->result = NULL; + fypx->fyn_start = NULL; +} + +/* publicly exported methods */ +struct fy_path_parser *fy_path_parser_create(const struct fy_path_parse_cfg *pcfg) +{ + struct fy_path_parser *fypp; + + fypp = malloc(sizeof(*fypp)); + if (!fypp) + return NULL; + fy_path_parser_setup(fypp, pcfg); + return fypp; +} + +void fy_path_parser_destroy(struct fy_path_parser *fypp) +{ + if (!fypp) + return; + fy_path_parser_cleanup(fypp); + free(fypp); +} + +int fy_path_parser_reset(struct fy_path_parser *fypp) +{ + if (!fypp) + return -1; + fy_path_parser_cleanup(fypp); + return 0; +} + +struct fy_path_expr * +fy_path_parse_expr_from_string(struct fy_path_parser *fypp, + const char *str, size_t len) +{ + struct fy_path_expr *expr = NULL; + struct fy_input *fyi = NULL; + int rc; + + if (!fypp || !str || !len) + return NULL; + + fy_path_parser_reset(fypp); + + fyi = fy_input_from_data(str, len, NULL, false); + if (!fyi) { + fy_error(fypp->cfg.diag, "failed to create ypath input from %.*s\n", + (int)len, str); + goto err_out; + } + + rc = fy_path_parser_open(fypp, fyi, NULL); + if (rc) { + fy_error(fypp->cfg.diag, "failed to open path parser input from %.*s\n", + (int)len, str); + goto err_out; + } + + expr = fy_path_parse_expression(fypp); + if (!expr) { + fy_error(fypp->cfg.diag, "failed to parse path expression %.*s\n", + (int)len, str); + goto err_out; + } + + fy_path_parser_close(fypp); + + fy_input_unref(fyi); + + return expr; + +err_out: + fy_path_expr_free(expr); + fy_path_parser_close(fypp); + fy_input_unref(fyi); + return NULL; +} + +struct fy_path_expr * +fy_path_expr_build_from_string(const struct fy_path_parse_cfg *pcfg, + const char *str, size_t len) +{ + struct fy_path_parser fypp_data, *fypp = &fypp_data; + struct fy_path_expr *expr = NULL; + + if (!str) + return NULL; + + fy_path_parser_setup(fypp, pcfg); + expr = fy_path_parse_expr_from_string(fypp, str, len); + fy_path_parser_cleanup(fypp); + + return expr; +} + +struct fy_path_exec *fy_path_exec_create(const struct fy_path_exec_cfg *xcfg) +{ + struct fy_path_exec *fypx; + + fypx = malloc(sizeof(*fypx)); + if (!fypx) + return NULL; + + memset(fypx, 0, sizeof(*fypx)); + if (xcfg) + fypx->cfg = *xcfg; + fypx->fwr_recycle = NULL; /* initially no recycling list */ + fypx->refs = 1; + + fypx->supress_recycling = !!(fypx->cfg.flags & FYPXCF_DISABLE_RECYCLING) || + (getenv("FY_VALGRIND") && + !getenv("FY_VALGRIND_RECYCLING")); + return fypx; +} + +struct fy_path_exec *fy_path_exec_create_on_document(struct fy_document *fyd) +{ + struct fy_path_exec_cfg xcfg_local, *xcfg = &xcfg_local; + struct fy_path_exec *fypx; + + memset(xcfg, 0, sizeof(*xcfg)); + xcfg->diag = fyd ? fyd->diag : NULL; + + xcfg->flags = (fyd->parse_cfg.flags & FYPCF_DISABLE_RECYCLING) ? + FYPXCF_DISABLE_RECYCLING : 0; + + fypx = fy_path_exec_create(xcfg); + if (!fypx) + return NULL; + return fypx; +} + +void fy_path_exec_destroy(struct fy_path_exec *fypx) +{ + if (!fypx) + return; + fy_path_exec_cleanup(fypx); + free(fypx); +} + +int fy_path_exec_reset(struct fy_path_exec *fypx) +{ + if (!fypx) + return -1; + fy_path_exec_cleanup(fypx); + return 0; +} + +struct fy_walk_result *fy_walk_result_simplify(struct fy_walk_result *fwr) +{ + struct fy_walk_result *fwr2; +#if 0 + struct fy_walk_result *fwrf; + bool recursive; +#endif + + /* no fwr */ + if (!fwr) + return NULL; + + /* non recursive */ + if (fwr->type != fwrt_refs) + return fwr; + + /* refs, if empty, return NULL */ + if (fy_walk_result_list_empty(&fwr->refs)) { + fy_walk_result_free(fwr); + return NULL; + } + + /* single element, switch it out */ + if (fy_walk_result_list_is_singular(&fwr->refs)) { + fwr2 = fy_walk_result_list_pop(&fwr->refs); + assert(fwr2); + + fy_walk_result_free(fwr); + fwr = fwr2; + } + + return fwr; +#if 0 + /* non recursive return immediately */ + if (fwr->type != fwrt_refs) + return fwr; + + /* flatten if recursive */ + recursive = false; + for (fwr2 = fy_walk_result_list_head(&fwr->refs); fwr2; + fwr2 = fy_walk_result_next(&fwr->refs, fwr2)) { + + /* refs, recursive */ + if (fwr2->type == fwrt_refs) { + recursive = true; + break; + } + } + + if (!recursive) + return fwr; + + fwrf = fy_path_exec_walk_result_create(fypx, fwrt_refs); + assert(fwrf); + + fy_walk_result_flatten_internal(fwr, fwrf); + + fy_walk_result_free(fwr); + return fwrf; +#endif + +} + +int fy_walk_result_all_children_recursive_internal(struct fy_path_exec *fypx, struct fy_node *fyn, struct fy_walk_result *output) +{ + struct fy_node *fyni; + struct fy_walk_result *fwr; + void *prevp; + int ret; + + if (!fyn) + return 0; + + assert(output); + assert(output->type == fwrt_refs); + + /* this node */ + fwr = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fyn); + if (!fwr) + return -1; + fy_walk_result_list_add_tail(&output->refs, fwr); + + if (fy_node_is_scalar(fyn)) + return 0; + + prevp = NULL; + while ((fyni = fy_node_collection_iterate(fyn, &prevp)) != NULL) { + ret = fy_walk_result_all_children_recursive_internal(fypx, fyni, output); + if (ret) + return ret; + } + + return 0; +} + +bool +fy_walk_result_compare_simple(struct fy_path_exec *fypx, enum fy_path_expr_type type, + struct fy_walk_result *fwrl, struct fy_walk_result *fwrr) +{ + struct fy_token *fyt; + struct fy_walk_result *fwrt; + const char *str; + bool match; + + /* both NULL */ + if (!fwrl && !fwrr) { + switch (type) { + case fpet_eq: + return true; + default: + break; + } + return false; + } + + /* any NULL */ + if (!fwrl || !fwrr) { + switch (type) { + case fpet_neq: + return true; + default: + break; + } + return false; + } + + /* both are non NULL */ + + /* none should be multiple */ + assert(fwrl->type != fwrt_refs && fwrr->type != fwrt_refs); + + /* both are the same type */ + if (fwrl->type == fwrr->type) { + + switch (fwrl->type) { + case fwrt_none: + abort(); /* should never happen */ + break; + + case fwrt_node_ref: + switch (type) { + case fpet_eq: + /* simple and fast direct node comparison */ + if (fwrl->fyn == fwrr->fyn) + return true; + return fy_node_compare(fwrl->fyn, fwrr->fyn); + case fpet_neq: + /* simple and fast direct node comparison */ + if (fwrl->fyn != fwrr->fyn) + return true; + return !fy_node_compare(fwrl->fyn, fwrr->fyn); + default: + break; + } + break; + + case fwrt_refs: + assert(0); /* should not get here */ + break; + + case fwrt_doc: + switch (type) { + case fpet_eq: + case fpet_neq: + match = false; + if (fwrl->fyd == fwrr->fyd) + match = true; + else if (!fwrl->fyd || !fwrr->fyd) + match = false; + else + match = fy_node_compare(fwrl->fyd->root, fwrr->fyd->root); + if (type == fpet_neq) + match = !match; + return match; + default: + break; + } + break; + + case fwrt_number: + switch (type) { + case fpet_eq: + return fwrl->number == fwrr->number; + case fpet_neq: + return fwrl->number != fwrr->number; + case fpet_lt: + return fwrl->number < fwrr->number; + case fpet_gt: + return fwrl->number > fwrr->number; + case fpet_lte: + return fwrl->number <= fwrr->number; + case fpet_gte: + return fwrl->number >= fwrr->number; + default: + break; + } + break; + + case fwrt_string: + switch (type) { + case fpet_eq: + return strcmp(fwrl->string, fwrr->string) == 0; + case fpet_neq: + return strcmp(fwrl->string, fwrr->string) != 0; + case fpet_lt: + return strcmp(fwrl->string, fwrr->string) < 0; + case fpet_gt: + return strcmp(fwrl->string, fwrr->string) > 0; + case fpet_lte: + return strcmp(fwrl->string, fwrr->string) <= 0; + case fpet_gte: + return strcmp(fwrl->string, fwrr->string) >= 0; + default: + break; + } + break; + } + return false; + } + + /* only handle the node refs at the left */ + if (fwrr->type == fwrt_node_ref) { + switch (type) { + case fpet_lt: + type = fpet_gte; + break; + case fpet_gt: + type = fpet_lte; + break; + case fpet_lte: + type = fpet_gt; + break; + case fpet_gte: + type = fpet_lt; + break; + default: + break; + } + + /* swap left with right */ + return fy_walk_result_compare_simple(fypx, type, fwrr, fwrl); + } + + switch (fwrl->type) { + case fwrt_node_ref: + + /* non scalar mode, only returns true for non-eq */ + if (!fy_node_is_scalar(fwrl->fyn)) { + /* XXX case of rhs being a document not handled */ + return type == fpet_neq; + } + + fyt = fy_node_get_scalar_token(fwrl->fyn); + assert(fyt); + + str = fy_token_get_text0(fyt); + assert(str); + + fwrt = NULL; + /* node ref against */ + switch (fwrr->type) { + case fwrt_string: + /* create a new temporary walk result */ + fwrt = fy_path_exec_walk_result_create(fypx, fwrt_string, str); + assert(fwrt); + + break; + + case fwrt_number: + /* if it's not a number return true only for non-eq */ + if (!fy_token_is_number(fyt)) + return type == fpet_neq; + + /* create a new temporary walk result */ + fwrt = fy_path_exec_walk_result_create(fypx, fwrt_number, strtod(str, NULL)); + assert(fwrt); + break; + + default: + break; + } + + if (!fwrt) + return false; + + match = fy_walk_result_compare_simple(fypx, type, fwrt, fwrr); + + /* free the temporary result */ + fy_walk_result_free(fwrt); + + return match; + + default: + break; + } + + return false; +} + +struct fy_walk_result * +fy_walk_result_arithmetic_simple(struct fy_path_exec *fypx, + struct fy_path_expr *expr, + struct fy_path_expr *exprl, struct fy_walk_result *fwrl, + struct fy_path_expr *exprr, struct fy_walk_result *fwrr) +{ + struct fy_diag *diag; + struct fy_walk_result *output = NULL; + char *str; + size_t len, len1, len2; + + if (!fwrl || !fwrr) + goto out; + + diag = fypx->cfg.diag; + + /* node refs are not handled yet */ + if (fwrl->type == fwrt_node_ref || fwrr->type == fwrt_node_ref) + goto out; + + /* same type */ + if (fwrl->type == fwrr->type) { + + switch (fwrl->type) { + + case fwrt_string: + /* for strings, only concatenation */ + if (expr->type != fpet_plus) + break; + len1 = strlen(fwrl->string); + len2 = strlen(fwrr->string); + len = len1 + len2; + str = malloc(len + 1); + assert(str); + memcpy(str, fwrl->string, len1); + memcpy(str + len1, fwrr->string, len2); + str[len] = '\0'; + + free(fwrl->string); + fwrl->string = str; + + /* reuse */ + output = fwrl; + fwrl = NULL; + + break; + + case fwrt_number: + /* reuse fwrl */ + output = fwrl; + switch (expr->type) { + case fpet_plus: + output->number = fwrl->number + fwrr->number; + break; + case fpet_minus: + output->number = fwrl->number - fwrr->number; + break; + case fpet_mult: + output->number = fwrl->number * fwrr->number; + break; + case fpet_div: + output->number = fwrr->number ? (fwrl->number / fwrr->number) : INFINITY; + break; + default: + assert(0); + break; + } + fwrl = NULL; + break; + + default: + fy_error(diag, "fwrl->type=%s\n", fy_walk_result_type_txt[fwrl->type]); + assert(0); + break; + } + } + +out: + fy_walk_result_free(fwrl); + fy_walk_result_free(fwrr); + return output; +} + +struct fy_walk_result * +fy_walk_result_conditional_simple(struct fy_path_exec *fypx, + struct fy_path_expr *expr, + struct fy_path_expr *exprl, struct fy_walk_result *fwrl, + struct fy_path_expr *exprr, struct fy_walk_result *fwrr) +{ + bool match; + + match = fy_walk_result_compare_simple(fypx, expr->type, fwrl, fwrr); + + if (!match) { + fy_walk_result_free(fwrl); + fy_walk_result_free(fwrr); + return NULL; + } + + /* path expr, return left hand side result */ + fy_walk_result_free(fwrr); + return fwrl; +} + +struct fy_walk_result * +fy_walk_result_lhs_rhs(struct fy_path_exec *fypx, + struct fy_path_expr *expr, + struct fy_path_expr *exprl, struct fy_walk_result *fwrl, + struct fy_path_expr *exprr, struct fy_walk_result *fwrr) +{ + struct fy_walk_result *output = NULL, *fwr, *fwrrt, *fwrlt, *fwrlc, *fwrrc; + struct fy_walk_result *outputl = NULL, *outputr = NULL; + + assert(expr); + assert(exprl); + assert(exprr); + + /* only supports those */ + if (!fy_path_expr_type_is_conditional(expr->type) && + !fy_path_expr_type_is_arithmetic(expr->type)) + goto out; + + /* both NULL */ + if (!fwrl && !fwrr) + goto out; + + /* any NULL */ + if (!fwrl || !fwrr) { + if (expr->type == fpet_neq) { + output = fwrl; + fwrl = NULL; + } + goto out; + } + + output = fy_path_exec_walk_result_create(fypx, fwrt_refs); + assert(output); + + for (fwrlt = fy_walk_result_iter_start(fwrl); fwrlt; + fwrlt = fy_walk_result_iter_next(fwrl, fwrlt)) { + + /* for recursive ones */ + if (fwrlt->type == fwrt_refs) { + + fwrlc = fy_walk_result_clone(fwrlt); + assert(fwrlc); + fwrrc = fy_walk_result_clone(fwrr); + assert(fwrrc); + + outputl = fy_walk_result_lhs_rhs(fypx, expr, exprl, fwrlc, exprr, fwrrc); + if (outputl) + fy_walk_result_list_add_tail(&output->refs, outputl); + else + fy_walk_result_free(outputl); + continue; + } + + /* non-recursive case */ + for (fwrrt = fy_walk_result_iter_start(fwrr); fwrrt; + fwrrt = fy_walk_result_iter_next(fwrr, fwrrt)) { + + /* for recursive ones */ + if (fwrrt->type == fwrt_refs) { + + fwrlc = fy_walk_result_clone(fwrlt); + assert(fwrlc); + fwrrc = fy_walk_result_clone(fwrrt); + assert(fwrrc); + + outputr = fy_walk_result_lhs_rhs(fypx, expr, exprl, fwrlc, exprr, fwrrc); + if (outputr) + fy_walk_result_list_add_tail(&output->refs, outputr); + else + fy_walk_result_free(outputr); + continue; + } + + + fwrlc = fy_walk_result_clone(fwrlt); + assert(fwrlc); + fwrrc = fy_walk_result_clone(fwrrt); + assert(fwrrc); + + fwr = NULL; + + if (fy_path_expr_type_is_conditional(expr->type)) + fwr = fy_walk_result_conditional_simple(fypx, expr, exprl, fwrlc, exprr, fwrrc); + else if (fy_path_expr_type_is_arithmetic(expr->type)) + fwr = fy_walk_result_arithmetic_simple(fypx, expr, exprl, fwrlc, exprr, fwrrc); + else { + assert(0); + } + + fwrlc = NULL; + fwrrc = NULL; + + if (fwr) + fy_walk_result_list_add_tail(&output->refs, fwr); + } + } + +out: + fy_walk_result_free(fwrl); + fy_walk_result_free(fwrr); + + return fy_walk_result_simplify(output); +} + +struct fy_path_expr * +fy_scalar_walk_result_to_expr(struct fy_path_exec *fypx, struct fy_walk_result *fwr, enum fy_path_expr_type ptype) +{ + struct fy_input *fyit = NULL; + struct fy_path_expr *exprt = NULL; + struct fy_atom handle; + bool collection_addressing; + char *buf; + int rc __FY_DEBUG_UNUSED__; + + exprt = NULL; + + if (!fwr) + return NULL; + + collection_addressing = ptype == fpet_chain || ptype == fpet_multi; + + switch (fwr->type) { + case fwrt_string: + fyit = fy_input_from_malloc_data(fwr->string, FY_NT, &handle, true); + assert(fyit); + + fwr->string = NULL; + fy_walk_result_free(fwr); + fwr = NULL; + + exprt = fy_path_expr_alloc(); + assert(exprt); + if (collection_addressing) { + exprt->type = fpet_map_key; + exprt->fyt = fy_token_create(FYTT_PE_MAP_KEY, &handle, NULL); + assert(exprt->fyt); + } else { + exprt->type = fpet_scalar; + exprt->fyt = fy_token_create(FYTT_SCALAR, &handle, FYSS_PLAIN, NULL); + assert(exprt->fyt); + } + break; + + case fwrt_number: + + rc = asprintf(&buf, "%d", (int)fwr->number); + assert(rc != -1); + + fyit = fy_input_from_malloc_data(buf, FY_NT, &handle, true); + assert(fyit); + + exprt = fy_path_expr_alloc(); + assert(exprt); + if (collection_addressing) { + exprt->type = fpet_seq_index; + exprt->fyt = fy_token_create(FYTT_PE_SEQ_INDEX, &handle, (int)fwr->number); + assert(exprt->fyt); + } else { + exprt->type = fpet_scalar; + exprt->fyt = fy_token_create(FYTT_SCALAR, &handle, FYSS_PLAIN, NULL); + assert(exprt->fyt); + } + + break; + + default: + break; + } + + fy_walk_result_free(fwr); + fy_input_unref(fyit); + + return exprt; +} + +struct fy_walk_result * +fy_path_expr_execute(struct fy_path_exec *fypx, int level, struct fy_path_expr *expr, + struct fy_walk_result *input, enum fy_path_expr_type ptype) +{ + struct fy_diag *diag; + struct fy_walk_result *fwr, *fwrn, *fwrt, *fwrtn; + struct fy_walk_result *output = NULL, *input1, *output1, *input2, *output2; + struct fy_path_expr *exprn, *exprl, *exprr; + struct fy_node *fyn, *fynn, *fyni; + struct fy_token *fyt; + int start, end, count, i; + bool match; + struct fy_path_expr *exprt; + unsigned int nargs; + struct fy_walk_result **fwr_args; + void *prevp; + int rc __FY_DEBUG_UNUSED__; + + /* error */ + if (!fypx || !expr) + goto out; + + diag = fypx->cfg.diag; + +#ifdef DEBUG_EXPR + if (input) + fy_walk_result_dump(input, diag, FYET_NOTICE, level, "input %s\n", fy_path_expr_type_txt[expr->type]); +#endif + + /* recursive */ + if (input && input->type == fwrt_refs && !fy_path_expr_type_handles_refs(expr->type)) { + + output = fy_path_exec_walk_result_create(fypx, fwrt_refs); + assert(output); + + while ((fwr = fy_walk_result_list_pop(&input->refs)) != NULL) { + + fwrn = fy_path_expr_execute(fypx, level + 1, expr, fwr, ptype); + if (fwrn) + fy_walk_result_list_add_tail(&output->refs, fwrn); + } + fy_walk_result_free(input); + input = NULL; + goto out; + } + + + /* single result case is common enough to optimize */ + if (fy_path_expr_type_is_single_result(expr->type)) { + + if (input && input->type == fwrt_node_ref) { + + fynn = fy_path_expr_execute_single_result(diag, expr, input->fyn); + if (!fynn) + goto out; + + fy_walk_result_clean(input); + output = input; + output->type = fwrt_node_ref; + output->fyn = fynn; + input = NULL; + } + + goto out; + } + + /* handle the remaining multi result cases */ + switch (expr->type) { + + case fpet_chain: + + if (!input) + goto out; + + /* iterate over each chain item */ + output = input; + input = NULL; + for (exprn = fy_path_expr_list_head(&expr->children); exprn; + exprn = fy_path_expr_next(&expr->children, exprn)) { + + output = fy_path_expr_execute(fypx, level + 1, exprn, output, expr->type); + if (!output) + break; + } + + break; + + case fpet_multi: + + if (!input) + goto out; + + /* allocate a refs output result */ + output = fy_path_exec_walk_result_create(fypx, fwrt_refs); + assert(output); + + /* iterate over each multi item */ + for (exprn = fy_path_expr_list_head(&expr->children); exprn; + exprn = fy_path_expr_next(&expr->children, exprn)) { + + input2 = fy_walk_result_clone(input); + assert(input2); + + output2 = fy_path_expr_execute(fypx, level + 1, exprn, input2, expr->type); + if (!output2) + continue; + + fy_walk_result_list_add_tail(&output->refs, output2); + } + fy_walk_result_free(input); + input = NULL; + break; + + case fpet_every_child: + + if (!input) + goto out; + + /* only valid for node ref */ + if (input->type != fwrt_node_ref) + break; + + fyn = input->fyn; + + /* every scalar/alias is a single result (although it should not happen) */ + if (fy_node_is_scalar(fyn) || fy_node_is_alias(fyn)) { + output = input; + input = NULL; + break; + + } + + /* re-use input for output root */ + fy_walk_result_clean(input); + output = input; + input = NULL; + + output->type = fwrt_refs; + fy_walk_result_list_init(&output->refs); + + prevp = NULL; + while ((fyni = fy_node_collection_iterate(fyn, &prevp)) != NULL) { + fwr = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fyni); + assert(fwr); + + fy_walk_result_list_add_tail(&output->refs, fwr); + } + + break; + + case fpet_every_child_r: + + if (!input) + goto out; + + /* only valid for node ref */ + if (input->type != fwrt_node_ref) + break; + + fyn = input->fyn; + + /* re-use input for output root */ + fy_walk_result_clean(input); + output = input; + input = NULL; + + output->type = fwrt_refs; + fy_walk_result_list_init(&output->refs); + + rc = fy_walk_result_all_children_recursive_internal(fypx, fyn, output); + assert(!rc); + + break; + + case fpet_seq_slice: + + if (!input) + goto out; + + /* only valid for node ref on a sequence */ + if (input->type != fwrt_node_ref || !fy_node_is_sequence(input->fyn)) { + break; + } + fyn = input->fyn; + + fyt = expr->fyt; + assert(fyt); + assert(fyt->type == FYTT_PE_SEQ_SLICE); + + start = fyt->seq_slice.start_index; + end = fyt->seq_slice.end_index; + count = fy_node_sequence_item_count(fyn); + + /* don't handle negative slices yet */ + if (start < 0 || end < 1 || start >= end) + break; + + if (count < end) + end = count; + + /* re-use input for output root */ + fy_walk_result_clean(input); + output = input; + input = NULL; + + output->type = fwrt_refs; + fy_walk_result_list_init(&output->refs); + + for (i = start; i < end; i++) { + + fynn = fy_node_sequence_get_by_index(fyn, i); + if (!fynn) + continue; + + fwr = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fynn); + assert(fwr); + + fy_walk_result_list_add_tail(&output->refs, fwr); + } + + break; + + case fpet_eq: + case fpet_neq: + case fpet_lt: + case fpet_gt: + case fpet_lte: + case fpet_gte: + case fpet_plus: + case fpet_minus: + case fpet_mult: + case fpet_div: + + exprl = fy_path_expr_lhs(expr); + assert(exprl); + + exprr = fy_path_expr_rhs(expr); + assert(exprr); + + if (input) { + input1 = fy_walk_result_clone(input); + assert(input1); + + input2 = input; + input = NULL; + + } else { + input1 = NULL; + input2 = NULL; + } + + /* execute LHS and RHS */ + output1 = fy_path_expr_execute(fypx, level + 1, exprl, input1, expr->type); + output2 = fy_path_expr_execute(fypx, level + 1, exprr, input2, expr->type); + + output = fy_walk_result_lhs_rhs(fypx, expr, exprl, output1, exprr, output2); + + break; + + case fpet_scalar: + + /* duck typing! */ + if (fy_token_is_number(expr->fyt)) { + output = fy_path_exec_walk_result_create(fypx, fwrt_number, token_number(expr->fyt)); + assert(output); + } else { + output = fy_path_exec_walk_result_create(fypx, fwrt_string, fy_token_get_text0(expr->fyt)); + assert(output); + } + + fy_walk_result_free(input); + input = NULL; + + break; + + case fpet_logical_or: + + /* return the first that is not NULL */ + for (exprn = fy_path_expr_list_head(&expr->children); exprn; + exprn = fy_path_expr_next(&expr->children, exprn)) { + + if (input) { + input1 = fy_walk_result_clone(input); + assert(input1); + } else { + input1 = NULL; + } + + output = fy_path_expr_execute(fypx, level + 1, exprn, input1, expr->type); + if (output) + break; + } + break; + + case fpet_logical_and: + output = NULL; + + /* return the last that was not NULL */ + for (exprn = fy_path_expr_list_head(&expr->children); exprn; + exprn = fy_path_expr_next(&expr->children, exprn)) { + + if (input) { + input1 = fy_walk_result_clone(input); + assert(input1); + } else { + input1 = NULL; + } + + output1 = fy_path_expr_execute(fypx, level + 1, exprn, input1, expr->type); + if (output1) { + fy_walk_result_free(output); + output = output1; + } else + break; + } + break; + + case fpet_filter_unique: + + if (!input) + goto out; + + /* flatten input */ + input = fy_walk_result_flatten(input); + assert(input); /* must work */ + + /* for non refs, return input */ + if (input->type != fwrt_refs) { + output = input; + input = NULL; + break; + } + + /* remove duplicates filter */ + for (fwr = fy_walk_result_list_head(&input->refs); fwr; + fwr = fy_walk_result_next(&input->refs, fwr)) { + + /* do not check recursively */ + if (fwr->type == fwrt_refs) + continue; + + /* check the entries from this point forward */ + for (fwrt = fy_walk_result_next(&input->refs, fwr); fwrt; fwrt = fwrtn) { + + fwrtn = fy_walk_result_next(&input->refs, fwrt); + + /* do not check recursively (or the same result) */ + if (fwrt->type == fwrt_refs) + continue; + + assert(fwrt != fwr); + + match = fy_walk_result_compare_simple(fypx, fpet_eq, fwr, fwrt); + + if (match) { + fy_walk_result_list_del(&input->refs, fwrt); + fy_walk_result_free(fwrt); + } + } + } + output = input; + input = NULL; + + break; + + case fpet_scalar_expr: + + exprl = fy_path_expr_list_head(&expr->children); + if (!exprl) { + fy_warning(diag, "%s:%d\n", __FILE__, __LINE__); + goto out; + } + + output = fy_path_expr_execute(fypx, level + 1, exprl, NULL, ptype); + if (!output) { + fy_warning(diag, "%s:%d\n", __FILE__, __LINE__); + goto out; + } + + exprt = fy_scalar_walk_result_to_expr(fypx, output, ptype); + output = NULL; + if (!exprt) { + fy_warning(diag, "%s:%d\n", __FILE__, __LINE__); + break; + } + + output = fy_path_expr_execute(fypx, level + 1, exprt, input, ptype); + if (!output) { + fy_warning(diag, "%s:%d\n", __FILE__, __LINE__); + } + input = NULL; + + fy_path_expr_free(exprt); + break; + + case fpet_path_expr: + exprl = fy_path_expr_list_head(&expr->children); + if (!exprl) + goto out; + + output = fy_path_expr_execute(fypx, level + 1, exprl, input, ptype); + input = NULL; + break; + + case fpet_method: + + assert(expr->fym); + + /* execute the arguments */ + nargs = expr->fym->nargs; + if (nargs > 0) { + fwr_args = alloca(sizeof(*fwr_args) * nargs); + memset(fwr_args, 0, sizeof(*fwr_args) * nargs); + for (i = 0, exprt = fy_path_expr_list_head(&expr->children); exprt; + exprt = fy_path_expr_next(&expr->children, exprt), i++) { + + if (input) { + input1 = fy_walk_result_clone(input); + assert(input1); + } else + input1 = NULL; + + fwr_args[i] = fy_path_expr_execute(fypx, level + 1, exprt, input1, expr->type); + } + } else + fwr_args = NULL; + + output = expr->fym->exec(expr->fym, fypx, level + 1, expr, input, fwr_args, nargs); + input = NULL; + + break; + + default: + fy_error(diag, "%s\n", fy_path_expr_type_txt[expr->type]); + assert(0); + break; + } + +out: + fy_walk_result_free(input); + output = fy_walk_result_simplify(output); + +#ifdef DEBUG_EXPR + if (output) + fy_walk_result_dump(output, diag, FYET_NOTICE, level, "output %s\n", fy_path_expr_type_txt[expr->type]); +#endif + return output; +} + +static int fy_path_exec_execute_internal(struct fy_path_exec *fypx, + struct fy_path_expr *expr, struct fy_node *fyn_start) +{ + struct fy_walk_result *fwr; + + if (!fypx || !expr || !fyn_start) + return -1; + + fy_walk_result_free(fypx->result); + fypx->result = NULL; + + fwr = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fyn_start); + assert(fwr); + + fwr = fy_path_expr_execute(fypx, 0, expr, fwr, fpet_none); + if (!fwr) + return 0; + + /* flatten results */ + if (fwr->type == fwrt_refs) { + fwr = fy_walk_result_flatten(fwr); + if (!fwr) + return -1; + } + fypx->result = fwr; + + return 0; +} + +int fy_path_exec_execute(struct fy_path_exec *fypx, struct fy_path_expr *expr, struct fy_node *fyn_start) +{ + if (!fypx || !expr || !fyn_start) + return -1; + + fypx->fyn_start = fyn_start; + return fy_path_exec_execute_internal(fypx, expr, fypx->fyn_start); +} + +struct fy_node * +fy_path_exec_results_iterate(struct fy_path_exec *fypx, void **prevp) +{ + struct fy_walk_result *fwr; + + if (!fypx || !prevp) + return NULL; + + if (!fypx->result) + return NULL; + + if (fypx->result->type != fwrt_refs) { + fwr = fypx->result; + + if (fwr->type != fwrt_node_ref) + return NULL; + + if (!*prevp) { + *prevp = fwr; + return fwr->fyn; + } + *prevp = NULL; + return NULL; + } + + /* loop over non node refs for now */ + do { + if (!*prevp) + fwr = fy_walk_result_list_head(&fypx->result->refs); + else + fwr = fy_walk_result_next(&fypx->result->refs, *prevp); + *prevp = fwr; + } while (fwr && fwr->type != fwrt_node_ref); + + return fwr ? fwr->fyn : NULL; +} + +struct fy_walk_result * +fy_path_exec_take_results(struct fy_path_exec *fypx) +{ + struct fy_walk_result *fwr; + + if (!fypx || !fypx->result) + return NULL; + fwr = fypx->result; + fypx->result = NULL; + return fwr; +} + +struct fy_walk_result * +fy_path_exec_walk_result_vcreate(struct fy_path_exec *fypx, enum fy_walk_result_type type, va_list ap) +{ + struct fy_walk_result_list *fwrl; + + if (!fypx) + return NULL; + + fwrl = fy_path_exec_walk_result_rl(fypx); + return fy_walk_result_vcreate_rl(fwrl, type, ap); +} + +struct fy_walk_result * +fy_path_exec_walk_result_create(struct fy_path_exec *fypx, enum fy_walk_result_type type, ...) +{ + struct fy_walk_result_list *fwrl; + struct fy_walk_result *fwr; + va_list ap; + + if (!fypx) + return NULL; + + fwrl = fy_path_exec_walk_result_rl(fypx); + + va_start(ap, type); + fwr = fy_walk_result_vcreate_rl(fwrl, type, ap); + va_end(ap); + + if (!fwr) + return NULL; + + fwr->fypx = fy_path_exec_ref(fypx); + + return fwr; +} + +void +fy_path_exec_walk_result_free(struct fy_path_exec *fypx, struct fy_walk_result *fwr) +{ + struct fy_walk_result_list *fwrl; + + fwrl = fypx ? fy_path_exec_walk_result_rl(fypx) : NULL; + fy_walk_result_free_rl(fwrl, fwr); +} + +int fy_document_setup_path_expr_data(struct fy_document *fyd) +{ + struct fy_path_parse_cfg pcfg_local, *pcfg = &pcfg_local; + struct fy_path_expr_document_data *pxdd; + + if (!fyd || fyd->pxdd) + return 0; + + pxdd = malloc(sizeof(*pxdd)); + if (!pxdd) + goto err_no_mem; + + memset(pxdd, 0, sizeof(*pxdd)); + + fy_walk_result_list_init(&pxdd->fwr_recycle); + + memset(pcfg, 0, sizeof(*pcfg)); + pcfg->diag = fyd->diag; + pxdd->fypp = fy_path_parser_create(pcfg); + if (!pxdd->fypp) + goto err_no_fypp; + + fyd->pxdd = pxdd; + + return 0; + +err_no_fypp: + free(pxdd); +err_no_mem: + return -1; +} + +void fy_document_cleanup_path_expr_data(struct fy_document *fyd) +{ + struct fy_path_expr_document_data *pxdd; + struct fy_walk_result *fwr; + + if (!fyd || !fyd->pxdd) + return; + + pxdd = fyd->pxdd; + + fy_path_parser_destroy(pxdd->fypp); + + while ((fwr = fy_walk_result_list_pop(&pxdd->fwr_recycle)) != NULL) + free(fwr); + + free(fyd->pxdd); + fyd->pxdd = NULL; +} + +int fy_node_setup_path_expr_data(struct fy_node *fyn) +{ + struct fy_path_expr_document_data *pxdd; + struct fy_path_expr_node_data *pxnd; + const char *text; + size_t len; + char *alloc = NULL; + int rc; + + if (!fyn || fyn->pxnd) + return 0; + + /* only on alias nodes */ + if (!fy_node_is_alias(fyn)) + return 0; + + /* a document must exist */ + if (!fyn->fyd) + return -1; + + if (!fyn->fyd->pxdd) { + rc = fy_document_setup_path_expr_data(fyn->fyd); + if (rc) + return rc; + } + pxdd = fyn->fyd->pxdd; + assert(pxdd); + + pxnd = malloc(sizeof(*pxnd)); + if (!pxnd) + goto err_no_mem; + memset(pxnd, 0, sizeof(*pxnd)); + + text = fy_token_get_text(fyn->scalar, &len); + if (!text) + goto err_no_text; + + if (!fy_is_first_alpha(*text)) { + pxnd->fyi = fy_input_from_data(text, len, NULL, false); + if (!pxnd->fyi) + goto err_no_input; + } else { + alloc = malloc(len + 2); + if (!alloc) + goto err_no_input; + alloc[0] = '*'; + memcpy(alloc + 1, text, len); + alloc[len + 1] = '\0'; + + pxnd->fyi = fy_input_from_malloc_data(alloc, len + 1, NULL, false); + if (!pxnd->fyi) + goto err_no_input; + } + + fy_path_parser_reset(pxdd->fypp); + + rc = fy_path_parser_open(pxdd->fypp, pxnd->fyi, NULL); + if (rc) + goto err_no_open; + + pxnd->expr = fy_path_parse_expression(pxdd->fypp); + if (!pxnd->expr) + goto err_parse; + + fy_path_parser_close(pxdd->fypp); + + fyn->pxnd = pxnd; + + return 0; +err_parse: + fy_path_parser_close(pxdd->fypp); +err_no_open: + fy_input_unref(pxnd->fyi); +err_no_input: + if (alloc) + free(alloc); +err_no_text: + free(pxnd); +err_no_mem: + return -1; +} + +void fy_node_cleanup_path_expr_data(struct fy_node *fyn) +{ + struct fy_path_expr_node_data *pxnd; + + if (!fyn || !fyn->pxnd) + return; + + pxnd = fyn->pxnd; + + if (pxnd->expr) + fy_path_expr_free(pxnd->expr); + + if (pxnd->fyi) + fy_input_unref(pxnd->fyi); + + free(pxnd); + fyn->pxnd = NULL; +} + +struct fy_walk_result * +fy_node_alias_resolve_by_ypath_result(struct fy_node *fyn) +{ + struct fy_document *fyd; + struct fy_path_expr_document_data *pxdd = NULL; + struct fy_path_expr_node_data *pxnd = NULL; + struct fy_walk_result *fwr; + struct fy_anchor *fya; + struct fy_path_exec *fypx = NULL; + int rc; + + if (!fyn || !fy_node_is_alias(fyn)) + return NULL; + + fyd = fyn->fyd; + if (!fyd) + return NULL; + + /* simple */ + fya = fy_document_lookup_anchor_by_token(fyd, fyn->scalar); + if (fya) { + + fwr = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fya->fyn); + fyd_error_check(fyd, fwr, err_out, + "fy_walk_result_alloc_rl() failed"); + + return fwr; + } + + /* ok, complex, setup the node data */ + rc = fy_node_setup_path_expr_data(fyn); + fyd_error_check(fyd, !rc, err_out, + "fy_node_setup_path_expr_data() failed"); + + pxnd = fyn->pxnd; + assert(pxnd); + + pxdd = fyd->pxdd; + assert(pxdd); + + if (pxnd->traversals++ > 0) { + FYD_NODE_ERROR(fyd, fyn, FYEM_DOC, + "recursive reference detected at %s\n", + fy_node_get_path_alloca(fyn)); + pxnd->traversals--; + return NULL; + } + + fypx = fy_path_exec_create_on_document(fyd); + fyd_error_check(fyd, !rc, err_out, + "fy_path_exec_create_on_document() failed"); + + fy_path_exec_set_result_recycle_list(fypx, &pxdd->fwr_recycle); + +#if 0 + { + struct fy_document *fyd_pe; + const char *text; + size_t len; + + text = fy_token_get_text(fyn->scalar, &len); + if (text) { + fyd_pe = fy_path_expr_to_document(pxnd->expr); + if (fyd_pe) { + fprintf(stderr, "%s: %.*s\n", __func__, (int)len, text); + fy_document_default_emit_to_fp(fyd_pe, stderr); + fy_document_destroy(fyd_pe); + } + } + } +#endif + + // fprintf(stderr, "%s: %s 2\n", __func__, fy_node_get_path_alloca(fyn)); + + /* execute, starting at this */ + rc = fy_path_exec_execute(fypx, pxnd->expr, fyn); + fyd_error_check(fyd, !rc, err_out, + "fy_path_exec_execute() failed"); + + // fprintf(stderr, "%s: %s 3\n", __func__, fy_node_get_path_alloca(fyn)); + + fwr = fy_path_exec_take_results(fypx); + + fy_path_exec_unref(fypx); + + pxnd->traversals--; + + if (!fwr) + return NULL; + + // fprintf(stderr, "%s: %s 4\n", __func__, fy_node_get_path_alloca(fyn)); + + return fwr; + +err_out: + if (pxnd) + pxnd->traversals--; + fy_path_exec_unref(fypx); /* NULL OK */ + return NULL; +} + +struct fy_node *fy_node_alias_resolve_by_ypath(struct fy_node *fyn) +{ + struct fy_anchor *fya; + struct fy_walk_result *fwr; + void *iterp; + + if (!fyn || !fy_node_is_alias(fyn)) + return NULL; + + /* simple and common enough to do it now */ + fya = fy_document_lookup_anchor_by_token(fyn->fyd, fyn->scalar); + if (fya) + return fya->fyn; + + fwr = fy_node_alias_resolve_by_ypath_result(fyn); + if (!fwr) + return NULL; + + iterp = NULL; + fyn = fy_walk_result_node_iterate(fwr, &iterp); + + fy_walk_result_free(fwr); + + return fyn; +} + +struct fy_walk_result * +fy_node_by_ypath_result(struct fy_node *fyn, const char *path, size_t len) +{ + struct fy_path_expr_document_data *pxdd; + struct fy_document *fyd; + struct fy_walk_result *fwr; + struct fy_anchor *fya; + struct fy_input *fyi; + struct fy_path_expr *expr; + struct fy_path_exec *fypx = NULL; + int rc; + + if (!fyn || !path || !len) + return NULL; + + fyd = fyn->fyd; + if (!fyd) + return NULL; + + if (len == FY_NT) + len = strlen(path); + + /* simple */ + fya = fy_document_lookup_anchor(fyn->fyd, path, len); + if (fya) { + fwr = fy_path_exec_walk_result_create(fypx, fwrt_node_ref, fya->fyn); + fyd_error_check(fyd, fwr, err_out, + "fy_walk_result_alloc_rl() failed"); + return fwr; + } + + /* ok, complex, setup the document data */ + rc = fy_document_setup_path_expr_data(fyd); + fyd_error_check(fyd, !rc, err_setup, + "fy_node_setup_path_expr_data() failed"); + + pxdd = fyd->pxdd; + assert(pxdd); + + fyi = fy_input_from_data(path, len, NULL, false); + fyd_error_check(fyd, fyi, err_no_input, + "fy_input_from_data() failed"); + + fy_path_parser_reset(pxdd->fypp); + + rc = fy_path_parser_open(pxdd->fypp, fyi, NULL); + fyd_error_check(fyd, !rc, err_no_open, + "fy_path_parser_open() failed"); + + expr = fy_path_parse_expression(pxdd->fypp); + fyd_error_check(fyd, expr, err_parse, + "fy_path_parse_expression() failed"); + + fy_path_parser_close(pxdd->fypp); + + fypx = fy_path_exec_create_on_document(fyd); + fyd_error_check(fyd, !rc, err_no_fypx, + "fy_path_exec_create_on_document() failed"); + + /* execute, starting at this */ + rc = fy_path_exec_execute(fypx, expr, fyn); + fyd_error_check(fyd, !rc, err_exec, + "fy_path_parse_expression() failed"); + + fwr = fy_path_exec_take_results(fypx); + + fy_path_exec_unref(fypx); + + fy_path_expr_free(expr); + fy_input_unref(fyi); + + return fwr; + +err_exec: + fy_path_expr_free(expr); +err_no_fypx: + fy_path_exec_unref(fypx); +err_parse: + fy_path_parser_close(pxdd->fypp); + +err_no_open: + fy_input_unref(fyi); + +err_no_input: +err_setup: +err_out: + return NULL; +} + +struct fy_node *fy_node_by_ypath(struct fy_node *fyn, const char *path, size_t len) +{ + struct fy_walk_result *fwr; + struct fy_anchor *fya; + void *iterp; + + if (!fyn || !path || !len) + return NULL; + + /* simple */ + fya = fy_document_lookup_anchor(fyn->fyd, path, len); + if (fya) + return fya->fyn; + + fwr = fy_node_by_ypath_result(fyn, path, len); + if (!fwr) + return NULL; + + iterp = NULL; + fyn = fy_walk_result_node_iterate(fwr, &iterp); + + fy_walk_result_free(fwr); + + return fyn; +} diff --git a/src/lib/fy-walk.h b/src/lib/fy-walk.h new file mode 100644 index 0000000..e42a76f --- /dev/null +++ b/src/lib/fy-walk.h @@ -0,0 +1,438 @@ +/* + * fy-walk.h - walker internal header file + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ +#ifndef FY_WALK_H +#define FY_WALK_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "fy-ctype.h" +#include "fy-utf8.h" +#include "fy-list.h" +#include "fy-typelist.h" +#include "fy-types.h" +#include "fy-diag.h" +#include "fy-dump.h" +#include "fy-docstate.h" +#include "fy-accel.h" +#include "fy-token.h" + +struct fy_document; + +enum fy_walk_result_type { + fwrt_none, + fwrt_node_ref, + fwrt_number, + fwrt_string, + fwrt_doc, + fwrt_refs, +}; + +#define FWRT_COUNT (fwrt_refs + 1) +extern const char *fy_walk_result_type_txt[FWRT_COUNT]; + +struct fy_path_exec; + +FY_TYPE_FWD_DECL_LIST(walk_result); +struct fy_walk_result { + struct list_head node; + struct fy_path_exec *fypx; + enum fy_walk_result_type type; + union { + struct fy_node *fyn; + double number; + char *string; + struct fy_walk_result_list refs; + struct fy_document *fyd; + }; +}; +FY_TYPE_DECL_LIST(walk_result); + +struct fy_walk_result *fy_walk_result_alloc_rl(struct fy_walk_result_list *fwrl); +void fy_walk_result_free_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result *fwr); +void fy_walk_result_list_free_rl(struct fy_walk_result_list *fwrl, struct fy_walk_result_list *results); + +void fy_walk_result_free(struct fy_walk_result *fwr); + +struct fy_walk_result *fy_walk_result_vcreate_rl(struct fy_walk_result_list *fwrl, enum fy_walk_result_type type, va_list ap); +struct fy_walk_result *fy_walk_result_create_rl(struct fy_walk_result_list *fwrl, enum fy_walk_result_type type, ...); + +static inline struct fy_walk_result * +fy_walk_result_iter_start(struct fy_walk_result *fwr) +{ + struct fy_walk_result *fwri; + + if (!fwr) + return NULL; + if (fwr->type != fwrt_refs) + return fwr; + fwri = fy_walk_result_list_head(&fwr->refs); + if (!fwri) + return NULL; + return fwri; +} + +static inline struct fy_walk_result * +fy_walk_result_iter_next(struct fy_walk_result *fwr, struct fy_walk_result *fwri) +{ + if (!fwr || !fwri || fwr->type != fwrt_refs) + return NULL; + fwri = fy_walk_result_next(&fwr->refs, fwri); + if (!fwri) + return NULL; + return fwri; +} + +struct fy_node * +fy_walk_result_node_iterate(struct fy_walk_result *fwr, void **prevp); + +enum fy_path_expr_type { + fpet_none, + /* ypath */ + fpet_root, /* /^ or / at the beginning of the expr */ + fpet_this, /* /. */ + fpet_parent, /* /.. */ + fpet_every_child, // /* every immediate child + fpet_every_child_r, // /** every recursive child + fpet_filter_collection, /* match only collection (at the end only) */ + fpet_filter_scalar, /* match only scalars (leaves) */ + fpet_filter_sequence, /* match only sequences */ + fpet_filter_mapping, /* match only mappings */ + fpet_filter_unique, /* removes duplicates */ + fpet_seq_index, + fpet_map_key, /* complex map key (quoted, flow seq or map) */ + fpet_seq_slice, + fpet_alias, + + fpet_multi, /* merge results of children */ + fpet_chain, /* children move in sequence */ + fpet_logical_or, /* first non null result set */ + fpet_logical_and, /* the last non null result set */ + + fpet_eq, /* equal expression */ + fpet_neq, /* not equal */ + fpet_lt, /* less than */ + fpet_gt, /* greater than */ + fpet_lte, /* less or equal than */ + fpet_gte, /* greater or equal than */ + + fpet_scalar, /* scalar */ + + fpet_plus, /* add */ + fpet_minus, /* subtract */ + fpet_mult, /* multiply */ + fpet_div, /* divide */ + + fpet_lparen, /* left paren (they do not appear in final expression) */ + fpet_rparen, /* right parent */ + fpet_method, /* method (or parentheses) */ + + fpet_scalar_expr, /* non-eval phase scalar expression */ + fpet_path_expr, /* non-eval phase path expression */ + fpet_arg_separator, /* argument separator (comma in scalar mode) */ +}; + +#define FPET_COUNT (fpet_arg_separator + 1) + +extern const char *path_expr_type_txt[FPET_COUNT]; + +static inline bool fy_path_expr_type_is_valid(enum fy_path_expr_type type) +{ + return type >= fpet_root && type < FPET_COUNT; +} + +static inline bool fy_path_expr_type_is_single_result(enum fy_path_expr_type type) +{ + return type == fpet_root || + type == fpet_this || + type == fpet_parent || + type == fpet_map_key || + type == fpet_seq_index || + type == fpet_alias || + type == fpet_filter_collection || + type == fpet_filter_scalar || + type == fpet_filter_sequence || + type == fpet_filter_mapping; +} + +static inline bool fy_path_expr_type_is_parent(enum fy_path_expr_type type) +{ + return type == fpet_multi || + type == fpet_chain || + type == fpet_logical_or || + type == fpet_logical_and || + type == fpet_eq || + type == fpet_method || + type == fpet_scalar_expr || + type == fpet_path_expr; +} + +static inline bool fy_path_expr_type_is_mergeable(enum fy_path_expr_type type) +{ + return type == fpet_multi || + type == fpet_chain || + type == fpet_logical_or || + type == fpet_logical_and; +} + +/* type handles refs by itself */ +static inline bool fy_path_expr_type_handles_refs(enum fy_path_expr_type type) +{ + return type == fpet_filter_unique || + type == fpet_method; +} + +static inline bool fy_path_expr_type_is_parent_lhs_rhs(enum fy_path_expr_type type) +{ + return type == fpet_eq || + type == fpet_neq || + type == fpet_lt || + type == fpet_gt || + type == fpet_lte || + type == fpet_gte || + + type == fpet_plus || + type == fpet_minus || + type == fpet_mult || + type == fpet_div; +} + +static inline bool +fy_path_expr_type_is_conditional(enum fy_path_expr_type type) +{ + return type == fpet_eq || + type == fpet_neq || + type == fpet_lt || + type == fpet_gt || + type == fpet_lte || + type == fpet_gte; +} + +static inline bool +fy_path_expr_type_is_arithmetic(enum fy_path_expr_type type) +{ + return type == fpet_plus || + type == fpet_minus || + type == fpet_mult || + type == fpet_div; +} + +static inline bool +fy_path_expr_type_is_lparen(enum fy_path_expr_type type) +{ + return type == fpet_lparen /* || + type == fpet_method */ ; +} + +enum fy_expr_mode { + fyem_none, /* invalid mode */ + fyem_path, /* expression is path */ + fyem_scalar, /* expression is scalar */ +}; + +#define FYEM_COUNT (fyem_scalar + 1) + +extern const char *fy_expr_mode_txt[FYEM_COUNT]; + +struct fy_path_expr; + +struct fy_method { + const char *name; + size_t len; + enum fy_expr_mode mode; + unsigned int nargs; + struct fy_walk_result *(*exec)(const struct fy_method *fym, + struct fy_path_exec *fypx, int level, + struct fy_path_expr *expr, + struct fy_walk_result *input, + struct fy_walk_result **args, int nargs); +}; + +FY_TYPE_FWD_DECL_LIST(path_expr); +struct fy_path_expr { + struct list_head node; + struct fy_path_expr *parent; + enum fy_path_expr_type type; + struct fy_token *fyt; + struct fy_path_expr_list children; + enum fy_expr_mode expr_mode; /* for parens */ + const struct fy_method *fym; +}; +FY_TYPE_DECL_LIST(path_expr); + +static inline struct fy_path_expr * +fy_path_expr_lhs(struct fy_path_expr *expr) +{ + if (!expr || !fy_path_expr_type_is_parent_lhs_rhs(expr->type)) + return NULL; + return fy_path_expr_list_head(&expr->children); +} + +static inline struct fy_path_expr * +fy_path_expr_rhs(struct fy_path_expr *expr) +{ + if (!expr || !fy_path_expr_type_is_parent_lhs_rhs(expr->type)) + return NULL; + return fy_path_expr_list_tail(&expr->children); +} + +const struct fy_mark *fy_path_expr_start_mark(struct fy_path_expr *expr); +const struct fy_mark *fy_path_expr_end_mark(struct fy_path_expr *expr); + +struct fy_expr_stack { + unsigned int top; + unsigned int alloc; + struct fy_path_expr **items; + struct fy_path_expr *items_static[32]; +}; + +void fy_expr_stack_setup(struct fy_expr_stack *stack); +void fy_expr_stack_cleanup(struct fy_expr_stack *stack); +void fy_expr_stack_dump(struct fy_diag *diag, struct fy_expr_stack *stack); +int fy_expr_stack_push(struct fy_expr_stack *stack, struct fy_path_expr *expr); +struct fy_path_expr *fy_expr_stack_peek_at(struct fy_expr_stack *stack, unsigned int pos); +struct fy_path_expr *fy_expr_stack_peek(struct fy_expr_stack *stack); +struct fy_path_expr *fy_expr_stack_pop(struct fy_expr_stack *stack); + +struct fy_path_parser { + struct fy_path_parse_cfg cfg; + struct fy_reader reader; + struct fy_token_list queued_tokens; + enum fy_token_type last_queued_token_type; + bool stream_start_produced; + bool stream_end_produced; + bool stream_error; + int token_activity_counter; + + struct fy_input *fyi; + struct fy_expr_stack operators; + struct fy_expr_stack operands; + + /* to avoid allocating */ + struct fy_path_expr_list expr_recycle; + bool suppress_recycling; + + enum fy_expr_mode expr_mode; + int paren_nest_level; + +}; + +struct fy_path_expr *fy_path_expr_alloc(void); +/* fy_path_expr_free is declared in libfyaml.h */ +// void fy_path_expr_free(struct fy_path_expr *expr); + +void fy_path_parser_setup(struct fy_path_parser *fypp, const struct fy_path_parse_cfg *pcfg); +void fy_path_parser_cleanup(struct fy_path_parser *fypp); +int fy_path_parser_open(struct fy_path_parser *fypp, + struct fy_input *fyi, const struct fy_reader_input_cfg *icfg); +void fy_path_parser_close(struct fy_path_parser *fypp); + +struct fy_token *fy_path_scan(struct fy_path_parser *fypp); + +struct fy_path_expr *fy_path_parse_expression(struct fy_path_parser *fypp); + +void fy_path_expr_dump(struct fy_path_expr *expr, struct fy_diag *diag, enum fy_error_type errlevel, int level, const char *banner); + +struct fy_path_exec { + struct fy_path_exec_cfg cfg; + struct fy_node *fyn_start; + struct fy_walk_result *result; + struct fy_walk_result_list *fwr_recycle; + int refs; + bool supress_recycling; +}; + +struct fy_path_exec *fy_path_exec_create(const struct fy_path_exec_cfg *xcfg); +struct fy_path_exec *fy_path_exec_create_on_document(struct fy_document *fyd); +void fy_path_exec_destroy(struct fy_path_exec *fypx); +void fy_path_exec_cleanup(struct fy_path_exec *fypx); + +static inline struct fy_path_exec * +fy_path_exec_ref(struct fy_path_exec *fypx) +{ + /* take care of overflow */ + if (!fypx) + return NULL; + assert(fypx->refs + 1 > 0); + fypx->refs++; + + return fypx; +} + +static inline void +fy_path_exec_unref(struct fy_path_exec *fypx) +{ + if (!fypx) + return; + + assert(fypx->refs > 0); + + if (--fypx->refs == 0) + fy_path_exec_destroy(fypx); +} + +struct fy_walk_result * +fy_path_expr_execute(struct fy_path_exec *fypx, int level, struct fy_path_expr *expr, + struct fy_walk_result *input, enum fy_path_expr_type ptype); + +static inline struct fy_walk_result_list * +fy_path_exec_walk_result_rl(struct fy_path_exec *fypx) +{ + return fypx && !fypx->supress_recycling ? fypx->fwr_recycle : NULL; +} + +static inline void +fy_path_exec_set_result_recycle_list(struct fy_path_exec *fypx, + struct fy_walk_result_list *fwrl) +{ + if (!fypx) + return; + fypx->fwr_recycle = fwrl; +} + +struct fy_walk_result * +fy_path_exec_walk_result_create(struct fy_path_exec *fypx, enum fy_walk_result_type type, ...); + +void +fy_path_exec_walk_result_free(struct fy_path_exec *fypx, struct fy_walk_result *fwr); + +struct fy_path_expr_document_data { + struct fy_path_parser *fypp; + struct fy_walk_result_list fwr_recycle; +}; + +struct fy_path_expr_node_data { + struct fy_input *fyi; + struct fy_path_expr *expr; + struct fy_node *fyn_target; + int traversals; +}; + +int fy_document_setup_path_expr_data(struct fy_document *fyd); +void fy_document_cleanup_path_expr_data(struct fy_document *fyd); +int fy_node_setup_path_expr_data(struct fy_node *fyn); +void fy_node_cleanup_path_expr_data(struct fy_node *fyn); + +struct fy_walk_result * +fy_node_alias_resolve_by_ypath_result(struct fy_node *fyn); +struct fy_node *fy_node_alias_resolve_by_ypath(struct fy_node *fyn); + +struct fy_walk_result * +fy_node_by_ypath_result(struct fy_node *fyn, const char *path, size_t len); +struct fy_node *fy_node_by_ypath(struct fy_node *fyn, const char *path, size_t len); + +#endif diff --git a/src/tool/fy-tool.c b/src/tool/fy-tool.c new file mode 100644 index 0000000..0740acb --- /dev/null +++ b/src/tool/fy-tool.c @@ -0,0 +1,2175 @@ +/* + * fy-tool.c - libfyaml YAML manipulation/dumping utility + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fy-valgrind.h" + +#define QUIET_DEFAULT false +#define INCLUDE_DEFAULT "" +#define DEBUG_LEVEL_DEFAULT 3 +#define COLOR_DEFAULT "auto" +#define INDENT_DEFAULT 2 +#define WIDTH_DEFAULT 80 +#define RESOLVE_DEFAULT false +#define SORT_DEFAULT false +#define COMMENT_DEFAULT false +#define VISIBLE_DEFAULT false +#define MODE_DEFAULT "original" +#define TO_DEFAULT "/" +#define FROM_DEFAULT "/" +#define TRIM_DEFAULT "/" +#define FOLLOW_DEFAULT false +#define STRIP_LABELS_DEFAULT false +#define STRIP_TAGS_DEFAULT false +#define STRIP_DOC_DEFAULT false +#define STREAMING_DEFAULT false +#define JSON_DEFAULT "auto" +#define DISABLE_ACCEL_DEFAULT false +#define DISABLE_BUFFERING_DEFAULT false +#define DISABLE_DEPTH_LIMIT_DEFAULT false +#define SLOPPY_FLOW_INDENTATION_DEFAULT false +#define PREFER_RECURSIVE_DEFAULT false +#define YPATH_ALIASES_DEFAULT false +#define DISABLE_FLOW_MARKERS_DEFAULT false +#define DUMP_PATH_DEFAULT false + +#define OPT_DUMP 1000 +#define OPT_TESTSUITE 1001 +#define OPT_FILTER 1002 +#define OPT_JOIN 1003 +#define OPT_TOOL 1004 +#define OPT_YPATH 1005 +#define OPT_SCAN_DUMP 1006 +#define OPT_PARSE_DUMP 1007 +#define OPT_YAML_VERSION_DUMP 1008 +#define OPT_COMPOSE 1009 + +#define OPT_STRIP_LABELS 2000 +#define OPT_STRIP_TAGS 2001 +#define OPT_STRIP_DOC 2002 +#define OPT_STREAMING 2003 +#define OPT_DISABLE_ACCEL 2005 +#define OPT_DISABLE_BUFFERING 2006 +#define OPT_DISABLE_DEPTH_LIMIT 2007 +#define OPT_SLOPPY_FLOW_INDENTATION 2008 +#define OPT_PREFER_RECURSIVE 2009 +#define OPT_DUMP_PATHEXPR 2010 +#define OPT_NOEXEC 2011 +#define OPT_NULL_OUTPUT 2012 +#define OPT_YPATH_ALIASES 2013 +#define OPT_DISABLE_FLOW_MARKERS 2014 +#define OPT_DUMP_PATH 2015 + +#define OPT_DISABLE_DIAG 3000 +#define OPT_ENABLE_DIAG 3001 +#define OPT_SHOW_DIAG 3002 +#define OPT_HIDE_DIAG 3003 + +#define OPT_YAML_1_1 4000 +#define OPT_YAML_1_2 4001 +#define OPT_YAML_1_3 4002 + +static struct option lopts[] = { + {"include", required_argument, 0, 'I' }, + {"debug-level", required_argument, 0, 'd' }, + {"indent", required_argument, 0, 'i' }, + {"width", required_argument, 0, 'w' }, + {"resolve", no_argument, 0, 'r' }, + {"sort", no_argument, 0, 's' }, + {"comment", no_argument, 0, 'c' }, + {"color", required_argument, 0, 'C' }, + {"visible", no_argument, 0, 'V' }, + {"mode", required_argument, 0, 'm' }, + {"json", required_argument, 0, 'j' }, + {"file", required_argument, 0, 'f' }, + {"trim", required_argument, 0, 't' }, + {"follow", no_argument, 0, 'l' }, + {"dump", no_argument, 0, OPT_DUMP }, + {"testsuite", no_argument, 0, OPT_TESTSUITE }, + {"filter", no_argument, 0, OPT_FILTER }, + {"join", no_argument, 0, OPT_JOIN }, + {"ypath", no_argument, 0, OPT_YPATH }, + {"scan-dump", no_argument, 0, OPT_SCAN_DUMP }, + {"parse-dump", no_argument, 0, OPT_PARSE_DUMP }, + {"compose", no_argument, 0, OPT_COMPOSE }, + {"dump-path", no_argument, 0, OPT_DUMP_PATH }, + {"yaml-version-dump", no_argument, 0, OPT_YAML_VERSION_DUMP }, + {"strip-labels", no_argument, 0, OPT_STRIP_LABELS }, + {"strip-tags", no_argument, 0, OPT_STRIP_TAGS }, + {"strip-doc", no_argument, 0, OPT_STRIP_DOC }, + {"streaming", no_argument, 0, OPT_STREAMING }, + {"disable-accel", no_argument, 0, OPT_DISABLE_ACCEL }, + {"disable-buffering", no_argument, 0, OPT_DISABLE_BUFFERING }, + {"disable-depth-limit", no_argument, 0, OPT_DISABLE_DEPTH_LIMIT }, + {"disable-diag", required_argument, 0, OPT_DISABLE_DIAG }, + {"enable-diag", required_argument, 0, OPT_ENABLE_DIAG }, + {"show-diag", required_argument, 0, OPT_SHOW_DIAG }, + {"hide-diag", required_argument, 0, OPT_HIDE_DIAG }, + {"yaml-1.1", no_argument, 0, OPT_YAML_1_1 }, + {"yaml-1.2", no_argument, 0, OPT_YAML_1_2 }, + {"yaml-1.3", no_argument, 0, OPT_YAML_1_3 }, + {"sloppy-flow-indentation", no_argument, 0, OPT_SLOPPY_FLOW_INDENTATION }, + {"prefer-recursive", no_argument, 0, OPT_PREFER_RECURSIVE }, + {"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 }, + {"noexec", no_argument, 0, OPT_NOEXEC }, + {"null-output", no_argument, 0, OPT_NULL_OUTPUT }, + {"to", required_argument, 0, 'T' }, + {"from", required_argument, 0, 'F' }, + {"quiet", no_argument, 0, 'q' }, + {"help", no_argument, 0, 'h' }, + {"version", no_argument, 0, 'v' }, + {0, 0, 0, 0 }, +}; + +static void display_usage(FILE *fp, char *progname, int tool_mode) +{ + fprintf(fp, "Usage: %s [options] [args]\n", progname); + fprintf(fp, "\nOptions:\n\n"); + fprintf(fp, "\t--include, -I : Add directory to include path " + "(default path \"%s\")\n", + INCLUDE_DEFAULT); + fprintf(fp, "\t--debug-level, -d : Set debug level to " + "(default level %d)\n", + DEBUG_LEVEL_DEFAULT); + fprintf(fp, "\t--disable-diag : Disable diag error module \n"); + fprintf(fp, "\t--enable-diag : Enable diag error module \n"); + fprintf(fp, "\t--show-diag-diag : Show diag option \n"); + fprintf(fp, "\t--hide-diag : Hide diag optione \n"); + + fprintf(fp, "\t--indent, -i : Set dump indent to " + " (default indent %d)\n", + INDENT_DEFAULT); + fprintf(fp, "\t--width, -w : Set dump width to " + " (default width %d)\n", + WIDTH_DEFAULT); + fprintf(fp, "\t--resolve, -r : Perform anchor and merge key resolution" + " (default %s)\n", + RESOLVE_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--color, -C : Color output can be one of on, off, auto" + " (default %s)\n", + COLOR_DEFAULT); + fprintf(fp, "\t--visible, -V : Make all whitespace and linebreaks visible" + " (default %s)\n", + VISIBLE_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--follow, -l : Follow aliases when using paths" + " (default %s)\n", + FOLLOW_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--strip-labels : Strip labels when emitting" + " (default %s)\n", + STRIP_LABELS_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--strip-tags : Strip tags when emitting" + " (default %s)\n", + STRIP_TAGS_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--strip-doc : Strip document headers and indicators when emitting" + " (default %s)\n", + STRIP_DOC_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--disable-accel : Disable access accelerators (slower but uses less memory)" + " (default %s)\n", + DISABLE_ACCEL_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--disable-buffering : Disable buffering (i.e. no stdio file reads, unix fd instead)" + " (default %s)\n", + DISABLE_BUFFERING_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--disable-depth-limit : Disable depth limit" + " (default %s)\n", + DISABLE_DEPTH_LIMIT_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--json, -j : JSON input mode (no | force | auto)" + " (default %s)\n", + JSON_DEFAULT); + fprintf(fp, "\t--yaml-1.1 : Enable YAML 1.1 version instead of the library's default\n"); + fprintf(fp, "\t--yaml-1.2 : Enable YAML 1.2 version instead of the library's default\n"); + fprintf(fp, "\t--yaml-1.3 : Enable YAML 1.3 version instead of the library's default\n"); + fprintf(fp, "\t--sloppy-flow-indentation: Enable sloppy indentation in flow mode)" + " (default %s)\n", + SLOPPY_FLOW_INDENTATION_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--prefer-recursive : Prefer recursive instead of iterative algorighms" + " (default %s)\n", + PREFER_RECURSIVE_DEFAULT ? "true" : "false"); + 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--quiet, -q : Quiet operation, do not " + "output messages (default %s)\n", + QUIET_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--version, -v : Display libfyaml version\n"); + fprintf(fp, "\t--help, -h : Display help message\n"); + + if (tool_mode == OPT_TOOL || tool_mode != OPT_TESTSUITE) { + fprintf(fp, "\t--sort, -s : Perform mapping key sort (valid for dump)" + " (default %s)\n", + SORT_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--comment, -c : Output comments (experimental)" + " (default %s)\n", + COMMENT_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--mode, -m : Output mode can be one of original, block, flow, flow-oneline, json, json-tp, json-oneline, dejson" + " (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"); + if (tool_mode == OPT_TOOL || tool_mode == OPT_DUMP) + fprintf(fp, "\t--streaming : Use streaming output mode" + " (default %s)\n", + STREAMING_DEFAULT ? "true" : "false"); + } + + if (tool_mode == OPT_TOOL || (tool_mode != OPT_DUMP && tool_mode != OPT_TESTSUITE)) { + fprintf(fp, "\t--file, -f : Use given file instead of \n" + "\t Note that using a string with a leading '>' is equivalent to a file with the trailing content\n" + "\t --file \">foo: bar\" is as --file file.yaml with file.yaml \"foo: bar\"\n"); + } + + if (tool_mode == OPT_TOOL || tool_mode == OPT_JOIN) { + fprintf(fp, "\t--to, -T : Join to (default %s)\n", + TO_DEFAULT); + fprintf(fp, "\t--from, -F : Join from (default %s)\n", + FROM_DEFAULT); + fprintf(fp, "\t--trim, -t : Output given path (default %s)\n", + TRIM_DEFAULT); + } + + if (tool_mode == OPT_TOOL || tool_mode == OPT_YPATH) { + fprintf(fp, "\t--from, -F : Start from (default %s)\n", + FROM_DEFAULT); + fprintf(fp, "\t--dump-pathexpr : Dump the path expresion before the results\n"); + fprintf(fp, "\t--noexec : Do not execute the expression\n"); + } + + if (tool_mode == OPT_TOOL || tool_mode == OPT_COMPOSE) { + fprintf(fp, "\t--dump-path : Dump the path while composing\n"); + } + + if (tool_mode == OPT_TOOL) { + fprintf(fp, "\t--dump : Dump mode, [arguments] are file names\n"); + fprintf(fp, "\t--testsuite : Testsuite mode, [arguments] are s to output parse events\n"); + fprintf(fp, "\t--filter : Filter mode, is input, [arguments] are s, outputs to stdout\n"); + fprintf(fp, "\t--join : Join mode, [arguments] are s, outputs to stdout\n"); + fprintf(fp, "\t--ypath : YPATH mode, [arguments] are s, file names, outputs to stdout\n"); + fprintf(fp, "\t--scan-dump : scan-dump mode, [arguments] are file names\n"); + fprintf(fp, "\t--parse-dump : parse-dump mode, [arguments] are file names\n"); + fprintf(fp, "\t--compose : composer driver dump mode, [arguments] are file names\n"); + fprintf(fp, "\t--yaml-version : Information about supported libfyaml's YAML versions\n"); + } + + fprintf(fp, "\n"); + + switch (tool_mode) { + case OPT_TOOL: + default: + break; + case OPT_TESTSUITE: + fprintf(fp, "\tParse and dump test-suite event format\n"); + fprintf(fp, "\t$ %s input.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and dump of event example\n"); + fprintf(fp, "\t$ echo \"foo: bar\" | %s -\n", progname); + fprintf(fp, "\t+STR\n\t+DOC\n\t+MAP\n\t=VAL :foo\n\t=VAL :bar\n\t-MAP\n\t-DOC\n\t-STR\n"); + break; + case OPT_DUMP: + fprintf(fp, "\tParse and dump generated YAML document tree in the original YAML form\n"); + fprintf(fp, "\t$ %s input.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and dump generated YAML document tree in block YAML form (and make whitespace visible)\n"); + fprintf(fp, "\t$ %s -V -mblock input.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and dump generated YAML document from the input string\n"); + fprintf(fp, "\t$ %s -mjson \">foo: bar\"\n", progname); + fprintf(fp, "\t{\n\t \"foo\": \"bar\"\n\t}\n"); + break; + case OPT_FILTER: + fprintf(fp, "\tParse and filter YAML document tree starting from the '/foo' path followed by the '/bar' path\n"); + fprintf(fp, "\t$ %s --file input.yaml /foo /bar\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and filter for two paths (note how a multi-document stream is produced)\n"); + fprintf(fp, "\t$ %s --file -mblock --filter --file \">{ foo: bar, baz: [ frooz, whee ] }\" /foo /baz\n", progname); + fprintf(fp, "\tbar\n\t---\n\t- frooz\n\t- whee\n"); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and filter YAML document in stdin (note how the key may be complex)\n"); + fprintf(fp, "\t$ echo \"{ foo: bar }: baz\" | %s \"/{foo: bar}/\"\n", progname); + fprintf(fp, "\tbaz\n"); + break; + case OPT_JOIN: + fprintf(fp, "\tParse and join two YAML files\n"); + fprintf(fp, "\t$ %s file1.yaml file2.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and join two YAML maps\n"); + fprintf(fp, "\t$ %s \">foo: bar\" \">baz: frooz\"\n", progname); + fprintf(fp, "\tfoo: bar\n\tbaz: frooz\n"); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and join two YAML sequences\n"); + fprintf(fp, "\t$ %s -mblock \">[ foo ]\" \">[ bar ]\"\n", progname); + fprintf(fp, "\t- foo\n\t- bar\n"); + fprintf(fp, "\n"); + break; + case OPT_YPATH: + fprintf(fp, "\tParse and filter YAML with the ypath expression that results to /foo followed by /bar\n"); + fprintf(fp, "\t$ %s --ypath /foo,bar input.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + break; + case OPT_SCAN_DUMP: + fprintf(fp, "\tParse and dump YAML scanner tokens (internal)\n"); + fprintf(fp, "\n"); + break; + case OPT_PARSE_DUMP: + fprintf(fp, "\tParse and dump YAML parser events (internal)\n"); + fprintf(fp, "\n"); + break; + case OPT_COMPOSE: + fprintf(fp, "\tParse and dump generated YAML document tree using the composer api\n"); + fprintf(fp, "\t$ %s input.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and dump generated YAML document tree in block YAML form (and make whitespace visible)\n"); + fprintf(fp, "\t$ %s --compose -V -mblock input.yaml\n\t...\n", progname); + fprintf(fp, "\n"); + fprintf(fp, "\tParse and dump generated YAML document from the input string\n"); + fprintf(fp, "\t$ %s --compose -mjson \">foo: bar\"\n", progname); + fprintf(fp, "\t{\n\t \"foo\": \"bar\"\n\t}\n"); + break; + case OPT_YAML_VERSION_DUMP: + fprintf(fp, "\tDisplay information about the YAML versions libfyaml supports)\n"); + fprintf(fp, "\n"); + break; + } +} + +static int apply_mode_flags(const char *what, enum fy_emitter_cfg_flags *flagsp) +{ + static const struct { + const char *name; + unsigned int value; + } mf[] = { + { .name = "original", .value = FYECF_MODE_ORIGINAL }, + { .name = "block", .value = FYECF_MODE_BLOCK }, + { .name = "flow", .value = FYECF_MODE_FLOW }, + { .name = "flow-oneline", .value = FYECF_MODE_FLOW_ONELINE }, + { .name = "json", .value = FYECF_MODE_JSON }, + { .name = "json-tp", .value = FYECF_MODE_JSON_TP }, + { .name = "json-oneline", .value = FYECF_MODE_JSON_ONELINE }, + { .name = "dejson", .value = FYECF_MODE_DEJSON }, + }; + unsigned int i; + + if (!what || !flagsp) + return -1; + + if (!strcmp(what, "default")) + what = MODE_DEFAULT; + + for (i = 0; i < sizeof(mf)/sizeof(mf[0]); i++) { + if (!strcmp(what, mf[i].name)) { + *flagsp &= ~FYECF_MODE(FYECF_MODE_MASK); + *flagsp |= mf[i].value; + return 0; + } + } + + return -1; +} + +int apply_flags_option(const char *arg, unsigned int *flagsp, + int (*modify_flags)(const char *what, unsigned int *flagsp)) +{ + const char *s, *e, *sn; + char *targ; + int len, ret; + + if (!arg || !flagsp || !modify_flags) + return -1; + + s = arg; + e = arg + strlen(s); + while (s < e) { + sn = strchr(s, ','); + if (!sn) + sn = e; + + len = sn - s; + targ = alloca(len + 1); + memcpy(targ, s, len); + targ[len] = '\0'; + + ret = modify_flags(targ, flagsp); + if (ret) + return ret; + + s = sn < e ? (sn + 1) : sn; + } + + return 0; +} + +struct dump_userdata { + FILE *fp; + bool colorize; + bool visible; +}; + +static inline int +utf8_width_by_first_octet(uint8_t c) +{ + return (c & 0x80) == 0x00 ? 1 : + (c & 0xe0) == 0xc0 ? 2 : + (c & 0xf0) == 0xe0 ? 3 : + (c & 0xf8) == 0xf0 ? 4 : 0; +} + +static int do_output(struct fy_emitter *fye, enum fy_emitter_write_type type, const char *str, int len, void *userdata) +{ + struct dump_userdata *du = userdata; + FILE *fp = du->fp; + int ret, w; + const char *color = NULL; + const char *s, *e; + + s = str; + e = str + len; + if (du->colorize) { + switch (type) { + case fyewt_document_indicator: + color = "\x1b[36m"; + break; + case fyewt_tag_directive: + case fyewt_version_directive: + color = "\x1b[33m"; + break; + case fyewt_indent: + if (du->visible) { + fputs("\x1b[32m", fp); + while (s < e && (w = utf8_width_by_first_octet(((uint8_t)*s))) > 0) { + /* open box - U+2423 */ + fputs("\xe2\x90\xa3", fp); + s += w; + } + fputs("\x1b[0m", fp); + return len; + } + break; + case fyewt_indicator: + if (len == 1 && (str[0] == '\'' || str[0] == '"')) + color = "\x1b[33m"; + else if (len == 1 && str[0] == '&') + color = "\x1b[32;1m"; + else + color = "\x1b[35m"; + break; + case fyewt_whitespace: + if (du->visible) { + fputs("\x1b[32m", fp); + while (s < e && (w = utf8_width_by_first_octet(((uint8_t)*s))) > 0) { + /* symbol for space - U+2420 */ + /* symbol for interpunct - U+00B7 */ + fputs("\xc2\xb7", fp); + s += w; + } + fputs("\x1b[0m", fp); + return len; + } + break; + case fyewt_plain_scalar: + color = "\x1b[37;1m"; + break; + case fyewt_single_quoted_scalar: + case fyewt_double_quoted_scalar: + color = "\x1b[33m"; + break; + case fyewt_literal_scalar: + case fyewt_folded_scalar: + color = "\x1b[33m"; + break; + case fyewt_anchor: + case fyewt_tag: + case fyewt_alias: + color = "\x1b[32;1m"; + break; + case fyewt_linebreak: + if (du->visible) { + fputs("\x1b[32m", fp); + while (s < e && (w = utf8_width_by_first_octet(((uint8_t)*s))) > 0) { + /* symbol for space - ^M */ + /* fprintf(fp, "^M\n"); */ + /* down arrow - U+2193 */ + fputs("\xe2\x86\x93\n", fp); + s += w; + } + fputs("\x1b[0m", fp); + return len; + } + color = NULL; + break; + case fyewt_terminating_zero: + color = NULL; + break; + case fyewt_plain_scalar_key: + case fyewt_single_quoted_scalar_key: + case fyewt_double_quoted_scalar_key: + color = "\x1b[36;1m"; + break; + case fyewt_comment: + color = "\x1b[34;1m"; + break; + } + } + + /* don't output the terminating zero */ + if (type == fyewt_terminating_zero) + return len; + + if (color) + fputs(color, fp); + + ret = fwrite(str, 1, len, fp); + + if (color) + fputs("\x1b[0m", fp); + + return ret; +} + +void print_escaped(const char *str, int length) +{ + int i; + char c; + + if (length < 0) + length = strlen(str); + for (i = 0; i < length; i++) { + c = *str++; + if (c == '\\') + printf("\\\\"); + else if (c == '\0') + printf("\\0"); + else if (c == '\b') + printf("\\b"); + else if (c == '\n') + printf("\\n"); + else if (c == '\r') + printf("\\r"); + else if (c == '\t') + printf("\\t"); + else + printf("%c", c); + } +} + +void dump_token_comments(struct fy_token *fyt, bool colorize, const char *banner) +{ + static const char *placement_txt[] = { + [fycp_top] = "top", + [fycp_right] = "right", + [fycp_bottom] = "bottom", + }; + enum fy_comment_placement placement; + char buf[4096]; + const char *str; + + if (!fyt) + return; + + for (placement = fycp_top; placement < fycp_max; placement++) { + str = fy_token_get_comment(fyt, buf, sizeof(buf), placement); + if (!str) + continue; + fputs("\n", stdout); + if (colorize) + fputs("\x1b[31m", stdout); + printf("\t%s %6s: ", banner, placement_txt[placement]); + print_escaped(str, strlen(str)); + if (colorize) + fputs("\x1b[0m", stdout); + } +} + +void dump_testsuite_event(struct fy_parser *fyp, struct fy_event *fye, bool colorize, + struct fy_token_iter *iter, bool disable_flow_markers) +{ + const char *anchor = NULL; + const char *tag = NULL; + size_t anchor_len = 0, tag_len = 0; + enum fy_scalar_style style; + const struct fy_iter_chunk *ic; + int ret; + + switch (fye->type) { + case FYET_NONE: + if (colorize) + fputs("\x1b[31;1m", stdout); + printf("???"); + break; + case FYET_STREAM_START: + if (colorize) + fputs("\x1b[36m", stdout); + printf("+STR"); + break; + case FYET_STREAM_END: + if (colorize) + fputs("\x1b[36m", stdout); + printf("-STR"); + break; + case FYET_DOCUMENT_START: + if (colorize) + fputs("\x1b[36m", stdout); + printf("+DOC%s", !fy_document_event_is_implicit(fye) ? " ---" : ""); + break; + case FYET_DOCUMENT_END: + if (colorize) + fputs("\x1b[36m", stdout); + printf("-DOC%s", !fy_document_event_is_implicit(fye) ? " ..." : ""); + break; + case FYET_MAPPING_START: + if (fye->mapping_start.anchor) + anchor = fy_token_get_text(fye->mapping_start.anchor, &anchor_len); + if (fye->mapping_start.tag) + tag = fy_token_get_text(fye->mapping_start.tag, &tag_len); + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("+MAP"); + if (!disable_flow_markers && fy_event_get_node_style(fye) == FYNS_FLOW) + printf(" {}"); + if (anchor) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" &%.*s", (int)anchor_len, anchor); + } + if (tag) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" <%.*s>", (int)tag_len, tag); + } + break; + case FYET_MAPPING_END: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("-MAP"); + break; + case FYET_SEQUENCE_START: + if (fye->sequence_start.anchor) + anchor = fy_token_get_text(fye->sequence_start.anchor, &anchor_len); + if (fye->sequence_start.tag) + tag = fy_token_get_text(fye->sequence_start.tag, &tag_len); + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("+SEQ"); + if (!disable_flow_markers && fy_event_get_node_style(fye) == FYNS_FLOW) + printf(" []"); + if (anchor) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" &%.*s", (int)anchor_len, anchor); + } + if (tag) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" <%.*s>", (int)tag_len, tag); + } + break; + case FYET_SEQUENCE_END: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("-SEQ"); + break; + case FYET_SCALAR: + if (fye->scalar.anchor) + anchor = fy_token_get_text(fye->scalar.anchor, &anchor_len); + if (fye->scalar.tag) + tag = fy_token_get_text(fye->scalar.tag, &tag_len); + + if (colorize) + fputs("\x1b[37;1m", stdout); + printf("=VAL"); + if (anchor) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" &%.*s", (int)anchor_len, anchor); + } + if (tag) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" <%.*s>", (int)tag_len, tag); + } + + style = fy_token_scalar_style(fye->scalar.value); + switch (style) { + case FYSS_PLAIN: + if (colorize) + fputs("\x1b[37;1m", stdout); + printf(" :"); + break; + case FYSS_SINGLE_QUOTED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" '"); + break; + case FYSS_DOUBLE_QUOTED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" \""); + break; + case FYSS_LITERAL: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" |"); + break; + case FYSS_FOLDED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" >"); + break; + default: + abort(); + } + + fy_token_iter_start(fye->scalar.value, iter); + ic = NULL; + while ((ic = fy_token_iter_chunk_next(iter, ic, &ret)) != NULL) + print_escaped(ic->str, ic->len); + fy_token_iter_finish(iter); + + break; + case FYET_ALIAS: + anchor = fy_token_get_text(fye->alias.anchor, &anchor_len); + if (colorize) + fputs("\x1b[32m", stdout); + printf("=ALI *%.*s", (int)anchor_len, anchor); + break; + default: + assert(0); + } + if (colorize) + fputs("\x1b[0m", stdout); + fputs("\n", stdout); +} + +void dump_parse_event(struct fy_parser *fyp, struct fy_event *fye, bool colorize) +{ + struct fy_token *fyt_tag = NULL, *fyt_anchor = NULL; + const char *anchor = NULL; + const char *tag = NULL; + const char *value = NULL; + size_t anchor_len = 0, tag_len = 0, len = 0; + enum fy_scalar_style style; + const struct fy_version *vers; + const struct fy_tag *tagp = NULL; + void *iterp; + struct fy_document_state *fyds; + + fyt_anchor = fy_event_get_anchor_token(fye); + if (fyt_anchor) { + anchor = fy_token_get_text(fyt_anchor, &anchor_len); + assert(anchor); + } + + fyt_tag = fy_event_get_tag_token(fye); + if (fyt_tag) { + tag = fy_token_get_text(fyt_tag, &tag_len); + assert(tag); + tagp = fy_tag_token_tag(fyt_tag); + assert(tagp); + } + + switch (fye->type) { + case FYET_NONE: + if (colorize) + fputs("\x1b[31;1m", stdout); + printf("???"); + break; + case FYET_STREAM_START: + if (colorize) + fputs("\x1b[36m", stdout); + printf("STREAM_START"); + dump_token_comments(fye->stream_start.stream_start, colorize, ""); + break; + case FYET_STREAM_END: + if (colorize) + fputs("\x1b[36m", stdout); + printf("STREAM_END"); + dump_token_comments(fye->stream_end.stream_end, colorize, ""); + break; + case FYET_DOCUMENT_START: + if (colorize) + fputs("\x1b[36m", stdout); + + printf("DOCUMENT_START implicit=%s", + fye->document_start.implicit ? "true" : "false"); + + fyds = fye->document_start.document_state; + assert(fyds); + vers = fy_document_state_version(fyds); + assert(vers); + printf("( V=%d.%d VE=%s TE=%s", vers->major, vers->minor, + fy_document_state_version_explicit(fyds) ? "true" : "false", + fy_document_state_tags_explicit(fyds) ? "true" : "false"); + iterp = NULL; + if ((tagp = fy_document_state_tag_directive_iterate(fyds, &iterp)) != NULL) { + printf(" TDs: ["); + do { + printf(" \"%s\",\"%s\"", tagp->handle, tagp->prefix); + } while ((tagp = fy_document_state_tag_directive_iterate(fyds, &iterp)) != NULL); + printf(" ]"); + } + printf(" )"); + dump_token_comments(fye->document_start.document_start, colorize, ""); + break; + + case FYET_DOCUMENT_END: + if (colorize) + fputs("\x1b[36m", stdout); + printf("DOCUMENT_END implicit=%s", + fye->document_end.implicit ? "true" : "false"); + dump_token_comments(fye->document_end.document_end, colorize, ""); + break; + case FYET_MAPPING_START: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("MAPPING_START"); + if (anchor) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" &%.*s", (int)anchor_len, anchor); + } + if (tag) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" <%.*s> (\"%s\",\"%s\")", + (int)tag_len, tag, + tagp->handle, tagp->prefix); + } + dump_token_comments(fye->mapping_start.mapping_start, colorize, ""); + break; + case FYET_MAPPING_END: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("MAPPING_END"); + dump_token_comments(fye->mapping_end.mapping_end, colorize, ""); + break; + case FYET_SEQUENCE_START: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("SEQUENCE_START"); + if (anchor) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" &%.*s", (int)anchor_len, anchor); + } + if (tag) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" <%.*s> (\"%s\",\"%s\")", + (int)tag_len, tag, + tagp->handle, tagp->prefix); + } + dump_token_comments(fye->sequence_start.sequence_start, colorize, ""); + break; + case FYET_SEQUENCE_END: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("SEQUENCE_END"); + dump_token_comments(fye->sequence_end.sequence_end, colorize, ""); + break; + case FYET_SCALAR: + if (colorize) + fputs("\x1b[37;1m", stdout); + printf("SCALAR"); + if (anchor) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" &%.*s", (int)anchor_len, anchor); + } + if (tag) { + if (colorize) + fputs("\x1b[32m", stdout); + printf(" <%.*s> (\"%s\",\"%s\")", + (int)tag_len, tag, + tagp->handle, tagp->prefix); + } + + style = fy_token_scalar_style(fye->scalar.value); + switch (style) { + case FYSS_PLAIN: + if (colorize) + fputs("\x1b[37;1m", stdout); + printf(" "); + break; + case FYSS_SINGLE_QUOTED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" '"); + break; + case FYSS_DOUBLE_QUOTED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" \""); + break; + case FYSS_LITERAL: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" |"); + break; + case FYSS_FOLDED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" >"); + break; + default: + abort(); + } + value = fy_token_get_text(fye->scalar.value, &len); + if (value && len > 0) + print_escaped(value, len); + dump_token_comments(fye->scalar.value, colorize, ""); + break; + case FYET_ALIAS: + anchor = fy_token_get_text(fye->alias.anchor, &anchor_len); + if (colorize) + fputs("\x1b[32m", stdout); + printf("ALIAS *%.*s", (int)anchor_len, anchor); + dump_token_comments(fye->alias.anchor, colorize, ""); + break; + default: + /* ignored */ + break; + } + if (colorize) + fputs("\x1b[0m", stdout); + fputs("\n", stdout); +} + +void dump_scan_token(struct fy_parser *fyp, struct fy_token *fyt, bool colorize) +{ + const char *anchor = NULL, *value = NULL; + size_t anchor_len = 0, len = 0; + enum fy_scalar_style style; + const struct fy_version *vers; + const struct fy_tag *tag; + + switch (fy_token_get_type(fyt)) { + case FYTT_NONE: + if (colorize) + fputs("\x1b[31;1m", stdout); + printf("NONE"); + break; + case FYTT_STREAM_START: + if (colorize) + fputs("\x1b[36m", stdout); + printf("STREAM_START"); + break; + case FYTT_STREAM_END: + if (colorize) + fputs("\x1b[36m", stdout); + printf("STREAM_END"); + break; + case FYTT_VERSION_DIRECTIVE: + if (colorize) + fputs("\x1b[36m", stdout); + vers = fy_version_directive_token_version(fyt); + assert(vers); + printf("VERSION_DIRECTIVE major=%d minor=%d", vers->major, vers->minor); + break; + case FYTT_TAG_DIRECTIVE: + if (colorize) + fputs("\x1b[36m", stdout); + tag = fy_tag_directive_token_tag(fyt); + assert(tag); + printf("TAG_DIRECTIVE handle=\"%s\" prefix=\"%s\"", tag->handle, tag->prefix); + break; + case FYTT_DOCUMENT_START: + if (colorize) + fputs("\x1b[36m", stdout); + printf("DOCUMENT_START"); + break; + case FYTT_DOCUMENT_END: + if (colorize) + fputs("\x1b[36m", stdout); + printf("DOCUMENT_END"); + break; + case FYTT_BLOCK_SEQUENCE_START: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("BLOCK_SEQUENCE_START"); + break; + case FYTT_BLOCK_MAPPING_START: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("BLOCK_MAPPING_START"); + break; + case FYTT_BLOCK_END: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("BLOCK_END"); + break; + case FYTT_FLOW_SEQUENCE_START: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("FLOW_SEQUENCE_START"); + break; + case FYTT_FLOW_SEQUENCE_END: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("FLOW_SEQUENCE_END"); + break; + case FYTT_FLOW_MAPPING_START: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("FLOW_MAPPING_START"); + break; + case FYTT_FLOW_MAPPING_END: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("FLOW_MAPPING_END"); + break; + case FYTT_BLOCK_ENTRY: + if (colorize) + fputs("\x1b[36;1m", stdout); + printf("BLOCK_ENTRY"); + break; + case FYTT_FLOW_ENTRY: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("BLOCK_ENTRY"); + break; + case FYTT_KEY: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("KEY"); + break; + case FYTT_VALUE: + if (colorize) + fputs("\x1b[33;1m", stdout); + printf("KEY"); + break; + case FYTT_ALIAS: + anchor = fy_token_get_text(fyt, &anchor_len); + assert(anchor); + if (colorize) + fputs("\x1b[32m", stdout); + printf("ALIAS *%.*s", (int)anchor_len, anchor); + break; + case FYTT_ANCHOR: + anchor = fy_token_get_text(fyt, &anchor_len); + assert(anchor); + if (colorize) + fputs("\x1b[32m", stdout); + printf("ANCHOR &%.*s", (int)anchor_len, anchor); + break; + case FYTT_TAG: + tag = fy_tag_token_tag(fyt); + assert(tag); + if (colorize) + fputs("\x1b[32m", stdout); + /* prefix is a suffix for tag */ + printf("TAG handle=\"%s\" suffix=\"%s\"", tag->handle, tag->prefix); + break; + case FYTT_SCALAR: + if (colorize) + fputs("\x1b[37;1m", stdout); + + printf("SCALAR "); + value = fy_token_get_text(fyt, &len); + assert(value); + style = fy_token_scalar_style(fyt); + switch (style) { + case FYSS_PLAIN: + if (colorize) + fputs("\x1b[37;1m", stdout); + printf(" "); + break; + case FYSS_SINGLE_QUOTED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" '"); + break; + case FYSS_DOUBLE_QUOTED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" \""); + break; + case FYSS_LITERAL: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" |"); + break; + case FYSS_FOLDED: + if (colorize) + fputs("\x1b[33m", stdout); + printf(" >"); + break; + default: + abort(); + } + printf("%.*s", (int)len, value); + break; + default: + /* not handled; should not be produced by scan */ + break; + } + if (colorize) + fputs("\x1b[0m", stdout); + fputs("\n", stdout); +} + +static int set_parser_input(struct fy_parser *fyp, const char *what, + bool default_string) +{ + int rc; + + if (!strcmp(what, "-")) + rc = fy_parser_set_input_fp(fyp, "stdin", stdin); + else if (*what == '<') + rc = fy_parser_set_input_file(fyp, what + 1); + else if (*what == '>') + rc = fy_parser_set_string(fyp, what + 1, FY_NT); + else + rc = fy_parser_set_input_file(fyp, what); + + return rc; +} + +static void no_diag_output_fn(struct fy_diag *diag, void *user, + const char *buf, size_t len) +{ + /* nothing */ +} + +struct composer_data { + struct fy_parser *fyp; + struct fy_document *fyd; + struct fy_emitter *emit; + bool null_output; + bool document_ready; + bool verbose; + bool single_document; +}; + +static enum fy_composer_return +compose_process_event(struct fy_parser *fyp, struct fy_event *fye, struct fy_path *path, void *userdata) +{ + struct composer_data *cd = userdata; + struct fy_document *fyd; + struct fy_path_component *parent, *last; + struct fy_node *fyn, *fyn_parent; + struct fy_node_pair *fynp; + int rc; + + if (cd->verbose) { + fprintf(stderr, "%s: %c%c%c%c%c %3d - %-32s\n", + fy_event_type_get_text(fye->type), + fy_path_in_root(path) ? 'R' : '-', + fy_path_in_sequence(path) ? 'S' : '-', + 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_depth(path), + fy_path_get_text_alloca(path)); + } + + switch (fye->type) { + /* nothing to do for those */ + case FYET_NONE: + case FYET_STREAM_START: + case FYET_STREAM_END: + break; + + case FYET_DOCUMENT_START: + if (cd->fyd) { + fy_document_destroy(cd->fyd); + cd->fyd = NULL; + } + cd->document_ready = false; + + cd->fyd = fy_document_create_from_event(fyp, fye); + assert(cd->fyd); + + break; + + case FYET_DOCUMENT_END: + rc = fy_document_update_from_event(cd->fyd, fyp, fye); + assert(!rc); + + cd->document_ready = true; + + if (!cd->null_output && cd->fyd) + fy_emit_document(cd->emit, cd->fyd); + + fy_document_destroy(cd->fyd); + cd->fyd = NULL; + + /* on single document mode we stop here */ + if (cd->single_document) + return FYCR_OK_STOP; + break; + + + case FYET_SCALAR: + case FYET_ALIAS: + case FYET_MAPPING_START: + case FYET_SEQUENCE_START: + + fyd = cd->fyd; + assert(fyd); + + fyn = fy_node_create_from_event(fyd, fyp, fye); + assert(fyn); + + switch (fye->type) { + default: + /* XXX should now happen */ + break; + + case FYET_SCALAR: + case FYET_ALIAS: + last = NULL; + break; + + case FYET_MAPPING_START: + last = fy_path_last_component(path); + assert(last); + + fy_path_component_set_mapping_user_data(last, fyn); + fy_path_component_set_mapping_key_user_data(last, NULL); + + break; + + case FYET_SEQUENCE_START: + + last = fy_path_last_component(path); + assert(last); + + fy_path_component_set_sequence_user_data(last, fyn); + break; + } + + /* parent */ + parent = fy_path_last_not_collection_root_component(path); + + if (fy_path_in_root(path)) { + + rc = fy_document_set_root(cd->fyd, fyn); + assert(!rc); + + } else if (fy_path_in_sequence(path)) { + + assert(parent); + fyn_parent = fy_path_component_get_sequence_user_data(parent); + assert(fyn_parent); + assert(fy_node_is_sequence(fyn_parent)); + + rc = fy_node_sequence_add_item(fyn_parent, fyn); + assert(!rc); + + } else { + /* only thing left */ + assert(fy_path_in_mapping(path)); + + assert(parent); + fyn_parent = fy_path_component_get_mapping_user_data(parent); + assert(fyn_parent); + assert(fy_node_is_mapping(fyn_parent)); + + if (fy_path_in_mapping_key(path)) { + + fynp = fy_node_pair_create_with_key(fyd, fyn_parent, fyn); + assert(fynp); + + fy_path_component_set_mapping_key_user_data(parent, fynp); + + } else { + + assert(fy_path_in_mapping_value(path)); + + fynp = fy_path_component_get_mapping_key_user_data(parent); + assert(fynp); + + rc = fy_node_pair_update_with_value(fynp, fyn); + if (rc) /* this may happen normally */ + goto err_out; + + fy_path_component_set_mapping_key_user_data(parent, NULL); + } + } + + break; + + case FYET_MAPPING_END: + last = fy_path_last_component(path); + assert(last); + + fyn = fy_path_component_get_mapping_user_data(last); + assert(fyn); + assert(fy_node_is_mapping(fyn)); + + rc = fy_node_update_from_event(fyn, fyp, fye); + assert(!rc); + + break; + + case FYET_SEQUENCE_END: + last = fy_path_last_component(path); + assert(last); + + fyn = fy_path_component_get_sequence_user_data(last); + assert(fyn); + assert(fy_node_is_sequence(fyn)); + + rc = fy_node_update_from_event(fyn, fyp, fye); + assert(!rc); + + break; + } + + return FYCR_OK_CONTINUE; + +err_out: + return FYCR_ERROR; +} + +int main(int argc, char *argv[]) +{ + struct fy_parse_cfg cfg = { + .search_path = INCLUDE_DEFAULT, + .flags = + (QUIET_DEFAULT ? FYPCF_QUIET : 0) | + (RESOLVE_DEFAULT ? FYPCF_RESOLVE_DOCUMENT : 0) | + (DISABLE_ACCEL_DEFAULT ? FYPCF_DISABLE_ACCELERATORS : 0) | + (DISABLE_BUFFERING_DEFAULT ? FYPCF_DISABLE_BUFFERING : 0) | + (DISABLE_DEPTH_LIMIT_DEFAULT ? FYPCF_DISABLE_DEPTH_LIMIT : 0) | + (SLOPPY_FLOW_INDENTATION_DEFAULT ? FYPCF_SLOPPY_FLOW_INDENTATION : 0) | + (PREFER_RECURSIVE_DEFAULT ? FYPCF_PREFER_RECURSIVE : 0) | + (YPATH_ALIASES_DEFAULT ? FYPCF_YPATH_ALIASES : 0), + }; + struct fy_emitter_cfg emit_cfg; + struct fy_parser *fyp = NULL; + struct fy_emitter *fye = NULL; + int rc, exitcode = EXIT_FAILURE, opt, lidx, count, i, j, step = 1; + enum fy_error_module errmod; + unsigned int errmod_mask; + bool show; + int indent = INDENT_DEFAULT; + int width = WIDTH_DEFAULT; + bool follow = FOLLOW_DEFAULT; + const char *to = TO_DEFAULT; + const char *from = FROM_DEFAULT; + const char *color = COLOR_DEFAULT; + const char *file = NULL, *trim = TRIM_DEFAULT; + char *tmp, *s, *progname; + struct fy_document *fyd, *fyd_join = NULL; + struct dump_userdata du; + enum fy_emitter_cfg_flags emit_flags = 0; + struct fy_node *fyn, *fyn_emit, *fyn_to, *fyn_from; + int count_ins = 0; + struct fy_document **fyd_ins = NULL; + int tool_mode = OPT_TOOL; + struct fy_event *fyev; + struct fy_token *fyt; + bool join_resolve = RESOLVE_DEFAULT; + struct fy_token_iter *iter; + bool streaming = STREAMING_DEFAULT; + struct fy_diag_cfg dcfg; + struct fy_diag *diag = NULL; + struct fy_path_parse_cfg pcfg; + struct fy_path_expr *expr = NULL; + struct fy_path_exec_cfg xcfg; + struct fy_path_exec *fypx = NULL; + struct fy_node *fyn_start; + bool dump_pathexpr = false; + bool noexec = false; + bool null_output = false; + bool stdin_input; + void *res_iter; + bool disable_flow_markers = false; + struct composer_data cd; + bool dump_path = DUMP_PATH_DEFAULT; + + fy_valgrind_check(&argc, &argv); + + /* select the appropriate tool mode */ + progname = argv[0]; + progname = strrchr(argv[0], '/'); + if (!progname) + progname = argv[0]; + else + progname++; + + /* default mode is dump */ + if (!strcmp(progname, "fy-filter")) + tool_mode = OPT_FILTER; + else if (!strcmp(progname, "fy-testsuite")) + tool_mode = OPT_TESTSUITE; + else if (!strcmp(progname, "fy-dump")) + tool_mode = OPT_DUMP; + else if (!strcmp(progname, "fy-join")) + tool_mode = OPT_JOIN; + else if (!strcmp(progname, "fy-ypath")) + tool_mode = OPT_YPATH; + else if (!strcmp(progname, "fy-scan-dump")) + tool_mode = OPT_SCAN_DUMP; + else if (!strcmp(progname, "fy-parse-dump")) + tool_mode = OPT_PARSE_DUMP; + else if (!strcmp(progname, "fy-compose")) + tool_mode = OPT_COMPOSE; + else if (!strcmp(progname, "fy-yaml-version-dump")) + tool_mode = OPT_YAML_VERSION_DUMP; + else + tool_mode = OPT_TOOL; + + fy_diag_cfg_default(&dcfg); + /* XXX remember to modify this if you change COLOR_DEFAULT */ + + memset(&du, 0, sizeof(du)); + du.fp = stdout; + du.colorize = isatty(fileno(stdout)) == 1; + du.visible = VISIBLE_DEFAULT; + + emit_flags = (SORT_DEFAULT ? FYECF_SORT_KEYS : 0) | + (COMMENT_DEFAULT ? FYECF_OUTPUT_COMMENTS : 0) | + (STRIP_LABELS_DEFAULT ? FYECF_STRIP_LABELS : 0) | + (STRIP_TAGS_DEFAULT ? FYECF_STRIP_TAGS : 0) | + (STRIP_DOC_DEFAULT ? FYECF_STRIP_DOC : 0); + apply_mode_flags(MODE_DEFAULT, &emit_flags); + + while ((opt = getopt_long_only(argc, argv, + "I:" "d:" "i:" "w:" "rsc" "C:" "m:" "V" "f:" "t:" "T:F:" "j:" "qhvl", + lopts, &lidx)) != -1) { + switch (opt) { + case 'I': + tmp = alloca(strlen(cfg.search_path) + 1 + strlen(optarg) + 1); + s = tmp; + strcpy(s, cfg.search_path); + if (cfg.search_path && cfg.search_path[0]) { + s += strlen(cfg.search_path); + *s++ = ':'; + } + strcpy(s, optarg); + s += strlen(optarg); + *s = '\0'; + cfg.search_path = tmp; + break; + case 'i': + indent = atoi(optarg); + if (indent < 0 || indent > FYECF_INDENT_MASK) { + fprintf(stderr, "bad indent option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + + break; + case 'w': + width = atoi(optarg); + if (width < 0 || width > FYECF_WIDTH_MASK) { + fprintf(stderr, "bad width option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + break; + case 'd': + dcfg.level = fy_string_to_error_type(optarg); + if (dcfg.level == FYET_MAX) { + fprintf(stderr, "bad debug level option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + break; + case OPT_DISABLE_DIAG: + case OPT_ENABLE_DIAG: + if (!strcmp(optarg, "all")) { + errmod_mask = FY_BIT(FYEM_MAX) - 1; + } else { + errmod = fy_string_to_error_module(optarg); + if (errmod == FYEM_MAX) { + fprintf(stderr, "bad error module option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + errmod_mask = FY_BIT(errmod); + } + if (opt == OPT_DISABLE_DIAG) + dcfg.module_mask &= ~errmod_mask; + else + dcfg.module_mask |= errmod_mask; + break; + + case OPT_SHOW_DIAG: + case OPT_HIDE_DIAG: + show = opt == OPT_SHOW_DIAG; + if (!strcmp(optarg, "source")) { + dcfg.show_source = show; + } else if (!strcmp(optarg, "position")) { + dcfg.show_position = show; + } else if (!strcmp(optarg, "type")) { + dcfg.show_type = show; + } else if (!strcmp(optarg, "module")) { + dcfg.show_module = show; + } else { + fprintf(stderr, "bad %s option %s\n", + show ? "show" : "hide", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + break; + + case 'r': + cfg.flags |= FYPCF_RESOLVE_DOCUMENT; + break; + case 's': + emit_flags |= FYECF_SORT_KEYS; + break; + case 'c': + cfg.flags |= FYPCF_PARSE_COMMENTS; + emit_flags |= FYECF_OUTPUT_COMMENTS; + break; + case 'C': + color = optarg; + if (!strcmp(color, "auto")) { + dcfg.colorize = isatty(fileno(stderr)) == 1; + du.colorize = isatty(fileno(stdout)) == 1; + } + else if (!strcmp(color, "yes") || !strcmp(color, "1") || !strcmp(color, "on")) { + dcfg.colorize = true; + du.colorize = true; + } else if (!strcmp(color, "no") || !strcmp(color, "0") || !strcmp(color, "off")) { + dcfg.colorize = false; + du.colorize = false; + } else { + fprintf(stderr, "bad color option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + break; + case 'm': + rc = apply_mode_flags(optarg, &emit_flags); + if (rc) { + fprintf(stderr, "bad mode option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + break; + case 'V': + du.visible = true; + break; + case 'l': + follow = true; + break; + case 'q': + cfg.flags |= FYPCF_QUIET; + dcfg.output_fn = no_diag_output_fn; + dcfg.fp = NULL; + dcfg.colorize = false; + break; + case 'f': + file = optarg; + break; + case 't': + trim = optarg; + break; + case 'T': + to = optarg; + break; + case 'F': + from = optarg; + break; + case OPT_TESTSUITE: + case OPT_FILTER: + case OPT_DUMP: + case OPT_JOIN: + case OPT_TOOL: + case OPT_YPATH: + case OPT_SCAN_DUMP: + case OPT_PARSE_DUMP: + case OPT_COMPOSE: + case OPT_YAML_VERSION_DUMP: + tool_mode = opt; + break; + case OPT_STRIP_LABELS: + emit_flags |= FYECF_STRIP_LABELS; + break; + case OPT_STRIP_TAGS: + emit_flags |= FYECF_STRIP_TAGS; + break; + case OPT_STRIP_DOC: + emit_flags |= FYECF_STRIP_DOC; + break; + case OPT_STREAMING: + streaming = true; + break; + case OPT_DUMP_PATH: + dump_path = true; + break; + case 'j': + cfg.flags &= ~(FYPCF_JSON_MASK << FYPCF_JSON_SHIFT); + if (!strcmp(optarg, "no")) + cfg.flags |= FYPCF_JSON_NONE; + else if (!strcmp(optarg, "auto")) + cfg.flags |= FYPCF_JSON_AUTO; + else if (!strcmp(optarg, "force")) + cfg.flags |= FYPCF_JSON_FORCE; + else { + fprintf(stderr, "bad json option %s\n", optarg); + display_usage(stderr, progname, tool_mode); + return EXIT_FAILURE; + } + break; + case OPT_DISABLE_ACCEL: + cfg.flags |= FYPCF_DISABLE_ACCELERATORS; + break; + case OPT_DISABLE_BUFFERING: + cfg.flags |= FYPCF_DISABLE_BUFFERING; + break; + case OPT_DISABLE_DEPTH_LIMIT: + cfg.flags |= FYPCF_DISABLE_DEPTH_LIMIT; + break; + case OPT_DUMP_PATHEXPR: + dump_pathexpr = true; + break; + case OPT_NOEXEC: + noexec = true; + break; + case OPT_NULL_OUTPUT: + null_output = true; + break; + case OPT_YAML_1_1: + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_1; + break; + case OPT_YAML_1_2: + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_2; + break; + case OPT_YAML_1_3: + cfg.flags &= ~(FYPCF_DEFAULT_VERSION_MASK << FYPCF_DEFAULT_VERSION_SHIFT); + cfg.flags |= FYPCF_DEFAULT_VERSION_1_3; + break; + case OPT_SLOPPY_FLOW_INDENTATION: + cfg.flags |= FYPCF_SLOPPY_FLOW_INDENTATION; + break; + case OPT_PREFER_RECURSIVE: + cfg.flags |= FYPCF_PREFER_RECURSIVE; + break; + case OPT_YPATH_ALIASES: + cfg.flags |= FYPCF_YPATH_ALIASES; + break; + case OPT_DISABLE_FLOW_MARKERS: + disable_flow_markers = true; + break; + case 'h' : + default: + if (opt != 'h') + fprintf(stderr, "Unknown option '%c' %d\n", opt, opt); + display_usage(opt == 'h' ? stdout : stderr, progname, tool_mode); + return opt == 'h' ? EXIT_SUCCESS : EXIT_FAILURE; + case 'v': + printf("%s\n", fy_library_version()); + return EXIT_SUCCESS; + } + } + + if (tool_mode == OPT_YAML_VERSION_DUMP) { + const struct fy_version *vers; + void *iter; + + vers = fy_version_default(); + printf("Default version : %d.%d\n", vers->major, vers->minor); + + printf("Supported versions :"); + iter = NULL; + while ((vers = fy_version_supported_iterate(&iter)) != NULL) + printf(" %d.%d", vers->major, vers->minor); + printf("\n"); + } + + /* if we're still in tool mode, switch to dump */ + if (tool_mode == OPT_TOOL) + tool_mode = OPT_DUMP; + + /* as a special case for join, we resolve the document once */ + if (tool_mode == OPT_JOIN) { + join_resolve = !!(cfg.flags & FYPCF_RESOLVE_DOCUMENT); + cfg.flags &= ~FYPCF_RESOLVE_DOCUMENT; + } + + /* create common diagnostic object */ + diag = fy_diag_create(&dcfg); + if (!diag) { + fprintf(stderr, "fy_diag_create() failed\n"); + goto cleanup; + } + + /* all set, use fy_diag for error reporting, debugging now */ + + cfg.diag = diag; + fyp = fy_parser_create(&cfg); + if (!fyp) { + fprintf(stderr, "fy_parser_create() failed\n"); + goto cleanup; + } + + exitcode = EXIT_FAILURE; + + if (tool_mode != OPT_TESTSUITE) { + + memset(&emit_cfg, 0, sizeof(emit_cfg)); + emit_cfg.flags = emit_flags | + FYECF_INDENT(indent) | FYECF_WIDTH(width); + + /* unconditionally turn on document start markers for ypath */ + if (tool_mode == OPT_YPATH) + emit_cfg.flags |= FYECF_DOC_START_MARK_ON; + + emit_cfg.output = do_output; + emit_cfg.userdata = &du; + + fye = fy_emitter_create(&emit_cfg); + if (!fye) { + fprintf(stderr, "fy_emitter_create() failed\n"); + goto cleanup; + } + + } + + switch (tool_mode) { + + case OPT_TESTSUITE: + if (optind >= argc || !strcmp(argv[optind], "-")) + rc = fy_parser_set_input_fp(fyp, "stdin", stdin); + else + rc = fy_parser_set_input_file(fyp, argv[optind]); + if (rc) { + fprintf(stderr, "failed to set testsuite input\n"); + goto cleanup; + } + + iter = fy_token_iter_create(NULL); + if (!iter) { + fprintf(stderr, "failed to create token iterator\n"); + goto cleanup; + } + while ((fyev = fy_parser_parse(fyp)) != NULL) { + dump_testsuite_event(fyp, fyev, du.colorize, iter, disable_flow_markers); + fy_parser_event_free(fyp, fyev); + } + 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); + if (rc) { + fprintf(stderr, "failed to set parser input to '%s' for dump\n", argv[i]); + goto cleanup; + } + + if (!streaming) { + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + if (!null_output) + rc = fy_emit_document(fye, fyd); + else + rc = 0; + fy_parse_document_destroy(fyp, fyd); + if (rc) + goto cleanup; + + count++; + } + } else { + while ((fyev = fy_parser_parse(fyp)) != NULL) { + if (!null_output) { + rc = fy_emit_event(fye, fyev); + if (rc) + goto cleanup; + } else { + fy_parser_event_free(fyp, fyev); + } + } + count++; + } + + if (fy_parser_get_stream_error(fyp)) + goto cleanup; + } + break; + + case OPT_FILTER: + step = 1; + if (optind >= argc || (argc - optind) % step) { + fprintf(stderr, "illegal arguments\n"); + goto cleanup; + } + + if (!file) + rc = fy_parser_set_input_fp(fyp, "stdin", stdin); + else + rc = set_parser_input(fyp, file, false); + + if (rc) { + fprintf(stderr, "failed to set parser input to %s for filter\n", + file ? file : "stdin"); + goto cleanup; + } + + count = 0; + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + for (i = optind, j = 0; i < argc; i += step, j++) { + + fyn = fy_node_by_path(fy_document_root(fyd), argv[i], FY_NT, + follow ? FYNWF_FOLLOW : FYNWF_DONT_FOLLOW); + + /* ignore not found paths */ + if (!fyn) { + if (!(cfg.flags & FYPCF_QUIET)) + fprintf(stderr, "filter: could not find '%s'\n", + argv[i]); + continue; + } + + fyn_emit = fyn; + if (!fyn_emit) + continue; + + rc = fy_emit_document_start(fye, fyd, fyn_emit); + if (rc) + goto cleanup; + + rc = fy_emit_root_node(fye, fyn_emit); + if (rc) + goto cleanup; + + rc = fy_emit_document_end(fye); + if (rc) + goto cleanup; + + count++; + } + + fy_parse_document_destroy(fyp, fyd); + } + + if (fy_parser_get_stream_error(fyp)) + goto cleanup; + break; + + case OPT_JOIN: + if (optind >= argc) { + fprintf(stderr, "missing yaml file(s) to join\n"); + goto cleanup; + } + + fyd_join = NULL; + for (i = optind; i < argc; i++) { + rc = set_parser_input(fyp, argv[i], false); + if (rc) { + fprintf(stderr, "failed to set parser input to '%s' for join\n", argv[i]); + goto cleanup; + } + + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + if (!fyd_join) { + fyd_join = fyd; + continue; + } + + fyn_to = fy_node_by_path(fy_document_root(fyd_join), to, FY_NT, + follow ? FYNWF_FOLLOW : FYNWF_DONT_FOLLOW); + if (!fyn_to) { + fprintf(stderr, "unable to find to=%s\n", to); + goto cleanup; + } + + fyn_from = fy_node_by_path(fy_document_root(fyd), from, FY_NT, + follow ? FYNWF_FOLLOW : FYNWF_DONT_FOLLOW); + + if (!fyn_from) { + fprintf(stderr, "unable to find from=%s\n", from); + goto cleanup; + } + + rc = fy_node_insert(fyn_to, fyn_from); + if (rc) { + fprintf(stderr, "fy_node_insert() failed\n"); + goto cleanup; + } + + fy_document_destroy(fyd); + } + + if (fy_parser_get_stream_error(fyp)) + goto cleanup; + } + + /* perform the resolution at the end */ + if (join_resolve) { + rc = fy_document_resolve(fyd_join); + if (rc) + goto cleanup; + } + + fyn_emit = fy_node_by_path(fy_document_root(fyd_join), trim, FY_NT, + follow ? FYNWF_FOLLOW : FYNWF_DONT_FOLLOW); + + /* nothing to output ? */ + if (!fyn_emit) { + if (!(cfg.flags & FYPCF_QUIET)) + fprintf(stderr, "warning: empty document\n"); + } + + rc = fy_emit_document_start(fye, fyd_join, fyn_emit); + if (rc) + goto cleanup; + + rc = fy_emit_root_node(fye, fyn_emit); + if (rc) + goto cleanup; + + rc = fy_emit_document_end(fye); + if (rc) + goto cleanup; + + break; + + case OPT_YPATH: + step = 1; + if ((argc - optind) < 1) { + fprintf(stderr, "missing path expression\n"); + goto cleanup; + } + + memset(&pcfg, 0, sizeof(pcfg)); + pcfg.diag = diag; + + i = optind++; + expr = fy_path_expr_build_from_string(&pcfg, argv[i], FY_NT); + if (!expr) { + fprintf(stderr, "failed to parse path expression %s\n", argv[i]); + goto cleanup; + } + + if (dump_pathexpr) { + struct fy_document *fyd_pe; + + fy_path_expr_dump(expr, diag, FYET_ERROR, 0, "ypath expression:"); + + fyd_pe = fy_path_expr_to_document(expr); + if (!fyd_pe) { + fprintf(stderr, "failed to convert path expression to document\n"); + goto cleanup; + } + fy_emit_document(fye, fyd_pe); + + fy_document_destroy(fyd_pe); + } + + /* nothing more */ + if (noexec) { + exitcode = EXIT_SUCCESS; + goto cleanup; + } + + memset(&xcfg, 0, sizeof(xcfg)); + xcfg.diag = diag; + + fypx = fy_path_exec_create(&xcfg); + if (!fypx) { + fprintf(stderr, "failed to create a path executor\n"); + goto cleanup; + } + + /* if no more arguments use stdin */ + if (optind >= argc) { + rc = fy_parser_set_input_fp(fyp, "stdin", stdin); + if (rc) { + fprintf(stderr, "failed to set parser input to %s for ypath\n", + "stdin"); + goto cleanup; + } + stdin_input = true; + } else + stdin_input = false; + + count = 0; + for (;;) { + + if (!stdin_input) { + i = optind++; + rc = fy_parser_set_input_file(fyp, argv[i]); + if (rc) { + fprintf(stderr, "failed to set parser input to %s for ypath\n", + argv[i]); + goto cleanup; + } + } + + while ((fyd = fy_parse_load_document(fyp)) != NULL) { + + fyn_start = fy_node_by_path(fy_document_root(fyd), from, FY_NT, + follow ? FYNWF_FOLLOW : FYNWF_DONT_FOLLOW); + + /* if from is not found, then it's a null document */ + if (!fyn_start) { + if (!(cfg.flags & FYPCF_QUIET)) + fprintf(stderr, "filter: could not find starting point'%s'\n", + from); + continue; + } + + fy_path_exec_reset(fypx); + + rc = fy_path_exec_execute(fypx, expr, fyn_start); + if (rc) { + fprintf(stderr, "failed to fy_path_exec_execute() - %d\n", rc); + goto cleanup; + } + + res_iter = NULL; + while ((fyn_emit = fy_path_exec_results_iterate(fypx, &res_iter)) != NULL) { + + rc = fy_emit_document_start(fye, fyd, fyn_emit); + if (rc) + goto cleanup; + + rc = fy_emit_root_node(fye, fyn_emit); + if (rc) + goto cleanup; + + rc = fy_emit_document_end(fye); + if (rc) + goto cleanup; + } + + fy_parse_document_destroy(fyp, fyd); + } + + if (optind >= argc) + break; + + } + + if (fy_parser_get_stream_error(fyp)) + goto cleanup; + break; + + case OPT_SCAN_DUMP: + case OPT_PARSE_DUMP: + if (optind >= argc) { + fprintf(stderr, "missing yaml file to %s-dump\n", + tool_mode == OPT_SCAN_DUMP ? "scan" : "dump"); + goto cleanup; + } + + count = 0; + for (i = optind; i < argc; i++) { + rc = set_parser_input(fyp, argv[i], false); + if (rc) { + fprintf(stderr, "failed to set parser input to '%s' for dump\n", argv[i]); + goto cleanup; + } + + if (tool_mode == OPT_SCAN_DUMP) { + while ((fyt = fy_scan(fyp)) != NULL) { + dump_scan_token(fyp, fyt, du.colorize); + fy_scan_token_free(fyp, fyt); + } + } else { + while ((fyev = fy_parser_parse(fyp)) != NULL) { + dump_parse_event(fyp, fyev, du.colorize); + fy_parser_event_free(fyp, fyev); + } + } + count++; + + if (fy_parser_get_stream_error(fyp)) + goto cleanup; + } + break; + + case OPT_COMPOSE: + if (optind >= argc) { + fprintf(stderr, "missing yaml file to dump\n"); + goto cleanup; + } + + memset(&cd, 0, sizeof(cd)); + cd.fyp = fyp; + cd.emit = fye; + cd.null_output = null_output; + cd.single_document = false; + cd.verbose = dump_path; + + count = 0; + for (i = optind; i < argc; i++) { + rc = set_parser_input(fyp, argv[i], false); + if (rc) { + fprintf(stderr, "failed to set parser input to '%s' for dump\n", argv[i]); + goto cleanup; + } + + count++; + } + + /* ignore errors for now */ + rc = fy_parse_compose(fyp, compose_process_event, &cd); + + /* NULL OK */ + fy_document_destroy(cd.fyd); + + if (rc || fy_parser_get_stream_error(fyp)) + goto cleanup; + + break; + + + } + exitcode = EXIT_SUCCESS; + +cleanup: + if (fypx) + fy_path_exec_destroy(fypx); + + if (expr) + fy_path_expr_free(expr); + + if (fyd_join) + fy_document_destroy(fyd_join); + + if (fyd_ins) { + for (j = 0; j < count_ins; j++) + fy_document_destroy(fyd_ins[j]); + } + + if (fye) + fy_emitter_destroy(fye); + + if (fyp) + fy_parser_destroy(fyp); + + if (diag) + fy_diag_destroy(diag); + + return exitcode; +} diff --git a/src/valgrind/fy-valgrind.h b/src/valgrind/fy-valgrind.h new file mode 100644 index 0000000..c826403 --- /dev/null +++ b/src/valgrind/fy-valgrind.h @@ -0,0 +1,158 @@ +/* + * fy-valgrind.h - valgrind auto option handling + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifndef FY_VALGRIND_H +#define FY_VALGRIND_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +enum fy_valgrind_tool { + fyvt_none, + fyvt_valgrind, + fyvt_callgrind, + fyvt_massif, +}; + +static inline void fy_valgrind_check(int *argcp, char ***argvp) +{ + int argc = *argcp, va_argc; + char **argv = *argvp, **va_argv; + int i; +#ifdef __linux__ + char exe[PATH_MAX]; + ssize_t ret; +#endif + char *argv0 = NULL; + char *valgrind; + enum fy_valgrind_tool tool = fyvt_none; + + /* check for environment variables at first */ + if (getenv("USE_VALGRIND")) { + tool = fyvt_valgrind; + goto do_valgrind_no_opt; + } + if (getenv("USE_CALLGRIND") || getenv("USE_CACHEGRIND")) { + tool = fyvt_callgrind; + goto do_valgrind_no_opt; + } + if (getenv("USE_MASSIF")) { + tool = fyvt_callgrind; + goto do_valgrind_no_opt; + } + for (i = 1; i < argc; i++) { + /* -- is end of options */ + if (!strcmp(argv[i], "--")) + break; + + if (!strcmp(argv[i], "--valgrind")) { + tool = fyvt_valgrind; + break; + } + if (!strcmp(argv[i], "--callgrind") || !strcmp(argv[i], "--cachegrind")) { + tool = fyvt_callgrind; + break; + } + if (!strcmp(argv[i], "--massif")) { + tool = fyvt_massif; + break; + } + } + + if (tool == fyvt_none) + return; + + /* remove --valgrind/--callgrind/--massif from the option list */ + memmove(argv + i, argv + i + 1, (argc - i) * sizeof(*argv)); + (*argcp)--; + argc--; + +do_valgrind_no_opt: + /* clear those environment variables in any case */ + unsetenv("USE_VALGRIND"); + unsetenv("USE_CALLGRIND"); + unsetenv("USE_MASSIF"); + +#ifdef __linux__ + /* it's a Linuxism! but it should fail gracefully */ + ret = readlink("/proc/self/exe", exe, sizeof(exe)); + if (ret == 0) + argv0 = exe; +#endif + if (!argv0) + argv0 = argv[0]; + + valgrind = getenv("VALGRIND"); + if (valgrind) + unsetenv("VALGRIND"); + else + valgrind = "valgrind"; + + switch (tool) { + + case fyvt_valgrind: + va_argc = 1 + 4 + argc - 1; + va_argv = alloca(sizeof(*va_argv) * (va_argc + 1)); + va_argv[0] = valgrind; + va_argv[1] = "--leak-check=full"; + va_argv[2] = "--track-origins=yes"; + va_argv[3] = "--error-exitcode=5"; + va_argv[4] = argv0; + memcpy(va_argv + 1 + 4, argv + 1, argc * sizeof(*va_argv)); + break; + + case fyvt_callgrind: + va_argc = 1 + 5 + argc - 1; + va_argv = alloca(sizeof(*va_argv) * (va_argc + 1)); + va_argv[0] = valgrind; + va_argv[1] = "--tool=callgrind"; + va_argv[2] = "--dump-instr=yes"; + va_argv[3] = "--simulate-cache=yes"; + va_argv[4] = "--collect-jumps=yes"; + va_argv[5] = argv0; + memcpy(va_argv + 1 + 5, argv + 1, argc * sizeof(*va_argv)); + break; + + case fyvt_massif: + va_argc = 1 + 2 + argc - 1; + va_argv = alloca(sizeof(*va_argv) * (va_argc + 1)); + va_argv[0] = valgrind; + va_argv[1] = "--tool=massif"; + va_argv[2] = argv0; + memcpy(va_argv + 1 + 2, argv + 1, argc * sizeof(*va_argv)); + break; + + default: + abort(); /* should never get here */ + break; + } + + assert(va_argv[va_argc] == NULL); + + for (i = 0; i < va_argc; i++) + fprintf(stderr, "[%d]: %s\n", i, va_argv[i]); + fprintf(stderr, "[%d]: %s\n", i, va_argv[i]); + + setenv("FY_VALGRIND", "1", 1); + + execvp("valgrind", va_argv); + + fprintf(stderr, "warning: failed to start valgrind, continue without"); +} + +#endif diff --git a/src/xxhash/xxhash.c b/src/xxhash/xxhash.c new file mode 100644 index 0000000..892c601 --- /dev/null +++ b/src/xxhash/xxhash.c @@ -0,0 +1,1881 @@ +/* +xxHash - Fast Hash algorithm +Copyright (C) 2012-2014, Yann Collet. +BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You can contact the author at : +- xxHash source repository : http://code.google.com/p/xxhash/ +- public discussion board : https://groups.google.com/forum/#!forum/lz4c +*/ + + +//************************************** +// Tuning parameters +//************************************** +// Unaligned memory access is automatically enabled for "common" CPU, such as x86. +// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. +// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. +// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). +#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +// panto: -fsanitize fails with this so disable if compiling with it enabled +# if !defined(__SANITIZE_ADDRESS__) +# define XXH_USE_UNALIGNED_ACCESS 1 +# endif +#endif + +// XXH_ACCEPT_NULL_INPUT_POINTER : +// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. +// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. +// This option has a very small performance cost (only measurable on small inputs). +// By default, this option is disabled. To enable it, uncomment below define : +// #define XXH_ACCEPT_NULL_INPUT_POINTER 1 + +// XXH_FORCE_NATIVE_FORMAT : +// By default, xxHash library provides endian-independant Hash values, based on little-endian convention. +// Results are therefore identical for little-endian and big-endian CPU. +// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. +// Should endian-independance be of no importance for your application, you may set the #define below to 1. +// It will improve speed for Big-endian CPU. +// This option has no impact on Little_Endian CPU. +#define XXH_FORCE_NATIVE_FORMAT 0 + +//************************************** +// Compiler Specific Options +//************************************** +// Disable some Visual warning messages +#ifdef _MSC_VER // Visual Studio +# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant +#endif + +#ifdef _MSC_VER // Visual Studio +# define FORCE_INLINE static __forceinline +#else +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +#endif + +//************************************** +// Includes & Memory related functions +//************************************** +#include "xxhash.h" +// Modify the local functions below should you wish to use some other memory routines +// for malloc(), free() +#include +FORCE_INLINE void* XXH_malloc(size_t s) { return malloc(s); } +FORCE_INLINE void XXH_free (void* p) { free(p); } +// for memcpy() +#include +FORCE_INLINE void* XXH_memcpy(void* dest, const void* src, size_t size) +{ + return memcpy(dest,src,size); +} + +//************************************** +// Basic Types +//************************************** +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 +# include +typedef uint8_t BYTE; +typedef uint16_t U16; +typedef uint32_t U32; +typedef int32_t S32; +typedef uint64_t U64; +#else +typedef unsigned char BYTE; +typedef unsigned short U16; +typedef unsigned int U32; +typedef signed int S32; +typedef unsigned long long U64; +#endif + + +#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS) +# define _PACKED __attribute__ ((packed)) +#else +# define _PACKED +#endif + +#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) +# ifdef __IBMC__ +# pragma pack(1) +# else +# pragma pack(push, 1) +# endif +#endif + +typedef struct _U32_S +{ + U32 v; +} _PACKED U32_S; +typedef struct _U64_S +{ + U64 v; +} _PACKED U64_S; + +#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) +# pragma pack(pop) +#endif + +#define A32(x) (((U32_S *)(x))->v) +#define A64(x) (((U64_S *)(x))->v) + + +//*************************************** +// Compiler-specific Functions and Macros +//*************************************** +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +// Note : although _rotl exists for minGW (GCC under windows), performance seems poor +#if defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) +# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) +#endif + + +#if defined(_MSC_VER) // Visual Studio +# define XXH_swap32 _byteswap_ulong +# define XXH_swap64 _byteswap_uint64 +#elif GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +# define XXH_swap64 __builtin_bswap64 +#else +FORCE_INLINE U32 XXH_swap32 (U32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +FORCE_INLINE U64 XXH_swap64 (U64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + +//************************************** +// Constants +//************************************** +#define PRIME32_1 2654435761U +#define PRIME32_2 2246822519U +#define PRIME32_3 3266489917U +#define PRIME32_4 668265263U +#define PRIME32_5 374761393U + +#define PRIME64_1 11400714785074694791ULL +#define PRIME64_2 14029467366897019727ULL +#define PRIME64_3 1609587929392839161ULL +#define PRIME64_4 9650029242287828579ULL +#define PRIME64_5 2870177450012600261ULL + +//************************************** +// Architecture Macros +//************************************** +typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; +#ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch +static const int one = 1; +# define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one)) +#endif + + +//************************************** +// Macros +//************************************** +#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations + + +//**************************** +// Memory reads +//**************************** +typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; + +FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr)); + else + return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr); +} + +FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) +{ + return XXH_readLE32_align(ptr, endian, XXH_unaligned); +} + +FORCE_INLINE U64 XXH_readLE64_align(const U64* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? A64(ptr) : XXH_swap64(A64(ptr)); + else + return endian==XXH_littleEndian ? *ptr : XXH_swap64(*ptr); +} + +FORCE_INLINE U64 XXH_readLE64(const U64* ptr, XXH_endianess endian) +{ + return XXH_readLE64_align(ptr, endian, XXH_unaligned); +} + +//**************************** +// Simple Hash Functions +//**************************** +FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U32 h32; +#define XXH_get32bits(p) XXH_readLE32_align((const U32*)p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) + { + len=0; + bEnd=p=(const BYTE*)(size_t)16; + } +#endif + + if (len>=16) + { + const BYTE* const limit = bEnd - 16; + U32 v1 = seed + PRIME32_1 + PRIME32_2; + U32 v2 = seed + PRIME32_2; + U32 v3 = seed + 0; + U32 v4 = seed - PRIME32_1; + + do + { + v1 += XXH_get32bits(p) * PRIME32_2; + v1 = XXH_rotl32(v1, 13); + v1 *= PRIME32_1; + p+=4; + v2 += XXH_get32bits(p) * PRIME32_2; + v2 = XXH_rotl32(v2, 13); + v2 *= PRIME32_1; + p+=4; + v3 += XXH_get32bits(p) * PRIME32_2; + v3 = XXH_rotl32(v3, 13); + v3 *= PRIME32_1; + p+=4; + v4 += XXH_get32bits(p) * PRIME32_2; + v4 = XXH_rotl32(v4, 13); + v4 *= PRIME32_1; + p+=4; + } + while (p<=limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } + else + { + h32 = seed + PRIME32_5; + } + + h32 += (U32) len; + + while (p+4<=bEnd) + { + h32 += XXH_get32bits(p) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +unsigned int XXH32 (const void* input, size_t len, unsigned seed) +{ +#if 0 + // Simple version, good for code maintenance, but unfortunately slow for small inputs + XXH32_state_t state; + XXH32_reset(&state, seed); + XXH32_update(&state, input, len); + return XXH32_digest(&state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + +# if !defined(XXH_USE_UNALIGNED_ACCESS) + if ((((size_t)input) & 3) == 0) // Input is aligned, let's leverage the speed advantage + { + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } +# endif + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + +FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U64 h64; +#define XXH_get64bits(p) XXH_readLE64_align((const U64*)p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) + { + len=0; + bEnd=p=(const BYTE*)(size_t)32; + } +#endif + + if (len>=32) + { + const BYTE* const limit = bEnd - 32; + U64 v1 = seed + PRIME64_1 + PRIME64_2; + U64 v2 = seed + PRIME64_2; + U64 v3 = seed + 0; + U64 v4 = seed - PRIME64_1; + + do + { + v1 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + v2 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + v3 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + v4 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + } + while (p<=limit); + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + + v1 *= PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + h64 ^= v1; + h64 = h64 * PRIME64_1 + PRIME64_4; + + v2 *= PRIME64_2; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + h64 ^= v2; + h64 = h64 * PRIME64_1 + PRIME64_4; + + v3 *= PRIME64_2; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + h64 ^= v3; + h64 = h64 * PRIME64_1 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + h64 ^= v4; + h64 = h64 * PRIME64_1 + PRIME64_4; + } + else + { + h64 = seed + PRIME64_5; + } + + h64 += (U64) len; + + while (p+8<=bEnd) + { + U64 k1 = XXH_get64bits(p); + k1 *= PRIME64_2; + k1 = XXH_rotl64(k1,31); + k1 *= PRIME64_1; + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) + { + h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; + +#undef XXH_get64bits +} + + +unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) +{ +#if 0 + // Simple version, good for code maintenance, but unfortunately slow for small inputs + XXH64_state_t state; + XXH64_reset(&state, seed); + XXH64_update(&state, input, len); + return XXH64_digest(&state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + +# if !defined(XXH_USE_UNALIGNED_ACCESS) + if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage + { + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } +# endif + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + +FORCE_INLINE void XXH128_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align, void* out) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U64 h1, h2; +#define XXH_get64bits(p) XXH_readLE64_align((const U64*)p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) + { + len=0; + bEnd=p=(const BYTE*)(size_t)32; + } +#endif + + if (len>=32) + { + const BYTE* const limit = bEnd - 32; + U64 v1 = seed + PRIME64_1 + PRIME64_2; + U64 v2 = seed + PRIME64_2; + U64 v3 = seed + 0; + U64 v4 = seed - PRIME64_1; + + do + { + v1 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + v2 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + v3 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + v4 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + } + while (p<=limit); + + v1 *= PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + h1 = v1; + h2 = ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_4; + + v2 *= PRIME64_2; + v2 = XXH_rotl64(v2, 33); + v2 *= PRIME64_1; + h2 ^= v2; + h1 ^= ( XXH_rotl64(h2, 27) + h2 ) * PRIME64_1 + PRIME64_4; + + v3 *= PRIME64_2; + v3 = XXH_rotl64(v3, 29); + v3 *= PRIME64_1; + h1 ^= v3; + h2 ^= ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = XXH_rotl64(v4, 27); + v4 *= PRIME64_1; + h2 ^= v4; + h1 ^= ( XXH_rotl64(h2, 27) + h2 ) * PRIME64_1 + PRIME64_4; + } + else + { + h1 = seed + PRIME64_5; + h2 = seed + PRIME64_1; + } + + switch(len & 31) + { + case 31: h2 ^= ((U64)p[30]) << 48; + /* fall-through */ + case 30: h2 ^= ((U64)p[29]) << 40; + /* fall-through */ + case 29: h2 ^= ((U64)p[28]) << 32; + /* fall-through */ + case 28: h2 ^= ((U64)p[27]) << 24; + /* fall-through */ + case 27: h2 ^= ((U64)p[26]) << 16; + /* fall-through */ + case 26: h2 ^= ((U64)p[25]) << 8; + /* fall-through */ + case 25: h2 ^= ((U64)p[24]) << 0; + h1 ^= XXH_rotl64(h2 * PRIME64_2, 11) * PRIME64_1; + /* fall-through */ + case 24: h1 ^= ((U64)p[23]) << 56; + /* fall-through */ + case 23: h1 ^= ((U64)p[22]) << 48; + /* fall-through */ + case 22: h1 ^= ((U64)p[21]) << 40; + /* fall-through */ + case 21: h1 ^= ((U64)p[20]) << 32; + /* fall-through */ + case 20: h1 ^= ((U64)p[19]) << 24; + /* fall-through */ + case 19: h1 ^= ((U64)p[18]) << 16; + /* fall-through */ + case 18: h1 ^= ((U64)p[17]) << 8; + /* fall-through */ + case 17: h1 ^= ((U64)p[16]) << 0; + h2 ^= XXH_rotl64(h1 * PRIME64_2, 11) * PRIME64_1; + /* fall-through */ + case 16: h2 ^= ((U64)p[15]) << 56; + /* fall-through */ + case 15: h2 ^= ((U64)p[14]) << 48; + /* fall-through */ + case 14: h2 ^= ((U64)p[13]) << 40; + /* fall-through */ + case 13: h2 ^= ((U64)p[12]) << 32; + /* fall-through */ + case 12: h2 ^= ((U64)p[11]) << 24; + /* fall-through */ + case 11: h2 ^= ((U64)p[10]) << 16; + /* fall-through */ + case 10: h2 ^= ((U64)p[9]) << 8; + /* fall-through */ + case 9: h2 ^= ((U64)p[8]) << 0; + h1 ^= XXH_rotl64(h2 * PRIME64_2, 11) * PRIME64_1; + /* fall-through */ + case 8: h1 ^= ((U64)p[7]) << 56; + /* fall-through */ + case 7: h1 ^= ((U64)p[6]) << 48; + /* fall-through */ + case 6: h1 ^= ((U64)p[5]) << 40; + /* fall-through */ + case 5: h1 ^= ((U64)p[4]) << 32; + /* fall-through */ + case 4: h1 ^= ((U64)p[3]) << 24; + /* fall-through */ + case 3: h1 ^= ((U64)p[2]) << 16; + /* fall-through */ + case 2: h1 ^= ((U64)p[1]) << 8; + /* fall-through */ + case 1: h1 ^= ((U64)p[0]) << 0; + h2 ^= XXH_rotl64(h1 * PRIME64_5, 11) * PRIME64_1; + /* fall-through */ + } + + h1 = XXH_rotl64(h2, 27) * PRIME64_1 + PRIME64_4; + + h1 += (U64) len; + h2 += (U64) len; + + h2 ^= h1 >> 33; + h2 *= PRIME64_2; + h1 ^= h2 >> 29; + h1 *= PRIME64_3; + h2 ^= h1 >> 32; + + ((U64*)out)[0] = h1; + ((U64*)out)[1] = h2; + +#undef XXH_get64bits +} + +void XXH128 (const void* input, size_t len, unsigned long long seed, void* out) +{ +#if 0 + XXH128_state_t state; + XXH128_reset(&state, seed); + XXH128_update(&state, input, len); + XXH128_digest(&state, out); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + +# if !defined(XXH_USE_UNALIGNED_ACCESS) + if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage + { + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + XXH128_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned, out); + else + XXH128_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned, out); + } +# endif + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + XXH128_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned, out); + else + XXH128_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned, out); +#endif +} + + +FORCE_INLINE void XXH256_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align, void* out) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U64 h1, h2, h3, h4; + +#define XXH_get64bits(p) XXH_readLE64_align((const U64*)p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) + { + len=0; + bEnd=p=(const BYTE*)(size_t)32; + } +#endif + + if (len>=32) + { + const BYTE* const limit = bEnd - 32; + U64 v1 = seed + PRIME64_1 + PRIME64_2; + U64 v2 = seed + PRIME64_2; + U64 v3 = seed + 0; + U64 v4 = seed - PRIME64_1; + + do + { + v1 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + v2 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + v3 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + v4 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + } + while (p<=limit); + + v1 *= PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + h1 = v1; + h2 = ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_2; + + v2 *= PRIME64_2; + v2 = XXH_rotl64(v2, 33); + v2 *= PRIME64_1; + h2 ^= v2; + h3 = ( XXH_rotl64(h2, 29) + h2 ) * PRIME64_2 + PRIME64_3; + + v3 *= PRIME64_2; + v3 = XXH_rotl64(v3, 29); + v3 *= PRIME64_1; + h3 ^= v3; + h4 = ( XXH_rotl64(h3, 31) + h3 ) * PRIME64_3 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = XXH_rotl64(v4, 27); + v4 *= PRIME64_1; + h4 ^= v4; + h1 ^= ( XXH_rotl64(h4, 33) + h4 ) * PRIME64_4 + PRIME64_5; + } + else + { + h1 = seed + PRIME64_5; + h2 = seed + PRIME64_1; + h3 = seed + PRIME64_4; + h4 = seed + PRIME64_2; + } + + switch(len & 31) + { + case 31: h4 ^= ((U64)p[30]) << 48; + /* fall-through */ + case 30: h4 ^= ((U64)p[29]) << 40; + /* fall-through */ + case 29: h4 ^= ((U64)p[28]) << 32; + /* fall-through */ + case 28: h4 ^= ((U64)p[27]) << 24; + /* fall-through */ + case 27: h4 ^= ((U64)p[26]) << 16; + /* fall-through */ + case 26: h4 ^= ((U64)p[25]) << 8; + /* fall-through */ + case 25: h4 ^= ((U64)p[24]) << 0; + h3 ^= XXH_rotl64(h4 * PRIME64_5, 17) * PRIME64_1; + /* fall-through */ + case 24: h3 ^= ((U64)p[23]) << 56; + /* fall-through */ + case 23: h3 ^= ((U64)p[22]) << 48; + /* fall-through */ + case 22: h3 ^= ((U64)p[21]) << 40; + /* fall-through */ + case 21: h3 ^= ((U64)p[20]) << 32; + /* fall-through */ + case 20: h3 ^= ((U64)p[19]) << 24; + /* fall-through */ + case 19: h3 ^= ((U64)p[18]) << 16; + /* fall-through */ + case 18: h3 ^= ((U64)p[17]) << 8; + /* fall-through */ + case 17: h3 ^= ((U64)p[16]) << 0; + h2 ^= XXH_rotl64(h3 * PRIME64_5, 13) * PRIME64_1; + /* fall-through */ + case 16: h2 ^= ((U64)p[15]) << 56; + /* fall-through */ + case 15: h2 ^= ((U64)p[14]) << 48; + /* fall-through */ + case 14: h2 ^= ((U64)p[13]) << 40; + /* fall-through */ + case 13: h2 ^= ((U64)p[12]) << 32; + /* fall-through */ + case 12: h2 ^= ((U64)p[11]) << 24; + /* fall-through */ + case 11: h2 ^= ((U64)p[10]) << 16; + /* fall-through */ + case 10: h2 ^= ((U64)p[9]) << 8; + /* fall-through */ + case 9: h2 ^= ((U64)p[8]) << 0; + h1 ^= XXH_rotl64(h2 * PRIME64_5, 11) * PRIME64_1; + /* fall-through */ + case 8: h1 ^= ((U64)p[7]) << 56; + /* fall-through */ + case 7: h1 ^= ((U64)p[6]) << 48; + /* fall-through */ + case 6: h1 ^= ((U64)p[5]) << 40; + /* fall-through */ + case 5: h1 ^= ((U64)p[4]) << 32; + /* fall-through */ + case 4: h1 ^= ((U64)p[3]) << 24; + /* fall-through */ + case 3: h1 ^= ((U64)p[2]) << 16; + /* fall-through */ + case 2: h1 ^= ((U64)p[1]) << 8; + /* fall-through */ + case 1: h1 ^= ((U64)p[0]) << 0; + h4 ^= XXH_rotl64(h1 * PRIME64_5, 7) * PRIME64_1; + /* fall-through */ + } + + h2 ^= ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_4; + h3 ^= ( XXH_rotl64(h2, 29) + h2 ) * PRIME64_2 + PRIME64_3; + h4 ^= ( XXH_rotl64(h3, 31) + h3 ) * PRIME64_3 + PRIME64_2; + h1 ^= ( XXH_rotl64(h4, 33) + h4 ) * PRIME64_4 + PRIME64_1; + + h1 += (U64) len; + h2 += (U64) len; + h3 += (U64) len; + h4 += (U64) len; + + h4 ^= h1 >> 33; + h4 *= PRIME64_2; + h1 ^= h4 >> 29; + h1 *= PRIME64_3; + h4 ^= h1 >> 32; + + h3 ^= h2 >> 33; + h3 *= PRIME64_2; + h2 ^= h3 >> 29; + h2 *= PRIME64_3; + h3 ^= h2 >> 32; + + ((unsigned long long*)out)[0] = h1; + ((unsigned long long*)out)[1] = h2; + ((unsigned long long*)out)[2] = h3; + ((unsigned long long*)out)[3] = h4; + +#undef XXH_get64bits +} + +void XXH256 (const void* input, size_t len, unsigned long long seed, void* out) +{ +#if 0 + XXH256_state_t state; + XXH256_reset(&state, seed); + XXH256_update(&state, input, len); + XXH256_digest(&state, out); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + +# if !defined(XXH_USE_UNALIGNED_ACCESS) + if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage + { + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + XXH256_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned, out); + else + XXH256_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned, out); + } +# endif + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + XXH256_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned, out); + else + XXH256_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned, out); +#endif +} + + +/**************************************************** + * Advanced Hash Functions +****************************************************/ + +/*** Allocation ***/ +typedef struct +{ + U64 total_len; + U32 seed; + U32 v1; + U32 v2; + U32 v3; + U32 v4; + U32 memsize; + char memory[16]; +} XXH_istate32_t; + +typedef struct +{ + U64 total_len; + U64 seed; + U64 v1; + U64 v2; + U64 v3; + U64 v4; + U32 memsize; + char memory[32]; +} XXH_istate64_t; + + +typedef struct +{ + U64 total_len; + U64 seed; + U64 v1; + U64 v2; + U64 v3; + U64 v4; + char memory[64]; + U32 memsize; +} XXH_istate128_t; + +typedef struct +{ + U64 total_len; + U64 seed; + U64 v1; + U64 v2; + U64 v3; + U64 v4; + char memory[64]; + U32 memsize; +} XXH_istate256_t; + + +XXH32_state_t* XXH32_createState(void) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t)); // A compilation error here means XXH32_state_t is not large enough + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +}; + +XXH64_state_t* XXH64_createState(void) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t)); // A compilation error here means XXH64_state_t is not large enough + return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); +} +XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +}; + +XXH128_state_t* XXH128_createState(void) +{ + XXH_STATIC_ASSERT(sizeof(XXH128_state_t) >= sizeof(XXH_istate128_t)); // A compilation error here means XXH128_state_t is not large enough + return (XXH128_state_t*)XXH_malloc(sizeof(XXH128_state_t)); +} +XXH_errorcode XXH128_freeState(XXH128_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + + +/*** Hash feed ***/ + +XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed) +{ + XXH_istate32_t* state = (XXH_istate32_t*) state_in; + state->seed = seed; + state->v1 = seed + PRIME32_1 + PRIME32_2; + state->v2 = seed + PRIME32_2; + state->v3 = seed + 0; + state->v4 = seed - PRIME32_1; + state->total_len = 0; + state->memsize = 0; + return XXH_OK; +} + +XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed) +{ + XXH_istate64_t* state = (XXH_istate64_t*) state_in; + state->seed = seed; + state->v1 = seed + PRIME64_1 + PRIME64_2; + state->v2 = seed + PRIME64_2; + state->v3 = seed + 0; + state->v4 = seed - PRIME64_1; + state->total_len = 0; + state->memsize = 0; + return XXH_OK; +} + +XXH_errorcode XXH128_reset(XXH128_state_t* state_in, unsigned long long seed) +{ + XXH_istate128_t* state = (XXH_istate128_t*) state_in; + state->seed = seed; + state->v1 = seed + PRIME64_1 + PRIME64_2; + state->v2 = seed + PRIME64_2; + state->v3 = seed + 0; + state->v4 = seed - PRIME64_1; + state->total_len = 0; + state->memsize = 0; + return XXH_OK; +} + +XXH_errorcode XXH256_reset(XXH256_state_t* state_in, unsigned long long seed) +{ + XXH_istate256_t* state = (XXH_istate256_t*) state_in; + state->seed = seed; + state->v1 = seed + PRIME64_1 + PRIME64_2; + state->v2 = seed + PRIME64_2; + state->v3 = seed + 0; + state->v4 = seed - PRIME64_1; + state->total_len = 0; + state->memsize = 0; + return XXH_OK; +} + + +FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianess endian) +{ + XXH_istate32_t* state = (XXH_istate32_t *) state_in; + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 16) // fill in tmp buffer + { + XXH_memcpy(state->memory + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) // some data left from previous update + { + XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize); + { + const U32* p32 = (const U32*)state->memory; + state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; + state->v1 = XXH_rotl32(state->v1, 13); + state->v1 *= PRIME32_1; + p32++; + state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; + state->v2 = XXH_rotl32(state->v2, 13); + state->v2 *= PRIME32_1; + p32++; + state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; + state->v3 = XXH_rotl32(state->v3, 13); + state->v3 *= PRIME32_1; + p32++; + state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; + state->v4 = XXH_rotl32(state->v4, 13); + state->v4 *= PRIME32_1; + p32++; + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) + { + const BYTE* const limit = bEnd - 16; + U32 v1 = state->v1; + U32 v2 = state->v2; + U32 v3 = state->v3; + U32 v4 = state->v4; + + do + { + v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; + v1 = XXH_rotl32(v1, 13); + v1 *= PRIME32_1; + p+=4; + v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; + v2 = XXH_rotl32(v2, 13); + v2 *= PRIME32_1; + p+=4; + v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; + v3 = XXH_rotl32(v3, 13); + v3 *= PRIME32_1; + p+=4; + v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; + v4 = XXH_rotl32(v4, 13); + v4 *= PRIME32_1; + p+=4; + } + while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) + { + XXH_memcpy(state->memory, p, bEnd-p); + state->memsize = (int)(bEnd-p); + } + + return XXH_OK; +} + +XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH32_update_endian(state_in, input, len, XXH_bigEndian); +} + + + +FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianess endian) +{ + XXH_istate32_t* state = (XXH_istate32_t*) state_in; + const BYTE * p = (const BYTE*)state->memory; + BYTE* bEnd = (BYTE*)state->memory + state->memsize; + U32 h32; + + if (state->total_len >= 16) + { + h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); + } + else + { + h32 = state->seed + PRIME32_5; + } + + h32 += (U32) state->total_len; + + while (p+4<=bEnd) + { + h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +U32 XXH32_digest (const XXH32_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_digest_endian(state_in, XXH_littleEndian); + else + return XXH32_digest_endian(state_in, XXH_bigEndian); +} + + +FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianess endian) +{ + XXH_istate64_t * state = (XXH_istate64_t *) state_in; + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 32) // fill in tmp buffer + { + XXH_memcpy(state->memory + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) // some data left from previous update + { + XXH_memcpy(state->memory + state->memsize, input, 32-state->memsize); + { + const U64* p64 = (const U64*)state->memory; + state->v1 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v1 = XXH_rotl64(state->v1, 31); + state->v1 *= PRIME64_1; + p64++; + state->v2 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v2 = XXH_rotl64(state->v2, 31); + state->v2 *= PRIME64_1; + p64++; + state->v3 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v3 = XXH_rotl64(state->v3, 31); + state->v3 *= PRIME64_1; + p64++; + state->v4 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v4 = XXH_rotl64(state->v4, 31); + state->v4 *= PRIME64_1; + p64++; + } + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) + { + const BYTE* const limit = bEnd - 32; + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + do + { + v1 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + p+=8; + v2 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + p+=8; + v3 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + p+=8; + v4 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + p+=8; + } + while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) + { + XXH_memcpy(state->memory, p, bEnd-p); + state->memsize = (int)(bEnd-p); + } + + return XXH_OK; +} + +XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH64_update_endian(state_in, input, len, XXH_bigEndian); +} + + + +FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianess endian) +{ + XXH_istate64_t * state = (XXH_istate64_t *) state_in; + const BYTE * p = (const BYTE*)state->memory; + BYTE* bEnd = (BYTE*)state->memory + state->memsize; + U64 h64; + + if (state->total_len >= 32) + { + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + + v1 *= PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + h64 ^= v1; + h64 = h64*PRIME64_1 + PRIME64_4; + + v2 *= PRIME64_2; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + h64 ^= v2; + h64 = h64*PRIME64_1 + PRIME64_4; + + v3 *= PRIME64_2; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + h64 ^= v3; + h64 = h64*PRIME64_1 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + h64 ^= v4; + h64 = h64*PRIME64_1 + PRIME64_4; + } + else + { + h64 = state->seed + PRIME64_5; + } + + h64 += (U64) state->total_len; + + while (p+8<=bEnd) + { + U64 k1 = XXH_readLE64((const U64*)p, endian); + k1 *= PRIME64_2; + k1 = XXH_rotl64(k1,31); + k1 *= PRIME64_1; + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) + { + h64 ^= (U64)(XXH_readLE32((const U32*)p, endian)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + + +unsigned long long XXH64_digest (const XXH64_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_digest_endian(state_in, XXH_littleEndian); + else + return XXH64_digest_endian(state_in, XXH_bigEndian); +} + + +FORCE_INLINE XXH_errorcode XXH128_update_endian (XXH128_state_t* state_in, const void* input, size_t len, XXH_endianess endian) +{ + XXH_istate128_t * state = (XXH_istate128_t *) state_in; + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; +#define XXH_get64bits(p) XXH_readLE64((const U64*)p, endian) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 32) // fill in tmp buffer + { + XXH_memcpy(state->memory + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) // some data left from previous update + { + XXH_memcpy(state->memory + state->memsize, input, 32-state->memsize); + { + const BYTE* ps = (const BYTE*)state->memory; + state->v1 += XXH_get64bits(ps) * PRIME64_2; + state->v1 = XXH_rotl64(state->v1, 31); + state->v1 *= PRIME64_1; + ps+=8; + state->v2 += XXH_get64bits(ps) * PRIME64_2; + state->v2 = XXH_rotl64(state->v2, 31); + state->v2 *= PRIME64_1; + ps+=8; + state->v3 += XXH_get64bits(ps) * PRIME64_2; + state->v3 = XXH_rotl64(state->v3, 31); + state->v3 *= PRIME64_1; + ps+=8; + state->v4 += XXH_get64bits(ps) * PRIME64_2; + state->v4 = XXH_rotl64(state->v4, 31); + state->v4 *= PRIME64_1; + ps+=8; + } + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) + { + const BYTE* const limit = bEnd - 32; + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + do + { + v1 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + v2 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v2 = XXH_rotl64(v2, 31); + v2 *= PRIME64_1; + v3 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v3 = XXH_rotl64(v3, 31); + v3 *= PRIME64_1; + v4 += XXH_get64bits(p) * PRIME64_2; + p+=8; + v4 = XXH_rotl64(v4, 31); + v4 *= PRIME64_1; + } + while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) + { + XXH_memcpy(state->memory, p, bEnd-p); + state->memsize = (int)(bEnd-p); + } + + return XXH_OK; + +#undef XXH_get64bits +} + +XXH_errorcode XXH128_update (XXH128_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH128_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH128_update_endian(state_in, input, len, XXH_bigEndian); +} + + +FORCE_INLINE void XXH128_digest_endian (const XXH128_state_t* state_in, XXH_endianess endian, void* out) +{ + (void)endian; + XXH_istate128_t * state = (XXH_istate128_t *) state_in; + const BYTE * p = (const BYTE*)state->memory; + U64 h1, h2; + + if (state->total_len >= 32) + { + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + v1 *= PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + h1 = v1; + h2 = ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_4; + + v2 *= PRIME64_2; + v2 = XXH_rotl64(v2, 33); + v2 *= PRIME64_1; + h2 ^= v2; + h1 ^= ( XXH_rotl64(h2, 27) + h2 ) * PRIME64_1 + PRIME64_4; + + v3 *= PRIME64_2; + v3 = XXH_rotl64(v3, 29); + v3 *= PRIME64_1; + h1 ^= v3; + h2 ^= ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = XXH_rotl64(v4, 27); + v4 *= PRIME64_1; + h2 ^= v4; + h1 ^= ( XXH_rotl64(h2, 27) + h2 ) * PRIME64_1 + PRIME64_4; + } + else + { + h1 = state->seed + PRIME64_5; + h2 = state->seed + PRIME64_1; + } + + switch(state->total_len & 31) + { + case 31: h2 ^= ((U64)p[30]) << 48; + /* fall-through */ + case 30: h2 ^= ((U64)p[29]) << 40; + /* fall-through */ + case 29: h2 ^= ((U64)p[28]) << 32; + /* fall-through */ + case 28: h2 ^= ((U64)p[27]) << 24; + /* fall-through */ + case 27: h2 ^= ((U64)p[26]) << 16; + /* fall-through */ + case 26: h2 ^= ((U64)p[25]) << 8; + /* fall-through */ + case 25: h2 ^= ((U64)p[24]) << 0; + h1 ^= XXH_rotl64(h2 * PRIME64_2, 11) * PRIME64_1; + /* fall-through */ + case 24: h1 ^= ((U64)p[23]) << 56; + /* fall-through */ + case 23: h1 ^= ((U64)p[22]) << 48; + /* fall-through */ + case 22: h1 ^= ((U64)p[21]) << 40; + /* fall-through */ + case 21: h1 ^= ((U64)p[20]) << 32; + /* fall-through */ + case 20: h1 ^= ((U64)p[19]) << 24; + /* fall-through */ + case 19: h1 ^= ((U64)p[18]) << 16; + /* fall-through */ + case 18: h1 ^= ((U64)p[17]) << 8; + /* fall-through */ + case 17: h1 ^= ((U64)p[16]) << 0; + h2 ^= XXH_rotl64(h1 * PRIME64_2, 11) * PRIME64_1; + /* fall-through */ + case 16: h2 ^= ((U64)p[15]) << 56; + /* fall-through */ + case 15: h2 ^= ((U64)p[14]) << 48; + /* fall-through */ + case 14: h2 ^= ((U64)p[13]) << 40; + /* fall-through */ + case 13: h2 ^= ((U64)p[12]) << 32; + /* fall-through */ + case 12: h2 ^= ((U64)p[11]) << 24; + /* fall-through */ + case 11: h2 ^= ((U64)p[10]) << 16; + /* fall-through */ + case 10: h2 ^= ((U64)p[9]) << 8; + /* fall-through */ + case 9: h2 ^= ((U64)p[8]) << 0; + h1 ^= XXH_rotl64(h2 * PRIME64_2, 11) * PRIME64_1; + /* fall-through */ + case 8: h1 ^= ((U64)p[7]) << 56; + /* fall-through */ + case 7: h1 ^= ((U64)p[6]) << 48; + /* fall-through */ + case 6: h1 ^= ((U64)p[5]) << 40; + /* fall-through */ + case 5: h1 ^= ((U64)p[4]) << 32; + /* fall-through */ + case 4: h1 ^= ((U64)p[3]) << 24; + /* fall-through */ + case 3: h1 ^= ((U64)p[2]) << 16; + /* fall-through */ + case 2: h1 ^= ((U64)p[1]) << 8; + /* fall-through */ + case 1: h1 ^= ((U64)p[0]) << 0; + h2 ^= XXH_rotl64(h1 * PRIME64_5, 11) * PRIME64_1; + /* fall-through */ + } + + h1 = XXH_rotl64(h2, 27) * PRIME64_1 + PRIME64_4; + + h1 += (U64) state->total_len; + h2 += (U64) state->total_len; + + h2 ^= h1 >> 33; + h2 *= PRIME64_2; + h1 ^= h2 >> 29; + h1 *= PRIME64_3; + h2 ^= h1 >> 32; + + ((U64*)out)[0] = h1; + ((U64*)out)[1] = h2; +} + +void XXH128_digest (const XXH128_state_t* state_in, void* out) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH128_digest_endian(state_in, XXH_littleEndian, (unsigned long long*)out); + else + return XXH128_digest_endian(state_in, XXH_bigEndian, (unsigned long long*)out); +} + + +FORCE_INLINE XXH_errorcode XXH256_update_endian (XXH256_state_t* state_in, const void* input, size_t len, XXH_endianess endian) +{ + XXH_istate256_t * state = (XXH_istate256_t *) state_in; + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 32) // fill in tmp buffer + { + XXH_memcpy(state->memory + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) // some data left from previous update + { + XXH_memcpy(state->memory + state->memsize, input, 32-state->memsize); + { + const U64* p64 = (const U64*)state->memory; + state->v1 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v1 = XXH_rotl64(state->v1, 31); + state->v1 *= PRIME64_1; + p64++; + state->v2 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v2 = XXH_rotl64(state->v2, 31); + state->v2 *= PRIME64_1; + p64++; + state->v3 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v3 = XXH_rotl64(state->v3, 31); + state->v3 *= PRIME64_1; + p64++; + state->v4 += XXH_readLE64(p64, endian) * PRIME64_2; + state->v4 = XXH_rotl64(state->v4, 31); + state->v4 *= PRIME64_1; + p64++; + } + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) + { + const BYTE* const limit = bEnd - 32; + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + do + { + v1 += XXH_readLE64((const U64*)p+0, endian) * PRIME64_2; + v1 = XXH_rotl64(v1, 31) * PRIME64_1; + + v2 += XXH_readLE64((const U64*)p+1, endian) * PRIME64_2; + v2 = XXH_rotl64(v2, 31) * PRIME64_1; + + v3 += XXH_readLE64((const U64*)p+2, endian) * PRIME64_2; + v3 = XXH_rotl64(v3, 31) * PRIME64_1; + + v4 += XXH_readLE64((const U64*)p+3, endian) * PRIME64_2; + v4 = XXH_rotl64(v4, 31) * PRIME64_1; + + p+=32; + } + while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) + { + XXH_memcpy(state->memory, p, bEnd-p); + state->memsize = (int)(bEnd-p); + } + + return XXH_OK; +} + +XXH_errorcode XXH256_update (XXH256_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH256_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH256_update_endian(state_in, input, len, XXH_bigEndian); +} + + +FORCE_INLINE void XXH256_digest_endian (const XXH256_state_t* state_in, XXH_endianess endian, void* out) +{ + (void)endian; + XXH_istate256_t * state = (XXH_istate256_t *) state_in; + const BYTE * p = (const BYTE*)state->memory; + U64 h1, h2, h3, h4; + + if (state->total_len >= 32) + { + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + v1 *= PRIME64_2; + v1 = XXH_rotl64(v1, 31); + v1 *= PRIME64_1; + h1 = v1; + h2 = ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_2; + + v2 *= PRIME64_2; + v2 = XXH_rotl64(v2, 33); + v2 *= PRIME64_1; + h2 ^= v2; + h3 = ( XXH_rotl64(h2, 29) + h2 ) * PRIME64_2 + PRIME64_3; + + v3 *= PRIME64_2; + v3 = XXH_rotl64(v3, 29); + v3 *= PRIME64_1; + h3 ^= v3; + h4 = ( XXH_rotl64(h3, 31) + h3 ) * PRIME64_3 + PRIME64_4; + + v4 *= PRIME64_2; + v4 = XXH_rotl64(v4, 27); + v4 *= PRIME64_1; + h4 ^= v4; + h1 ^= ( XXH_rotl64(h4, 33) + h4 ) * PRIME64_4 + PRIME64_5; + } + else + { + h1 = state->seed + PRIME64_5; + h2 = state->seed + PRIME64_1; + h3 = state->seed + PRIME64_4; + h4 = state->seed + PRIME64_2; + } + + switch(state->total_len & 31) + { + case 31: h4 ^= ((U64)p[30]) << 48; + /* fall-through */ + case 30: h4 ^= ((U64)p[29]) << 40; + /* fall-through */ + case 29: h4 ^= ((U64)p[28]) << 32; + /* fall-through */ + case 28: h4 ^= ((U64)p[27]) << 24; + /* fall-through */ + case 27: h4 ^= ((U64)p[26]) << 16; + /* fall-through */ + case 26: h4 ^= ((U64)p[25]) << 8; + /* fall-through */ + case 25: h4 ^= ((U64)p[24]) << 0; + h3 ^= XXH_rotl64(h4 * PRIME64_5, 17) * PRIME64_1; + /* fall-through */ + case 24: h3 ^= ((U64)p[23]) << 56; + /* fall-through */ + case 23: h3 ^= ((U64)p[22]) << 48; + /* fall-through */ + case 22: h3 ^= ((U64)p[21]) << 40; + /* fall-through */ + case 21: h3 ^= ((U64)p[20]) << 32; + /* fall-through */ + case 20: h3 ^= ((U64)p[19]) << 24; + /* fall-through */ + case 19: h3 ^= ((U64)p[18]) << 16; + /* fall-through */ + case 18: h3 ^= ((U64)p[17]) << 8; + /* fall-through */ + case 17: h3 ^= ((U64)p[16]) << 0; + h2 ^= XXH_rotl64(h3 * PRIME64_5, 13) * PRIME64_1; + /* fall-through */ + case 16: h2 ^= ((U64)p[15]) << 56; + /* fall-through */ + case 15: h2 ^= ((U64)p[14]) << 48; + /* fall-through */ + case 14: h2 ^= ((U64)p[13]) << 40; + /* fall-through */ + case 13: h2 ^= ((U64)p[12]) << 32; + /* fall-through */ + case 12: h2 ^= ((U64)p[11]) << 24; + /* fall-through */ + case 11: h2 ^= ((U64)p[10]) << 16; + /* fall-through */ + case 10: h2 ^= ((U64)p[9]) << 8; + /* fall-through */ + case 9: h2 ^= ((U64)p[8]) << 0; + h1 ^= XXH_rotl64(h2 * PRIME64_5, 11) * PRIME64_1; + /* fall-through */ + case 8: h1 ^= ((U64)p[7]) << 56; + /* fall-through */ + case 7: h1 ^= ((U64)p[6]) << 48; + /* fall-through */ + case 6: h1 ^= ((U64)p[5]) << 40; + /* fall-through */ + case 5: h1 ^= ((U64)p[4]) << 32; + /* fall-through */ + case 4: h1 ^= ((U64)p[3]) << 24; + /* fall-through */ + case 3: h1 ^= ((U64)p[2]) << 16; + /* fall-through */ + case 2: h1 ^= ((U64)p[1]) << 8; + /* fall-through */ + case 1: h1 ^= ((U64)p[0]) << 0; + h4 ^= XXH_rotl64(h1 * PRIME64_5, 7) * PRIME64_1; + /* fall-through */ + } + + h2 ^= ( XXH_rotl64(h1, 27) + h1 ) * PRIME64_1 + PRIME64_4; + h3 ^= ( XXH_rotl64(h2, 29) + h2 ) * PRIME64_2 + PRIME64_3; + h4 ^= ( XXH_rotl64(h3, 31) + h3 ) * PRIME64_3 + PRIME64_2; + h1 ^= ( XXH_rotl64(h4, 33) + h4 ) * PRIME64_4 + PRIME64_1; + + h1 += (U64) state->total_len; + h2 += (U64) state->total_len; + h3 += (U64) state->total_len; + h4 += (U64) state->total_len; + + h4 ^= h1 >> 33; + h4 *= PRIME64_2; + h1 ^= h4 >> 29; + h1 *= PRIME64_3; + h4 ^= h1 >> 32; + + h3 ^= h2 >> 33; + h3 *= PRIME64_2; + h2 ^= h3 >> 29; + h2 *= PRIME64_3; + h3 ^= h2 >> 32; + + ((unsigned long long*)out)[0] = h1; + ((unsigned long long*)out)[1] = h2; + ((unsigned long long*)out)[2] = h3; + ((unsigned long long*)out)[3] = h4; +} + +void XXH256_digest (const XXH256_state_t* state_in, void* out) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH256_digest_endian(state_in, XXH_littleEndian, (unsigned long long*)out); + else + return XXH256_digest_endian(state_in, XXH_bigEndian, (unsigned long long*)out); +} diff --git a/src/xxhash/xxhash.h b/src/xxhash/xxhash.h new file mode 100644 index 0000000..3dc3967 --- /dev/null +++ b/src/xxhash/xxhash.h @@ -0,0 +1,193 @@ +#ifndef XXHASH_H +#define XXHASH_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* + xxHash - Extremely Fast Hash algorithm + Header File + Copyright (C) 2012-2014, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash source repository : http://code.google.com/p/xxhash/ + + Modified for internal use for libfyaml by: + Pantelis Antoniou + + Minor cosmetic and warning fixes +*/ + +/* Notice extracted from xxHash homepage : + +xxHash is an extremely fast Hash algorithm, running at RAM speed limits. +It also successfully passes all tests from the SMHasher suite. + +Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) + +Name Speed Q.Score Author +xxHash 5.4 GB/s 10 +CrapWow 3.2 GB/s 2 Andrew +MumurHash 3a 2.7 GB/s 10 Austin Appleby +SpookyHash 2.0 GB/s 10 Bob Jenkins +SBox 1.4 GB/s 9 Bret Mulvey +Lookup3 1.2 GB/s 9 Bob Jenkins +SuperFastHash 1.2 GB/s 1 Paul Hsieh +CityHash64 1.05 GB/s 10 Pike & Alakuijala +FNV 0.55 GB/s 5 Fowler, Noll, Vo +CRC32 0.43 GB/s 9 +MD5-32 0.33 GB/s 10 Ronald L. Rivest +SHA1-32 0.28 GB/s 10 + +Q.Score is a measure of quality of the hash function. +It depends on successfully passing SMHasher test set. +10 is a perfect score. +*/ + +#pragma once + +#if defined (__cplusplus) +extern "C" { +#endif + + +/***************************** + Includes +*****************************/ +#include /* size_t */ + + +/***************************** + Type +*****************************/ +typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; + + + +/***************************** + Simple Hash Functions +*****************************/ + +unsigned int XXH32 (const void* input, size_t length, unsigned seed); +unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); +void XXH128 (const void* input, size_t length, unsigned long long seed, void* out); +void XXH256 (const void* input, size_t length, unsigned long long seed, void* out); + +/* +XXH32() : + Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". + The memory between input & input+length must be valid (allocated and read-accessible). + "seed" can be used to alter the result predictably. + This function successfully passes all SMHasher tests. + Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s +XXH64() : + Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". +XXH128(): + Calculate the 128-bits hash of sequence of length "len" stored at memory address "input". + Output is stored in the 16 byte array "out" +XXH256(): + Calculate the 256-bits hash of sequence of length "len" stored at memory address "input". + Output is stored in the 32 byte array "out" +*/ + + + +/***************************** + Advanced Hash Functions +*****************************/ +typedef struct { long long ll[ 6]; } XXH32_state_t; +typedef struct { long long ll[11]; } XXH64_state_t; +typedef struct { long long ll[28]; } XXH128_state_t; +typedef struct { long long ll[28]; } XXH256_state_t; + +/* +These structures allow static allocation of XXH states. +States must then be initialized using XXHnn_reset() before first use. + +If you prefer dynamic allocation, please refer to functions below. +*/ + +XXH32_state_t* XXH32_createState(void); +XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); + +XXH64_state_t* XXH64_createState(void); +XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); + +XXH128_state_t* XXH128_createState(void); +XXH_errorcode XXH128_freeState(XXH128_state_t* statePtr); + +XXH256_state_t* XXH256_createState(void); +XXH_errorcode XXH256_freeState(XXH256_state_t* statePtr); + +/* +These functions create and release memory for XXH state. +States must then be initialized using XXHnn_reset() before first use. +*/ + + +XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed); +XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); +unsigned int XXH32_digest (const XXH32_state_t* statePtr); + +XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); +XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); +unsigned long long XXH64_digest (const XXH64_state_t* statePtr); + +XXH_errorcode XXH128_reset (XXH128_state_t* statePtr, unsigned long long seed); +XXH_errorcode XXH128_update (XXH128_state_t* statePtr, const void* input, size_t length); +void XXH128_digest (const XXH128_state_t* statePtr, void* out); + +XXH_errorcode XXH256_reset (XXH256_state_t* statePtr, unsigned long long seed); +XXH_errorcode XXH256_update (XXH256_state_t* statePtr, const void* input, size_t length); +void XXH256_digest (const XXH256_state_t* statePtr, void* out); + +/* +These functions calculate the xxHash of an input provided in multiple smaller packets, +as opposed to an input provided as a single block. + +XXH state space must first be allocated, using either static or dynamic method provided above. + +Start a new hash by initializing state with a seed, using XXHnn_reset(). + +Then, feed the hash state by calling XXHnn_update() as many times as necessary. +Obviously, input must be valid, meaning allocated and read accessible. +The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. + +Finally, you can produce a hash anytime, by using XXHnn_digest(). +This function returns the final nn-bits hash. +You can nonetheless continue feeding the hash state with more input, +and therefore get some new hashes, by calling again XXHnn_digest(). + +When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). +*/ + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..0c87edf --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,296 @@ +# test-suite (run with 'make check') + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include +AM_CFLAGS = + +AM_TESTS_ENVIRONMENT= \ + TOP_SRCDIR="${top_srcdir}" \ + TOP_BUILDDIR="${top_builddir}" \ + SRCDIR="${srcdir}" \ + BUILDDIR="${builddir}" \ + JQ="@JQ@" + +TESTS_ENVIRONMENT= \ + TOP_SRCDIR="${top_srcdir}" \ + TOP_BUILDDIR="${top_builddir}" \ + SRCDIR="${srcdir}" \ + BUILDDIR="${builddir}" \ + JQ="@JQ@" + +# TEST_EXTENSIONS = .test + +TEST_LOG_COMPILE = $(SHELL) +TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/build-aux/tap-driver.sh + +TESTS = + +if HAVE_COMPATIBLE_CHECK + +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_CFLAGS = $(AM_CFLAGS) $(CHECK_CFLAGS) +libfyaml_test_LDFLAGS = $(AM_LDFLAGS) $(CHECK_LDFLAGS) + +libfyaml_test_SOURCES = \ + libfyaml-test.c \ + libfyaml-test-private.c \ + libfyaml-test-core.c \ + libfyaml-test-meta.c \ + libfyaml-test-emit.c + +TESTS += libfyaml.test + +endif + +if HAVE_NETWORK +if HAVE_GIT + +# normal YAML testsuite +TESTS += testsuite.test + +# YAML testsuite JSON generation +if HAVE_JQ +TESTS += testsuite-json.test +endif + +# normal JSON testsuite +TESTS += jsontestsuite.test + +testsuite.test: test-suite-data json-test-suite-data + +test-suite-data: + @GIT@ clone "@TESTSUITEURL@" -- $@ && \ + cd $@ && \ + @GIT@ checkout --detach @TESTSUITECHECKOUT@ + +jsontestsuite.test: json-test-suite-data + +json-test-suite-data: + @GIT@ clone "@JSONTESTSUITEURL@" -- $@ && \ + cd $@ && \ + @GIT@ checkout --detach @JSONTESTSUITECHECKOUT@ + +check-local: test-suite-data json-test-suite-data + +distclean-local: + @rm -rf test-suite-data json-test-suite-data + +endif +endif + +TESTS += testerrors.test + +TESTS += testemitter.test +TESTS += testemitter-streaming.test + +EXTRA_DIST = test-env $(TESTS) + +# Add the error test files +EXTRA_DIST += \ + test-errors/0002/=== \ + test-errors/0002/in.yaml \ + test-errors/0002/test.error \ + test-errors/0003/=== \ + test-errors/0003/in.yaml \ + test-errors/0003/test.error \ + test-errors/0004/=== \ + test-errors/0004/in.yaml \ + test-errors/0004/test.error \ + test-errors/0005/=== \ + test-errors/0005/in.yaml \ + test-errors/0005/test.error \ + test-errors/0006/=== \ + test-errors/0006/in.yaml \ + test-errors/0006/test.error \ + test-errors/0007/=== \ + test-errors/0007/in.yaml \ + test-errors/0007/test.error \ + test-errors/0008/=== \ + test-errors/0008/in.yaml \ + test-errors/0008/test.error \ + test-errors/0009/=== \ + test-errors/0009/in.yaml \ + test-errors/0009/test.error \ + test-errors/0010/=== \ + test-errors/0010/in.yaml \ + test-errors/0010/test.error \ + test-errors/0011/=== \ + test-errors/0011/in.yaml \ + test-errors/0011/test.error + +# Add the emitter test files +EXTRA_DIST += \ + emitter-examples/anchors-1.yaml \ + emitter-examples/anchors-2.yaml \ + emitter-examples/anchors-3.yaml \ + emitter-examples/anchors-4.1.yaml \ + emitter-examples/anchors-4.yaml \ + emitter-examples/anchors-on-empty-scalars1.yaml \ + emitter-examples/anchors-on-empty-scalars2.yaml \ + emitter-examples/anchors-on-empty-scalars3.yaml \ + emitter-examples/anchors-on-empty-scalars4.yaml \ + emitter-examples/anchors-on-empty-scalars.yaml \ + emitter-examples/anchors.yaml \ + emitter-examples/array.yaml \ + emitter-examples/block2.yaml \ + emitter-examples/block3.yaml \ + emitter-examples/block4.yaml \ + emitter-examples/block6.yaml \ + emitter-examples/block7.yaml \ + emitter-examples/blocked.yaml \ + emitter-examples/blockind.yaml \ + emitter-examples/block.yaml \ + emitter-examples/c10.yaml \ + emitter-examples/c11.yaml \ + emitter-examples/c12.yaml \ + emitter-examples/c13.yaml \ + emitter-examples/c1.yaml \ + emitter-examples/c2.yaml \ + emitter-examples/c3.yaml \ + emitter-examples/c4.yaml \ + emitter-examples/c5.yaml \ + emitter-examples/c6.yaml \ + emitter-examples/c7.yaml \ + emitter-examples/c8.yaml \ + emitter-examples/c9.yaml \ + emitter-examples/compact1.yaml \ + emitter-examples/compactblockmap.yaml \ + emitter-examples/complexkey2.yaml \ + emitter-examples/complexkey3.yaml \ + emitter-examples/complexkey4.yaml \ + emitter-examples/complexkey5.yaml \ + emitter-examples/complexkey6.yaml \ + emitter-examples/complexkey7.yaml \ + emitter-examples/complexkey8.yaml \ + emitter-examples/complexkey9.yaml \ + emitter-examples/complexkey.yaml \ + emitter-examples/docstartend.yaml \ + emitter-examples/dqscalar.yaml \ + emitter-examples/dqzero.yaml \ + emitter-examples/emoji.yaml \ + emitter-examples/emptydoc.yaml \ + emitter-examples/emptykey.yaml \ + emitter-examples/emptystream.yaml \ + emitter-examples/flow1.yaml \ + emitter-examples/flow2.yaml \ + emitter-examples/flow.yaml \ + emitter-examples/fold2.yaml \ + emitter-examples/fold3.yaml \ + emitter-examples/fold4.yaml \ + emitter-examples/fold5.yaml \ + emitter-examples/folded2.yaml \ + emitter-examples/folded.yaml \ + emitter-examples/folding.yaml \ + emitter-examples/fold.yaml \ + emitter-examples/global-tag.yaml \ + emitter-examples/invoice.yaml \ + emitter-examples/json.yaml \ + emitter-examples/keyflow.yaml \ + emitter-examples/keykey2.yaml \ + emitter-examples/keykey.yaml \ + emitter-examples/line.yaml \ + emitter-examples/literal1.yaml \ + emitter-examples/literal2.yaml \ + emitter-examples/literal3.yaml \ + emitter-examples/literal4.yaml \ + emitter-examples/literal.yaml \ + emitter-examples/mapping.yaml \ + emitter-examples/mergekeyspec.yaml \ + emitter-examples/multi-document.yaml \ + emitter-examples/multiline-quoted-key.yaml \ + emitter-examples/multiline-simple-key.yaml \ + emitter-examples/nodeprop2.yaml \ + emitter-examples/nodeprop.yaml \ + emitter-examples/numbers-flow.yaml \ + emitter-examples/numbers.yaml \ + emitter-examples/plainlines.yaml \ + emitter-examples/plainscalar.yaml \ + emitter-examples/quotedbackslash.yaml \ + emitter-examples/quoted.yaml \ + emitter-examples/scalar-multiline.yaml \ + emitter-examples/scalars2.yaml \ + emitter-examples/scalar-singlequoted.yaml \ + emitter-examples/scalar-space1.yaml \ + emitter-examples/scalar-space.yaml \ + emitter-examples/scalars.yaml \ + emitter-examples/scanner-c-10.yaml \ + emitter-examples/scanner-c-11.yaml \ + emitter-examples/scanner-c-12.yaml \ + emitter-examples/scanner-c-13.yaml \ + emitter-examples/scanner-c-1.yaml \ + emitter-examples/scanner-c-2.yaml \ + emitter-examples/scanner-c-3.yaml \ + emitter-examples/scanner-c-4.yaml \ + emitter-examples/scanner-c-5.yaml \ + emitter-examples/scanner-c-6.yaml \ + emitter-examples/scanner-c-7.yaml \ + emitter-examples/scanner-c-8-2.yaml \ + emitter-examples/scanner-c-8.yaml \ + emitter-examples/scanner-c-9.yaml \ + emitter-examples/seq1.yaml \ + emitter-examples/seq2.yaml \ + emitter-examples/seq3.yaml \ + emitter-examples/seq4.yaml \ + emitter-examples/seq5.yaml \ + emitter-examples/seq6.yaml \ + emitter-examples/seq.yaml \ + emitter-examples/sets.yaml \ + emitter-examples/simple1.yaml \ + emitter-examples/simple2.yaml \ + emitter-examples/simpleanchor1.yaml \ + emitter-examples/simpleanchor2.yaml \ + emitter-examples/simpleanchor3.yaml \ + emitter-examples/simpleanchor4.yaml \ + emitter-examples/simpleanchor.yaml \ + emitter-examples/simplefolded.yaml \ + emitter-examples/simplekey1.yaml \ + emitter-examples/simplekey2.yaml \ + emitter-examples/simplekey3.yaml \ + emitter-examples/simplekey4.yaml \ + emitter-examples/simplekey5.yaml \ + emitter-examples/simplekey.yaml \ + emitter-examples/simpleliteral.yaml \ + emitter-examples/simpleseq1.yaml \ + emitter-examples/simpleseq.yaml \ + emitter-examples/simple.yaml \ + emitter-examples/singlepairimp2.yaml \ + emitter-examples/singlepairimp.yaml \ + emitter-examples/sqscalarspace.yaml \ + emitter-examples/sqscalar.yaml \ + emitter-examples/strings.yaml \ + emitter-examples/t1.yaml \ + emitter-examples/t2.yaml \ + emitter-examples/t3.yaml \ + emitter-examples/t4.yaml \ + emitter-examples/t5.yaml \ + emitter-examples/tabsmix.yaml \ + emitter-examples/tagdirective.yaml \ + emitter-examples/tagesc.yaml \ + emitter-examples/tags-1.yaml \ + emitter-examples/tags.yaml \ + emitter-examples/test1.yaml \ + emitter-examples/test2.yaml \ + emitter-examples/test.yaml \ + emitter-examples/t.yaml \ + emitter-examples/u1.yaml \ + emitter-examples/u2.yaml \ + emitter-examples/u3.yaml \ + emitter-examples/utf8-simple.yaml \ + emitter-examples/utf8.yaml \ + emitter-examples/u.yaml \ + emitter-examples/v1.yaml \ + emitter-examples/v2.yaml \ + emitter-examples/version.yaml \ + emitter-examples/v.yaml \ + emitter-examples/weirdplain.yaml \ + emitter-examples/ws0.yaml \ + emitter-examples/ws1.yaml \ + emitter-examples/ws2.yaml \ + emitter-examples/ws3.yaml \ + emitter-examples/yaml-version.yaml \ + emitter-examples/y.yaml \ + emitter-examples/yy.yaml \ + emitter-examples/zeroexplicit.yaml diff --git a/test/Makefile.in b/test/Makefile.in new file mode 100644 index 0000000..c73b09d --- /dev/null +++ b/test/Makefile.in @@ -0,0 +1,1337 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# test-suite (run with 'make check') +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HAVE_COMPATIBLE_CHECK_TRUE@check_PROGRAMS = libfyaml-test$(EXEEXT) +@HAVE_COMPATIBLE_CHECK_TRUE@am__append_1 = libfyaml.test + +# normal YAML testsuite +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@am__append_2 = testsuite.test + +# YAML testsuite JSON generation +@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 +subdir = test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_enable_debug.m4 \ + $(top_srcdir)/m4/ax_check_flag.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 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__libfyaml_test_SOURCES_DIST = libfyaml-test.c \ + libfyaml-test-private.c libfyaml-test-core.c \ + libfyaml-test-meta.c libfyaml-test-emit.c +@HAVE_COMPATIBLE_CHECK_TRUE@am_libfyaml_test_OBJECTS = libfyaml_test-libfyaml-test.$(OBJEXT) \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml_test-libfyaml-test-private.$(OBJEXT) \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml_test-libfyaml-test-core.$(OBJEXT) \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml_test-libfyaml-test-meta.$(OBJEXT) \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml_test-libfyaml-test-emit.$(OBJEXT) +libfyaml_test_OBJECTS = $(am_libfyaml_test_OBJECTS) +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 +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_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libfyaml_test_CFLAGS) \ + $(CFLAGS) $(libfyaml_test_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libfyaml_test_SOURCES) +DIST_SOURCES = $(am__libfyaml_test_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__extra_recursive_targets = doc-help-recursive doc-html-recursive \ + doc-latexpdf-recursive doc-man-recursive doc-clean-recursive \ + doc-markdown-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_MAKEFLAGS = @AM_MAKEFLAGS@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LDFLAGS = @CHECK_LDFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBVERSION = @DEBVERSION@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOCKER = @DOCKER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA = @EXTRA@ +F77 = @F77@ +FC = @FC@ +FGREP = @FGREP@ +GIT = @GIT@ +GREP = @GREP@ +HAVE_CHECK = @HAVE_CHECK@ +HAVE_COMPATIBLE_CHECK = @HAVE_COMPATIBLE_CHECK@ +HAVE_LIBYAML = @HAVE_LIBYAML@ +HAVE_NETWORK = @HAVE_NETWORK@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JQ = @JQ@ +JSONTESTSUITECHECKOUT = @JSONTESTSUITECHECKOUT@ +JSONTESTSUITEURL = @JSONTESTSUITEURL@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ +LIBYAML_LIBS = @LIBYAML_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4 = @M4@ +MAJOR = @MAJOR@ +MAKEFLAGS = @MAKEFLAGS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MCS = @MCS@ +MINOR = @MINOR@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATCH = @PATCH@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PIP3 = @PIP3@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +Q = @Q@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX = @SPHINX@ +STRIP = @STRIP@ +TESTSUITECHECKOUT = @TESTSUITECHECKOUT@ +TESTSUITEURL = @TESTSUITEURL@ +V = @V@ +VERSION = @VERSION@ +YACC = @YACC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +shavedir = @shavedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include + +AM_CFLAGS = +AM_TESTS_ENVIRONMENT = \ + TOP_SRCDIR="${top_srcdir}" \ + TOP_BUILDDIR="${top_builddir}" \ + SRCDIR="${srcdir}" \ + BUILDDIR="${builddir}" \ + JQ="@JQ@" + +TESTS_ENVIRONMENT = \ + TOP_SRCDIR="${top_srcdir}" \ + TOP_BUILDDIR="${top_builddir}" \ + SRCDIR="${srcdir}" \ + BUILDDIR="${builddir}" \ + JQ="@JQ@" + + +# TEST_EXTENSIONS = .test +TEST_LOG_COMPILE = $(SHELL) +TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/build-aux/tap-driver.sh +TESTS = $(am__append_1) $(am__append_2) $(am__append_3) \ + $(am__append_4) testerrors.test testemitter.test \ + testemitter-streaming.test +@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_CFLAGS = $(AM_CFLAGS) $(CHECK_CFLAGS) +@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_LDFLAGS = $(AM_LDFLAGS) $(CHECK_LDFLAGS) +@HAVE_COMPATIBLE_CHECK_TRUE@libfyaml_test_SOURCES = \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml-test.c \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml-test-private.c \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml-test-core.c \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml-test-meta.c \ +@HAVE_COMPATIBLE_CHECK_TRUE@ libfyaml-test-emit.c + + +# Add the error test files + +# Add the emitter test files +EXTRA_DIST = test-env $(TESTS) test-errors/0002/=== \ + test-errors/0002/in.yaml test-errors/0002/test.error \ + test-errors/0003/=== test-errors/0003/in.yaml \ + test-errors/0003/test.error test-errors/0004/=== \ + test-errors/0004/in.yaml test-errors/0004/test.error \ + test-errors/0005/=== test-errors/0005/in.yaml \ + test-errors/0005/test.error test-errors/0006/=== \ + test-errors/0006/in.yaml test-errors/0006/test.error \ + test-errors/0007/=== test-errors/0007/in.yaml \ + test-errors/0007/test.error test-errors/0008/=== \ + test-errors/0008/in.yaml test-errors/0008/test.error \ + test-errors/0009/=== test-errors/0009/in.yaml \ + test-errors/0009/test.error test-errors/0010/=== \ + test-errors/0010/in.yaml test-errors/0010/test.error \ + test-errors/0011/=== test-errors/0011/in.yaml \ + test-errors/0011/test.error emitter-examples/anchors-1.yaml \ + emitter-examples/anchors-2.yaml \ + emitter-examples/anchors-3.yaml \ + emitter-examples/anchors-4.1.yaml \ + emitter-examples/anchors-4.yaml \ + emitter-examples/anchors-on-empty-scalars1.yaml \ + emitter-examples/anchors-on-empty-scalars2.yaml \ + emitter-examples/anchors-on-empty-scalars3.yaml \ + emitter-examples/anchors-on-empty-scalars4.yaml \ + emitter-examples/anchors-on-empty-scalars.yaml \ + emitter-examples/anchors.yaml emitter-examples/array.yaml \ + emitter-examples/block2.yaml emitter-examples/block3.yaml \ + emitter-examples/block4.yaml emitter-examples/block6.yaml \ + emitter-examples/block7.yaml emitter-examples/blocked.yaml \ + emitter-examples/blockind.yaml emitter-examples/block.yaml \ + emitter-examples/c10.yaml emitter-examples/c11.yaml \ + emitter-examples/c12.yaml emitter-examples/c13.yaml \ + emitter-examples/c1.yaml emitter-examples/c2.yaml \ + emitter-examples/c3.yaml emitter-examples/c4.yaml \ + emitter-examples/c5.yaml emitter-examples/c6.yaml \ + emitter-examples/c7.yaml emitter-examples/c8.yaml \ + emitter-examples/c9.yaml emitter-examples/compact1.yaml \ + emitter-examples/compactblockmap.yaml \ + emitter-examples/complexkey2.yaml \ + emitter-examples/complexkey3.yaml \ + emitter-examples/complexkey4.yaml \ + emitter-examples/complexkey5.yaml \ + emitter-examples/complexkey6.yaml \ + emitter-examples/complexkey7.yaml \ + emitter-examples/complexkey8.yaml \ + emitter-examples/complexkey9.yaml \ + emitter-examples/complexkey.yaml \ + emitter-examples/docstartend.yaml \ + emitter-examples/dqscalar.yaml emitter-examples/dqzero.yaml \ + emitter-examples/emoji.yaml emitter-examples/emptydoc.yaml \ + emitter-examples/emptykey.yaml \ + emitter-examples/emptystream.yaml emitter-examples/flow1.yaml \ + emitter-examples/flow2.yaml emitter-examples/flow.yaml \ + emitter-examples/fold2.yaml emitter-examples/fold3.yaml \ + emitter-examples/fold4.yaml emitter-examples/fold5.yaml \ + emitter-examples/folded2.yaml emitter-examples/folded.yaml \ + emitter-examples/folding.yaml emitter-examples/fold.yaml \ + emitter-examples/global-tag.yaml emitter-examples/invoice.yaml \ + emitter-examples/json.yaml emitter-examples/keyflow.yaml \ + emitter-examples/keykey2.yaml emitter-examples/keykey.yaml \ + emitter-examples/line.yaml emitter-examples/literal1.yaml \ + emitter-examples/literal2.yaml emitter-examples/literal3.yaml \ + emitter-examples/literal4.yaml emitter-examples/literal.yaml \ + emitter-examples/mapping.yaml \ + emitter-examples/mergekeyspec.yaml \ + emitter-examples/multi-document.yaml \ + emitter-examples/multiline-quoted-key.yaml \ + emitter-examples/multiline-simple-key.yaml \ + emitter-examples/nodeprop2.yaml emitter-examples/nodeprop.yaml \ + emitter-examples/numbers-flow.yaml \ + emitter-examples/numbers.yaml emitter-examples/plainlines.yaml \ + emitter-examples/plainscalar.yaml \ + emitter-examples/quotedbackslash.yaml \ + emitter-examples/quoted.yaml \ + emitter-examples/scalar-multiline.yaml \ + emitter-examples/scalars2.yaml \ + emitter-examples/scalar-singlequoted.yaml \ + emitter-examples/scalar-space1.yaml \ + emitter-examples/scalar-space.yaml \ + emitter-examples/scalars.yaml \ + emitter-examples/scanner-c-10.yaml \ + emitter-examples/scanner-c-11.yaml \ + emitter-examples/scanner-c-12.yaml \ + emitter-examples/scanner-c-13.yaml \ + emitter-examples/scanner-c-1.yaml \ + emitter-examples/scanner-c-2.yaml \ + emitter-examples/scanner-c-3.yaml \ + emitter-examples/scanner-c-4.yaml \ + emitter-examples/scanner-c-5.yaml \ + emitter-examples/scanner-c-6.yaml \ + emitter-examples/scanner-c-7.yaml \ + emitter-examples/scanner-c-8-2.yaml \ + emitter-examples/scanner-c-8.yaml \ + emitter-examples/scanner-c-9.yaml emitter-examples/seq1.yaml \ + emitter-examples/seq2.yaml emitter-examples/seq3.yaml \ + emitter-examples/seq4.yaml emitter-examples/seq5.yaml \ + emitter-examples/seq6.yaml emitter-examples/seq.yaml \ + emitter-examples/sets.yaml emitter-examples/simple1.yaml \ + emitter-examples/simple2.yaml \ + emitter-examples/simpleanchor1.yaml \ + emitter-examples/simpleanchor2.yaml \ + emitter-examples/simpleanchor3.yaml \ + emitter-examples/simpleanchor4.yaml \ + emitter-examples/simpleanchor.yaml \ + emitter-examples/simplefolded.yaml \ + emitter-examples/simplekey1.yaml \ + emitter-examples/simplekey2.yaml \ + emitter-examples/simplekey3.yaml \ + emitter-examples/simplekey4.yaml \ + emitter-examples/simplekey5.yaml \ + emitter-examples/simplekey.yaml \ + emitter-examples/simpleliteral.yaml \ + emitter-examples/simpleseq1.yaml \ + emitter-examples/simpleseq.yaml emitter-examples/simple.yaml \ + emitter-examples/singlepairimp2.yaml \ + emitter-examples/singlepairimp.yaml \ + emitter-examples/sqscalarspace.yaml \ + emitter-examples/sqscalar.yaml emitter-examples/strings.yaml \ + emitter-examples/t1.yaml emitter-examples/t2.yaml \ + emitter-examples/t3.yaml emitter-examples/t4.yaml \ + emitter-examples/t5.yaml emitter-examples/tabsmix.yaml \ + emitter-examples/tagdirective.yaml \ + emitter-examples/tagesc.yaml emitter-examples/tags-1.yaml \ + emitter-examples/tags.yaml emitter-examples/test1.yaml \ + emitter-examples/test2.yaml emitter-examples/test.yaml \ + emitter-examples/t.yaml emitter-examples/u1.yaml \ + emitter-examples/u2.yaml emitter-examples/u3.yaml \ + emitter-examples/utf8-simple.yaml emitter-examples/utf8.yaml \ + emitter-examples/u.yaml emitter-examples/v1.yaml \ + emitter-examples/v2.yaml emitter-examples/version.yaml \ + emitter-examples/v.yaml emitter-examples/weirdplain.yaml \ + emitter-examples/ws0.yaml emitter-examples/ws1.yaml \ + emitter-examples/ws2.yaml emitter-examples/ws3.yaml \ + emitter-examples/yaml-version.yaml emitter-examples/y.yaml \ + emitter-examples/yy.yaml emitter-examples/zeroexplicit.yaml +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +libfyaml-test$(EXEEXT): $(libfyaml_test_OBJECTS) $(libfyaml_test_DEPENDENCIES) $(EXTRA_libfyaml_test_DEPENDENCIES) + @rm -f libfyaml-test$(EXEEXT) + $(AM_V_CCLD)$(libfyaml_test_LINK) $(libfyaml_test_OBJECTS) $(libfyaml_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfyaml_test-libfyaml-test-core.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfyaml_test-libfyaml-test-emit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfyaml_test-libfyaml-test-meta.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfyaml_test-libfyaml-test-private.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfyaml_test-libfyaml-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libfyaml_test-libfyaml-test.o: libfyaml-test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test.o -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test.Tpo -c -o libfyaml_test-libfyaml-test.o `test -f 'libfyaml-test.c' || echo '$(srcdir)/'`libfyaml-test.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test.c' object='libfyaml_test-libfyaml-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test.o `test -f 'libfyaml-test.c' || echo '$(srcdir)/'`libfyaml-test.c + +libfyaml_test-libfyaml-test.obj: libfyaml-test.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test.obj -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test.Tpo -c -o libfyaml_test-libfyaml-test.obj `if test -f 'libfyaml-test.c'; then $(CYGPATH_W) 'libfyaml-test.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test.c' object='libfyaml_test-libfyaml-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test.obj `if test -f 'libfyaml-test.c'; then $(CYGPATH_W) 'libfyaml-test.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test.c'; fi` + +libfyaml_test-libfyaml-test-private.o: libfyaml-test-private.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-private.o -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-private.Tpo -c -o libfyaml_test-libfyaml-test-private.o `test -f 'libfyaml-test-private.c' || echo '$(srcdir)/'`libfyaml-test-private.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-private.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-private.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-private.c' object='libfyaml_test-libfyaml-test-private.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-private.o `test -f 'libfyaml-test-private.c' || echo '$(srcdir)/'`libfyaml-test-private.c + +libfyaml_test-libfyaml-test-private.obj: libfyaml-test-private.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-private.obj -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-private.Tpo -c -o libfyaml_test-libfyaml-test-private.obj `if test -f 'libfyaml-test-private.c'; then $(CYGPATH_W) 'libfyaml-test-private.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-private.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-private.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-private.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-private.c' object='libfyaml_test-libfyaml-test-private.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-private.obj `if test -f 'libfyaml-test-private.c'; then $(CYGPATH_W) 'libfyaml-test-private.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-private.c'; fi` + +libfyaml_test-libfyaml-test-core.o: libfyaml-test-core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-core.o -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-core.Tpo -c -o libfyaml_test-libfyaml-test-core.o `test -f 'libfyaml-test-core.c' || echo '$(srcdir)/'`libfyaml-test-core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-core.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-core.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-core.c' object='libfyaml_test-libfyaml-test-core.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-core.o `test -f 'libfyaml-test-core.c' || echo '$(srcdir)/'`libfyaml-test-core.c + +libfyaml_test-libfyaml-test-core.obj: libfyaml-test-core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-core.obj -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-core.Tpo -c -o libfyaml_test-libfyaml-test-core.obj `if test -f 'libfyaml-test-core.c'; then $(CYGPATH_W) 'libfyaml-test-core.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-core.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-core.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-core.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-core.c' object='libfyaml_test-libfyaml-test-core.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-core.obj `if test -f 'libfyaml-test-core.c'; then $(CYGPATH_W) 'libfyaml-test-core.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-core.c'; fi` + +libfyaml_test-libfyaml-test-meta.o: libfyaml-test-meta.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-meta.o -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-meta.Tpo -c -o libfyaml_test-libfyaml-test-meta.o `test -f 'libfyaml-test-meta.c' || echo '$(srcdir)/'`libfyaml-test-meta.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-meta.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-meta.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-meta.c' object='libfyaml_test-libfyaml-test-meta.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-meta.o `test -f 'libfyaml-test-meta.c' || echo '$(srcdir)/'`libfyaml-test-meta.c + +libfyaml_test-libfyaml-test-meta.obj: libfyaml-test-meta.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-meta.obj -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-meta.Tpo -c -o libfyaml_test-libfyaml-test-meta.obj `if test -f 'libfyaml-test-meta.c'; then $(CYGPATH_W) 'libfyaml-test-meta.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-meta.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-meta.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-meta.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-meta.c' object='libfyaml_test-libfyaml-test-meta.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-meta.obj `if test -f 'libfyaml-test-meta.c'; then $(CYGPATH_W) 'libfyaml-test-meta.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-meta.c'; fi` + +libfyaml_test-libfyaml-test-emit.o: libfyaml-test-emit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-emit.o -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-emit.Tpo -c -o libfyaml_test-libfyaml-test-emit.o `test -f 'libfyaml-test-emit.c' || echo '$(srcdir)/'`libfyaml-test-emit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-emit.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-emit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-emit.c' object='libfyaml_test-libfyaml-test-emit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-emit.o `test -f 'libfyaml-test-emit.c' || echo '$(srcdir)/'`libfyaml-test-emit.c + +libfyaml_test-libfyaml-test-emit.obj: libfyaml-test-emit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -MT libfyaml_test-libfyaml-test-emit.obj -MD -MP -MF $(DEPDIR)/libfyaml_test-libfyaml-test-emit.Tpo -c -o libfyaml_test-libfyaml-test-emit.obj `if test -f 'libfyaml-test-emit.c'; then $(CYGPATH_W) 'libfyaml-test-emit.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-emit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfyaml_test-libfyaml-test-emit.Tpo $(DEPDIR)/libfyaml_test-libfyaml-test-emit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libfyaml-test-emit.c' object='libfyaml_test-libfyaml-test-emit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfyaml_test_CPPFLAGS) $(CPPFLAGS) $(libfyaml_test_CFLAGS) $(CFLAGS) -c -o libfyaml_test-libfyaml-test-emit.obj `if test -f 'libfyaml-test-emit.c'; then $(CYGPATH_W) 'libfyaml-test-emit.c'; else $(CYGPATH_W) '$(srcdir)/libfyaml-test-emit.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +doc-help-local: +doc-html-local: +doc-latexpdf-local: +doc-man-local: +doc-clean-local: +doc-markdown-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +@HAVE_GIT_FALSE@check-local: +@HAVE_NETWORK_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@HAVE_GIT_FALSE@distclean-local: +@HAVE_NETWORK_FALSE@distclean-local: +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-local distclean-tags + +doc-clean: doc-clean-am + +doc-clean-am: doc-clean-local + +doc-help: doc-help-am + +doc-help-am: doc-help-local + +doc-html: doc-html-am + +doc-html-am: doc-html-local + +doc-latexpdf: doc-latexpdf-am + +doc-latexpdf-am: doc-latexpdf-local + +doc-man: doc-man-am + +doc-man-am: doc-man-local + +doc-markdown: doc-markdown-am + +doc-markdown-am: doc-markdown-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am \ + check-local clean clean-checkPROGRAMS clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-local distclean-tags distdir doc-clean-am \ + doc-clean-local doc-help-am doc-help-local doc-html-am \ + doc-html-local doc-latexpdf-am doc-latexpdf-local doc-man-am \ + doc-man-local doc-markdown-am doc-markdown-local dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@testsuite.test: test-suite-data json-test-suite-data + +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@test-suite-data: +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ @GIT@ clone "@TESTSUITEURL@" -- $@ && \ +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ cd $@ && \ +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ @GIT@ checkout --detach @TESTSUITECHECKOUT@ + +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@jsontestsuite.test: json-test-suite-data + +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@json-test-suite-data: +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ @GIT@ clone "@JSONTESTSUITEURL@" -- $@ && \ +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ cd $@ && \ +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ @GIT@ checkout --detach @JSONTESTSUITECHECKOUT@ + +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@check-local: test-suite-data json-test-suite-data + +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@distclean-local: +@HAVE_GIT_TRUE@@HAVE_NETWORK_TRUE@ @rm -rf test-suite-data json-test-suite-data + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/test/emitter-examples/anchors-1.yaml b/test/emitter-examples/anchors-1.yaml new file mode 100644 index 0000000..beaf8ec --- /dev/null +++ b/test/emitter-examples/anchors-1.yaml @@ -0,0 +1,2 @@ +base: &base + name: this-is-a-name diff --git a/test/emitter-examples/anchors-2.yaml b/test/emitter-examples/anchors-2.yaml new file mode 100644 index 0000000..3574f01 --- /dev/null +++ b/test/emitter-examples/anchors-2.yaml @@ -0,0 +1,2 @@ +base: &base { name: this-is-a-name } + diff --git a/test/emitter-examples/anchors-3.yaml b/test/emitter-examples/anchors-3.yaml new file mode 100644 index 0000000..0d0dc92 --- /dev/null +++ b/test/emitter-examples/anchors-3.yaml @@ -0,0 +1,2 @@ +&base { name: this-is-a-name } + diff --git a/test/emitter-examples/anchors-4.1.yaml b/test/emitter-examples/anchors-4.1.yaml new file mode 100644 index 0000000..6881ba7 --- /dev/null +++ b/test/emitter-examples/anchors-4.1.yaml @@ -0,0 +1,3 @@ +base: &base + name: Everyone has same name + age: 10 diff --git a/test/emitter-examples/anchors-4.yaml b/test/emitter-examples/anchors-4.yaml new file mode 100644 index 0000000..05b387e --- /dev/null +++ b/test/emitter-examples/anchors-4.yaml @@ -0,0 +1,3 @@ +base: &base + name: Everyone has same name + age: 10 diff --git a/test/emitter-examples/anchors-on-empty-scalars.yaml b/test/emitter-examples/anchors-on-empty-scalars.yaml new file mode 100644 index 0000000..c027125 --- /dev/null +++ b/test/emitter-examples/anchors-on-empty-scalars.yaml @@ -0,0 +1,12 @@ +- &a +- a +- + &a1 : a + b: &b +- + &c : &a2 +- + ? &d +- + ? &e + : &a3 diff --git a/test/emitter-examples/anchors-on-empty-scalars1.yaml b/test/emitter-examples/anchors-on-empty-scalars1.yaml new file mode 100644 index 0000000..2be6683 --- /dev/null +++ b/test/emitter-examples/anchors-on-empty-scalars1.yaml @@ -0,0 +1,3 @@ +- + ? &e + : &a diff --git a/test/emitter-examples/anchors-on-empty-scalars2.yaml b/test/emitter-examples/anchors-on-empty-scalars2.yaml new file mode 100644 index 0000000..7a0145a --- /dev/null +++ b/test/emitter-examples/anchors-on-empty-scalars2.yaml @@ -0,0 +1,3 @@ +- + ? + : diff --git a/test/emitter-examples/anchors-on-empty-scalars3.yaml b/test/emitter-examples/anchors-on-empty-scalars3.yaml new file mode 100644 index 0000000..47c32ca --- /dev/null +++ b/test/emitter-examples/anchors-on-empty-scalars3.yaml @@ -0,0 +1,3 @@ +- + ? a + : diff --git a/test/emitter-examples/anchors-on-empty-scalars4.yaml b/test/emitter-examples/anchors-on-empty-scalars4.yaml new file mode 100644 index 0000000..f5814d5 --- /dev/null +++ b/test/emitter-examples/anchors-on-empty-scalars4.yaml @@ -0,0 +1,3 @@ +- + ? &a + : diff --git a/test/emitter-examples/anchors.yaml b/test/emitter-examples/anchors.yaml new file mode 100644 index 0000000..8755853 --- /dev/null +++ b/test/emitter-examples/anchors.yaml @@ -0,0 +1,10 @@ +base: &base + name: Everyone has same name + +foo: &foo + <<: *base + age: 10 + +bar: &bar + <<: *base + age: 20 diff --git a/test/emitter-examples/array.yaml b/test/emitter-examples/array.yaml new file mode 100644 index 0000000..18efd12 --- /dev/null +++ b/test/emitter-examples/array.yaml @@ -0,0 +1,2 @@ +- member +- member2 diff --git a/test/emitter-examples/block.yaml b/test/emitter-examples/block.yaml new file mode 100644 index 0000000..fb6d80a --- /dev/null +++ b/test/emitter-examples/block.yaml @@ -0,0 +1,7 @@ +- item 1 +# STREAM_START FYTT_STREAM_START +# BLOCK_SEQUENCE_START FYTT_BLOCK_SEQUENCE_START +# BLOCK_ENTRY FYTT_BLOCK_ENTRY +# SCALAR value='item 1' style=PLAIN FYTT_SCALAR value='item 1' style=PLAIN +# BLOCK_END FYTT_BLOCK_END +# STREAM_END FYTT_STREAM_END diff --git a/test/emitter-examples/block2.yaml b/test/emitter-examples/block2.yaml new file mode 100644 index 0000000..cb745e0 --- /dev/null +++ b/test/emitter-examples/block2.yaml @@ -0,0 +1,10 @@ +- item 1 +- item 2 +# STREAM_START +# BLOCK_SEQUENCE_START +# BLOCK_ENTRY +# SCALAR value='item 1' style=PLAIN +# BLOCK_ENTRY +# SCALAR value='item 2' style=PLAIN +# BLOCK_END +# STREAM_END diff --git a/test/emitter-examples/block3.yaml b/test/emitter-examples/block3.yaml new file mode 100644 index 0000000..1c0593c --- /dev/null +++ b/test/emitter-examples/block3.yaml @@ -0,0 +1,3 @@ +one: one-value +two: two-value +three: three-value diff --git a/test/emitter-examples/block4.yaml b/test/emitter-examples/block4.yaml new file mode 100644 index 0000000..bbea92a --- /dev/null +++ b/test/emitter-examples/block4.yaml @@ -0,0 +1,3 @@ +test: | + + foo diff --git a/test/emitter-examples/block6.yaml b/test/emitter-examples/block6.yaml new file mode 100644 index 0000000..1ff9bfa --- /dev/null +++ b/test/emitter-examples/block6.yaml @@ -0,0 +1,5 @@ +--- |+ + ab + + +... diff --git a/test/emitter-examples/block7.yaml b/test/emitter-examples/block7.yaml new file mode 100644 index 0000000..418a586 --- /dev/null +++ b/test/emitter-examples/block7.yaml @@ -0,0 +1,6 @@ +block-scalar: | + Test + 12 + testing + FOO +... diff --git a/test/emitter-examples/blocked.yaml b/test/emitter-examples/blocked.yaml new file mode 100644 index 0000000..19824b4 --- /dev/null +++ b/test/emitter-examples/blocked.yaml @@ -0,0 +1,4 @@ +|- + ab + +... diff --git a/test/emitter-examples/blockind.yaml b/test/emitter-examples/blockind.yaml new file mode 100644 index 0000000..608ea19 --- /dev/null +++ b/test/emitter-examples/blockind.yaml @@ -0,0 +1,7 @@ +sequence: +- one +- two +mapping: + ? sky + : blue + sea : green diff --git a/test/emitter-examples/c1.yaml b/test/emitter-examples/c1.yaml new file mode 100644 index 0000000..473afea --- /dev/null +++ b/test/emitter-examples/c1.yaml @@ -0,0 +1,2 @@ +--- +foo # comment diff --git a/test/emitter-examples/c10.yaml b/test/emitter-examples/c10.yaml new file mode 100644 index 0000000..48c6082 --- /dev/null +++ b/test/emitter-examples/c10.yaml @@ -0,0 +1,9 @@ +# root comment + + # top comment of A +- A # right comment of A + # bottom comment of A + + # top comment of B +- B # right comment of B + # bottom comment of B diff --git a/test/emitter-examples/c11.yaml b/test/emitter-examples/c11.yaml new file mode 100644 index 0000000..525d6e7 --- /dev/null +++ b/test/emitter-examples/c11.yaml @@ -0,0 +1,10 @@ +[ + # top comment of A + A, # right comment of A + # bottom comment of A + + # top comment of A + B, # right comment of A + # bottom comment of A +] + diff --git a/test/emitter-examples/c12.yaml b/test/emitter-examples/c12.yaml new file mode 100644 index 0000000..9002396 --- /dev/null +++ b/test/emitter-examples/c12.yaml @@ -0,0 +1,4 @@ +key: # key-comment + value # value-comment +key2: + key3: value diff --git a/test/emitter-examples/c13.yaml b/test/emitter-examples/c13.yaml new file mode 100644 index 0000000..46e22fa --- /dev/null +++ b/test/emitter-examples/c13.yaml @@ -0,0 +1,3 @@ +foo: bar # comment +{ foo: bar }: # comment2 + baz diff --git a/test/emitter-examples/c2.yaml b/test/emitter-examples/c2.yaml new file mode 100644 index 0000000..c0d56ad --- /dev/null +++ b/test/emitter-examples/c2.yaml @@ -0,0 +1,4 @@ +--- +# top comment +foo # right comment +# bottom comment diff --git a/test/emitter-examples/c3.yaml b/test/emitter-examples/c3.yaml new file mode 100644 index 0000000..7040aa9 --- /dev/null +++ b/test/emitter-examples/c3.yaml @@ -0,0 +1,2 @@ +--- +foo: bar # comment diff --git a/test/emitter-examples/c4.yaml b/test/emitter-examples/c4.yaml new file mode 100644 index 0000000..50d4be9 --- /dev/null +++ b/test/emitter-examples/c4.yaml @@ -0,0 +1,5 @@ +--- +{ + foo: bar, # comment + baz: frooz +} diff --git a/test/emitter-examples/c5.yaml b/test/emitter-examples/c5.yaml new file mode 100644 index 0000000..7e39af8 --- /dev/null +++ b/test/emitter-examples/c5.yaml @@ -0,0 +1,6 @@ +--- +{ + foo: bar, # comment + # top comment + baz: frooz # last comment +} diff --git a/test/emitter-examples/c6.yaml b/test/emitter-examples/c6.yaml new file mode 100644 index 0000000..c56a8c1 --- /dev/null +++ b/test/emitter-examples/c6.yaml @@ -0,0 +1,5 @@ +--- +[ + foo, # comment + bar +] diff --git a/test/emitter-examples/c7.yaml b/test/emitter-examples/c7.yaml new file mode 100644 index 0000000..627eef2 --- /dev/null +++ b/test/emitter-examples/c7.yaml @@ -0,0 +1,5 @@ +--- +[ + [ foo, bar ], # comment + baz +] diff --git a/test/emitter-examples/c8.yaml b/test/emitter-examples/c8.yaml new file mode 100644 index 0000000..e1adf02 --- /dev/null +++ b/test/emitter-examples/c8.yaml @@ -0,0 +1,6 @@ +--- +{ + foo: bar, # foo:bar comment + baz: frooz, # baz:frooz comment + whee: yikes # whee: yikes comment +} diff --git a/test/emitter-examples/c9.yaml b/test/emitter-examples/c9.yaml new file mode 100644 index 0000000..9058f07 --- /dev/null +++ b/test/emitter-examples/c9.yaml @@ -0,0 +1,17 @@ +--- +# 1 +# top foo:bar comment +# 2 +foo: bar # foo:bar comment + # continue foo:bar comment + +# 3 +# top baz:frooz comment +# 4 + # break +baz: frooz # baz:frooz comment + +# top whee comment +whee: # whee: comment + level: # level: comment + 1: level-1 # level-1 comment diff --git a/test/emitter-examples/compact1.yaml b/test/emitter-examples/compact1.yaml new file mode 100644 index 0000000..5925e07 --- /dev/null +++ b/test/emitter-examples/compact1.yaml @@ -0,0 +1,6 @@ +- # Empty +- | + block node +- - one # Compact +- - two # sequence +- - one: two # Compact mapping diff --git a/test/emitter-examples/compactblockmap.yaml b/test/emitter-examples/compactblockmap.yaml new file mode 100644 index 0000000..476b362 --- /dev/null +++ b/test/emitter-examples/compactblockmap.yaml @@ -0,0 +1,2 @@ +? a: b +: c: d diff --git a/test/emitter-examples/complexkey.yaml b/test/emitter-examples/complexkey.yaml new file mode 100644 index 0000000..d5f6d26 --- /dev/null +++ b/test/emitter-examples/complexkey.yaml @@ -0,0 +1 @@ +? complex : value diff --git a/test/emitter-examples/complexkey2.yaml b/test/emitter-examples/complexkey2.yaml new file mode 100644 index 0000000..4fbbddb --- /dev/null +++ b/test/emitter-examples/complexkey2.yaml @@ -0,0 +1 @@ +{ ? complex: value } diff --git a/test/emitter-examples/complexkey3.yaml b/test/emitter-examples/complexkey3.yaml new file mode 100644 index 0000000..4586d1c --- /dev/null +++ b/test/emitter-examples/complexkey3.yaml @@ -0,0 +1,12 @@ +{ + ? complex key: value +} +# STREAM_START FYTT_STREAM_START +# FLOW_MAPPING_START FYTT_FLOW_MAPPING_START +# KEY FYTT_KEY +# SCALAR value='complex key' style=PLAIN FYTT_KEY +# VALUE FYTT_SCALAR value='complex key' style=PLAIN +# SCALAR value='value' style=PLAIN FYTT_VALUE +# FLOW_MAPPING_END FYTT_SCALAR value='value' style=PLAIN +# STREAM_END FYTT_FLOW_MAPPING_END +# FYTT_STREAM_END diff --git a/test/emitter-examples/complexkey4.yaml b/test/emitter-examples/complexkey4.yaml new file mode 100644 index 0000000..c8cd88c --- /dev/null +++ b/test/emitter-examples/complexkey4.yaml @@ -0,0 +1,10 @@ +[ ? complex: value ] +# STREAM_START FYTT_STREAM_START +# FLOW_SEQUENCE_START FYTT_FLOW_SEQUENCE_START +# KEY FYTT_KEY +# SCALAR value='complex key' style=PLAIN FYTT_KEY +# VALUE FYTT_SCALAR value='complex key' style=PLAIN +# SCALAR value='value' style=PLAIN FYTT_VALUE +# FLOW_SEQUENCE_END FYTT_SCALAR value='value' style=PLAIN +# STREAM_END FYTT_FLOW_SEQUENCE_END +# FYTT_STREAM_END diff --git a/test/emitter-examples/complexkey5.yaml b/test/emitter-examples/complexkey5.yaml new file mode 100644 index 0000000..181aa2a --- /dev/null +++ b/test/emitter-examples/complexkey5.yaml @@ -0,0 +1 @@ +{ ? { complex: 2 }: value } diff --git a/test/emitter-examples/complexkey6.yaml b/test/emitter-examples/complexkey6.yaml new file mode 100644 index 0000000..7baf45d --- /dev/null +++ b/test/emitter-examples/complexkey6.yaml @@ -0,0 +1,2 @@ +? complex +: value diff --git a/test/emitter-examples/complexkey7.yaml b/test/emitter-examples/complexkey7.yaml new file mode 100644 index 0000000..4dbae17 --- /dev/null +++ b/test/emitter-examples/complexkey7.yaml @@ -0,0 +1 @@ +- ? complex : value diff --git a/test/emitter-examples/complexkey8.yaml b/test/emitter-examples/complexkey8.yaml new file mode 100644 index 0000000..1495237 --- /dev/null +++ b/test/emitter-examples/complexkey8.yaml @@ -0,0 +1 @@ +[ ]: foo diff --git a/test/emitter-examples/complexkey9.yaml b/test/emitter-examples/complexkey9.yaml new file mode 100644 index 0000000..cbaba7f --- /dev/null +++ b/test/emitter-examples/complexkey9.yaml @@ -0,0 +1,3 @@ +? a: b + c: d +: e diff --git a/test/emitter-examples/docstartend.yaml b/test/emitter-examples/docstartend.yaml new file mode 100644 index 0000000..f0d5983 --- /dev/null +++ b/test/emitter-examples/docstartend.yaml @@ -0,0 +1,3 @@ +--- +foo +... diff --git a/test/emitter-examples/dqscalar.yaml b/test/emitter-examples/dqscalar.yaml new file mode 100644 index 0000000..d6bbd62 --- /dev/null +++ b/test/emitter-examples/dqscalar.yaml @@ -0,0 +1,14 @@ +- "quoted" +- "quoted\nescaped new line" +- "quoted + explicit new line" +- "" +- " + " +- " pre-spaces" +- "post-spaces " +- "key": value +- "key\nnewline": value +- "\r\"\\foo" +- "\x20" +- "testing \0null" diff --git a/test/emitter-examples/dqzero.yaml b/test/emitter-examples/dqzero.yaml new file mode 100644 index 0000000..b5db05f --- /dev/null +++ b/test/emitter-examples/dqzero.yaml @@ -0,0 +1 @@ +"zero\0zero" diff --git a/test/emitter-examples/emoji.yaml b/test/emitter-examples/emoji.yaml new file mode 100644 index 0000000..3487828 --- /dev/null +++ b/test/emitter-examples/emoji.yaml @@ -0,0 +1,3846 @@ +- chars: ! "\U0001F600" + codes: 1F600 + name: GRINNING FACE +- chars: ! "\U0001F601" + codes: 1F601 + name: GRINNING FACE WITH SMILING EYES +- chars: ! "\U0001F602" + codes: 1F602 + name: FACE WITH TEARS OF JOY +- chars: ! "\U0001F603" + codes: 1F603 + name: SMILING FACE WITH OPEN MOUTH +- chars: ! "\U0001F604" + codes: 1F604 + name: SMILING FACE WITH OPEN MOUTH AND SMILING EYES +- chars: ! "\U0001F605" + codes: 1F605 + name: SMILING FACE WITH OPEN MOUTH AND COLD SWEAT +- chars: ! "\U0001F606" + codes: 1F606 + name: SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES +- chars: ! "\U0001F609" + codes: 1F609 + name: WINKING FACE +- chars: ! "\U0001F60A" + codes: 1F60A + name: SMILING FACE WITH SMILING EYES +- chars: ! "\U0001F60B" + codes: 1F60B + name: FACE SAVOURING DELICIOUS FOOD +- chars: ! "\U0001F60E" + codes: 1F60E + name: SMILING FACE WITH SUNGLASSES +- chars: ! "\U0001F60D" + codes: 1F60D + name: SMILING FACE WITH HEART-SHAPED EYES +- chars: ! "\U0001F618" + codes: 1F618 + name: FACE THROWING A KISS +- chars: ! "\U0001F617" + codes: 1F617 + name: KISSING FACE +- chars: ! "\U0001F619" + codes: 1F619 + name: KISSING FACE WITH SMILING EYES +- chars: ! "\U0001F61A" + codes: 1F61A + name: KISSING FACE WITH CLOSED EYES +- chars: ☺️ + codes: 263A + name: WHITE SMILING FACE +- chars: ! "\U0001F642" + codes: 1F642 + name: SLIGHTLY SMILING FACE +- chars: ! "\U0001F917" + codes: 1F917 + name: HUGGING FACE +- chars: ! "\U0001F607" + codes: 1F607 + name: SMILING FACE WITH HALO +- chars: ! "\U0001F914" + codes: 1F914 + name: THINKING FACE +- chars: ! "\U0001F610" + codes: 1F610 + name: NEUTRAL FACE +- chars: ! "\U0001F611" + codes: 1F611 + name: EXPRESSIONLESS FACE +- chars: ! "\U0001F636" + codes: 1F636 + name: FACE WITHOUT MOUTH +- chars: ! "\U0001F644" + codes: 1F644 + name: FACE WITH ROLLING EYES +- chars: ! "\U0001F60F" + codes: 1F60F + name: SMIRKING FACE +- chars: ! "\U0001F623" + codes: 1F623 + name: PERSEVERING FACE +- chars: ! "\U0001F625" + codes: 1F625 + name: DISAPPOINTED BUT RELIEVED FACE +- chars: ! "\U0001F62E" + codes: 1F62E + name: FACE WITH OPEN MOUTH +- chars: ! "\U0001F910" + codes: 1F910 + name: ZIPPER-MOUTH FACE +- chars: ! "\U0001F62F" + codes: 1F62F + name: HUSHED FACE +- chars: ! "\U0001F62A" + codes: 1F62A + name: SLEEPY FACE +- chars: ! "\U0001F62B" + codes: 1F62B + name: TIRED FACE +- chars: ! "\U0001F634" + codes: 1F634 + name: SLEEPING FACE +- chars: ! "\U0001F60C" + codes: 1F60C + name: RELIEVED FACE +- chars: ! "\U0001F913" + codes: 1F913 + name: NERD FACE +- chars: ! "\U0001F61B" + codes: 1F61B + name: FACE WITH STUCK-OUT TONGUE +- chars: ! "\U0001F61C" + codes: 1F61C + name: FACE WITH STUCK-OUT TONGUE AND WINKING EYE +- chars: ! "\U0001F61D" + codes: 1F61D + name: FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES +- chars: ☹ + codes: '2639' + name: WHITE FROWNING FACE +- chars: ! "\U0001F641" + codes: 1F641 + name: SLIGHTLY FROWNING FACE +- chars: ! "\U0001F612" + codes: 1F612 + name: UNAMUSED FACE +- chars: ! "\U0001F613" + codes: 1F613 + name: FACE WITH COLD SWEAT +- chars: ! "\U0001F614" + codes: 1F614 + name: PENSIVE FACE +- chars: ! "\U0001F615" + codes: 1F615 + name: CONFUSED FACE +- chars: ! "\U0001F616" + codes: 1F616 + name: CONFOUNDED FACE +- chars: ! "\U0001F643" + codes: 1F643 + name: UPSIDE-DOWN FACE +- chars: ! "\U0001F637" + codes: 1F637 + name: FACE WITH MEDICAL MASK +- chars: ! "\U0001F912" + codes: 1F912 + name: FACE WITH THERMOMETER +- chars: ! "\U0001F915" + codes: 1F915 + name: FACE WITH HEAD-BANDAGE +- chars: ! "\U0001F911" + codes: 1F911 + name: MONEY-MOUTH FACE +- chars: ! "\U0001F632" + codes: 1F632 + name: ASTONISHED FACE +- chars: ! "\U0001F61E" + codes: 1F61E + name: DISAPPOINTED FACE +- chars: ! "\U0001F61F" + codes: 1F61F + name: WORRIED FACE +- chars: ! "\U0001F624" + codes: 1F624 + name: FACE WITH LOOK OF TRIUMPH +- chars: ! "\U0001F622" + codes: 1F622 + name: CRYING FACE +- chars: ! "\U0001F62D" + codes: 1F62D + name: LOUDLY CRYING FACE +- chars: ! "\U0001F626" + codes: 1F626 + name: FROWNING FACE WITH OPEN MOUTH +- chars: ! "\U0001F627" + codes: 1F627 + name: ANGUISHED FACE +- chars: ! "\U0001F628" + codes: 1F628 + name: FEARFUL FACE +- chars: ! "\U0001F629" + codes: 1F629 + name: WEARY FACE +- chars: ! "\U0001F62C" + codes: 1F62C + name: GRIMACING FACE +- chars: ! "\U0001F630" + codes: 1F630 + name: FACE WITH OPEN MOUTH AND COLD SWEAT +- chars: ! "\U0001F631" + codes: 1F631 + name: FACE SCREAMING IN FEAR +- chars: ! "\U0001F633" + codes: 1F633 + name: FLUSHED FACE +- chars: ! "\U0001F635" + codes: 1F635 + name: DIZZY FACE +- chars: ! "\U0001F621" + codes: 1F621 + name: POUTING FACE +- chars: ! "\U0001F620" + codes: 1F620 + name: ANGRY FACE +- chars: ! "\U0001F608" + codes: 1F608 + name: SMILING FACE WITH HORNS +- chars: ! "\U0001F47F" + codes: 1F47F + name: IMP +- chars: ! "\U0001F479" + codes: 1F479 + name: JAPANESE OGRE +- chars: ! "\U0001F47A" + codes: 1F47A + name: JAPANESE GOBLIN +- chars: ! "\U0001F480" + codes: 1F480 + name: SKULL +- chars: ☠ + codes: '2620' + name: SKULL AND CROSSBONES +- chars: ! "\U0001F47B" + codes: 1F47B + name: GHOST +- chars: ! "\U0001F47D" + codes: 1F47D + name: EXTRATERRESTRIAL ALIEN +- chars: ! "\U0001F47E" + codes: 1F47E + name: ALIEN MONSTER +- chars: ! "\U0001F916" + codes: 1F916 + name: ROBOT FACE +- chars: ! "\U0001F4A9" + codes: 1F4A9 + name: PILE OF POO +- chars: ! "\U0001F63A" + codes: 1F63A + name: SMILING CAT FACE WITH OPEN MOUTH +- chars: ! "\U0001F638" + codes: 1F638 + name: GRINNING CAT FACE WITH SMILING EYES +- chars: ! "\U0001F639" + codes: 1F639 + name: CAT FACE WITH TEARS OF JOY +- chars: ! "\U0001F63B" + codes: 1F63B + name: SMILING CAT FACE WITH HEART-SHAPED EYES +- chars: ! "\U0001F63C" + codes: 1F63C + name: CAT FACE WITH WRY SMILE +- chars: ! "\U0001F63D" + codes: 1F63D + name: KISSING CAT FACE WITH CLOSED EYES +- chars: ! "\U0001F640" + codes: 1F640 + name: WEARY CAT FACE +- chars: ! "\U0001F63F" + codes: 1F63F + name: CRYING CAT FACE +- chars: ! "\U0001F63E" + codes: 1F63E + name: POUTING CAT FACE +- chars: ! "\U0001F648" + codes: 1F648 + name: SEE-NO-EVIL MONKEY +- chars: ! "\U0001F649" + codes: 1F649 + name: HEAR-NO-EVIL MONKEY +- chars: ! "\U0001F64A" + codes: 1F64A + name: SPEAK-NO-EVIL MONKEY +- chars: ! "\U0001F466" + codes: 1F466 + name: BOY +- chars: ! "\U0001F467" + codes: 1F467 + name: GIRL +- chars: ! "\U0001F468" + codes: 1F468 + name: MAN +- chars: ! "\U0001F469" + codes: 1F469 + name: WOMAN +- chars: ! "\U0001F474" + codes: 1F474 + name: OLDER MAN +- chars: ! "\U0001F475" + codes: 1F475 + name: OLDER WOMAN +- chars: ! "\U0001F476" + codes: 1F476 + name: BABY +- chars: ! "\U0001F471" + codes: 1F471 + name: PERSON WITH BLOND HAIR +- chars: ! "\U0001F46E" + codes: 1F46E + name: POLICE OFFICER +- chars: ! "\U0001F472" + codes: 1F472 + name: MAN WITH GUA PI MAO +- chars: ! "\U0001F473" + codes: 1F473 + name: MAN WITH TURBAN +- chars: ! "\U0001F477" + codes: 1F477 + name: CONSTRUCTION WORKER +- chars: ⛑ + codes: 26D1 + name: HELMET WITH WHITE CROSS +- chars: ! "\U0001F478" + codes: 1F478 + name: PRINCESS +- chars: ! "\U0001F482" + codes: 1F482 + name: GUARDSMAN +- chars: ! "\U0001F575" + codes: 1F575 + name: SLEUTH OR SPY +- chars: ! "\U0001F385" + codes: 1F385 + name: FATHER CHRISTMAS +- chars: ! "\U0001F47C" + codes: 1F47C + name: BABY ANGEL +- chars: ! "\U0001F46F" + codes: 1F46F + name: WOMAN WITH BUNNY EARS +- chars: ! "\U0001F486" + codes: 1F486 + name: FACE MASSAGE +- chars: ! "\U0001F487" + codes: 1F487 + name: HAIRCUT +- chars: ! "\U0001F470" + codes: 1F470 + name: BRIDE WITH VEIL +- chars: ! "\U0001F64D" + codes: 1F64D + name: PERSON FROWNING +- chars: ! "\U0001F64E" + codes: 1F64E + name: PERSON WITH POUTING FACE +- chars: ! "\U0001F645" + codes: 1F645 + name: FACE WITH NO GOOD GESTURE +- chars: ! "\U0001F646" + codes: 1F646 + name: FACE WITH OK GESTURE +- chars: ! "\U0001F481" + codes: 1F481 + name: INFORMATION DESK PERSON +- chars: ! "\U0001F64B" + codes: 1F64B + name: HAPPY PERSON RAISING ONE HAND +- chars: ! "\U0001F647" + codes: 1F647 + name: PERSON BOWING DEEPLY +- chars: ! "\U0001F64C" + codes: 1F64C + name: PERSON RAISING BOTH HANDS IN CELEBRATION +- chars: ! "\U0001F64F" + codes: 1F64F + name: PERSON WITH FOLDED HANDS +- chars: ! "\U0001F5E3" + codes: 1F5E3 + name: SPEAKING HEAD IN SILHOUETTE +- chars: ! "\U0001F464" + codes: 1F464 + name: BUST IN SILHOUETTE +- chars: ! "\U0001F465" + codes: 1F465 + name: BUSTS IN SILHOUETTE +- chars: ! "\U0001F6B6" + codes: 1F6B6 + name: PEDESTRIAN +- chars: ! "\U0001F3C3" + codes: 1F3C3 + name: RUNNER +- chars: ! "\U0001F483" + codes: 1F483 + name: DANCER +- chars: ! "\U0001F574" + codes: 1F574 + name: MAN IN BUSINESS SUIT LEVITATING +- chars: ! "\U0001F48F" + codes: 1F48F + name: KISS +- chars: ! "\U0001F491" + codes: 1F491 + name: COUPLE WITH HEART +- chars: ! "\U0001F46A" + codes: 1F46A + name: FAMILY +- chars: ! "\U0001F46B" + codes: 1F46B + name: MAN AND WOMAN HOLDING HANDS +- chars: ! "\U0001F46C" + codes: 1F46C + name: TWO MEN HOLDING HANDS +- chars: ! "\U0001F46D" + codes: 1F46D + name: TWO WOMEN HOLDING HANDS +- chars: ! "\U0001F3FB" + codes: 1F3FB + name: EMOJI MODIFIER FITZPATRICK TYPE-1-2 +- chars: ! "\U0001F3FC" + codes: 1F3FC + name: EMOJI MODIFIER FITZPATRICK TYPE-3 +- chars: ! "\U0001F3FD" + codes: 1F3FD + name: EMOJI MODIFIER FITZPATRICK TYPE-4 +- chars: ! "\U0001F3FE" + codes: 1F3FE + name: EMOJI MODIFIER FITZPATRICK TYPE-5 +- chars: ! "\U0001F3FF" + codes: 1F3FF + name: EMOJI MODIFIER FITZPATRICK TYPE-6 +- chars: ! "\U0001F4AA" + codes: 1F4AA + name: FLEXED BICEPS +- chars: ! "\U0001F448" + codes: 1F448 + name: WHITE LEFT POINTING BACKHAND INDEX +- chars: ! "\U0001F449" + codes: 1F449 + name: WHITE RIGHT POINTING BACKHAND INDEX +- chars: ☝️ + codes: 261D + name: WHITE UP POINTING INDEX +- chars: ! "\U0001F446" + codes: 1F446 + name: WHITE UP POINTING BACKHAND INDEX +- chars: ! "\U0001F595" + codes: 1F595 + name: REVERSED HAND WITH MIDDLE FINGER EXTENDED +- chars: ! "\U0001F447" + codes: 1F447 + name: WHITE DOWN POINTING BACKHAND INDEX +- chars: ✌️ + codes: 270C + name: VICTORY HAND +- chars: ! "\U0001F596" + codes: 1F596 + name: RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS +- chars: ! "\U0001F918" + codes: 1F918 + name: SIGN OF THE HORNS +- chars: ! "\U0001F590" + codes: 1F590 + name: RAISED HAND WITH FINGERS SPLAYED +- chars: ✊ + codes: 270A + name: RAISED FIST +- chars: ✋ + codes: 270B + name: RAISED HAND +- chars: ! "\U0001F44A" + codes: 1F44A + name: FISTED HAND SIGN +- chars: ! "\U0001F44C" + codes: 1F44C + name: OK HAND SIGN +- chars: ! "\U0001F44D" + codes: 1F44D + name: THUMBS UP SIGN +- chars: ! "\U0001F44E" + codes: 1F44E + name: THUMBS DOWN SIGN +- chars: ! "\U0001F44B" + codes: 1F44B + name: WAVING HAND SIGN +- chars: ! "\U0001F44F" + codes: 1F44F + name: CLAPPING HANDS SIGN +- chars: ! "\U0001F450" + codes: 1F450 + name: OPEN HANDS SIGN +- chars: ✍ + codes: 270D + name: WRITING HAND +- chars: ! "\U0001F485" + codes: 1F485 + name: NAIL POLISH +- chars: ! "\U0001F442" + codes: 1F442 + name: EAR +- chars: ! "\U0001F443" + codes: 1F443 + name: NOSE +- chars: ! "\U0001F463" + codes: 1F463 + name: FOOTPRINTS +- chars: ! "\U0001F440" + codes: 1F440 + name: EYES +- chars: ! "\U0001F441" + codes: 1F441 + name: EYE +- chars: ! "\U0001F445" + codes: 1F445 + name: TONGUE +- chars: ! "\U0001F444" + codes: 1F444 + name: MOUTH +- chars: ! "\U0001F48B" + codes: 1F48B + name: KISS MARK +- chars: ! "\U0001F498" + codes: 1F498 + name: HEART WITH ARROW +- chars: ❤️ + codes: '2764' + name: HEAVY BLACK HEART +- chars: ! "\U0001F493" + codes: 1F493 + name: BEATING HEART +- chars: ! "\U0001F494" + codes: 1F494 + name: BROKEN HEART +- chars: ! "\U0001F495" + codes: 1F495 + name: TWO HEARTS +- chars: ! "\U0001F496" + codes: 1F496 + name: SPARKLING HEART +- chars: ! "\U0001F497" + codes: 1F497 + name: GROWING HEART +- chars: ! "\U0001F499" + codes: 1F499 + name: BLUE HEART +- chars: ! "\U0001F49A" + codes: 1F49A + name: GREEN HEART +- chars: ! "\U0001F49B" + codes: 1F49B + name: YELLOW HEART +- chars: ! "\U0001F49C" + codes: 1F49C + name: PURPLE HEART +- chars: ! "\U0001F49D" + codes: 1F49D + name: HEART WITH RIBBON +- chars: ! "\U0001F49E" + codes: 1F49E + name: REVOLVING HEARTS +- chars: ! "\U0001F49F" + codes: 1F49F + name: HEART DECORATION +- chars: ❣ + codes: '2763' + name: HEAVY HEART EXCLAMATION MARK ORNAMENT +- chars: ! "\U0001F48C" + codes: 1F48C + name: LOVE LETTER +- chars: ! "\U0001F4A4" + codes: 1F4A4 + name: SLEEPING SYMBOL +- chars: ! "\U0001F4A2" + codes: 1F4A2 + name: ANGER SYMBOL +- chars: ! "\U0001F4A3" + codes: 1F4A3 + name: BOMB +- chars: ! "\U0001F4A5" + codes: 1F4A5 + name: COLLISION SYMBOL +- chars: ! "\U0001F4A6" + codes: 1F4A6 + name: SPLASHING SWEAT SYMBOL +- chars: ! "\U0001F4A8" + codes: 1F4A8 + name: DASH SYMBOL +- chars: ! "\U0001F4AB" + codes: 1F4AB + name: DIZZY SYMBOL +- chars: ! "\U0001F4AC" + codes: 1F4AC + name: SPEECH BALLOON +- chars: ! "\U0001F5E8" + codes: 1F5E8 + name: LEFT SPEECH BUBBLE +- chars: ! "\U0001F5EF" + codes: 1F5EF + name: RIGHT ANGER BUBBLE +- chars: ! "\U0001F4AD" + codes: 1F4AD + name: THOUGHT BALLOON +- chars: ! "\U0001F573" + codes: 1F573 + name: HOLE +- chars: ! "\U0001F453" + codes: 1F453 + name: EYEGLASSES +- chars: ! "\U0001F576" + codes: 1F576 + name: DARK SUNGLASSES +- chars: ! "\U0001F454" + codes: 1F454 + name: NECKTIE +- chars: ! "\U0001F455" + codes: 1F455 + name: T-SHIRT +- chars: ! "\U0001F456" + codes: 1F456 + name: JEANS +- chars: ! "\U0001F457" + codes: 1F457 + name: DRESS +- chars: ! "\U0001F458" + codes: 1F458 + name: KIMONO +- chars: ! "\U0001F459" + codes: 1F459 + name: BIKINI +- chars: ! "\U0001F45A" + codes: 1F45A + name: WOMANS CLOTHES +- chars: ! "\U0001F45B" + codes: 1F45B + name: PURSE +- chars: ! "\U0001F45C" + codes: 1F45C + name: HANDBAG +- chars: ! "\U0001F45D" + codes: 1F45D + name: POUCH +- chars: ! "\U0001F6CD" + codes: 1F6CD + name: SHOPPING BAGS +- chars: ! "\U0001F392" + codes: 1F392 + name: SCHOOL SATCHEL +- chars: ! "\U0001F45E" + codes: 1F45E + name: MANS SHOE +- chars: ! "\U0001F45F" + codes: 1F45F + name: ATHLETIC SHOE +- chars: ! "\U0001F460" + codes: 1F460 + name: HIGH-HEELED SHOE +- chars: ! "\U0001F461" + codes: 1F461 + name: WOMANS SANDAL +- chars: ! "\U0001F462" + codes: 1F462 + name: WOMANS BOOTS +- chars: ! "\U0001F451" + codes: 1F451 + name: CROWN +- chars: ! "\U0001F452" + codes: 1F452 + name: WOMANS HAT +- chars: ! "\U0001F3A9" + codes: 1F3A9 + name: TOP HAT +- chars: ! "\U0001F393" + codes: 1F393 + name: GRADUATION CAP +- chars: ! "\U0001F4FF" + codes: 1F4FF + name: PRAYER BEADS +- chars: ! "\U0001F484" + codes: 1F484 + name: LIPSTICK +- chars: ! "\U0001F48D" + codes: 1F48D + name: RING +- chars: ! "\U0001F48E" + codes: 1F48E + name: GEM STONE +- chars: ! "\U0001F435" + codes: 1F435 + name: MONKEY FACE +- chars: ! "\U0001F412" + codes: 1F412 + name: MONKEY +- chars: ! "\U0001F436" + codes: 1F436 + name: DOG FACE +- chars: ! "\U0001F415" + codes: 1F415 + name: DOG +- chars: ! "\U0001F429" + codes: 1F429 + name: POODLE +- chars: ! "\U0001F43A" + codes: 1F43A + name: WOLF FACE +- chars: ! "\U0001F431" + codes: 1F431 + name: CAT FACE +- chars: ! "\U0001F408" + codes: 1F408 + name: CAT +- chars: ! "\U0001F981" + codes: 1F981 + name: LION FACE +- chars: ! "\U0001F42F" + codes: 1F42F + name: TIGER FACE +- chars: ! "\U0001F405" + codes: 1F405 + name: TIGER +- chars: ! "\U0001F406" + codes: 1F406 + name: LEOPARD +- chars: ! "\U0001F434" + codes: 1F434 + name: HORSE FACE +- chars: ! "\U0001F40E" + codes: 1F40E + name: HORSE +- chars: ! "\U0001F984" + codes: 1F984 + name: UNICORN FACE +- chars: ! "\U0001F42E" + codes: 1F42E + name: COW FACE +- chars: ! "\U0001F402" + codes: 1F402 + name: OX +- chars: ! "\U0001F403" + codes: 1F403 + name: WATER BUFFALO +- chars: ! "\U0001F404" + codes: 1F404 + name: COW +- chars: ! "\U0001F437" + codes: 1F437 + name: PIG FACE +- chars: ! "\U0001F416" + codes: 1F416 + name: PIG +- chars: ! "\U0001F417" + codes: 1F417 + name: BOAR +- chars: ! "\U0001F43D" + codes: 1F43D + name: PIG NOSE +- chars: ! "\U0001F40F" + codes: 1F40F + name: RAM +- chars: ! "\U0001F411" + codes: 1F411 + name: SHEEP +- chars: ! "\U0001F410" + codes: 1F410 + name: GOAT +- chars: ! "\U0001F42A" + codes: 1F42A + name: DROMEDARY CAMEL +- chars: ! "\U0001F42B" + codes: 1F42B + name: BACTRIAN CAMEL +- chars: ! "\U0001F418" + codes: 1F418 + name: ELEPHANT +- chars: ! "\U0001F42D" + codes: 1F42D + name: MOUSE FACE +- chars: ! "\U0001F401" + codes: 1F401 + name: MOUSE +- chars: ! "\U0001F400" + codes: 1F400 + name: RAT +- chars: ! "\U0001F439" + codes: 1F439 + name: HAMSTER FACE +- chars: ! "\U0001F430" + codes: 1F430 + name: RABBIT FACE +- chars: ! "\U0001F407" + codes: 1F407 + name: RABBIT +- chars: ! "\U0001F43F" + codes: 1F43F + name: CHIPMUNK +- chars: ! "\U0001F43B" + codes: 1F43B + name: BEAR FACE +- chars: ! "\U0001F428" + codes: 1F428 + name: KOALA +- chars: ! "\U0001F43C" + codes: 1F43C + name: PANDA FACE +- chars: ! "\U0001F43E" + codes: 1F43E + name: PAW PRINTS +- chars: ! "\U0001F983" + codes: 1F983 + name: TURKEY +- chars: ! "\U0001F414" + codes: 1F414 + name: CHICKEN +- chars: ! "\U0001F413" + codes: 1F413 + name: ROOSTER +- chars: ! "\U0001F423" + codes: 1F423 + name: HATCHING CHICK +- chars: ! "\U0001F424" + codes: 1F424 + name: BABY CHICK +- chars: ! "\U0001F425" + codes: 1F425 + name: FRONT-FACING BABY CHICK +- chars: ! "\U0001F426" + codes: 1F426 + name: BIRD +- chars: ! "\U0001F427" + codes: 1F427 + name: PENGUIN +- chars: ! "\U0001F54A" + codes: 1F54A + name: DOVE OF PEACE +- chars: ! "\U0001F438" + codes: 1F438 + name: FROG FACE +- chars: ! "\U0001F40A" + codes: 1F40A + name: CROCODILE +- chars: ! "\U0001F422" + codes: 1F422 + name: TURTLE +- chars: ! "\U0001F40D" + codes: 1F40D + name: SNAKE +- chars: ! "\U0001F432" + codes: 1F432 + name: DRAGON FACE +- chars: ! "\U0001F409" + codes: 1F409 + name: DRAGON +- chars: ! "\U0001F433" + codes: 1F433 + name: SPOUTING WHALE +- chars: ! "\U0001F40B" + codes: 1F40B + name: WHALE +- chars: ! "\U0001F42C" + codes: 1F42C + name: DOLPHIN +- chars: ! "\U0001F41F" + codes: 1F41F + name: FISH +- chars: ! "\U0001F420" + codes: 1F420 + name: TROPICAL FISH +- chars: ! "\U0001F421" + codes: 1F421 + name: BLOWFISH +- chars: ! "\U0001F419" + codes: 1F419 + name: OCTOPUS +- chars: ! "\U0001F41A" + codes: 1F41A + name: SPIRAL SHELL +- chars: ! "\U0001F980" + codes: 1F980 + name: CRAB +- chars: ! "\U0001F40C" + codes: 1F40C + name: SNAIL +- chars: ! "\U0001F41B" + codes: 1F41B + name: BUG +- chars: ! "\U0001F41C" + codes: 1F41C + name: ANT +- chars: ! "\U0001F41D" + codes: 1F41D + name: HONEYBEE +- chars: ! "\U0001F41E" + codes: 1F41E + name: LADY BEETLE +- chars: ! "\U0001F577" + codes: 1F577 + name: SPIDER +- chars: ! "\U0001F578" + codes: 1F578 + name: SPIDER WEB +- chars: ! "\U0001F982" + codes: 1F982 + name: SCORPION +- chars: ! "\U0001F490" + codes: 1F490 + name: BOUQUET +- chars: ! "\U0001F338" + codes: 1F338 + name: CHERRY BLOSSOM +- chars: ! "\U0001F4AE" + codes: 1F4AE + name: WHITE FLOWER +- chars: ! "\U0001F3F5" + codes: 1F3F5 + name: ROSETTE +- chars: ! "\U0001F339" + codes: 1F339 + name: ROSE +- chars: ! "\U0001F33A" + codes: 1F33A + name: HIBISCUS +- chars: ! "\U0001F33B" + codes: 1F33B + name: SUNFLOWER +- chars: ! "\U0001F33C" + codes: 1F33C + name: BLOSSOM +- chars: ! "\U0001F337" + codes: 1F337 + name: TULIP +- chars: ☘ + codes: '2618' + name: SHAMROCK +- chars: ! "\U0001F331" + codes: 1F331 + name: SEEDLING +- chars: ! "\U0001F332" + codes: 1F332 + name: EVERGREEN TREE +- chars: ! "\U0001F333" + codes: 1F333 + name: DECIDUOUS TREE +- chars: ! "\U0001F334" + codes: 1F334 + name: PALM TREE +- chars: ! "\U0001F335" + codes: 1F335 + name: CACTUS +- chars: ! "\U0001F33E" + codes: 1F33E + name: EAR OF RICE +- chars: ! "\U0001F33F" + codes: 1F33F + name: HERB +- chars: ! "\U0001F340" + codes: 1F340 + name: FOUR LEAF CLOVER +- chars: ! "\U0001F341" + codes: 1F341 + name: MAPLE LEAF +- chars: ! "\U0001F342" + codes: 1F342 + name: FALLEN LEAF +- chars: ! "\U0001F343" + codes: 1F343 + name: LEAF FLUTTERING IN WIND +- chars: ! "\U0001F347" + codes: 1F347 + name: GRAPES +- chars: ! "\U0001F348" + codes: 1F348 + name: MELON +- chars: ! "\U0001F349" + codes: 1F349 + name: WATERMELON +- chars: ! "\U0001F34A" + codes: 1F34A + name: TANGERINE +- chars: ! "\U0001F34B" + codes: 1F34B + name: LEMON +- chars: ! "\U0001F34C" + codes: 1F34C + name: BANANA +- chars: ! "\U0001F34D" + codes: 1F34D + name: PINEAPPLE +- chars: ! "\U0001F34E" + codes: 1F34E + name: RED APPLE +- chars: ! "\U0001F34F" + codes: 1F34F + name: GREEN APPLE +- chars: ! "\U0001F350" + codes: 1F350 + name: PEAR +- chars: ! "\U0001F351" + codes: 1F351 + name: PEACH +- chars: ! "\U0001F352" + codes: 1F352 + name: CHERRIES +- chars: ! "\U0001F353" + codes: 1F353 + name: STRAWBERRY +- chars: ! "\U0001F345" + codes: 1F345 + name: TOMATO +- chars: ! "\U0001F346" + codes: 1F346 + name: AUBERGINE +- chars: ! "\U0001F33D" + codes: 1F33D + name: EAR OF MAIZE +- chars: ! "\U0001F336" + codes: 1F336 + name: HOT PEPPER +- chars: ! "\U0001F344" + codes: 1F344 + name: MUSHROOM +- chars: ! "\U0001F330" + codes: 1F330 + name: CHESTNUT +- chars: ! "\U0001F35E" + codes: 1F35E + name: BREAD +- chars: ! "\U0001F9C0" + codes: 1F9C0 + name: CHEESE WEDGE +- chars: ! "\U0001F356" + codes: 1F356 + name: MEAT ON BONE +- chars: ! "\U0001F357" + codes: 1F357 + name: POULTRY LEG +- chars: ! "\U0001F354" + codes: 1F354 + name: HAMBURGER +- chars: ! "\U0001F35F" + codes: 1F35F + name: FRENCH FRIES +- chars: ! "\U0001F355" + codes: 1F355 + name: SLICE OF PIZZA +- chars: ! "\U0001F32D" + codes: 1F32D + name: HOT DOG +- chars: ! "\U0001F32E" + codes: 1F32E + name: TACO +- chars: ! "\U0001F32F" + codes: 1F32F + name: BURRITO +- chars: ! "\U0001F37F" + codes: 1F37F + name: POPCORN +- chars: ! "\U0001F372" + codes: 1F372 + name: POT OF FOOD +- chars: ! "\U0001F371" + codes: 1F371 + name: BENTO BOX +- chars: ! "\U0001F358" + codes: 1F358 + name: RICE CRACKER +- chars: ! "\U0001F359" + codes: 1F359 + name: RICE BALL +- chars: ! "\U0001F35A" + codes: 1F35A + name: COOKED RICE +- chars: ! "\U0001F35B" + codes: 1F35B + name: CURRY AND RICE +- chars: ! "\U0001F35C" + codes: 1F35C + name: STEAMING BOWL +- chars: ! "\U0001F35D" + codes: 1F35D + name: SPAGHETTI +- chars: ! "\U0001F360" + codes: 1F360 + name: ROASTED SWEET POTATO +- chars: ! "\U0001F362" + codes: 1F362 + name: ODEN +- chars: ! "\U0001F363" + codes: 1F363 + name: SUSHI +- chars: ! "\U0001F364" + codes: 1F364 + name: FRIED SHRIMP +- chars: ! "\U0001F365" + codes: 1F365 + name: FISH CAKE WITH SWIRL DESIGN +- chars: ! "\U0001F361" + codes: 1F361 + name: DANGO +- chars: ! "\U0001F366" + codes: 1F366 + name: SOFT ICE CREAM +- chars: ! "\U0001F367" + codes: 1F367 + name: SHAVED ICE +- chars: ! "\U0001F368" + codes: 1F368 + name: ICE CREAM +- chars: ! "\U0001F369" + codes: 1F369 + name: DOUGHNUT +- chars: ! "\U0001F36A" + codes: 1F36A + name: COOKIE +- chars: ! "\U0001F382" + codes: 1F382 + name: BIRTHDAY CAKE +- chars: ! "\U0001F370" + codes: 1F370 + name: SHORTCAKE +- chars: ! "\U0001F36B" + codes: 1F36B + name: CHOCOLATE BAR +- chars: ! "\U0001F36C" + codes: 1F36C + name: CANDY +- chars: ! "\U0001F36D" + codes: 1F36D + name: LOLLIPOP +- chars: ! "\U0001F36E" + codes: 1F36E + name: CUSTARD +- chars: ! "\U0001F36F" + codes: 1F36F + name: HONEY POT +- chars: ! "\U0001F37C" + codes: 1F37C + name: BABY BOTTLE +- chars: ☕️ + codes: '2615' + name: HOT BEVERAGE +- chars: ! "\U0001F375" + codes: 1F375 + name: TEACUP WITHOUT HANDLE +- chars: ! "\U0001F376" + codes: 1F376 + name: SAKE BOTTLE AND CUP +- chars: ! "\U0001F37E" + codes: 1F37E + name: BOTTLE WITH POPPING CORK +- chars: ! "\U0001F377" + codes: 1F377 + name: WINE GLASS +- chars: ! "\U0001F378" + codes: 1F378 + name: COCKTAIL GLASS +- chars: ! "\U0001F379" + codes: 1F379 + name: TROPICAL DRINK +- chars: ! "\U0001F37A" + codes: 1F37A + name: BEER MUG +- chars: ! "\U0001F37B" + codes: 1F37B + name: CLINKING BEER MUGS +- chars: ! "\U0001F37D" + codes: 1F37D + name: FORK AND KNIFE WITH PLATE +- chars: ! "\U0001F374" + codes: 1F374 + name: FORK AND KNIFE +- chars: ! "\U0001F373" + codes: 1F373 + name: COOKING +- chars: ! "\U0001F3FA" + codes: 1F3FA + name: AMPHORA +- chars: ! "\U0001F30D" + codes: 1F30D + name: EARTH GLOBE EUROPE-AFRICA +- chars: ! "\U0001F30E" + codes: 1F30E + name: EARTH GLOBE AMERICAS +- chars: ! "\U0001F30F" + codes: 1F30F + name: EARTH GLOBE ASIA-AUSTRALIA +- chars: ! "\U0001F310" + codes: 1F310 + name: GLOBE WITH MERIDIANS +- chars: ! "\U0001F5FA" + codes: 1F5FA + name: WORLD MAP +- chars: ! "\U0001F3D4" + codes: 1F3D4 + name: SNOW CAPPED MOUNTAIN +- chars: ⛰ + codes: 26F0 + name: MOUNTAIN +- chars: ! "\U0001F30B" + codes: 1F30B + name: VOLCANO +- chars: ! "\U0001F5FB" + codes: 1F5FB + name: MOUNT FUJI +- chars: ! "\U0001F3D5" + codes: 1F3D5 + name: CAMPING +- chars: ! "\U0001F3D6" + codes: 1F3D6 + name: BEACH WITH UMBRELLA +- chars: ! "\U0001F3DC" + codes: 1F3DC + name: DESERT +- chars: ! "\U0001F3DD" + codes: 1F3DD + name: DESERT ISLAND +- chars: ! "\U0001F3DE" + codes: 1F3DE + name: NATIONAL PARK +- chars: ! "\U0001F3DF" + codes: 1F3DF + name: STADIUM +- chars: ! "\U0001F3DB" + codes: 1F3DB + name: CLASSICAL BUILDING +- chars: ! "\U0001F3D7" + codes: 1F3D7 + name: BUILDING CONSTRUCTION +- chars: ! "\U0001F3D8" + codes: 1F3D8 + name: HOUSE BUILDINGS +- chars: ! "\U0001F3D9" + codes: 1F3D9 + name: CITYSCAPE +- chars: ! "\U0001F3DA" + codes: 1F3DA + name: DERELICT HOUSE BUILDING +- chars: ! "\U0001F3E0" + codes: 1F3E0 + name: HOUSE BUILDING +- chars: ! "\U0001F3E1" + codes: 1F3E1 + name: HOUSE WITH GARDEN +- chars: ⛪️ + codes: 26EA + name: CHURCH +- chars: ! "\U0001F54B" + codes: 1F54B + name: KAABA +- chars: ! "\U0001F54C" + codes: 1F54C + name: MOSQUE +- chars: ! "\U0001F54D" + codes: 1F54D + name: SYNAGOGUE +- chars: ⛩ + codes: '26E9' + name: SHINTO SHRINE +- chars: ! "\U0001F3E2" + codes: 1F3E2 + name: OFFICE BUILDING +- chars: ! "\U0001F3E3" + codes: 1F3E3 + name: JAPANESE POST OFFICE +- chars: ! "\U0001F3E4" + codes: 1F3E4 + name: EUROPEAN POST OFFICE +- chars: ! "\U0001F3E5" + codes: 1F3E5 + name: HOSPITAL +- chars: ! "\U0001F3E6" + codes: 1F3E6 + name: BANK +- chars: ! "\U0001F3E8" + codes: 1F3E8 + name: HOTEL +- chars: ! "\U0001F3E9" + codes: 1F3E9 + name: LOVE HOTEL +- chars: ! "\U0001F3EA" + codes: 1F3EA + name: CONVENIENCE STORE +- chars: ! "\U0001F3EB" + codes: 1F3EB + name: SCHOOL +- chars: ! "\U0001F3EC" + codes: 1F3EC + name: DEPARTMENT STORE +- chars: ! "\U0001F3ED" + codes: 1F3ED + name: FACTORY +- chars: ! "\U0001F3EF" + codes: 1F3EF + name: JAPANESE CASTLE +- chars: ! "\U0001F3F0" + codes: 1F3F0 + name: EUROPEAN CASTLE +- chars: ! "\U0001F492" + codes: 1F492 + name: WEDDING +- chars: ! "\U0001F5FC" + codes: 1F5FC + name: TOKYO TOWER +- chars: ! "\U0001F5FD" + codes: 1F5FD + name: STATUE OF LIBERTY +- chars: ! "\U0001F5FE" + codes: 1F5FE + name: SILHOUETTE OF JAPAN +- chars: ⛲️ + codes: 26F2 + name: FOUNTAIN +- chars: ⛺️ + codes: 26FA + name: TENT +- chars: ! "\U0001F301" + codes: 1F301 + name: FOGGY +- chars: ! "\U0001F303" + codes: 1F303 + name: NIGHT WITH STARS +- chars: ! "\U0001F304" + codes: 1F304 + name: SUNRISE OVER MOUNTAINS +- chars: ! "\U0001F305" + codes: 1F305 + name: SUNRISE +- chars: ! "\U0001F306" + codes: 1F306 + name: CITYSCAPE AT DUSK +- chars: ! "\U0001F307" + codes: 1F307 + name: SUNSET OVER BUILDINGS +- chars: ! "\U0001F309" + codes: 1F309 + name: BRIDGE AT NIGHT +- chars: ♨️ + codes: '2668' + name: HOT SPRINGS +- chars: ! "\U0001F30C" + codes: 1F30C + name: MILKY WAY +- chars: ! "\U0001F3A0" + codes: 1F3A0 + name: CAROUSEL HORSE +- chars: ! "\U0001F3A1" + codes: 1F3A1 + name: FERRIS WHEEL +- chars: ! "\U0001F3A2" + codes: 1F3A2 + name: ROLLER COASTER +- chars: ! "\U0001F488" + codes: 1F488 + name: BARBER POLE +- chars: ! "\U0001F3AA" + codes: 1F3AA + name: CIRCUS TENT +- chars: ! "\U0001F3AD" + codes: 1F3AD + name: PERFORMING ARTS +- chars: ! "\U0001F5BC" + codes: 1F5BC + name: FRAME WITH PICTURE +- chars: ! "\U0001F3A8" + codes: 1F3A8 + name: ARTIST PALETTE +- chars: ! "\U0001F3B0" + codes: 1F3B0 + name: SLOT MACHINE +- chars: ! "\U0001F682" + codes: 1F682 + name: STEAM LOCOMOTIVE +- chars: ! "\U0001F683" + codes: 1F683 + name: RAILWAY CAR +- chars: ! "\U0001F684" + codes: 1F684 + name: HIGH-SPEED TRAIN +- chars: ! "\U0001F685" + codes: 1F685 + name: HIGH-SPEED TRAIN WITH BULLET NOSE +- chars: ! "\U0001F686" + codes: 1F686 + name: TRAIN +- chars: ! "\U0001F687" + codes: 1F687 + name: METRO +- chars: ! "\U0001F688" + codes: 1F688 + name: LIGHT RAIL +- chars: ! "\U0001F689" + codes: 1F689 + name: STATION +- chars: ! "\U0001F68A" + codes: 1F68A + name: TRAM +- chars: ! "\U0001F69D" + codes: 1F69D + name: MONORAIL +- chars: ! "\U0001F69E" + codes: 1F69E + name: MOUNTAIN RAILWAY +- chars: ! "\U0001F68B" + codes: 1F68B + name: TRAM CAR +- chars: ! "\U0001F68C" + codes: 1F68C + name: BUS +- chars: ! "\U0001F68D" + codes: 1F68D + name: ONCOMING BUS +- chars: ! "\U0001F68E" + codes: 1F68E + name: TROLLEYBUS +- chars: ! "\U0001F68F" + codes: 1F68F + name: BUS STOP +- chars: ! "\U0001F690" + codes: 1F690 + name: MINIBUS +- chars: ! "\U0001F691" + codes: 1F691 + name: AMBULANCE +- chars: ! "\U0001F692" + codes: 1F692 + name: FIRE ENGINE +- chars: ! "\U0001F693" + codes: 1F693 + name: POLICE CAR +- chars: ! "\U0001F694" + codes: 1F694 + name: ONCOMING POLICE CAR +- chars: ! "\U0001F695" + codes: 1F695 + name: TAXI +- chars: ! "\U0001F696" + codes: 1F696 + name: ONCOMING TAXI +- chars: ! "\U0001F697" + codes: 1F697 + name: AUTOMOBILE +- chars: ! "\U0001F698" + codes: 1F698 + name: ONCOMING AUTOMOBILE +- chars: ! "\U0001F699" + codes: 1F699 + name: RECREATIONAL VEHICLE +- chars: ! "\U0001F69A" + codes: 1F69A + name: DELIVERY TRUCK +- chars: ! "\U0001F69B" + codes: 1F69B + name: ARTICULATED LORRY +- chars: ! "\U0001F69C" + codes: 1F69C + name: TRACTOR +- chars: ! "\U0001F6B2" + codes: 1F6B2 + name: BICYCLE +- chars: ⛽️ + codes: 26FD + name: FUEL PUMP +- chars: ! "\U0001F6E3" + codes: 1F6E3 + name: MOTORWAY +- chars: ! "\U0001F6E4" + codes: 1F6E4 + name: RAILWAY TRACK +- chars: ! "\U0001F6A8" + codes: 1F6A8 + name: POLICE CARS REVOLVING LIGHT +- chars: ! "\U0001F6A5" + codes: 1F6A5 + name: HORIZONTAL TRAFFIC LIGHT +- chars: ! "\U0001F6A6" + codes: 1F6A6 + name: VERTICAL TRAFFIC LIGHT +- chars: ! "\U0001F6A7" + codes: 1F6A7 + name: CONSTRUCTION SIGN +- chars: ⚓️ + codes: '2693' + name: ANCHOR +- chars: ⛵️ + codes: 26F5 + name: SAILBOAT +- chars: ! "\U0001F6A3" + codes: 1F6A3 + name: ROWBOAT +- chars: ! "\U0001F6A4" + codes: 1F6A4 + name: SPEEDBOAT +- chars: ! "\U0001F6F3" + codes: 1F6F3 + name: PASSENGER SHIP +- chars: ⛴ + codes: 26F4 + name: FERRY +- chars: ! "\U0001F6E5" + codes: 1F6E5 + name: MOTOR BOAT +- chars: ! "\U0001F6A2" + codes: 1F6A2 + name: SHIP +- chars: ✈️ + codes: '2708' + name: AIRPLANE +- chars: ! "\U0001F6E9" + codes: 1F6E9 + name: SMALL AIRPLANE +- chars: ! "\U0001F6EB" + codes: 1F6EB + name: AIRPLANE DEPARTURE +- chars: ! "\U0001F6EC" + codes: 1F6EC + name: AIRPLANE ARRIVING +- chars: ! "\U0001F4BA" + codes: 1F4BA + name: SEAT +- chars: ! "\U0001F681" + codes: 1F681 + name: HELICOPTER +- chars: ! "\U0001F69F" + codes: 1F69F + name: SUSPENSION RAILWAY +- chars: ! "\U0001F6A0" + codes: 1F6A0 + name: MOUNTAIN CABLEWAY +- chars: ! "\U0001F6A1" + codes: 1F6A1 + name: AERIAL TRAMWAY +- chars: ! "\U0001F680" + codes: 1F680 + name: ROCKET +- chars: ! "\U0001F6F0" + codes: 1F6F0 + name: SATELLITE +- chars: ! "\U0001F6CE" + codes: 1F6CE + name: BELLHOP BELL +- chars: ! "\U0001F6AA" + codes: 1F6AA + name: DOOR +- chars: ! "\U0001F6CC" + codes: 1F6CC + name: SLEEPING ACCOMMODATION +- chars: ! "\U0001F6CF" + codes: 1F6CF + name: BED +- chars: ! "\U0001F6CB" + codes: 1F6CB + name: COUCH AND LAMP +- chars: ! "\U0001F6BD" + codes: 1F6BD + name: TOILET +- chars: ! "\U0001F6BF" + codes: 1F6BF + name: SHOWER +- chars: ! "\U0001F6C0" + codes: 1F6C0 + name: BATH +- chars: ! "\U0001F6C1" + codes: 1F6C1 + name: BATHTUB +- chars: ⌛️ + codes: 231B + name: HOURGLASS +- chars: ⏳ + codes: 23F3 + name: HOURGLASS WITH FLOWING SAND +- chars: ⌚️ + codes: 231A + name: WATCH +- chars: ⏰ + codes: 23F0 + name: ALARM CLOCK +- chars: ⏱ + codes: 23F1 + name: STOPWATCH +- chars: ⏲ + codes: 23F2 + name: TIMER CLOCK +- chars: ! "\U0001F570" + codes: 1F570 + name: MANTELPIECE CLOCK +- chars: ! "\U0001F55B" + codes: 1F55B + name: CLOCK FACE TWELVE OCLOCK +- chars: ! "\U0001F567" + codes: 1F567 + name: CLOCK FACE TWELVE-THIRTY +- chars: ! "\U0001F550" + codes: 1F550 + name: CLOCK FACE ONE OCLOCK +- chars: ! "\U0001F55C" + codes: 1F55C + name: CLOCK FACE ONE-THIRTY +- chars: ! "\U0001F551" + codes: 1F551 + name: CLOCK FACE TWO OCLOCK +- chars: ! "\U0001F55D" + codes: 1F55D + name: CLOCK FACE TWO-THIRTY +- chars: ! "\U0001F552" + codes: 1F552 + name: CLOCK FACE THREE OCLOCK +- chars: ! "\U0001F55E" + codes: 1F55E + name: CLOCK FACE THREE-THIRTY +- chars: ! "\U0001F553" + codes: 1F553 + name: CLOCK FACE FOUR OCLOCK +- chars: ! "\U0001F55F" + codes: 1F55F + name: CLOCK FACE FOUR-THIRTY +- chars: ! "\U0001F554" + codes: 1F554 + name: CLOCK FACE FIVE OCLOCK +- chars: ! "\U0001F560" + codes: 1F560 + name: CLOCK FACE FIVE-THIRTY +- chars: ! "\U0001F555" + codes: 1F555 + name: CLOCK FACE SIX OCLOCK +- chars: ! "\U0001F561" + codes: 1F561 + name: CLOCK FACE SIX-THIRTY +- chars: ! "\U0001F556" + codes: 1F556 + name: CLOCK FACE SEVEN OCLOCK +- chars: ! "\U0001F562" + codes: 1F562 + name: CLOCK FACE SEVEN-THIRTY +- chars: ! "\U0001F557" + codes: 1F557 + name: CLOCK FACE EIGHT OCLOCK +- chars: ! "\U0001F563" + codes: 1F563 + name: CLOCK FACE EIGHT-THIRTY +- chars: ! "\U0001F558" + codes: 1F558 + name: CLOCK FACE NINE OCLOCK +- chars: ! "\U0001F564" + codes: 1F564 + name: CLOCK FACE NINE-THIRTY +- chars: ! "\U0001F559" + codes: 1F559 + name: CLOCK FACE TEN OCLOCK +- chars: ! "\U0001F565" + codes: 1F565 + name: CLOCK FACE TEN-THIRTY +- chars: ! "\U0001F55A" + codes: 1F55A + name: CLOCK FACE ELEVEN OCLOCK +- chars: ! "\U0001F566" + codes: 1F566 + name: CLOCK FACE ELEVEN-THIRTY +- chars: ! "\U0001F311" + codes: 1F311 + name: NEW MOON SYMBOL +- chars: ! "\U0001F312" + codes: 1F312 + name: WAXING CRESCENT MOON SYMBOL +- chars: ! "\U0001F313" + codes: 1F313 + name: FIRST QUARTER MOON SYMBOL +- chars: ! "\U0001F314" + codes: 1F314 + name: WAXING GIBBOUS MOON SYMBOL +- chars: ! "\U0001F315" + codes: 1F315 + name: FULL MOON SYMBOL +- chars: ! "\U0001F316" + codes: 1F316 + name: WANING GIBBOUS MOON SYMBOL +- chars: ! "\U0001F317" + codes: 1F317 + name: LAST QUARTER MOON SYMBOL +- chars: ! "\U0001F318" + codes: 1F318 + name: WANING CRESCENT MOON SYMBOL +- chars: ! "\U0001F319" + codes: 1F319 + name: CRESCENT MOON +- chars: ! "\U0001F31A" + codes: 1F31A + name: NEW MOON WITH FACE +- chars: ! "\U0001F31B" + codes: 1F31B + name: FIRST QUARTER MOON WITH FACE +- chars: ! "\U0001F31C" + codes: 1F31C + name: LAST QUARTER MOON WITH FACE +- chars: ! "\U0001F321" + codes: 1F321 + name: THERMOMETER +- chars: ☀️ + codes: '2600' + name: BLACK SUN WITH RAYS +- chars: ! "\U0001F31D" + codes: 1F31D + name: FULL MOON WITH FACE +- chars: ! "\U0001F31E" + codes: 1F31E + name: SUN WITH FACE +- chars: ⭐️ + codes: 2B50 + name: WHITE MEDIUM STAR +- chars: ! "\U0001F31F" + codes: 1F31F + name: GLOWING STAR +- chars: ! "\U0001F320" + codes: 1F320 + name: SHOOTING STAR +- chars: ☁️ + codes: '2601' + name: CLOUD +- chars: ⛅️ + codes: 26C5 + name: SUN BEHIND CLOUD +- chars: ⛈ + codes: 26C8 + name: THUNDER CLOUD AND RAIN +- chars: ! "\U0001F324" + codes: 1F324 + name: WHITE SUN WITH SMALL CLOUD +- chars: ! "\U0001F325" + codes: 1F325 + name: WHITE SUN BEHIND CLOUD +- chars: ! "\U0001F326" + codes: 1F326 + name: WHITE SUN BEHIND CLOUD WITH RAIN +- chars: ! "\U0001F327" + codes: 1F327 + name: CLOUD WITH RAIN +- chars: ! "\U0001F328" + codes: 1F328 + name: CLOUD WITH SNOW +- chars: ! "\U0001F329" + codes: 1F329 + name: CLOUD WITH LIGHTNING +- chars: ! "\U0001F32A" + codes: 1F32A + name: CLOUD WITH TORNADO +- chars: ! "\U0001F32B" + codes: 1F32B + name: FOG +- chars: ! "\U0001F32C" + codes: 1F32C + name: WIND BLOWING FACE +- chars: ! "\U0001F300" + codes: 1F300 + name: CYCLONE +- chars: ! "\U0001F308" + codes: 1F308 + name: RAINBOW +- chars: ! "\U0001F302" + codes: 1F302 + name: CLOSED UMBRELLA +- chars: ☂ + codes: '2602' + name: UMBRELLA +- chars: ☔️ + codes: '2614' + name: UMBRELLA WITH RAIN DROPS +- chars: ⛱ + codes: 26F1 + name: UMBRELLA ON GROUND +- chars: ⚡️ + codes: 26A1 + name: HIGH VOLTAGE SIGN +- chars: ❄️ + codes: '2744' + name: SNOWFLAKE +- chars: ☃ + codes: '2603' + name: SNOWMAN +- chars: ⛄️ + codes: 26C4 + name: SNOWMAN WITHOUT SNOW +- chars: ☄ + codes: '2604' + name: COMET +- chars: ! "\U0001F525" + codes: 1F525 + name: FIRE +- chars: ! "\U0001F4A7" + codes: 1F4A7 + name: DROPLET +- chars: ! "\U0001F30A" + codes: 1F30A + name: WATER WAVE +- chars: ! "\U0001F383" + codes: 1F383 + name: JACK-O-LANTERN +- chars: ! "\U0001F384" + codes: 1F384 + name: CHRISTMAS TREE +- chars: ! "\U0001F386" + codes: 1F386 + name: FIREWORKS +- chars: ! "\U0001F387" + codes: 1F387 + name: FIREWORK SPARKLER +- chars: ✨ + codes: '2728' + name: SPARKLES +- chars: ! "\U0001F388" + codes: 1F388 + name: BALLOON +- chars: ! "\U0001F389" + codes: 1F389 + name: PARTY POPPER +- chars: ! "\U0001F38A" + codes: 1F38A + name: CONFETTI BALL +- chars: ! "\U0001F38B" + codes: 1F38B + name: TANABATA TREE +- chars: ! "\U0001F38C" + codes: 1F38C + name: CROSSED FLAGS +- chars: ! "\U0001F38D" + codes: 1F38D + name: PINE DECORATION +- chars: ! "\U0001F38E" + codes: 1F38E + name: JAPANESE DOLLS +- chars: ! "\U0001F38F" + codes: 1F38F + name: CARP STREAMER +- chars: ! "\U0001F390" + codes: 1F390 + name: WIND CHIME +- chars: ! "\U0001F391" + codes: 1F391 + name: MOON VIEWING CEREMONY +- chars: ! "\U0001F380" + codes: 1F380 + name: RIBBON +- chars: ! "\U0001F381" + codes: 1F381 + name: WRAPPED PRESENT +- chars: ! "\U0001F396" + codes: 1F396 + name: MILITARY MEDAL +- chars: ! "\U0001F397" + codes: 1F397 + name: REMINDER RIBBON +- chars: ! "\U0001F39E" + codes: 1F39E + name: FILM FRAMES +- chars: ! "\U0001F39F" + codes: 1F39F + name: ADMISSION TICKETS +- chars: ! "\U0001F3AB" + codes: 1F3AB + name: TICKET +- chars: ! "\U0001F3F7" + codes: 1F3F7 + name: LABEL +- chars: ⚽️ + codes: 26BD + name: SOCCER BALL +- chars: ⚾️ + codes: 26BE + name: BASEBALL +- chars: ! "\U0001F3C0" + codes: 1F3C0 + name: BASKETBALL AND HOOP +- chars: ! "\U0001F3C8" + codes: 1F3C8 + name: AMERICAN FOOTBALL +- chars: ! "\U0001F3C9" + codes: 1F3C9 + name: RUGBY FOOTBALL +- chars: ! "\U0001F3BE" + codes: 1F3BE + name: TENNIS RACQUET AND BALL +- chars: ! "\U0001F3B1" + codes: 1F3B1 + name: BILLIARDS +- chars: ! "\U0001F3B3" + codes: 1F3B3 + name: BOWLING +- chars: ⛳️ + codes: 26F3 + name: FLAG IN HOLE +- chars: ! "\U0001F3CC" + codes: 1F3CC + name: GOLFER +- chars: ⛸ + codes: 26F8 + name: ICE SKATE +- chars: ! "\U0001F3A3" + codes: 1F3A3 + name: FISHING POLE AND FISH +- chars: ! "\U0001F3BD" + codes: 1F3BD + name: RUNNING SHIRT WITH SASH +- chars: ! "\U0001F3BF" + codes: 1F3BF + name: SKI AND SKI BOOT +- chars: ⛷ + codes: 26F7 + name: SKIER +- chars: ! "\U0001F3C2" + codes: 1F3C2 + name: SNOWBOARDER +- chars: ! "\U0001F3C4" + codes: 1F3C4 + name: SURFER +- chars: ! "\U0001F3C7" + codes: 1F3C7 + name: HORSE RACING +- chars: ! "\U0001F3CA" + codes: 1F3CA + name: SWIMMER +- chars: ⛹ + codes: 26F9 + name: PERSON WITH BALL +- chars: ! "\U0001F3CB" + codes: 1F3CB + name: WEIGHT LIFTER +- chars: ! "\U0001F6B4" + codes: 1F6B4 + name: BICYCLIST +- chars: ! "\U0001F6B5" + codes: 1F6B5 + name: MOUNTAIN BICYCLIST +- chars: ! "\U0001F3CE" + codes: 1F3CE + name: RACING CAR +- chars: ! "\U0001F3CD" + codes: 1F3CD + name: RACING MOTORCYCLE +- chars: ! "\U0001F3C5" + codes: 1F3C5 + name: SPORTS MEDAL +- chars: ! "\U0001F3C6" + codes: 1F3C6 + name: TROPHY +- chars: ! "\U0001F3CF" + codes: 1F3CF + name: CRICKET BAT AND BALL +- chars: ! "\U0001F3D0" + codes: 1F3D0 + name: VOLLEYBALL +- chars: ! "\U0001F3D1" + codes: 1F3D1 + name: FIELD HOCKEY STICK AND BALL +- chars: ! "\U0001F3D2" + codes: 1F3D2 + name: ICE HOCKEY STICK AND PUCK +- chars: ! "\U0001F3D3" + codes: 1F3D3 + name: TABLE TENNIS PADDLE AND BALL +- chars: ! "\U0001F3F8" + codes: 1F3F8 + name: BADMINTON RACQUET AND SHUTTLECOCK +- chars: ! "\U0001F3AF" + codes: 1F3AF + name: DIRECT HIT +- chars: ! "\U0001F3AE" + codes: 1F3AE + name: VIDEO GAME +- chars: ! "\U0001F579" + codes: 1F579 + name: JOYSTICK +- chars: ! "\U0001F3B2" + codes: 1F3B2 + name: GAME DIE +- chars: ♠️ + codes: '2660' + name: BLACK SPADE SUIT +- chars: ♥️ + codes: '2665' + name: BLACK HEART SUIT +- chars: ♦️ + codes: '2666' + name: BLACK DIAMOND SUIT +- chars: ♣️ + codes: '2663' + name: BLACK CLUB SUIT +- chars: ! "\U0001F0CF" + codes: 1F0CF + name: PLAYING CARD BLACK JOKER +- chars: ! "\U0001F004️" + codes: 1F004 + name: MAHJONG TILE RED DRAGON +- chars: ! "\U0001F3B4" + codes: 1F3B4 + name: FLOWER PLAYING CARDS +- chars: ! "\U0001F507" + codes: 1F507 + name: SPEAKER WITH CANCELLATION STROKE +- chars: ! "\U0001F508" + codes: 1F508 + name: SPEAKER +- chars: ! "\U0001F509" + codes: 1F509 + name: SPEAKER WITH ONE SOUND WAVE +- chars: ! "\U0001F50A" + codes: 1F50A + name: SPEAKER WITH THREE SOUND WAVES +- chars: ! "\U0001F4E2" + codes: 1F4E2 + name: PUBLIC ADDRESS LOUDSPEAKER +- chars: ! "\U0001F4E3" + codes: 1F4E3 + name: CHEERING MEGAPHONE +- chars: ! "\U0001F4EF" + codes: 1F4EF + name: POSTAL HORN +- chars: ! "\U0001F514" + codes: 1F514 + name: BELL +- chars: ! "\U0001F515" + codes: 1F515 + name: BELL WITH CANCELLATION STROKE +- chars: ! "\U0001F3BC" + codes: 1F3BC + name: MUSICAL SCORE +- chars: ! "\U0001F3B5" + codes: 1F3B5 + name: MUSICAL NOTE +- chars: ! "\U0001F3B6" + codes: 1F3B6 + name: MULTIPLE MUSICAL NOTES +- chars: ! "\U0001F399" + codes: 1F399 + name: STUDIO MICROPHONE +- chars: ! "\U0001F39A" + codes: 1F39A + name: LEVEL SLIDER +- chars: ! "\U0001F39B" + codes: 1F39B + name: CONTROL KNOBS +- chars: ! "\U0001F3A4" + codes: 1F3A4 + name: MICROPHONE +- chars: ! "\U0001F3A7" + codes: 1F3A7 + name: HEADPHONE +- chars: ! "\U0001F3B7" + codes: 1F3B7 + name: SAXOPHONE +- chars: ! "\U0001F3B8" + codes: 1F3B8 + name: GUITAR +- chars: ! "\U0001F3B9" + codes: 1F3B9 + name: MUSICAL KEYBOARD +- chars: ! "\U0001F3BA" + codes: 1F3BA + name: TRUMPET +- chars: ! "\U0001F3BB" + codes: 1F3BB + name: VIOLIN +- chars: ! "\U0001F4FB" + codes: 1F4FB + name: RADIO +- chars: ! "\U0001F4F1" + codes: 1F4F1 + name: MOBILE PHONE +- chars: ! "\U0001F4F2" + codes: 1F4F2 + name: MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT +- chars: ☎️ + codes: '260E' + name: BLACK TELEPHONE +- chars: ! "\U0001F4DE" + codes: 1F4DE + name: TELEPHONE RECEIVER +- chars: ! "\U0001F4DF" + codes: 1F4DF + name: PAGER +- chars: ! "\U0001F4E0" + codes: 1F4E0 + name: FAX MACHINE +- chars: ! "\U0001F50B" + codes: 1F50B + name: BATTERY +- chars: ! "\U0001F50C" + codes: 1F50C + name: ELECTRIC PLUG +- chars: ! "\U0001F4BB" + codes: 1F4BB + name: PERSONAL COMPUTER +- chars: ! "\U0001F5A5" + codes: 1F5A5 + name: DESKTOP COMPUTER +- chars: ! "\U0001F5A8" + codes: 1F5A8 + name: PRINTER +- chars: ⌨ + codes: '2328' + name: KEYBOARD +- chars: ! "\U0001F5B1" + codes: 1F5B1 + name: THREE BUTTON MOUSE +- chars: ! "\U0001F5B2" + codes: 1F5B2 + name: TRACKBALL +- chars: ! "\U0001F4BD" + codes: 1F4BD + name: MINIDISC +- chars: ! "\U0001F4BE" + codes: 1F4BE + name: FLOPPY DISK +- chars: ! "\U0001F4BF" + codes: 1F4BF + name: OPTICAL DISC +- chars: ! "\U0001F4C0" + codes: 1F4C0 + name: DVD +- chars: ! "\U0001F3A5" + codes: 1F3A5 + name: MOVIE CAMERA +- chars: ! "\U0001F3AC" + codes: 1F3AC + name: CLAPPER BOARD +- chars: ! "\U0001F4FD" + codes: 1F4FD + name: FILM PROJECTOR +- chars: ! "\U0001F4FA" + codes: 1F4FA + name: TELEVISION +- chars: ! "\U0001F4F7" + codes: 1F4F7 + name: CAMERA +- chars: ! "\U0001F4F8" + codes: 1F4F8 + name: CAMERA WITH FLASH +- chars: ! "\U0001F4F9" + codes: 1F4F9 + name: VIDEO CAMERA +- chars: ! "\U0001F4FC" + codes: 1F4FC + name: VIDEOCASSETTE +- chars: ! "\U0001F50D" + codes: 1F50D + name: LEFT-POINTING MAGNIFYING GLASS +- chars: ! "\U0001F50E" + codes: 1F50E + name: RIGHT-POINTING MAGNIFYING GLASS +- chars: ! "\U0001F52C" + codes: 1F52C + name: MICROSCOPE +- chars: ! "\U0001F52D" + codes: 1F52D + name: TELESCOPE +- chars: ! "\U0001F4E1" + codes: 1F4E1 + name: SATELLITE ANTENNA +- chars: ! "\U0001F56F" + codes: 1F56F + name: CANDLE +- chars: ! "\U0001F4A1" + codes: 1F4A1 + name: ELECTRIC LIGHT BULB +- chars: ! "\U0001F526" + codes: 1F526 + name: ELECTRIC TORCH +- chars: ! "\U0001F3EE" + codes: 1F3EE + name: IZAKAYA LANTERN +- chars: ! "\U0001F4D4" + codes: 1F4D4 + name: NOTEBOOK WITH DECORATIVE COVER +- chars: ! "\U0001F4D5" + codes: 1F4D5 + name: CLOSED BOOK +- chars: ! "\U0001F4D6" + codes: 1F4D6 + name: OPEN BOOK +- chars: ! "\U0001F4D7" + codes: 1F4D7 + name: GREEN BOOK +- chars: ! "\U0001F4D8" + codes: 1F4D8 + name: BLUE BOOK +- chars: ! "\U0001F4D9" + codes: 1F4D9 + name: ORANGE BOOK +- chars: ! "\U0001F4DA" + codes: 1F4DA + name: BOOKS +- chars: ! "\U0001F4D3" + codes: 1F4D3 + name: NOTEBOOK +- chars: ! "\U0001F4D2" + codes: 1F4D2 + name: LEDGER +- chars: ! "\U0001F4C3" + codes: 1F4C3 + name: PAGE WITH CURL +- chars: ! "\U0001F4DC" + codes: 1F4DC + name: SCROLL +- chars: ! "\U0001F4C4" + codes: 1F4C4 + name: PAGE FACING UP +- chars: ! "\U0001F4F0" + codes: 1F4F0 + name: NEWSPAPER +- chars: ! "\U0001F5DE" + codes: 1F5DE + name: ROLLED-UP NEWSPAPER +- chars: ! "\U0001F4D1" + codes: 1F4D1 + name: BOOKMARK TABS +- chars: ! "\U0001F516" + codes: 1F516 + name: BOOKMARK +- chars: ! "\U0001F4B0" + codes: 1F4B0 + name: MONEY BAG +- chars: ! "\U0001F4B4" + codes: 1F4B4 + name: BANKNOTE WITH YEN SIGN +- chars: ! "\U0001F4B5" + codes: 1F4B5 + name: BANKNOTE WITH DOLLAR SIGN +- chars: ! "\U0001F4B6" + codes: 1F4B6 + name: BANKNOTE WITH EURO SIGN +- chars: ! "\U0001F4B7" + codes: 1F4B7 + name: BANKNOTE WITH POUND SIGN +- chars: ! "\U0001F4B8" + codes: 1F4B8 + name: MONEY WITH WINGS +- chars: ! "\U0001F4B3" + codes: 1F4B3 + name: CREDIT CARD +- chars: ! "\U0001F4B9" + codes: 1F4B9 + name: CHART WITH UPWARDS TREND AND YEN SIGN +- chars: ✉️ + codes: '2709' + name: ENVELOPE +- chars: ! "\U0001F4E7" + codes: 1F4E7 + name: E-MAIL SYMBOL +- chars: ! "\U0001F4E8" + codes: 1F4E8 + name: INCOMING ENVELOPE +- chars: ! "\U0001F4E9" + codes: 1F4E9 + name: ENVELOPE WITH DOWNWARDS ARROW ABOVE +- chars: ! "\U0001F4E4" + codes: 1F4E4 + name: OUTBOX TRAY +- chars: ! "\U0001F4E5" + codes: 1F4E5 + name: INBOX TRAY +- chars: ! "\U0001F4E6" + codes: 1F4E6 + name: PACKAGE +- chars: ! "\U0001F4EB" + codes: 1F4EB + name: CLOSED MAILBOX WITH RAISED FLAG +- chars: ! "\U0001F4EA" + codes: 1F4EA + name: CLOSED MAILBOX WITH LOWERED FLAG +- chars: ! "\U0001F4EC" + codes: 1F4EC + name: OPEN MAILBOX WITH RAISED FLAG +- chars: ! "\U0001F4ED" + codes: 1F4ED + name: OPEN MAILBOX WITH LOWERED FLAG +- chars: ! "\U0001F4EE" + codes: 1F4EE + name: POSTBOX +- chars: ! "\U0001F5F3" + codes: 1F5F3 + name: BALLOT BOX WITH BALLOT +- chars: ✏️ + codes: 270F + name: PENCIL +- chars: ✒️ + codes: '2712' + name: BLACK NIB +- chars: ! "\U0001F58B" + codes: 1F58B + name: LOWER LEFT FOUNTAIN PEN +- chars: ! "\U0001F58A" + codes: 1F58A + name: LOWER LEFT BALLPOINT PEN +- chars: ! "\U0001F58C" + codes: 1F58C + name: LOWER LEFT PAINTBRUSH +- chars: ! "\U0001F58D" + codes: 1F58D + name: LOWER LEFT CRAYON +- chars: ! "\U0001F4DD" + codes: 1F4DD + name: MEMO +- chars: ! "\U0001F4BC" + codes: 1F4BC + name: BRIEFCASE +- chars: ! "\U0001F4C1" + codes: 1F4C1 + name: FILE FOLDER +- chars: ! "\U0001F4C2" + codes: 1F4C2 + name: OPEN FILE FOLDER +- chars: ! "\U0001F5C2" + codes: 1F5C2 + name: CARD INDEX DIVIDERS +- chars: ! "\U0001F4C5" + codes: 1F4C5 + name: CALENDAR +- chars: ! "\U0001F4C6" + codes: 1F4C6 + name: TEAR-OFF CALENDAR +- chars: ! "\U0001F5D2" + codes: 1F5D2 + name: SPIRAL NOTE PAD +- chars: ! "\U0001F5D3" + codes: 1F5D3 + name: SPIRAL CALENDAR PAD +- chars: ! "\U0001F4C7" + codes: 1F4C7 + name: CARD INDEX +- chars: ! "\U0001F4C8" + codes: 1F4C8 + name: CHART WITH UPWARDS TREND +- chars: ! "\U0001F4C9" + codes: 1F4C9 + name: CHART WITH DOWNWARDS TREND +- chars: ! "\U0001F4CA" + codes: 1F4CA + name: BAR CHART +- chars: ! "\U0001F4CB" + codes: 1F4CB + name: CLIPBOARD +- chars: ! "\U0001F4CC" + codes: 1F4CC + name: PUSHPIN +- chars: ! "\U0001F4CD" + codes: 1F4CD + name: ROUND PUSHPIN +- chars: ! "\U0001F4CE" + codes: 1F4CE + name: PAPERCLIP +- chars: ! "\U0001F587" + codes: 1F587 + name: LINKED PAPERCLIPS +- chars: ! "\U0001F4CF" + codes: 1F4CF + name: STRAIGHT RULER +- chars: ! "\U0001F4D0" + codes: 1F4D0 + name: TRIANGULAR RULER +- chars: ✂️ + codes: '2702' + name: BLACK SCISSORS +- chars: ! "\U0001F5C3" + codes: 1F5C3 + name: CARD FILE BOX +- chars: ! "\U0001F5C4" + codes: 1F5C4 + name: FILE CABINET +- chars: ! "\U0001F5D1" + codes: 1F5D1 + name: WASTEBASKET +- chars: ! "\U0001F512" + codes: 1F512 + name: LOCK +- chars: ! "\U0001F513" + codes: 1F513 + name: OPEN LOCK +- chars: ! "\U0001F50F" + codes: 1F50F + name: LOCK WITH INK PEN +- chars: ! "\U0001F510" + codes: 1F510 + name: CLOSED LOCK WITH KEY +- chars: ! "\U0001F511" + codes: 1F511 + name: KEY +- chars: ! "\U0001F5DD" + codes: 1F5DD + name: OLD KEY +- chars: ! "\U0001F528" + codes: 1F528 + name: HAMMER +- chars: ⛏ + codes: 26CF + name: PICK +- chars: ⚒ + codes: '2692' + name: HAMMER AND PICK +- chars: ! "\U0001F6E0" + codes: 1F6E0 + name: HAMMER AND WRENCH +- chars: ! "\U0001F527" + codes: 1F527 + name: WRENCH +- chars: ! "\U0001F529" + codes: 1F529 + name: NUT AND BOLT +- chars: ⚙ + codes: '2699' + name: GEAR +- chars: ! "\U0001F5DC" + codes: 1F5DC + name: COMPRESSION +- chars: ⚗ + codes: '2697' + name: ALEMBIC +- chars: ⚖ + codes: '2696' + name: SCALES +- chars: ! "\U0001F517" + codes: 1F517 + name: LINK SYMBOL +- chars: ⛓ + codes: 26D3 + name: CHAINS +- chars: ! "\U0001F489" + codes: 1F489 + name: SYRINGE +- chars: ! "\U0001F48A" + codes: 1F48A + name: PILL +- chars: ! "\U0001F5E1" + codes: 1F5E1 + name: DAGGER KNIFE +- chars: ! "\U0001F52A" + codes: 1F52A + name: HOCHO +- chars: ⚔ + codes: '2694' + name: CROSSED SWORDS +- chars: ! "\U0001F52B" + codes: 1F52B + name: PISTOL +- chars: ! "\U0001F6E1" + codes: 1F6E1 + name: SHIELD +- chars: ! "\U0001F3F9" + codes: 1F3F9 + name: BOW AND ARROW +- chars: ! "\U0001F3C1" + codes: 1F3C1 + name: CHEQUERED FLAG +- chars: ! "\U0001F3F3" + codes: 1F3F3 + name: WAVING WHITE FLAG +- chars: ! "\U0001F3F4" + codes: 1F3F4 + name: WAVING BLACK FLAG +- chars: ! "\U0001F6A9" + codes: 1F6A9 + name: TRIANGULAR FLAG ON POST +- chars: ! "\U0001F6AC" + codes: 1F6AC + name: SMOKING SYMBOL +- chars: ⚰ + codes: 26B0 + name: COFFIN +- chars: ⚱ + codes: 26B1 + name: FUNERAL URN +- chars: ! "\U0001F5FF" + codes: 1F5FF + name: MOYAI +- chars: ! "\U0001F6E2" + codes: 1F6E2 + name: OIL DRUM +- chars: ! "\U0001F52E" + codes: 1F52E + name: CRYSTAL BALL +- chars: ! "\U0001F3E7" + codes: 1F3E7 + name: AUTOMATED TELLER MACHINE +- chars: ! "\U0001F6AE" + codes: 1F6AE + name: PUT LITTER IN ITS PLACE SYMBOL +- chars: ! "\U0001F6B0" + codes: 1F6B0 + name: POTABLE WATER SYMBOL +- chars: ♿️ + codes: 267F + name: WHEELCHAIR SYMBOL +- chars: ! "\U0001F6B9" + codes: 1F6B9 + name: MENS SYMBOL +- chars: ! "\U0001F6BA" + codes: 1F6BA + name: WOMENS SYMBOL +- chars: ! "\U0001F6BB" + codes: 1F6BB + name: RESTROOM +- chars: ! "\U0001F6BC" + codes: 1F6BC + name: BABY SYMBOL +- chars: ! "\U0001F6BE" + codes: 1F6BE + name: WATER CLOSET +- chars: ! "\U0001F6C2" + codes: 1F6C2 + name: PASSPORT CONTROL +- chars: ! "\U0001F6C3" + codes: 1F6C3 + name: CUSTOMS +- chars: ! "\U0001F6C4" + codes: 1F6C4 + name: BAGGAGE CLAIM +- chars: ! "\U0001F6C5" + codes: 1F6C5 + name: LEFT LUGGAGE +- chars: ⚠️ + codes: 26A0 + name: WARNING SIGN +- chars: ! "\U0001F6B8" + codes: 1F6B8 + name: CHILDREN CROSSING +- chars: ⛔️ + codes: 26D4 + name: NO ENTRY +- chars: ! "\U0001F6AB" + codes: 1F6AB + name: NO ENTRY SIGN +- chars: ! "\U0001F6B3" + codes: 1F6B3 + name: NO BICYCLES +- chars: ! "\U0001F6AD" + codes: 1F6AD + name: NO SMOKING SYMBOL +- chars: ! "\U0001F6AF" + codes: 1F6AF + name: DO NOT LITTER SYMBOL +- chars: ! "\U0001F6B1" + codes: 1F6B1 + name: NON-POTABLE WATER SYMBOL +- chars: ! "\U0001F6B7" + codes: 1F6B7 + name: NO PEDESTRIANS +- chars: ☢ + codes: '2622' + name: RADIOACTIVE SIGN +- chars: ☣ + codes: '2623' + name: BIOHAZARD SIGN +- chars: ⬆️ + codes: 2B06 + name: UPWARDS BLACK ARROW +- chars: ↗️ + codes: '2197' + name: NORTH EAST ARROW +- chars: ➡️ + codes: 27A1 + name: BLACK RIGHTWARDS ARROW +- chars: ↘️ + codes: '2198' + name: SOUTH EAST ARROW +- chars: ⬇️ + codes: 2B07 + name: DOWNWARDS BLACK ARROW +- chars: ↙️ + codes: '2199' + name: SOUTH WEST ARROW +- chars: ⬅️ + codes: 2B05 + name: LEFTWARDS BLACK ARROW +- chars: ↖️ + codes: '2196' + name: NORTH WEST ARROW +- chars: ↕️ + codes: '2195' + name: UP DOWN ARROW +- chars: ↔️ + codes: '2194' + name: LEFT RIGHT ARROW +- chars: ↩️ + codes: 21A9 + name: LEFTWARDS ARROW WITH HOOK +- chars: ↪️ + codes: 21AA + name: RIGHTWARDS ARROW WITH HOOK +- chars: ⤴️ + codes: '2934' + name: ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS +- chars: ⤵️ + codes: '2935' + name: ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS +- chars: ! "\U0001F503" + codes: 1F503 + name: CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS +- chars: ! "\U0001F504" + codes: 1F504 + name: ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS +- chars: ! "\U0001F519" + codes: 1F519 + name: BACK WITH LEFTWARDS ARROW ABOVE +- chars: ! "\U0001F51A" + codes: 1F51A + name: END WITH LEFTWARDS ARROW ABOVE +- chars: ! "\U0001F51B" + codes: 1F51B + name: ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE +- chars: ! "\U0001F51C" + codes: 1F51C + name: SOON WITH RIGHTWARDS ARROW ABOVE +- chars: ! "\U0001F51D" + codes: 1F51D + name: TOP WITH UPWARDS ARROW ABOVE +- chars: ! "\U0001F6D0" + codes: 1F6D0 + name: PLACE OF WORSHIP +- chars: ⚛ + codes: 269B + name: ATOM SYMBOL +- chars: ! "\U0001F549" + codes: 1F549 + name: OM SYMBOL +- chars: ✡ + codes: '2721' + name: STAR OF DAVID +- chars: ☸ + codes: '2638' + name: WHEEL OF DHARMA +- chars: ☯ + codes: 262F + name: YIN YANG +- chars: ✝ + codes: 271D + name: LATIN CROSS +- chars: ☦ + codes: '2626' + name: ORTHODOX CROSS +- chars: ☪ + codes: 262A + name: STAR AND CRESCENT +- chars: ☮ + codes: '262E' + name: PEACE SYMBOL +- chars: ! "\U0001F54E" + codes: 1F54E + name: MENORAH WITH NINE BRANCHES +- chars: ! "\U0001F52F" + codes: 1F52F + name: SIX POINTED STAR WITH MIDDLE DOT +- chars: ♻️ + codes: 267B + name: BLACK UNIVERSAL RECYCLING SYMBOL +- chars: ! "\U0001F4DB" + codes: 1F4DB + name: NAME BADGE +- chars: ⚜ + codes: 269C + name: FLEUR-DE-LIS +- chars: ! "\U0001F530" + codes: 1F530 + name: JAPANESE SYMBOL FOR BEGINNER +- chars: ! "\U0001F531" + codes: 1F531 + name: TRIDENT EMBLEM +- chars: ⭕️ + codes: 2B55 + name: HEAVY LARGE CIRCLE +- chars: ✅ + codes: '2705' + name: WHITE HEAVY CHECK MARK +- chars: ☑️ + codes: '2611' + name: BALLOT BOX WITH CHECK +- chars: ✔️ + codes: '2714' + name: HEAVY CHECK MARK +- chars: ✖️ + codes: '2716' + name: HEAVY MULTIPLICATION X +- chars: ❌ + codes: 274C + name: CROSS MARK +- chars: ❎ + codes: '274E' + name: NEGATIVE SQUARED CROSS MARK +- chars: ➕ + codes: '2795' + name: HEAVY PLUS SIGN +- chars: ➖ + codes: '2796' + name: HEAVY MINUS SIGN +- chars: ➗ + codes: '2797' + name: HEAVY DIVISION SIGN +- chars: ➰ + codes: 27B0 + name: CURLY LOOP +- chars: ➿ + codes: 27BF + name: DOUBLE CURLY LOOP +- chars: 〽️ + codes: 303D + name: PART ALTERNATION MARK +- chars: ✳️ + codes: '2733' + name: EIGHT SPOKED ASTERISK +- chars: ✴️ + codes: '2734' + name: EIGHT POINTED BLACK STAR +- chars: ❇️ + codes: '2747' + name: SPARKLE +- chars: ! "\U0001F4B1" + codes: 1F4B1 + name: CURRENCY EXCHANGE +- chars: ! "\U0001F4B2" + codes: 1F4B2 + name: HEAVY DOLLAR SIGN +- chars: ‼️ + codes: 203C + name: DOUBLE EXCLAMATION MARK +- chars: ⁉️ + codes: '2049' + name: EXCLAMATION QUESTION MARK +- chars: ❓ + codes: '2753' + name: BLACK QUESTION MARK ORNAMENT +- chars: ❔ + codes: '2754' + name: WHITE QUESTION MARK ORNAMENT +- chars: ❕ + codes: '2755' + name: WHITE EXCLAMATION MARK ORNAMENT +- chars: ❗️ + codes: '2757' + name: HEAVY EXCLAMATION MARK SYMBOL +- chars: 〰️ + codes: '3030' + name: WAVY DASH +- chars: ©️ + codes: 00A9 + name: COPYRIGHT SIGN +- chars: ®️ + codes: 00AE + name: REGISTERED SIGN +- chars: ™️ + codes: '2122' + name: TRADE MARK SIGN +- chars: ♈️ + codes: '2648' + name: ARIES +- chars: ♉️ + codes: '2649' + name: TAURUS +- chars: ♊️ + codes: 264A + name: GEMINI +- chars: ♋️ + codes: 264B + name: CANCER +- chars: ♌️ + codes: 264C + name: LEO +- chars: ♍️ + codes: 264D + name: VIRGO +- chars: ♎️ + codes: '264E' + name: LIBRA +- chars: ♏️ + codes: 264F + name: SCORPIUS +- chars: ♐️ + codes: '2650' + name: SAGITTARIUS +- chars: ♑️ + codes: '2651' + name: CAPRICORN +- chars: ♒️ + codes: '2652' + name: AQUARIUS +- chars: ♓️ + codes: '2653' + name: PISCES +- chars: ⛎ + codes: 26CE + name: OPHIUCHUS +- chars: ! "\U0001F500" + codes: 1F500 + name: TWISTED RIGHTWARDS ARROWS +- chars: ! "\U0001F501" + codes: 1F501 + name: CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS +- chars: ! "\U0001F502" + codes: 1F502 + name: CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY +- chars: ▶️ + codes: 25B6 + name: BLACK RIGHT-POINTING TRIANGLE +- chars: ⏩ + codes: '23E9' + name: BLACK RIGHT-POINTING DOUBLE TRIANGLE +- chars: ⏭ + codes: 23ED + name: BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +- chars: ⏯ + codes: 23EF + name: BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR +- chars: ◀️ + codes: 25C0 + name: BLACK LEFT-POINTING TRIANGLE +- chars: ⏪ + codes: 23EA + name: BLACK LEFT-POINTING DOUBLE TRIANGLE +- chars: ⏮ + codes: '23EE' + name: BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +- chars: ! "\U0001F53C" + codes: 1F53C + name: UP-POINTING SMALL RED TRIANGLE +- chars: ⏫ + codes: 23EB + name: BLACK UP-POINTING DOUBLE TRIANGLE +- chars: ! "\U0001F53D" + codes: 1F53D + name: DOWN-POINTING SMALL RED TRIANGLE +- chars: ⏬ + codes: 23EC + name: BLACK DOWN-POINTING DOUBLE TRIANGLE +- chars: ⏸ + codes: 23F8 + name: DOUBLE VERTICAL BAR +- chars: ⏹ + codes: 23F9 + name: BLACK SQUARE FOR STOP +- chars: ⏺ + codes: 23FA + name: BLACK CIRCLE FOR RECORD +- chars: ⏏ + codes: 23CF + name: EJECT SYMBOL +- chars: ! "\U0001F3A6" + codes: 1F3A6 + name: CINEMA +- chars: ! "\U0001F505" + codes: 1F505 + name: LOW BRIGHTNESS SYMBOL +- chars: ! "\U0001F506" + codes: 1F506 + name: HIGH BRIGHTNESS SYMBOL +- chars: ! "\U0001F4F6" + codes: 1F4F6 + name: ANTENNA WITH BARS +- chars: ! "\U0001F4F5" + codes: 1F4F5 + name: NO MOBILE PHONES +- chars: ! "\U0001F4F3" + codes: 1F4F3 + name: VIBRATION MODE +- chars: ! "\U0001F4F4" + codes: 1F4F4 + name: MOBILE PHONE OFF +- chars: ! '#' + codes: 0023 20E3 + name: Keycap NUMBER SIGN +- chars: ! '*⃣' + codes: 002A 20E3 + name: Keycap ASTERISK +- chars: '0' + codes: 0030 20E3 + name: Keycap DIGIT ZERO +- chars: '1' + codes: 0031 20E3 + name: Keycap DIGIT ONE +- chars: '2' + codes: 0032 20E3 + name: Keycap DIGIT TWO +- chars: '3' + codes: 0033 20E3 + name: Keycap DIGIT THREE +- chars: '4' + codes: 0034 20E3 + name: Keycap DIGIT FOUR +- chars: '5' + codes: 0035 20E3 + name: Keycap DIGIT FIVE +- chars: '6' + codes: 0036 20E3 + name: Keycap DIGIT SIX +- chars: '7' + codes: 0037 20E3 + name: Keycap DIGIT SEVEN +- chars: '8' + codes: 0038 20E3 + name: Keycap DIGIT EIGHT +- chars: '9' + codes: 0039 20E3 + name: Keycap DIGIT NINE +- chars: ! "\U0001F51F" + codes: 1F51F + name: KEYCAP TEN +- chars: ! "\U0001F4AF" + codes: 1F4AF + name: HUNDRED POINTS SYMBOL +- chars: ! "\U0001F51E" + codes: 1F51E + name: NO ONE UNDER EIGHTEEN SYMBOL +- chars: ! "\U0001F520" + codes: 1F520 + name: INPUT SYMBOL FOR LATIN CAPITAL LETTERS +- chars: ! "\U0001F521" + codes: 1F521 + name: INPUT SYMBOL FOR LATIN SMALL LETTERS +- chars: ! "\U0001F522" + codes: 1F522 + name: INPUT SYMBOL FOR NUMBERS +- chars: ! "\U0001F523" + codes: 1F523 + name: INPUT SYMBOL FOR SYMBOLS +- chars: ! "\U0001F524" + codes: 1F524 + name: INPUT SYMBOL FOR LATIN LETTERS +- chars: ! "\U0001F170️" + codes: 1F170 + name: NEGATIVE SQUARED LATIN CAPITAL LETTER A +- chars: ! "\U0001F18E" + codes: 1F18E + name: NEGATIVE SQUARED AB +- chars: ! "\U0001F171️" + codes: 1F171 + name: NEGATIVE SQUARED LATIN CAPITAL LETTER B +- chars: ! "\U0001F191" + codes: 1F191 + name: SQUARED CL +- chars: ! "\U0001F192" + codes: 1F192 + name: SQUARED COOL +- chars: ! "\U0001F193" + codes: 1F193 + name: SQUARED FREE +- chars: ℹ️ + codes: '2139' + name: INFORMATION SOURCE +- chars: ! "\U0001F194" + codes: 1F194 + name: SQUARED ID +- chars: Ⓜ️ + codes: 24C2 + name: CIRCLED LATIN CAPITAL LETTER M +- chars: ! "\U0001F195" + codes: 1F195 + name: SQUARED NEW +- chars: ! "\U0001F196" + codes: 1F196 + name: SQUARED NG +- chars: ! "\U0001F17E️" + codes: 1F17E + name: NEGATIVE SQUARED LATIN CAPITAL LETTER O +- chars: ! "\U0001F197" + codes: 1F197 + name: SQUARED OK +- chars: ! "\U0001F17F️" + codes: 1F17F + name: NEGATIVE SQUARED LATIN CAPITAL LETTER P +- chars: ! "\U0001F198" + codes: 1F198 + name: SQUARED SOS +- chars: ! "\U0001F199" + codes: 1F199 + name: SQUARED UP WITH EXCLAMATION MARK +- chars: ! "\U0001F19A" + codes: 1F19A + name: SQUARED VS +- chars: ! "\U0001F201" + codes: 1F201 + name: SQUARED KATAKANA KOKO +- chars: ! "\U0001F202️" + codes: 1F202 + name: SQUARED KATAKANA SA +- chars: ! "\U0001F237️" + codes: 1F237 + name: SQUARED CJK UNIFIED IDEOGRAPH-6708 +- chars: ! "\U0001F236" + codes: 1F236 + name: SQUARED CJK UNIFIED IDEOGRAPH-6709 +- chars: ! "\U0001F22F️" + codes: 1F22F + name: SQUARED CJK UNIFIED IDEOGRAPH-6307 +- chars: ! "\U0001F250" + codes: 1F250 + name: CIRCLED IDEOGRAPH ADVANTAGE +- chars: ! "\U0001F239" + codes: 1F239 + name: SQUARED CJK UNIFIED IDEOGRAPH-5272 +- chars: ! "\U0001F21A️" + codes: 1F21A + name: SQUARED CJK UNIFIED IDEOGRAPH-7121 +- chars: ! "\U0001F232" + codes: 1F232 + name: SQUARED CJK UNIFIED IDEOGRAPH-7981 +- chars: ! "\U0001F251" + codes: 1F251 + name: CIRCLED IDEOGRAPH ACCEPT +- chars: ! "\U0001F238" + codes: 1F238 + name: SQUARED CJK UNIFIED IDEOGRAPH-7533 +- chars: ! "\U0001F234" + codes: 1F234 + name: SQUARED CJK UNIFIED IDEOGRAPH-5408 +- chars: ! "\U0001F233" + codes: 1F233 + name: SQUARED CJK UNIFIED IDEOGRAPH-7A7A +- chars: ㊗️ + codes: '3297' + name: CIRCLED IDEOGRAPH CONGRATULATION +- chars: ㊙️ + codes: '3299' + name: CIRCLED IDEOGRAPH SECRET +- chars: ! "\U0001F23A" + codes: 1F23A + name: SQUARED CJK UNIFIED IDEOGRAPH-55B6 +- chars: ! "\U0001F235" + codes: 1F235 + name: SQUARED CJK UNIFIED IDEOGRAPH-6E80 +- chars: ▪️ + codes: 25AA + name: BLACK SMALL SQUARE +- chars: ▫️ + codes: 25AB + name: WHITE SMALL SQUARE +- chars: ◻️ + codes: 25FB + name: WHITE MEDIUM SQUARE +- chars: ◼️ + codes: 25FC + name: BLACK MEDIUM SQUARE +- chars: ◽️ + codes: 25FD + name: WHITE MEDIUM SMALL SQUARE +- chars: ◾️ + codes: 25FE + name: BLACK MEDIUM SMALL SQUARE +- chars: ⬛️ + codes: 2B1B + name: BLACK LARGE SQUARE +- chars: ⬜️ + codes: 2B1C + name: WHITE LARGE SQUARE +- chars: ! "\U0001F536" + codes: 1F536 + name: LARGE ORANGE DIAMOND +- chars: ! "\U0001F537" + codes: 1F537 + name: LARGE BLUE DIAMOND +- chars: ! "\U0001F538" + codes: 1F538 + name: SMALL ORANGE DIAMOND +- chars: ! "\U0001F539" + codes: 1F539 + name: SMALL BLUE DIAMOND +- chars: ! "\U0001F53A" + codes: 1F53A + name: UP-POINTING RED TRIANGLE +- chars: ! "\U0001F53B" + codes: 1F53B + name: DOWN-POINTING RED TRIANGLE +- chars: ! "\U0001F4A0" + codes: 1F4A0 + name: DIAMOND SHAPE WITH A DOT INSIDE +- chars: ! "\U0001F518" + codes: 1F518 + name: RADIO BUTTON +- chars: ! "\U0001F532" + codes: 1F532 + name: BLACK SQUARE BUTTON +- chars: ! "\U0001F533" + codes: 1F533 + name: WHITE SQUARE BUTTON +- chars: ⚪️ + codes: 26AA + name: MEDIUM WHITE CIRCLE +- chars: ⚫️ + codes: 26AB + name: MEDIUM BLACK CIRCLE +- chars: ! "\U0001F534" + codes: 1F534 + name: LARGE RED CIRCLE +- chars: ! "\U0001F535" + codes: 1F535 + name: LARGE BLUE CIRCLE +- chars: ! "\U0001F1E6\U0001F1E8" + codes: 1F1E6 1F1E8 + name: Flag for Ascension Island +- chars: ! "\U0001F1E6\U0001F1E9" + codes: 1F1E6 1F1E9 + name: Flag for Andorra +- chars: ! "\U0001F1E6\U0001F1EA" + codes: 1F1E6 1F1EA + name: Flag for United Arab Emirates +- chars: ! "\U0001F1E6\U0001F1EB" + codes: 1F1E6 1F1EB + name: Flag for Afghanistan +- chars: ! "\U0001F1E6\U0001F1EC" + codes: 1F1E6 1F1EC + name: Flag for Antigua & Barbuda +- chars: ! "\U0001F1E6\U0001F1EE" + codes: 1F1E6 1F1EE + name: Flag for Anguilla +- chars: ! "\U0001F1E6\U0001F1F1" + codes: 1F1E6 1F1F1 + name: Flag for Albania +- chars: ! "\U0001F1E6\U0001F1F2" + codes: 1F1E6 1F1F2 + name: Flag for Armenia +- chars: ! "\U0001F1E6\U0001F1F4" + codes: 1F1E6 1F1F4 + name: Flag for Angola +- chars: ! "\U0001F1E6\U0001F1F6" + codes: 1F1E6 1F1F6 + name: Flag for Antarctica +- chars: ! "\U0001F1E6\U0001F1F7" + codes: 1F1E6 1F1F7 + name: Flag for Argentina +- chars: ! "\U0001F1E6\U0001F1F8" + codes: 1F1E6 1F1F8 + name: Flag for American Samoa +- chars: ! "\U0001F1E6\U0001F1F9" + codes: 1F1E6 1F1F9 + name: Flag for Austria +- chars: ! "\U0001F1E6\U0001F1FA" + codes: 1F1E6 1F1FA + name: Flag for Australia +- chars: ! "\U0001F1E6\U0001F1FC" + codes: 1F1E6 1F1FC + name: Flag for Aruba +- chars: ! "\U0001F1E6\U0001F1FD" + codes: 1F1E6 1F1FD + name: Flag for Åland Islands +- chars: ! "\U0001F1E6\U0001F1FF" + codes: 1F1E6 1F1FF + name: Flag for Azerbaijan +- chars: ! "\U0001F1E7\U0001F1E6" + codes: 1F1E7 1F1E6 + name: Flag for Bosnia & Herzegovina +- chars: ! "\U0001F1E7\U0001F1E7" + codes: 1F1E7 1F1E7 + name: Flag for Barbados +- chars: ! "\U0001F1E7\U0001F1E9" + codes: 1F1E7 1F1E9 + name: Flag for Bangladesh +- chars: ! "\U0001F1E7\U0001F1EA" + codes: 1F1E7 1F1EA + name: Flag for Belgium +- chars: ! "\U0001F1E7\U0001F1EB" + codes: 1F1E7 1F1EB + name: Flag for Burkina Faso +- chars: ! "\U0001F1E7\U0001F1EC" + codes: 1F1E7 1F1EC + name: Flag for Bulgaria +- chars: ! "\U0001F1E7\U0001F1ED" + codes: 1F1E7 1F1ED + name: Flag for Bahrain +- chars: ! "\U0001F1E7\U0001F1EE" + codes: 1F1E7 1F1EE + name: Flag for Burundi +- chars: ! "\U0001F1E7\U0001F1EF" + codes: 1F1E7 1F1EF + name: Flag for Benin +- chars: ! "\U0001F1E7\U0001F1F1" + codes: 1F1E7 1F1F1 + name: Flag for St. Barthélemy +- chars: ! "\U0001F1E7\U0001F1F2" + codes: 1F1E7 1F1F2 + name: Flag for Bermuda +- chars: ! "\U0001F1E7\U0001F1F3" + codes: 1F1E7 1F1F3 + name: Flag for Brunei +- chars: ! "\U0001F1E7\U0001F1F4" + codes: 1F1E7 1F1F4 + name: Flag for Bolivia +- chars: ! "\U0001F1E7\U0001F1F6" + codes: 1F1E7 1F1F6 + name: Flag for Caribbean Netherlands +- chars: ! "\U0001F1E7\U0001F1F7" + codes: 1F1E7 1F1F7 + name: Flag for Brazil +- chars: ! "\U0001F1E7\U0001F1F8" + codes: 1F1E7 1F1F8 + name: Flag for Bahamas +- chars: ! "\U0001F1E7\U0001F1F9" + codes: 1F1E7 1F1F9 + name: Flag for Bhutan +- chars: ! "\U0001F1E7\U0001F1FB" + codes: 1F1E7 1F1FB + name: Flag for Bouvet Island +- chars: ! "\U0001F1E7\U0001F1FC" + codes: 1F1E7 1F1FC + name: Flag for Botswana +- chars: ! "\U0001F1E7\U0001F1FE" + codes: 1F1E7 1F1FE + name: Flag for Belarus +- chars: ! "\U0001F1E7\U0001F1FF" + codes: 1F1E7 1F1FF + name: Flag for Belize +- chars: ! "\U0001F1E8\U0001F1E6" + codes: 1F1E8 1F1E6 + name: Flag for Canada +- chars: ! "\U0001F1E8\U0001F1E8" + codes: 1F1E8 1F1E8 + name: Flag for Cocos Islands +- chars: ! "\U0001F1E8\U0001F1E9" + codes: 1F1E8 1F1E9 + name: Flag for Congo - Kinshasa +- chars: ! "\U0001F1E8\U0001F1EB" + codes: 1F1E8 1F1EB + name: Flag for Central African Republic +- chars: ! "\U0001F1E8\U0001F1EC" + codes: 1F1E8 1F1EC + name: Flag for Congo - Brazzaville +- chars: ! "\U0001F1E8\U0001F1ED" + codes: 1F1E8 1F1ED + name: Flag for Switzerland +- chars: ! "\U0001F1E8\U0001F1EE" + codes: 1F1E8 1F1EE + name: Flag for Côte d’Ivoire +- chars: ! "\U0001F1E8\U0001F1F0" + codes: 1F1E8 1F1F0 + name: Flag for Cook Islands +- chars: ! "\U0001F1E8\U0001F1F1" + codes: 1F1E8 1F1F1 + name: Flag for Chile +- chars: ! "\U0001F1E8\U0001F1F2" + codes: 1F1E8 1F1F2 + name: Flag for Cameroon +- chars: ! "\U0001F1E8\U0001F1F3" + codes: 1F1E8 1F1F3 + name: Flag for China +- chars: ! "\U0001F1E8\U0001F1F4" + codes: 1F1E8 1F1F4 + name: Flag for Colombia +- chars: ! "\U0001F1E8\U0001F1F5" + codes: 1F1E8 1F1F5 + name: Flag for Clipperton Island +- chars: ! "\U0001F1E8\U0001F1F7" + codes: 1F1E8 1F1F7 + name: Flag for Costa Rica +- chars: ! "\U0001F1E8\U0001F1FA" + codes: 1F1E8 1F1FA + name: Flag for Cuba +- chars: ! "\U0001F1E8\U0001F1FB" + codes: 1F1E8 1F1FB + name: Flag for Cape Verde +- chars: ! "\U0001F1E8\U0001F1FC" + codes: 1F1E8 1F1FC + name: Flag for Curaçao +- chars: ! "\U0001F1E8\U0001F1FD" + codes: 1F1E8 1F1FD + name: Flag for Christmas Island +- chars: ! "\U0001F1E8\U0001F1FE" + codes: 1F1E8 1F1FE + name: Flag for Cyprus +- chars: ! "\U0001F1E8\U0001F1FF" + codes: 1F1E8 1F1FF + name: Flag for Czech Republic +- chars: ! "\U0001F1E9\U0001F1EA" + codes: 1F1E9 1F1EA + name: Flag for Germany +- chars: ! "\U0001F1E9\U0001F1EC" + codes: 1F1E9 1F1EC + name: Flag for Diego Garcia +- chars: ! "\U0001F1E9\U0001F1EF" + codes: 1F1E9 1F1EF + name: Flag for Djibouti +- chars: ! "\U0001F1E9\U0001F1F0" + codes: 1F1E9 1F1F0 + name: Flag for Denmark +- chars: ! "\U0001F1E9\U0001F1F2" + codes: 1F1E9 1F1F2 + name: Flag for Dominica +- chars: ! "\U0001F1E9\U0001F1F4" + codes: 1F1E9 1F1F4 + name: Flag for Dominican Republic +- chars: ! "\U0001F1E9\U0001F1FF" + codes: 1F1E9 1F1FF + name: Flag for Algeria +- chars: ! "\U0001F1EA\U0001F1E6" + codes: 1F1EA 1F1E6 + name: Flag for Ceuta & Melilla +- chars: ! "\U0001F1EA\U0001F1E8" + codes: 1F1EA 1F1E8 + name: Flag for Ecuador +- chars: ! "\U0001F1EA\U0001F1EA" + codes: 1F1EA 1F1EA + name: Flag for Estonia +- chars: ! "\U0001F1EA\U0001F1EC" + codes: 1F1EA 1F1EC + name: Flag for Egypt +- chars: ! "\U0001F1EA\U0001F1ED" + codes: 1F1EA 1F1ED + name: Flag for Western Sahara +- chars: ! "\U0001F1EA\U0001F1F7" + codes: 1F1EA 1F1F7 + name: Flag for Eritrea +- chars: ! "\U0001F1EA\U0001F1F8" + codes: 1F1EA 1F1F8 + name: Flag for Spain +- chars: ! "\U0001F1EA\U0001F1F9" + codes: 1F1EA 1F1F9 + name: Flag for Ethiopia +- chars: ! "\U0001F1EA\U0001F1FA" + codes: 1F1EA 1F1FA + name: Flag for European Union +- chars: ! "\U0001F1EB\U0001F1EE" + codes: 1F1EB 1F1EE + name: Flag for Finland +- chars: ! "\U0001F1EB\U0001F1EF" + codes: 1F1EB 1F1EF + name: Flag for Fiji +- chars: ! "\U0001F1EB\U0001F1F0" + codes: 1F1EB 1F1F0 + name: Flag for Falkland Islands +- chars: ! "\U0001F1EB\U0001F1F2" + codes: 1F1EB 1F1F2 + name: Flag for Micronesia +- chars: ! "\U0001F1EB\U0001F1F4" + codes: 1F1EB 1F1F4 + name: Flag for Faroe Islands +- chars: ! "\U0001F1EB\U0001F1F7" + codes: 1F1EB 1F1F7 + name: Flag for France +- chars: ! "\U0001F1EC\U0001F1E6" + codes: 1F1EC 1F1E6 + name: Flag for Gabon +- chars: ! "\U0001F1EC\U0001F1E7" + codes: 1F1EC 1F1E7 + name: Flag for United Kingdom +- chars: ! "\U0001F1EC\U0001F1E9" + codes: 1F1EC 1F1E9 + name: Flag for Grenada +- chars: ! "\U0001F1EC\U0001F1EA" + codes: 1F1EC 1F1EA + name: Flag for Georgia +- chars: ! "\U0001F1EC\U0001F1EB" + codes: 1F1EC 1F1EB + name: Flag for French Guiana +- chars: ! "\U0001F1EC\U0001F1EC" + codes: 1F1EC 1F1EC + name: Flag for Guernsey +- chars: ! "\U0001F1EC\U0001F1ED" + codes: 1F1EC 1F1ED + name: Flag for Ghana +- chars: ! "\U0001F1EC\U0001F1EE" + codes: 1F1EC 1F1EE + name: Flag for Gibraltar +- chars: ! "\U0001F1EC\U0001F1F1" + codes: 1F1EC 1F1F1 + name: Flag for Greenland +- chars: ! "\U0001F1EC\U0001F1F2" + codes: 1F1EC 1F1F2 + name: Flag for Gambia +- chars: ! "\U0001F1EC\U0001F1F3" + codes: 1F1EC 1F1F3 + name: Flag for Guinea +- chars: ! "\U0001F1EC\U0001F1F5" + codes: 1F1EC 1F1F5 + name: Flag for Guadeloupe +- chars: ! "\U0001F1EC\U0001F1F6" + codes: 1F1EC 1F1F6 + name: Flag for Equatorial Guinea +- chars: ! "\U0001F1EC\U0001F1F7" + codes: 1F1EC 1F1F7 + name: Flag for Greece +- chars: ! "\U0001F1EC\U0001F1F8" + codes: 1F1EC 1F1F8 + name: Flag for South Georgia & South Sandwich Islands +- chars: ! "\U0001F1EC\U0001F1F9" + codes: 1F1EC 1F1F9 + name: Flag for Guatemala +- chars: ! "\U0001F1EC\U0001F1FA" + codes: 1F1EC 1F1FA + name: Flag for Guam +- chars: ! "\U0001F1EC\U0001F1FC" + codes: 1F1EC 1F1FC + name: Flag for Guinea-Bissau +- chars: ! "\U0001F1EC\U0001F1FE" + codes: 1F1EC 1F1FE + name: Flag for Guyana +- chars: ! "\U0001F1ED\U0001F1F0" + codes: 1F1ED 1F1F0 + name: Flag for Hong Kong +- chars: ! "\U0001F1ED\U0001F1F2" + codes: 1F1ED 1F1F2 + name: Flag for Heard & McDonald Islands +- chars: ! "\U0001F1ED\U0001F1F3" + codes: 1F1ED 1F1F3 + name: Flag for Honduras +- chars: ! "\U0001F1ED\U0001F1F7" + codes: 1F1ED 1F1F7 + name: Flag for Croatia +- chars: ! "\U0001F1ED\U0001F1F9" + codes: 1F1ED 1F1F9 + name: Flag for Haiti +- chars: ! "\U0001F1ED\U0001F1FA" + codes: 1F1ED 1F1FA + name: Flag for Hungary +- chars: ! "\U0001F1EE\U0001F1E8" + codes: 1F1EE 1F1E8 + name: Flag for Canary Islands +- chars: ! "\U0001F1EE\U0001F1E9" + codes: 1F1EE 1F1E9 + name: Flag for Indonesia +- chars: ! "\U0001F1EE\U0001F1EA" + codes: 1F1EE 1F1EA + name: Flag for Ireland +- chars: ! "\U0001F1EE\U0001F1F1" + codes: 1F1EE 1F1F1 + name: Flag for Israel +- chars: ! "\U0001F1EE\U0001F1F2" + codes: 1F1EE 1F1F2 + name: Flag for Isle of Man +- chars: ! "\U0001F1EE\U0001F1F3" + codes: 1F1EE 1F1F3 + name: Flag for India +- chars: ! "\U0001F1EE\U0001F1F4" + codes: 1F1EE 1F1F4 + name: Flag for British Indian Ocean Territory +- chars: ! "\U0001F1EE\U0001F1F6" + codes: 1F1EE 1F1F6 + name: Flag for Iraq +- chars: ! "\U0001F1EE\U0001F1F7" + codes: 1F1EE 1F1F7 + name: Flag for Iran +- chars: ! "\U0001F1EE\U0001F1F8" + codes: 1F1EE 1F1F8 + name: Flag for Iceland +- chars: ! "\U0001F1EE\U0001F1F9" + codes: 1F1EE 1F1F9 + name: Flag for Italy +- chars: ! "\U0001F1EF\U0001F1EA" + codes: 1F1EF 1F1EA + name: Flag for Jersey +- chars: ! "\U0001F1EF\U0001F1F2" + codes: 1F1EF 1F1F2 + name: Flag for Jamaica +- chars: ! "\U0001F1EF\U0001F1F4" + codes: 1F1EF 1F1F4 + name: Flag for Jordan +- chars: ! "\U0001F1EF\U0001F1F5" + codes: 1F1EF 1F1F5 + name: Flag for Japan +- chars: ! "\U0001F1F0\U0001F1EA" + codes: 1F1F0 1F1EA + name: Flag for Kenya +- chars: ! "\U0001F1F0\U0001F1EC" + codes: 1F1F0 1F1EC + name: Flag for Kyrgyzstan +- chars: ! "\U0001F1F0\U0001F1ED" + codes: 1F1F0 1F1ED + name: Flag for Cambodia +- chars: ! "\U0001F1F0\U0001F1EE" + codes: 1F1F0 1F1EE + name: Flag for Kiribati +- chars: ! "\U0001F1F0\U0001F1F2" + codes: 1F1F0 1F1F2 + name: Flag for Comoros +- chars: ! "\U0001F1F0\U0001F1F3" + codes: 1F1F0 1F1F3 + name: Flag for St. Kitts & Nevis +- chars: ! "\U0001F1F0\U0001F1F5" + codes: 1F1F0 1F1F5 + name: Flag for North Korea +- chars: ! "\U0001F1F0\U0001F1F7" + codes: 1F1F0 1F1F7 + name: Flag for South Korea +- chars: ! "\U0001F1F0\U0001F1FC" + codes: 1F1F0 1F1FC + name: Flag for Kuwait +- chars: ! "\U0001F1F0\U0001F1FE" + codes: 1F1F0 1F1FE + name: Flag for Cayman Islands +- chars: ! "\U0001F1F0\U0001F1FF" + codes: 1F1F0 1F1FF + name: Flag for Kazakhstan +- chars: ! "\U0001F1F1\U0001F1E6" + codes: 1F1F1 1F1E6 + name: Flag for Laos +- chars: ! "\U0001F1F1\U0001F1E7" + codes: 1F1F1 1F1E7 + name: Flag for Lebanon +- chars: ! "\U0001F1F1\U0001F1E8" + codes: 1F1F1 1F1E8 + name: Flag for St. Lucia +- chars: ! "\U0001F1F1\U0001F1EE" + codes: 1F1F1 1F1EE + name: Flag for Liechtenstein +- chars: ! "\U0001F1F1\U0001F1F0" + codes: 1F1F1 1F1F0 + name: Flag for Sri Lanka +- chars: ! "\U0001F1F1\U0001F1F7" + codes: 1F1F1 1F1F7 + name: Flag for Liberia +- chars: ! "\U0001F1F1\U0001F1F8" + codes: 1F1F1 1F1F8 + name: Flag for Lesotho +- chars: ! "\U0001F1F1\U0001F1F9" + codes: 1F1F1 1F1F9 + name: Flag for Lithuania +- chars: ! "\U0001F1F1\U0001F1FA" + codes: 1F1F1 1F1FA + name: Flag for Luxembourg +- chars: ! "\U0001F1F1\U0001F1FB" + codes: 1F1F1 1F1FB + name: Flag for Latvia +- chars: ! "\U0001F1F1\U0001F1FE" + codes: 1F1F1 1F1FE + name: Flag for Libya +- chars: ! "\U0001F1F2\U0001F1E6" + codes: 1F1F2 1F1E6 + name: Flag for Morocco +- chars: ! "\U0001F1F2\U0001F1E8" + codes: 1F1F2 1F1E8 + name: Flag for Monaco +- chars: ! "\U0001F1F2\U0001F1E9" + codes: 1F1F2 1F1E9 + name: Flag for Moldova +- chars: ! "\U0001F1F2\U0001F1EA" + codes: 1F1F2 1F1EA + name: Flag for Montenegro +- chars: ! "\U0001F1F2\U0001F1EB" + codes: 1F1F2 1F1EB + name: Flag for St. Martin +- chars: ! "\U0001F1F2\U0001F1EC" + codes: 1F1F2 1F1EC + name: Flag for Madagascar +- chars: ! "\U0001F1F2\U0001F1ED" + codes: 1F1F2 1F1ED + name: Flag for Marshall Islands +- chars: ! "\U0001F1F2\U0001F1F0" + codes: 1F1F2 1F1F0 + name: Flag for Macedonia +- chars: ! "\U0001F1F2\U0001F1F1" + codes: 1F1F2 1F1F1 + name: Flag for Mali +- chars: ! "\U0001F1F2\U0001F1F2" + codes: 1F1F2 1F1F2 + name: Flag for Myanmar +- chars: ! "\U0001F1F2\U0001F1F3" + codes: 1F1F2 1F1F3 + name: Flag for Mongolia +- chars: ! "\U0001F1F2\U0001F1F4" + codes: 1F1F2 1F1F4 + name: Flag for Macau +- chars: ! "\U0001F1F2\U0001F1F5" + codes: 1F1F2 1F1F5 + name: Flag for Northern Mariana Islands +- chars: ! "\U0001F1F2\U0001F1F6" + codes: 1F1F2 1F1F6 + name: Flag for Martinique +- chars: ! "\U0001F1F2\U0001F1F7" + codes: 1F1F2 1F1F7 + name: Flag for Mauritania +- chars: ! "\U0001F1F2\U0001F1F8" + codes: 1F1F2 1F1F8 + name: Flag for Montserrat +- chars: ! "\U0001F1F2\U0001F1F9" + codes: 1F1F2 1F1F9 + name: Flag for Malta +- chars: ! "\U0001F1F2\U0001F1FA" + codes: 1F1F2 1F1FA + name: Flag for Mauritius +- chars: ! "\U0001F1F2\U0001F1FB" + codes: 1F1F2 1F1FB + name: Flag for Maldives +- chars: ! "\U0001F1F2\U0001F1FC" + codes: 1F1F2 1F1FC + name: Flag for Malawi +- chars: ! "\U0001F1F2\U0001F1FD" + codes: 1F1F2 1F1FD + name: Flag for Mexico +- chars: ! "\U0001F1F2\U0001F1FE" + codes: 1F1F2 1F1FE + name: Flag for Malaysia +- chars: ! "\U0001F1F2\U0001F1FF" + codes: 1F1F2 1F1FF + name: Flag for Mozambique +- chars: ! "\U0001F1F3\U0001F1E6" + codes: 1F1F3 1F1E6 + name: Flag for Namibia +- chars: ! "\U0001F1F3\U0001F1E8" + codes: 1F1F3 1F1E8 + name: Flag for New Caledonia +- chars: ! "\U0001F1F3\U0001F1EA" + codes: 1F1F3 1F1EA + name: Flag for Niger +- chars: ! "\U0001F1F3\U0001F1EB" + codes: 1F1F3 1F1EB + name: Flag for Norfolk Island +- chars: ! "\U0001F1F3\U0001F1EC" + codes: 1F1F3 1F1EC + name: Flag for Nigeria +- chars: ! "\U0001F1F3\U0001F1EE" + codes: 1F1F3 1F1EE + name: Flag for Nicaragua +- chars: ! "\U0001F1F3\U0001F1F1" + codes: 1F1F3 1F1F1 + name: Flag for Netherlands +- chars: ! "\U0001F1F3\U0001F1F4" + codes: 1F1F3 1F1F4 + name: Flag for Norway +- chars: ! "\U0001F1F3\U0001F1F5" + codes: 1F1F3 1F1F5 + name: Flag for Nepal +- chars: ! "\U0001F1F3\U0001F1F7" + codes: 1F1F3 1F1F7 + name: Flag for Nauru +- chars: ! "\U0001F1F3\U0001F1FA" + codes: 1F1F3 1F1FA + name: Flag for Niue +- chars: ! "\U0001F1F3\U0001F1FF" + codes: 1F1F3 1F1FF + name: Flag for New Zealand +- chars: ! "\U0001F1F4\U0001F1F2" + codes: 1F1F4 1F1F2 + name: Flag for Oman +- chars: ! "\U0001F1F5\U0001F1E6" + codes: 1F1F5 1F1E6 + name: Flag for Panama +- chars: ! "\U0001F1F5\U0001F1EA" + codes: 1F1F5 1F1EA + name: Flag for Peru +- chars: ! "\U0001F1F5\U0001F1EB" + codes: 1F1F5 1F1EB + name: Flag for French Polynesia +- chars: ! "\U0001F1F5\U0001F1EC" + codes: 1F1F5 1F1EC + name: Flag for Papua New Guinea +- chars: ! "\U0001F1F5\U0001F1ED" + codes: 1F1F5 1F1ED + name: Flag for Philippines +- chars: ! "\U0001F1F5\U0001F1F0" + codes: 1F1F5 1F1F0 + name: Flag for Pakistan +- chars: ! "\U0001F1F5\U0001F1F1" + codes: 1F1F5 1F1F1 + name: Flag for Poland +- chars: ! "\U0001F1F5\U0001F1F2" + codes: 1F1F5 1F1F2 + name: Flag for St. Pierre & Miquelon +- chars: ! "\U0001F1F5\U0001F1F3" + codes: 1F1F5 1F1F3 + name: Flag for Pitcairn Islands +- chars: ! "\U0001F1F5\U0001F1F7" + codes: 1F1F5 1F1F7 + name: Flag for Puerto Rico +- chars: ! "\U0001F1F5\U0001F1F8" + codes: 1F1F5 1F1F8 + name: Flag for Palestinian Territories +- chars: ! "\U0001F1F5\U0001F1F9" + codes: 1F1F5 1F1F9 + name: Flag for Portugal +- chars: ! "\U0001F1F5\U0001F1FC" + codes: 1F1F5 1F1FC + name: Flag for Palau +- chars: ! "\U0001F1F5\U0001F1FE" + codes: 1F1F5 1F1FE + name: Flag for Paraguay +- chars: ! "\U0001F1F6\U0001F1E6" + codes: 1F1F6 1F1E6 + name: Flag for Qatar +- chars: ! "\U0001F1F7\U0001F1EA" + codes: 1F1F7 1F1EA + name: Flag for Réunion +- chars: ! "\U0001F1F7\U0001F1F4" + codes: 1F1F7 1F1F4 + name: Flag for Romania +- chars: ! "\U0001F1F7\U0001F1F8" + codes: 1F1F7 1F1F8 + name: Flag for Serbia +- chars: ! "\U0001F1F7\U0001F1FA" + codes: 1F1F7 1F1FA + name: Flag for Russia +- chars: ! "\U0001F1F7\U0001F1FC" + codes: 1F1F7 1F1FC + name: Flag for Rwanda +- chars: ! "\U0001F1F8\U0001F1E6" + codes: 1F1F8 1F1E6 + name: Flag for Saudi Arabia +- chars: ! "\U0001F1F8\U0001F1E7" + codes: 1F1F8 1F1E7 + name: Flag for Solomon Islands +- chars: ! "\U0001F1F8\U0001F1E8" + codes: 1F1F8 1F1E8 + name: Flag for Seychelles +- chars: ! "\U0001F1F8\U0001F1E9" + codes: 1F1F8 1F1E9 + name: Flag for Sudan +- chars: ! "\U0001F1F8\U0001F1EA" + codes: 1F1F8 1F1EA + name: Flag for Sweden +- chars: ! "\U0001F1F8\U0001F1EC" + codes: 1F1F8 1F1EC + name: Flag for Singapore +- chars: ! "\U0001F1F8\U0001F1ED" + codes: 1F1F8 1F1ED + name: Flag for St. Helena +- chars: ! "\U0001F1F8\U0001F1EE" + codes: 1F1F8 1F1EE + name: Flag for Slovenia +- chars: ! "\U0001F1F8\U0001F1EF" + codes: 1F1F8 1F1EF + name: Flag for Svalbard & Jan Mayen +- chars: ! "\U0001F1F8\U0001F1F0" + codes: 1F1F8 1F1F0 + name: Flag for Slovakia +- chars: ! "\U0001F1F8\U0001F1F1" + codes: 1F1F8 1F1F1 + name: Flag for Sierra Leone +- chars: ! "\U0001F1F8\U0001F1F2" + codes: 1F1F8 1F1F2 + name: Flag for San Marino +- chars: ! "\U0001F1F8\U0001F1F3" + codes: 1F1F8 1F1F3 + name: Flag for Senegal +- chars: ! "\U0001F1F8\U0001F1F4" + codes: 1F1F8 1F1F4 + name: Flag for Somalia +- chars: ! "\U0001F1F8\U0001F1F7" + codes: 1F1F8 1F1F7 + name: Flag for Suriname +- chars: ! "\U0001F1F8\U0001F1F8" + codes: 1F1F8 1F1F8 + name: Flag for South Sudan +- chars: ! "\U0001F1F8\U0001F1F9" + codes: 1F1F8 1F1F9 + name: Flag for São Tomé & Príncipe +- chars: ! "\U0001F1F8\U0001F1FB" + codes: 1F1F8 1F1FB + name: Flag for El Salvador +- chars: ! "\U0001F1F8\U0001F1FD" + codes: 1F1F8 1F1FD + name: Flag for Sint Maarten +- chars: ! "\U0001F1F8\U0001F1FE" + codes: 1F1F8 1F1FE + name: Flag for Syria +- chars: ! "\U0001F1F8\U0001F1FF" + codes: 1F1F8 1F1FF + name: Flag for Swaziland +- chars: ! "\U0001F1F9\U0001F1E6" + codes: 1F1F9 1F1E6 + name: Flag for Tristan da Cunha +- chars: ! "\U0001F1F9\U0001F1E8" + codes: 1F1F9 1F1E8 + name: Flag for Turks & Caicos Islands +- chars: ! "\U0001F1F9\U0001F1E9" + codes: 1F1F9 1F1E9 + name: Flag for Chad +- chars: ! "\U0001F1F9\U0001F1EB" + codes: 1F1F9 1F1EB + name: Flag for French Southern Territories +- chars: ! "\U0001F1F9\U0001F1EC" + codes: 1F1F9 1F1EC + name: Flag for Togo +- chars: ! "\U0001F1F9\U0001F1ED" + codes: 1F1F9 1F1ED + name: Flag for Thailand +- chars: ! "\U0001F1F9\U0001F1EF" + codes: 1F1F9 1F1EF + name: Flag for Tajikistan +- chars: ! "\U0001F1F9\U0001F1F0" + codes: 1F1F9 1F1F0 + name: Flag for Tokelau +- chars: ! "\U0001F1F9\U0001F1F1" + codes: 1F1F9 1F1F1 + name: Flag for Timor-Leste +- chars: ! "\U0001F1F9\U0001F1F2" + codes: 1F1F9 1F1F2 + name: Flag for Turkmenistan +- chars: ! "\U0001F1F9\U0001F1F3" + codes: 1F1F9 1F1F3 + name: Flag for Tunisia +- chars: ! "\U0001F1F9\U0001F1F4" + codes: 1F1F9 1F1F4 + name: Flag for Tonga +- chars: ! "\U0001F1F9\U0001F1F7" + codes: 1F1F9 1F1F7 + name: Flag for Turkey +- chars: ! "\U0001F1F9\U0001F1F9" + codes: 1F1F9 1F1F9 + name: Flag for Trinidad & Tobago +- chars: ! "\U0001F1F9\U0001F1FB" + codes: 1F1F9 1F1FB + name: Flag for Tuvalu +- chars: ! "\U0001F1F9\U0001F1FC" + codes: 1F1F9 1F1FC + name: Flag for Taiwan +- chars: ! "\U0001F1F9\U0001F1FF" + codes: 1F1F9 1F1FF + name: Flag for Tanzania +- chars: ! "\U0001F1FA\U0001F1E6" + codes: 1F1FA 1F1E6 + name: Flag for Ukraine +- chars: ! "\U0001F1FA\U0001F1EC" + codes: 1F1FA 1F1EC + name: Flag for Uganda +- chars: ! "\U0001F1FA\U0001F1F2" + codes: 1F1FA 1F1F2 + name: Flag for U.S. Outlying Islands +- chars: ! "\U0001F1FA\U0001F1F8" + codes: 1F1FA 1F1F8 + name: Flag for United States +- chars: ! "\U0001F1FA\U0001F1FE" + codes: 1F1FA 1F1FE + name: Flag for Uruguay +- chars: ! "\U0001F1FA\U0001F1FF" + codes: 1F1FA 1F1FF + name: Flag for Uzbekistan +- chars: ! "\U0001F1FB\U0001F1E6" + codes: 1F1FB 1F1E6 + name: Flag for Vatican City +- chars: ! "\U0001F1FB\U0001F1E8" + codes: 1F1FB 1F1E8 + name: Flag for St. Vincent & Grenadines +- chars: ! "\U0001F1FB\U0001F1EA" + codes: 1F1FB 1F1EA + name: Flag for Venezuela +- chars: ! "\U0001F1FB\U0001F1EC" + codes: 1F1FB 1F1EC + name: Flag for British Virgin Islands +- chars: ! "\U0001F1FB\U0001F1EE" + codes: 1F1FB 1F1EE + name: Flag for U.S. Virgin Islands +- chars: ! "\U0001F1FB\U0001F1F3" + codes: 1F1FB 1F1F3 + name: Flag for Vietnam +- chars: ! "\U0001F1FB\U0001F1FA" + codes: 1F1FB 1F1FA + name: Flag for Vanuatu +- chars: ! "\U0001F1FC\U0001F1EB" + codes: 1F1FC 1F1EB + name: Flag for Wallis & Futuna +- chars: ! "\U0001F1FC\U0001F1F8" + codes: 1F1FC 1F1F8 + name: Flag for Samoa +- chars: ! "\U0001F1FD\U0001F1F0" + codes: 1F1FD 1F1F0 + name: Flag for Kosovo +- chars: ! "\U0001F1FE\U0001F1EA" + codes: 1F1FE 1F1EA + name: Flag for Yemen +- chars: ! "\U0001F1FE\U0001F1F9" + codes: 1F1FE 1F1F9 + name: Flag for Mayotte +- chars: ! "\U0001F1FF\U0001F1E6" + codes: 1F1FF 1F1E6 + name: Flag for South Africa +- chars: ! "\U0001F1FF\U0001F1F2" + codes: 1F1FF 1F1F2 + name: Flag for Zambia +- chars: ! "\U0001F1FF\U0001F1FC" + codes: 1F1FF 1F1FC + name: Flag for Zimbabwe diff --git a/test/emitter-examples/emptydoc.yaml b/test/emitter-examples/emptydoc.yaml new file mode 100644 index 0000000..a845151 --- /dev/null +++ b/test/emitter-examples/emptydoc.yaml @@ -0,0 +1,2 @@ +--- +--- diff --git a/test/emitter-examples/emptykey.yaml b/test/emitter-examples/emptykey.yaml new file mode 100644 index 0000000..7c784ca --- /dev/null +++ b/test/emitter-examples/emptykey.yaml @@ -0,0 +1 @@ +- [ YAML : separate ] diff --git a/test/emitter-examples/emptystream.yaml b/test/emitter-examples/emptystream.yaml new file mode 100644 index 0000000..e69de29 diff --git a/test/emitter-examples/flow.yaml b/test/emitter-examples/flow.yaml new file mode 100644 index 0000000..95f2303 --- /dev/null +++ b/test/emitter-examples/flow.yaml @@ -0,0 +1,5 @@ +a: + b: + - c + - d + - e diff --git a/test/emitter-examples/flow1.yaml b/test/emitter-examples/flow1.yaml new file mode 100644 index 0000000..0f591db --- /dev/null +++ b/test/emitter-examples/flow1.yaml @@ -0,0 +1,5 @@ +a: + b: [ c, + d, + e ] + diff --git a/test/emitter-examples/flow2.yaml b/test/emitter-examples/flow2.yaml new file mode 100644 index 0000000..61f52d2 --- /dev/null +++ b/test/emitter-examples/flow2.yaml @@ -0,0 +1,8 @@ +a: + b: [ c, + d, + e, [ f, g, h, i, j + k, l, m, n, o + ] + ] + diff --git a/test/emitter-examples/fold.yaml b/test/emitter-examples/fold.yaml new file mode 100644 index 0000000..9252180 --- /dev/null +++ b/test/emitter-examples/fold.yaml @@ -0,0 +1,25 @@ +fold: > + 1 2 + 3 + 4 +fold2: > + 1 2 + 3 # comment + 4 +fold3: > + 1 2 + 3 + 4 +fold4: > + 1 2 + + 3 + 4 +fold5: > + 1 + + 2 +fold6: > + 1 2 + 3 + 4 diff --git a/test/emitter-examples/fold2.yaml b/test/emitter-examples/fold2.yaml new file mode 100644 index 0000000..eb186d6 --- /dev/null +++ b/test/emitter-examples/fold2.yaml @@ -0,0 +1,5 @@ +fold: > + 1 2 + 3 4 + 5 + 6 diff --git a/test/emitter-examples/fold3.yaml b/test/emitter-examples/fold3.yaml new file mode 100644 index 0000000..0fc4ca9 --- /dev/null +++ b/test/emitter-examples/fold3.yaml @@ -0,0 +1,5 @@ +fold4: > + 1 2 + + 3 + 4 diff --git a/test/emitter-examples/fold4.yaml b/test/emitter-examples/fold4.yaml new file mode 100644 index 0000000..7140e98 --- /dev/null +++ b/test/emitter-examples/fold4.yaml @@ -0,0 +1,4 @@ +fold: > + 1 + + 2 diff --git a/test/emitter-examples/fold5.yaml b/test/emitter-examples/fold5.yaml new file mode 100644 index 0000000..9ef791b --- /dev/null +++ b/test/emitter-examples/fold5.yaml @@ -0,0 +1,4 @@ +fold3: > + 1 2 + 3 + 4 diff --git a/test/emitter-examples/folded.yaml b/test/emitter-examples/folded.yaml new file mode 100644 index 0000000..ae24857 --- /dev/null +++ b/test/emitter-examples/folded.yaml @@ -0,0 +1,33 @@ +clip: > + This is a single clipped line +keep: >+ + This is a single kept line +strip: >- + This is a single stripped line +clip2: > + These are two + clipped lines +keep2: >+ + These are two + kept lines +strip2: >- + These are two + striped lines +clip3: > + These are two + clipped lines with trailing line breaks + + + +keep3: >+ + These are two + kept lines with trailing line breaks + + + +strip3: >- + These are two + striped lines with trailing line breaks + + + diff --git a/test/emitter-examples/folded2.yaml b/test/emitter-examples/folded2.yaml new file mode 100644 index 0000000..eda4b49 --- /dev/null +++ b/test/emitter-examples/folded2.yaml @@ -0,0 +1,5 @@ +"folded +to a space, + +to a line feed, or \ + \ non-content" diff --git a/test/emitter-examples/folding.yaml b/test/emitter-examples/folding.yaml new file mode 100644 index 0000000..0896cc6 --- /dev/null +++ b/test/emitter-examples/folding.yaml @@ -0,0 +1,6 @@ +> + foo + + bar + + baz diff --git a/test/emitter-examples/global-tag.yaml b/test/emitter-examples/global-tag.yaml new file mode 100644 index 0000000..1180757 --- /dev/null +++ b/test/emitter-examples/global-tag.yaml @@ -0,0 +1,14 @@ +%TAG ! tag:clarkevans.com,2002: +--- !shape + # Use the ! handle for presenting + # tag:clarkevans.com,2002:circle +- !circle + center: &ORIGIN {x: 73, y: 129} + radius: 7 +- !line + start: *ORIGIN + finish: { x: 89, y: 102 } +- !label + start: *ORIGIN + color: 0xFFEEBB + text: Pretty vector drawing. diff --git a/test/emitter-examples/invoice.yaml b/test/emitter-examples/invoice.yaml new file mode 100644 index 0000000..434f080 --- /dev/null +++ b/test/emitter-examples/invoice.yaml @@ -0,0 +1,9 @@ +invoice: 34843 +date : !!str 2001-01-23 +bill-to: &id001 + given : Chris + family : Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 diff --git a/test/emitter-examples/json.yaml b/test/emitter-examples/json.yaml new file mode 100644 index 0000000..7822ddc --- /dev/null +++ b/test/emitter-examples/json.yaml @@ -0,0 +1 @@ +{"key": ["value", 3]} diff --git a/test/emitter-examples/keyflow.yaml b/test/emitter-examples/keyflow.yaml new file mode 100644 index 0000000..074e0fc --- /dev/null +++ b/test/emitter-examples/keyflow.yaml @@ -0,0 +1,5 @@ +{ + a: b, + c: { d: e }, + { f: g }: h, +} diff --git a/test/emitter-examples/keykey.yaml b/test/emitter-examples/keykey.yaml new file mode 100644 index 0000000..00a179c --- /dev/null +++ b/test/emitter-examples/keykey.yaml @@ -0,0 +1,3 @@ +top1: + key1 : value1 +"top2": value2 diff --git a/test/emitter-examples/keykey2.yaml b/test/emitter-examples/keykey2.yaml new file mode 100644 index 0000000..e5a5af9 --- /dev/null +++ b/test/emitter-examples/keykey2.yaml @@ -0,0 +1 @@ +{ }: value diff --git a/test/emitter-examples/line.yaml b/test/emitter-examples/line.yaml new file mode 100644 index 0000000..a1230a8 --- /dev/null +++ b/test/emitter-examples/line.yaml @@ -0,0 +1,8 @@ +text: | + a + + b + + c + + d diff --git a/test/emitter-examples/literal.yaml b/test/emitter-examples/literal.yaml new file mode 100644 index 0000000..018bcda --- /dev/null +++ b/test/emitter-examples/literal.yaml @@ -0,0 +1,33 @@ +clip: | + This is a single clipped line +keep: |+ + This is a single kept line +strip: |- + This is a single stripped line +clip2: | + These are two + clipped lines +keep2: |+ + These are two + kept lines +strip2: |- + These are two + striped lines +clip3: | + These are two + clipped lines with trailing line breaks + + + +keep3: |+ + These are two + kept lines with trailing line breaks + + + +strip3: |- + These are two + striped lines with trailing line breaks + + + diff --git a/test/emitter-examples/literal1.yaml b/test/emitter-examples/literal1.yaml new file mode 100644 index 0000000..f2d2e90 --- /dev/null +++ b/test/emitter-examples/literal1.yaml @@ -0,0 +1,3 @@ +a: | + literal +... diff --git a/test/emitter-examples/literal2.yaml b/test/emitter-examples/literal2.yaml new file mode 100644 index 0000000..9d537cb --- /dev/null +++ b/test/emitter-examples/literal2.yaml @@ -0,0 +1,9 @@ +| + + + literal + + + text + + # Comment diff --git a/test/emitter-examples/literal3.yaml b/test/emitter-examples/literal3.yaml new file mode 100644 index 0000000..5a3259b --- /dev/null +++ b/test/emitter-examples/literal3.yaml @@ -0,0 +1,5 @@ +--- | +foo +bar +... +foo diff --git a/test/emitter-examples/literal4.yaml b/test/emitter-examples/literal4.yaml new file mode 100644 index 0000000..370ecc3 --- /dev/null +++ b/test/emitter-examples/literal4.yaml @@ -0,0 +1,6 @@ +keep3: |+ + These are two + kept lines with trailing line breaks + + + diff --git a/test/emitter-examples/mapping.yaml b/test/emitter-examples/mapping.yaml new file mode 100644 index 0000000..53d2567 --- /dev/null +++ b/test/emitter-examples/mapping.yaml @@ -0,0 +1,2 @@ +key: value +other-key: other-value diff --git a/test/emitter-examples/mergekeyspec.yaml b/test/emitter-examples/mergekeyspec.yaml new file mode 100644 index 0000000..ee4a48f --- /dev/null +++ b/test/emitter-examples/mergekeyspec.yaml @@ -0,0 +1,27 @@ +--- +- &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 diff --git a/test/emitter-examples/multi-document.yaml b/test/emitter-examples/multi-document.yaml new file mode 100644 index 0000000..2fea5d0 --- /dev/null +++ b/test/emitter-examples/multi-document.yaml @@ -0,0 +1,8 @@ +%YAML 1.1 +--- +First +... +%YAML 1.2 +--- +Second +... diff --git a/test/emitter-examples/multiline-quoted-key.yaml b/test/emitter-examples/multiline-quoted-key.yaml new file mode 100644 index 0000000..577642f --- /dev/null +++ b/test/emitter-examples/multiline-quoted-key.yaml @@ -0,0 +1,2 @@ +{ "foo + bar" : 20 } diff --git a/test/emitter-examples/multiline-simple-key.yaml b/test/emitter-examples/multiline-simple-key.yaml new file mode 100644 index 0000000..c608157 --- /dev/null +++ b/test/emitter-examples/multiline-simple-key.yaml @@ -0,0 +1,2 @@ +{ foo + bar : 20 } diff --git a/test/emitter-examples/nodeprop.yaml b/test/emitter-examples/nodeprop.yaml new file mode 100644 index 0000000..66d75f3 --- /dev/null +++ b/test/emitter-examples/nodeprop.yaml @@ -0,0 +1,3 @@ +!!str &a1 "foo": + !!str bar +&a2 baz : *a1 diff --git a/test/emitter-examples/nodeprop2.yaml b/test/emitter-examples/nodeprop2.yaml new file mode 100644 index 0000000..32dd542 --- /dev/null +++ b/test/emitter-examples/nodeprop2.yaml @@ -0,0 +1,3 @@ +"foo": + bar +&a2 baz : fuzz diff --git a/test/emitter-examples/numbers-flow.yaml b/test/emitter-examples/numbers-flow.yaml new file mode 100644 index 0000000..dc06e9e --- /dev/null +++ b/test/emitter-examples/numbers-flow.yaml @@ -0,0 +1,4 @@ +- 100 +- 12.5 +- -130 +- 1.3e9 diff --git a/test/emitter-examples/numbers.yaml b/test/emitter-examples/numbers.yaml new file mode 100644 index 0000000..45d2bf0 --- /dev/null +++ b/test/emitter-examples/numbers.yaml @@ -0,0 +1 @@ +[100, 12.5, -130, 1.3e+9] diff --git a/test/emitter-examples/plainlines.yaml b/test/emitter-examples/plainlines.yaml new file mode 100644 index 0000000..0499250 --- /dev/null +++ b/test/emitter-examples/plainlines.yaml @@ -0,0 +1,4 @@ +1st non-empty + + 2nd non-empty + 3rd non-empty diff --git a/test/emitter-examples/plainscalar.yaml b/test/emitter-examples/plainscalar.yaml new file mode 100644 index 0000000..a7b828f --- /dev/null +++ b/test/emitter-examples/plainscalar.yaml @@ -0,0 +1,11 @@ +- plain +- plain with spaces +- plain with + breaks and stuff +- plain which should break at some point since it is somewhat longer than usual. nice weather eh... +- plain with breaks + + and + + gaps +- various two space stuff diff --git a/test/emitter-examples/quoted.yaml b/test/emitter-examples/quoted.yaml new file mode 100644 index 0000000..aed6e4b --- /dev/null +++ b/test/emitter-examples/quoted.yaml @@ -0,0 +1,8 @@ +--- +" + foo + + bar + + baz +" diff --git a/test/emitter-examples/quotedbackslash.yaml b/test/emitter-examples/quotedbackslash.yaml new file mode 100644 index 0000000..9ea0d05 --- /dev/null +++ b/test/emitter-examples/quotedbackslash.yaml @@ -0,0 +1,4 @@ +"\ + 123\ + 456\ + 789" diff --git a/test/emitter-examples/scalar-multiline.yaml b/test/emitter-examples/scalar-multiline.yaml new file mode 100644 index 0000000..c40c86c --- /dev/null +++ b/test/emitter-examples/scalar-multiline.yaml @@ -0,0 +1,36 @@ +comment: + Deliver here, but if not + possible deliver there. + + + Tatta! + + + +comment-2: + " Deliver here, but if not + possible deliver there. + + + Tatta! " + +comment-3: + ' Deliver here, but if not + possible deliver there. + + + Tatta! ' + +comment-4: + Deliver here, but if not + possible deliver there. + + + Tatta! + + +comment-5: + "" + +comment-6: " + " diff --git a/test/emitter-examples/scalar-singlequoted.yaml b/test/emitter-examples/scalar-singlequoted.yaml new file mode 100644 index 0000000..67ddb0c --- /dev/null +++ b/test/emitter-examples/scalar-singlequoted.yaml @@ -0,0 +1,14 @@ +simple: 'simple' +multiline: 'multi line + singled quoted scalar' +multiline2: 'multi line + singled quoted scalar + + with a newline ' +comment-3: + ' Deliver here, but if not + possible deliver there. + + + Tatta! ' + diff --git a/test/emitter-examples/scalar-space.yaml b/test/emitter-examples/scalar-space.yaml new file mode 100644 index 0000000..868f393 --- /dev/null +++ b/test/emitter-examples/scalar-space.yaml @@ -0,0 +1,17 @@ +z: " + " +aa: foo + bar +a: " + + + " +b: "" +c: + + b +d: " + " +e: " + + " diff --git a/test/emitter-examples/scalar-space1.yaml b/test/emitter-examples/scalar-space1.yaml new file mode 100644 index 0000000..5c4a085 --- /dev/null +++ b/test/emitter-examples/scalar-space1.yaml @@ -0,0 +1,6 @@ +0: " + " +a: " + + + " diff --git a/test/emitter-examples/scalars.yaml b/test/emitter-examples/scalars.yaml new file mode 100644 index 0000000..2f17998 --- /dev/null +++ b/test/emitter-examples/scalars.yaml @@ -0,0 +1,24 @@ +--- +plain-simple : plain-simple +plain: This is a plain scalar # alright +key with spaces-1 : scalar with spaces too +key with spaces-2: scalar with spaces too 2 +key with spaces-3 : scalar with spaces too 3# comment +key with spaces-4 : scalar with spaces too 4 # comment + +single-quoted: 'This is a single quoted scalar' +single-quoted-escaped: 'This is a single quoted scalar with ''escapes''' +double-quoted: "This is a double quoted scalar" +double-quoted-escaped: "This is a double quoted\tscalar\nwith escapes" +double-quoted-escaped2: "This is a double quoted\tscalar\nwith \x20 escapes" +literal: | + This is a literal scalar # comments included +literal2: | + This is a literal scalar 2 + More than one line + Indentation + Indeed +folded: > + This is a folded + scalar +... diff --git a/test/emitter-examples/scalars2.yaml b/test/emitter-examples/scalars2.yaml new file mode 100644 index 0000000..8f7fd0c --- /dev/null +++ b/test/emitter-examples/scalars2.yaml @@ -0,0 +1,24 @@ +key spaces: | + Normal indent + One more indent + Back to normal +folded : > + Folding is easy to do + Indenting too + Roses are blue +foo: bar +another-fold: >- + fold + 1 + 2 + 3 +yet-another-fold: >+ + another-fold + 11 + 12 + 13 +more-fold: > + more-fold + 21 + 22 + 23 diff --git a/test/emitter-examples/scanner-c-1.yaml b/test/emitter-examples/scanner-c-1.yaml new file mode 100644 index 0000000..0f1c2df --- /dev/null +++ b/test/emitter-examples/scanner-c-1.yaml @@ -0,0 +1,4 @@ +%YAML 1.1 +%TAG ! !foo +%TAG !yaml! tag:yaml.org,2002: +--- diff --git a/test/emitter-examples/scanner-c-10.yaml b/test/emitter-examples/scanner-c-10.yaml new file mode 100644 index 0000000..c4b3415 --- /dev/null +++ b/test/emitter-examples/scanner-c-10.yaml @@ -0,0 +1,18 @@ +{ + a simple key: a value, # Note that the KEY token is produced. + ? a complex key: another value, +} +# STREAM_START FYTT_STREAM_START +# FLOW_MAPPING_START FYTT_FLOW_MAPPING_START +# KEY FYTT_KEY +# SCALAR value='a simple key' style=PLAIN FYTT_SCALAR value='a simple key' style=PLAIN +# VALUE FYTT_VALUE +# SCALAR value='a value' style=PLAIN FYTT_SCALAR value='a value' style=PLAIN +# FLOW_ENTRY FYTT_FLOW_ENTRY +# KEY FYTT_KEY +# SCALAR value='a complex key' style=PLAIN FYTT_SCALAR value='a complex key' style=PLAIN +# VALUE FYTT_VALUE +# SCALAR value='another value' style=PLAIN FYTT_SCALAR value='another value' style=PLAIN +# FLOW_ENTRY FYTT_FLOW_ENTRY +# FLOW_MAPPING_END FYTT_FLOW_MAPPING_END +# STREAM_END FYTT_STREAM_END diff --git a/test/emitter-examples/scanner-c-11.yaml b/test/emitter-examples/scanner-c-11.yaml new file mode 100644 index 0000000..1e70b94 --- /dev/null +++ b/test/emitter-examples/scanner-c-11.yaml @@ -0,0 +1,34 @@ +- item 1 +- item 2 +- + - item 3.1 + - item 3.2 +- + key 1: value 1 + key 2: value 2 +# STREAM_START +# BLOCK_SEQUENCE_START +# BLOCK_ENTRY +# SCALAR value='item 1' style=PLAIN +# BLOCK_ENTRY +# SCALAR value='item 2' style=PLAIN +# BLOCK_ENTRY +# BLOCK_SEQUENCE_START +# BLOCK_ENTRY +# SCALAR value='item 3.1' style=PLAIN +# BLOCK_ENTRY +# SCALAR value='item 3.2' style=PLAIN +# BLOCK_END +# BLOCK_ENTRY +# BLOCK_MAPPING_START +# KEY +# SCALAR value='key 1' style=PLAIN +# VALUE +# SCALAR value='value 1' style=PLAIN +# KEY +# SCALAR value='key 2' style=PLAIN +# VALUE +# SCALAR value='value 2' style=PLAIN +# BLOCK_END +# BLOCK_END +# STREAM_END diff --git a/test/emitter-examples/scanner-c-12.yaml b/test/emitter-examples/scanner-c-12.yaml new file mode 100644 index 0000000..c00f23f --- /dev/null +++ b/test/emitter-examples/scanner-c-12.yaml @@ -0,0 +1,42 @@ +a simple key: a value # The KEY token is produced here. +? a complex key +: another value +a mapping: + key 1: value 1 + key 2: value 2 +a sequence: + - item 1 + - item 2 +# STREAM-START(utf-8) +# BLOCK-MAPPING-START +# KEY +# SCALAR("a simple key",plain) +# VALUE +# SCALAR("a value",plain) +# KEY +# SCALAR("a complex key",plain) +# VALUE +# SCALAR("another value",plain) +# KEY +# SCALAR("a mapping",plain) +# BLOCK-MAPPING-START +# KEY +# SCALAR("key 1",plain) +# VALUE +# SCALAR("value 1",plain) +# KEY +# SCALAR("key 2",plain) +# VALUE +# SCALAR("value 2",plain) +# BLOCK-END +# KEY +# SCALAR("a sequence",plain) +# VALUE +# BLOCK-SEQUENCE-START +# BLOCK-ENTRY +# SCALAR("item 1",plain) +# BLOCK-ENTRY +# SCALAR("item 2",plain) +# BLOCK-END +# BLOCK-END +# STREAM-END diff --git a/test/emitter-examples/scanner-c-13.yaml b/test/emitter-examples/scanner-c-13.yaml new file mode 100644 index 0000000..4107762 --- /dev/null +++ b/test/emitter-examples/scanner-c-13.yaml @@ -0,0 +1,13 @@ +key: +- item 1 # BLOCK-SEQUENCE-START is NOT produced here. +- item 2 +# STREAM-START(utf-8) +# BLOCK-MAPPING-START +# KEY +# SCALAR("key",plain) +# VALUE +# BLOCK-ENTRY +# SCALAR("item 1",plain) +# BLOCK-ENTRY +# SCALAR("item 2",plain) +# BLOCK-END diff --git a/test/emitter-examples/scanner-c-2.yaml b/test/emitter-examples/scanner-c-2.yaml new file mode 100644 index 0000000..91da2a7 --- /dev/null +++ b/test/emitter-examples/scanner-c-2.yaml @@ -0,0 +1,2 @@ +--- +... diff --git a/test/emitter-examples/scanner-c-3.yaml b/test/emitter-examples/scanner-c-3.yaml new file mode 100644 index 0000000..ee53cc5 --- /dev/null +++ b/test/emitter-examples/scanner-c-3.yaml @@ -0,0 +1 @@ +'a scalar' diff --git a/test/emitter-examples/scanner-c-4.yaml b/test/emitter-examples/scanner-c-4.yaml new file mode 100644 index 0000000..dbfa5a7 --- /dev/null +++ b/test/emitter-examples/scanner-c-4.yaml @@ -0,0 +1,3 @@ +--- +'a scalar' +... diff --git a/test/emitter-examples/scanner-c-5.yaml b/test/emitter-examples/scanner-c-5.yaml new file mode 100644 index 0000000..76df81e --- /dev/null +++ b/test/emitter-examples/scanner-c-5.yaml @@ -0,0 +1,5 @@ +'a scalar' +--- +'another scalar' +--- +'yet another scalar' diff --git a/test/emitter-examples/scanner-c-6.yaml b/test/emitter-examples/scanner-c-6.yaml new file mode 100644 index 0000000..1d4cdd8 --- /dev/null +++ b/test/emitter-examples/scanner-c-6.yaml @@ -0,0 +1 @@ +&A [ *A ] diff --git a/test/emitter-examples/scanner-c-7.yaml b/test/emitter-examples/scanner-c-7.yaml new file mode 100644 index 0000000..2d75792 --- /dev/null +++ b/test/emitter-examples/scanner-c-7.yaml @@ -0,0 +1 @@ +!!float "3.14" # A good approximation. diff --git a/test/emitter-examples/scanner-c-8-2.yaml b/test/emitter-examples/scanner-c-8-2.yaml new file mode 100644 index 0000000..64a248c --- /dev/null +++ b/test/emitter-examples/scanner-c-8-2.yaml @@ -0,0 +1,28 @@ +--- # Implicit empty plain scalars do not produce tokens. +--- a plain scalar +--- 'a single-quoted scalar' +--- "a double-quoted scalar" +--- |- + a literal scalar (|-) + + test + + +--- >- + a folded (>-) + scalar + + test + + + +--- | + a literal scalar (|) +--- > + a folded (>) + scalar +--- |+ + a literal scalar (|+) +--- >+ + a folded (>+) + scalar diff --git a/test/emitter-examples/scanner-c-8.yaml b/test/emitter-examples/scanner-c-8.yaml new file mode 100644 index 0000000..4176f15 --- /dev/null +++ b/test/emitter-examples/scanner-c-8.yaml @@ -0,0 +1,9 @@ +--- # Implicit empty plain scalars do not produce tokens. +--- a plain scalar +--- 'a single-quoted scalar' +--- "a double-quoted scalar" +--- |- + a literal scalar +--- >- + a folded + scalar diff --git a/test/emitter-examples/scanner-c-9.yaml b/test/emitter-examples/scanner-c-9.yaml new file mode 100644 index 0000000..cb6d8ef --- /dev/null +++ b/test/emitter-examples/scanner-c-9.yaml @@ -0,0 +1 @@ +[item 1, item 2, item 3] diff --git a/test/emitter-examples/seq.yaml b/test/emitter-examples/seq.yaml new file mode 100644 index 0000000..db250df --- /dev/null +++ b/test/emitter-examples/seq.yaml @@ -0,0 +1,8 @@ +# Outside flow collection: +- ::vector +- ": - ()" +- Up, up, and away! +- -123 +- http://example.com/foo#bar +# Inside flow collection: +- [ ::vector ] diff --git a/test/emitter-examples/seq1.yaml b/test/emitter-examples/seq1.yaml new file mode 100644 index 0000000..7cf7dca --- /dev/null +++ b/test/emitter-examples/seq1.yaml @@ -0,0 +1,6 @@ +- 1 +- 2 +- 3 +- key: + - value1 + - value 2 diff --git a/test/emitter-examples/seq2.yaml b/test/emitter-examples/seq2.yaml new file mode 100644 index 0000000..fdff3b5 --- /dev/null +++ b/test/emitter-examples/seq2.yaml @@ -0,0 +1,3 @@ +- [ YAML : separate ] +- [ : empty key entry ] +- [ {JSON: like}:adjacent ] diff --git a/test/emitter-examples/seq3.yaml b/test/emitter-examples/seq3.yaml new file mode 100644 index 0000000..c82dff5 --- /dev/null +++ b/test/emitter-examples/seq3.yaml @@ -0,0 +1,3 @@ +# - [ YAML : separate ] +- [ "" : empty key entry ] +# - [ {JSON: like}:adjacent ] diff --git a/test/emitter-examples/seq4.yaml b/test/emitter-examples/seq4.yaml new file mode 100644 index 0000000..1ff4f2b --- /dev/null +++ b/test/emitter-examples/seq4.yaml @@ -0,0 +1 @@ +[ : empty ] diff --git a/test/emitter-examples/seq5.yaml b/test/emitter-examples/seq5.yaml new file mode 100644 index 0000000..31bca7d --- /dev/null +++ b/test/emitter-examples/seq5.yaml @@ -0,0 +1 @@ +- : empty diff --git a/test/emitter-examples/seq6.yaml b/test/emitter-examples/seq6.yaml new file mode 100644 index 0000000..328d363 --- /dev/null +++ b/test/emitter-examples/seq6.yaml @@ -0,0 +1,3 @@ +key: +- value1 +- value 2 diff --git a/test/emitter-examples/sets.yaml b/test/emitter-examples/sets.yaml new file mode 100644 index 0000000..30e2ee8 --- /dev/null +++ b/test/emitter-examples/sets.yaml @@ -0,0 +1,8 @@ +# Sets are represented as a +# Mapping where each key is +# associated with a null value +--- +? a +? b +? c +? d diff --git a/test/emitter-examples/simple.yaml b/test/emitter-examples/simple.yaml new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/test/emitter-examples/simple.yaml @@ -0,0 +1 @@ +5 diff --git a/test/emitter-examples/simple1.yaml b/test/emitter-examples/simple1.yaml new file mode 100644 index 0000000..8025a0e --- /dev/null +++ b/test/emitter-examples/simple1.yaml @@ -0,0 +1,2 @@ +--- !!str &anchor +foo diff --git a/test/emitter-examples/simple2.yaml b/test/emitter-examples/simple2.yaml new file mode 100644 index 0000000..14e24d4 --- /dev/null +++ b/test/emitter-examples/simple2.yaml @@ -0,0 +1 @@ +"foobar" diff --git a/test/emitter-examples/simpleanchor.yaml b/test/emitter-examples/simpleanchor.yaml new file mode 100644 index 0000000..b617b80 --- /dev/null +++ b/test/emitter-examples/simpleanchor.yaml @@ -0,0 +1 @@ +&anchor key: value diff --git a/test/emitter-examples/simpleanchor1.yaml b/test/emitter-examples/simpleanchor1.yaml new file mode 100644 index 0000000..6cfc23e --- /dev/null +++ b/test/emitter-examples/simpleanchor1.yaml @@ -0,0 +1,3 @@ +a: &anchor b +c: *anchor +d: e diff --git a/test/emitter-examples/simpleanchor2.yaml b/test/emitter-examples/simpleanchor2.yaml new file mode 100644 index 0000000..9b14943 --- /dev/null +++ b/test/emitter-examples/simpleanchor2.yaml @@ -0,0 +1,3 @@ +a: &anchor [ b, bb, b3, b4 ] +c: *anchor +d: e diff --git a/test/emitter-examples/simpleanchor3.yaml b/test/emitter-examples/simpleanchor3.yaml new file mode 100644 index 0000000..950acfa --- /dev/null +++ b/test/emitter-examples/simpleanchor3.yaml @@ -0,0 +1,8 @@ +a: &anchor + - b + - &another bb + - b3 + - b4 +c: *anchor +d: e +f: *another diff --git a/test/emitter-examples/simpleanchor4.yaml b/test/emitter-examples/simpleanchor4.yaml new file mode 100644 index 0000000..2d2807f --- /dev/null +++ b/test/emitter-examples/simpleanchor4.yaml @@ -0,0 +1,9 @@ +a: &anchor + - b + - &another bb + - b3 + - b4 +c: + d: + e: *anchor +f: *another diff --git a/test/emitter-examples/simplefolded.yaml b/test/emitter-examples/simplefolded.yaml new file mode 100644 index 0000000..40a4a31 --- /dev/null +++ b/test/emitter-examples/simplefolded.yaml @@ -0,0 +1,3 @@ +> + this is a folded + scalar diff --git a/test/emitter-examples/simplekey.yaml b/test/emitter-examples/simplekey.yaml new file mode 100644 index 0000000..3c494f3 --- /dev/null +++ b/test/emitter-examples/simplekey.yaml @@ -0,0 +1 @@ +key : value diff --git a/test/emitter-examples/simplekey1.yaml b/test/emitter-examples/simplekey1.yaml new file mode 100644 index 0000000..bbac3ce --- /dev/null +++ b/test/emitter-examples/simplekey1.yaml @@ -0,0 +1 @@ +{ key : value } diff --git a/test/emitter-examples/simplekey2.yaml b/test/emitter-examples/simplekey2.yaml new file mode 100644 index 0000000..167e6bf --- /dev/null +++ b/test/emitter-examples/simplekey2.yaml @@ -0,0 +1,5 @@ +root: # level 0 + key: # level 1 + value # level 2 + key2: # level 1 + value2 # level 2 diff --git a/test/emitter-examples/simplekey3.yaml b/test/emitter-examples/simplekey3.yaml new file mode 100644 index 0000000..56df99a --- /dev/null +++ b/test/emitter-examples/simplekey3.yaml @@ -0,0 +1,5 @@ +{ + root: { + key: value + } +} diff --git a/test/emitter-examples/simplekey4.yaml b/test/emitter-examples/simplekey4.yaml new file mode 100644 index 0000000..5851568 --- /dev/null +++ b/test/emitter-examples/simplekey4.yaml @@ -0,0 +1,2 @@ +a: b +c: d diff --git a/test/emitter-examples/simplekey5.yaml b/test/emitter-examples/simplekey5.yaml new file mode 100644 index 0000000..2ac4cd4 --- /dev/null +++ b/test/emitter-examples/simplekey5.yaml @@ -0,0 +1,2 @@ +key: + value diff --git a/test/emitter-examples/simpleliteral.yaml b/test/emitter-examples/simpleliteral.yaml new file mode 100644 index 0000000..59da07a --- /dev/null +++ b/test/emitter-examples/simpleliteral.yaml @@ -0,0 +1,3 @@ +| + this is a literal + scalar diff --git a/test/emitter-examples/simpleseq.yaml b/test/emitter-examples/simpleseq.yaml new file mode 100644 index 0000000..a0cd6f3 --- /dev/null +++ b/test/emitter-examples/simpleseq.yaml @@ -0,0 +1,3 @@ +- 1 +- 2 +- 3 diff --git a/test/emitter-examples/simpleseq1.yaml b/test/emitter-examples/simpleseq1.yaml new file mode 100644 index 0000000..a9cd5ae --- /dev/null +++ b/test/emitter-examples/simpleseq1.yaml @@ -0,0 +1,5 @@ +- 1 +- 2 +- 3 +- 4: + foo diff --git a/test/emitter-examples/singlepairimp.yaml b/test/emitter-examples/singlepairimp.yaml new file mode 100644 index 0000000..0f0b325 --- /dev/null +++ b/test/emitter-examples/singlepairimp.yaml @@ -0,0 +1,3 @@ +- [ YAML : separate ] +- [ ffo : empty key entry ] +- [ {JSON: like}:adjacent ] diff --git a/test/emitter-examples/singlepairimp2.yaml b/test/emitter-examples/singlepairimp2.yaml new file mode 100644 index 0000000..38c3b31 --- /dev/null +++ b/test/emitter-examples/singlepairimp2.yaml @@ -0,0 +1,2 @@ +[ [ foo ]: bar ] +# [ foo ]: bar diff --git a/test/emitter-examples/sqscalar.yaml b/test/emitter-examples/sqscalar.yaml new file mode 100644 index 0000000..e74b73e --- /dev/null +++ b/test/emitter-examples/sqscalar.yaml @@ -0,0 +1,13 @@ +- 'quoted' +- 'quoted\nescaped new line' +- 'quoted + explicit new line' +- '' +- ' ' +- ' + ' +- ' pre-spaces' +- 'post-spaces ' +- 'key': value +- 'key/newline': value +- 'escaped '' quote' diff --git a/test/emitter-examples/sqscalarspace.yaml b/test/emitter-examples/sqscalarspace.yaml new file mode 100644 index 0000000..266109e --- /dev/null +++ b/test/emitter-examples/sqscalarspace.yaml @@ -0,0 +1,2 @@ +' + ' diff --git a/test/emitter-examples/strings.yaml b/test/emitter-examples/strings.yaml new file mode 100644 index 0000000..3a196df --- /dev/null +++ b/test/emitter-examples/strings.yaml @@ -0,0 +1,7 @@ +unquoted: string +literal-block: | + This entire block of text will be the value of the 'literal-block' key, + with line breaks being preserved. +folded: > + This entire block of text will be the value of 'folded', but this + time, all newlines will be replaced with a single space. diff --git a/test/emitter-examples/t.yaml b/test/emitter-examples/t.yaml new file mode 100644 index 0000000..2caf1b2 --- /dev/null +++ b/test/emitter-examples/t.yaml @@ -0,0 +1 @@ +: a diff --git a/test/emitter-examples/t1.yaml b/test/emitter-examples/t1.yaml new file mode 100644 index 0000000..aa03859 --- /dev/null +++ b/test/emitter-examples/t1.yaml @@ -0,0 +1 @@ +x: a diff --git a/test/emitter-examples/t2.yaml b/test/emitter-examples/t2.yaml new file mode 100644 index 0000000..a8ca83d --- /dev/null +++ b/test/emitter-examples/t2.yaml @@ -0,0 +1 @@ +? : a diff --git a/test/emitter-examples/t3.yaml b/test/emitter-examples/t3.yaml new file mode 100644 index 0000000..9ab723f --- /dev/null +++ b/test/emitter-examples/t3.yaml @@ -0,0 +1 @@ +? x : a diff --git a/test/emitter-examples/t4.yaml b/test/emitter-examples/t4.yaml new file mode 100644 index 0000000..7eb2a3a --- /dev/null +++ b/test/emitter-examples/t4.yaml @@ -0,0 +1,2 @@ +? x # foo +: a diff --git a/test/emitter-examples/t5.yaml b/test/emitter-examples/t5.yaml new file mode 100644 index 0000000..f35eed8 --- /dev/null +++ b/test/emitter-examples/t5.yaml @@ -0,0 +1 @@ +{ ? : a } diff --git a/test/emitter-examples/tabsmix.yaml b/test/emitter-examples/tabsmix.yaml new file mode 100644 index 0000000..3b895bb --- /dev/null +++ b/test/emitter-examples/tabsmix.yaml @@ -0,0 +1,3 @@ +- > + + detected diff --git a/test/emitter-examples/tagdirective.yaml b/test/emitter-examples/tagdirective.yaml new file mode 100644 index 0000000..82e04a9 --- /dev/null +++ b/test/emitter-examples/tagdirective.yaml @@ -0,0 +1,2 @@ +%TAG !yaml! tag:yaml.org,2002: +--- diff --git a/test/emitter-examples/tagesc.yaml b/test/emitter-examples/tagesc.yaml new file mode 100644 index 0000000..70365f4 --- /dev/null +++ b/test/emitter-examples/tagesc.yaml @@ -0,0 +1,5 @@ +%TAG !e! tag:example.com,2000:app/ +--- +- !local foo +- !!str bar +- !e!tag%21 baz diff --git a/test/emitter-examples/tags-1.yaml b/test/emitter-examples/tags-1.yaml new file mode 100644 index 0000000..bb179ee --- /dev/null +++ b/test/emitter-examples/tags-1.yaml @@ -0,0 +1 @@ +explicit_string: !!str 0.5 diff --git a/test/emitter-examples/tags.yaml b/test/emitter-examples/tags.yaml new file mode 100644 index 0000000..3d5a010 --- /dev/null +++ b/test/emitter-examples/tags.yaml @@ -0,0 +1,7 @@ +gif_file: !!binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= +explicit_string: !!str 0.5 +python_tag: !!python/complex '1.0+2.0j' diff --git a/test/emitter-examples/test.yaml b/test/emitter-examples/test.yaml new file mode 100644 index 0000000..9a24056 --- /dev/null +++ b/test/emitter-examples/test.yaml @@ -0,0 +1,6 @@ +- + a: b + c: d +- + e: f + g: h diff --git a/test/emitter-examples/test1.yaml b/test/emitter-examples/test1.yaml new file mode 100644 index 0000000..a1199a7 --- /dev/null +++ b/test/emitter-examples/test1.yaml @@ -0,0 +1,3 @@ +aa: + bb: cc + dd: ee diff --git a/test/emitter-examples/test2.yaml b/test/emitter-examples/test2.yaml new file mode 100644 index 0000000..5851568 --- /dev/null +++ b/test/emitter-examples/test2.yaml @@ -0,0 +1,2 @@ +a: b +c: d diff --git a/test/emitter-examples/u.yaml b/test/emitter-examples/u.yaml new file mode 100644 index 0000000..aa86103 --- /dev/null +++ b/test/emitter-examples/u.yaml @@ -0,0 +1,4 @@ +{ + foo : !!str, + !!str : bar, +} diff --git a/test/emitter-examples/u1.yaml b/test/emitter-examples/u1.yaml new file mode 100644 index 0000000..329f064 --- /dev/null +++ b/test/emitter-examples/u1.yaml @@ -0,0 +1 @@ +- [ : empty ] diff --git a/test/emitter-examples/u2.yaml b/test/emitter-examples/u2.yaml new file mode 100644 index 0000000..f1805e4 --- /dev/null +++ b/test/emitter-examples/u2.yaml @@ -0,0 +1 @@ +- { : empty } diff --git a/test/emitter-examples/u3.yaml b/test/emitter-examples/u3.yaml new file mode 100644 index 0000000..182599f --- /dev/null +++ b/test/emitter-examples/u3.yaml @@ -0,0 +1 @@ +: empty diff --git a/test/emitter-examples/utf8-simple.yaml b/test/emitter-examples/utf8-simple.yaml new file mode 100644 index 0000000..dd9a18a --- /dev/null +++ b/test/emitter-examples/utf8-simple.yaml @@ -0,0 +1 @@ +Τιμή ελληνική diff --git a/test/emitter-examples/utf8.yaml b/test/emitter-examples/utf8.yaml new file mode 100644 index 0000000..296532c --- /dev/null +++ b/test/emitter-examples/utf8.yaml @@ -0,0 +1,10 @@ +unqouted: string +literal-block: | + This entire block of text will be the value of the 'literal-block' key, + with line breaks being preserved. +folded: > + This entire block of text will be the value of 'folded', but this + time, all newlines will be replaced with a single space. +key-en: "Τιμή ελληνική" +κλειδί-ελ: "English value" + diff --git a/test/emitter-examples/v.yaml b/test/emitter-examples/v.yaml new file mode 100644 index 0000000..5a1554e --- /dev/null +++ b/test/emitter-examples/v.yaml @@ -0,0 +1,8 @@ +--- +a: 0 +--- +? b : 1 +--- +{ c: 2 } +--- +{ ? d : e } diff --git a/test/emitter-examples/v1.yaml b/test/emitter-examples/v1.yaml new file mode 100644 index 0000000..3ae0210 --- /dev/null +++ b/test/emitter-examples/v1.yaml @@ -0,0 +1 @@ +? key : value diff --git a/test/emitter-examples/v2.yaml b/test/emitter-examples/v2.yaml new file mode 100644 index 0000000..57eb12e --- /dev/null +++ b/test/emitter-examples/v2.yaml @@ -0,0 +1 @@ +{ ? d : e } diff --git a/test/emitter-examples/version.yaml b/test/emitter-examples/version.yaml new file mode 100644 index 0000000..96cd702 --- /dev/null +++ b/test/emitter-examples/version.yaml @@ -0,0 +1,4 @@ +# test +%YAML 1.1 +--- +# more comments diff --git a/test/emitter-examples/weirdplain.yaml b/test/emitter-examples/weirdplain.yaml new file mode 100644 index 0000000..020458e --- /dev/null +++ b/test/emitter-examples/weirdplain.yaml @@ -0,0 +1 @@ +this is a:w weird plain diff --git a/test/emitter-examples/ws0.yaml b/test/emitter-examples/ws0.yaml new file mode 100644 index 0000000..6440382 --- /dev/null +++ b/test/emitter-examples/ws0.yaml @@ -0,0 +1 @@ +--- scalar diff --git a/test/emitter-examples/ws1.yaml b/test/emitter-examples/ws1.yaml new file mode 100644 index 0000000..8171dcc --- /dev/null +++ b/test/emitter-examples/ws1.yaml @@ -0,0 +1 @@ +--- scalar diff --git a/test/emitter-examples/ws2.yaml b/test/emitter-examples/ws2.yaml new file mode 100644 index 0000000..5df48e7 --- /dev/null +++ b/test/emitter-examples/ws2.yaml @@ -0,0 +1,12 @@ +"top1" : + "key1" : &alias1 scalar1 +'top2' : + 'key2' : &alias2 scalar2 +top3: &node3 + *alias1 : scalar3 +top4: + *alias2 : scalar4 +top5 : + scalar5 +top6: + &anchor6 'key6' : scalar6 diff --git a/test/emitter-examples/ws3.yaml b/test/emitter-examples/ws3.yaml new file mode 100644 index 0000000..e1e1113 --- /dev/null +++ b/test/emitter-examples/ws3.yaml @@ -0,0 +1,6 @@ +{ first: Sammy, last: Sosa }: +# Statistics: + hr: # Home runs + 65 + avg: # Average + 0.278 diff --git a/test/emitter-examples/y.yaml b/test/emitter-examples/y.yaml new file mode 100644 index 0000000..e14d59c --- /dev/null +++ b/test/emitter-examples/y.yaml @@ -0,0 +1,3 @@ +a: + ? b + : c diff --git a/test/emitter-examples/yaml-version.yaml b/test/emitter-examples/yaml-version.yaml new file mode 100644 index 0000000..122b508 --- /dev/null +++ b/test/emitter-examples/yaml-version.yaml @@ -0,0 +1,3 @@ +%YAML 1.1 +--- +[1, 2, 3] diff --git a/test/emitter-examples/yy.yaml b/test/emitter-examples/yy.yaml new file mode 100644 index 0000000..a44dcdf --- /dev/null +++ b/test/emitter-examples/yy.yaml @@ -0,0 +1,2 @@ +a: + ? b : c diff --git a/test/emitter-examples/zeroexplicit.yaml b/test/emitter-examples/zeroexplicit.yaml new file mode 100644 index 0000000..5637a1a --- /dev/null +++ b/test/emitter-examples/zeroexplicit.yaml @@ -0,0 +1,7 @@ +--- +? +- a +- b +: +- c +- d diff --git a/test/jsontestsuite.test b/test/jsontestsuite.test new file mode 100755 index 0000000..9383f60 --- /dev/null +++ b/test/jsontestsuite.test @@ -0,0 +1,72 @@ +#!/bin/bash + +count=0 + +# count expected to pass +for f in json-test-suite-data/test_parsing/y_*.json; do + count=`expr $count + 1` +done + +# add expected to fail +for f in json-test-suite-data/test_parsing/n_*.json; do + count=`expr $count + 1` +done + +# add implementation defined +for f in json-test-suite-data/test_parsing/i_*.json; do + count=`expr $count + 1` +done + +# output plan +echo 1..$count + +i=0 + +# expected to pass +for f in json-test-suite-data/test_parsing/y_*.json; do + + i=`expr $i + 1` + tf=`basename $f` + + ${TOP_BUILDDIR}/src/fy-tool --testsuite --streaming "$f" >/dev/null + if [ $? -eq 0 ]; then + res="ok" + else + res="not ok" + fi + + echo "$res $i - $tf" +done + +# expected to fail +for f in json-test-suite-data/test_parsing/n_*.json; do + + i=`expr $i + 1` + tf=`basename $f` + + ${TOP_BUILDDIR}/src/fy-tool --testsuite --streaming "$f" >/dev/null + if [ $? -eq 0 ]; then + res="not ok" + else + res="ok" + fi + + echo "$res $i - $tf" +done + +# implementation defined +for f in json-test-suite-data/test_parsing/i_*.json; do + + i=`expr $i + 1` + tf=`basename $f` + + ${TOP_BUILDDIR}/src/fy-tool --testsuite --streaming "$f" >/dev/null + if [ $? -eq 0 ]; then + ires="i-pass" + else + ires="i-fail" + fi + res="ok" + + echo "$res $i - $ires $tf" +done diff --git a/test/libfyaml-test-core.c b/test/libfyaml-test-core.c new file mode 100644 index 0000000..517d0b3 --- /dev/null +++ b/test/libfyaml-test-core.c @@ -0,0 +1,1895 @@ +/* + * libfyaml-test-core.c - libfyaml core testing harness + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +START_TEST(doc_build_simple) +{ + struct fy_document *fyd; + + /* setup */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + /* cleanup */ + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_build_parse_check) +{ + struct fy_document *fyd; + char *buf; + + /* build document (with comments, newlines etc) */ + fyd = fy_document_build_from_string(NULL, "#comment\n[ 42, \n 12 ] # comment\n", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* convert to string */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* compare with expected result */ + ck_assert_str_eq(buf, "[42, 12]\n"); + + free(buf); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_build_scalar) +{ + struct fy_document *fyd; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "plain scalar # comment", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* compare with expected result */ + ck_assert_str_eq(fy_node_get_scalar0(fy_document_root(fyd)), "plain scalar"); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_build_sequence) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int count; + void *iter; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "[ 10, 11, foo ] # comment", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check for correct count value */ + count = fy_node_sequence_item_count(fy_document_root(fyd)); + ck_assert_int_eq(count, 3); + + /* try forward iterator first */ + iter = NULL; + + /* 0 */ + fyn = fy_node_sequence_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "10"); + + /* 1 */ + fyn = fy_node_sequence_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "11"); + + /* 2 */ + fyn = fy_node_sequence_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "foo"); + + /* final, iterator must return NULL */ + fyn = fy_node_sequence_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_eq(fyn, NULL); + + /* reverse iterator */ + iter = NULL; + + /* 2 */ + fyn = fy_node_sequence_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "foo"); + + /* 1 */ + fyn = fy_node_sequence_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "11"); + + /* 0 */ + fyn = fy_node_sequence_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "10"); + + /* final, iterator must return NULL */ + fyn = fy_node_sequence_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_eq(fyn, NULL); + + /* do forward index based accesses */ + + /* 0 */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), 0); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "10"); + + /* 1 */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), 1); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "11"); + + /* 2 */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), 2); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "foo"); + + /* 3, it must not exist */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), 3); + ck_assert_ptr_eq(fyn, NULL); + + /* do backward index based accesses */ + + /* 2 */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), -1); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "foo"); + + /* 1 */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), -2); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "11"); + + /* 0 */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), -3); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fyn), "10"); + + /* -1, it must not exist */ + fyn = fy_node_sequence_get_by_index(fy_document_root(fyd), -4); + ck_assert_ptr_eq(fyn, NULL); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_build_mapping) +{ + struct fy_document *fyd; + struct fy_node_pair *fynp; + int count; + void *iter; + + fyd = fy_document_build_from_string(NULL, "{ foo: 10, bar : 20, baz: [100, 101], [frob, 1]: boo }", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check for correct count value */ + count = fy_node_mapping_item_count(fy_document_root(fyd)); + ck_assert_int_eq(count, 4); + + /* forward iterator first */ + iter = NULL; + + /* 0 */ + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_key(fynp)), "foo"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "10"); + + /* 1 */ + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_key(fynp)), "bar"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "20"); + + /* 2 */ + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_key(fynp)), "baz"); + ck_assert_int_eq(fy_node_sequence_item_count(fy_node_pair_value(fynp)), 2); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_value(fynp), 0)), "100"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_value(fynp), 1)), "101"); + + /* 3 */ + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_int_eq(fy_node_sequence_item_count(fy_node_pair_key(fynp)), 2); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_key(fynp), 0)), "frob"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_key(fynp), 1)), "1"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "boo"); + + /* 4, it must not exist */ + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_eq(fynp, NULL); + + /* reverse iterator */ + iter = NULL; + + /* 3 */ + fynp = fy_node_mapping_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_int_eq(fy_node_sequence_item_count(fy_node_pair_key(fynp)), 2); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_key(fynp), 0)), "frob"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_key(fynp), 1)), "1"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "boo"); + + /* 2 */ + fynp = fy_node_mapping_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_key(fynp)), "baz"); + ck_assert_int_eq(fy_node_sequence_item_count(fy_node_pair_value(fynp)), 2); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_value(fynp), 0)), "100"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_sequence_get_by_index(fy_node_pair_value(fynp), 1)), "101"); + + /* 1 */ + fynp = fy_node_mapping_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_key(fynp)), "bar"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "20"); + + /* 0 */ + fynp = fy_node_mapping_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_key(fynp)), "foo"); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "10"); + + /* -1, it must not exist */ + fynp = fy_node_mapping_reverse_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_eq(fynp, NULL); + + /* key lookups (note how only the contents are compared) */ + ck_assert(fy_node_compare_string(fy_node_mapping_lookup_by_string(fy_document_root(fyd), "foo", FY_NT), "10", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_mapping_lookup_by_string(fy_document_root(fyd), "bar", FY_NT), "20", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_mapping_lookup_by_string(fy_document_root(fyd), "baz", FY_NT), "- 100\n- 101", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_mapping_lookup_by_string(fy_document_root(fyd), "- 'frob'\n- \"\x31\"", FY_NT), "boo", FY_NT) == true); + + fy_document_destroy(fyd); + fyd = NULL; +} +END_TEST + +START_TEST(doc_path_access) +{ + struct fy_document *fyd; + struct fy_node *fyn; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "{ " + "foo: 10, bar : 20, baz:{ frob: boo }, " + "frooz: [ seq1, { key: value} ], \"zero\\0zero\" : 0, " + "{ key2: value2 }: { key3: value3 } " + "}", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check that getting root node works */ + fyn = fy_node_by_path(fy_document_root(fyd), "/", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fy_document_root(fyd)); + + /* check access to scalars */ + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/foo", FY_NT, FYNWF_DONT_FOLLOW), "10", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "bar", FY_NT, FYNWF_DONT_FOLLOW), "20", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "baz/frob", FY_NT, FYNWF_DONT_FOLLOW), "boo", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/frooz/0", FY_NT, FYNWF_DONT_FOLLOW), "seq1", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/frooz/1/key", FY_NT, FYNWF_DONT_FOLLOW), "value", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "\"zero\\0zero\"", FY_NT, FYNWF_DONT_FOLLOW), "0", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/{ key2: value2 }/key3", FY_NT, FYNWF_DONT_FOLLOW), "value3", FY_NT) == true); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_path_node) +{ + struct fy_document *fyd; + char *path; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "{ " + "foo: 10, bar : 20, baz:{ frob: boo }, " + "frooz: [ seq1, { key: value} ], \"zero\\0zero\" : 0, " + "{ key2: value2 }: { key3: value3 } " + "}", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fyd), "/", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_str_eq(path, "/"); + free(path); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fyd), "/frooz", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_str_eq(path, "/frooz"); + free(path); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fyd), "/frooz/0", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_str_eq(path, "/frooz/0"); + free(path); + + path = fy_node_get_path(fy_node_by_path(fy_document_root(fyd), "/{ key2: value2 }/key3", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_str_eq(path, "/{key2: value2}/key3"); + free(path); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_path_parent) +{ + struct fy_document *fyd; + struct fy_node *fyn_root, *fyn_foo, *fyn_bar, *fyn_baz, *fyn_frob, *fyn_ten; + struct fy_node *fyn_deep, *fyn_deeper; + char *path; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "{ " + "foo: 10, bar : [ ten, 20 ], baz:{ frob: boo, deep: { deeper: yet } }, " + "}", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + fyn_foo = fy_node_by_path(fyn_root, "/foo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_foo, NULL); + + fyn_bar = fy_node_by_path(fyn_root, "/bar", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_bar, NULL); + + fyn_baz = fy_node_by_path(fyn_root, "/baz", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_baz, NULL); + + fyn_frob = fy_node_by_path(fyn_root, "/baz/frob", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_frob, NULL); + + fyn_ten = fy_node_by_path(fyn_root, "/bar/0", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_ten, NULL); + + fyn_deep = fy_node_by_path(fyn_root, "/baz/deep", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_deep, NULL); + + fyn_deeper = fy_node_by_path(fyn_root, "/baz/deep/deeper", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_deeper, NULL); + + /* check parent paths of foo, frob, ten */ + path = fy_node_get_parent_address(fyn_foo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "foo"); + free(path); + + path = fy_node_get_parent_address(fyn_frob); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "frob"); + free(path); + + path = fy_node_get_parent_address(fyn_ten); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "0"); + free(path); + + /* check relative paths to root */ + path = fy_node_get_path_relative_to(NULL, fyn_foo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "foo"); + free(path); + + path = fy_node_get_path_relative_to(fyn_root, fyn_foo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "foo"); + free(path); + + path = fy_node_get_path_relative_to(fyn_root, fyn_frob); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "baz/frob"); + free(path); + + path = fy_node_get_path_relative_to(fyn_root, fyn_ten); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "bar/0"); + free(path); + + /* check relative paths to other parents */ + path = fy_node_get_path_relative_to(fyn_baz, fyn_frob); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "frob"); + free(path); + + path = fy_node_get_path_relative_to(fyn_bar, fyn_ten); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "0"); + free(path); + + path = fy_node_get_path_relative_to(fyn_baz, fyn_deeper); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "deep/deeper"); + free(path); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_short_path) +{ + struct fy_document *fyd; + struct fy_node *fyn_root, *fyn_foo, *fyn_notfoo, *fyn_bar, *fyn_baz; + const char *str; + + /* build document */ + fyd = fy_document_build_from_string(NULL, + "--- &r\n" + " foo: &f\n" + " bar: [ 0, two, baz: what ]\n" + " frob: true\n" + " notfoo: false\n" + , FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + fyn_foo = fy_node_by_path(fyn_root, "/foo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_foo, NULL); + + fyn_notfoo = fy_node_by_path(fyn_root, "/notfoo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_notfoo, NULL); + + fyn_bar = fy_node_by_path(fyn_root, "/foo/bar", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_bar, NULL); + + fyn_baz = fy_node_by_path(fyn_root, "/foo/bar/2/baz", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_baz, NULL); + + str = fy_node_get_short_path_alloca(fyn_root); + ck_assert_ptr_ne(str, NULL); + ck_assert_str_eq(str, "*r"); + ck_assert_ptr_eq(fy_node_by_path(fy_document_root(fyd), str, FY_NT, FYNWF_FOLLOW), fyn_root); + + str = fy_node_get_short_path_alloca(fyn_foo); + ck_assert_ptr_ne(str, NULL); + ck_assert_str_eq(str, "*f"); + ck_assert_ptr_eq(fy_node_by_path(fy_document_root(fyd), str, FY_NT, FYNWF_FOLLOW), fyn_foo); + + str = fy_node_get_short_path_alloca(fyn_notfoo); + ck_assert_ptr_ne(str, NULL); + ck_assert_str_eq(str, "*r/notfoo"); + ck_assert_ptr_eq(fy_node_by_path(fy_document_root(fyd), str, FY_NT, FYNWF_FOLLOW), fyn_notfoo); + + str = fy_node_get_short_path_alloca(fyn_bar); + ck_assert_ptr_ne(str, NULL); + ck_assert_str_eq(str, "*f/bar"); + ck_assert_ptr_eq(fy_node_by_path(fy_document_root(fyd), str, FY_NT, FYNWF_FOLLOW), fyn_bar); + + str = fy_node_get_short_path_alloca(fyn_baz); + ck_assert_ptr_ne(str, NULL); + ck_assert_str_eq(str, "*f/bar/2/baz"); + ck_assert_ptr_eq(fy_node_by_path(fy_document_root(fyd), str, FY_NT, FYNWF_FOLLOW), fyn_baz); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_nearest_anchor) +{ + struct fy_document *fyd; + struct fy_node *fyn, *fyn_root, *fyn_foo, *fyn_notfoo, *fyn_bar, *fyn_baz; + + /* build document */ + fyd = fy_document_build_from_string(NULL, + "--- &r\n" + " foo: &f\n" + " bar: [ 0, two, baz: what ]\n" + " frob: true\n" + " notfoo: false\n" + , FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + fyn_foo = fy_node_by_path(fyn_root, "/foo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_foo, NULL); + + fyn_notfoo = fy_node_by_path(fyn_root, "/notfoo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_notfoo, NULL); + + fyn_bar = fy_node_by_path(fyn_root, "/foo/bar", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_bar, NULL); + + fyn_baz = fy_node_by_path(fyn_root, "/foo/bar/2/baz", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_baz, NULL); + + /* get nearest anchor of root (is root) */ + fyn = fy_anchor_node(fy_node_get_nearest_anchor(fyn_root)); + ck_assert_ptr_eq(fyn, fyn_root); + + /* get nearest anchor of notfoo (is root) */ + fyn = fy_anchor_node(fy_node_get_nearest_anchor(fyn_notfoo)); + ck_assert_ptr_eq(fyn, fyn_root); + + /* get nearest anchor of baz (is foo) */ + fyn = fy_anchor_node(fy_node_get_nearest_anchor(fyn_baz)); + ck_assert_ptr_eq(fyn, fyn_foo); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_references) +{ + struct fy_document *fyd; + struct fy_node *fyn, *fyn_ref, *fyn_root, *fyn_foo, *fyn_notfoo, *fyn_bar, *fyn_baz; + char *path; + + /* build document */ + fyd = fy_document_build_from_string(NULL, + "---\n" + " foo: &f\n" + " bar: [ 0, two, baz: what ]\n" + " frob: true\n" + " notfoo: false\n" + , FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + fyn_foo = fy_node_by_path(fyn_root, "/foo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_foo, NULL); + + fyn_notfoo = fy_node_by_path(fyn_root, "/notfoo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_notfoo, NULL); + + fyn_bar = fy_node_by_path(fyn_root, "/foo/bar", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_bar, NULL); + + fyn_baz = fy_node_by_path(fyn_root, "/foo/bar/2/baz", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_baz, NULL); + + /* get reference to root */ + path = fy_node_get_reference(fyn_root); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*/"); + free(path); + + /* get reference to /foo */ + path = fy_node_get_reference(fyn_foo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*f"); + free(path); + + /* get reference to /notfoo */ + path = fy_node_get_reference(fyn_notfoo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*/notfoo"); + free(path); + + /* get reference to /foo/bar/2/baz */ + path = fy_node_get_reference(fyn_baz); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*/foo/bar/2/baz"); + free(path); + + /* create reference to root and verify it points there */ + fyn_ref = fy_node_create_reference(fyn_root); + ck_assert_ptr_ne(fyn_ref, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_root); + fy_node_free(fyn_ref); + + /* get reference to /foo */ + fyn_ref = fy_node_create_reference(fyn_foo); + ck_assert_ptr_ne(path, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_foo); + fy_node_free(fyn_ref); + + /* get reference to /notfoo */ + fyn_ref = fy_node_create_reference(fyn_notfoo); + ck_assert_ptr_ne(path, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_notfoo); + fy_node_free(fyn_ref); + + /* get reference to /bar */ + fyn_ref = fy_node_create_reference(fyn_bar); + ck_assert_ptr_ne(path, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_bar); + fy_node_free(fyn_ref); + + /* get reference to /baz */ + fyn_ref = fy_node_create_reference(fyn_baz); + ck_assert_ptr_ne(path, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_baz); + fy_node_free(fyn_ref); + + /* get relative reference to /foo starting at / */ + path = fy_node_get_relative_reference(fyn_root, fyn_foo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*/foo"); + free(path); + + /* get relative reference to /foo/bar/2/baz starting at / */ + path = fy_node_get_relative_reference(fyn_root, fyn_baz); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*/foo/bar/2/baz"); + free(path); + + /* get relative reference to /foo/bar/2/baz starting at /foo */ + path = fy_node_get_relative_reference(fyn_foo, fyn_baz); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*f/bar/2/baz"); + free(path); + + /* get relative reference to /notfoo at /foo (will return absolute) */ + path = fy_node_get_relative_reference(fyn_foo, fyn_notfoo); + ck_assert_ptr_ne(path, NULL); + ck_assert_str_eq(path, "*/notfoo"); + free(path); + + /* create relative reference to /foo starting at / */ + fyn_ref = fy_node_create_relative_reference(fyn_root, fyn_foo); + ck_assert_ptr_ne(fyn_ref, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_foo); + fy_node_free(fyn_ref); + + /* create relative reference to /foo/bar/2/baz starting at / */ + fyn_ref = fy_node_create_relative_reference(fyn_root, fyn_baz); + ck_assert_ptr_ne(fyn_ref, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_baz); + fy_node_free(fyn_ref); + + /* create relative reference to /foo/bar/2/baz starting at /foo */ + fyn_ref = fy_node_create_relative_reference(fyn_foo, fyn_baz); + ck_assert_ptr_ne(fyn_ref, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_baz); + fy_node_free(fyn_ref); + + /* create relative reference to /notfoo starting at /foo (will use absolute) */ + fyn_ref = fy_node_create_relative_reference(fyn_foo, fyn_notfoo); + ck_assert_ptr_ne(fyn_ref, NULL); + fyn = fy_node_resolve_alias(fyn_ref); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_notfoo); + fy_node_free(fyn_ref); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_nearest_child_of) +{ + struct fy_document *fyd; + struct fy_node *fyn, *fyn_root, *fyn_foo, *fyn_bar, *fyn_baz; + + /* build document */ + fyd = fy_document_build_from_string(NULL, + "foo:\n" + " bar:\n" + " barz: [ zero, baz: true ]\n" + " frooz: notfoo\n" + , FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + fyn_foo = fy_node_by_path(fyn_root, "/foo", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_foo, NULL); + + fyn_bar = fy_node_by_path(fyn_root, "/foo/bar", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_bar, NULL); + + fyn_baz = fy_node_by_path(fyn_root, "/foo/bar/barz/1/baz", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_baz, NULL); + + /* nearest child to the root of /foo is /foo */ + fyn = fy_node_get_nearest_child_of(fyn_root, fyn_foo); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_foo); + + /* nearest child to the root of /foo/bar/barz/1/baz is /foo */ + fyn = fy_node_get_nearest_child_of(fyn_root, fyn_baz); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_foo); + + /* nearest child to foo of /foo/bar/barz/1/baz is /foo/bar */ + fyn = fy_node_get_nearest_child_of(fyn_foo, fyn_baz); + ck_assert_ptr_ne(fyn, NULL); + ck_assert_ptr_eq(fyn, fyn_bar); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_create_empty_seq1) +{ + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_build_from_string(fyd, "[ ]", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + /* convert to string */ + buf = fy_emit_node_to_string(fy_document_root(fyd), FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* compare with expected result */ + ck_assert_str_eq(buf, "[]"); + + free(buf); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_create_empty_seq2) +{ + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + /* convert to string */ + buf = fy_emit_node_to_string(fy_document_root(fyd), FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* compare with expected result */ + ck_assert_str_eq(buf, "[]"); + + free(buf); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_create_empty_map1) +{ + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_build_from_string(fyd, "{ }", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + /* convert to string */ + buf = fy_emit_node_to_string(fy_document_root(fyd), FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* compare with expected result */ + ck_assert_str_eq(buf, "{}"); + + free(buf); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_create_empty_map2) +{ + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_mapping(fyd); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + /* convert to string */ + buf = fy_emit_node_to_string(fy_document_root(fyd), FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* compare with expected result */ + ck_assert_str_eq(buf, "{}"); + + free(buf); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_create_test_seq1) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int ret; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn, NULL); + + ret = fy_node_sequence_append(fyn, fy_node_create_scalar(fyd, "foo", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_sequence_append(fyn, fy_node_create_scalar(fyd, "bar", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_sequence_append(fyn, fy_node_build_from_string(fyd, "{ baz: frooz }", FY_NT)); + ck_assert_int_eq(ret, 0); + + fy_document_set_root(fyd, fyn); + + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/0", FY_NT, FYNWF_DONT_FOLLOW), "foo", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/1", FY_NT, FYNWF_DONT_FOLLOW), "bar", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/2/baz", FY_NT, FYNWF_DONT_FOLLOW), "frooz", FY_NT) == true); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_create_test_map1) +{ + struct fy_document *fyd; + struct fy_node *fyn, *fyn1, *fyn2, *fyn3; + int ret; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_mapping(fyd); + ck_assert_ptr_ne(fyn, NULL); + + ret = fy_node_mapping_append(fyn, + fy_node_build_from_string(fyd, "seq", FY_NT), + fy_node_build_from_string(fyd, "[ zero, one ]", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_mapping_append(fyn, NULL, + fy_node_build_from_string(fyd, "value-of-null-key", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_mapping_append(fyn, + fy_node_build_from_string(fyd, "key-of-null-value", FY_NT), NULL); + ck_assert_int_eq(ret, 0); + + fy_document_set_root(fyd, fyn); + + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/seq/0", FY_NT, FYNWF_DONT_FOLLOW), "zero", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/seq/1", FY_NT, FYNWF_DONT_FOLLOW), "one", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/''", FY_NT, FYNWF_DONT_FOLLOW), "value-of-null-key", FY_NT) == true); + + fyn1 = fy_node_by_path(fy_document_root(fyd), "/key-of-null-value", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_eq(fyn1, NULL); + + /* try to append duplicate key (it should fail) */ + fyn2 = fy_node_build_from_string(fyd, "seq", FY_NT); + ck_assert_ptr_ne(fyn2, NULL); + fyn3 = fy_node_create_scalar(fyd, "dupl", FY_NT); + ck_assert_ptr_ne(fyn3, NULL); + ret = fy_node_mapping_append(fyn, fyn2, fyn3); + ck_assert_int_ne(ret, 0); + + fy_node_free(fyn3); + fy_node_free(fyn2); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_insert_remove_seq) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int ret; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fy_document_set_root(fyd, fy_node_build_from_string(fyd, "[ one, two, four ]", FY_NT)); + + /* check that the order is correct */ + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/0", FY_NT, FYNWF_DONT_FOLLOW), "one", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/1", FY_NT, FYNWF_DONT_FOLLOW), "two", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/2", FY_NT, FYNWF_DONT_FOLLOW), "four", FY_NT) == true); + + ret = fy_node_sequence_append(fy_document_root(fyd), fy_node_build_from_string(fyd, "five", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_sequence_prepend(fy_document_root(fyd), fy_node_build_from_string(fyd, "zero", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_sequence_insert_after(fy_document_root(fyd), + fy_node_by_path(fy_document_root(fyd), "/2", FY_NT, FYNWF_DONT_FOLLOW), + fy_node_build_from_string(fyd, "three", FY_NT)); + ck_assert_int_eq(ret, 0); + + ret = fy_node_sequence_insert_before(fy_document_root(fyd), + fy_node_by_path(fy_document_root(fyd), "/3", FY_NT, FYNWF_DONT_FOLLOW), + fy_node_build_from_string(fyd, "two-and-a-half", FY_NT)); + ck_assert_int_eq(ret, 0); + + fyn = fy_node_sequence_remove(fy_document_root(fyd), + fy_node_by_path(fy_document_root(fyd), "/3", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_ptr_ne(fyn, NULL); + + fy_node_free(fyn); + + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/0", FY_NT, FYNWF_DONT_FOLLOW), "zero", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/1", FY_NT, FYNWF_DONT_FOLLOW), "one", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/2", FY_NT, FYNWF_DONT_FOLLOW), "two", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/3", FY_NT, FYNWF_DONT_FOLLOW), "three", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/4", FY_NT, FYNWF_DONT_FOLLOW), "four", FY_NT) == true); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_insert_remove_map) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int ret; + + fyd = fy_document_build_from_string(NULL, "{ one: 1, two: 2, four: 4 }", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check that the order is correct */ + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/one", FY_NT, FYNWF_DONT_FOLLOW), "1", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/two", FY_NT, FYNWF_DONT_FOLLOW), "2", FY_NT) == true); + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/four", FY_NT, FYNWF_DONT_FOLLOW), "4", FY_NT) == true); + + ret = fy_node_mapping_append(fy_document_root(fyd), + fy_node_build_from_string(fyd, "three", FY_NT), + fy_node_build_from_string(fyd, "3", FY_NT)); + ck_assert_int_eq(ret, 0); + + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/three", FY_NT, FYNWF_DONT_FOLLOW), "3", FY_NT) == true); + + ret = fy_node_mapping_prepend(fy_document_root(fyd), + fy_node_build_from_string(fyd, "zero", FY_NT), + fy_node_build_from_string(fyd, "0", FY_NT)); + ck_assert_int_eq(ret, 0); + + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/zero", FY_NT, FYNWF_DONT_FOLLOW), "0", FY_NT) == true); + + ret = fy_node_mapping_append(fy_document_root(fyd), + fy_node_build_from_string(fyd, "two-and-a-half", FY_NT), + fy_node_build_from_string(fyd, "2.5", FY_NT)); + ck_assert_int_eq(ret, 0); + + ck_assert(fy_node_compare_string(fy_node_by_path(fy_document_root(fyd), "/two-and-a-half", FY_NT, FYNWF_DONT_FOLLOW), "2.5", FY_NT) == true); + + fyn = fy_node_mapping_remove_by_key(fy_document_root(fyd), + fy_node_build_from_string(fyd, "two-and-a-half", FY_NT)); + ck_assert_ptr_ne(fyn, NULL); + + fy_node_free(fyn); + + /* it must be removed */ + fyn = fy_node_by_path(fy_document_root(fyd), "/two-and-a-half", FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_eq(fyn, NULL); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_sort) +{ + struct fy_document *fyd; + void *fynp; + void *iter; + int ret, count; + + fyd = fy_document_build_from_string(NULL, "{ a: 5, { z: bar }: 1, z: 7, " + "[ a, b, c] : 3, { a: whee } : 2 , " + "b: 6, [ z ]: 4 }", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + ret = fy_node_sort(fy_document_root(fyd), NULL, NULL); + ck_assert_int_eq(ret, 0); + + /* check for correct count value */ + count = fy_node_mapping_item_count(fy_document_root(fyd)); + ck_assert_int_eq(count, 7); + + /* forward iterator first */ + iter = NULL; + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "1"); + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "2"); + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "3"); + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "4"); + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "5"); + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "6"); + + fynp = fy_node_mapping_iterate(fy_document_root(fyd), &iter); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_str_eq(fy_node_get_scalar0(fy_node_pair_value(fynp)), "7"); + + fy_document_destroy(fyd); +} +END_TEST + +static char *join_docs(const char *tgt_text, const char *tgt_path, + const char *src_text, const char *src_path, + const char *emit_path) +{ + struct fy_document *fyd_tgt, *fyd_src; + struct fy_node *fyn_tgt, *fyn_src, *fyn_emit; + char *output; + int ret; + + /* insert which overwrites root ( <- ) */ + fyd_tgt = fy_document_build_from_string(NULL, tgt_text, FY_NT); + ck_assert_ptr_ne(fyd_tgt, NULL); + + fyd_src = fy_document_build_from_string(NULL, src_text, FY_NT); + ck_assert_ptr_ne(fyd_src, NULL); + + fyn_tgt = fy_node_by_path(fy_document_root(fyd_tgt), tgt_path, FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_tgt, NULL); + + fyn_src = fy_node_by_path(fy_document_root(fyd_src), src_path, FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_src, NULL); + + ret = fy_node_insert(fyn_tgt, fyn_src); + ck_assert_int_eq(ret, 0); + + ret = fy_document_set_parent(fyd_tgt, fyd_src); + ck_assert_int_eq(ret, 0); + + fyn_emit = fy_node_by_path(fy_document_root(fyd_tgt), emit_path, FY_NT, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_emit, NULL); + + output = fy_emit_node_to_string(fyn_emit, FYECF_MODE_FLOW_ONELINE | FYECF_WIDTH_INF); + ck_assert_ptr_ne(output, NULL); + + fy_document_destroy(fyd_tgt); + + return output; +} + +START_TEST(doc_join_scalar_to_scalar) +{ + char *output; + + output = join_docs( + "foo", "/", /* target */ + "bar", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "bar"); + free(output); +} +END_TEST + +START_TEST(doc_join_scalar_to_map) +{ + char *output; + + output = join_docs( + "{ foo: baz }", "/", /* target */ + "bar", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "bar"); + free(output); +} +END_TEST + +START_TEST(doc_join_scalar_to_seq) +{ + char *output; + + output = join_docs( + "[ foo, baz ]", "/", /* target */ + "bar", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "bar"); + free(output); +} +END_TEST + +START_TEST(doc_join_map_to_scalar) +{ + char *output; + + output = join_docs( + "foo", "/", /* target */ + "{bar: baz}", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "{bar: baz}"); + free(output); +} +END_TEST + +START_TEST(doc_join_map_to_seq) +{ + char *output; + + output = join_docs( + "[foo, frooz]", "/", /* target */ + "{bar: baz}", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "{bar: baz}"); + free(output); +} +END_TEST + +START_TEST(doc_join_map_to_map) +{ + char *output; + + output = join_docs( + "{foo: frooz}", "/", /* target */ + "{bar: baz}", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "{foo: frooz, bar: baz}"); + free(output); +} +END_TEST + +START_TEST(doc_join_seq_to_scalar) +{ + char *output; + + output = join_docs( + "foo", "/", /* target */ + "[bar, baz]", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "[bar, baz]"); + free(output); +} +END_TEST + +START_TEST(doc_join_seq_to_seq) +{ + char *output; + + output = join_docs( + "[foo, frooz]", "/", /* target */ + "[bar, baz]", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "[foo, frooz, bar, baz]"); + free(output); +} +END_TEST + +START_TEST(doc_join_seq_to_map) +{ + char *output; + + output = join_docs( + "{foo: frooz}", "/", /* target */ + "[bar, baz]", "/", /* source */ + "/"); /* emit path */ + + ck_assert_str_eq(output, "[bar, baz]"); + free(output); +} +END_TEST + +START_TEST(doc_join_tags) +{ + char *output; + + output = join_docs( + "%TAG !a! tag:a.com,2019:\n" + "---\n" + "- !a!foo\n" + " foo: bar\n", "/", + "%TAG !b! tag:b.com,2019:\n" + "---\n" + "- !b!bar\n" + " something: other\n", "/", + "/"); + + ck_assert_str_eq(output, "[!a!foo {foo: bar}, !b!bar {something: other}]"); + free(output); +} +END_TEST + +START_TEST(doc_build_with_tags) +{ + struct fy_document *fyd; + struct fy_node *fyn; + struct fy_token *fyt; + char *buf; + int rc; + + /* build document */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + /* create a sequence and set it as root */ + fyn = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + fyn = NULL; + + /* create a node, containing a new tag */ + fyn = fy_node_build_from_string(fyd, "%TAG !e! tag:example.com,2000:app/\n---\n- foo\n- !e!foo bar\n", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + /* append it to the root of the document */ + rc = fy_node_sequence_append(fy_document_root(fyd), fyn); + ck_assert_int_eq(rc, 0); + fyn = NULL; + + /* there must be a new tag */ + fyt = fy_document_tag_directive_lookup(fyd, "!e!"); + ck_assert_ptr_ne(fyt, NULL); + + /* try to build another, but with a different !e! prefix, it must fail */ + fyn = fy_node_build_from_string(fyd, "%TAG !e! tag:example.com,2019:app/\n---\n- foo\n- !e!foo bar\n", FY_NT); + ck_assert_ptr_eq(fyn, NULL); + + /* manually add a tag */ + rc = fy_document_tag_directive_add(fyd, "!f!", "tag:example.com,2019:f/"); + ck_assert_int_eq(rc, 0); + + /* build a node with a tag that's already in the document */ + fyn = fy_node_build_from_string(fyd, "!f!whiz frooz\n", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + /* append it to the root of the document */ + rc = fy_node_sequence_append(fy_document_root(fyd), fyn); + ck_assert_int_eq(rc, 0); + fyn = NULL; + + /* convert to string */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + free(buf); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(doc_attach_check) +{ + struct fy_document *fyd; + struct fy_node *fyn, *fyn_seq, *fyn_map; + struct fy_node *fyn_foo, *fyn_foo2, *fyn_bar, *fyn_baz; + struct fy_node_pair *fynp; + int rc; + + /* build document */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + /* create a sequence */ + fyn_seq = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn_seq, NULL); + + /* create a mapping */ + fyn_map = fy_node_create_mapping(fyd); + ck_assert_ptr_ne(fyn_map, NULL); + + /* create a simple scalar node foo */ + fyn_foo = fy_node_build_from_string(fyd, "foo", FY_NT); + ck_assert_ptr_ne(fyn_foo, NULL); + + /* create another simple scalar node bar */ + fyn_bar = fy_node_build_from_string(fyd, "bar", FY_NT); + ck_assert_ptr_ne(fyn_bar, NULL); + + /* create another simple scalar node baz */ + fyn_baz = fy_node_build_from_string(fyd, "baz", FY_NT); + ck_assert_ptr_ne(fyn_baz, NULL); + + /* create a scalar node with the same content as foo */ + fyn_foo2 = fy_node_build_from_string(fyd, "foo", FY_NT); + ck_assert_ptr_ne(fyn_foo2, NULL); + + /* set the root as the sequence */ + rc = fy_document_set_root(fyd, fyn_seq); + ck_assert_int_eq(rc, 0); + + /* should fail since fyn_seq is now attached */ + rc = fy_document_set_root(fyd, fyn_seq); + ck_assert_int_ne(rc, 0); + + /* freeing should fail, since it's attached too */ + rc = fy_node_free(fyn_seq); + ck_assert_int_ne(rc, 0); + + /* append it to the sequence */ + rc = fy_node_sequence_append(fyn_seq, fyn_foo); + ck_assert_int_eq(rc, 0); + + /* freeing should fail, since it's attached to the seq */ + rc = fy_node_free(fyn_foo); + ck_assert_int_ne(rc, 0); + + /* trying to append it to the sequence again should fail */ + rc = fy_node_sequence_append(fyn_seq, fyn_foo); + ck_assert_int_ne(rc, 0); + + /* append the mapping to the sequence */ + rc = fy_node_sequence_append(fyn_seq, fyn_map); + ck_assert_int_eq(rc, 0); + + /* this should fail, since foo is attached to the sequence */ + rc = fy_node_mapping_append(fyn_map, fyn_foo, fyn_bar); + ck_assert_int_ne(rc, 0); + + /* this should be OK, since foo2 is not attached */ + rc = fy_node_mapping_append(fyn_map, fyn_foo2, fyn_bar); + ck_assert_int_eq(rc, 0); + + /* remove foo from the sequence */ + fyn = fy_node_sequence_remove(fyn_seq, fyn_foo); + ck_assert_ptr_eq(fyn, fyn_foo); + + /* trying to append the same key should fail */ + rc = fy_node_mapping_append(fyn_map, fyn_foo, NULL); + ck_assert_int_ne(rc, 0); + + /* append the baz: NULL mapping */ + rc = fy_node_mapping_append(fyn_map, fyn_baz, NULL); + ck_assert_int_eq(rc, 0); + + /* get the baz: null node pair */ + fynp = fy_node_mapping_lookup_pair(fyn_map, fyn_baz); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_ptr_eq(fy_node_pair_key(fynp), fyn_baz); + ck_assert_ptr_eq(fy_node_pair_value(fynp), NULL); + + /* trying to set the same key in the mapping should fail */ + rc = fy_node_pair_set_key(fynp, fyn_foo); + ck_assert_int_ne(rc, 0); + + /* get the foo: bar node pair */ + fynp = fy_node_mapping_lookup_pair(fyn_map, fyn_foo); + ck_assert_ptr_ne(fynp, NULL); + ck_assert_ptr_eq(fy_node_pair_key(fynp), fyn_foo2); + ck_assert_ptr_eq(fy_node_pair_value(fynp), fyn_bar); + + /* we're setting the same key to the mapping, but that's OK + * since the key is replaced */ + rc = fy_node_pair_set_key(fynp, fyn_foo); + ck_assert_int_eq(rc, 0); + + /* fyn_foo has been freed */ + fyn_foo = NULL; + + /* convert to string */ + rc = fy_emit_document_to_fp(fyd, FYECF_MODE_FLOW_ONELINE, stderr); + ck_assert_int_eq(rc, 0); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(manual_scalar_esc) +{ +#undef MANUAL_SCALAR_ESC +#undef MANUAL_SCALAR_ESC_TXT +#define MANUAL_SCALAR_ESC "\\\"\0\a\b\t\v\f\r\e\xc2\x85\xc2\xa0\xe2\x80\xa8\xe2\x80\xa9" +#define MANUAL_SCALAR_ESC_TXT "\"\\\\\\\"\\0\\a\\b\\t\\v\\f\\r\\e\\N\\_\\L\\P\"" + const char *what = MANUAL_SCALAR_ESC; + size_t what_sz = sizeof(MANUAL_SCALAR_ESC) - 1; + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + const char *buf2; + size_t sz2; + int rc; + + /* build document */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + /* create a manual scalar with all the escapes */ + fyn = fy_node_create_scalar(fyd, what, what_sz); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + fyn = NULL; + + /* emit to a buffer */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* destroy the old document */ + fy_document_destroy(fyd); + fyd = NULL; + + /* verify that the resulting document is in the escaped form */ + ck_assert_str_eq(buf, MANUAL_SCALAR_ESC_TXT "\n"); + + /* now load the result back and verify that it contains exactly the same */ + fyd = fy_document_build_from_string(NULL, buf, FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* get the scalar content */ + buf2 = fy_node_get_scalar(fy_document_root(fyd), &sz2); + ck_assert_ptr_ne(buf2, NULL); + + /* sizes must match */ + ck_assert_int_eq(what_sz, sz2); + + /* and the strings too */ + rc = memcmp(what, buf2, what_sz); + ck_assert_int_eq(rc, 0); + + /* free the document */ + fy_document_destroy(fyd); + fyd = NULL; + + free(buf); +} +END_TEST + +START_TEST(manual_scalar_quoted) +{ +#undef MANUAL_SCALAR_QUOTED +#undef MANUAL_SCALAR_QUOTED_TXT +#define MANUAL_SCALAR_QUOTED "&foo" +#define MANUAL_SCALAR_QUOTED_TXT "\"&foo\"" + const char *what = MANUAL_SCALAR_QUOTED; + size_t what_sz = sizeof(MANUAL_SCALAR_QUOTED) - 1; + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + const char *buf2; + size_t sz2; + int rc; + + /* build document */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + /* create a manual scalar with all the escapes */ + fyn = fy_node_create_scalar(fyd, what, what_sz); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + fyn = NULL; + + /* emit to a buffer */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* destroy the old document */ + fy_document_destroy(fyd); + fyd = NULL; + + /* verify that the resulting document is in the escaped form */ + ck_assert_str_eq(buf, MANUAL_SCALAR_QUOTED_TXT "\n"); + + /* now load the result back and verify that it contains exactly the same */ + fyd = fy_document_build_from_string(NULL, buf, FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* get the scalar content */ + buf2 = fy_node_get_scalar(fy_document_root(fyd), &sz2); + ck_assert_ptr_ne(buf2, NULL); + + /* sizes must match */ + ck_assert_int_eq(what_sz, sz2); + + /* and the strings too */ + rc = memcmp(what, buf2, what_sz); + ck_assert_int_eq(rc, 0); + + /* free the document */ + fy_document_destroy(fyd); + fyd = NULL; + + free(buf); +} +END_TEST + +START_TEST(manual_scalar_copy) +{ +#undef MANUAL_SCALAR_COPY +#define MANUAL_SCALAR_COPY "foo" + const char *what = MANUAL_SCALAR_COPY; + size_t what_sz = sizeof(MANUAL_SCALAR_COPY) - 1; + char *what_copy; + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + + /* build document */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + what_copy = malloc(what_sz); + ck_assert_ptr_ne(what_copy, NULL); + memcpy(what_copy, what, what_sz); + + /* create a manual scalar with all the escapes */ + fyn = fy_node_create_scalar_copy(fyd, what_copy, what_sz); + ck_assert_ptr_ne(fyn, NULL); + + /* free the data */ + free(what_copy); + + fy_document_set_root(fyd, fyn); + fyn = NULL; + + /* emit to a buffer */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* verify that the resulting document is the one we used + '\n' */ + ck_assert_str_eq(buf, MANUAL_SCALAR_COPY "\n"); + + /* destroy the old document */ + fy_document_destroy(fyd); + fyd = NULL; + + free(buf); + +} +END_TEST + +START_TEST(manual_scalarf) +{ + struct fy_document *fyd; + struct fy_node *fyn; + char *buf; + + /* build document */ + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + /* create a manual scalar using the printf interface */ + fyn = fy_node_create_scalarf(fyd, "foo%d", 13); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + fyn = NULL; + + /* emit to a buffer */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* verify that the resulting document is the one we used + '\n' */ + ck_assert_str_eq(buf, "foo13" "\n"); + + /* destroy the old document */ + fy_document_destroy(fyd); + fyd = NULL; + + free(buf); +} +END_TEST + +START_TEST(manual_valid_anchor) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int ret; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + fyn = fy_node_create_scalar(fyd, "foo", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + ret = fy_node_sequence_append(fy_document_root(fyd), fyn); + ck_assert_int_eq(ret, 0); + + /* create a valid anchor */ + ret = fy_node_set_anchor(fyn, "foo", FY_NT); + ck_assert_int_eq(ret, 0); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(manual_invalid_anchor) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int ret; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + fyn = fy_node_create_scalar(fyd, "foo", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + ret = fy_node_sequence_append(fy_document_root(fyd), fyn); + ck_assert_int_eq(ret, 0); + + /* create an invalid anchor */ + ret = fy_node_set_anchor(fyn, "*foo", FY_NT); + ck_assert_int_ne(ret, 0); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(manual_anchor_removal) +{ + struct fy_document *fyd; + struct fy_node *fyn; + int ret; + + fyd = fy_document_create(NULL); + ck_assert_ptr_ne(fyd, NULL); + + fyn = fy_node_create_sequence(fyd); + ck_assert_ptr_ne(fyn, NULL); + + fy_document_set_root(fyd, fyn); + + fyn = fy_node_create_scalar(fyd, "foo", FY_NT); + ck_assert_ptr_ne(fyn, NULL); + + ret = fy_node_sequence_append(fy_document_root(fyd), fyn); + ck_assert_int_eq(ret, 0); + + /* create a valid anchor */ + ret = fy_node_set_anchor(fyn, "foo", FY_NT); + ck_assert_int_eq(ret, 0); + + fprintf(stderr, "---\n# with anchor\n"); + fy_emit_document_to_fp(fyd, FYECF_MODE_FLOW_ONELINE, stderr); + + /* should fail (an anchor already exists) */ + ret = fy_node_set_anchor(fyn, "bar", FY_NT); + ck_assert_int_ne(ret, 0); + + /* should succeed */ + ret = fy_node_remove_anchor(fyn); + ck_assert_int_eq(ret, 0); + + fprintf(stderr, "---\n# without anchor\n"); + fy_emit_document_to_fp(fyd, FYECF_MODE_FLOW_ONELINE, stderr); + + fy_document_destroy(fyd); +} +END_TEST + +START_TEST(manual_block_flow_mix) +{ + struct fy_document *fyd; + struct fy_node *fyn_mapping, *fyn_key, *fyn_value; + char *buf; + int ret; + + fyd = fy_document_build_from_string(NULL, "--- &root\n{\n}\n", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + fyn_mapping = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_mapping, NULL); + + ck_assert(fy_node_is_mapping(fyn_mapping) == true); + + fyn_key = fy_node_create_scalar(fyd, "key", FY_NT); + ck_assert_ptr_ne(fyn_key, NULL); + + fyn_value = fy_node_build_from_string(fyd, "|\n literal\n", FY_NT); + ck_assert_ptr_ne(fyn_value, NULL); + + ret = fy_node_mapping_append(fyn_mapping, fyn_key, fyn_value); + ck_assert_int_eq(ret, 0); + + /* emit document to buffer */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + + /* destroy the first document */ + fy_document_destroy(fyd); + fyd = NULL; + + /* read the emitted document back */ + fyd = fy_document_build_from_string(NULL, buf, FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* compare with expected result */ + ck_assert_str_eq(fy_node_get_scalar0(fy_node_by_path(fy_document_root(fyd), "/key", FY_NT, FYNWF_DONT_FOLLOW)), "literal\n"); + + /* destroy the second document */ + fy_document_destroy(fyd); + fyd = NULL; + + free(buf); + +} +END_TEST + +START_TEST(alloca_check) +{ + struct fy_document *fyd; + char *buf; + const char *abuf; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "{ " + "foo: 10, bar : [ ten, 20 ], baz:{ frob: boo, deep: { deeper: yet } }, " + "}", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* fy_emit_document_to_string*() */ + buf = fy_emit_document_to_string(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + abuf = fy_emit_document_to_string_alloca(fyd, FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(abuf, NULL); + ck_assert_str_eq(buf, abuf); + free(buf); + + /* fy_emit_node_to_string*() */ + buf = fy_emit_node_to_string(fy_node_by_path(fy_document_root(fyd), "/foo", FY_NT, FYNWF_DONT_FOLLOW), FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(buf, NULL); + abuf = fy_emit_node_to_string_alloca(fy_node_by_path(fy_document_root(fyd), "/foo", FY_NT, FYNWF_DONT_FOLLOW), FYECF_MODE_FLOW_ONELINE); + ck_assert_ptr_ne(abuf, NULL); + ck_assert_str_eq(buf, abuf); + free(buf); + + /* path check eq */ + buf = fy_node_get_path(fy_node_by_path(fy_document_root(fyd), "/foo", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_ptr_ne(buf, NULL); + ck_assert_str_eq(buf, "/foo"); + abuf = fy_node_get_path_alloca(fy_node_by_path(fy_document_root(fyd), "/foo", FY_NT, FYNWF_DONT_FOLLOW)); + ck_assert_ptr_ne(abuf, NULL); + ck_assert_str_eq(abuf, "/foo"); + ck_assert_str_eq(buf, abuf); + free(buf); + + /* check that a bad path is "" */ + abuf = fy_node_get_path_alloca(NULL); + ck_assert_ptr_ne(abuf, NULL); + ck_assert_str_eq(abuf, ""); + + fy_document_destroy(fyd); + +} +END_TEST + +TCase *libfyaml_case_core(void) +{ + TCase *tc; + + tc = tcase_create("core"); + + tcase_add_test(tc, doc_build_simple); + tcase_add_test(tc, doc_build_parse_check); + tcase_add_test(tc, doc_build_scalar); + tcase_add_test(tc, doc_build_sequence); + tcase_add_test(tc, doc_build_mapping); + + tcase_add_test(tc, doc_path_access); + tcase_add_test(tc, doc_path_node); + tcase_add_test(tc, doc_path_parent); + tcase_add_test(tc, doc_short_path); + + tcase_add_test(tc, doc_nearest_anchor); + tcase_add_test(tc, doc_references); + tcase_add_test(tc, doc_nearest_child_of); + + tcase_add_test(tc, doc_create_empty_seq1); + tcase_add_test(tc, doc_create_empty_seq2); + tcase_add_test(tc, doc_create_empty_map1); + tcase_add_test(tc, doc_create_empty_map2); + + tcase_add_test(tc, doc_create_test_seq1); + tcase_add_test(tc, doc_create_test_map1); + + tcase_add_test(tc, doc_insert_remove_seq); + tcase_add_test(tc, doc_insert_remove_map); + + tcase_add_test(tc, doc_sort); + + tcase_add_test(tc, doc_join_scalar_to_scalar); + tcase_add_test(tc, doc_join_scalar_to_map); + tcase_add_test(tc, doc_join_scalar_to_seq); + + tcase_add_test(tc, doc_join_map_to_scalar); + tcase_add_test(tc, doc_join_map_to_seq); + tcase_add_test(tc, doc_join_map_to_map); + + tcase_add_test(tc, doc_join_seq_to_scalar); + tcase_add_test(tc, doc_join_seq_to_seq); + tcase_add_test(tc, doc_join_seq_to_map); + + tcase_add_test(tc, doc_join_tags); + + tcase_add_test(tc, doc_build_with_tags); + + tcase_add_test(tc, doc_attach_check); + + tcase_add_test(tc, manual_scalar_esc); + tcase_add_test(tc, manual_scalar_quoted); + tcase_add_test(tc, manual_scalar_copy); + tcase_add_test(tc, manual_scalarf); + + tcase_add_test(tc, manual_valid_anchor); + tcase_add_test(tc, manual_invalid_anchor); + tcase_add_test(tc, manual_anchor_removal); + + tcase_add_test(tc, manual_block_flow_mix); + + tcase_add_test(tc, alloca_check); + + return tc; +} diff --git a/test/libfyaml-test-emit.c b/test/libfyaml-test-emit.c new file mode 100644 index 0000000..6b3e8f4 --- /dev/null +++ b/test/libfyaml-test-emit.c @@ -0,0 +1,124 @@ +/* + * libfyaml-test-emit.c - libfyaml test public emitter interface + * + * Copyright (c) 2021 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +struct test_emitter_data { + struct fy_emitter *emit; + struct fy_emitter_cfg cfg; + size_t alloc; + size_t count; + char *buf; +}; + +static int collect_output(struct fy_emitter *emit, enum fy_emitter_write_type type, + const char *str, int len, void *userdata) +{ + struct test_emitter_data *data = userdata; + char *newbuf; + size_t alloc, need; + + need = data->count + len + 1; + alloc = data->alloc; + if (!alloc) + alloc = 512; /* start at 512 bytes and double */ + while (need > alloc) + alloc <<= 1; + + if (alloc > data->alloc) { + newbuf = realloc(data->buf, alloc); + if (!newbuf) + return -1; + data->buf = newbuf; + data->alloc = alloc; + } + assert(data->alloc >= need); + memcpy(data->buf + data->count, str, len); + data->count += len; + *(char *)(data->buf + data->count) = '\0'; + data->count++; + + return len; +} + +struct fy_emitter *setup_test_emitter(struct test_emitter_data *data) +{ + memset(data, 0, sizeof(*data)); + data->cfg.output = collect_output; + data->cfg.userdata = data; + data->cfg.flags = FYECF_DEFAULT; + data->emit = fy_emitter_create(&data->cfg); + return data->emit; + +} + +static void cleanup_test_emitter(struct test_emitter_data *data) +{ + if (data->emit) + fy_emitter_destroy(data->emit); + if (data->buf) + free(data->buf); +} + +START_TEST(emit_simple) +{ + struct test_emitter_data data; + struct fy_emitter *emit; + int rc; + + emit = setup_test_emitter(&data); + ck_assert_ptr_ne(emit, NULL); + + rc = fy_emit_event(emit, fy_emit_event_create(emit, FYET_STREAM_START)); + ck_assert_int_eq(rc, 0); + + rc = fy_emit_event(emit, fy_emit_event_create(emit, FYET_DOCUMENT_START, true, NULL, NULL)); + ck_assert_int_eq(rc, 0); + + rc = fy_emit_event(emit, fy_emit_event_create(emit, FYET_SCALAR, FYSS_PLAIN, "simple", FY_NT, NULL, NULL)); + ck_assert_int_eq(rc, 0); + + rc = fy_emit_event(emit, fy_emit_event_create(emit, FYET_DOCUMENT_END, true, NULL, NULL)); + ck_assert_int_eq(rc, 0); + + rc = fy_emit_event(emit, fy_emit_event_create(emit, FYET_STREAM_END)); + ck_assert_int_eq(rc, 0); + + ck_assert_ptr_ne(data.buf, NULL); + + /* the contents must be 'simple' (without a newline) */ + ck_assert_str_eq(data.buf, "simple"); + + cleanup_test_emitter(&data); +} +END_TEST + +TCase *libfyaml_case_emit(void) +{ + TCase *tc; + + tc = tcase_create("emit"); + + tcase_add_test(tc, emit_simple); + + return tc; +} diff --git a/test/libfyaml-test-meta.c b/test/libfyaml-test-meta.c new file mode 100644 index 0000000..7bf096b --- /dev/null +++ b/test/libfyaml-test-meta.c @@ -0,0 +1,199 @@ +/* + * libfyaml-test-meta.c - libfyaml meta testing harness + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +START_TEST(meta_basic) +{ + struct fy_document *fyd; + struct fy_node *fyn_root; + void *meta; + int meta_value; + int ret; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "100", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check that root exist */ + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + /* compare with expected result */ + ck_assert_str_eq(fy_node_get_scalar0(fyn_root), "100"); + + /* check that no meta at start */ + meta = fy_node_get_meta(fyn_root); + ck_assert_ptr_eq(meta, NULL); + + /* set a simple value meta */ + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)100); + ck_assert_int_eq(ret, 0); + + /* retrieve it and verify */ + meta = fy_node_get_meta(fyn_root); + meta_value = (int)(uintptr_t)meta; + ck_assert_int_eq(meta_value, 100); + + /* clear the meta */ + fy_node_clear_meta(fyn_root); + + /* check that no meta exists now */ + meta = fy_node_get_meta(fyn_root); + ck_assert_ptr_eq(meta, NULL); + + /* setting new meta now should work */ + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)200); + ck_assert_int_eq(ret, 0); + + /* retrieve it and verify */ + meta = fy_node_get_meta(fyn_root); + meta_value = (int)(uintptr_t)meta; + ck_assert_int_eq(meta_value, 200); + + /* setting new meta override */ + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)201); + ck_assert_int_eq(ret, 0); + + /* retrieve it and verify */ + meta = fy_node_get_meta(fyn_root); + meta_value = (int)(uintptr_t)meta; + ck_assert_int_eq(meta_value, 201); + + fy_document_destroy(fyd); +} +END_TEST + +static void test_meta_clear_cb(struct fy_node *fyn, void *meta, void *user) +{ + int meta_value = (int)(uintptr_t)meta; + int *clear_counter_p = user; + + *clear_counter_p += meta_value; +} + +START_TEST(meta_clear_cb) +{ + struct fy_document *fyd; + struct fy_node *fyn_root, *fyn_0, *fyn_1; + int ret; + int clear_counter; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "[ 100, 101 ]", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check that root exist */ + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + /* register the meta clear callback */ + clear_counter = 0; + ret = fy_document_register_meta(fyd, test_meta_clear_cb, &clear_counter); + + /* setting new meta */ + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)1000); + ck_assert_int_eq(ret, 0); + + /* the clear counter must be unchanged */ + ck_assert_int_eq(clear_counter, 0); + + /* get the two items of the sequence and assign meta */ + fyn_0 = fy_node_by_path(fyn_root, "/0", (size_t)-1, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_0, NULL); + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)100); + ck_assert_int_eq(ret, 0); + + fyn_1 = fy_node_by_path(fyn_root, "/1", (size_t)-1, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_1, NULL); + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)200); + ck_assert_int_eq(ret, 0); + + /* destroy the document */ + fy_document_destroy(fyd); + + /* the end result of the counter must be the sum of all */ + ck_assert_int_eq(clear_counter, 1000 + 100 + 200); +} +END_TEST + +START_TEST(meta_unregister) +{ + struct fy_document *fyd; + struct fy_node *fyn_root, *fyn_0, *fyn_1; + int ret; + int clear_counter; + + /* build document */ + fyd = fy_document_build_from_string(NULL, "[ 100, 101 ]", FY_NT); + ck_assert_ptr_ne(fyd, NULL); + + /* check that root exist */ + fyn_root = fy_document_root(fyd); + ck_assert_ptr_ne(fyn_root, NULL); + + /* register the meta clear callback */ + clear_counter = 0; + ret = fy_document_register_meta(fyd, test_meta_clear_cb, &clear_counter); + + /* setting new meta */ + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)1000); + ck_assert_int_eq(ret, 0); + + /* the clear counter must be unchanged */ + ck_assert_int_eq(clear_counter, 0); + + /* get the two items of the sequence and assign meta */ + fyn_0 = fy_node_by_path(fyn_root, "/0", (size_t)-1, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_0, NULL); + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)100); + ck_assert_int_eq(ret, 0); + + fyn_1 = fy_node_by_path(fyn_root, "/1", (size_t)-1, FYNWF_DONT_FOLLOW); + ck_assert_ptr_ne(fyn_1, NULL); + ret = fy_node_set_meta(fyn_root, (void *)(uintptr_t)200); + ck_assert_int_eq(ret, 0); + + /* unregister */ + fy_document_unregister_meta(fyd); + + /* the counter must be the sum of all after unregistering */ + ck_assert_int_eq(clear_counter, 1000 + 100 + 200); + + /* destroy the document */ + fy_document_destroy(fyd); + +} +END_TEST + +TCase *libfyaml_case_meta(void) +{ + TCase *tc; + + tc = tcase_create("meta"); + + tcase_add_test(tc, meta_basic); + tcase_add_test(tc, meta_clear_cb); + tcase_add_test(tc, meta_unregister); + + return tc; +} diff --git a/test/libfyaml-test-private.c b/test/libfyaml-test-private.c new file mode 100644 index 0000000..c428682 --- /dev/null +++ b/test/libfyaml-test-private.c @@ -0,0 +1,166 @@ +/* + * libfyaml-test-private.c - libfyaml private API test harness + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "fy-parse.h" + +static const struct fy_parse_cfg default_parse_cfg = { + .search_path = "", + .flags = FYPCF_QUIET, +}; + +START_TEST(parser_setup) +{ + struct fy_parser ctx, *fyp = &ctx; + const struct fy_parse_cfg *cfg = &default_parse_cfg; + int rc; + + /* setup */ + rc = fy_parse_setup(fyp, cfg); + ck_assert_int_eq(rc, 0); + + /* cleanup */ + fy_parse_cleanup(fyp); +} +END_TEST + +START_TEST(scan_simple) +{ + struct fy_parser ctx, *fyp = &ctx; + const struct fy_parse_cfg *cfg = &default_parse_cfg; + static const struct fy_input_cfg fyic = { + .type = fyit_memory, + .memory.data = "42", + .memory.size = 2, + }; + struct fy_token *fyt; + int rc; + + /* setup */ + rc = fy_parse_setup(fyp, cfg); + ck_assert_int_eq(rc, 0); + + /* add the input */ + rc = fy_parse_input_append(fyp, &fyic); + ck_assert_int_eq(rc, 0); + + /* STREAM_START */ + fyt = fy_scan(fyp); + ck_assert_ptr_ne(fyt, NULL); + ck_assert(fyt->type == FYTT_STREAM_START); + fy_token_unref(fyt); + + /* SCALAR */ + fyt = fy_scan(fyp); + ck_assert_ptr_ne(fyt, NULL); + ck_assert(fyt->type == FYTT_SCALAR); + ck_assert(fyt->scalar.style == FYSS_PLAIN); + ck_assert_str_eq(fy_token_get_text0(fyt), "42"); + fy_token_unref(fyt); + + /* STREAM_END */ + fyt = fy_scan(fyp); + ck_assert_ptr_ne(fyt, NULL); + ck_assert(fyt->type == FYTT_STREAM_END); + fy_token_unref(fyt); + + /* EOF */ + fyt = fy_scan(fyp); + ck_assert_ptr_eq(fyt, NULL); + + /* cleanup */ + fy_parse_cleanup(fyp); +} +END_TEST + +START_TEST(parse_simple) +{ + struct fy_parser ctx, *fyp = &ctx; + const struct fy_parse_cfg *cfg = &default_parse_cfg; + static const struct fy_input_cfg fyic = { + .type = fyit_memory, + .memory.data = "42", + .memory.size = 2, + }; + struct fy_eventp *fyep; + int rc; + + /* setup */ + rc = fy_parse_setup(fyp, cfg); + ck_assert_int_eq(rc, 0); + + /* add the input */ + rc = fy_parse_input_append(fyp, &fyic); + ck_assert_int_eq(rc, 0); + + /* STREAM_START */ + fyep = fy_parse_private(fyp); + ck_assert_ptr_ne(fyep, NULL); + ck_assert(fyep->e.type == FYET_STREAM_START); + fy_parse_eventp_recycle(fyp, fyep); + + /* DOCUMENT_START */ + fyep = fy_parse_private(fyp); + ck_assert_ptr_ne(fyep, NULL); + ck_assert(fyep->e.type == FYET_DOCUMENT_START); + fy_parse_eventp_recycle(fyp, fyep); + + /* SCALAR */ + fyep = fy_parse_private(fyp); + ck_assert_ptr_ne(fyep, NULL); + ck_assert(fyep->e.type == FYET_SCALAR); + ck_assert_str_eq(fy_token_get_text0(fyep->e.scalar.value), "42"); + fy_parse_eventp_recycle(fyp, fyep); + + /* DOCUMENT_END */ + fyep = fy_parse_private(fyp); + ck_assert_ptr_ne(fyep, NULL); + ck_assert(fyep->e.type == FYET_DOCUMENT_END); + fy_parse_eventp_recycle(fyp, fyep); + + /* STREAM_END */ + fyep = fy_parse_private(fyp); + ck_assert_ptr_ne(fyep, NULL); + ck_assert(fyep->e.type == FYET_STREAM_END); + fy_parse_eventp_recycle(fyp, fyep); + + /* EOF */ + fyep = fy_parse_private(fyp); + ck_assert_ptr_eq(fyep, NULL); + + /* cleanup */ + fy_parse_cleanup(fyp); +} +END_TEST + +TCase *libfyaml_case_private(void) +{ + TCase *tc; + + tc = tcase_create("private"); + + tcase_add_test(tc, parser_setup); + tcase_add_test(tc, scan_simple); + tcase_add_test(tc, parse_simple); + + return tc; +} diff --git a/test/libfyaml-test.c b/test/libfyaml-test.c new file mode 100644 index 0000000..1a336ef --- /dev/null +++ b/test/libfyaml-test.c @@ -0,0 +1,93 @@ +/* + * libfyaml-test.c - C API testing harness for libyaml + * + * Copyright (c) 2019 Pantelis Antoniou + * + * SPDX-License-Identifier: MIT + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "fy-valgrind.h" + +#define QUIET_DEFAULT false + +static struct option lopts[] = { + {"quiet", no_argument, 0, 'q' }, + {"help", no_argument, 0, 'h' }, + {0, 0, 0, 0 }, +}; + +static void display_usage(FILE *fp, char *progname) +{ + fprintf(fp, "Usage: %s [options] [files]\n", progname); + fprintf(fp, "\nOptions:\n\n"); + fprintf(fp, "\t--quiet, -q : Quiet operation, do not " + "output messages (default %s)\n", + QUIET_DEFAULT ? "true" : "false"); + fprintf(fp, "\t--help, -h : Display help message\n"); + fprintf(fp, "\ne.g. %s\n", progname); +} + +extern TCase *libfyaml_case_private(void); +extern TCase *libfyaml_case_core(void); +extern TCase *libfyaml_case_meta(void); +extern TCase *libfyaml_case_emit(void); + +Suite *libfyaml_suite(void) +{ + Suite *s; + + s = suite_create("libfyaml"); + + suite_add_tcase(s, libfyaml_case_private()); + suite_add_tcase(s, libfyaml_case_core()); + suite_add_tcase(s, libfyaml_case_meta()); + suite_add_tcase(s, libfyaml_case_emit()); + + return s; +} + +int main(int argc, char *argv[]) +{ + int exitcode = EXIT_FAILURE, opt, lidx; + bool quiet = QUIET_DEFAULT; + int number_failed; + Suite *s; + SRunner *sr; + + fy_valgrind_check(&argc, &argv); + + while ((opt = getopt_long_only(argc, argv, "qh", lopts, &lidx)) != -1) { + switch (opt) { + case 'q': + quiet = true; + break; + case 'h' : + default: + if (opt != 'h') + fprintf(stderr, "Unknown option\n"); + display_usage(opt == 'h' ? stdout : stderr, argv[0]); + return EXIT_SUCCESS; + } + } + + s = libfyaml_suite(); + sr = srunner_create(s); + srunner_set_tap(sr, "-"); + srunner_run_all(sr, quiet ? CK_SILENT : CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + exitcode = !number_failed ? EXIT_SUCCESS : EXIT_FAILURE; + + return exitcode; +} diff --git a/test/libfyaml.test b/test/libfyaml.test new file mode 100755 index 0000000..cb691aa --- /dev/null +++ b/test/libfyaml.test @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ "x$builddir" == "x" ]; then + T=`realpath ./libfyaml-test` +else + T=`realpath ${builddir}/libfyaml-test` +fi +${T} +exit $? diff --git a/test/test-env b/test/test-env new file mode 100644 index 0000000..abb4867 --- /dev/null +++ b/test/test-env @@ -0,0 +1 @@ +# test environment for libfyaml diff --git a/test/test-errors/0002/=== b/test/test-errors/0002/=== new file mode 100644 index 0000000..e7f4f89 --- /dev/null +++ b/test/test-errors/0002/=== @@ -0,0 +1 @@ +Duplicate key (plain scalar) diff --git a/test/test-errors/0002/in.yaml b/test/test-errors/0002/in.yaml new file mode 100644 index 0000000..c8b14cf --- /dev/null +++ b/test/test-errors/0002/in.yaml @@ -0,0 +1,2 @@ +foo: bar +foo: baz diff --git a/test/test-errors/0002/test.error b/test/test-errors/0002/test.error new file mode 100644 index 0000000..55e8955 --- /dev/null +++ b/test/test-errors/0002/test.error @@ -0,0 +1 @@ +:2:1: error: duplicate key diff --git a/test/test-errors/0003/=== b/test/test-errors/0003/=== new file mode 100644 index 0000000..5441272 --- /dev/null +++ b/test/test-errors/0003/=== @@ -0,0 +1 @@ +Duplicate key (plain scalar, quoted scalar) diff --git a/test/test-errors/0003/in.yaml b/test/test-errors/0003/in.yaml new file mode 100644 index 0000000..41a9f78 --- /dev/null +++ b/test/test-errors/0003/in.yaml @@ -0,0 +1,2 @@ +foo: bar +'foo': baz diff --git a/test/test-errors/0003/test.error b/test/test-errors/0003/test.error new file mode 100644 index 0000000..2ac16d5 --- /dev/null +++ b/test/test-errors/0003/test.error @@ -0,0 +1 @@ +:2:2: error: duplicate key diff --git a/test/test-errors/0004/=== b/test/test-errors/0004/=== new file mode 100644 index 0000000..3053517 --- /dev/null +++ b/test/test-errors/0004/=== @@ -0,0 +1 @@ +Duplicate key (plain scalar, literal scalar) diff --git a/test/test-errors/0004/in.yaml b/test/test-errors/0004/in.yaml new file mode 100644 index 0000000..43e2e52 --- /dev/null +++ b/test/test-errors/0004/in.yaml @@ -0,0 +1,4 @@ +foo: bar +? |- + foo +: baz diff --git a/test/test-errors/0004/test.error b/test/test-errors/0004/test.error new file mode 100644 index 0000000..5ad00f9 --- /dev/null +++ b/test/test-errors/0004/test.error @@ -0,0 +1 @@ +:3:1: error: duplicate key diff --git a/test/test-errors/0005/=== b/test/test-errors/0005/=== new file mode 100644 index 0000000..fe15eed --- /dev/null +++ b/test/test-errors/0005/=== @@ -0,0 +1 @@ +Duplicate key (sequence) diff --git a/test/test-errors/0005/in.yaml b/test/test-errors/0005/in.yaml new file mode 100644 index 0000000..dff9b3b --- /dev/null +++ b/test/test-errors/0005/in.yaml @@ -0,0 +1,2 @@ +[ foo ]: bar +[ foo ]: baz diff --git a/test/test-errors/0005/test.error b/test/test-errors/0005/test.error new file mode 100644 index 0000000..55e8955 --- /dev/null +++ b/test/test-errors/0005/test.error @@ -0,0 +1 @@ +:2:1: error: duplicate key diff --git a/test/test-errors/0006/=== b/test/test-errors/0006/=== new file mode 100644 index 0000000..b018d4d --- /dev/null +++ b/test/test-errors/0006/=== @@ -0,0 +1 @@ +Duplicate key (simple mapping) diff --git a/test/test-errors/0006/in.yaml b/test/test-errors/0006/in.yaml new file mode 100644 index 0000000..df2fabd --- /dev/null +++ b/test/test-errors/0006/in.yaml @@ -0,0 +1,2 @@ +{ foo: bar }: baz +{ foo: bar }: frooz diff --git a/test/test-errors/0006/test.error b/test/test-errors/0006/test.error new file mode 100644 index 0000000..55e8955 --- /dev/null +++ b/test/test-errors/0006/test.error @@ -0,0 +1 @@ +:2:1: error: duplicate key diff --git a/test/test-errors/0007/=== b/test/test-errors/0007/=== new file mode 100644 index 0000000..b8fdf31 --- /dev/null +++ b/test/test-errors/0007/=== @@ -0,0 +1 @@ +Duplicate key (complex sorted mapping) diff --git a/test/test-errors/0007/in.yaml b/test/test-errors/0007/in.yaml new file mode 100644 index 0000000..a2e231a --- /dev/null +++ b/test/test-errors/0007/in.yaml @@ -0,0 +1,2 @@ +{ a: b, { e: f, g: h}: d}: foo +{ { g: h, e: f}: d, a: b}: bar diff --git a/test/test-errors/0007/test.error b/test/test-errors/0007/test.error new file mode 100644 index 0000000..55e8955 --- /dev/null +++ b/test/test-errors/0007/test.error @@ -0,0 +1 @@ +:2:1: error: duplicate key diff --git a/test/test-errors/0008/=== b/test/test-errors/0008/=== new file mode 100644 index 0000000..4556c58 --- /dev/null +++ b/test/test-errors/0008/=== @@ -0,0 +1 @@ +Unknown alias diff --git a/test/test-errors/0008/in.yaml b/test/test-errors/0008/in.yaml new file mode 100644 index 0000000..c9afc53 --- /dev/null +++ b/test/test-errors/0008/in.yaml @@ -0,0 +1 @@ +a: *b diff --git a/test/test-errors/0008/test.error b/test/test-errors/0008/test.error new file mode 100644 index 0000000..35154e4 --- /dev/null +++ b/test/test-errors/0008/test.error @@ -0,0 +1 @@ +:1:5: error: invalid alias diff --git a/test/test-errors/0009/=== b/test/test-errors/0009/=== new file mode 100644 index 0000000..ffc2f0c --- /dev/null +++ b/test/test-errors/0009/=== @@ -0,0 +1 @@ +Invalid merge key (referencing not a mapping) diff --git a/test/test-errors/0009/in.yaml b/test/test-errors/0009/in.yaml new file mode 100644 index 0000000..48e4aaf --- /dev/null +++ b/test/test-errors/0009/in.yaml @@ -0,0 +1,2 @@ +- &FOO foo +- << : *FOO diff --git a/test/test-errors/0009/test.error b/test/test-errors/0009/test.error new file mode 100644 index 0000000..891d8e0 --- /dev/null +++ b/test/test-errors/0009/test.error @@ -0,0 +1 @@ +:2:9: error: invalid merge key value diff --git a/test/test-errors/0010/=== b/test/test-errors/0010/=== new file mode 100644 index 0000000..59e4371 --- /dev/null +++ b/test/test-errors/0010/=== @@ -0,0 +1 @@ +Invalid merge key (not an alias, scalar) diff --git a/test/test-errors/0010/in.yaml b/test/test-errors/0010/in.yaml new file mode 100644 index 0000000..b177cc3 --- /dev/null +++ b/test/test-errors/0010/in.yaml @@ -0,0 +1 @@ +- << : FOO diff --git a/test/test-errors/0010/test.error b/test/test-errors/0010/test.error new file mode 100644 index 0000000..5794178 --- /dev/null +++ b/test/test-errors/0010/test.error @@ -0,0 +1 @@ +:1:8: error: invalid merge key value diff --git a/test/test-errors/0011/=== b/test/test-errors/0011/=== new file mode 100644 index 0000000..77f5aea --- /dev/null +++ b/test/test-errors/0011/=== @@ -0,0 +1 @@ +Invalid merge key (not an alias sequence item) diff --git a/test/test-errors/0011/in.yaml b/test/test-errors/0011/in.yaml new file mode 100644 index 0000000..e3c2ec2 --- /dev/null +++ b/test/test-errors/0011/in.yaml @@ -0,0 +1,2 @@ +- &FOO foo +- << : [ *FOO, bar ] diff --git a/test/test-errors/0011/test.error b/test/test-errors/0011/test.error new file mode 100644 index 0000000..ca287e1 --- /dev/null +++ b/test/test-errors/0011/test.error @@ -0,0 +1 @@ +:2:8: error: invalid merge key value diff --git a/test/testemitter-streaming.test b/test/testemitter-streaming.test new file mode 100755 index 0000000..f5830ff --- /dev/null +++ b/test/testemitter-streaming.test @@ -0,0 +1,2 @@ +#!/bin/bash +${SRCDIR}/testemitter.test --streaming diff --git a/test/testemitter.test b/test/testemitter.test new file mode 100755 index 0000000..8dfb377 --- /dev/null +++ b/test/testemitter.test @@ -0,0 +1,53 @@ +#!/bin/bash + +EXTRA_DUMP_ARGS="" + +if [ "x$1" == "x--streaming" ]; then + EXTRA_DUMP_ARGS="$EXTRA_DUMP_ARGS --streaming" +fi + +count=0 +for f in "${SRCDIR}"/emitter-examples/*.yaml; do + count=`expr $count + 1` +done + +# output plan +echo 1..$count + +i=0 +for f in "${SRCDIR}"/emitter-examples/*.yaml; do + + i=`expr $i + 1` + tf=`basename $f` + + t1=`mktemp` + t2=`mktemp` + + res="not ok" + + pass_parse=0 + ${TOP_BUILDDIR}/src/fy-tool --testsuite --disable-flow-markers "$f" >"$t1" + if [ $? -eq 0 ]; then + ${TOP_BUILDDIR}/src/fy-tool --dump ${EXTRA_DUMP_ARGS} "$f" | \ + ${TOP_BUILDDIR}/src/fy-tool --testsuite --disable-flow-markers - >"$t2" + if [ $? -eq 0 ]; then + pass_parse=1 + fi + fi + + # all errors test are expected to fail + if [ "$pass_parse" == "1" ]; then + diff -u "$t1" "$t2" + if [ $? -eq 0 ]; then + res="ok" + else + res="not ok" + fi + else + res="not ok" + fi + + rm -f "$t1" "$t2" + + echo "$res $i $tf" +done diff --git a/test/testerrors.test b/test/testerrors.test new file mode 100755 index 0000000..e904ceb --- /dev/null +++ b/test/testerrors.test @@ -0,0 +1,55 @@ +#!/bin/bash + +count=0 +for dir in "${SRCDIR}"/test-errors/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do + count=`expr $count + 1` +done + +# output plan +echo 1..$count + +i=0 +for dir in "${SRCDIR}"/test-errors/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do + + i=`expr $i + 1` + desctxt=`cat 2>/dev/null "$dir/==="` + tdir=`basename $dir` + + t=`mktemp` + + res="not ok" + + pass_yaml=0 + ${TOP_BUILDDIR}/src/fy-tool --dump -r "$dir/in.yaml" >"$t" 2>&1 + if [ $? -eq 0 ]; then + pass_yaml=1 + fi + + errmsg=`cat "$t" | head -n1 | sed -e 's/^[^:]*//'` + echo "errmsg: $errmsg" + + # replace with error message + echo "$errmsg" >"$t" + + # all errors test are expected to fail + if [ "$pass_yaml" == "0" ]; then + res="ok" + + # diff is pointless under valgrind + if [ "x$USE_VALGRIND" == "x" ]; then + diff_err=0 + diff -u "$dir/test.error" "$t" + if [ $? -eq 0 ]; then + res="ok" + else + res="not ok" + fi + fi + else + res="not ok" + fi + + rm -f "$t" + + echo "$res $i $tdir - $desctxt" +done diff --git a/test/testsuite-json.test b/test/testsuite-json.test new file mode 100755 index 0000000..9b87ecc --- /dev/null +++ b/test/testsuite-json.test @@ -0,0 +1,66 @@ +#!/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` +done + +# output plan +echo 1..$count + +skiplist="C4HZ" + +i=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 + + i=`expr $i + 1` + desctxt=`cat 2>/dev/null "$dir/==="` + tdir=`basename $dir` + + skipdirective="" + for skip in $skiplist; do + if [ "$tdir" == "$skip" ]; then + skipdirective="# skip does not apply to libfyaml" + break + fi + done + + res="ok" + + if [ "x$skipdirective" == "x" ]; then + t1=`mktemp` + t2=`mktemp` + + # 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" + + # do the same with the json input (canonicalize) + cat "$dir/in.json" | "${JQ}" --sort-keys . > "$t2" + + diff -u "$t1" "$t2" + if [ $? -eq 0 ]; then + res="ok" + else + res="not ok" + fi + + rm -f "$t1" "$t2" + fi + + echo "$res $i $tdir - $desctxt (JSON)$skipdirective" +done diff --git a/test/testsuite.test b/test/testsuite.test new file mode 100755 index 0000000..d711d4b --- /dev/null +++ b/test/testsuite.test @@ -0,0 +1,54 @@ +#!/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` +done + +# output plan +echo 1..$count + +i=0 +for dir in test-suite-data/[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/; do + + i=`expr $i + 1` + desctxt=`cat 2>/dev/null "$dir/==="` + tdir=`basename $dir` + + t=`mktemp` + + res="not ok" + + pass_yaml=0 + ${TOP_BUILDDIR}/src/fy-tool --testsuite "$dir/in.yaml" >"$t" + if [ $? -eq 0 ]; then + pass_yaml=1 + fi + + if [ -e "$dir/error" ]; then + # test is expected to fail + if [ $pass_yaml == "0" ]; then + res="ok" + else + 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" + if [ $? -eq 0 ]; then + res="ok" + else + res="not ok" + fi + else + res="not ok" + fi + fi + + rm -f "$t" + + echo "$res $i $tdir - $desctxt" +done