diff options
author | marcel <marcel@FreeBSD.org> | 2014-10-23 22:30:14 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2014-10-23 22:30:14 +0000 |
commit | fefcd296e4716886912a74acd38abba4c94bc340 (patch) | |
tree | ce8b178967e5d33cbba89d0b2f3d2c2ea45616cb /contrib/libxo | |
parent | bc4f095bf4554f6047f55bd8d28df41679cade6b (diff) | |
download | FreeBSD-src-fefcd296e4716886912a74acd38abba4c94bc340.zip FreeBSD-src-fefcd296e4716886912a74acd38abba4c94bc340.tar.gz |
Import libxo 0.1.4
Obtained from: https://github.com/Juniper/libxo
Sponsored by: Juniper Networks, Inc.
Diffstat (limited to 'contrib/libxo')
204 files changed, 37851 insertions, 0 deletions
diff --git a/contrib/libxo/.gitignore b/contrib/libxo/.gitignore new file mode 100644 index 0000000..386bfc8 --- /dev/null +++ b/contrib/libxo/.gitignore @@ -0,0 +1,43 @@ +# Object files +*.o + +# Libraries +*.lib +*.a + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.app + +*~ +*.orig + +aclocal.m4 +ar-lib +autom4te.cache +build +compile +config.guess +config.h.in +config.sub +depcomp +ltmain.sh +missing + +Makefile.in +configure +.DS_Store + +xoconfig.h.in + +.gdbinit +.gdbinit.local +xtest +xtest.dSYM +tests/w diff --git a/contrib/libxo/.travis.yml b/contrib/libxo/.travis.yml new file mode 100644 index 0000000..e26a769 --- /dev/null +++ b/contrib/libxo/.travis.yml @@ -0,0 +1,12 @@ +language: c + +script: printenv && uname -a && /bin/sh ./bin/setup.sh && cd build && ../configure --enable-warnings && make && sudo make install && make test + +notifications: + recipients: + - libslax-noise@googlegroups.com + +branches: + only: + - master + - develop diff --git a/contrib/libxo/Copyright b/contrib/libxo/Copyright new file mode 100644 index 0000000..94ba75e --- /dev/null +++ b/contrib/libxo/Copyright @@ -0,0 +1,23 @@ +Copyright (c) 2014 Juniper Networks, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. 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 AUTHOR 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 AUTHOR 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. diff --git a/contrib/libxo/LICENSE b/contrib/libxo/LICENSE new file mode 100644 index 0000000..874da7b --- /dev/null +++ b/contrib/libxo/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2014, Juniper Networks +All rights reserved. + +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 HOLDER 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. diff --git a/contrib/libxo/Makefile.am b/contrib/libxo/Makefile.am new file mode 100644 index 0000000..f1fc999 --- /dev/null +++ b/contrib/libxo/Makefile.am @@ -0,0 +1,102 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = libxo xo xolint tests doc +bin_SCRIPTS=libxo-config +dist_doc_DATA = Copyright + +EXTRA_DIST = \ + libxo-config.in \ + warnings.mk \ + README.md \ + INSTALL.md \ + packaging/libxo.spec + +.PHONY: test tests + +test tests: + @(cd tests ; ${MAKE} test) + +errors: + @(cd tests/errors ; ${MAKE} test) + +docs: + @(cd doc ; ${MAKE} docs) + + +DIST_FILES_DIR = ~/Dropbox/dist-files/ +GH_PAGES_DIR = gh-pages/ +PACKAGE_FILE = ${PACKAGE_TARNAME}-${PACKAGE_VERSION}.tar.gz + +upload: dist upload-docs + @echo "Remember to run:" + @echo " gt tag ${PACKAGE_VERSION}" + +upload-docs: docs + @echo "Uploading libxo-manual.html ... " + @-[ -d ${GH_PAGES_DIR} ] \ + && echo "Updating manual on gh-pages ..." \ + && cp doc/libxo-manual.html ${GH_PAGES_DIR} \ + && (cd ${GH_PAGES_DIR} \ + && git commit -m 'new docs' \ + libxo-manual.html \ + && git push origin gh-pages ) ; true + +pkgconfigdir=$(libdir)/pkgconfig +pkgconfig_DATA = packaging/${PACKAGE_NAME}.pc + +get-wiki: + git clone https://github.com/Juniper/${PACKAGE_NAME}.wiki.git wiki + +get-gh-pages: + git clone https://github.com/Juniper/${PACKAGE_NAME}.git \ + gh-pages -b gh-pages + +UPDATE_PACKAGE_FILE = \ + -e "s;__SHA1__;$$SHA1;" \ + -e "s;__SHA256__;SHA256 (textproc/${PACKAGE_FILE}) = $$SHA256;" \ + -e "s;__SIZE__;SIZE (textproc/${PACKAGE_FILE}) = $$SIZE;" + +GH_PACKAGING_DIR = packaging/${PACKAGE_VERSION} +GH_PAGES_PACKAGE_DIR = ${GH_PAGES_DIR}/${GH_PACKAGING_DIR} + +packages: + @-[ -d ${GH_PAGES_DIR} ] && set -x \ + && echo "Updating packages on gh-pages ..." \ + && SHA1="`openssl sha1 ${PACKAGE_FILE} | awk '{print $$2}'`" \ + && SHA256="`openssl sha256 ${PACKAGE_FILE} | awk '{print $$2}'`" \ + && SIZE="`ls -l ${PACKAGE_FILE} | awk '{print $$5}'`" \ + && mkdir -p ${GH_PAGES_PACKAGE_DIR}/freebsd \ + && echo "... ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.rb ..." \ + && sed ${UPDATE_PACKAGE_FILE} \ + packaging/${PACKAGE_NAME}.rb.base \ + > ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.rb \ + && echo "... ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.spec ..." \ + && cp packaging/${PACKAGE_NAME}.spec \ + ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.spec \ + && echo "... ${GH_PAGES_PACKAGE_DIR}/freebsd ..." \ + && sed ${UPDATE_PACKAGE_FILE} \ + ${srcdir}/packaging/freebsd/distinfo.base \ + > ${GH_PAGES_PACKAGE_DIR}/freebsd/distinfo \ + && cp ${srcdir}/packaging/freebsd/pkg-descr \ + ${GH_PAGES_PACKAGE_DIR}/freebsd/pkg-descr \ + && cp ${srcdir}/packaging/freebsd/pkg-plist \ + ${GH_PAGES_PACKAGE_DIR}/freebsd/pkg-plist \ + && cp ${srcdir}/packaging/freebsd/pkg-plist \ + ${GH_PAGES_PACKAGE_DIR}/freebsd/pkg-plist \ + && cp packaging/freebsd/port-Makefile \ + ${GH_PAGES_PACKAGE_DIR}/freebsd/Makefile \ + && (cd ${GH_PAGES_DIR} \ + && git add ${GH_PACKAGING_DIR} \ + && git commit -m 'new packaging data' \ + ${GH_PACKAGING_DIR} \ + && git push origin gh-pages ) ; true diff --git a/contrib/libxo/README.md b/contrib/libxo/README.md new file mode 100644 index 0000000..40c162b --- /dev/null +++ b/contrib/libxo/README.md @@ -0,0 +1,62 @@ +libxo +===== + +libxo - A Library for Generating Text, XML, JSON, and HTML Output + +The libxo library allows an application to generate text, XML, JSON, +and HTML output using a common set of function calls. The application +decides at run time which output style should be produced. The +application calls a function "xo_emit" to product output that is +described in a format string. A "field descriptor" tells libxo what +the field is and what it means. + +``` + xo_emit(" {:lines/%7ju/%ju} {:words/%7ju/%ju} " + "{:characters/%7ju/%ju}{d:filename/%s}\n", + linect, wordct, charct, file); +``` + +Output can then be generated in various style, using the "--libxo" +option: + +``` + % wc /etc/motd + 25 165 1140 /etc/motd + % wc --libxo xml,pretty,warn /etc/motd + <wc> + <file> + <filename>/etc/motd</filename> + <lines>25</lines> + <words>165</words> + <characters>1140</characters> + </file> + </wc> + % wc --libxo json,pretty,warn /etc/motd + { + "wc": { + "file": [ + { + "filename": "/etc/motd", + "lines": 25, + "words": 165, + "characters": 1140 + } + ] + } + } + % wc --libxo html,pretty,warn /etc/motd + <div class="line"> + <div class="text"> </div> + <div class="data" data-tag="lines"> 25</div> + <div class="text"> </div> + <div class="data" data-tag="words"> 165</div> + <div class="text"> </div> + <div class="data" data-tag="characters"> 1140</div> + <div class="text"> </div> + <div class="data" data-tag="filename">/etc/motd</div> + </div> +``` + +View the beautiful documentation at: + +http://juniper.github.io/libxo/libxo-manual.html diff --git a/contrib/libxo/bin/Makefile.am b/contrib/libxo/bin/Makefile.am new file mode 100644 index 0000000..3bda1be --- /dev/null +++ b/contrib/libxo/bin/Makefile.am @@ -0,0 +1,29 @@ +# +# Copyright 2013, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +ACLOCAL_AMFLAGS = -I m4 + +EXTRA_DIST = gt setup.sh + +GT_INSTALL_DIR = ${prefix}/bin +GT_INSTALL_FILES = gt + +install-data-hook: + @echo "Installing gt ... " + @-mkdir -p ${GT_INSTALL_DIR} + @for file in ${GT_INSTALL_FILES} ; do \ + if [ -f $$file ]; then \ + rfile=$$file ; \ + else \ + rfile=${srcdir}/$$file ; \ + fi ; \ + mdir=${GT_INSTALL_DIR}/ ; \ + mkdir -p $$mdir ; \ + cp $$rfile $$mdir/ ; \ + done + @${CHMOD} a+x ${GT_INSTALL_DIR}/gt diff --git a/contrib/libxo/bin/Zaliases b/contrib/libxo/bin/Zaliases new file mode 100644 index 0000000..a24d33e --- /dev/null +++ b/contrib/libxo/bin/Zaliases @@ -0,0 +1,24 @@ +set top_src=`pwd` +alias Zautoreconf "(cd $top_src ; autoreconf --install)" + +set opts=' \ +--with-libslax-prefix=/Users/phil/work/root \ +--enable-debug \ +--enable-warnings \ +--enable-printflike \ +--prefix ${HOME}/work/root \ +' +set opts=`echo $opts` + +setenv CONFIGURE_OPTS "$opts" +setenv ADB_PATH $top_src/build/libxo/.libs + +alias Zconfigure "(cd $top_src/build; ../configure $opts)" +alias Zbuild "(cd $top_src/build; make \!* )" +alias mi "(cd $top_src/build; make && make install); ." + +mkdir -p build +cd build + + +alias xx 'cc -I.. -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Werror -Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wformat -Wimplicit -Wmissing-declarations -Wnested-externs -Wparentheses -Wreturn-type -Wshadow -Wswitch -Wtrigraphs -Wuninitialized -Wunused -Wwrite-strings -fno-inline-functions-called-once -g -O2 -o xtest -DUNIT_TEST libxo.c' diff --git a/contrib/libxo/bin/setup.sh b/contrib/libxo/bin/setup.sh new file mode 100755 index 0000000..5e03ff3 --- /dev/null +++ b/contrib/libxo/bin/setup.sh @@ -0,0 +1,31 @@ +# +# Copyright 2013, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + + +if [ ! -f configure ]; then + vers=`autoreconf --version | head -1` + echo "Using" $vers + + autoreconf --install + + if [ ! -f configure ]; then + echo "Failed to create configure script" + exit 1 + fi +fi + +echo "Creating build directory ..." +mkdir build + +echo "Setup is complete. To build libslax:" + +echo " 1) Type 'cd build ; ../configure' to configure libslax" +echo " 2) Type 'make' to build libslax" +echo " 3) Type 'make install' to install libslax" + +exit 0 diff --git a/contrib/libxo/build/.create b/contrib/libxo/build/.create new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/build/.create diff --git a/contrib/libxo/configure.ac b/contrib/libxo/configure.ac new file mode 100644 index 0000000..2412d12 --- /dev/null +++ b/contrib/libxo/configure.ac @@ -0,0 +1,263 @@ +# +# $Id$ +# +# See ./INSTALL for more info +# + +# +# Release numbering: even numbered dot releases are official ones, and +# odd numbers are development ones. The svn version of this file will +# only (ONLY!) ever (EVER!) contain odd numbers, so I'll always know if +# a particular user has the dist or svn release. +# + +AC_PREREQ(2.2) +AC_INIT([libxo], [0.1.4], [phil@juniper.net]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability]) + +# Support silent build rules. Requires at least automake-1.11. +# Disable with "configure --disable-silent-rules" or "make V=1" +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_PROG_CC +AM_PROG_AR +AC_PROG_INSTALL +AC_CONFIG_MACRO_DIR([m4]) +AC_PROG_LN_S + +# Must be after AC_PROG_AR +LT_INIT([dlopen shared]) + +AC_PATH_PROG(BASENAME, basename, /usr/bin/basename) +AC_PATH_PROG(BISON, bison, /usr/bin/bison) +AC_PATH_PROG(CAT, cat, /bin/cat) +AC_PATH_PROG(CHMOD, chmod, /bin/chmod) +AC_PATH_PROG(CP, cp, /bin/cp) +AC_PATH_PROG(DIFF, diff, /usr/bin/diff) +AC_PATH_PROG(MKDIR, mkdir, /bin/mkdir) +AC_PATH_PROG(MV, mv, /bin/mv) +AC_PATH_PROG(RM, rm, /bin/rm) +AC_PATH_PROG(SED, sed, /bin/sed) + +AC_STDC_HEADERS + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_INLINE +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_ALLOCA +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_CHECK_FUNCS([bzero memmove strchr strcspn strerror strspn]) +AC_CHECK_FUNCS([sranddev srand strlcpy]) +AC_CHECK_FUNCS([fdopen getrusage]) +AC_CHECK_FUNCS([gettimeofday ctime]) +AC_CHECK_FUNCS([getpass]) +AC_CHECK_FUNCS([sysctlbyname]) +AC_CHECK_FUNCS([flock]) +AC_CHECK_FUNCS([asprintf]) + +AC_CHECK_HEADERS([dlfcn.h]) +AC_CHECK_HEADERS([tzfile.h]) +AC_CHECK_HEADERS([stdtime/tzfile.h]) +AC_CHECK_FUNCS([dlfunc]) + +AC_CHECK_HEADERS([sys/time.h]) +AC_CHECK_HEADERS([ctype.h errno.h stdio.h stdlib.h]) +AC_CHECK_HEADERS([string.h sys/param.h unistd.h ]) +AC_CHECK_HEADERS([sys/sysctl.h]) + +AC_CHECK_LIB([crypto], [MD5_Init]) +AM_CONDITIONAL([HAVE_LIBCRYPTO], [test "$HAVE_LIBCRYPTO" != "no"]) + +dnl +dnl Some packages need to be checked against version numbers so we +dnl define a function here for later use +dnl +AC_DEFUN([VERSION_TO_NUMBER], +[`$1 | sed -e 's/lib.* //' | awk 'BEGIN { FS = "."; } { printf "%d", ([$]1 * 1000 + [$]2) * 1000 + [$]3;}'`]) + +LIBSLAX_CONFIG_PREFIX="" +LIBSLAX_SRC="" + +AC_ARG_WITH(libslax-prefix, + [ --with-libslax-prefix=[PFX] Specify location of libslax config], + LIBSLAX_CONFIG_PREFIX=$withval +) + +AC_MSG_CHECKING(for libslax) +if test "x$LIBSLAX_CONFIG_PREFIX" != "x" +then + SLAX_CONFIG=${LIBSLAX_CONFIG_PREFIX}/bin/slax-config +else + SLAX_CONFIG=slax-config +fi + +dnl +dnl make sure slax-config is executable, +dnl test version and init our variables +dnl + +if ${SLAX_CONFIG} --libs > /dev/null 2>&1 +then + LIBSLAX_VERSION=`$SLAX_CONFIG --version` + SLAX_BINDIR="`$SLAX_CONFIG --bindir | head -1`" + SLAX_OXTRADOCDIR="`$SLAX_CONFIG --oxtradoc | head -1`" + AC_MSG_RESULT($LIBSLAX_VERSION found) +else + LIBSLAX_VERSION= + SLAX_BINDIR= + SLAX_OXTRADOCDIR= + AC_MSG_RESULT([no]) +fi + +AC_SUBST(SLAX_BINDIR) +AC_SUBST(SLAX_OXTRADOCDIR) + +AC_MSG_CHECKING([whether to build with warnings]) +AC_ARG_ENABLE([warnings], + [ --enable-warnings Turn on compiler warnings], + [LIBXO_WARNINGS=$enableval], + [LIBXO_WARNINGS=no]) +AC_MSG_RESULT([$LIBXO_WARNINGS]) +AM_CONDITIONAL([LIBXO_WARNINGS_HIGH], [test "$LIBXO_WARNINGS" != "no"]) + +AC_MSG_CHECKING([whether to build with debugging]) +AC_ARG_ENABLE([debug], + [ --enable-debug Turn on debugging], + [LIBXO_DEBUG=yes; AC_DEFINE([LIBXO_DEBUG], [1], [Enable debugging])], + [LIBXO_DEBUG=no]) +AC_MSG_RESULT([$LIBXO_DEBUG]) +AM_CONDITIONAL([LIBXO_DEBUG], [test "$LIBXO_DEBUG" != "no"]) + +AC_CHECK_LIB([m], [lrint]) +AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"]) + +AC_MSG_CHECKING([compiler for gcc]) +HAVE_GCC=no +if test "${CC}" != ""; then + HAVE_GCC=`${CC} --version 2>&1 | grep GCC` + if test "${HAVE_GCC}" != ""; then + HAVE_GCC=yes + else + HAVE_GCC=no + fi +fi +AC_MSG_RESULT([$HAVE_GCC]) +AM_CONDITIONAL([HAVE_GCC], [test "$HAVE_GCC" = "yes"]) + +AC_MSG_CHECKING([whether to build with printflike]) +AC_ARG_ENABLE([printflike], + [ --enable-printflike Enable use of GCC __printflike attribute], + [HAVE_PRINTFLIKE=yes; + AC_DEFINE([HAVE_PRINTFLIKE], [1], [Support printflike])], + [HAVE_PRINTFLIKE=no]) +AC_MSG_RESULT([$HAVE_PRINTFLIKE]) +AM_CONDITIONAL([HAVE_PRINTFLIKE], [test "$HAVE_PRINTFLIKE" != ""]) + +AC_MSG_CHECKING([whether to build with LIBXO_OPTIONS]) +AC_ARG_ENABLE([libxo-options], + [ --disable-libxo-options Turn off support for LIBXO_OPTIONS], + [LIBXO_OPTS=$enableval], + [LIBXO_OPTS=yes]) +AC_MSG_RESULT([$LIBXO_OPTS]) +AM_CONDITIONAL([NO_LIBXO_OPTIONS], [test "$LIBXO_OPTS" != "yes"]) + + +case $host_os in + darwin*) + LIBTOOL=glibtool + ;; + Linux*|linux*) + CFLAGS="-D_GNU_SOURCE $CFLAGS" + LDFLAGS=-ldl + ;; + cygwin*|CYGWIN*) + LDFLAGS=-no-undefined + ;; +esac + +case $prefix in + NONE) + prefix=/usr/local + ;; +esac + +XO_LIBS=-lxo +XO_SRCDIR=${srcdir} +XO_LIBDIR=${libdir} +XO_BINDIR=${bindir} +XO_INCLUDEDIR=${includedir} + +AC_SUBST(XO_SRCDIR) +AC_SUBST(XO_LIBDIR) +AC_SUBST(XO_BINDIR) +AC_SUBST(XO_INCLUDEDIR) + +AC_ARG_WITH(share-dir, + [ --with-share-dir=[DIR] Specify location of shared files], + [XO_SHAREDIR=$withval], + [XO_SHAREDIR=$datarootdir/libxo] +) +XO_SHAREDIR=`echo $XO_SHAREDIR | sed "s;\\${prefix};$prefix;"` +AC_SUBST(XO_SHAREDIR) + +dnl for the spec file +RELDATE=`date +'%Y-%m-%d%n'` +AC_SUBST(RELDATE) + +AC_MSG_RESULT(Using configure dir $ac_abs_confdir) + +if test -d $ac_abs_confdir/.git ; then + extra=`git branch | awk '/\*/ { print $2 }'` + if test "$extra" != "" -a "$extra" != "master" + then + LIBXO_VERSION_EXTRA="-git-$extra" + fi +fi + +LIBXO_VERSION=$PACKAGE_VERSION +LIBXO_VERSION_NUMBER=VERSION_TO_NUMBER(echo $PACKAGE_VERSION) +AC_SUBST(LIBXO_VERSION) +AC_SUBST(LIBXO_VERSION_NUMBER) +AC_SUBST(LIBXO_VERSION_EXTRA) + +AC_CONFIG_HEADERS([libxo/xoconfig.h]) +AC_CONFIG_FILES([ + Makefile + libxo-config + xohtml/xohtml.sh + libxo/Makefile + libxo/xoversion.h + xo/Makefile + xolint/Makefile + packaging/libxo.pc + doc/Makefile + tests/Makefile + tests/core/Makefile + tests/xo/Makefile + packaging/libxo.spec +]) +AC_OUTPUT + +AC_MSG_NOTICE([summary of build options: + + libxo version: ${VERSION} ${LIBXO_VERSION_EXTRA} + host type: ${host} / ${host_os} + install prefix: ${prefix} + srcdir: ${XO_SRCDIR} + libdir: ${XO_LIBDIR} + bindir: ${XO_BINDIR} + includedir: ${XO_INCLUDEDIR} + share dir: ${XO_SHAREDIR} + + compiler: ${CC} (${HAVE_GCC:-no}) + compiler flags: ${CFLAGS} + library types: Shared=${enable_shared}, Static=${enable_static} + + warnings: ${LIBXO_WARNINGS:-no} + debug: ${LIBXO_DEBUG:-no} + printf-like: ${HAVE_PRINTFLIKE:-no} + libxo-options: ${LIBXO_OPTS:-no} +]) diff --git a/contrib/libxo/doc/Makefile.am b/contrib/libxo/doc/Makefile.am new file mode 100644 index 0000000..c0c3271 --- /dev/null +++ b/contrib/libxo/doc/Makefile.am @@ -0,0 +1,65 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +OXTRADOC_DIR = ${SLAX_OXTRADOCDIR} +OXTRADOC_PREFIX = ${OXTRADOC_DIR} +OXTRADOC = ${OXTRADOC_DIR}/oxtradoc +SLAXPROC_BINDIR = ${SLAX_BINDIR} + +XML2RFC = ${OXTRADOC_DIR}/xml2rfc.tcl +XML2HTMLDIR = ${OXTRADOC_DIR} +XML2HTMLBIN = ${XML2HTMLDIR}/rfc2629-to-html.slax +SLAXPROC = ${SLAX_BINDIR}/slaxproc + +SLAXPROC_ARGS = \ + -a oxtradoc-dir ${OXTRADOC_DIR} \ + -a oxtradoc-install-dir ${OXTRADOC_DIR} \ + -a anchor-prefix docs + +SLAXPROC_ARGS_INLINE = \ + -a oxtradoc-inline yes + +SLAXPROC_ARGS += ${SLAXPROC_ARGS_INLINE} + +XML2HTML = \ + ${SLAXPROC} -g -e -I ${OXTRADOC_DIR} -I . \ + ${SLAXPROC_ARGS} \ + ${XML2HTMLBIN} + +OX_ARGS = -P ${OXTRADOC_PREFIX} -L ${OXTRADOC_PREFIX} +OX_ARGS += -S ${SLAXPROC} -p doc +OX_CMD = ${PERL} ${PERLOPTS} ${OXTRADOC} ${OX_ARGS} +OXTRADOC_CMD = ${OX_CMD} + + +OUTPUT = libxo-manual +INPUT = libxo.txt + +EXTRA_DIST = \ + ${INPUT} \ + ${OUTPUT}.html \ + ${OUTPUT}.txt + +doc docs: ${OUTPUT}.txt ${OUTPUT}.html + +${OUTPUT}.txt: ${INPUT} ${OXTRADOC} xolint.txt + ${OXTRADOC_CMD} -m text -o $@ $< + +${OUTPUT}.html: ${INPUT} ${OXTRADOC} ${XML2HTMLBIN} xolint.txt + ${OXTRADOC_CMD} -m html -o $@ $< + +xolint.txt: ${top_srcdir}/xolint/xolint.pl + perl ${top_srcdir}/xolint/xolint.pl -D > xolint.txt + +CLEANFILES = \ +${OUTPUT}.xml \ +${OUTPUT}.txt \ +${OUTPUT}.fxml \ +${OUTPUT}.html diff --git a/contrib/libxo/doc/libxo.txt b/contrib/libxo/doc/libxo.txt new file mode 100644 index 0000000..5148de0 --- /dev/null +++ b/contrib/libxo/doc/libxo.txt @@ -0,0 +1,2400 @@ +# +# Copyright (c) 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. +# Phil Shafer, July 2014 +# + +* libxo + +libxo - A Library for Generating Text, XML, JSON, and HTML Output + +You live in the present, but you want to live in the future. You'd +love a flying car, but need to get to work today. You want to support +features like XML, JSON, and HTML rendering to allow integration with +NETCONF, REST, and web browsers, but you need to make text output for +command line users. And you don't want multiple code paths that can't +help but get out of sync. None of this "if (xml) {... } else {...}" +logic. And ifdefs are right out. But you'd really, really like all +the fancy features that modern encoding formats can provide. + +The libxo library allows an application to generate text, XML, JSON, +and HTML output using a common set of function calls. The application +decides at run time which output style should be produced. The +application calls a function "xo_emit" to product output that is +described in a format string. A "field descriptor" tells libxo what +the field is and what it means. Each field descriptor is placed in +braces with a printf-like format string: + + xo_emit(" {:lines/%7ju} {:words/%7ju} " + "{:characters/%7ju}{d:filename/%s}\n", + linect, wordct, charct, file); + +Each field can have a role, with the 'value' role being the default, +and the role tells libxo how and when to render that field. Output +can then be generated in various style, using the "--libxo" option: + + % wc /etc/motd + 25 165 1140 /etc/motd + % wc --libxo xml,pretty,warn /etc/motd + <wc> + <file> + <filename>/etc/motd</filename> + <lines>25</lines> + <words>165</words> + <characters>1140</characters> + </file> + </wc> + % wc --libxo json,pretty,warn /etc/motd + { + "wc": { + "file": [ + { + "filename": "/etc/motd", + "lines": 25, + "words": 165, + "characters": 1140 + } + ] + } + } + % wc --libxo html,pretty,warn /etc/motd + <div class="line"> + <div class="text"> </div> + <div class="data" data-tag="lines"> 25</div> + <div class="text"> </div> + <div class="data" data-tag="words"> 165</div> + <div class="text"> </div> + <div class="data" data-tag="characters"> 1140</div> + <div class="text"> </div> + <div class="data" data-tag="filename">/etc/motd</div> + </div> + +** Getting libxo + +libxo lives on github as: + + https://github.com/Juniper/libxo + +The latest release of libxo is available at: + + https://github.com/Juniper/libxo/releases + +We are following the branching scheme from +^http://nvie.com/posts/a-successful-git-branching-model/^ +which means we will do development under the "develop" branch, and +release from the master. To clone a developer tree, run the following +command: + + git clone https://github.com/Juniper/libxo.git -b develop + +We're using semantic release numbering. + +* Overview + +Most unix commands emit text output aimed at humans. It is designed +to be parsed and understood by a user. Humans are gifted at extracted +details and pattern matching. Often programmers need to extract +information from this human-oriented output. Programmers use tools +like grep, awk, and regular expressions to ferret out the pieces of +information they need. Such solutions are fragile and require +updates when output contents change or evolve, requiring testing and +validation. + +Modern tool developers favors encoding schemes like XML and JSON, +which allow trivial parsing and extraction of data. Such formats are +simple, well understood, hierarchical, easily parsed, and often +integrate easier with common tools and environments. + +In addition, modern reality means that more output ends up in web +browsers than in terminals, making HTML output valuable. + +libxo allows a single set of function calls in source code to generate +traditional text output, as well as XML and JSON formatted data. HTML +can also be generated; "<div>" elements surround the traditional text +output, with attributes that detail how to render the data. + +A single libxo function call in source code is all that's required: + + xo_emit("Connecting to {:host}.{:domain}...\n", host, domain); + + Text: + Connection to my-box.example.com... + XML: + <host>my-box</host> + <domain>example.com</domain> + JSON: + "host": my-box", + "domain": "example.com" + +For brevity, the HTML output is emitted. + +** Encoding Styles + +There are four encoding styles supported by libxo: TEXT, HTML, JSON, +and XML. JSON and XML are suitable for encoding data, while TEXT and +HTML are suited for display to the user. TEXT output can be display +on a terminal session, allowing compatibility with traditional usage. +HTML can be matched with a small CSS file to permit rendering in any +HTML5 browser. XML output is suitable for tools like XPath and +protocols like NETCONF. JSON output can be used for RESTful APIs. + +*** Text Output + +Most traditional programs generate text output on standard output, +with contents like: + + 36 ./src + 40 ./bin + 90 . + +In this example (taken from du source code), the code to generate this +data might look like: + + printf("%d\t%s\n", num_blocks, path); + +Simple, direct, obvious. But it's only making text output. Imagine +using a single code path to make text, XML, JSON or HTML, deciding at +run time which to generate. + +libxo expands on the idea of printf format strings to make a single +format containing instructions for creating multiple output styles: + + xo_emit("{:blocks/%d}\t{:path/%s}\n", num_blocks, path); + +This line will generate the same text output as the earlier printf +call, but also has enough information to generate XML, JSON, and HTML. + +The following sections introduce the other formats. + +*** XML Output + +XML output consists of a hierarchical set of elements, each encoded +with a start tag and an end tag. The element should be named for data +value that it is encoding: + + <item> + <blocks>36</blocks> + <path>./src</path> + </item> + <item> + <blocks>40</blocks> + <path>./bin</path> + </item> + <item> + <blocks>90</blocks> + <path>.</path> + </item> + +XML is a W3C standard for encoding data. See w3c.org/TR/xml for +additional information. + +*** JSON Output + +JSON output consists of a hierarchical set of objects and lists, each +encoded with a quoted name, a colon, and a value. If the value is a +string, it must be quoted, but numbers are not quoted. Objects are +encoded using braces; lists are encoded using square brackets. +Data inside objects and lists is separated using commas: + + items: [ + { "blocks": 36, "path" : "./src" }, + { "blocks": 40, "path" : "./bin" }, + { "blocks": 90, "path" : "./" } + ] + +*** HTML Output + +HTML output is designed to allow the output to be rendered in a web +browser with minimal effort. Each piece of output data is rendered +inside a <div> element, with a class name related to the role of the +data. By using a small set of class attribute values, a CSS +stylesheet can render the HTML into rich text that mirrors the +traditional text content. + +Additional attributes can be enabled to provide more details about the +data, including data type, description, and an XPath location. + + <div class="line"> + <div class="data" data-tag="blocks">36</div> + <div class="padding"> </div> + <div class="data data-tag="path">./src</div> + </div> + <div class="line"> + <div class="data" data-tag="blocks">40</div> + <div class="padding"> </div> + <div class="data data-tag="path">./bin</div> + </div> + <div class="line"> + <div class="data" data-tag="blocks">90</div> + <div class="padding"> </div> + <div class="data data-tag="path">./</div> + </div> + +** Format Strings @format-strings@ + +libxo uses format strings to control the rendering of data into the +various output styles. Each format string contains a set of zero or +more field descriptions, which describe independent data fields. Each +field description contains a set of modifiers, a content string, and +zero, one, or two format descriptors. The modifiers tell libxo what +the field is and how to treat it, while the format descriptors are +formatting instructions using printf-style format strings, telling +libxo how to format the field. The field description is placed inside +a set of braces, with a colon (":") after the modifiers and a slash +("/") before each format descriptors. Text may be intermixed with +field descriptions within the format string. + +The field description is given as follows: + + '{' [ role | modifier ]* ':' [ content ] + [ '/' field-format [ '/' encoding-format ]] '}' + +The role describes the function of the field, while the modifiers +enable optional behaviors. The contents, field-format, and +encoding-format are used in varying ways, based on the role. These +are described in the following sections. + +In the following example, three field descriptors appear. The first +is a padding field containing three spaces of padding, the second is a +label ("In stock"), and the third is a value field ("in-stock"). The +in-stock field has a "%u" format that will parse the next argument +passed to the xo_emit function as an unsigned integer. + + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", 65); + +This single line of code can generate text (" In stock: 65\n"), XML +("<in-stock>65</in-stock>"), JSON ('"in-stock": 6'), or HTML (too +lengthy to be listed here). + +*** Modifier Roles + +Modifiers are optional, and indicate the role and formatting of the +content. The roles are listed below; only one role is permitted: + +|---+--------------+-------------------------------------------------| +| M | Name | Description | +|---+--------------+-------------------------------------------------| +| D | decoration | Field is non-text (e.g. colon, comma) | +| E | error | Field is an error message | +| L | label | Field is text that prefixes a value | +| N | note | Field is text that follows a value | +| P | padding | Field is spaces needed for vertical alignment | +| T | title | Field is a title value for headings | +| U | units | Field is the units for the previous value field | +| V | value | Field is the name of field (the default) | +| W | warning | Field is a warning message | +| [ | start anchor | Begin a section of anchored variable-width text | +| ] | stop anchor | End a section of anchored variable-width text | +|---+--------------+-------------------------------------------------| + +**** The Decoration Role ({D:}) + +Decorations are typically punctuation marks such as colons, +semi-colons, and commas used to decorate the text and make it simpler +for human readers. By marking these distinctly, HTML usage scenarios +can use CSS to direct their display parameters. + + xo_emit("{D:((}{:name}{D:))}\n", name); + +**** The Label Role ({L:}) + +Labels are text that appears before a value. + + xo_emit("{Lwc:Cost}{:cost/%u}\n", cost); + +**** The Note Role ({N:}) + +Notes are text that appears after a value. + + xo_emit("{:cost/%u} {N:per year}\n", cost); + +**** The Padding Role ({P:}) + +Padding represents whitespace used before and between fields. + +The padding content can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"): + + xo_emit("{P: }{Lwc:Cost}{:cost/%u}\n", cost); + xo_emit("{P:/30s}{Lwc:Cost}{:cost/%u}\n", "", cost); + +**** The Title Role ({T:}) + +Title are heading or column headers that are meant to be displayed to +the user. The title can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"): + + xo_emit("{T:Interface Statistics}\n"); + xo_emit("{T:/%20.20s}{T:/%6.6s}\n", "Item Name", "Cost"); + +**** The Units Role ({U:}) + +Units are the dimension by which values are measured, such as degrees, +miles, bytes, and decibels. The units field carries this information +for the previous value field. + + xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\n", miles); + +Note that the sense of the 'w' modifier is reversed for units; +a blank is added before the contents, rather than after it. + +When the XOF_UNITS flag is set, units are rendered in XML as the +"units" attribute: + + <distance units="miles">50</distance> + +Units can also be rendered in HTML as the "data-units" attribute: + + <div class="data" data-tag="distance" data-units="miles" + data-xpath="/top/data/distance">50</div> + +**** The Value Role ({V:} and {:}) + +The value role is used to represent the a data value that is +interesting for the non-display output styles (XML and JSON). Value +is the default role; if no other role designation is given, the field +is a value. The field name must appear within the field descriptor, +followed by one or two format descriptors. The first format +descriptor is used for display styles (TEXT and HTML), while the +second one is used for encoding styles (XML and JSON). If no second +format is given, the encoding format defaults to the first format, +with any minimum width removed. If no first format is given, both +format descriptors default to "%s". + + xo_emit("{:length/%02u}x{:width/%02u}x{:height/%02u}\n", + length, width, height); + xo_emit("{:author} wrote \"{:poem}\" in {:year/%4d}\n, + author, poem, year); + +**** The Anchor Modifiers ({[:} and {]:}) + +The anchor roles allow a set of strings by be padded as a group, +but still be visible to xo_emit as distinct fields. Either the start +or stop anchor can give a field width and it can be either directly in +the descriptor or passed as an argument. Any fields between the start +and stop anchor are padded to meet the minimum width given. + +To give a width directly, encode it as the content of the anchor tag: + + xo_emit("({[:10}{:min/%d}/{:max/%d}{]:})\n", min, max); + +To pass a width as an argument, use "%d" as the format, which must +appear after the "/". Note that only "%d" is supported for widths. +Using any other value could ruin your day. + + xo_emit("({[:/%d}{:min/%d}/{:max/%d}{]:})\n", width, min, max); + +If the width is negative, padding will be added on the right, suitable +for left justification. Otherwise the padding will be added to the +left of the fields between the start and stop anchors, suitable for +right justification. If the width is zero, nothing happens. If the +number of columns of output between the start and stop anchors is less +than the absolute value of the given width, nothing happens. + +Widths over 8k are considered probable errors and not supported. If +XOF_WARN is set, a warning will be generated. + +*** Modifier Flags + +The modifiers can also include the following flags, which modify the +content emitted for some output styles: + +|---+--------------+-------------------------------------------------| +| M | Name | Description | +|---+--------------+-------------------------------------------------| +| c | colon | A colon (":") is appended after the label | +| d | display | Only emit field for display styles (text/HTML) | +| e | encoding | Only emit for encoding styles (XML/JSON) | +| k | key | Field is a key, suitable for XPath predicates | +| n | no-quotes | Do not quote the field when using JSON style | +| q | quotes | Quote the field when using JSON style | +| w | white space | A blank (" ") is appended after the label | +|---+--------------+-------------------------------------------------| + +For example, the modifier string "Lwc" means the field has a label +role (text that describes the next field) and should be followed by a +colon ('c') and a space ('w'). The modifier string "Vkq" means the +field has a value role, that it is a key for the current instance, and +that the value should be quoted when encoded for JSON. + +**** The Colon Modifier ({c:}) + +The colon modifier appends a single colon to the data value: + + EXAMPLE: + xo_emit("{Lc:Name}{:name}\n", "phil"); + TEXT: + Name:phil + +The colon modifier is only used for the TEXT and HTML output +styles. It is commonly combined with the space modifier ('{w:'). +It is purely a convenience feature. + +**** The Display Modifier ({d:}) + +The display modifier indicated the field should only be generated for +the display output styles, TEXT and HTML. + + EXAMPLE: + xo_emit("{Lcw:Name}{d:name} {:id/%d}\n", "phil", 1); + TEXT: + Name: phil 1 + XML: + <id>1</id> + +The display modifier is the opposite of the encoding modifier, and +they are often used to give to distinct views of the underlying data. + +**** The Encoding Modifier ({e:}) @e-modifier@ + +The display modifier indicated the field should only be generated for +the display output styles, TEXT and HTML. + + EXAMPLE: + xo_emit("{Lcw:Name}{:name} {e:id/%d}\n", "phil", 1); + TEXT: + Name: phil + XML: + <name>phil</name><id>1</id> + +The encoding modifier is the opposite of the display modifier, and +they are often used to give to distinct views of the underlying data. + +**** The Key Modifier ({k:}) + +The key modifier is used to indicate that a particular field helps +uniquely identify an instance of list data. + + EXAMPLE: + xo_open_list("user"); + for (i = 0; i < num_users; i++) { + xo_open_instance("user"); + xo_emit("User {k:name} has {:count} tickets\n", + user[i].u_name, user[i].u_tickets); + xo_close_instance("user"); + } + xo_close_list("user"); + +Currently the key modifier is only used when generating XPath value +for the HTML output style when XOF_XPATH is set, but other uses are +likely in the near future. + +**** The No-Quotes Modifier ({n:}) + +The no-quotes modifier (and its twin, the 'quotes' modifier) affect +the quoting of values in the JSON output style. JSON uses quotes for +string value, but no quotes for numeric, boolean, and null data. +xo_emit applies a simple heuristic to determine whether quotes are +needed, but often this needs to be controlled by the caller. + + EXAMPLE: + const char *bool = is_true ? "true" : "false"; + xo_emit("{n:fancy/%s}", bool); + JSON: + "fancy": true + +**** The Quotes Modifier ({q:}) + +The quotes modifier (and its twin, the 'no-quotes' modifier) affect +the quoting of values in the JSON output style. JSON uses quotes for +string value, but no quotes for numeric, boolean, and null data. +xo_emit applies a simple heuristic to determine whether quotes are +needed, but often this needs to be controlled by the caller. + + EXAMPLE: + xo_emit("{q:time/%d}", 2014); + JSON: + "year": "2014" + +**** The White Space Modifier ({w:}) + +The white space modifier appends a single space to the data value: + + EXAMPLE: + xo_emit("{Lw:Name}{:name}\n", "phil"); + TEXT: + Name phil + +The white space modifier is only used for the TEXT and HTML output +styles. It is commonly combined with the colon modifier ('{c:'). +It is purely a convenience feature. + +Note that the sense of the 'w' modifier is reversed for the units role +({Uw:}); a blank is added before the contents, rather than after it. + +*** Field Formatting + +The field format is similar to the format string for printf(3). It's +used varies based on the role of the field, but generally is used to +format the field's contents. + +If not provided, the format string defaults to "%s". + +Note a field definition can contain zero or more printf-style +'directives', which are sequences that start with a '%' and end with a +one of following characters: "diouxXDOUeEfFgGaAcCsSp". Each directive +is matched by one of more arguments to the xo_emit function. + +The format string has the form: + + '%' format-modifier * format-character + +The format- modifier can be: +- a '#' character, indicating the output value should be prefixed with +'0x', typically to indicate a base 16 (hex) value. +- a minus sign ('-'), indicating the output value should be padded on +the right instead of the left. +- a leading zero ('0') indicating the output value should be padded on the +left with zeroes instead of spaces (' '). +- one or more digits ('0' - '9') indicating the minimum width of the +argument. If the width in columns of the output value is less that +the minumum width, the value will be padded to reach the minimum. +- a period followed by one or more digits indicating the maximum +number of bytes which will be examined for a string argument, or the maximum +width for a non-string argument. When handling ASCII strings this is +functions as the field width but for multi-byte characters, a single +character may be composed of multiple bytes. +xo_emit will never dereference memory beyond the given number of bytes. +- a second period followed by one or more digits indicating the maximum +width for a string argument. This modifier cannot be given for non-string +arguments. +- one or more 'h' characters, indicating shorter input data. +- one or more 'l' characters, indicating longer input data. +- a 'z' character, indicating a 'size_t' argument. +- a 't' character, indicating a 'ptrdiff_t' argument. +- a ' ' character, indicating a space should be emitted before +positive numbers. +- a '+' character, indicating sign should emitted before any number. + +Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be +removed eventually. + +The format character is described in the following table: + +|-----+-----------------+----------------------| +| Ltr | Argument Type | Format | +|-----+-----------------+----------------------| +| d | int | base 10 (decimal) | +| i | int | base 10 (decimal) | +| o | int | base 8 (octal) | +| u | unsigned | base 10 (decimal) | +| x | unsigned | base 16 (hex) | +| X | unsigned long | base 16 (hex) | +| D | long | base 10 (decimal) | +| O | unsigned long | base 8 (octal) | +| U | unsigned long | base 10 (decimal) | +| e | double | [-]d.ddde+-dd | +| E | double | [-]d.dddE+-dd | +| f | double | [-]ddd.ddd | +| F | double | [-]ddd.ddd | +| g | double | as 'e' or 'f' | +| G | double | as 'E' or 'F' | +| a | double | [-]0xh.hhhp[+-]d | +| A | double | [-]0Xh.hhhp[+-]d | +| c | unsigned char | a character | +| C | wint_t | a character | +| s | char * | a UTF-8 string | +| S | wchar_t * | a unicode/WCS string | +| p | void * | '%#lx' | +|-----+-----------------+----------------------| + +The 'h' and 'l' modifiers affect the size and treatment of the +argument: + +|-----+-------------+--------------------| +| Mod | d, i | o, u, x, X | +|-----+-------------+--------------------| +| hh | signed char | unsigned char | +| h | short | unsigned short | +| l | long | unsigned long | +| ll | long long | unsigned long long | +| j | intmax_t | uintmax_t | +| t | ptrdiff_t | ptrdiff_t | +| z | size_t | size_t | +| q | quad_t | u_quad_t | +|-----+-------------+--------------------| + +*** UTF-8 and Locale Strings + +For strings, the 'h' and 'l' modifiers affect the interpretation of +the bytes pointed to argument. The default '%s' string is a 'char *' +pointer to a string encoded as UTF-8. Since UTF-8 is compatible with +ASCII data, a normal 7-bit ASCII string can be used. '%ls' expects a +'wchar_t *' pointer to a wide-character string, encoded as a 32-bit +Unicode values. '%hs' expects a 'char *' pointer to a multi-byte +string encoded with the current locale, as given by the LC_CTYPE, +LANG, or LC_ALL environment varibles. The first of this list of +variables is used and if none of the variables, the locale defaults to +"UTF-8". + +For example, a function is passed a locale-base name, a hat size, +and a time value. The hat size is formatted in a UTF-8 (ASCII) +string, and the time value is formatted into a wchar_t string. + + void print_order (const char *name, int size, + struct tm *timep) { + char buf[32]; + const char *size_val = "unknown"; + + if (size > 0) + snprintf(buf, sizeof(buf), "%d", size); + size_val = buf; + } + + wchar_t when[32]; + wcsftime(when, sizeof(when), L"%d%b%y", timep); + + xo_emit("The hat for {:name/%hs} is {:size/%s}.\n", + name, size_val); + xo_emit("It was ordered on {:order-time/%ls}.\n", + when); + } + +It is important to note that xo_emit will perform the conversion +required to make appropriate output. Text style output uses the +current locale (as described above), while XML, JSON, and HTML use +UTF-8. + +UTF-8 and locale-encoded strings can use multiple bytes to encode one +column of data. The traditional "precision'" (aka "max-width") value +for "%s" printf formatting becomes overloaded since it specifies both +the number of bytes that can be safely referenced and the maximum +number of columns to emit. xo_emit uses the precision as the former, +and adds a third value for specifying the maximum number of columns. + +In this example, the name field is printed with a minimum of 3 columns +and a maximum of 6. Up to ten bytes are in used in filling those +columns. + + xo_emit("{:name/%3.10.6s}", name); + +*** Characters Outside of Field Definitions + +Characters in the format string are not part of a field definition are +copied to the output for the TEXT style, and are ignored for the JSON +and XML styles. For HTML, these characters are placed in a <div> with +class "text". + + EXAMPLE: + xo_emit("The hat is {:size/%s}.\n", size_val); + TEXT: + The hat is extra small. + XML: + <size>extra small</size> + JSON: + "size": "extra small" + HTML: + <div class="text">The hat is </div> + <div class="data" data-tag="size">extra small</div> + <div class="text">.</div> + +*** "%n" is Not Supported + +libxo does not support the '%n' directive. It's a bad idea and we +just don't do it. + +*** The Encoding Format (eformat) + +The "eformat" string is the format string used when encoding the field +for JSON and XML. If not provided, it defaults to the primary format +with any minimum width removed. If the primary is not given, both +default to "%s". + +*** Content Strings + +For padding and labels, the content string is considered the content, +unless a format is given. + +*** Example + +In this example, the value for the number of items in stock is emitted: + + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", + instock); + +This call will generate the following output: + + TEXT: + In stock: 144 + XML: + <in-stock>144</in-stock> + JSON: + "in-stock": 144, + HTML: + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">144</div> + </div> + +Clearly HTML wins the verbosity award, and this output does +not include XOF_XPATH or XOF_INFO data, which would expand the +penultimate line to: + + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" + data-type="number" + data-help="Number of items in stock">144</div> + +** Command-line Arguments + +libxo uses command line options to trigger rendering behavior. The +following options are recognised: + +- --libxo <options> +- --libxo=<options> +- --libxo:<brief-options> + +Options is a comma-separated list of tokens that correspond to output +styles, flags, or features: + +|-----------+-------------------------------------------------------| +| Token | Action | +|-----------+-------------------------------------------------------| +| dtrt | Enable "Do The Right Thing" mode | +| html | Emit HTML output | +| indent=xx | Set the indentation level | +| info | Add info attributes (HTML) | +| json | Emit JSON output | +| keys | Emit the key attribute for keys (XML) | +| no-locale | Do not initialize the locale setting | +| no-top | Do not emit a top set of braces (JSON) | +| not-first | Pretend the 1st output item was not 1st (JSON) | +| pretty | Emit pretty-printed output | +| text | Emit TEXT output | +| units | Add the 'units' (XML) or 'data-units (HTML) attribute | +| warn | Emit warnings when libxo detects bad calls | +| warn-xml | Emit warnings in XML | +| xml | Emit XML output | +| xpath | Add XPath expressions (HTML) | +|-----------+-------------------------------------------------------| + +The brief options are detailed in ^LIBXO_OPTIONS^. + +** Representing Hierarchy + +For XML and JSON, individual fields appear inside hierarchies which +provide context and meaning to the fields. Unfortunately, these +encoding have a basic disconnect between how lists is similar objects +are represented. + +XML encodes lists as set of sequential elements: + + <user>phil</user> + <user>pallavi</user> + <user>sjg</user> + +JSON encodes lists using a single name and square brackets: + + "user": [ "phil", "pallavi", "sjg" ] + +This means libxo needs three distinct indications of hierarchy: one +for containers of hierarchy appear only once for any specific parent, +one for lists, and one for each item in a list. + +*** Containers + +A "container" is an element of a hierarchy that appears only once +under any specific parent. The container has no value, but serves to +contain other nodes. + +To open a container, call xo_open_container() or +xo_open_container_h(). The former uses the default handle and +the latter accepts a specific handle. + + int xo_open_container_h (xo_handle_t *xop, const char *name); + int xo_open_container (const char *name); + +To close a level, use the xo_close_container() or +xo_close_container_h() functions: + + int xo_close_container_h (xo_handle_t *xop, const char *name); + int xo_close_container (const char *name); + +Each open call must have a matching close call. If the XOF_WARN flag +is set and the name given does not match the name of the currently open +container, a warning will be generated. + + Example: + + xo_open_container("top"); + xo_open_container("system"); + xo_emit("{:host-name/%s%s%s", hostname, + domainname ? "." : "", domainname ?: ""); + xo_close_container("system"); + xo_close_container("top"); + + Sample Output: + Text: + my-host.example.org + XML: + <top> + <system> + <host-name>my-host.example.org</host-name> + </system> + </top> + JSON: + "top" : { + "system" : { + "host-name": "my-host.example.org" + } + } + HTML: + <div class="data" + data-tag="host-name">my-host.example.org</div> + +*** Lists and Instances + +A list is set of one or more instances that appear under the same +parent. The instances contains details about a specific object. One +can think of instances as objects or records. A call is needed to +open and close the list, while a distinct call is needed to open and +close each instance of the list: + + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); + xo_close_instance("item"); + } + + xo_close_list("item"); + +Getting the list and instance calls correct is critical to the proper +generation of XML and JSON data. + +*** DTRT Mode + +Some user may find tracking the names of open containers, lists, and +instances inconvenient. libxo offers "Do The Right Thing" mode, where +libxo will track the names of open containers, lists, and instances so +the close function can be called without a name. To enable DTRT mode, +turn on the XOF_DTRT flag prior to making any other libxo output. + + xo_set_flags(NULL, XOF_DTRT); + +Each open and close function has a version with the suffix "_d", which +will close the open container, list, or instance: + + xo_open_container("top"); + ... + xo_close_container_d(); + +Note that the XOF_WARN flag will also cause libxo to track open +containers, lists, and instances. A warning is generated with the +name given to the close function and the name recorded do not match. + +** Handles + +libxo uses "handles" to control its rendering functionality. The +handle contains state and buffered data, as well as callback functions +to process data. + +A default handle is used when a NULL is passed to functions accepting +a handle. This handle is initialized to write its data to stdout +using the default style of text (XO_STYLE_TEXT). + +For the convenience of callers, the libxo library includes handle-less +functions that implicitly use the default handle. Any function that +takes a handle will use the default handle is a value of NULL is +passed in place of a valid handle. + +For example, the following are equivalent: + + xo_emit("test"); + xo_emit_h(NULL, "test"); + +Handles are created using xo_create() and destroy using xo_destroy(). + +** UTF-8 + +All strings for libxo must be UTF-8. libxo will handle turning them +into locale-based strings for display to the user. + +The only exception is argument formatted using the "%ls" format, which +require a wide character string (wchar_t *) as input. libxo will +convert these arguments as needed to either UTF-8 (for XML, JSON, and +HTML styles) or locale-based strings for display in text style. + + xo_emit("Alll strings are utf-8 content {:tag/%ls}", + L"except for wide strings"); + +"%S" is equivalent to "%ls". + +* The libxo API + +This section gives details about the functions in libxo, how to call +them, and the actions they perform. + +** Handles + +Handles give an abstraction for libxo that encapsulates the state of a +stream of output. Handles have the data type "xo_handle_t" and are +opaque to the caller. + +The library has a default handle that is automatically initialized. +By default, this handle will send text style output to standard output. +The xo_set_style and xo_set_flags functions can be used to change this +behavior. + +Many libxo functions take a handle as their first parameter; most that +do not use the default handle. Any function taking a handle can +be passed NULL to access the default handle. + +For the typical command that is generating output on standard output, +there is no need to create an explicit handle, but they are available +when needed, e.g. for daemons that generate multiple streams of +output. + +*** xo_create + +A handle can be allocated using the xo_create() function: + + xo_handle_t *xo_create (unsigned style, unsigned flags); + + Example: + xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN); + .... + xo_emit_h(xop, "testing\n"); + +See also ^styles^ and ^flags^. + +*** xo_create_to_file + +By default, libxo writes output to standard output. A convenience +function is provided for situations when output should be written to +different file: + + xo_handle_t *xo_create_to_file (FILE *fp, unsigned style, + unsigned flags); + +Use the XOF_CLOSE_FP flag to trigger a call to fclose() for +the FILE pointer when the handle is destroyed. + +*** xo_set_writer + +The xo_set_writer function allows custom 'write' functions +which can tailor how libxo writes data. An opaque argument is +recorded and passed back to the write function, allowing the function +to acquire context information. The 'close' function can +release this opaque data and any other resources as needed. + + void xo_set_writer (xo_handle_t *xop, void *opaque, + xo_write_func_t write_func, + xo_close_func_t close_func); + +*** xo_set_style + +To set the style, use the xo_set_style() function: + + void xo_set_style(xo_handle_t *xop, unsigned style); + +To use the default handle, pass a NULL handle: + + xo_set_style(NULL, XO_STYLE_XML); + +**** Output Styles (XO_STYLE_*) @styles@ + +The libxo functions accept a set of output styles: + +|---------------+-------------------------| +| Flag | Description | +|---------------+-------------------------| +| XO_STYLE_TEXT | Traditional text output | +| XO_STYLE_XML | XML encoded data | +| XO_STYLE_JSON | JSON encoded data | +| XO_STYLE_HTML | HTML encoded data | +|---------------+-------------------------| + +**** xo_set_style_name + +The xo_set_style_name() can be used to set the style based on a name +encoded as a string: + + int xo_set_style_name (xo_handle_t *xop, const char *style); + +The name can be any of the styles: "text", "xml", "json", or "html". + + EXAMPLE: + xo_set_style_name(NULL, "html"); + +*** xo_set_flags + +To set the flags, use the xo_set_flags() function: + + void xo_set_flags(xo_handle_t *xop, unsigned flags); + +To use the default handle, pass a NULL handle: + + xo_set_style(NULL, XO_STYLE_XML); + +**** Flags (XOF_*) @flags@ + +The set of valid flags include: + +|-----------------+---------------------------------------| +| Flag | Description | +|-----------------+---------------------------------------| +| XOF_CLOSE_FP | Close file pointer on xo_destroy() | +| XOF_DTRT | Enable "do the right thing" mode | +| XOF_INFO | Display info data attributes (HTML) | +| XOF_KEYS | Emit the key attribute (XML) | +| XOF_NO_ENV | Do not use the LIBXO_OPTIONS env var | +| XOF_PRETTY | Make 'pretty printed' output | +| XOF_UNDERSCORES | Replaces hyphens with underscores | +| XOF_UNITS | Display units (XML and HMTL) | +| XOF_WARN | Generate warnings for broken calls | +| XOF_WARN_XML | Generate warnings in XML on stdout | +| XOF_XPATH | Emit XPath expressions (HTML) | +| XOF_COLUMNS | Force xo_emit to return columns used | +| XOF_FLUSH | Flush output after each xo_emit call | +|-----------------+---------------------------------------| + +The XOF_CLOSE_FP flag will trigger the call of the close_func +(provided via xo_set_writer()) when the handle is destroyed. + +The XOF_PRETTY flag requests 'pretty printing', which will trigger the +addition of indentation and newlines to enhance the readability of +XML, JSON, and HTML output. Text output is not affected. + +The XOF_WARN flag requests that warnings will trigger diagnostic +output (on standard error) when the library notices errors during +operations, or with arguments to functions. Without warning enabled, +such conditions are ignored. + +Warnings allow developers to debug their interaction with libxo. +The function "xo_failure" can used as a breakpoint for a debugger, +regardless of whether warnings are enabled. + +If the style is XO_STYLE_HTML, the following additional flags can be +used: + +|---------------+-----------------------------------------| +| Flag | Description | +|---------------+-----------------------------------------| +| XOF_XPATH | Emit "data-xpath" attributes | +| XOF_INFO | Emit additional info fields | +|---------------+-----------------------------------------| + +The XOF_XPATH flag enables the emission of XPath expressions detailing +the hierarchy of XML elements used to encode the data field, if the +XPATH style of output were requested. + +The XOF_INFO flag encodes additional informational fields for HTML +output. See ^info^ for details. + +If the style is XO_STYLE_XML, the following additional flags can be +used: + +|---------------+-----------------------------------------| +| Flag | Description | +|---------------+-----------------------------------------| +| XOF_KEYS | Flag 'key' fields for xml | +|---------------+-----------------------------------------| + +The XOF_KEYS flag adds 'key' attribute to the XML encoding for +field definitions that use the 'k' modifier. The key attribute has +the value "key": + + xo_emit("{k:name}", item); + + XML: + <name key="key">truck</name> + +**** xo_clear_flags + +The xo_clear_flags() function turns off the given flags in a specific +handle. + + void xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags); + +**** xo_set_options + +The xo_set_options() function accepts a comma-separated list of styles +and flags and enables them for a specific handle. + + int xo_set_options (xo_handle_t *xop, const char *input); + +The options are identical to those listed in ^command-line-arguments^. + +*** xo_destroy + +The xo_destroy function releases a handle and any resources it is +using. Calling xo_destroy with a NULL handle will release any +resources associated with the default handle. + + void xo_destroy(xo_handle_t *xop); + +** Emitting Content (xo_emit) + +The following functions are used to emit output: + + int xo_emit (const char *fmt, ...); + int xo_emit_h (xo_handle_t *xop, const char *fmt, ...); + int xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap); + +The "fmt" argument is a string containing field descriptors as +specified in ^format-strings^. The use of a handle is optional and +NULL can be passed to access the internal 'default' handle. See +^handles^. + +The remaining arguments to xo_emit() and xo_emit_h() are a set of +arguments corresponding to the fields in the format string. Care must +be taken to ensure the argument types match the fields in the format +string, since an inappropriate cast can ruin your day. The vap +argument to xo_emit_hv() points to a variable argument list that can +be used to retrieve arguments via va_arg(). + +*** Attributes (xo_attr) @xo_attr@ + +The xo_attr() function emits attributes for the XML output style. + + + int xo_attr (const char *name, const char *fmt, ...); + int xo_attr_h (xo_handle_t *xop, const char *name, + const char *fmt, ...); + int xo_attr_hv (xo_handle_t *xop, const char *name, + const char *fmt, va_list vap); + +The name parameter give the name of the attribute to be encoded. The +fmt parameter gives a printf-style format string used to format the +value of the attribute using any remaining arguments, or the vap +parameter passed to xo_attr_hv(). + + EXAMPLE: + xo_attr("seconds", "%ld", (unsigned long) login_time); + struct tm *tmp = localtime(login_time); + strftime(buf, sizeof(buf), "%R", tmp); + xo_emit("Logged in at {:login-time}\n", buf); + XML: + <login-time seconds="1408336270">00:14</login-time> + +*** Flushing Output (xo_flush) + +libxo buffers data, both for performance and consistency, but also to +allow some advanced features to work properly. At various times, the +caller may wish to flush any data buffered within the library. The +xo_flush() call is used for this: + + void xo_flush (void); + void xo_flush_h (xo_handle_t *xop); + +*** Finishing Output (xo_finish) + +When the program is ready to exit or close a handle, a call to +xo_finish() is required. This flushes any buffered data, closes +open libxo constructs, and completes any pending operations. + + void xo_finish (void); + void xo_finish_h (xo_handle_t *xop); + +Calling this function is vital to the proper operation of libxo, +especially for the non-TEXT output styles. + +** Emitting Hierarchy + +libxo represents to types of hierarchy: containers and lists. A +container appears once under a given parent where a list contains +instances that can appear multiple times. A container is used to hold +related fields and to give the data organization and scope. + +To create a container, use the xo_open_container and +xo_close_container functions: + + int xo_open_container (const char *name); + int xo_open_container_h (xo_handle_t *xop, const char *name); + int xo_open_container_hd (xo_handle_t *xop, const char *name); + int xo_open_container_d (const char *name); + + int xo_close_container (const char *name); + int xo_close_container_h (xo_handle_t *xop, const char *name); + int xo_close_container_hd (xo_handle_t *xop); + int xo_close_container_d (void); + +The name parameter gives the name of the container, encoded in UTF-8. +Since ASCII is a proper subset of UTF-8, traditional C strings can be +used directly. + +The close functions with the "_d" suffix are used in "Do The Right +Thing" mode, where the name of the open containers, lists, and +instances are maintained internally by libxo to allow the caller to +avoid keeping track of the open container name. + +Use the XOF_WARN flag to generate a warning if the name given on the +close does not match the current open container. + +For TEXT and HTML output, containers are not rendered into output +text, though for HTML they are used when the XOF_XPATH flag is set. + + EXAMPLE: + xo_open_container("system"); + xo_emit("The host name is {:host-name}\n", hn); + xo_close_container("system"); + XML: + <system><host-name>foo</host-name></system> + +*** Lists and Instances + +Lists are sequences of instances of homogeneous data objects. Two +distinct levels of calls are needed to represent them in our output +styles. Calls must be made to open and close a list, and for each +instance of data in that list, calls must be make to open and close +that instance. + +The name given to all calls must be identical, and it is strong +suggested that the name be singular, not plural, as a matter of +style and usage expectations. + + EXAMPLE: + xo_open_list("user"); + for (i = 0; i < num_users; i++) { + xo_open_instance("user"); + xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n", + pw[i].pw_name, pw[i].pw_uid, + pw[i].pw_gid, pw[i].pw_dir); + xo_close_instance("user"); + } + xo_close_list("user"); + TEXT: + phil:1001:1001:/home/phil + pallavi:1002:1002:/home/pallavi + XML: + <user> + <name>phil</name> + <uid>1001</uid> + <gid>1001</gid> + <home>/home/phil</home> + </user> + <user> + <name>pallavi</name> + <uid>1002</uid> + <gid>1002</gid> + <home>/home/pallavi</home> + </user> + JSON: + user: [ + { + "name": "phil", + "uid": 1001, + "gid": 1001, + "home": "/home/phil", + }, + { + "name": "pallavi", + "uid": 1002, + "gid": 1002, + "home": "/home/pallavi", + } + ] + +** Additional Functionality + +*** Parsing Command-line Arguments (xo_parse_args) + +The xo_parse_args() function is used to process a program's +arguments. libxo-specific options are processed and removed +from the argument list so the calling application does not +need to process them. If successful, a new value for argc +is returned. On failure, a message it emitted and -1 is returned. + + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); + +Following the call to xo_parse_args, the application can process the +remaining arguments in a normal manner. See ^command-line-arguments^ +for a description of valid arguments. + +*** Field Information (xo_info_t) @info@ + +HTML data can include additional information in attributes that +begin with "data-". To enable this, three things must occur: + +First the application must build an array of xo_info_t structures, +one per tag. The array must be sorted by name, since libxo uses a +binary search to find the entry that matches names from format +instructions. + +Second, the application must inform libxo about this information using +the xo_set_info() call: + + typedef struct xo_info_s { + const char *xi_name; /* Name of the element */ + const char *xi_type; /* Type of field */ + const char *xi_help; /* Description of field */ + } xo_info_t; + + void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count); + +Like other libxo calls, passing NULL for the handle tells libxo to use +the default handle. + +If the count is -1, libxo will count the elements of infop, but there +must be an empty element at the end. More typically, the number is +known to the application: + + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + }; + int info_count = (sizeof(info) / sizeof(info[0])); + ... + xo_set_info(NULL, info, info_count); + +Third, the emitting of info must be triggered with the XOF_INFO flag +using either the xo_set_flags() function or the "--libxo=info" command +line argument. + +The type and help values, if present, are emitted as the "data-type" +and "data-help" attributes: + + <div class="data" data-tag="sku" data-type="string" + data-help="Stock Keeping Unit">GRO-000-533</div> + +*** Memory Allocation + +The xo_set_allocator function allows libxo to be used in environments +where the standard realloc() and free() functions are not available. + + void xo_set_allocator (xo_realloc_func_t realloc_func, + xo_free_func_t free_func); + +realloc_func should expect the same arguments as realloc(3) and return +a pointer to memory following the same convention. free_func will +receive the same argument as free(3) and should release it, as +appropriate for the environment. + +By default, the standard realloc() and free() functions are used. + +*** LIBXO_OPTIONS @LIBXO_OPTIONS@ + +The environment variable "LIBXO_OPTIONS" can be set to a string of +options: + +|--------+-------------------------------------------| +| Option | Action | +|--------+-------------------------------------------| +| H | Enable HTML output (XO_STYLE_HTML) | +| I | Enable info output (XOF_INFO) | +| i<num> | Indent by <number> | +| J | Enable JSON output (XO_STYLE_JSON) | +| P | Enable pretty-printed output (XOF_PRETTY) | +| T | Enable text output (XO_STYLE_TEXT) | +| W | Enable warnings (XOF_WARN) | +| X | Enable XML output (XO_STYLE_XML) | +| x | Enable XPath data (XOF_XPATH) | +|--------+-------------------------------------------| + +For example, warnings can be enabled by: + + % env LIBXO_OPTIONS=W my-app + +Complete HTML output can be generated with: + + % env LIBXO_OPTIONS=HXI my-app + +*** Errors, Warnings, and Messages + +Many programs make use of the standard library functions err() and +warn() to generate errors and warnings for the user. libxo wants to +pass that information via the current output style, and provides +compatible functions to allow this: + + void xo_warn (const char *fmt, ...); + void xo_warnx (const char *fmt, ...); + void xo_warn_c (int code, const char *fmt, ...); + void xo_warn_hc (xo_handle_t *xop, int code, + const char *fmt, ...); + void xo_err (int eval, const char *fmt, ...); + void xo_errc (int eval, int code, const char *fmt, ...); + void xo_errx (int eval, const char *fmt, ...); + void xo_message (const char *fmt, ...); + void xo_message_c (int code, const char *fmt, ...); + void xo_message_hc (xo_handle_t *xop, int code, + const char *fmt, ...); + void xo_message_hcv (xo_handle_t *xop, int code, + const char *fmt, va_list vap); + +These functions display the program name, a colon, a formatted message +based on the arguments, and then optionally a colon and an error +message associated with either "errno" or the "code" parameter. + + EXAMPLE: + if (open(filename, O_RDONLY) < 0) + xo_err(1, "cannot open file '%s'", filename); + +*** xo_no_setlocale + +libxo automatically initializes the locale based on setting of the +environment variables LC_CTYPE, LANG, and LC_ALL. The first of this +list of variables is used and if none of the variables, the locale +defaults to "UTF-8". The caller may wish to avoid this behavior, and +can do so by calling the xo_no_setlocale() function. + + void xo_no_setlocale (void); + +* The "xo" Utility + +The "xo" utility allows command line access to the functionality of +the libxo library. Using "xo", shell scripts can emit XML, JSON, and +HTML using the same commands that emit text output. + +The style of output can be selected using a specific option: "-X" for +XML, "-J" for JSON, "-H" for HTML, or "-T" for TEXT, which is the +default. The "--style <style>" option can also be used. The +LIBXO_OPTIONS environment variable can also be used to set the style, +as well as other flags. + +The "xo" utility accepts a format string suitable for xo_emit() and a +set of zero or more arguments used to supply data for that string. + + xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6 + + TEXT: + The fish weighs 6 pounds. + XML: + <name>fish</name> + <weight>6</weight> + JSON: + "name": "fish", + "weight": 6 + HTML: + <div class="line"> + <div class="text">The </div> + <div class="data" data-tag="name">fish</div> + <div class="text"> weighs </div> + <div class="data" data-tag="weight">6</div> + <div class="text"> pounds.</div> + </div> + +The "--wrap <path>" option can be used to wrap emitted content in a +specific hierarchy. The path is a set of hierarchical names separated +by the '/' character. + + xo --wrap top/a/b/c '{:tag}' value + + XML: + <top> + <a> + <b> + <c> + <tag>value</tag> + </c> + </b> + </a> + </top> + JSON: + "top": { + "a": { + "b": { + "c": { + "tag": "value" + } + } + } + } + +The "--open <path>" and "--close <path>" can be used to emit +hierarchical information without the matching close and open +tag. This allows a shell script to emit open tags, data, and +then close tags. The "--depth" option may be used to set the +depth for indentation. The "--leading-xpath" may be used to +prepend data to the XPath values used for HTML output style. + + #!/bin/sh + xo --open top/data + xo --depth 2 '{tag}' value + xo --close top/data + XML: + <top> + <data> + <tag>value</tag> + </data> + </top> + JSON: + "top": { + "data": { + "tag": "value" + } + } + +** Command Line Options + +Usage: xo [options] format [fields] + --close <path> Close tags for the given path + --depth <num> Set the depth for pretty printing + --help Display this help text + --html OR -H Generate HTML output + --json OR -J Generate JSON output + --leading-xpath <path> Add a prefix to generated XPaths (HTML) + --open <path> Open tags for the given path + --pretty OR -p Make 'pretty' output (add indent, newlines) + --style <style> Generate given style (xml, json, text, html) + --text OR -T Generate text output (the default style) + --version Display version information + --warn OR -W Display warnings in text on stderr + --warn-xml Display warnings in xml on stdout + --wrap <path> Wrap output in a set of containers + --xml OR -X Generate XML output + --xpath Add XPath data to HTML output); + +** Example + + % xo 'The {:product} is {:status}\n' stereo "in route" + The stereo is in route + % ./xo/xo -p -X 'The {:product} is {:status}\n' stereo "in route" + <product>stereo</product> + <status>in route</status> + +* xolint + +xolint is a tool for reporting common mistakes in format strings +in source code that invokes xo_emit(). It allows these errors +to be diagnosed at build time, rather than waiting until runtime. + +xolint takes the one or more C files as arguments, and reports +and errors, warning, or informational messages as needed. + +|------------+---------------------------------------------------| +| Option | Meaning | +|------------+---------------------------------------------------| +| -c | Invoke 'cpp' against the input file | +| -C <flags> | Flags that are passed to 'cpp | +| -d | Enable debug output | +| -D | Generate documentation for all xolint messages | +| -I | Generate info table code | +| -p | Print the offending lines after the message | +| -V | Print vocabulary of all field names | +| -X | Extract samples from xolint, suitable for testing | +|------------+---------------------------------------------------| + +Output message contain the source filename and line number, the +class of the message, the message, and, if -p is given, the +line that contains the error: + + % xolint.pl -t xolint.c + xolint.c: 16: error: anchor format should be "%d" + 16 xo_emit("{[:/%s}"); + +The "-I" option will generate a table of xo_info_t structures , + +The "-V" option does not report errors, but prints a complete list of +all field names, sorted alphabetically. The output can help spot +inconsistencies and spelling errors. + +* FAQs + +This section contains the set of questions that users typically ask, +along with answers that might be helpful. + +!! list-sections + +** General + +*** Can you share the history of libxo? + +In 2001, we added an XML API to the JUNOS operating system, which is +built on top of FreeBSD. Eventually this API became standardized as +the NETCONF API (RFC 6241). As part of this effort, we modified many +FreeBSD utilities to emit XML, typically via a "-X" switch. The +results were mixed. The cost of maintaining this code, updating it +and carrying it were non-trivial, and contributed to our expense (and +the associated delay) with upgrading the version of FreeBSD on which +each release of JUNOS is based. + +A recent (2014) effort within JUNOS aims at removing our modifications +to the underlying FreeBSD code as a means of reducing the expense and +delay. JUNOS is structured to have system components generate XML +that is rendered by the CLI (think: login shell) into human-readable +text. This allows the API to use the same plumbing as the CLI, and +ensures that all components emit XML, and that it is emitted with +knowledge of the consumer of that XML, yielding an API that have no +incremental cost or feature delay. + +libxo is an effort to mix the best aspects of the JUNOS strategy into +FreeBSD in a seemless way, allowing commands to make printf-like +output calls without needing to care how the output is rendered. + +*** What makes a good field name? + +To make useful, consistent field names, follow these guidelines: + += Use lower case, even for TLAs +Lower case is more civilized. Even TLAs should be lower case +to avoid scenarios where the differences between "XPath" and +"Xpath" drive your users crazy. Using "xpath" is simpler and better. += Use hyphens, not underscores +Use of hyphens is traditional in XML, and the XOF_UNDERSCORES +flag can be used to generate underscores in JSON, if desired. +But the raw field name should use hyphens. += Use full words +Don't abbreviate especially when the abbreviation is not obvious or +not widely used. Use "data-size", not "dsz" or "dsize". Use +"interface" instead of "ifname", "if-name", "iface", "if", or "intf". += Use <verb>-<units> +Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in +making consistent, useful names, avoiding the situation where one app +uses "sent-packet" and another "packets-sent" and another +"packets-we-have-sent". The <units> can be dropped when it is +obvious, as can obvious words in the classification. +Use "receive-after-window-packets" instead of +"received-packets-of-data-after-window". += Reuse existing field names +Nothing's worse than writing expressions like: + + if ($src1/process[pid == $pid]/name == + $src2/proc-table/proc/p[process-id == $pid]/proc-name) { + ... + } + +Find someone else who is expressing similar data and follow their +field's and hierarchy. Remember the quote is not "Consistency is the +hobgoblin of little minds", but "A foolish consistency is the +hobgoblin of little minds". += Think about your users +Have empathy for your users, choosing clear and useful fields that +contain clear and useful data. You may need to augment the display +content with xo_attr() calls (^xo_attr^) or "{e:}" fields +(^e-modifier^) to make the data useful. += Don't use an arbitrary number postfix +What does "errors2" mean? No one will know. "errors-after-restart" +would be a better choice. Think of you users, and think of the +future. If you make "errors2", the next guy will happily make +"errors3" and before you know it, someone will be asking what's the +difference between errors37 and errors63. += Be consistent, uniform, unsurprising, and predictable +Think of your field vocabulary as an API. You want it useful, +expressive, meaningful, direct, and obvious. You want the client +application's programmer to move between without the need to +understand a variety of opinions on how fields are named. They should +see the system as a single cohesive whole, not a sack of cats. + +Field names constitute the means by which client programmers interact +with our system. By choosing wise names now, you are making their +lives better. + +After using "xolint" to find errors in your field descriptors, use +"xolint -V" to spell check your field names and to detect different +names for the same data. "dropped-short" and "dropped-too-short" are +both reasonable names, but using them both will lead users to ask the +difference between the two fields. If there isn't a difference, +use only one of the field names. If there is a difference, change the +names to make that difference more obvious. + +** What does this message mean? + +!!include-file xolint.txt + +* Examples + +** Unit Test + +Here is the unit test example: + + int + main (int argc, char **argv) + { + static char base_grocery[] = "GRO"; + static char base_hardware[] = "HRD"; + struct item { + const char *i_title; + int i_sold; + int i_instock; + int i_onorder; + const char *i_sku_base; + int i_sku_num; + }; + struct item list[] = { + { "gum", 1412, 54, 10, base_grocery, 415 }, + { "rope", 85, 4, 2, base_hardware, 212 }, + { "ladder", 0, 2, 1, base_hardware, 517 }, + { "bolt", 4123, 144, 42, base_hardware, 632 }, + { "water", 17, 14, 2, base_grocery, 2331 }, + { NULL, 0, 0, 0, NULL, 0 } + }; + struct item list2[] = { + { "fish", 1321, 45, 1, base_grocery, 533 }, + }; + struct item *ip; + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + { NULL, NULL, NULL }, + }; + int info_count = (sizeof(info) / sizeof(info[0])) - 1; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); + + xo_set_info(NULL, info, info_count); + + xo_open_container_h(NULL, "top"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", + ip->i_instock); + xo_emit("{P: }{Lwc:On order}{:on-order/%u}\n", + ip->i_onorder); + xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list2; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", + ip->i_instock); + xo_emit("{P: }{Lwc:On order}{:on-order/%u}\n", + ip->i_onorder); + xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_close_container_h(NULL, "top"); + + return 0; + } + +Text output: + + % ./testxo --libxo text + Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 + Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 + Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 + Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 + Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 + Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 + +JSON output: + + % ./testxo --libxo json,pretty + "top": { + "data": { + "item": [ + { + "name": "gum", + "sold": 1412.0, + "in-stock": 54, + "on-order": 10, + "sku": "GRO-000-415" + }, + { + "name": "rope", + "sold": 85.0, + "in-stock": 4, + "on-order": 2, + "sku": "HRD-000-212" + }, + { + "name": "ladder", + "sold": 0, + "in-stock": 2, + "on-order": 1, + "sku": "HRD-000-517" + }, + { + "name": "bolt", + "sold": 4123.0, + "in-stock": 144, + "on-order": 42, + "sku": "HRD-000-632" + }, + { + "name": "water", + "sold": 17.0, + "in-stock": 14, + "on-order": 2, + "sku": "GRO-000-2331" + } + ] + }, + "data": { + "item": [ + { + "name": "fish", + "sold": 1321.0, + "in-stock": 45, + "on-order": 1, + "sku": "GRO-000-533" + } + ] + } + } + +XML output: + + % ./testxo --libxo pretty,xml + <top> + <data> + <item> + <name>gum</name> + <sold>1412.0</sold> + <in-stock>54</in-stock> + <on-order>10</on-order> + <sku>GRO-000-415</sku> + </item> + <item> + <name>rope</name> + <sold>85.0</sold> + <in-stock>4</in-stock> + <on-order>2</on-order> + <sku>HRD-000-212</sku> + </item> + <item> + <name>ladder</name> + <sold>0</sold> + <in-stock>2</in-stock> + <on-order>1</on-order> + <sku>HRD-000-517</sku> + </item> + <item> + <name>bolt</name> + <sold>4123.0</sold> + <in-stock>144</in-stock> + <on-order>42</on-order> + <sku>HRD-000-632</sku> + </item> + <item> + <name>water</name> + <sold>17.0</sold> + <in-stock>14</in-stock> + <on-order>2</on-order> + <sku>GRO-000-2331</sku> + </item> + </data> + <data> + <item> + <name>fish</name> + <sold>1321.0</sold> + <in-stock>45</in-stock> + <on-order>1</on-order> + <sku>GRO-000-533</sku> + </item> + </data> + </top> + +HMTL output: + + % ./testxo --libxo pretty,html + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name">gum</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">1412.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">54</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">10</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku">GRO-000-415</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name">rope</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">85.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">4</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">2</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku">HRD-000-212</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name">ladder</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">2</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">1</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku">HRD-000-517</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name">bolt</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">4123.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">144</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">42</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku">HRD-000-632</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name">water</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">17.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">14</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">2</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku">GRO-000-2331</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name">fish</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">1321.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">45</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">1</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku">GRO-000-533</div> + </div> + +HTML output with xpath and info flags: + + % ./testxo --libxo pretty,html,xpath,info + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" + data-xpath="/top/data/item/name" data-type="string" + data-help="Name of the item">gum</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" + data-xpath="/top/data/item/sold" data-type="number" + data-help="Number of items sold">1412.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" data-type="number" + data-help="Number of items in stock">54</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" + data-xpath="/top/data/item/on-order" data-type="number" + data-help="Number of items on order">10</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" + data-xpath="/top/data/item/sku" data-type="string" + data-help="Stock Keeping Unit">GRO-000-415</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" + data-xpath="/top/data/item/name" data-type="string" + data-help="Name of the item">rope</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" + data-xpath="/top/data/item/sold" data-type="number" + data-help="Number of items sold">85.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" data-type="number" + data-help="Number of items in stock">4</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" + data-xpath="/top/data/item/on-order" data-type="number" + data-help="Number of items on order">2</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" + data-xpath="/top/data/item/sku" data-type="string" + data-help="Stock Keeping Unit">HRD-000-212</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" + data-xpath="/top/data/item/name" data-type="string" + data-help="Name of the item">ladder</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" + data-xpath="/top/data/item/sold" data-type="number" + data-help="Number of items sold">0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" data-type="number" + data-help="Number of items in stock">2</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" + data-xpath="/top/data/item/on-order" data-type="number" + data-help="Number of items on order">1</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" + data-xpath="/top/data/item/sku" data-type="string" + data-help="Stock Keeping Unit">HRD-000-517</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" + data-xpath="/top/data/item/name" data-type="string" + data-help="Name of the item">bolt</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" + data-xpath="/top/data/item/sold" data-type="number" + data-help="Number of items sold">4123.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" data-type="number" + data-help="Number of items in stock">144</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" + data-xpath="/top/data/item/on-order" data-type="number" + data-help="Number of items on order">42</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" + data-xpath="/top/data/item/sku" data-type="string" + data-help="Stock Keeping Unit">HRD-000-632</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" + data-xpath="/top/data/item/name" data-type="string" + data-help="Name of the item">water</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" + data-xpath="/top/data/item/sold" data-type="number" + data-help="Number of items sold">17.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" data-type="number" + data-help="Number of items in stock">14</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" + data-xpath="/top/data/item/on-order" data-type="number" + data-help="Number of items on order">2</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" + data-xpath="/top/data/item/sku" data-type="string" + data-help="Stock Keeping Unit">GRO-000-2331</div> + </div> + <div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" + data-xpath="/top/data/item/name" data-type="string" + data-help="Name of the item">fish</div> + <div class="text">':</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" + data-xpath="/top/data/item/sold" data-type="number" + data-help="Number of items sold">1321.0</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" data-type="number" + data-help="Number of items in stock">45</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" + data-xpath="/top/data/item/on-order" data-type="number" + data-help="Number of items on order">1</div> + </div> + <div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" + data-xpath="/top/data/item/sku" data-type="string" + data-help="Stock Keeping Unit">GRO-000-533</div> + </div> + +{{document: + name libxo-manual; + private "The libxo Project"; + ipr none; + category exp; + abbreviation LIBXO-MANUAL; + title "libxo: The Easy Way to Generate text, XML, JSON, and HTML output"; + contributor "author:Phil Shafer:Juniper Networks:phil@juniper.net"; +}} diff --git a/contrib/libxo/install-sh b/contrib/libxo/install-sh new file mode 100755 index 0000000..377bb86 --- /dev/null +++ b/contrib/libxo/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # 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. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# 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_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +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 +no_target_directory= + +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 + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +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 + 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 -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + 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. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/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. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 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 + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob 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` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob 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/contrib/libxo/libxo-config.in b/contrib/libxo/libxo-config.in new file mode 100644 index 0000000..3dbb7d4 --- /dev/null +++ b/contrib/libxo/libxo-config.in @@ -0,0 +1,119 @@ +#! /bin/sh +# +# $Id$ +# +# Copyright 2011-2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +includedir=@includedir@ +libdir=@libdir@ + +usage() +{ + cat <<EOF +Usage: libxo-config [OPTION] + +Known values for OPTION are: + + --prefix=DIR change libxo prefix [default $prefix] + --exec-prefix=DIR change libxo exec prefix [default $exec_prefix] + --libs print library linking information + --bindir print the bin directory + --cflags print pre-processor and compiler flags + --share print share directory + --help display this help and exit + --version output version information +EOF + + exit $1 +} + +if test $# -eq 0; then + usage 1 +fi + +cflags=false +libs=false + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case "$1" in + --prefix=*) + prefix=$optarg + includedir=$prefix/include + libdir=$prefix/lib + ;; + + --prefix) + echo $prefix + ;; + + --exec-prefix=*) + exec_prefix=$optarg + libdir=$exec_prefix/lib + ;; + + --exec-prefix) + echo $exec_prefix + ;; + + --version) + echo @VERSION@ + exit 0 + ;; + + --help) + usage 0 + ;; + + --cflags) + echo -I@LIBXO_INCLUDEDIR@ @LIBXO_CFLAGS@ + ;; + + + --share) + echo @LIBXO_SHAREDIR@ + ;; + + --bindir) + echo @LIBXO_BINDIR@ + ;; + + --libdir) + echo @LIBXO_LIBDIR@ + ;; + + + --libs) + if [ "`uname`" = "Linux" ] + then + if [ "@LIBXO_LIBDIR@" = "-L/usr/lib" -o "@LIBXO_LIBDIR@" = "-L/usr/lib64" ] + then + echo @LIBXO_LIBS@ + else + echo -L@LIBXO_LIBDIR@ @LIBXO_LIBS@ + fi + else + echo -L@LIBXO_LIBDIR@ @LIBXO_LIBS@ @WIN32_EXTRA_LIBADD@ + fi + ;; + + *) + usage + exit 1 + ;; + esac + shift +done + +exit 0 diff --git a/contrib/libxo/libxo/Makefile.am b/contrib/libxo/libxo/Makefile.am new file mode 100644 index 0000000..3303e94 --- /dev/null +++ b/contrib/libxo/libxo/Makefile.am @@ -0,0 +1,49 @@ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +if HAVE_GCC +GCC_WARNINGS = yes +endif +include ${top_srcdir}/warnings.mk + +libxoincdir = ${includedir}/libxo + +AM_CFLAGS = -I${top_srcdir} ${WARNINGS} + +lib_LTLIBRARIES = libxo.la + +libxoinc_HEADERS = \ + xo.h + +libxo_la_SOURCES = \ + libxo.c + +man_MANS = \ + libxo.3 \ + xo_attr.3 \ + xo_create.3 \ + xo_emit.3 \ + xo_err.3 \ + xo_finish.3 \ + xo_flush.3 \ + xo_format.5 \ + xo_no_setlocale.3 \ + xo_open_container.3 \ + xo_open_list.3 \ + xo_parse_args.3 \ + xo_set_allocator.3 \ + xo_set_flags.3 \ + xo_set_info.3 \ + xo_set_options.3 \ + xo_set_style.3 \ + xo_set_writer.3 + +EXTRA_DIST = diff --git a/contrib/libxo/libxo/gen-wide.sh b/contrib/libxo/libxo/gen-wide.sh new file mode 100755 index 0000000..b034287 --- /dev/null +++ b/contrib/libxo/libxo/gen-wide.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +FILE=$1 + +SYMBOLS=" +xo_buffer_s +xo_buffer_t +xo_stack_s +xo_stack_t +xo_handle_s +xo_handle_t +xo_default_handle +xo_default_inited +xo_realloc +xo_free +xo_write_to_file +xo_close_file +xo_buf_init +xo_init_handle +xo_default_init +xo_buf_has_room +xo_printf +xo_escape_xml +xo_escape_json +xo_buf_append +xo_buf_escape +xo_data_append +xo_data_escape +xo_default +xo_indent +xo_warn +xo_create +xo_create_to_file +xo_destroy +xo_set_style +xo_set_flags +xo_set_info +xo_set_formatter +xo_clear_flags +xo_buf_indent +xo_line_ensure_open +xo_line_close +xo_info_compare +xo_info_find +xo_format_data +xo_buf_append_div +xo_format_text +xo_format_label +xo_format_title +xo_format_prep +xo_format_value +xo_format_decoration +xo_format_padding +xo_do_emit +xo_emit_hv +xo_emit_h +xo_emit +xo_attr_hv +xo_attr_h +xo_attr +xo_depth_change +xo_open_container_h +xo_open_container +xo_close_container_h +xo_close_container +xo_open_list_h +xo_open_list +xo_close_list_h +xo_close_list +xo_open_instance_h +xo_open_instance +xo_close_instance_h +xo_close_instance +xo_set_writer +xo_set_allocator +" diff --git a/contrib/libxo/libxo/libxo.3 b/contrib/libxo/libxo/libxo.3 new file mode 100644 index 0000000..fca0774 --- /dev/null +++ b/contrib/libxo/libxo/libxo.3 @@ -0,0 +1,149 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm libxo +.Nd library for emitting text, XML, JSON, or HTML output +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Sh DESCRIPTION +The functions defined in +.Lb libxo +are used to generate a choice of +.Em TEXT , +.Em XML , +.Em JSON , +or +.Em HTML +output. A common set of functions are used, with +command line switches passed to the library to control the details of +the output. +.Pp +Most commands emit text output aimed at humans. It is designed +to be parsed and understood by a user. Humans are gifted at extracted +details and pattern matching. Often programmers need to extract +information from this human-oriented output. Programmers use tools +like grep, awk, and regular expressions to ferret out the pieces of +information they need. Such solutions are fragile and require +updates when output contents change or evolve, requiring testing and +validation. +.Pp +Modern tool developers favors encoding schemes like XML and JSON, +which allow trivial parsing and extraction of data. Such formats are +simple, well understood, hierarchical, easily parsed, and often +integrate easier with common tools and environments. +.Pp +In addition, modern reality means that more output ends up in web +browsers than in terminals, making HTML output valuable. +.Pp +.Em libxo +allows a single set of function calls in source code to generate +traditional text output, as well as XML and JSON formatted data. HTML +can also be generated; "<div>" elements surround the traditional text +output, with attributes that detail how to render the data. +.Pp +There are four encoding styles supported by libxo: TEXT, HTML, JSON, +and XML. JSON and XML are suitable for encoding data, while TEXT and +HTML are suited for display to the user. TEXT output can be display +on a terminal session, allowing compatibility with traditional usage. +HTML can be matched with a small CSS file to permit rendering in any +HTML5 browser. XML output is suitable for tools like XPath and +protocols like NETCONF. JSON output can be used for RESTful APIs. +.Pp +The +.Em libxo +library allows an application to generate text, XML, JSON, +and HTML output using a common set of function calls. The application +decides at run time which output style should be produced. The +application calls a function +.Fn xo_emit +to product output that is +described in a format string. A "field descriptor" tells libxo what +the field is and what it means. Each field descriptor is placed in +braces with a printf-like format string: +.Bd -literal -offset indent + xo_emit(" {:lines/%7ju} {:words/%7ju} " + "{:characters/%7ju}{d:filename/%s}\\n", + linect, wordct, charct, file); +.Ed +.Pp +Each field can have a role, with the 'value' role being the default, +and the role tells libxo how and when to render that field, as well as +a +.Xr printf 3 -like +format string. +.Pp +Output +can then be generated in various style, using the "--libxo" option. +.Sh DEFAULT HANDLE +Handles give an abstraction for libxo that encapsulates the state of a +stream of output. Handles have the data type "xo_handle_t" and are +opaque to the caller. + +The library has a default handle that is automatically initialized. +By default, this handle will send text style output to standard output. +The xo_set_style and xo_set_flags functions can be used to change this +behavior. + +Many libxo functions take a handle as their first parameter; most that +do not use the default handle. Any function taking a handle can +be passed NULL to access the default handle. + +For the typical command that is generating output on standard output, +there is no need to create an explicit handle, but they are available +when needed, e.g. for daemons that generate multiple streams of +output. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_attr 3 , +.Xr xo_create 3 , +.Xr xo_emit 3 , +.Xr xo_err 3 , +.Xr xo_finish 3 , +.Xr xo_flush 3 , +.Xr xo_format 5 , +.Xr xo_no_setlocale 3 , +.Xr xo_open_container 3 , +.Xr xo_open_list 3 , +.Xr xo_parse_args 3 , +.Xr xo_set_allocator 3 , +.Xr xo_set_flags 3 , +.Xr xo_set_info 3 , +.Xr xo_set_options 3 , +.Xr xo_set_style 3 , +.Xr xo_set_writer 3 , +.Xr xo 1 , +and +.Xr xolint 1 . +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/libxo.c b/contrib/libxo/libxo/libxo.c new file mode 100644 index 0000000..ebe55b9 --- /dev/null +++ b/contrib/libxo/libxo/libxo.c @@ -0,0 +1,4353 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stddef.h> +#include <wchar.h> +#include <locale.h> +#include <sys/types.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <limits.h> +#include <ctype.h> +#include <wctype.h> +#include <getopt.h> + +#include "xoconfig.h" +#include "xo.h" +#include "xoversion.h" + +const char xo_version[] = LIBXO_VERSION; +const char xo_version_extra[] = LIBXO_VERSION_EXTRA; + +#ifndef UNUSED +#define UNUSED __attribute__ ((__unused__)) +#endif /* UNUSED */ + +#define XO_INDENT_BY 2 /* Amount to indent when pretty printing */ +#define XO_BUFSIZ (8*1024) /* Initial buffer size */ +#define XO_DEPTH 512 /* Default stack depth */ +#define XO_MAX_ANCHOR_WIDTH (8*1024) /* Anything wider is just sillyb */ + +#define XO_FAILURE_NAME "failure" + +/* + * xo_buffer_t: a memory buffer that can be grown as needed. We + * use them for building format strings and output data. + */ +typedef struct xo_buffer_s { + char *xb_bufp; /* Buffer memory */ + char *xb_curp; /* Current insertion point */ + int xb_size; /* Size of buffer */ +} xo_buffer_t; + +/* Flags for the stack frame */ +typedef unsigned xo_xsf_flags_t; /* XSF_* flags */ +#define XSF_NOT_FIRST (1<<0) /* Not the first element */ +#define XSF_LIST (1<<1) /* Frame is a list */ +#define XSF_INSTANCE (1<<2) /* Frame is an instance */ +#define XSF_DTRT (1<<3) /* Save the name for DTRT mode */ + +/* + * xo_stack_t: As we open and close containers and levels, we + * create a stack of frames to track them. This is needed for + * XOF_WARN and XOF_XPATH. + */ +typedef struct xo_stack_s { + xo_xsf_flags_t xs_flags; /* Flags for this frame */ + char *xs_name; /* Name (for XPath value) */ + char *xs_keys; /* XPath predicate for any key fields */ +} xo_stack_t; + +/* + * xo_handle_t: this is the principle data structure for libxo. + * It's used as a store for state, options, and content. + */ +struct xo_handle_s { + unsigned long xo_flags; /* Flags */ + unsigned short xo_style; /* XO_STYLE_* value */ + unsigned short xo_indent; /* Indent level (if pretty) */ + unsigned short xo_indent_by; /* Indent amount (tab stop) */ + xo_write_func_t xo_write; /* Write callback */ + xo_close_func_t xo_close; /* Clo;se callback */ + xo_formatter_t xo_formatter; /* Custom formating function */ + xo_checkpointer_t xo_checkpointer; /* Custom formating support function */ + void *xo_opaque; /* Opaque data for write function */ + FILE *xo_fp; /* XXX File pointer */ + xo_buffer_t xo_data; /* Output data */ + xo_buffer_t xo_fmt; /* Work area for building format strings */ + xo_buffer_t xo_attrs; /* Work area for building XML attributes */ + xo_buffer_t xo_predicate; /* Work area for building XPath predicates */ + xo_stack_t *xo_stack; /* Stack pointer */ + int xo_depth; /* Depth of stack */ + int xo_stack_size; /* Size of the stack */ + xo_info_t *xo_info; /* Info fields for all elements */ + int xo_info_count; /* Number of info entries */ + va_list xo_vap; /* Variable arguments (stdargs) */ + char *xo_leading_xpath; /* A leading XPath expression */ + mbstate_t xo_mbstate; /* Multi-byte character conversion state */ + unsigned xo_anchor_offset; /* Start of anchored text */ + unsigned xo_anchor_columns; /* Number of columns since the start anchor */ + int xo_anchor_min_width; /* Desired width of anchored text */ + unsigned xo_units_offset; /* Start of units insertion point */ + unsigned xo_columns; /* Columns emitted during this xo_emit call */ +}; + +/* Flags for formatting functions */ +typedef unsigned long xo_xff_flags_t; +#define XFF_COLON (1<<0) /* Append a ":" */ +#define XFF_COMMA (1<<1) /* Append a "," iff there's more output */ +#define XFF_WS (1<<2) /* Append a blank */ +#define XFF_ENCODE_ONLY (1<<3) /* Only emit for encoding formats (xml and json) */ + +#define XFF_QUOTE (1<<4) /* Force quotes */ +#define XFF_NOQUOTE (1<<5) /* Force no quotes */ +#define XFF_DISPLAY_ONLY (1<<6) /* Only emit for display formats (text and html) */ +#define XFF_KEY (1<<7) /* Field is a key (for XPath) */ + +#define XFF_XML (1<<8) /* Force XML encoding style (for XPath) */ +#define XFF_ATTR (1<<9) /* Escape value using attribute rules (XML) */ +#define XFF_BLANK_LINE (1<<10) /* Emit a blank line */ +#define XFF_NO_OUTPUT (1<<11) /* Do not make any output */ + +#define XFF_TRIM_WS (1<<12) /* Trim whitespace off encoded values */ +#define XFF_LEAF_LIST (1<<13) /* A leaf-list (list of values) */ +#define XFF_UNESCAPE (1<<14) /* Need to printf-style unescape the value */ + +/* + * Normal printf has width and precision, which for strings operate as + * min and max number of columns. But this depends on the idea that + * one byte means one column, which UTF-8 and multi-byte characters + * pitches on its ear. It may take 40 bytes of data to populate 14 + * columns, but we can't go off looking at 40 bytes of data without the + * caller's permission for fear/knowledge that we'll generate core files. + * + * So we make three values, distinguishing between "max column" and + * "number of bytes that we will inspect inspect safely" We call the + * later "size", and make the format "%[[<min>].[[<size>].<max>]]s". + * + * Under the "first do no harm" theory, we default "max" to "size". + * This is a reasonable assumption for folks that don't grok the + * MBS/WCS/UTF-8 world, and while it will be annoying, it will never + * be evil. + * + * For example, xo_emit("{:tag/%-14.14s}", buf) will make 14 + * columns of output, but will never look at more than 14 bytes of the + * input buffer. This is mostly compatible with printf and caller's + * expectations. + * + * In contrast xo_emit("{:tag/%-14..14s}", buf) will look at however + * many bytes (or until a NUL is seen) are needed to fill 14 columns + * of output. xo_emit("{:tag/%-14.*.14s}", xx, buf) will look at up + * to xx bytes (or until a NUL is seen) in order to fill 14 columns + * of output. + * + * It's fairly amazing how a good idea (handle all languages of the + * world) blows such a big hole in the bottom of the fairly weak boat + * that is C string handling. The simplicity and completenesss are + * sunk in ways we haven't even begun to understand. + */ + +#define XF_WIDTH_MIN 0 /* Minimal width */ +#define XF_WIDTH_SIZE 1 /* Maximum number of bytes to examine */ +#define XF_WIDTH_MAX 2 /* Maximum width */ +#define XF_WIDTH_NUM 3 /* Numeric fields in printf (min.size.max) */ + +/* Input and output string encodings */ +#define XF_ENC_WIDE 1 /* Wide characters (wchar_t) */ +#define XF_ENC_UTF8 2 /* UTF-8 */ +#define XF_ENC_LOCALE 3 /* Current locale */ + +/* + * A place to parse printf-style format flags for each field + */ +typedef struct xo_format_s { + unsigned char xf_fc; /* Format character */ + unsigned char xf_enc; /* Encoding of the string (XF_ENC_*) */ + unsigned char xf_skip; /* Skip this field */ + unsigned char xf_lflag; /* 'l' (long) */ + unsigned char xf_hflag;; /* 'h' (half) */ + unsigned char xf_jflag; /* 'j' (intmax_t) */ + unsigned char xf_tflag; /* 't' (ptrdiff_t) */ + unsigned char xf_zflag; /* 'z' (size_t) */ + unsigned char xf_qflag; /* 'q' (quad_t) */ + unsigned char xf_seen_minus; /* Seen a minus */ + int xf_leading_zero; /* Seen a leading zero (zero fill) */ + unsigned xf_dots; /* Seen one or more '.'s */ + int xf_width[XF_WIDTH_NUM]; /* Width/precision/size numeric fields */ + unsigned xf_stars; /* Seen one or more '*'s */ + unsigned char xf_star[XF_WIDTH_NUM]; /* Seen one or more '*'s */ +} xo_format_t; + +/* + * We keep a default handle to allow callers to avoid having to + * allocate one. Passing NULL to any of our functions will use + * this default handle. + */ +static xo_handle_t xo_default_handle; +static int xo_default_inited; +static int xo_locale_inited; +static char *xo_program; + +/* + * To allow libxo to be used in diverse environment, we allow the + * caller to give callbacks for memory allocation. + */ +static xo_realloc_func_t xo_realloc = realloc; +static xo_free_func_t xo_free = free; + +/* Forward declarations */ +static void +xo_failure (xo_handle_t *xop, const char *fmt, ...); + +static void +xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, + const char *name, int nlen, + const char *value, int vlen, + const char *encoding, int elen); + +static void +xo_anchor_clear (xo_handle_t *xop); + +/* + * Callback to write data to a FILE pointer + */ +static int +xo_write_to_file (void *opaque, const char *data) +{ + FILE *fp = (FILE *) opaque; + return fprintf(fp, "%s", data); +} + +/* + * Callback to close a file + */ +static void +xo_close_file (void *opaque) +{ + FILE *fp = (FILE *) opaque; + fclose(fp); +} + +/* + * Initialize the contents of an xo_buffer_t. + */ +static void +xo_buf_init (xo_buffer_t *xbp) +{ + xbp->xb_size = XO_BUFSIZ; + xbp->xb_bufp = xo_realloc(NULL, xbp->xb_size); + xbp->xb_curp = xbp->xb_bufp; +} + +/* + * Initialize the contents of an xo_buffer_t. + */ +static void +xo_buf_cleanup (xo_buffer_t *xbp) +{ + if (xbp->xb_bufp) + xo_free(xbp->xb_bufp); + bzero(xbp, sizeof(*xbp)); +} + +static int +xo_depth_check (xo_handle_t *xop, int depth) +{ + xo_stack_t *xsp; + + if (depth >= xop->xo_stack_size) { + depth += 16; + xsp = xo_realloc(xop->xo_stack, sizeof(xop->xo_stack[0]) * depth); + if (xsp == NULL) { + xo_failure(xop, "xo_depth_check: out of memory (%d)", depth); + return 0; + } + + int count = depth - xop->xo_stack_size; + + bzero(xsp + xop->xo_stack_size, count * sizeof(*xsp)); + xop->xo_stack_size = depth; + xop->xo_stack = xsp; + } + + return 0; +} + +void +xo_no_setlocale (void) +{ + xo_locale_inited = 1; /* Skip initialization */ +} + +/* + * Initialize an xo_handle_t, using both static defaults and + * the global settings from the LIBXO_OPTIONS environment + * variable. + */ +static void +xo_init_handle (xo_handle_t *xop) +{ + xop->xo_opaque = stdout; + xop->xo_write = xo_write_to_file; + + /* + * We need to initialize the locale, which isn't really pretty. + * Libraries should depend on their caller to set up the + * environment. But we really can't count on the caller to do + * this, because well, they won't. Trust me. + */ + if (!xo_locale_inited) { + xo_locale_inited = 1; /* Only do this once */ + + const char *cp = getenv("LC_CTYPE"); + if (cp == NULL) + cp = getenv("LANG"); + if (cp == NULL) + cp = getenv("LC_ALL"); + if (cp == NULL) + cp = "UTF-8"; /* Optimistic? */ + cp = setlocale(LC_CTYPE, cp); + } + + /* + * Initialize only the xo_buffers we know we'll need; the others + * can be allocated as needed. + */ + xo_buf_init(&xop->xo_data); + xo_buf_init(&xop->xo_fmt); + + xop->xo_indent_by = XO_INDENT_BY; + xo_depth_check(xop, XO_DEPTH); + +#if !defined(NO_LIBXO_OPTIONS) + if (!(xop->xo_flags & XOF_NO_ENV)) { + char *env = getenv("LIBXO_OPTIONS"); + if (env) + xo_set_options(xop, env); + } +#endif /* NO_GETENV */ +} + +/* + * Initialize the default handle. + */ +static void +xo_default_init (void) +{ + xo_handle_t *xop = &xo_default_handle; + + xo_init_handle(xop); + + xo_default_inited = 1; +} + +/* + * Does the buffer have room for the given number of bytes of data? + * If not, realloc the buffer to make room. If that fails, we + * return 0 to tell the caller they are in trouble. + */ +static int +xo_buf_has_room (xo_buffer_t *xbp, int len) +{ + if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) { + int sz = xbp->xb_size + XO_BUFSIZ; + char *bp = xo_realloc(xbp->xb_bufp, sz); + if (bp == NULL) { + /* + * XXX If we wanted to put a stick XOF_ENOMEM on xop, + * this would be the place to do it. But we'd need + * to churn the code to pass xop in here.... + */ + return 0; + } + + xbp->xb_curp = bp + (xbp->xb_curp - xbp->xb_bufp); + xbp->xb_bufp = bp; + xbp->xb_size = sz; + } + + return 1; +} + +/* + * Cheap convenience function to return either the argument, or + * the internal handle, after it has been initialized. The usage + * is: + * xop = xo_default(xop); + */ +static xo_handle_t * +xo_default (xo_handle_t *xop) +{ + if (xop == NULL) { + if (xo_default_inited == 0) + xo_default_init(); + xop = &xo_default_handle; + } + + return xop; +} + +/* + * Return the number of spaces we should be indenting. If + * we are pretty-printing, theis is indent * indent_by. + */ +static int +xo_indent (xo_handle_t *xop) +{ + int rc = 0; + + xop = xo_default(xop); + + if (xop->xo_flags & XOF_PRETTY) { + rc = xop->xo_indent * xop->xo_indent_by; + if (xop->xo_flags & XOF_TOP_EMITTED) + rc += xop->xo_indent_by; + } + + return rc; +} + +static void +xo_buf_indent (xo_handle_t *xop, int indent) +{ + xo_buffer_t *xbp = &xop->xo_data; + + if (indent <= 0) + indent = xo_indent(xop); + + if (!xo_buf_has_room(xbp, indent)) + return; + + memset(xbp->xb_curp, ' ', indent); + xbp->xb_curp += indent; +} + +static char xo_xml_amp[] = "&"; +static char xo_xml_lt[] = "<"; +static char xo_xml_gt[] = ">"; +static char xo_xml_quot[] = """; + +static int +xo_escape_xml (xo_buffer_t *xbp, int len, int attr) +{ + int slen; + unsigned delta = 0; + char *cp, *ep, *ip; + const char *sp; + + for (cp = xbp->xb_curp, ep = cp + len; cp < ep; cp++) { + /* We're subtracting 2: 1 for the NUL, 1 for the char we replace */ + if (*cp == '<') + delta += sizeof(xo_xml_lt) - 2; + else if (*cp == '>') + delta += sizeof(xo_xml_gt) - 2; + else if (*cp == '&') + delta += sizeof(xo_xml_amp) - 2; + else if (attr && *cp == '"') + delta += sizeof(xo_xml_quot) - 2; + } + + if (delta == 0) /* Nothing to escape; bail */ + return len; + + if (!xo_buf_has_room(xbp, delta)) /* No room; bail, but don't append */ + return 0; + + ep = xbp->xb_curp; + cp = ep + len; + ip = cp + delta; + do { + cp -= 1; + ip -= 1; + + if (*cp == '<') + sp = xo_xml_lt; + else if (*cp == '>') + sp = xo_xml_gt; + else if (*cp == '&') + sp = xo_xml_amp; + else if (attr && *cp == '"') + sp = xo_xml_quot; + else { + *ip = *cp; + continue; + } + + slen = strlen(sp); + ip -= slen - 1; + memcpy(ip, sp, slen); + + } while (cp > ep && cp != ip); + + return len + delta; +} + +static int +xo_escape_json (xo_buffer_t *xbp, int len) +{ + unsigned delta = 0; + char *cp, *ep, *ip; + + for (cp = xbp->xb_curp, ep = cp + len; cp < ep; cp++) { + if (*cp == '\\') + delta += 1; + else if (*cp == '"') + delta += 1; + } + + if (delta == 0) /* Nothing to escape; bail */ + return len; + + if (!xo_buf_has_room(xbp, delta)) /* No room; bail, but don't append */ + return 0; + + ep = xbp->xb_curp; + cp = ep + len; + ip = cp + delta; + do { + cp -= 1; + ip -= 1; + + if (*cp != '\\' && *cp != '"') { + *ip = *cp; + continue; + } + + *ip-- = *cp; + *ip = '\\'; + + } while (cp > ep && cp != ip); + + return len + delta; +} + +/* + * Append the given string to the given buffer + */ +static void +xo_buf_append (xo_buffer_t *xbp, const char *str, int len) +{ + if (!xo_buf_has_room(xbp, len)) + return; + + memcpy(xbp->xb_curp, str, len); + xbp->xb_curp += len; +} + +static void +xo_buf_escape (xo_handle_t *xop, xo_buffer_t *xbp, + const char *str, int len, xo_xff_flags_t flags) +{ + if (!xo_buf_has_room(xbp, len)) + return; + + memcpy(xbp->xb_curp, str, len); + + switch (xop->xo_style) { + case XO_STYLE_XML: + case XO_STYLE_HTML: + len = xo_escape_xml(xbp, len, (flags & XFF_ATTR)); + break; + + case XO_STYLE_JSON: + len = xo_escape_json(xbp, len); + break; + } + + xbp->xb_curp += len; +} + +/* + * Write the current contents of the data buffer using the handle's + * xo_write function. + */ +static void +xo_write (xo_handle_t *xop) +{ + xo_buffer_t *xbp = &xop->xo_data; + + if (xbp->xb_curp != xbp->xb_bufp) { + xo_buf_append(xbp, "", 1); /* Append ending NUL */ + xo_anchor_clear(xop); + xop->xo_write(xop->xo_opaque, xbp->xb_bufp); + xbp->xb_curp = xbp->xb_bufp; + } + + /* Turn off the flags that don't survive across writes */ + xop->xo_flags &= ~(XOF_UNITS_PENDING); +} + +/* + * Format arguments into our buffer. If a custom formatter has been set, + * we use that to do the work; otherwise we vsnprintf(). + */ +static int +xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap) +{ + va_list va_local; + int rc; + int left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + + va_copy(va_local, vap); + + if (xop->xo_formatter) + rc = xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local); + else + rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); + + if (rc > xbp->xb_size) { + if (!xo_buf_has_room(xbp, rc)) + return -1; + + /* + * After we call vsnprintf(), the stage of vap is not defined. + * We need to copy it before we pass. Then we have to do our + * own logic below to move it along. This is because the + * implementation can have va_list be a point (bsd) or a + * structure (macosx) or anything in between. + */ + + va_end(va_local); /* Reset vap to the start */ + va_copy(va_local, vap); + + left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + if (xop->xo_formatter) + xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local); + else + rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); + } + va_end(va_local); + + return rc; +} + +/* + * Print some data thru the handle. + */ +static int +xo_printf_v (xo_handle_t *xop, const char *fmt, va_list vap) +{ + xo_buffer_t *xbp = &xop->xo_data; + int left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + int rc; + va_list va_local; + + va_copy(va_local, vap); + + rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); + + if (rc > xbp->xb_size) { + if (!xo_buf_has_room(xbp, rc)) + return -1; + + va_end(va_local); /* Reset vap to the start */ + va_copy(va_local, vap); + + left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); + } + + va_end(va_local); + + if (rc > 0) + xbp->xb_curp += rc; + + return rc; +} + +static int +xo_printf (xo_handle_t *xop, const char *fmt, ...) +{ + int rc; + va_list vap; + + va_start(vap, fmt); + + rc = xo_printf_v(xop, fmt, vap); + + va_end(vap); + return rc; +} + +/* + * These next few function are make The Essential UTF-8 Ginsu Knife. + * Identify an input and output character, and convert it. + */ +static int xo_utf8_bits[7] = { 0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; + +static int +xo_is_utf8 (char ch) +{ + return (ch & 0x80); +} + +static int +xo_utf8_to_wc_len (const char *buf) +{ + unsigned b = (unsigned char) *buf; + int len; + + if ((b & 0x80) == 0x0) + len = 1; + else if ((b & 0xe0) == 0xc0) + len = 2; + else if ((b & 0xf0) == 0xe0) + len = 3; + else if ((b & 0xf8) == 0xf0) + len = 4; + else if ((b & 0xfc) == 0xf8) + len = 5; + else if ((b & 0xfe) == 0xfc) + len = 6; + else + len = -1; + + return len; +} + +static int +xo_buf_utf8_len (xo_handle_t *xop, const char *buf, int bufsiz) +{ + + unsigned b = (unsigned char) *buf; + int len, i; + + len = xo_utf8_to_wc_len(buf); + if (len == -1) { + xo_failure(xop, "invalid UTF-8 data: %02hhx", b); + return -1; + } + + if (len > bufsiz) { + xo_failure(xop, "invalid UTF-8 data (short): %02hhx (%d/%d)", + b, len, bufsiz); + return -1; + } + + for (i = 2; i < len; i++) { + b = (unsigned char ) buf[i]; + if ((b & 0xc0) != 0x80) { + xo_failure(xop, "invalid UTF-8 data (byte %d): %x", i, b); + return -1; + } + } + + return len; +} + +/* + * Build a wide character from the input buffer; the number of + * bits we pull off the first character is dependent on the length, + * but we put 6 bits off all other bytes. + */ +static wchar_t +xo_utf8_char (const char *buf, int len) +{ + int i; + wchar_t wc; + const unsigned char *cp = (const unsigned char *) buf; + + wc = *cp & xo_utf8_bits[len]; + for (i = 1; i < len; i++) { + wc <<= 6; + wc |= cp[i] & 0x3f; + if ((cp[i] & 0xc0) != 0x80) + return (wchar_t) -1; + } + + return wc; +} + +/* + * Determine the number of bytes needed to encode a wide character. + */ +static int +xo_utf8_emit_len (wchar_t wc) +{ + int len; + + if ((wc & ((1<<7) - 1)) == wc) /* Simple case */ + len = 1; + else if ((wc & ((1<<11) - 1)) == wc) + len = 2; + else if ((wc & ((1<<16) - 1)) == wc) + len = 3; + else if ((wc & ((1<<21) - 1)) == wc) + len = 4; + else if ((wc & ((1<<26) - 1)) == wc) + len = 5; + else + len = 6; + + return len; +} + +static void +xo_utf8_emit_char (char *buf, int len, wchar_t wc) +{ + int i; + + if (len == 1) { /* Simple case */ + buf[0] = wc & 0x7f; + return; + } + + for (i = len - 1; i >= 0; i--) { + buf[i] = 0x80 | (wc & 0x3f); + wc >>= 6; + } + + buf[0] &= xo_utf8_bits[len]; + buf[0] |= ~xo_utf8_bits[len] << 1; +} + +static int +xo_buf_append_locale_from_utf8 (xo_handle_t *xop, xo_buffer_t *xbp, + const char *ibuf, int ilen) +{ + wchar_t wc; + int len; + + /* + * Build our wide character from the input buffer; the number of + * bits we pull off the first character is dependent on the length, + * but we put 6 bits off all other bytes. + */ + wc = xo_utf8_char(ibuf, ilen); + if (wc == (wchar_t) -1) { + xo_failure(xop, "invalid utf-8 byte sequence"); + return 0; + } + + if (xop->xo_flags & XOF_NO_LOCALE) { + if (!xo_buf_has_room(xbp, ilen)) + return 0; + + memcpy(xbp->xb_curp, ibuf, ilen); + xbp->xb_curp += ilen; + + } else { + if (!xo_buf_has_room(xbp, MB_LEN_MAX + 1)) + return 0; + + bzero(&xop->xo_mbstate, sizeof(xop->xo_mbstate)); + len = wcrtomb(xbp->xb_curp, wc, &xop->xo_mbstate); + + if (len <= 0) { + xo_failure(xop, "could not convert wide char: %lx", + (unsigned long) wc); + return 0; + } + xbp->xb_curp += len; + } + + return wcwidth(wc); +} + +static void +xo_buf_append_locale (xo_handle_t *xop, xo_buffer_t *xbp, + const char *cp, int len) +{ + const char *sp = cp, *ep = cp + len; + unsigned save_off = xbp->xb_bufp - xbp->xb_curp; + int slen; + int cols = 0; + + for ( ; cp < ep; cp++) { + if (!xo_is_utf8(*cp)) { + cols += 1; + continue; + } + + /* + * We're looking at a non-ascii UTF-8 character. + * First we copy the previous data. + * Then we need find the length and validate it. + * Then we turn it into a wide string. + * Then we turn it into a localized string. + * Then we repeat. Isn't i18n fun? + */ + if (sp != cp) + xo_buf_append(xbp, sp, cp - sp); /* Append previous data */ + + slen = xo_buf_utf8_len(xop, cp, ep - cp); + if (slen <= 0) { + /* Bad data; back it all out */ + xbp->xb_curp = xbp->xb_bufp + save_off; + return; + } + + cols += xo_buf_append_locale_from_utf8(xop, xbp, cp, slen); + + /* Next time thru, we'll start at the next character */ + cp += slen - 1; + sp = cp + 1; + } + + /* Update column values */ + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += cols; + + /* Before we fall into the basic logic below, we need reset len */ + len = ep - sp; + if (len != 0) /* Append trailing data */ + xo_buf_append(xbp, sp, len); +} + +/* + * Append the given string to the given buffer + */ +static void +xo_data_append (xo_handle_t *xop, const char *str, int len) +{ + xo_buf_append(&xop->xo_data, str, len); +} + +/* + * Append the given string to the given buffer + */ +static void +xo_data_escape (xo_handle_t *xop, const char *str, int len) +{ + xo_buf_escape(xop, &xop->xo_data, str, len, 0); +} + +/* + * Generate a warning. Normally, this is a text message written to + * standard error. If the XOF_WARN_XML flag is set, then we generate + * XMLified content on standard output. + */ +static void +xo_warn_hcv (xo_handle_t *xop, int code, int check_warn, + const char *fmt, va_list vap) +{ + xop = xo_default(xop); + if (check_warn && !(xop->xo_flags & XOF_WARN)) + return; + + if (fmt == NULL) + return; + + int len = strlen(fmt); + int plen = xo_program ? strlen(xo_program) : 0; + char *newfmt = alloca(len + 2 + plen + 2); /* newline, NUL, and ": " */ + + if (plen) { + memcpy(newfmt, xo_program, plen); + newfmt[plen++] = ':'; + newfmt[plen++] = ' '; + } + memcpy(newfmt + plen, fmt, len); + + /* Add a newline to the fmt string */ + if (!(xop->xo_flags & XOF_WARN_XML)) + newfmt[len++ + plen] = '\n'; + newfmt[len + plen] = '\0'; + + if (xop->xo_flags & XOF_WARN_XML) { + static char err_open[] = "<error>"; + static char err_close[] = "</error>"; + static char msg_open[] = "<message>"; + static char msg_close[] = "</message>"; + + xo_buffer_t *xbp = &xop->xo_data; + + xo_buf_append(xbp, err_open, sizeof(err_open) - 1); + xo_buf_append(xbp, msg_open, sizeof(msg_open) - 1); + + va_list va_local; + va_copy(va_local, vap); + + int left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + int rc = vsnprintf(xbp->xb_curp, left, newfmt, vap); + if (rc > xbp->xb_size) { + if (!xo_buf_has_room(xbp, rc)) + return; + + va_end(vap); /* Reset vap to the start */ + va_copy(vap, va_local); + + left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + rc = vsnprintf(xbp->xb_curp, left, fmt, vap); + } + va_end(va_local); + + rc = xo_escape_xml(xbp, rc, 1); + xbp->xb_curp += rc; + + xo_buf_append(xbp, msg_close, sizeof(msg_close) - 1); + xo_buf_append(xbp, err_close, sizeof(err_close) - 1); + + if (code > 0) { + const char *msg = strerror(code); + if (msg) { + xo_buf_append(xbp, ": ", 2); + xo_buf_append(xbp, msg, strlen(msg)); + } + } + + xo_buf_append(xbp, "\n", 2); /* Append newline and NUL to string */ + xo_write(xop); + + } else { + vfprintf(stderr, newfmt, vap); + } +} + +void +xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(xop, code, 0, fmt, vap); + va_end(vap); +} + +void +xo_warn_c (int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(NULL, 0, code, fmt, vap); + va_end(vap); +} + +void +xo_warn (const char *fmt, ...) +{ + int code = errno; + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(NULL, code, 0, fmt, vap); + va_end(vap); +} + +void +xo_warnx (const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(NULL, -1, 0, fmt, vap); + va_end(vap); +} + +void +xo_err (int eval, const char *fmt, ...) +{ + int code = errno; + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(NULL, code, 0, fmt, vap); + va_end(vap); + xo_finish(); + exit(eval); +} + +void +xo_errx (int eval, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(NULL, -1, 0, fmt, vap); + va_end(vap); + xo_finish(); + exit(eval); +} + +void +xo_errc (int eval, int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(NULL, code, 0, fmt, vap); + va_end(vap); + xo_finish(); + exit(eval); +} + +/* + * Generate a warning. Normally, this is a text message written to + * standard error. If the XOF_WARN_XML flag is set, then we generate + * XMLified content on standard output. + */ +void +xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) +{ + static char msg_open[] = "<message>"; + static char msg_close[] = "</message>"; + xo_buffer_t *xbp; + int rc; + va_list va_local; + + xop = xo_default(xop); + + if (fmt == NULL || *fmt == '\0') + return; + + int need_nl = (fmt[strlen(fmt) - 1] != '\n'); + + switch (xop->xo_style) { + case XO_STYLE_XML: + xbp = &xop->xo_data; + if (xop->xo_flags & XOF_PRETTY) + xo_buf_indent(xop, xop->xo_indent_by); + xo_buf_append(xbp, msg_open, sizeof(msg_open) - 1); + + va_copy(va_local, vap); + + int left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + rc = vsnprintf(xbp->xb_curp, left, fmt, vap); + if (rc > xbp->xb_size) { + if (!xo_buf_has_room(xbp, rc)) + return; + + va_end(vap); /* Reset vap to the start */ + va_copy(vap, va_local); + + left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + rc = vsnprintf(xbp->xb_curp, left, fmt, vap); + } + va_end(va_local); + + rc = xo_escape_xml(xbp, rc, 1); + xbp->xb_curp += rc; + + if (need_nl && code > 0) { + const char *msg = strerror(code); + if (msg) { + xo_buf_append(xbp, ": ", 2); + xo_buf_append(xbp, msg, strlen(msg)); + } + } + + xo_buf_append(xbp, msg_close, sizeof(msg_close) - 1); + if (need_nl) + xo_buf_append(xbp, "\n", 2); /* Append newline and NUL to string */ + xo_write(xop); + break; + + case XO_STYLE_HTML: + { + char buf[BUFSIZ], *bp = buf, *cp; + int bufsiz = sizeof(buf); + int rc2; + + va_copy(va_local, vap); + + rc = vsnprintf(buf, bufsiz, fmt, va_local); + if (rc > bufsiz) { + bufsiz = rc + BUFSIZ; + bp = alloca(bufsiz); + va_end(va_local); + va_copy(va_local, vap); + rc = vsnprintf(buf, bufsiz, fmt, va_local); + } + cp = bp + rc; + + if (need_nl) { + rc2 = snprintf(cp, bufsiz - rc, "%s%s\n", + (code > 0) ? ": " : "", + (code > 0) ? strerror(code) : ""); + if (rc2 > 0) + rc += rc2; + } + + xo_buf_append_div(xop, "message", 0, NULL, 0, bp, rc, NULL, 0); + } + break; + + case XO_STYLE_JSON: + /* No meanings of representing messages in JSON */ + break; + + case XO_STYLE_TEXT: + rc = xo_printf_v(xop, fmt, vap); + /* + * XXX need to handle UTF-8 widths + */ + if (rc > 0) { + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += rc; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += rc; + } + + if (need_nl && code > 0) { + const char *msg = strerror(code); + if (msg) { + xo_printf(xop, ": %s", msg); + } + } + if (need_nl) + xo_printf(xop, "\n"); + + break; + } + + xo_flush_h(xop); +} + +void +xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_message_hcv(xop, code, fmt, vap); + va_end(vap); +} + +void +xo_message_c (int code, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_message_hcv(NULL, code, fmt, vap); + va_end(vap); +} + +void +xo_message (const char *fmt, ...) +{ + int code = errno; + va_list vap; + + va_start(vap, fmt); + xo_message_hcv(NULL, code, fmt, vap); + va_end(vap); +} + +static void +xo_failure (xo_handle_t *xop, const char *fmt, ...) +{ + if (!(xop->xo_flags & XOF_WARN)) + return; + + va_list vap; + + va_start(vap, fmt); + xo_warn_hcv(xop, -1, 1, fmt, vap); + va_end(vap); +} + +/** + * Create a handle for use by later libxo functions. + * + * Note: normal use of libxo does not require a distinct handle, since + * the default handle (used when NULL is passed) generates text on stdout. + * + * @style Style of output desired (XO_STYLE_* value) + * @flags Set of XOF_* flags in use with this handle + */ +xo_handle_t * +xo_create (xo_style_t style, xo_xof_flags_t flags) +{ + xo_handle_t *xop = xo_realloc(NULL, sizeof(*xop)); + + if (xop) { + bzero(xop, sizeof(*xop)); + + xop->xo_style = style; + xop->xo_flags = flags; + xo_init_handle(xop); + } + + return xop; +} + +/** + * Create a handle that will write to the given file. Use + * the XOF_CLOSE_FP flag to have the file closed on xo_destroy(). + * @fp FILE pointer to use + * @style Style of output desired (XO_STYLE_* value) + * @flags Set of XOF_* flags to use with this handle + */ +xo_handle_t * +xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags) +{ + xo_handle_t *xop = xo_create(style, flags); + + if (xop) { + xop->xo_opaque = fp; + xop->xo_write = xo_write_to_file; + xop->xo_close = xo_close_file; + } + + return xop; +} + +/** + * Release any resources held by the handle. + * @xop XO handle to alter (or NULL for default handle) + */ +void +xo_destroy (xo_handle_t *xop) +{ + xop = xo_default(xop); + + if (xop->xo_close && (xop->xo_flags & XOF_CLOSE_FP)) + xop->xo_close(xop->xo_opaque); + + xo_free(xop->xo_stack); + xo_buf_cleanup(&xop->xo_data); + xo_buf_cleanup(&xop->xo_fmt); + xo_buf_cleanup(&xop->xo_predicate); + xo_buf_cleanup(&xop->xo_attrs); + + if (xop == &xo_default_handle) { + bzero(&xo_default_handle, sizeof(&xo_default_handle)); + xo_default_inited = 0; + } else + xo_free(xop); +} + +/** + * Record a new output style to use for the given handle (or default if + * handle is NULL). This output style will be used for any future output. + * + * @xop XO handle to alter (or NULL for default handle) + * @style new output style (XO_STYLE_*) + */ +void +xo_set_style (xo_handle_t *xop, xo_style_t style) +{ + xop = xo_default(xop); + xop->xo_style = style; +} + +xo_style_t +xo_get_style (xo_handle_t *xop) +{ + xop = xo_default(xop); + return xop->xo_style; +} + +static int +xo_name_to_style (const char *name) +{ + if (strcmp(name, "xml") == 0) + return XO_STYLE_XML; + else if (strcmp(name, "json") == 0) + return XO_STYLE_JSON; + else if (strcmp(name, "text") == 0) + return XO_STYLE_TEXT; + else if (strcmp(name, "html") == 0) + return XO_STYLE_HTML; + + return -1; +} + +/* + * Convert string name to XOF_* flag value. + * Not all are useful. Or safe. Or sane. + */ +static unsigned +xo_name_to_flag (const char *name) +{ + if (strcmp(name, "pretty") == 0) + return XOF_PRETTY; + if (strcmp(name, "warn") == 0) + return XOF_WARN; + if (strcmp(name, "xpath") == 0) + return XOF_XPATH; + if (strcmp(name, "info") == 0) + return XOF_INFO; + if (strcmp(name, "warn-xml") == 0) + return XOF_WARN_XML; + if (strcmp(name, "columns") == 0) + return XOF_COLUMNS; + if (strcmp(name, "dtrt") == 0) + return XOF_DTRT; + if (strcmp(name, "flush") == 0) + return XOF_FLUSH; + if (strcmp(name, "keys") == 0) + return XOF_KEYS; + if (strcmp(name, "ignore-close") == 0) + return XOF_IGNORE_CLOSE; + if (strcmp(name, "not-first") == 0) + return XOF_NOT_FIRST; + if (strcmp(name, "no-locale") == 0) + return XOF_NO_LOCALE; + if (strcmp(name, "no-top") == 0) + return XOF_NO_TOP; + if (strcmp(name, "units") == 0) + return XOF_UNITS; + if (strcmp(name, "underscores") == 0) + return XOF_UNDERSCORES; + + return 0; +} + +int +xo_set_style_name (xo_handle_t *xop, const char *name) +{ + if (name == NULL) + return -1; + + int style = xo_name_to_style(name); + if (style < 0) + return -1; + + xo_set_style(xop, style); + return 0; +} + +/* + * Set the options for a handle using a string of options + * passed in. The input is a comma-separated set of names + * and optional values: "xml,pretty,indent=4" + */ +int +xo_set_options (xo_handle_t *xop, const char *input) +{ + char *cp, *ep, *vp, *np, *bp; + int style = -1, new_style, len, rc = 0; + xo_xof_flags_t new_flag; + + if (input == NULL) + return 0; + + xop = xo_default(xop); + + /* + * We support a simpler, old-school style of giving option + * also, using a single character for each option. It's + * ideal for lazy people, such as myself. + */ + if (*input == ':') { + int sz; + + for (input++ ; *input; input++) { + switch (*input) { + case 'f': + xop->xo_flags |= XOF_FLUSH; + break; + + case 'H': + xop->xo_style = XO_STYLE_HTML; + break; + + case 'I': + xop->xo_flags |= XOF_INFO; + break; + + case 'i': + sz = strspn(input + 1, "0123456789"); + if (sz > 0) { + xop->xo_indent_by = atoi(input + 1); + input += sz - 1; /* Skip value */ + } + break; + + case 'k': + xop->xo_flags |= XOF_KEYS; + break; + + case 'J': + xop->xo_style = XO_STYLE_JSON; + break; + + case 'P': + xop->xo_flags |= XOF_PRETTY; + break; + + case 'T': + xop->xo_style = XO_STYLE_TEXT; + break; + + case 'U': + xop->xo_flags |= XOF_UNITS; + break; + + case 'u': + xop->xo_flags |= XOF_UNDERSCORES; + break; + + case 'W': + xop->xo_flags |= XOF_WARN; + break; + + case 'X': + xop->xo_style = XO_STYLE_XML; + break; + + case 'x': + xop->xo_flags |= XOF_XPATH; + break; + } + } + return 0; + } + + len = strlen(input) + 1; + bp = alloca(len); + memcpy(bp, input, len); + + for (cp = bp, ep = cp + len - 1; cp && cp < ep; cp = np) { + np = strchr(cp, ','); + if (np) + *np++ = '\0'; + + vp = strchr(cp, '='); + if (vp) + *vp++ = '\0'; + + new_style = xo_name_to_style(cp); + if (new_style >= 0) { + if (style >= 0) + xo_warnx("ignoring multiple styles: '%s'", cp); + else + style = new_style; + } else { + new_flag = xo_name_to_flag(cp); + if (new_flag != 0) + xop->xo_flags |= new_flag; + else { + if (strcmp(cp, "indent") == 0) { + xop->xo_indent_by = atoi(vp); + } else { + xo_warnx("unknown option: '%s'", cp); + rc = -1; + } + } + } + } + + if (style > 0) + xop->xo_style= style; + + return rc; +} + +/** + * Set one or more flags for a given handle (or default if handle is NULL). + * These flags will affect future output. + * + * @xop XO handle to alter (or NULL for default handle) + * @flags Flags to be set (XOF_*) + */ +void +xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags) +{ + xop = xo_default(xop); + + xop->xo_flags |= flags; +} + +xo_xof_flags_t +xo_get_flags (xo_handle_t *xop) +{ + xop = xo_default(xop); + + return xop->xo_flags; +} + +/** + * Record a leading prefix for the XPath we generate. This allows the + * generated data to be placed within an XML hierarchy but still have + * accurate XPath expressions. + * + * @xop XO handle to alter (or NULL for default handle) + * @path The XPath expression + */ +void +xo_set_leading_xpath (xo_handle_t *xop, const char *path) +{ + xop = xo_default(xop); + + if (xop->xo_leading_xpath) { + xo_free(xop->xo_leading_xpath); + xop->xo_leading_xpath = NULL; + } + + if (path == NULL) + return; + + int len = strlen(path); + xop->xo_leading_xpath = xo_realloc(NULL, len + 1); + if (xop->xo_leading_xpath) { + memcpy(xop->xo_leading_xpath, path, len + 1); + } +} + +/** + * Record the info data for a set of tags + * + * @xop XO handle to alter (or NULL for default handle) + * @info Info data (xo_info_t) to be recorded (or NULL) (MUST BE SORTED) + * @count Number of entries in info (or -1 to count them ourselves) + */ +void +xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count) +{ + xop = xo_default(xop); + + if (count < 0 && infop) { + xo_info_t *xip; + + for (xip = infop, count = 0; xip->xi_name; xip++, count++) + continue; + } + + xop->xo_info = infop; + xop->xo_info_count = count; +} + +/** + * Set the formatter callback for a handle. The callback should + * return a newly formatting contents of a formatting instruction, + * meaning the bits inside the braces. + */ +void +xo_set_formatter (xo_handle_t *xop, xo_formatter_t func, + xo_checkpointer_t cfunc) +{ + xop = xo_default(xop); + + xop->xo_formatter = func; + xop->xo_checkpointer = cfunc; +} + +/** + * Clear one or more flags for a given handle (or default if handle is NULL). + * These flags will affect future output. + * + * @xop XO handle to alter (or NULL for default handle) + * @flags Flags to be cleared (XOF_*) + */ +void +xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags) +{ + xop = xo_default(xop); + + xop->xo_flags &= ~flags; +} + +static void +xo_line_ensure_open (xo_handle_t *xop, xo_xff_flags_t flags UNUSED) +{ + static char div_open[] = "<div class=\"line\">"; + static char div_open_blank[] = "<div class=\"blank-line\">"; + + if (xop->xo_flags & XOF_DIV_OPEN) + return; + + if (xop->xo_style != XO_STYLE_HTML) + return; + + xop->xo_flags |= XOF_DIV_OPEN; + if (flags & XFF_BLANK_LINE) + xo_data_append(xop, div_open_blank, sizeof(div_open_blank) - 1); + else + xo_data_append(xop, div_open, sizeof(div_open) - 1); + + if (xop->xo_flags & XOF_PRETTY) + xo_data_append(xop, "\n", 1); +} + +static void +xo_line_close (xo_handle_t *xop) +{ + static char div_close[] = "</div>"; + + switch (xop->xo_style) { + case XO_STYLE_HTML: + if (!(xop->xo_flags & XOF_DIV_OPEN)) + xo_line_ensure_open(xop, 0); + + xop->xo_flags &= ~XOF_DIV_OPEN; + xo_data_append(xop, div_close, sizeof(div_close) - 1); + + if (xop->xo_flags & XOF_PRETTY) + xo_data_append(xop, "\n", 1); + break; + + case XO_STYLE_TEXT: + xo_data_append(xop, "\n", 1); + break; + } +} + +static int +xo_info_compare (const void *key, const void *data) +{ + const char *name = key; + const xo_info_t *xip = data; + + return strcmp(name, xip->xi_name); +} + + +static xo_info_t * +xo_info_find (xo_handle_t *xop, const char *name, int nlen) +{ + xo_info_t *xip; + char *cp = alloca(nlen + 1); /* Need local copy for NUL termination */ + + memcpy(cp, name, nlen); + cp[nlen] = '\0'; + + xip = bsearch(cp, xop->xo_info, xop->xo_info_count, + sizeof(xop->xo_info[0]), xo_info_compare); + return xip; +} + +#define CONVERT(_have, _need) (((_have) << 8) | (_need)) + +/* + * Check to see that the conversion is safe and sane. + */ +static int +xo_check_conversion (xo_handle_t *xop, int have_enc, int need_enc) +{ + switch (CONVERT(have_enc, need_enc)) { + case CONVERT(XF_ENC_UTF8, XF_ENC_UTF8): + case CONVERT(XF_ENC_UTF8, XF_ENC_LOCALE): + case CONVERT(XF_ENC_WIDE, XF_ENC_UTF8): + case CONVERT(XF_ENC_WIDE, XF_ENC_LOCALE): + case CONVERT(XF_ENC_LOCALE, XF_ENC_LOCALE): + case CONVERT(XF_ENC_LOCALE, XF_ENC_UTF8): + return 0; + + default: + xo_failure(xop, "invalid conversion (%c:%c)", have_enc, need_enc); + return 1; + } +} + +static int +xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, + xo_xff_flags_t flags, + const wchar_t *wcp, const char *cp, int len, int max, + int need_enc, int have_enc) +{ + int cols = 0; + wchar_t wc; + int ilen, olen, width; + int attr = (flags & XFF_ATTR); + const char *sp; + + if (len > 0 && !xo_buf_has_room(xbp, len)) + return 0; + + for (;;) { + if (len == 0) + break; + + if (cp) { + if (*cp == '\0') + break; + if ((flags & XFF_UNESCAPE) && (*cp == '\\' || *cp == '%')) { + cp += 1; + len -= 1; + } + } + + if (wcp && *wcp == L'\0') + break; + + ilen = 0; + + switch (have_enc) { + case XF_ENC_WIDE: /* Wide character */ + wc = *wcp++; + ilen = 1; + break; + + case XF_ENC_UTF8: /* UTF-8 */ + ilen = xo_utf8_to_wc_len(cp); + if (ilen < 0) { + xo_failure(xop, "invalid UTF-8 character: %02hhx", *cp); + return -1; + } + + if (len > 0 && len < ilen) { + len = 0; /* Break out of the loop */ + continue; + } + + wc = xo_utf8_char(cp, ilen); + if (wc == (wchar_t) -1) { + xo_failure(xop, "invalid UTF-8 character: %02hhx/%d", + *cp, ilen); + return -1; + } + cp += ilen; + break; + + case XF_ENC_LOCALE: /* Native locale */ + ilen = (len > 0) ? len : MB_LEN_MAX; + ilen = mbrtowc(&wc, cp, ilen, &xop->xo_mbstate); + if (ilen < 0) { /* Invalid data; skip */ + xo_failure(xop, "invalid mbs char: %02hhx", *cp); + continue; + } + if (ilen == 0) { /* Hit a wide NUL character */ + len = 0; + continue; + } + + cp += ilen; + break; + } + + /* Reduce len, but not below zero */ + if (len > 0) { + len -= ilen; + if (len < 0) + len = 0; + } + + /* + * Find the width-in-columns of this character, which must be done + * in wide characters, since we lack a mbswidth() function. If + * it doesn't fit + */ + width = wcwidth(wc); + if (width < 0) + width = iswcntrl(wc) ? 0 : 1; + + if (xop->xo_style == XO_STYLE_TEXT || xop->xo_style == XO_STYLE_HTML) { + if (max > 0 && cols + width > max) + break; + } + + switch (need_enc) { + case XF_ENC_UTF8: + + /* Output in UTF-8 needs to be escaped, based on the style */ + switch (xop->xo_style) { + case XO_STYLE_XML: + case XO_STYLE_HTML: + if (wc == '<') + sp = xo_xml_lt; + else if (wc == '>') + sp = xo_xml_gt; + else if (wc == '&') + sp = xo_xml_amp; + else if (attr && wc == '"') + sp = xo_xml_quot; + else + break; + + int slen = strlen(sp); + if (!xo_buf_has_room(xbp, slen - 1)) + return -1; + + memcpy(xbp->xb_curp, sp, slen); + xbp->xb_curp += slen; + goto done_with_encoding; /* Need multi-level 'break' */ + + case XO_STYLE_JSON: + if (wc != '\\' && wc != '"') + break; + + if (!xo_buf_has_room(xbp, 2)) + return -1; + + *xbp->xb_curp++ = '\\'; + *xbp->xb_curp++ = wc & 0x7f; + goto done_with_encoding; + } + + olen = xo_utf8_emit_len(wc); + if (olen < 0) { + xo_failure(xop, "ignoring bad length"); + continue; + } + + if (!xo_buf_has_room(xbp, olen)) + return -1; + + xo_utf8_emit_char(xbp->xb_curp, olen, wc); + xbp->xb_curp += olen; + break; + + case XF_ENC_LOCALE: + if (!xo_buf_has_room(xbp, MB_LEN_MAX + 1)) + return -1; + + olen = wcrtomb(xbp->xb_curp, wc, &xop->xo_mbstate); + if (olen <= 0) { + xo_failure(xop, "could not convert wide char: %lx", + (unsigned long) wc); + olen = 1; + width = 1; + *xbp->xb_curp++ = '?'; + } else + xbp->xb_curp += olen; + break; + } + + done_with_encoding: + cols += width; + } + + return cols; +} + +static int +xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, + xo_format_t *xfp) +{ + static char null[] = "(null)"; + char *cp = NULL; + wchar_t *wcp = NULL; + int len, cols = 0, rc = 0; + int off = xbp->xb_curp - xbp->xb_bufp, off2; + int need_enc = (xop->xo_style == XO_STYLE_TEXT) + ? XF_ENC_LOCALE : XF_ENC_UTF8; + + if (xo_check_conversion(xop, xfp->xf_enc, need_enc)) + return 0; + + if (xfp->xf_enc == XF_ENC_WIDE) { + wcp = va_arg(xop->xo_vap, wchar_t *); + if (xfp->xf_skip) + return 0; + + } else { + cp = va_arg(xop->xo_vap, char *); /* UTF-8 or native */ + if (xfp->xf_skip) + return 0; + + /* + * Optimize the most common case, which is "%s". We just + * need to copy the complete string to the output buffer. + */ + if (xfp->xf_enc == need_enc + && xfp->xf_width[XF_WIDTH_MIN] < 0 + && xfp->xf_width[XF_WIDTH_SIZE] < 0 + && xfp->xf_width[XF_WIDTH_MAX] < 0 + && !(xop->xo_flags & (XOF_ANCHOR | XOF_COLUMNS))) { + len = strlen(cp); + xo_buf_escape(xop, xbp, cp, len, flags); + + /* + * Our caller expects xb_curp left untouched, so we have + * to reset it and return the number of bytes written to + * the buffer. + */ + off2 = xbp->xb_curp - xbp->xb_bufp; + rc = off2 - off; + xbp->xb_curp = xbp->xb_bufp + off; + + return rc; + } + } + + len = xfp->xf_width[XF_WIDTH_SIZE]; + + /* + * Dont' deref NULL; use the traditional "(null)" instead + * of the more accurate "who's been a naughty boy, then?". + */ + if (cp == NULL && wcp == NULL) { + cp = null; + len = sizeof(null) - 1; + } + + cols = xo_format_string_direct(xop, xbp, flags, wcp, cp, len, + xfp->xf_width[XF_WIDTH_MAX], + need_enc, xfp->xf_enc); + if (cols < 0) + goto bail; + + /* + * xo_buf_append* will move xb_curp, so we save/restore it. + */ + off2 = xbp->xb_curp - xbp->xb_bufp; + rc = off2 - off; + xbp->xb_curp = xbp->xb_bufp + off; + + if (cols < xfp->xf_width[XF_WIDTH_MIN]) { + /* + * Find the number of columns needed to display the string. + * If we have the original wide string, we just call wcswidth, + * but if we did the work ourselves, then we need to do it. + */ + int delta = xfp->xf_width[XF_WIDTH_MIN] - cols; + if (!xo_buf_has_room(xbp, delta)) + goto bail; + + /* + * If seen_minus, then pad on the right; otherwise move it so + * we can pad on the left. + */ + if (xfp->xf_seen_minus) { + cp = xbp->xb_curp + rc; + } else { + cp = xbp->xb_curp; + memmove(xbp->xb_curp + delta, xbp->xb_curp, rc); + } + + /* Set the padding */ + memset(cp, (xfp->xf_leading_zero > 0) ? '0' : ' ', delta); + rc += delta; + cols += delta; + } + + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += cols; + + return rc; + + bail: + xbp->xb_curp = xbp->xb_bufp + off; + return 0; +} + +static void +xo_data_append_content (xo_handle_t *xop, const char *str, int len) +{ + int cols; + int need_enc = (xop->xo_style == XO_STYLE_TEXT) + ? XF_ENC_LOCALE : XF_ENC_UTF8; + + cols = xo_format_string_direct(xop, &xop->xo_data, XFF_UNESCAPE, + NULL, str, len, -1, + need_enc, XF_ENC_UTF8); + + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += cols; +} + +static void +xo_bump_width (xo_format_t *xfp, int digit) +{ + int *ip = &xfp->xf_width[xfp->xf_dots]; + + *ip = ((*ip > 0) ? *ip : 0) * 10 + digit; +} + +static int +xo_trim_ws (xo_buffer_t *xbp, int len) +{ + char *cp, *sp, *ep; + int delta; + + /* First trim leading space */ + for (cp = sp = xbp->xb_curp, ep = cp + len; cp < ep; cp++) { + if (*cp != ' ') + break; + } + + delta = cp - sp; + if (delta) { + len -= delta; + memmove(sp, cp, len); + } + + /* Then trim off the end */ + for (cp = xbp->xb_curp, sp = ep = cp + len; cp < ep; ep--) { + if (ep[-1] != ' ') + break; + } + + delta = sp - ep; + if (delta) { + len -= delta; + cp[len] = '\0'; + } + + return len; +} + +static int +xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp, + const char *fmt, int flen, xo_xff_flags_t flags) +{ + xo_format_t xf; + const char *cp, *ep, *sp, *xp = NULL; + int rc, cols; + int style = (flags & XFF_XML) ? XO_STYLE_XML : xop->xo_style; + unsigned make_output = !(flags & XFF_NO_OUTPUT); + int need_enc = (xop->xo_style == XO_STYLE_TEXT) + ? XF_ENC_LOCALE : XF_ENC_UTF8; + + if (xbp == NULL) + xbp = &xop->xo_data; + + for (cp = fmt, ep = fmt + flen; cp < ep; cp++) { + if (*cp != '%') { + add_one: + if (xp == NULL) + xp = cp; + + if (*cp == '\\' && cp[1] != '\0') + cp += 1; + continue; + + } if (cp + 1 < ep && cp[1] == '%') { + cp += 1; + goto add_one; + } + + if (xp) { + if (make_output) { + cols = xo_format_string_direct(xop, xbp, flags | XFF_UNESCAPE, + NULL, xp, cp - xp, -1, + need_enc, XF_ENC_UTF8); + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += cols; + } + + xp = NULL; + } + + bzero(&xf, sizeof(xf)); + xf.xf_leading_zero = -1; + xf.xf_width[0] = xf.xf_width[1] = xf.xf_width[2] = -1; + + /* + * "%@" starts an XO-specific set of flags: + * @X@ - XML-only field; ignored if style isn't XML + */ + if (cp[1] == '@') { + for (cp += 2; cp < ep; cp++) { + if (*cp == '@') { + break; + } + if (*cp == '*') { + /* + * '*' means there's a "%*.*s" value in vap that + * we want to ignore + */ + if (!(xop->xo_flags & XOF_NO_VA_ARG)) + va_arg(xop->xo_vap, int); + } + } + } + + /* Hidden fields are only visible to JSON and XML */ + if (xop->xo_flags & XFF_ENCODE_ONLY) { + if (style != XO_STYLE_XML + && xop->xo_style != XO_STYLE_JSON) + xf.xf_skip = 1; + } else if (xop->xo_flags & XFF_DISPLAY_ONLY) { + if (style != XO_STYLE_TEXT + && xop->xo_style != XO_STYLE_HTML) + xf.xf_skip = 1; + } + + if (!make_output) + xf.xf_skip = 1; + + /* + * Looking at one piece of a format; find the end and + * call snprintf. Then advance xo_vap on our own. + * + * Note that 'n', 'v', and '$' are not supported. + */ + sp = cp; /* Save start pointer */ + for (cp += 1; cp < ep; cp++) { + if (*cp == 'l') + xf.xf_lflag += 1; + else if (*cp == 'h') + xf.xf_hflag += 1; + else if (*cp == 'j') + xf.xf_jflag += 1; + else if (*cp == 't') + xf.xf_tflag += 1; + else if (*cp == 'z') + xf.xf_zflag += 1; + else if (*cp == 'q') + xf.xf_qflag += 1; + else if (*cp == '.') { + if (++xf.xf_dots >= XF_WIDTH_NUM) { + xo_failure(xop, "Too many dots in format: '%s'", fmt); + return -1; + } + } else if (*cp == '-') + xf.xf_seen_minus = 1; + else if (isdigit((int) *cp)) { + if (xf.xf_leading_zero < 0) + xf.xf_leading_zero = (*cp == '0'); + xo_bump_width(&xf, *cp - '0'); + } else if (*cp == '*') { + xf.xf_stars += 1; + xf.xf_star[xf.xf_dots] = 1; + } else if (strchr("diouxXDOUeEfFgGaAcCsSp", *cp) != NULL) + break; + else if (*cp == 'n' || *cp == 'v') { + xo_failure(xop, "unsupported format: '%s'", fmt); + return -1; + } + } + + if (cp == ep) + xo_failure(xop, "field format missing format character: %s", + fmt); + + xf.xf_fc = *cp; + + if (!(xop->xo_flags & XOF_NO_VA_ARG)) { + if (*cp == 's' || *cp == 'S') { + /* Handle "%*.*.*s" */ + int s; + for (s = 0; s < XF_WIDTH_NUM; s++) { + if (xf.xf_star[s]) { + xf.xf_width[s] = va_arg(xop->xo_vap, int); + + /* Normalize a negative width value */ + if (xf.xf_width[s] < 0) { + if (s == 0) { + xf.xf_width[0] = -xf.xf_width[0]; + xf.xf_seen_minus = 1; + } else + xf.xf_width[s] = -1; /* Ignore negative values */ + } + } + } + } + } + + /* If no max is given, it defaults to size */ + if (xf.xf_width[XF_WIDTH_MAX] < 0 && xf.xf_width[XF_WIDTH_SIZE] >= 0) + xf.xf_width[XF_WIDTH_MAX] = xf.xf_width[XF_WIDTH_SIZE]; + + if (xf.xf_fc == 'D' || xf.xf_fc == 'O' || xf.xf_fc == 'U') + xf.xf_lflag = 1; + + if (!xf.xf_skip) { + xo_buffer_t *fbp = &xop->xo_fmt; + int len = cp - sp + 1; + if (!xo_buf_has_room(fbp, len + 1)) + return -1; + + char *newfmt = fbp->xb_curp; + memcpy(newfmt, sp, len); + newfmt[0] = '%'; /* If we skipped over a "%@...@s" format */ + newfmt[len] = '\0'; + + /* + * Bad news: our strings are UTF-8, but the stock printf + * functions won't handle field widths for wide characters + * correctly. So we have to handle this ourselves. + */ + if (xop->xo_formatter == NULL + && (xf.xf_fc == 's' || xf.xf_fc == 'S')) { + xf.xf_enc = (xf.xf_lflag || (xf.xf_fc == 'S')) + ? XF_ENC_WIDE : xf.xf_hflag ? XF_ENC_LOCALE : XF_ENC_UTF8; + rc = xo_format_string(xop, xbp, flags, &xf); + + if ((flags & XFF_TRIM_WS) + && (xop->xo_style == XO_STYLE_XML + || xop->xo_style == XO_STYLE_JSON)) + rc = xo_trim_ws(xbp, rc); + + } else { + int columns = rc = xo_vsnprintf(xop, xbp, newfmt, xop->xo_vap); + + /* + * For XML and HTML, we need "&<>" processing; for JSON, + * it's quotes. Text gets nothing. + */ + switch (style) { + case XO_STYLE_XML: + if (flags & XFF_TRIM_WS) + columns = rc = xo_trim_ws(xbp, rc); + /* fall thru */ + case XO_STYLE_HTML: + rc = xo_escape_xml(xbp, rc, (flags & XFF_ATTR)); + break; + + case XO_STYLE_JSON: + if (flags & XFF_TRIM_WS) + columns = rc = xo_trim_ws(xbp, rc); + rc = xo_escape_json(xbp, rc); + break; + } + + /* + * We can assume all the data we've added is ASCII, so + * the columns and bytes are the same. xo_format_string + * handles all the fancy string conversions and updates + * xo_anchor_columns accordingly. + */ + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += columns; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += columns; + } + + xbp->xb_curp += rc; + } + + /* + * Now for the tricky part: we need to move the argument pointer + * along by the amount needed. + */ + if (!(xop->xo_flags & XOF_NO_VA_ARG)) { + + if (xf.xf_fc == 's' ||xf.xf_fc == 'S') { + /* + * The 'S' and 's' formats are normally handled in + * xo_format_string, but if we skipped it, then we + * need to pop it. + */ + if (xf.xf_skip) + va_arg(xop->xo_vap, char *); + + } else { + int s; + for (s = 0; s < XF_WIDTH_NUM; s++) { + if (xf.xf_star[s]) + va_arg(xop->xo_vap, int); + } + + if (strchr("diouxXDOU", xf.xf_fc) != NULL) { + if (xf.xf_hflag > 1) { + va_arg(xop->xo_vap, int); + + } else if (xf.xf_hflag > 0) { + va_arg(xop->xo_vap, int); + + } else if (xf.xf_lflag > 1) { + va_arg(xop->xo_vap, unsigned long long); + + } else if (xf.xf_lflag > 0) { + va_arg(xop->xo_vap, unsigned long); + + } else if (xf.xf_jflag > 0) { + va_arg(xop->xo_vap, intmax_t); + + } else if (xf.xf_tflag > 0) { + va_arg(xop->xo_vap, ptrdiff_t); + + } else if (xf.xf_zflag > 0) { + va_arg(xop->xo_vap, size_t); + + } else if (xf.xf_qflag > 0) { + va_arg(xop->xo_vap, quad_t); + + } else { + va_arg(xop->xo_vap, int); + } + } else if (strchr("eEfFgGaA", xf.xf_fc) != NULL) + if (xf.xf_lflag) + va_arg(xop->xo_vap, long double); + else + va_arg(xop->xo_vap, double); + + else if (xf.xf_fc == 'C' || (xf.xf_fc == 'c' && xf.xf_lflag)) + va_arg(xop->xo_vap, wint_t); + + else if (xf.xf_fc == 'c') + va_arg(xop->xo_vap, int); + + else if (xf.xf_fc == 'p') + va_arg(xop->xo_vap, void *); + } + } + } + + if (xp) { + if (make_output) { + cols = xo_format_string_direct(xop, xbp, flags | XFF_UNESCAPE, + NULL, xp, cp - xp, -1, + need_enc, XF_ENC_UTF8); + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += cols; + } + + xp = NULL; + } + + return 0; +} + +static char * +xo_fix_encoding (xo_handle_t *xop UNUSED, char *encoding) +{ + char *cp = encoding; + + if (cp[0] != '%' || !isdigit((int) cp[1])) + return encoding; + + for (cp += 2; *cp; cp++) { + if (!isdigit((int) *cp)) + break; + } + + cp -= 1; + *cp = '%'; + + return cp; +} + +static void +xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags, + const char *name, int nlen, + const char *value, int vlen, + const char *encoding, int elen) +{ + static char div_start[] = "<div class=\""; + static char div_tag[] = "\" data-tag=\""; + static char div_xpath[] = "\" data-xpath=\""; + static char div_key[] = "\" data-key=\"key"; + static char div_end[] = "\">"; + static char div_close[] = "</div>"; + + /* + * To build our XPath predicate, we need to save the va_list before + * we format our data, and then restore it before we format the + * xpath expression. + * Display-only keys implies that we've got an encode-only key + * elsewhere, so we don't use them from making predicates. + */ + int need_predidate = + (name && (flags & XFF_KEY) && !(flags & XFF_DISPLAY_ONLY) + && (xop->xo_flags & XOF_XPATH)); + + if (need_predidate) { + va_list va_local; + + va_copy(va_local, xop->xo_vap); + if (xop->xo_checkpointer) + xop->xo_checkpointer(xop, xop->xo_vap, 0); + + /* + * Build an XPath predicate expression to match this key. + * We use the format buffer. + */ + xo_buffer_t *pbp = &xop->xo_predicate; + pbp->xb_curp = pbp->xb_bufp; /* Restart buffer */ + + xo_buf_append(pbp, "[", 1); + xo_buf_escape(xop, pbp, name, nlen, 0); + if (xop->xo_flags & XOF_PRETTY) + xo_buf_append(pbp, " = '", 4); + else + xo_buf_append(pbp, "='", 2); + + /* The encoding format defaults to the normal format */ + if (encoding == NULL) { + char *enc = alloca(vlen + 1); + memcpy(enc, value, vlen); + enc[vlen] = '\0'; + encoding = xo_fix_encoding(xop, enc); + elen = strlen(encoding); + } + + xo_format_data(xop, pbp, encoding, elen, XFF_XML | XFF_ATTR); + + xo_buf_append(pbp, "']", 2); + + /* Now we record this predicate expression in the stack */ + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth]; + int olen = xsp->xs_keys ? strlen(xsp->xs_keys) : 0; + int dlen = pbp->xb_curp - pbp->xb_bufp; + + char *cp = xo_realloc(xsp->xs_keys, olen + dlen + 1); + if (cp) { + memcpy(cp + olen, pbp->xb_bufp, dlen); + cp[olen + dlen] = '\0'; + xsp->xs_keys = cp; + } + + /* Now we reset the xo_vap as if we were never here */ + va_end(xop->xo_vap); + va_copy(xop->xo_vap, va_local); + va_end(va_local); + if (xop->xo_checkpointer) + xop->xo_checkpointer(xop, xop->xo_vap, 1); + } + + if (flags & XFF_ENCODE_ONLY) { + /* + * Even if this is encode-only, we need to go thru the + * work of formatting it to make sure the args are cleared + * from xo_vap. + */ + xo_format_data(xop, &xop->xo_data, encoding, elen, + flags | XFF_NO_OUTPUT); + return; + } + + xo_line_ensure_open(xop, 0); + + if (xop->xo_flags & XOF_PRETTY) + xo_buf_indent(xop, xop->xo_indent_by); + + xo_data_append(xop, div_start, sizeof(div_start) - 1); + xo_data_append(xop, class, strlen(class)); + + if (name) { + xo_data_append(xop, div_tag, sizeof(div_tag) - 1); + xo_data_escape(xop, name, nlen); + + /* + * Save the offset at which we'd place units. See xo_format_units. + */ + if (xop->xo_flags & XOF_UNITS) { + xop->xo_flags |= XOF_UNITS_PENDING; + /* + * Note: We need the '+1' here because we know we've not + * added the closing quote. We add one, knowing the quote + * will be added shortly. + */ + xop->xo_units_offset = + xop->xo_data.xb_curp -xop->xo_data.xb_bufp + 1; + } + } + + if (name) { + if (xop->xo_flags & XOF_XPATH) { + int i; + xo_stack_t *xsp; + + xo_data_append(xop, div_xpath, sizeof(div_xpath) - 1); + if (xop->xo_leading_xpath) + xo_data_append(xop, xop->xo_leading_xpath, + strlen(xop->xo_leading_xpath)); + + for (i = 0; i <= xop->xo_depth; i++) { + xsp = &xop->xo_stack[i]; + if (xsp->xs_name == NULL) + continue; + + xo_data_append(xop, "/", 1); + xo_data_escape(xop, xsp->xs_name, strlen(xsp->xs_name)); + if (xsp->xs_keys) { + /* Don't show keys for the key field */ + if (i != xop->xo_depth || !(flags & XFF_KEY)) + xo_data_append(xop, xsp->xs_keys, strlen(xsp->xs_keys)); + } + } + + xo_data_append(xop, "/", 1); + xo_data_escape(xop, name, nlen); + } + + if ((xop->xo_flags & XOF_INFO) && xop->xo_info) { + static char in_type[] = "\" data-type=\""; + static char in_help[] = "\" data-help=\""; + + xo_info_t *xip = xo_info_find(xop, name, nlen); + if (xip) { + if (xip->xi_type) { + xo_data_append(xop, in_type, sizeof(in_type) - 1); + xo_data_escape(xop, xip->xi_type, strlen(xip->xi_type)); + } + if (xip->xi_help) { + xo_data_append(xop, in_help, sizeof(in_help) - 1); + xo_data_escape(xop, xip->xi_help, strlen(xip->xi_help)); + } + } + } + + if ((flags & XFF_KEY) && (xop->xo_flags & XOF_KEYS)) + xo_data_append(xop, div_key, sizeof(div_key) - 1); + } + + xo_data_append(xop, div_end, sizeof(div_end) - 1); + + xo_format_data(xop, NULL, value, vlen, 0); + + xo_data_append(xop, div_close, sizeof(div_close) - 1); + + if (xop->xo_flags & XOF_PRETTY) + xo_data_append(xop, "\n", 1); +} + +static void +xo_format_text (xo_handle_t *xop, const char *str, int len) +{ + switch (xop->xo_style) { + case XO_STYLE_TEXT: + xo_buf_append_locale(xop, &xop->xo_data, str, len); + break; + + case XO_STYLE_HTML: + xo_buf_append_div(xop, "text", 0, NULL, 0, str, len, NULL, 0); + break; + } +} + +static void +xo_format_title (xo_handle_t *xop, const char *str, int len, + const char *fmt, int flen) +{ + static char div_open[] = "<div class=\"title\">"; + static char div_close[] = "</div>"; + + switch (xop->xo_style) { + case XO_STYLE_XML: + case XO_STYLE_JSON: + /* + * Even though we don't care about text, we need to do + * enough parsing work to skip over the right bits of xo_vap. + */ + if (len == 0) + xo_format_data(xop, NULL, fmt, flen, XFF_NO_OUTPUT); + return; + } + + xo_buffer_t *xbp = &xop->xo_data; + int start = xbp->xb_curp - xbp->xb_bufp; + int left = xbp->xb_size - start; + int rc; + int need_enc = XF_ENC_LOCALE; + + if (xop->xo_style == XO_STYLE_HTML) { + need_enc = XF_ENC_UTF8; + xo_line_ensure_open(xop, 0); + if (xop->xo_flags & XOF_PRETTY) + xo_buf_indent(xop, xop->xo_indent_by); + xo_buf_append(&xop->xo_data, div_open, sizeof(div_open) - 1); + } + + start = xbp->xb_curp - xbp->xb_bufp; /* Reset start */ + if (len) { + char *newfmt = alloca(flen + 1); + memcpy(newfmt, fmt, flen); + newfmt[flen] = '\0'; + + /* If len is non-zero, the format string apply to the name */ + char *newstr = alloca(len + 1); + memcpy(newstr, str, len); + newstr[len] = '\0'; + + if (newstr[len - 1] == 's') { + int cols; + char *bp; + + rc = snprintf(NULL, 0, newfmt, newstr); + if (rc > 0) { + /* + * We have to do this the hard way, since we might need + * the columns. + */ + bp = alloca(rc + 1); + rc = snprintf(bp, rc + 1, newfmt, newstr); + cols = xo_format_string_direct(xop, xbp, 0, NULL, bp, rc, -1, + need_enc, XF_ENC_UTF8); + if (cols > 0) { + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += cols; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += cols; + } + } + goto move_along; + + } else { + rc = snprintf(xbp->xb_curp, left, newfmt, newstr); + if (rc > left) { + if (!xo_buf_has_room(xbp, rc)) + return; + left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); + rc = snprintf(xbp->xb_curp, left, newfmt, newstr); + } + + if (rc > 0) { + if (xop->xo_flags & XOF_COLUMNS) + xop->xo_columns += rc; + if (xop->xo_flags & XOF_ANCHOR) + xop->xo_anchor_columns += rc; + } + } + + } else { + xo_format_data(xop, NULL, fmt, flen, 0); + + /* xo_format_data moved curp, so we need to reset it */ + rc = xbp->xb_curp - (xbp->xb_bufp + start); + xbp->xb_curp = xbp->xb_bufp + start; + } + + /* If we're styling HTML, then we need to escape it */ + if (xop->xo_style == XO_STYLE_HTML) { + rc = xo_escape_xml(xbp, rc, 0); + } + + if (rc > 0) + xbp->xb_curp += rc; + + move_along: + if (xop->xo_style == XO_STYLE_HTML) { + xo_data_append(xop, div_close, sizeof(div_close) - 1); + if (xop->xo_flags & XOF_PRETTY) + xo_data_append(xop, "\n", 1); + } +} + +static void +xo_format_prep (xo_handle_t *xop, xo_xff_flags_t flags) +{ + if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) { + xo_data_append(xop, ",", 1); + if (!(flags & XFF_LEAF_LIST) && (xop->xo_flags & XOF_PRETTY)) + xo_data_append(xop, "\n", 1); + } else + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; +} + +#if 0 +/* Useful debugging function */ +void +xo_arg (xo_handle_t *xop); +void +xo_arg (xo_handle_t *xop) +{ + xop = xo_default(xop); + fprintf(stderr, "0x%x", va_arg(xop->xo_vap, unsigned)); +} +#endif /* 0 */ + +static void +xo_format_value (xo_handle_t *xop, const char *name, int nlen, + const char *format, int flen, + const char *encoding, int elen, xo_xff_flags_t flags) +{ + int pretty = (xop->xo_flags & XOF_PRETTY); + int quote; + xo_buffer_t *xbp; + + switch (xop->xo_style) { + case XO_STYLE_TEXT: + if (flags & XFF_ENCODE_ONLY) + flags |= XFF_NO_OUTPUT; + xo_format_data(xop, NULL, format, flen, flags); + break; + + case XO_STYLE_HTML: + if (flags & XFF_ENCODE_ONLY) + flags |= XFF_NO_OUTPUT; + xo_buf_append_div(xop, "data", flags, name, nlen, + format, flen, encoding, elen); + break; + + case XO_STYLE_XML: + /* + * Even though we're not making output, we still need to + * let the formatting code handle the va_arg popping. + */ + if (flags & XFF_DISPLAY_ONLY) { + flags |= XFF_NO_OUTPUT; + xo_format_data(xop, NULL, format, flen, flags); + break; + } + + if (encoding) { + format = encoding; + flen = elen; + } else { + char *enc = alloca(flen + 1); + memcpy(enc, format, flen); + enc[flen] = '\0'; + format = xo_fix_encoding(xop, enc); + flen = strlen(format); + } + + if (nlen == 0) { + static char missing[] = "missing-field-name"; + xo_failure(xop, "missing field name: %s", format); + name = missing; + nlen = sizeof(missing) - 1; + } + + if (pretty) + xo_buf_indent(xop, -1); + xo_data_append(xop, "<", 1); + xo_data_escape(xop, name, nlen); + + if (xop->xo_attrs.xb_curp != xop->xo_attrs.xb_bufp) { + xo_data_append(xop, xop->xo_attrs.xb_bufp, + xop->xo_attrs.xb_curp - xop->xo_attrs.xb_bufp); + xop->xo_attrs.xb_curp = xop->xo_attrs.xb_bufp; + } + + /* + * We indicate 'key' fields using the 'key' attribute. While + * this is really committing the crime of mixing meta-data with + * data, it's often useful. Especially when format meta-data is + * difficult to come by. + */ + if ((flags & XFF_KEY) && (xop->xo_flags & XOF_KEYS)) { + static char attr[] = " key=\"key\""; + xo_data_append(xop, attr, sizeof(attr) - 1); + } + + /* + * Save the offset at which we'd place units. See xo_format_units. + */ + if (xop->xo_flags & XOF_UNITS) { + xop->xo_flags |= XOF_UNITS_PENDING; + xop->xo_units_offset = xop->xo_data.xb_curp -xop->xo_data.xb_bufp; + } + + xo_data_append(xop, ">", 1); + xo_format_data(xop, NULL, format, flen, flags); + xo_data_append(xop, "</", 2); + xo_data_escape(xop, name, nlen); + xo_data_append(xop, ">", 1); + if (pretty) + xo_data_append(xop, "\n", 1); + break; + + case XO_STYLE_JSON: + if (flags & XFF_DISPLAY_ONLY) { + flags |= XFF_NO_OUTPUT; + xo_format_data(xop, NULL, format, flen, flags); + break; + } + + if (encoding) { + format = encoding; + flen = elen; + } else { + char *enc = alloca(flen + 1); + memcpy(enc, format, flen); + enc[flen] = '\0'; + format = xo_fix_encoding(xop, enc); + flen = strlen(format); + } + + int first = !(xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST); + + xo_format_prep(xop, flags); + + if (flags & XFF_QUOTE) + quote = 1; + else if (flags & XFF_NOQUOTE) + quote = 0; + else if (flen == 0) { + quote = 0; + format = "true"; /* JSON encodes empty tags as a boolean true */ + flen = 4; + } else if (strchr("diouxXDOUeEfFgGaAcCp", format[flen - 1]) == NULL) + quote = 1; + else + quote = 0; + + if (nlen == 0) { + static char missing[] = "missing-field-name"; + xo_failure(xop, "missing field name: %s", format); + name = missing; + nlen = sizeof(missing) - 1; + } + + if (flags & XFF_LEAF_LIST) { + if (first && pretty) + xo_buf_indent(xop, -1); + } else { + if (pretty) + xo_buf_indent(xop, -1); + xo_data_append(xop, "\"", 1); + + xbp = &xop->xo_data; + int off = xbp->xb_curp - xbp->xb_bufp; + + xo_data_escape(xop, name, nlen); + + if (xop->xo_flags & XOF_UNDERSCORES) { + int now = xbp->xb_curp - xbp->xb_bufp; + for ( ; off < now; off++) + if (xbp->xb_bufp[off] == '-') + xbp->xb_bufp[off] = '_'; + } + xo_data_append(xop, "\":", 2); + } + + if (pretty) + xo_data_append(xop, " ", 1); + if (quote) + xo_data_append(xop, "\"", 1); + + xo_format_data(xop, NULL, format, flen, flags); + + if (quote) + xo_data_append(xop, "\"", 1); + break; + } +} + +static void +xo_format_content (xo_handle_t *xop, const char *class_name, + const char *xml_tag, int display_only, + const char *str, int len, const char *fmt, int flen) +{ + switch (xop->xo_style) { + case XO_STYLE_TEXT: + if (len) { + xo_data_append_content(xop, str, len); + } else + xo_format_data(xop, NULL, fmt, flen, 0); + break; + + case XO_STYLE_HTML: + if (len == 0) { + str = fmt; + len = flen; + } + + xo_buf_append_div(xop, class_name, 0, NULL, 0, str, len, NULL, 0); + break; + + case XO_STYLE_XML: + if (xml_tag) { + if (len == 0) { + str = fmt; + len = flen; + } + + xo_open_container_h(xop, xml_tag); + xo_format_value(xop, "message", 7, str, len, NULL, 0, 0); + xo_close_container_h(xop, xml_tag); + + } else { + /* + * Even though we don't care about labels, we need to do + * enough parsing work to skip over the right bits of xo_vap. + */ + if (len == 0) + xo_format_data(xop, NULL, fmt, flen, XFF_NO_OUTPUT); + } + break; + + case XO_STYLE_JSON: + /* + * Even though we don't care about labels, we need to do + * enough parsing work to skip over the right bits of xo_vap. + */ + if (display_only) { + if (len == 0) + xo_format_data(xop, NULL, fmt, flen, XFF_NO_OUTPUT); + break; + } + /* XXX need schem for representing errors in JSON */ + break; + } +} + +static void +xo_format_units (xo_handle_t *xop, const char *str, int len, + const char *fmt, int flen) +{ + static char units_start_xml[] = " units=\""; + static char units_start_html[] = " data-units=\""; + + if (!(xop->xo_flags & XOF_UNITS_PENDING)) { + xo_format_content(xop, "units", NULL, 1, str, len, fmt, flen); + return; + } + + xo_buffer_t *xbp = &xop->xo_data; + int start = xop->xo_units_offset; + int stop = xbp->xb_curp - xbp->xb_bufp; + + if (xop->xo_style == XO_STYLE_XML) + xo_buf_append(xbp, units_start_xml, sizeof(units_start_xml) - 1); + else if (xop->xo_style == XO_STYLE_HTML) + xo_buf_append(xbp, units_start_html, sizeof(units_start_html) - 1); + else + return; + + if (len) + xo_data_append(xop, str, len); + else + xo_format_data(xop, NULL, fmt, flen, 0); + + xo_buf_append(xbp, "\"", 1); + + int now = xbp->xb_curp - xbp->xb_bufp; + int delta = now - stop; + if (delta < 0) { /* Strange; no output to move */ + xbp->xb_curp = xbp->xb_bufp + stop; /* Reset buffer to prior state */ + return; + } + + /* + * Now we're in it alright. We've need to insert the unit value + * we just created into the right spot. We make a local copy, + * move it and then insert our copy. We know there's room in the + * buffer, since we're just moving this around. + */ + char *buf = alloca(delta); + + memcpy(buf, xbp->xb_bufp + stop, delta); + memmove(xbp->xb_bufp + start + delta, xbp->xb_bufp + start, stop - start); + memmove(xbp->xb_bufp + start, buf, delta); +} + +static int +xo_find_width (xo_handle_t *xop, const char *str, int len, + const char *fmt, int flen) +{ + long width = 0; + char *bp; + char *cp; + + if (len) { + bp = alloca(len + 1); /* Make local NUL-terminated copy of str */ + memcpy(bp, str, len); + bp[len] = '\0'; + + width = strtol(bp, &cp, 0); + if (width == LONG_MIN || width == LONG_MAX + || bp == cp || *cp != '\0' ) { + width = 0; + xo_failure(xop, "invalid width for anchor: '%s'", bp); + } + } else if (flen) { + if (flen != 2 || strncmp("%d", fmt, flen) != 0) + xo_failure(xop, "invalid width format: '%*.*s'", flen, flen, fmt); + if (!(xop->xo_flags & XOF_NO_VA_ARG)) + width = va_arg(xop->xo_vap, int); + } + + return width; +} + +static void +xo_anchor_clear (xo_handle_t *xop) +{ + xop->xo_flags &= ~XOF_ANCHOR; + xop->xo_anchor_offset = 0; + xop->xo_anchor_columns = 0; + xop->xo_anchor_min_width = 0; +} + +/* + * An anchor is a marker used to delay field width implications. + * Imagine the format string "{[:10}{min:%d}/{cur:%d}/{max:%d}{:]}". + * We are looking for output like " 1/4/5" + * + * To make this work, we record the anchor and then return to + * format it when the end anchor tag is seen. + */ +static void +xo_anchor_start (xo_handle_t *xop, const char *str, int len, + const char *fmt, int flen) +{ + if (xop->xo_style != XO_STYLE_TEXT && xop->xo_style != XO_STYLE_HTML) + return; + + if (xop->xo_flags & XOF_ANCHOR) + xo_failure(xop, "the anchor already recording is discarded"); + + xop->xo_flags |= XOF_ANCHOR; + xo_buffer_t *xbp = &xop->xo_data; + xop->xo_anchor_offset = xbp->xb_curp - xbp->xb_bufp; + xop->xo_anchor_columns = 0; + + /* + * Now we find the width, if possible. If it's not there, + * we'll get it on the end anchor. + */ + xop->xo_anchor_min_width = xo_find_width(xop, str, len, fmt, flen); +} + +static void +xo_anchor_stop (xo_handle_t *xop, const char *str, int len, + const char *fmt, int flen) +{ + if (xop->xo_style != XO_STYLE_TEXT && xop->xo_style != XO_STYLE_HTML) + return; + + if (!(xop->xo_flags & XOF_ANCHOR)) { + xo_failure(xop, "no start anchor"); + return; + } + + xop->xo_flags &= ~XOF_UNITS_PENDING; + + int width = xo_find_width(xop, str, len, fmt, flen); + if (width == 0) + width = xop->xo_anchor_min_width; + + if (width == 0) /* No width given; nothing to do */ + goto done; + + xo_buffer_t *xbp = &xop->xo_data; + int start = xop->xo_anchor_offset; + int stop = xbp->xb_curp - xbp->xb_bufp; + int abswidth = (width > 0) ? width : -width; + int blen = abswidth - xop->xo_anchor_columns; + + if (blen <= 0) /* Already over width */ + goto done; + + if (abswidth > XO_MAX_ANCHOR_WIDTH) { + xo_failure(xop, "width over %u are not supported", + XO_MAX_ANCHOR_WIDTH); + goto done; + } + + /* Make a suitable padding field and emit it */ + char *buf = alloca(blen); + memset(buf, ' ', blen); + xo_format_content(xop, "padding", NULL, 1, buf, blen, NULL, 0); + + if (width < 0) /* Already left justified */ + goto done; + + int now = xbp->xb_curp - xbp->xb_bufp; + int delta = now - stop; + if (delta < 0) /* Strange; no output to move */ + goto done; + + /* + * Now we're in it alright. We've need to insert the padding data + * we just created (which might be an HTML <div> or text) before + * the formatted data. We make a local copy, move it and then + * insert our copy. We know there's room in the buffer, since + * we're just moving this around. + */ + if (delta > blen) + buf = alloca(delta); /* Expand buffer if needed */ + + memcpy(buf, xbp->xb_bufp + stop, delta); + memmove(xbp->xb_bufp + start + delta, xbp->xb_bufp + start, stop - start); + memmove(xbp->xb_bufp + start, buf, delta); + + done: + xo_anchor_clear(xop); +} + +static int +xo_do_emit (xo_handle_t *xop, const char *fmt) +{ + int rc = 0; + const char *cp, *sp, *ep, *basep; + char *newp = NULL; + int flush = (xop->xo_flags & XOF_FLUSH) ? 1 : 0; + + xop->xo_columns = 0; /* Always reset it */ + + for (cp = fmt; *cp; ) { + if (*cp == '\n') { + xo_line_close(xop); + xo_flush_h(xop); + cp += 1; + continue; + + } else if (*cp == '{') { + if (cp[1] == '{') { /* Start of {{escaped braces}} */ + + cp += 2; /* Skip over _both_ characters */ + for (sp = cp; *sp; sp++) { + if (*sp == '}' && sp[1] == '}') + break; + } + if (*sp == '\0') { + xo_failure(xop, "missing closing '}}': %s", fmt); + return -1; + } + + xo_format_text(xop, cp, sp - cp); + + /* Move along the string, but don't run off the end */ + if (*sp == '}' && sp[1] == '}') + sp += 2; + cp = *sp ? sp + 1 : sp; + continue; + } + /* Else fall thru to the code below */ + + } else { + /* Normal text */ + for (sp = cp; *sp; sp++) { + if (*sp == '{' || *sp == '\n') + break; + } + xo_format_text(xop, cp, sp - cp); + + cp = sp; + continue; + } + + basep = cp + 1; + + /* + * We are looking at the start of a field definition. The format is: + * '{' modifiers ':' content [ '/' print-fmt [ '/' encode-fmt ]] '}' + * Modifiers are optional and include the following field types: + * 'D': decoration; something non-text and non-data (colons, commmas) + * 'E': error message + * 'L': label; text preceding data + * 'N': note; text following data + * 'P': padding; whitespace + * 'T': Title, where 'content' is a column title + * 'U': Units, where 'content' is the unit label + * 'V': value, where 'content' is the name of the field (the default) + * 'W': warning message + * '[': start a section of anchored text + * ']': end a section of anchored text + * The following flags are also supported: + * 'c': flag: emit a colon after the label + * 'd': field is only emitted for display formats (text and html) + * 'e': field is only emitted for encoding formats (xml and json) + * 'k': this field is a key, suitable for XPath predicates + * 'l': a leaf-list, a simple list of values + * 'n': no quotes around this field + * 'q': add quotes around this field + * 't': trim whitespace around the value + * 'w': emit a blank after the label + * The print-fmt and encode-fmt strings is the printf-style formating + * for this data. JSON and XML will use the encoding-fmt, if present. + * If the encode-fmt is not provided, it defaults to the print-fmt. + * If the print-fmt is not provided, it defaults to 's'. + */ + unsigned ftype = 0, flags = 0; + const char *content = NULL, *format = NULL, *encoding = NULL; + int clen = 0, flen = 0, elen = 0; + + for (sp = basep; sp; sp++) { + if (*sp == ':' || *sp == '/' || *sp == '}') + break; + + if (*sp == '\\') { + if (sp[1] == '\0') { + xo_failure(xop, "backslash at the end of string"); + return -1; + } + sp += 1; + continue; + } + + switch (*sp) { + case 'D': + case 'E': + case 'L': + case 'N': + case 'P': + case 'T': + case 'U': + case 'V': + case 'W': + case '[': + case ']': + if (ftype != 0) { + xo_failure(xop, "field descriptor uses multiple types: %s", + fmt); + return -1; + } + ftype = *sp; + break; + + case 'c': + flags |= XFF_COLON; + break; + + case 'd': + flags |= XFF_DISPLAY_ONLY; + break; + + case 'e': + flags |= XFF_ENCODE_ONLY; + break; + + case 'k': + flags |= XFF_KEY; + break; + + case 'l': + flags |= XFF_LEAF_LIST; + break; + + case 'n': + flags |= XFF_NOQUOTE; + break; + + case 'q': + flags |= XFF_QUOTE; + break; + + case 't': + flags |= XFF_TRIM_WS; + break; + + case 'w': + flags |= XFF_WS; + break; + + default: + xo_failure(xop, "field descriptor uses unknown modifier: %s", + fmt); + /* + * No good answer here; a bad format will likely + * mean a core file. We just return and hope + * the caller notices there's no output, and while + * that seems, well, bad. There's nothing better. + */ + return -1; + } + } + + if (*sp == ':') { + for (ep = ++sp; *sp; sp++) { + if (*sp == '}' || *sp == '/') + break; + if (*sp == '\\') { + if (sp[1] == '\0') { + xo_failure(xop, "backslash at the end of string"); + return -1; + } + sp += 1; + continue; + } + } + if (ep != sp) { + clen = sp - ep; + content = ep; + } + } else { + xo_failure(xop, "missing content (':'): %s", fmt); + return -1; + } + + if (*sp == '/') { + for (ep = ++sp; *sp; sp++) { + if (*sp == '}' || *sp == '/') + break; + if (*sp == '\\') { + if (sp[1] == '\0') { + xo_failure(xop, "backslash at the end of string"); + return -1; + } + sp += 1; + continue; + } + } + flen = sp - ep; + format = ep; + } + + if (*sp == '/') { + for (ep = ++sp; *sp; sp++) { + if (*sp == '}') + break; + } + elen = sp - ep; + encoding = ep; + } + + if (*sp == '}') { + sp += 1; + } else { + xo_failure(xop, "missing closing '}': %s", fmt); + return -1; + } + + if (format == NULL && ftype != '[' && ftype != ']' ) { + format = "%s"; + flen = 2; + } + + if (ftype == 0 || ftype == 'V') + xo_format_value(xop, content, clen, format, flen, + encoding, elen, flags); + else if (ftype == 'D') + xo_format_content(xop, "decoration", NULL, 1, + content, clen, format, flen); + else if (ftype == 'E') + xo_format_content(xop, "error", "error", 0, + content, clen, format, flen); + else if (ftype == 'L') + xo_format_content(xop, "label", NULL, 1, + content, clen, format, flen); + else if (ftype == 'N') + xo_format_content(xop, "note", NULL, 1, + content, clen, format, flen); + else if (ftype == 'P') + xo_format_content(xop, "padding", NULL, 1, + content, clen, format, flen); + else if (ftype == 'T') + xo_format_title(xop, content, clen, format, flen); + else if (ftype == 'U') { + if (flags & XFF_WS) + xo_format_content(xop, "padding", NULL, 1, " ", 1, NULL, 0); + xo_format_units(xop, content, clen, format, flen); + } else if (ftype == 'W') + xo_format_content(xop, "warning", "warning", 0, + content, clen, format, flen); + else if (ftype == '[') + xo_anchor_start(xop, content, clen, format, flen); + else if (ftype == ']') + xo_anchor_stop(xop, content, clen, format, flen); + + if (flags & XFF_COLON) + xo_format_content(xop, "decoration", NULL, 1, ":", 1, NULL, 0); + if (ftype != 'U' && (flags & XFF_WS)) + xo_format_content(xop, "padding", NULL, 1, " ", 1, NULL, 0); + + cp += sp - basep + 1; + if (newp) { + xo_free(newp); + newp = NULL; + } + } + + /* If we don't have an anchor, write the text out */ + if (flush && !(xop->xo_flags & XOF_ANCHOR)) + xo_write(xop); + + return (rc < 0) ? rc : (int) xop->xo_columns; +} + +int +xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap) +{ + int rc; + + xop = xo_default(xop); + va_copy(xop->xo_vap, vap); + rc = xo_do_emit(xop, fmt); + va_end(xop->xo_vap); + bzero(&xop->xo_vap, sizeof(xop->xo_vap)); + + return rc; +} + +int +xo_emit_h (xo_handle_t *xop, const char *fmt, ...) +{ + int rc; + + xop = xo_default(xop); + va_start(xop->xo_vap, fmt); + rc = xo_do_emit(xop, fmt); + va_end(xop->xo_vap); + bzero(&xop->xo_vap, sizeof(xop->xo_vap)); + + return rc; +} + +int +xo_emit (const char *fmt, ...) +{ + xo_handle_t *xop = xo_default(NULL); + int rc; + + va_start(xop->xo_vap, fmt); + rc = xo_do_emit(xop, fmt); + va_end(xop->xo_vap); + bzero(&xop->xo_vap, sizeof(xop->xo_vap)); + + return rc; +} + +int +xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap) +{ + const int extra = 5; /* space, equals, quote, quote, and nul */ + xop = xo_default(xop); + + if (xop->xo_style != XO_STYLE_XML) + return 0; + + int nlen = strlen(name); + xo_buffer_t *xbp = &xop->xo_attrs; + + if (!xo_buf_has_room(xbp, nlen + extra)) + return -1; + + *xbp->xb_curp++ = ' '; + memcpy(xbp->xb_curp, name, nlen); + xbp->xb_curp += nlen; + *xbp->xb_curp++ = '='; + *xbp->xb_curp++ = '"'; + + int rc = xo_vsnprintf(xop, xbp, fmt, vap); + + if (rc > 0) { + rc = xo_escape_xml(xbp, rc, 1); + xbp->xb_curp += rc; + } + + if (!xo_buf_has_room(xbp, 2)) + return -1; + + *xbp->xb_curp++ = '"'; + *xbp->xb_curp = '\0'; + + return rc + nlen + extra; +} + +int +xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...) +{ + int rc; + va_list vap; + + va_start(vap, fmt); + rc = xo_attr_hv(xop, name, fmt, vap); + va_end(vap); + + return rc; +} + +int +xo_attr (const char *name, const char *fmt, ...) +{ + int rc; + va_list vap; + + va_start(vap, fmt); + rc = xo_attr_hv(NULL, name, fmt, vap); + va_end(vap); + + return rc; +} + +static void +xo_stack_set_flags (xo_handle_t *xop) +{ + if (xop->xo_flags & XOF_NOT_FIRST) { + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth]; + + xsp->xs_flags |= XSF_NOT_FIRST; + xop->xo_flags &= ~XOF_NOT_FIRST; + } +} + +static void +xo_depth_change (xo_handle_t *xop, const char *name, + int delta, int indent, xo_xsf_flags_t flags) +{ + if (xop->xo_flags & XOF_DTRT) + flags |= XSF_DTRT; + + if (delta >= 0) { /* Push operation */ + if (xo_depth_check(xop, xop->xo_depth + delta)) + return; + + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth + delta]; + xsp->xs_flags = flags; + xo_stack_set_flags(xop); + + unsigned save = (xop->xo_flags & (XOF_XPATH | XOF_WARN | XOF_DTRT)); + save |= (flags & XSF_DTRT); + + if (name && save) { + int len = strlen(name) + 1; + char *cp = xo_realloc(NULL, len); + if (cp) { + memcpy(cp, name, len); + xsp->xs_name = cp; + } + } + + } else { /* Pop operation */ + if (xop->xo_depth == 0) { + if (!(xop->xo_flags & XOF_IGNORE_CLOSE)) + xo_failure(xop, "close with empty stack: '%s'", name); + return; + } + + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth]; + if (xop->xo_flags & XOF_WARN) { + const char *top = xsp->xs_name; + if (top && strcmp(name, top) != 0) { + xo_failure(xop, "incorrect close: '%s' .vs. '%s'", + name, top); + return; + } + if ((xsp->xs_flags & XSF_LIST) != (flags & XSF_LIST)) { + xo_failure(xop, "list close on list confict: '%s'", + name); + return; + } + if ((xsp->xs_flags & XSF_INSTANCE) != (flags & XSF_INSTANCE)) { + xo_failure(xop, "list close on instance confict: '%s'", + name); + return; + } + } + + if (xsp->xs_name) { + xo_free(xsp->xs_name); + xsp->xs_name = NULL; + } + if (xsp->xs_keys) { + xo_free(xsp->xs_keys); + xsp->xs_keys = NULL; + } + } + + xop->xo_depth += delta; /* Record new depth */ + xop->xo_indent += indent; +} + +void +xo_set_depth (xo_handle_t *xop, int depth) +{ + xop = xo_default(xop); + + if (xo_depth_check(xop, depth)) + return; + + xop->xo_depth += depth; + xop->xo_indent += depth; +} + +static xo_xsf_flags_t +xo_stack_flags (unsigned xflags) +{ + if (xflags & XOF_DTRT) + return XSF_DTRT; + return 0; +} + +static int +xo_open_container_hf (xo_handle_t *xop, xo_xof_flags_t flags, const char *name) +{ + xop = xo_default(xop); + + int rc = 0; + const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + + if (name == NULL) { + xo_failure(xop, "NULL passed for container name"); + name = XO_FAILURE_NAME; + } + + flags |= xop->xo_flags; /* Pick up handle flags */ + + switch (xop->xo_style) { + case XO_STYLE_XML: + rc = xo_printf(xop, "%*s<%s>%s", xo_indent(xop), "", + name, ppn); + xo_depth_change(xop, name, 1, 1, xo_stack_flags(flags)); + break; + + case XO_STYLE_JSON: + xo_stack_set_flags(xop); + + if (!(xop->xo_flags & XOF_NO_TOP)) { + if (!(xop->xo_flags & XOF_TOP_EMITTED)) { + xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn); + xop->xo_flags |= XOF_TOP_EMITTED; + } + } + + if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) + pre_nl = (xop->xo_flags & XOF_PRETTY) ? ",\n" : ", "; + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + + rc = xo_printf(xop, "%s%*s\"%s\": {%s", + pre_nl, xo_indent(xop), "", name, ppn); + xo_depth_change(xop, name, 1, 1, xo_stack_flags(flags)); + break; + + case XO_STYLE_HTML: + case XO_STYLE_TEXT: + xo_depth_change(xop, name, 1, 0, xo_stack_flags(flags)); + break; + } + + return rc; +} + +int +xo_open_container_h (xo_handle_t *xop, const char *name) +{ + return xo_open_container_hf(xop, 0, name); +} + +int +xo_open_container (const char *name) +{ + return xo_open_container_hf(NULL, 0, name); +} + +int +xo_open_container_hd (xo_handle_t *xop, const char *name) +{ + return xo_open_container_hf(xop, XOF_DTRT, name); +} + +int +xo_open_container_d (const char *name) +{ + return xo_open_container_hf(NULL, XOF_DTRT, name); +} + +int +xo_close_container_h (xo_handle_t *xop, const char *name) +{ + xop = xo_default(xop); + + int rc = 0; + const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + + if (name == NULL) { + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth]; + if (!(xsp->xs_flags & XSF_DTRT)) + xo_failure(xop, "missing name without 'dtrt' mode"); + + name = xsp->xs_name; + if (name) { + int len = strlen(name) + 1; + /* We need to make a local copy; xo_depth_change will free it */ + char *cp = alloca(len); + memcpy(cp, name, len); + name = cp; + } else + name = XO_FAILURE_NAME; + } + + switch (xop->xo_style) { + case XO_STYLE_XML: + xo_depth_change(xop, name, -1, -1, 0); + rc = xo_printf(xop, "%*s</%s>%s", xo_indent(xop), "", name, ppn); + break; + + case XO_STYLE_JSON: + pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + ppn = (xop->xo_depth <= 1) ? "\n" : ""; + + xo_depth_change(xop, name, -1, -1, 0); + rc = xo_printf(xop, "%s%*s}%s", pre_nl, xo_indent(xop), "", ppn); + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + break; + + case XO_STYLE_HTML: + case XO_STYLE_TEXT: + xo_depth_change(xop, name, -1, 0, 0); + break; + } + + return rc; +} + +int +xo_close_container (const char *name) +{ + return xo_close_container_h(NULL, name); +} + +int +xo_close_container_hd (xo_handle_t *xop) +{ + return xo_close_container_h(xop, NULL); +} + +int +xo_close_container_d (void) +{ + return xo_close_container_h(NULL, NULL); +} + +static int +xo_open_list_hf (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) +{ + xop = xo_default(xop); + + if (xop->xo_style != XO_STYLE_JSON) + return 0; + + int rc = 0; + const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + + if (!(xop->xo_flags & XOF_NO_TOP)) { + if (!(xop->xo_flags & XOF_TOP_EMITTED)) { + xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn); + xop->xo_flags |= XOF_TOP_EMITTED; + } + } + + if (name == NULL) { + xo_failure(xop, "NULL passed for list name"); + name = XO_FAILURE_NAME; + } + + xo_stack_set_flags(xop); + + if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) + pre_nl = (xop->xo_flags & XOF_PRETTY) ? ",\n" : ", "; + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + + rc = xo_printf(xop, "%s%*s\"%s\": [%s", + pre_nl, xo_indent(xop), "", name, ppn); + xo_depth_change(xop, name, 1, 1, XSF_LIST | xo_stack_flags(flags)); + + return rc; +} + +int +xo_open_list_h (xo_handle_t *xop, const char *name UNUSED) +{ + return xo_open_list_hf(xop, 0, name); +} + +int +xo_open_list (const char *name) +{ + return xo_open_list_hf(NULL, 0, name); +} + +int +xo_open_list_hd (xo_handle_t *xop, const char *name UNUSED) +{ + return xo_open_list_hf(xop, XOF_DTRT, name); +} + +int +xo_open_list_d (const char *name) +{ + return xo_open_list_hf(NULL, XOF_DTRT, name); +} + +int +xo_close_list_h (xo_handle_t *xop, const char *name) +{ + int rc = 0; + const char *pre_nl = ""; + + xop = xo_default(xop); + + if (xop->xo_style != XO_STYLE_JSON) + return 0; + + if (name == NULL) { + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth]; + if (!(xsp->xs_flags & XSF_DTRT)) + xo_failure(xop, "missing name without 'dtrt' mode"); + + name = xsp->xs_name; + if (name) { + int len = strlen(name) + 1; + /* We need to make a local copy; xo_depth_change will free it */ + char *cp = alloca(len); + memcpy(cp, name, len); + name = cp; + } else + name = XO_FAILURE_NAME; + } + + if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) + pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + + xo_depth_change(xop, name, -1, -1, XSF_LIST); + rc = xo_printf(xop, "%s%*s]", pre_nl, xo_indent(xop), ""); + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + + return 0; +} + +int +xo_close_list (const char *name) +{ + return xo_close_list_h(NULL, name); +} + +int +xo_close_list_hd (xo_handle_t *xop) +{ + return xo_close_list_h(xop, NULL); +} + +int +xo_close_list_d (void) +{ + return xo_close_list_h(NULL, NULL); +} + +static int +xo_open_instance_hf (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name) +{ + xop = xo_default(xop); + + int rc = 0; + const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + + flags |= xop->xo_flags; + + if (name == NULL) { + xo_failure(xop, "NULL passed for instance name"); + name = XO_FAILURE_NAME; + } + + switch (xop->xo_style) { + case XO_STYLE_XML: + rc = xo_printf(xop, "%*s<%s>%s", xo_indent(xop), "", name, ppn); + xo_depth_change(xop, name, 1, 1, xo_stack_flags(flags)); + break; + + case XO_STYLE_JSON: + xo_stack_set_flags(xop); + + if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST) + pre_nl = (xop->xo_flags & XOF_PRETTY) ? ",\n" : ", "; + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + + rc = xo_printf(xop, "%s%*s{%s", + pre_nl, xo_indent(xop), "", ppn); + xo_depth_change(xop, name, 1, 1, xo_stack_flags(flags)); + break; + + case XO_STYLE_HTML: + case XO_STYLE_TEXT: + xo_depth_change(xop, name, 1, 0, xo_stack_flags(flags)); + break; + } + + return rc; +} + +int +xo_open_instance_h (xo_handle_t *xop, const char *name) +{ + return xo_open_instance_hf(xop, 0, name); +} + +int +xo_open_instance (const char *name) +{ + return xo_open_instance_hf(NULL, 0, name); +} + +int +xo_open_instance_hd (xo_handle_t *xop, const char *name) +{ + return xo_open_instance_hf(xop, XOF_DTRT, name); +} + +int +xo_open_instance_d (const char *name) +{ + return xo_open_instance_hf(NULL, XOF_DTRT, name); +} + +int +xo_close_instance_h (xo_handle_t *xop, const char *name) +{ + xop = xo_default(xop); + + int rc = 0; + const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + const char *pre_nl = ""; + + if (name == NULL) { + xo_stack_t *xsp = &xop->xo_stack[xop->xo_depth]; + if (!(xsp->xs_flags & XSF_DTRT)) + xo_failure(xop, "missing name without 'dtrt' mode"); + + name = xsp->xs_name; + if (name) { + int len = strlen(name) + 1; + /* We need to make a local copy; xo_depth_change will free it */ + char *cp = alloca(len); + memcpy(cp, name, len); + name = cp; + } else + name = XO_FAILURE_NAME; + } + + switch (xop->xo_style) { + case XO_STYLE_XML: + xo_depth_change(xop, name, -1, -1, 0); + rc = xo_printf(xop, "%*s</%s>%s", xo_indent(xop), "", name, ppn); + break; + + case XO_STYLE_JSON: + pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : ""; + + xo_depth_change(xop, name, -1, -1, 0); + rc = xo_printf(xop, "%s%*s}", pre_nl, xo_indent(xop), ""); + xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; + break; + + case XO_STYLE_HTML: + case XO_STYLE_TEXT: + xo_depth_change(xop, name, -1, 0, 0); + break; + } + + return rc; +} + +int +xo_close_instance (const char *name) +{ + return xo_close_instance_h(NULL, name); +} + +int +xo_close_instance_hd (xo_handle_t *xop) +{ + return xo_close_instance_h(xop, NULL); +} + +int +xo_close_instance_d (void) +{ + return xo_close_instance_h(NULL, NULL); +} + +void +xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func, + xo_close_func_t close_func) +{ + xop = xo_default(xop); + + xop->xo_opaque = opaque; + xop->xo_write = write_func; + xop->xo_close = close_func; +} + +void +xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func) +{ + xo_realloc = realloc_func; + xo_free = free_func; +} + +void +xo_flush_h (xo_handle_t *xop) +{ + static char div_close[] = "</div>"; + + xop = xo_default(xop); + + switch (xop->xo_style) { + case XO_STYLE_HTML: + if (xop->xo_flags & XOF_DIV_OPEN) { + xop->xo_flags &= ~XOF_DIV_OPEN; + xo_data_append(xop, div_close, sizeof(div_close) - 1); + + if (xop->xo_flags & XOF_PRETTY) + xo_data_append(xop, "\n", 1); + } + break; + } + + xo_write(xop); +} + +void +xo_flush (void) +{ + xo_flush_h(NULL); +} + +void +xo_finish_h (xo_handle_t *xop) +{ + const char *cp = ""; + xop = xo_default(xop); + + switch (xop->xo_style) { + case XO_STYLE_JSON: + if (!(xop->xo_flags & XOF_NO_TOP)) { + if (xop->xo_flags & XOF_TOP_EMITTED) + xop->xo_flags &= ~XOF_TOP_EMITTED; /* Turn off before output */ + else + cp = "{ "; + xo_printf(xop, "%*s%s}\n",xo_indent(xop), "", cp); + } + break; + } + + xo_flush_h(xop); +} + +void +xo_finish (void) +{ + xo_finish_h(NULL); +} + +/* + * Generate an error message, such as would be displayed on stderr + */ +void +xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) +{ + xop = xo_default(xop); + + /* + * If the format string doesn't end with a newline, we pop + * one on ourselves. + */ + int len = strlen(fmt); + if (len > 0 && fmt[len - 1] != '\n') { + char *newfmt = alloca(len + 2); + memcpy(newfmt, fmt, len); + newfmt[len] = '\n'; + newfmt[len] = '\0'; + fmt = newfmt; + } + + switch (xop->xo_style) { + case XO_STYLE_TEXT: + vfprintf(stderr, fmt, vap); + break; + + case XO_STYLE_HTML: + va_copy(xop->xo_vap, vap); + + xo_buf_append_div(xop, "error", 0, NULL, 0, fmt, strlen(fmt), NULL, 0); + + if (xop->xo_flags & XOF_DIV_OPEN) + xo_line_close(xop); + + xo_write(xop); + + va_end(xop->xo_vap); + bzero(&xop->xo_vap, sizeof(xop->xo_vap)); + break; + + case XO_STYLE_XML: + va_copy(xop->xo_vap, vap); + + xo_open_container_h(xop, "error"); + xo_format_value(xop, "message", 7, fmt, strlen(fmt), NULL, 0, 0); + xo_close_container_h(xop, "error"); + + va_end(xop->xo_vap); + bzero(&xop->xo_vap, sizeof(xop->xo_vap)); + break; + } +} + +void +xo_error_h (xo_handle_t *xop, const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_error_hv(xop, fmt, vap); + va_end(vap); +} + +/* + * Generate an error message, such as would be displayed on stderr + */ +void +xo_error (const char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + xo_error_hv(NULL, fmt, vap); + va_end(vap); +} + +int +xo_parse_args (int argc, char **argv) +{ + static char libxo_opt[] = "--libxo"; + char *cp; + int i, save; + + /* Save our program name for xo_err and friends */ + xo_program = argv[0]; + cp = strrchr(xo_program, '/'); + if (cp) + xo_program = cp + 1; + + for (save = i = 1; i < argc; i++) { + if (argv[i] == NULL + || strncmp(argv[i], libxo_opt, sizeof(libxo_opt) - 1) != 0) { + if (save != i) + argv[save] = argv[i]; + save += 1; + continue; + } + + cp = argv[i] + sizeof(libxo_opt) - 1; + if (*cp == 0) { + cp = argv[++i]; + if (cp == 0) { + xo_warnx("missing libxo option"); + return -1; + } + + if (xo_set_options(NULL, cp) < 0) + return -1; + } else if (*cp == ':') { + if (xo_set_options(NULL, cp) < 0) + return -1; + + } else if (*cp == '=') { + if (xo_set_options(NULL, ++cp) < 0) + return -1; + + } else if (*cp == '-') { + cp += 1; + if (strcmp(cp, "check") == 0) { + exit(XO_HAS_LIBXO); + + } else { + xo_warnx("unknown libxo option: '%s'", argv[i]); + return -1; + } + } else { + xo_warnx("unknown libxo option: '%s'", argv[i]); + return -1; + } + } + + argv[save] = NULL; + return save; +} + +#ifdef UNIT_TEST +int +main (int argc, char **argv) +{ + static char base_grocery[] = "GRO"; + static char base_hardware[] = "HRD"; + struct item { + const char *i_title; + int i_sold; + int i_instock; + int i_onorder; + const char *i_sku_base; + int i_sku_num; + }; + struct item list[] = { + { "gum&this&that", 1412, 54, 10, base_grocery, 415 }, + { "<rope>", 85, 4, 2, base_hardware, 212 }, + { "ladder", 0, 2, 1, base_hardware, 517 }, + { "\"bolt\"", 4123, 144, 42, base_hardware, 632 }, + { "water\\blue", 17, 14, 2, base_grocery, 2331 }, + { NULL, 0, 0, 0, NULL, 0 } + }; + struct item list2[] = { + { "fish", 1321, 45, 1, base_grocery, 533 }, + { NULL, 0, 0, 0, NULL, 0 } + }; + struct item *ip; + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + { NULL, NULL, NULL }, + }; + int info_count = (sizeof(info) / sizeof(info[0])) - 1; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); + + xo_set_info(NULL, info, info_count); + + xo_open_container_h(NULL, "top"); + + xo_open_container("data"); + xo_open_list("item"); + + xo_emit("{T:Item/%-15s}{T:Total Sold/%12s}{T:In Stock/%12s}" + "{T:On Order/%12s}{T:SKU/%5s}\n"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{k:name/%-15s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}" + "{:on-order/%12u/%u} {q:sku/%5s-000-%u/%s-000-%u}\n", + ip->i_title, ip->i_sold, ip->i_instock, ip->i_onorder, + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_emit("\n\n"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_attr("fancy", "%s%d", "item", ip - list); + xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}{e:percent/%u}\n", + ip->i_sold, ip->i_sold ? ".0" : "", 44); + xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); + xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); + xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list2; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); + xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); + xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_open_list("month"); + + const char *months[] = { "Jan", "Feb", "Mar", NULL }; + int discounts[] = { 10, 20, 25, 0 }; + int i; + for (i = 0; months[i]; i++) { + xo_open_instance("month"); + xo_emit("{P: }" + "{Lwc:Month}{k:month}, {Lwc:Special}{:discount/%d}\n", + months[i], discounts[i]); + xo_close_instance("month"); + } + + xo_close_list("month"); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_close_container_h(NULL, "top"); + + xo_finish(); + + return 0; +} +#endif /* UNIT_TEST */ diff --git a/contrib/libxo/libxo/xo.h b/contrib/libxo/libxo/xo.h new file mode 100644 index 0000000..3a59e4c --- /dev/null +++ b/contrib/libxo/libxo/xo.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +/** + * libxo provides a means of generating text, XML, and JSON output + * using a single set of function calls, maximizing the value of output + * while minimizing the cost/impact on the code. + */ + +#ifndef INCLUDE_XO_H +#define INCLUDE_XO_H + +/** Formatting types */ +typedef unsigned xo_style_t; +#define XO_STYLE_TEXT 0 /** Generate text output */ +#define XO_STYLE_XML 1 /** Generate XML output */ +#define XO_STYLE_JSON 2 /** Generate JSON output */ +#define XO_STYLE_HTML 3 /** Generate HTML output */ + +/** Flags for libxo */ +typedef unsigned long xo_xof_flags_t; +#define XOF_CLOSE_FP (1<<0) /** Close file pointer on xo_close() */ +#define XOF_PRETTY (1<<1) /** Make 'pretty printed' output */ +#define XOF_DIV_OPEN (1<<2) /** Internal use only: a <div> is open */ +#define XOF_LINE_OPEN (1<<3) /** Internal use only: a <div class="line"> */ + +#define XOF_WARN (1<<4) /** Generate warnings for broken calls */ +#define XOF_XPATH (1<<5) /** Emit XPath attributes in HTML */ +#define XOF_INFO (1<<6) /** Emit additional info fields (HTML) */ +#define XOF_WARN_XML (1<<7) /** Emit warnings in XML (on stdout) */ + +#define XOF_NO_ENV (1<<8) /** Don't look at the LIBXO_OPTIONS env var */ +#define XOF_NO_VA_ARG (1<<9) /** Don't advance va_list w/ va_arg() */ +#define XOF_DTRT (1<<10) /** Enable "do the right thing" mode */ +#define XOF_KEYS (1<<11) /** Flag 'key' fields for xml and json */ + +#define XOF_IGNORE_CLOSE (1<<12) /** Ignore errors on close tags */ +#define XOF_NOT_FIRST (1<<13) /* Not the first item (JSON) */ +#define XOF_NO_LOCALE (1<<14) /** Don't bother with locale */ +#define XOF_TOP_EMITTED (1<<15) /* The top JSON braces have been emitted */ + +#define XOF_NO_TOP (1<<16) /** Don't emit the top braces in JSON */ +#define XOF_ANCHOR (1<<17) /** An anchor is in place */ +#define XOF_UNITS (1<<18) /** Encode units in XML */ +#define XOF_UNITS_PENDING (1<<19) /** We have a units-insertion pending */ + +#define XOF_UNDERSCORES (1<<20) /** Replace dashes with underscores (JSON) */ +#define XOF_COLUMNS (1<<21) /** xo_emit should return a column count */ +#define XOF_FLUSH (1<<22) /** Flush after each xo_emit call */ + +/* + * The xo_info_t structure provides a mapping between names and + * additional data emitted via HTML. + */ +typedef struct xo_info_s { + const char *xi_name; /* Name of the element */ + const char *xi_type; /* Type of field */ + const char *xi_help; /* Description of field */ +} xo_info_t; + +struct xo_handle_s; /* Opaque structure forward */ +typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */ + +typedef int (*xo_write_func_t)(void *, const char *); +typedef void (*xo_close_func_t)(void *); +typedef void *(*xo_realloc_func_t)(void *, size_t); +typedef void (*xo_free_func_t)(void *); + +/* + * The formatter function mirrors "vsnprintf", with an additional argument + * of the xo handle. The caller should return the number of bytes _needed_ + * to fit the data, even if this exceeds 'len'. + */ +typedef int (*xo_formatter_t)(xo_handle_t *, char *, int, + const char *, va_list); +typedef void (*xo_checkpointer_t)(xo_handle_t *, va_list, int); + +xo_handle_t * +xo_create (xo_style_t style, xo_xof_flags_t flags); + +xo_handle_t * +xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags); + +void +xo_destroy (xo_handle_t *xop); + +void +xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func, + xo_close_func_t close_func); + +void +xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func); + +void +xo_set_style (xo_handle_t *xop, xo_style_t style); + +xo_style_t +xo_get_style (xo_handle_t *xop); + +int +xo_set_style_name (xo_handle_t *xop, const char *style); + +int +xo_set_options (xo_handle_t *xop, const char *input); + +xo_xof_flags_t +xo_get_flags (xo_handle_t *xop); + +void +xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags); + +void +xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags); + +void +xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count); + +void +xo_set_formatter (xo_handle_t *xop, xo_formatter_t func, xo_checkpointer_t); + +void +xo_set_depth (xo_handle_t *xop, int depth); + +int +xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap); + +int +xo_emit_h (xo_handle_t *xop, const char *fmt, ...); + +int +xo_emit (const char *fmt, ...); + +int +xo_open_container_h (xo_handle_t *xop, const char *name); + +int +xo_open_container (const char *name); + +int +xo_open_container_hd (xo_handle_t *xop, const char *name); + +int +xo_open_container_d (const char *name); + +int +xo_close_container_h (xo_handle_t *xop, const char *name); + +int +xo_close_container (const char *name); + +int +xo_close_container_hd (xo_handle_t *xop); + +int +xo_close_container_d (void); + +int +xo_open_list_h (xo_handle_t *xop, const char *name); + +int +xo_open_list (const char *name); + +int +xo_open_list_hd (xo_handle_t *xop, const char *name); + +int +xo_open_list_d (const char *name); + +int +xo_close_list_h (xo_handle_t *xop, const char *name); + +int +xo_close_list (const char *name); + +int +xo_close_list_hd (xo_handle_t *xop); + +int +xo_close_list_d (void); + +int +xo_open_instance_h (xo_handle_t *xop, const char *name); + +int +xo_open_instance (const char *name); + +int +xo_open_instance_hd (xo_handle_t *xop, const char *name); + +int +xo_open_instance_d (const char *name); + +int +xo_close_instance_h (xo_handle_t *xop, const char *name); + +int +xo_close_instance (const char *name); + +int +xo_close_instance_hd (xo_handle_t *xop); + +int +xo_close_instance_d (void); + +int +xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...); + +int +xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap); + +int +xo_attr (const char *name, const char *fmt, ...); + +void +xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap); + +void +xo_error_h (xo_handle_t *xop, const char *fmt, ...); + +void +xo_error (const char *fmt, ...); + +void +xo_flush_h (xo_handle_t *xop); + +void +xo_flush (void); + +void +xo_finish_h (xo_handle_t *xop); + +void +xo_finish (void); + +void +xo_set_leading_xpath (xo_handle_t *xop, const char *path); + +void +xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...); + +void +xo_warn_c (int code, const char *fmt, ...); + +void +xo_warn (const char *fmt, ...); + +void +xo_warnx (const char *fmt, ...); + +void +xo_err (int eval, const char *fmt, ...); + +void +xo_errx (int eval, const char *fmt, ...); + +void +xo_errc (int eval, int code, const char *fmt, ...); + +void +xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap); + +void +xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...); + +void +xo_message_c (int code, const char *fmt, ...); + +void +xo_message (const char *fmt, ...); + +void +xo_no_setlocale (void); + +int +xo_parse_args (int argc, char **argv); + +/* + * This is the "magic" number returned by libxo-supporting commands + * when passed the equally magic "--libxo-check" option. If you + * return this, we can assume that since you know the magic handshake, + * you'll happily handle future --libxo options and not do something + * violent like reboot the box or create another hole in the ozone + * layer. + */ +#define XO_HAS_LIBXO 121 + +/* + * externs for our version number strings + */ +extern const char xo_version[]; +extern const char xo_version_extra[]; + +#endif /* INCLUDE_XO_H */ diff --git a/contrib/libxo/libxo/xo_attr.3 b/contrib/libxo/libxo/xo_attr.3 new file mode 100644 index 0000000..afd805f --- /dev/null +++ b/contrib/libxo/libxo/xo_attr.3 @@ -0,0 +1,77 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft int +.Fn xo_attr "const char *name" "const char *fmt" "..." +.Ft int +.Fn xo_attr_h "xo_handle_t *handle" "const char *name, const char *fmt" "..." +.Ft int +.Fn xo_attr_hv "xo_handle_t *handle" "const char *name" "const char *fmt" "va_list vap" +.Sh DESCRIPTION +The +.Fn xo_attr +function emits attributes for the XML output style. The attribute +value is recorded in the +.Fa handle +and is attached to the next field that is emitted via a +.Xr xo_emit 3 +call. +.Pp +The +.Fa name +parameter give the name of the attribute to be encoded. The +.Fa fmt +parameter gives a printf-style format string used to format the +value of the attribute using any remaining arguments, or the +.Fa vap +parameter as passed to +.Fn xo_attr_hv . +.Bd -literal -offset indent + EXAMPLE: + xo_attr("seconds", "%ld", (unsigned long) login_time); + struct tm *tmp = localtime(login_time); + strftime(buf, sizeof(buf), "%R", tmp); + xo_emit("Logged in at {:login-time}\\n", buf); + XML: + <login-time seconds="1408336270">00:14</login-time> +.Ed +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_create.3 b/contrib/libxo/libxo/xo_create.3 new file mode 100644 index 0000000..1e0a69b --- /dev/null +++ b/contrib/libxo/libxo/xo_create.3 @@ -0,0 +1,85 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft xo_handle_t * +.Fn xo_create "unsigned style" "unsigned flags" +.Ft xo_handle_t * +.Fn xo_create_to_file "FILE *fp" "unsigned style" "unsigned flags" +.Ft void +.Fn xo_destroy "xo_handle_t *handle" +.Sh DESCRIPTION +A +.Em libxo +handle can be allocated using the +.Fn xo_create +function. +.Bd -literal -offset indent + Example: + xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN); + .... + xo_emit_h(xop, "testing\n"); +.Ed +.Pp +By default, +.Em libxo +writes output to standard output. A convenience +function is provided for situations when output should be written to +different file. +.Pp +Use the +.Em XOF_CLOSE_FP +flag to trigger a call to +.Em fclose 3 +for the FILE pointer when the handle is destroyed. +.Pp +The +.Fn xo_destroy +function releases a handle and any resources it is +using. Calling +.Fn xo_destroy +with a +.Em NULL +handle will release any +resources associated with the default handle. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +and +.Xf xo_set_options 3 . +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_emit.3 b/contrib/libxo/libxo/xo_emit.3 new file mode 100644 index 0000000..1128dc7 --- /dev/null +++ b/contrib/libxo/libxo/xo_emit.3 @@ -0,0 +1,71 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft int +.Fn xo_emit "const char *fmt" "..." +.Ft int +.Fn xo_emit_h "xo_handle_t *xop" "const char *fmt" "..." +.Ft int +.Fn xo_emit_hv "xo_handle_t *xop" "const char *fmt" "va_list vap" +.Sh DESCRIPTION +The +.Fn xo_emit +function emits formatted output using the description in a format +string along with a set of zero or more arguments, in a style similar +to +.Xr printf 3 +but using a more complex format description string, as described in +.Xr xo_format 5 . +.Pp +.Fn xo_emit +uses the default output handle, as described in +.Xf libxo 3 , +where +.Fn xo_emit_h +uses an explicit handle. +.Fn xo_emit_hv +accepts a +.Fa va_list +for additional flexibility. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_open_container 3 , +.Xr xo_open_list 3 , and +.Xr xo_format 5 . +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_err.3 b/contrib/libxo/libxo/xo_err.3 new file mode 100644 index 0000000..2445aa7 --- /dev/null +++ b/contrib/libxo/libxo/xo_err.3 @@ -0,0 +1,84 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_err +.Nd emit errors and warnings in multiple formats +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_warn "const char *fmt" "..." +.Ft void +.Fn xo_warnx "const char *fmt" "..." +.Ft void +.Fn xo_warn_c "int code" "const char *fmt" "..." +.Ft void +.Fn xo_warn_hc "xo_handle_t *xop" "int code, const char *fmt" "..." +.Ft void +.Fn xo_err "int eval" "const char *fmt" "..." +.Ft void +.Fn xo_errc "int eval" "int code" "const char *fmt" "..." +.Ft void +.Fn xo_errx "int eval" "const char *fmt" "..." +.Ft void +.Fn xo_message "const char *fmt" "..." +.Ft void +.Fn xo_message_c "int code" "const char *fmt" "..." +.Ft void +.Fn xo_message_hc "xo_handle_t *xop" "int code, const char *fmt" "..." +.Ft void +.Fn xo_message_hcv "xo_handle_t *xop" "int code" "const char *fmt" "va_list vap" +.Sh DESCRIPTION +Many programs make use of the standard library functions +.Xr err 3 +and +.Xr warn 3 +to generate errors and warnings for the user. +.Em libxo +wants to +pass that information via the current output style, and provides +compatible functions to allow this. +.Pp +These functions display the program name, a colon, a formatted message +based on the arguments, and then optionally a colon and an error +message associated with either "errno" or the "code" parameter. +.Bd -literal -offset indent + EXAMPLE: + if (open(filename, O_RDONLY) < 0) + xo_err(1, "cannot open file '%s'", filename); +.Ed +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_finish.3 b/contrib/libxo/libxo/xo_finish.3 new file mode 100644 index 0000000..3b25dc3 --- /dev/null +++ b/contrib/libxo/libxo/xo_finish.3 @@ -0,0 +1,59 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_finish "void" +.Ft void +.Fn xo_finish_h "xo_handle_t *xop" +.Sh DESCRIPTION +When the program is ready to exit or close a handle, a call to +.Fn xo_finish +is required. This flushes any buffered data, closes +open +.Em libxo +constructs, and completes any pending operations. +.Pp +Calling this function is +.Em vital +to the proper operation of libxo, +especially for the non-TEXT output styles. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_flush.3 b/contrib/libxo/libxo/xo_flush.3 new file mode 100644 index 0000000..160f634 --- /dev/null +++ b/contrib/libxo/libxo/xo_flush.3 @@ -0,0 +1,54 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_flush "void" +.Ft void +.Fn xo_flush_h "xo_handle_t *handle" +.Sh DESCRIPTION +.Em libxo +buffers data, both for performance and consistency, but also to +allow some advanced features to work properly. At various times, the +caller may wish to flush any data buffered within the library. The +.Fn xo_flush +function is used for this. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_format.5 b/contrib/libxo/libxo/xo_format.5 new file mode 100644 index 0000000..62cfeb6 --- /dev/null +++ b/contrib/libxo/libxo/xo_format.5 @@ -0,0 +1,657 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_format +.Nd content of format descriptors for xo_emit +.Sh DESCRIPTION +.Pp +.Em libxo +uses format strings to control the rendering of data into +various output styles, including +.Em text , +.Em XML , +.EM JSON , +and +.Em HTML . +Each format string contains a set of zero or more +.Dq field descriptions , +which describe independent data fields. Each +field description contains a set of +.Dq modifiers , +a +.Dq content string , +and zero, one, or two +.Dq format descriptors . +The modifiers tell +.Em libxo +what the field is and how to treat it, while the format descriptors are +formatting instructions using +.Xr printf 3 -style +format strings, telling +libxo how to format the field. The field description is placed inside +a set of braces, with a colon +.Ql ( \&: ) +after the modifiers and a slash +.Ql ( \&/ ) +before each format descriptors. Text may be intermixed with +field descriptions within the format string. +.Pp +The field description is given as follows: +.Bd -literal -offset indent + '{' [ role | modifier ]* ':' [ content ] + [ '/' field-format [ '/' encoding-format ]] '}' +.Ed +.Pp +The role describes the function of the field, while the modifiers +enable optional behaviors. The contents, field-format, and +encoding-format are used in varying ways, based on the role. These +are described in the following sections. +.Pp +In the following example, three field descriptors appear. The first +is a padding field containing three spaces of padding, the second is a +label ("In stock"), and the third is a value field ("in-stock"). The +in-stock field has a "%u" format that will parse the next argument +passed to the xo_emit function as an unsigned integer. +.Bd -literal -offset indent + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\\n", 65); +.Ed +.Pp +This single line of code can generate text ("In stock: 65\\n"), XML +("<in-stock>65</in-stock>"), JSON ('"in-stock": 6'), or HTML (too +lengthy to be listed here). +.Ss Modifier Roles +Modifiers are optional, and indicate the role and formatting of the +content. The roles are listed below; only one role is permitted: +.Pp +.Bl -column "M" "Name12341234" +.It Sy "M Name Description" +.It D "decoration " "Field is non-text (e.g. colon, comma)" +.It E "error " "Field is an error message" +.It L "label " "Field is text that prefixes a value" +.It N "note " "Field is text that follows a value" +.It P "padding " "Field is spaces needed for vertical alignment" +.It T "title " "Field is a title value for headings" +.It U "units " "Field is the units for the previous value field" +.It V "value " "Field is the name of field (the default)" +.It W "warning " "Field is a warning message" +.It \&[ "start anchor" "Begin a section of anchored variable-width text" +.It \&] "stop anchor " "End a section of anchored variable-width text" +.El +.Pp +.Ss The Decoration Role ({D:}) +Decorations are typically punctuation marks such as colons, +semi-colons, and commas used to decorate the text and make it simpler +for human readers. By marking these distinctly, HTML usage scenarios +can use CSS to direct their display parameters. +.Bd -literal -offset indent + xo_emit("{D:((}{:name}{D:))}\\n", name); +.Ed +.Ss The Label Role ({L:}) +Labels are text that appears before a value. +.Bd -literal -offset indent + xo_emit("{Lwc:Cost}{:cost/%u}\\n", cost); +.Ed +.Ss The Note Role ({N:}) +Notes are text that appears after a value. +.Bd -literal -offset indent + xo_emit("{:cost/%u} {N:per year}\\n", cost); +.Ed +.Ss The Padding Role ({P:}) +Padding represents whitespace used before and between fields. +The padding content can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"): +.Bd -literal -offset indent + xo_emit("{P: }{Lwc:Cost}{:cost/%u}\\n", cost); + xo_emit("{P:/30s}{Lwc:Cost}{:cost/%u}\\n", "", cost); +.Ed +.Ss The Title Role ({T:}) +Title are heading or column headers that are meant to be displayed to +the user. The title can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"): +.Bd -literal -offset indent + xo_emit("{T:Interface Statistics}\\n"); + xo_emit("{T:/%20.20s}{T:/%6.6s}\\n", "Item Name", "Cost"); +.Ed +.Ss The Units Role ({U:}) +Units are the dimension by which values are measured, such as degrees, +miles, bytes, and decibels. The units field carries this information +for the previous value field. +.Bd -literal -offset indent + xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\\n", miles); +.Ed +.Pp +Note that the sense of the 'w' modifier is reversed for units; +a blank is added before the contents, rather than after it. +.Pp +When the +.Em XOF_UNITS +flag is set, units are rendered in XML as the +.Dq units +attribute: +.Bd -literal -offset indent + <distance units="miles">50</distance> +.Ed +.Pp +Units can also be rendered in HTML as the "data-units" attribute: +.Bd -literal -offset indent + <div class="data" data-tag="distance" data-units="miles" + data-xpath="/top/data/distance">50</div> +.Ed +.Ss The Value Role ({V:} and {:}) +The value role is used to represent the a data value that is +interesting for the non-display output styles (XML and JSON). Value +is the default role; if no other role designation is given, the field +is a value. The field name must appear within the field descriptor, +followed by one or two format descriptors. The first format +descriptor is used for display styles (TEXT and HTML), while the +second one is used for encoding styles (XML and JSON). If no second +format is given, the encoding format defaults to the first format, +with any minimum width removed. If no first format is given, both +format descriptors default to "%s". +.Bd -literal -offset indent + xo_emit("{:length/%02u}x{:width/%02u}x{:height/%02u}\\n", + length, width, height); + xo_emit("{:author} wrote \"{:poem}\" in {:year/%4d}\\n, + author, poem, year); +.Ed +.Ss The Anchor Modifiers ({[:} and {]:}) +The anchor roles allow a set of strings by be padded as a group, +but still be visible to xo_emit as distinct fields. Either the start +or stop anchor can give a field width and it can be either directly in +the descriptor or passed as an argument. Any fields between the start +and stop anchor are padded to meet the minimum width given. +.Pp +To give a width directly, encode it as the content of the anchor tag: +.Bd -literal -offset indent + xo_emit("({[:10}{:min/%d}/{:max/%d}{]:})\\n", min, max); +.Ed +.Pp +To pass a width as an argument, use "%d" as the format, which must +appear after the "/". Note that only "%d" is supported for widths. +Using any other value could ruin your day. +.Bd -literal -offset indent + xo_emit("({[:/%d}{:min/%d}/{:max/%d}{]:})\\n", width, min, max); +.Ed +.Pp +If the width is negative, padding will be added on the right, suitable +for left justification. Otherwise the padding will be added to the +left of the fields between the start and stop anchors, suitable for +right justification. If the width is zero, nothing happens. If the +number of columns of output between the start and stop anchors is less +than the absolute value of the given width, nothing happens. +.Pp +Widths over 8k are considered probable errors and not supported. If +.Em XOF_WARN +is set, a warning will be generated. +.Ss Modifier Flags +The modifiers can also include the following flags, which modify the +content emitted for some output styles: +.Pp +.Bl -column M "Name12341234" +.It Sy M "Name Description" +.It c "colon " "A colon (":") is appended after the label" +.It d "display " "Only emit field for display styles (text/HTML)" +.It e "encoding " "Only emit for encoding styles (XML/JSON)" +.It k "key " "Field is a key, suitable for XPath predicates" +.It n "no-quotes " "Do not quote the field when using JSON style" +.It q "quotes " "Quote the field when using JSON style" +.It w "white space " "A blank (" ") is appended after the label" +.El +.Pp +For example, the modifier string "Lwc" means the field has a label +role (text that describes the next field) and should be followed by a +colon ('c') and a space ('w'). The modifier string "Vkq" means the +field is has value role, that it is a key for the current instance, and +that the value should be quoted when encoded for JSON. +.Ss The Colon Modifier ({c:}) +The colon modifier appends a single colon to the data value: +.Bd -literal -offset indent + EXAMPLE: + xo_emit("{Lc:Name}{:name}\\n", "phil"); + TEXT: + Name:phil +.Ed +.Pp +The colon modifier is only used for the TEXT and HTML output +styles. It is commonly combined with the space modifier ('{w:'). +It is purely a convenience feature. +.Ss The Display Modifier ({d:}) +The display modifier indicated the field should only be generated for +the display output styles, TEXT and HTML. +.Bd -literal -offset indent + EXAMPLE: + xo_emit("{Lcw:Name}{d:name} {:id/%d}\\n", "phil", 1); + TEXT: + Name: phil 1 + XML: + <id>1</id> +.Ed +.Pp +The display modifier is the opposite of the encoding modifier, and +they are often used to give to distinct views of the underlying data. +.Ss The Encoding Modifier ({e:}) +The display modifier indicated the field should only be generated for +the display output styles, TEXT and HTML. +.Bd -literal -offset indent + EXAMPLE: + xo_emit("{Lcw:Name}{:name} {e:id/%d}\\n", "phil", 1); + TEXT: + Name: phil + XML: + <name>phil</name><id>1</id> +.Ed +.Pp +The encoding modifier is the opposite of the display modifier, and +they are often used to give to distinct views of the underlying data. +.Ss The Key Modifier ({k:}) +The key modifier is used to indicate that a particular field helps +uniquely identify an instance of list data. +.Bd -literal -offset indent + EXAMPLE: + xo_open_list("user"); + for (i = 0; i < num_users; i++) { + xo_open_instance("user"); + xo_emit("User {k:name} has {:count} tickets\\n", + user[i].u_name, user[i].u_tickets); + xo_close_instance("user"); + } + xo_close_list("user"); +.Ed +.Pp +Currently the key modifier is only used when generating XPath value +for the HTML output style when +.Em XOF_XPATH +is set, but other uses are likely in the near future. +.Ss The No-Quotes Modifier ({n:}) +The no-quotes modifier (and its twin, the 'quotes' modifier) affect +the quoting of values in the JSON output style. JSON uses quotes for +string value, but no quotes for numeric, boolean, and null data. +xo_emit applies a simple heuristic to determine whether quotes are +needed, but often this needs to be controlled by the caller. +.Bd -literal -offset indent + EXAMPLE: + const char *bool = is_true ? "true" : "false"; + xo_emit("{n:fancy/%s}", bool); + JSON: + "fancy": true +.Ed +.Ss The Quotes Modifier ({q:}) +The quotes modifier (and its twin, the 'no-quotes' modifier) affect +the quoting of values in the JSON output style. JSON uses quotes for +string value, but no quotes for numeric, boolean, and null data. +xo_emit applies a simple heuristic to determine whether quotes are +needed, but often this needs to be controlled by the caller. +.Bd -literal -offset indent + EXAMPLE: + xo_emit("{q:time/%d}", 2014); + JSON: + "year": "2014" +.Ed +.Ss The White Space Modifier ({w:}) +The white space modifier appends a single space to the data value: +.Bd -literal -offset indent + EXAMPLE: + xo_emit("{Lw:Name}{:name}\\n", "phil"); + TEXT: + Name phil +.Ed +.Pp +The white space modifier is only used for the TEXT and HTML output +styles. It is commonly combined with the colon modifier ('{c:'). +It is purely a convenience feature. +.Pp +Note that the sense of the 'w' modifier is reversed for the units role +({Uw:}); a blank is added before the contents, rather than after it. +.Ss Field Formatting +The field format is similar to the format string for +.Xr printf 3 . +It's used varies based on the role of the field, but generally is used to +format the field's contents. +.Pp +If not provided, the format string defaults to "%s". +.Pp +Note a field definition can contain zero or more printf-style +.Dq directives , +which are sequences that start with a '%' and end with a +one of following characters: "diouxXDOUeEfFgGaAcCsSp". Each directive +is matched by one of more arguments to the xo_emit function. +.Pp +The format string has the form: +.Bd -literal -offset indent + '%' format-modifier * format-character +.Ed +.Pp +The format- modifier can be: +.Bl -bullet +.It +a '#' character, indicating the output value should be prefixed with +'0x', typically to indicate a base 16 (hex) value. +.It +a minus sign ('-'), indicating the output value should be padded on +the right instead of the left. +.It +a leading zero ('0') indicating the output value should be padded on the +left with zeroes instead of spaces (' '). +.It +one or more digits ('0' - '9') indicating the minimum width of the +argument. If the width in columns of the output value is less that +the minumum width, the value will be padded to reach the minimum. +.It +a period followed by one or more digits indicating the maximum +number of bytes which will be examined for a string argument, or the maximum +width for a non-string argument. When handling ASCII strings this is +functions as the field width but for multi-byte characters, a single +character may be composed of multiple bytes. +xo_emit will never dereference memory beyond the given number of bytes. +.It +a second period followed by one or more digits indicating the maximum +width for a string argument. This modifier cannot be given for non-string +arguments. +.It +one or more 'h' characters, indicating shorter input data. +.It +one or more 'l' characters, indicating longer input data. +.It +a 'z' character, indicating a 'size_t' argument. +.It +a 't' character, indicating a 'ptrdiff_t' argument. +.It +a ' ' character, indicating a space should be emitted before +positive numbers. +.It +a '+' character, indicating sign should emitted before any number. +.El +.Pp +Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be +removed eventually. +.Pp +The format character is described in the following table: +.Pp +.Bl -column C "Argument Type12" +.It Sy "C Argument Type Format" +.It d "int " "base 10 (decimal)" +.It i "int " "base 10 (decimal)" +.It o "int " "base 8 (octal)" +.It u "unsigned " "base 10 (decimal)" +.It x "unsigned " "base 16 (hex)" +.It X "unsigned long " "base 16 (hex)" +.It D "long " "base 10 (decimal)" +.It O "unsigned long " "base 8 (octal)" +.It U "unsigned long " "base 10 (decimal)" +.It e "double " "[-]d.ddde+-dd" +.It E "double " "[-]d.dddE+-dd" +.It f "double " "[-]ddd.ddd" +.It F "double " "[-]ddd.ddd" +.It g "double " "as 'e' or 'f'" +.It G "double " "as 'E' or 'F'" +.It a "double " "[-]0xh.hhhp[+-]d" +.It A "double " "[-]0Xh.hhhp[+-]d" +.It c "unsigned char " "a character" +.It C "wint_t " "a character" +.It s "char * " "a UTF-8 string" +.It S "wchar_t * " "a unicode/WCS string" +.It p "void * " "'%#lx'" +.El +.Pp +The 'h' and 'l' modifiers affect the size and treatment of the +argument: +.Bl -column "Mod" "d, i " "o, u, x, X " +.It Sy "Mod" "d, i " "o, u, x, X" +.It "hh " "signed char " "unsigned char" +.It "h " "short " "unsigned short" +.It "l " "long " "unsigned long" +.It "ll " "long long " "unsigned long long" +.It "j " "intmax_t " "uintmax_t" +.It "t " "ptrdiff_t " "ptrdiff_t" +.It "z " "size_t " "size_t" +.It "q " "quad_t " "u_quad_t" +.El +.Pp +.Ss UTF-8 and Locale Strings +All strings for libxo must be UTF-8. libxo will handle turning them +into locale-based strings for display to the user. +.Pp +For strings, the 'h' and 'l' modifiers affect the interpretation of +the bytes pointed to argument. The default '%s' string is a 'char *' +pointer to a string encoded as UTF-8. Since UTF-8 is compatible with +.Em ASCII +data, a normal 7-bit +.Em ASCII + string can be used. '%ls' expects a +'wchar_t *' pointer to a wide-character string, encoded as a 32-bit +Unicode values. '%hs' expects a 'char *' pointer to a multi-byte +string encoded with the current locale, as given by the +.Em LC_CTYPE , +.Em LANG , +or +.Em LC_ALL +environment varibles. The first of this list of +variables is used and if none of the variables, the locale defaults to +.Em UTF-8. +.Pp +libxo will +convert these arguments as needed to either UTF-8 (for XML, JSON, and +HTML styles) or locale-based strings for display in text style. +.Bd -literal -offset indent + xo_emit("Alll strings are utf-8 content {:tag/%ls}", + L"except for wide strings"); +.Ed +.Pp +"%S" is equivalent to "%ls". +.Pp +For example, a function is passed a locale-base name, a hat size, +and a time value. The hat size is formatted in a UTF-8 (ASCII) +string, and the time value is formatted into a wchar_t string. +.Bd -literal -offset indent + void print_order (const char *name, int size, + struct tm *timep) { + char buf[32]; + const char *size_val = "unknown"; + + if (size > 0) + snprintf(buf, sizeof(buf), "%d", size); + size_val = buf; + } + + wchar_t when[32]; + wcsftime(when, sizeof(when), L"%d%b%y", timep); + + xo_emit("The hat for {:name/%hs} is {:size/%s}.\\n", + name, size_val); + xo_emit("It was ordered on {:order-time/%ls}.\\n", + when); + } +.Ed +.Pp +It is important to note that xo_emit will perform the conversion +required to make appropriate output. Text style output uses the +current locale (as described above), while XML, JSON, and HTML use +UTF-8. +.Pp +UTF-8 and locale-encoded strings can use multiple bytes to encode one +column of data. The traditional "precision'" (aka "max-width") value +for "%s" printf formatting becomes overloaded since it specifies both +the number of bytes that can be safely referenced and the maximum +number of columns to emit. xo_emit uses the precision as the former, +and adds a third value for specifying the maximum number of columns. +.Pp +In this example, the name field is printed with a minimum of 3 columns +and a maximum of 6. Up to ten bytes are in used in filling those +columns. +.Bd -literal -offset indent + xo_emit("{:name/%3.10.6s}", name); +.Ed +.Ss Characters Outside of Field Definitions +Characters in the format string are not part of a field definition are +copied to the output for the TEXT style, and are ignored for the JSON +and XML styles. For HTML, these characters are placed in a <div> with +class "text". +.Bd -literal -offset indent + EXAMPLE: + xo_emit("The hat is {:size/%s}.\\n", size_val); + TEXT: + The hat is extra small. + XML: + <size>extra small</size> + JSON: + "size": "extra small" + HTML: + <div class="text">The hat is </div> + <div class="data" data-tag="size">extra small</div> + <div class="text">.</div> +.Ed +.Ss "%n" is Not Supported +libxo does not support the '%n' directive. It's a bad idea and we +just don't do it. +.Ss The Encoding Format (eformat) +The "eformat" string is the format string used when encoding the field +for JSON and XML. If not provided, it defaults to the primary format +with any minimum width removed. If the primary is not given, both +default to "%s". +.Sh EXAMPLE +In this example, the value for the number of items in stock is emitted: +.Bd -literal -offset indent + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\\n", + instock); +.Ed +.Pp +This call will generate the following output: +.Bd -literal -offset indent + TEXT: + In stock: 144 + XML: + <in-stock>144</in-stock> + JSON: + "in-stock": 144, + HTML: + <div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">144</div> + </div> +.Ed +.Pp +Clearly HTML wins the verbosity award, and this output does +not include +.Em XOF_XPATH +or +.Em XOF_INFO +data, which would expand the penultimate line to: +.Bd -literal -offset indent + <div class="data" data-tag="in-stock" + data-xpath="/top/data/item/in-stock" + data-type="number" + data-help="Number of items in stock">144</div> +.Ed +.Sh WHAT MAKES A GOOD FIELD NAME? +To make useful, consistent field names, follow these guidelines: +.Pp +.Ss Use lower case, even for TLAs +Lower case is more civilized. Even TLAs should be lower case +to avoid scenarios where the differences between "XPath" and +"Xpath" drive your users crazy. Using "xpath" is simpler and better. +.Ss Use hyphens, not underscores +Use of hyphens is traditional in XML, and the +.Em XOF_UNDERSCORES +flag can be used to generate underscores in JSON, if desired. +But the raw field name should use hyphens. +.Se Use full words +Don't abbreviate especially when the abbreviation is not obvious or +not widely used. Use "data-size", not "dsz" or "dsize". Use +"interface" instead of "ifname", "if-name", "iface", "if", or "intf". +.Se Use <verb>-<units> +Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in +making consistent, useful names, avoiding the situation where one app +uses "sent-packet" and another "packets-sent" and another +"packets-we-have-sent". The <units> can be dropped when it is +obvious, as can obvious words in the classification. +Use "receive-after-window-packets" instead of +"received-packets-of-data-after-window". +.Se Reuse existing field names +Nothing's worse than writing expressions like: +.Bd -literal -offset indent + if ($src1/process[pid == $pid]/name == + $src2/proc-table/proc/p[process-id == $pid]/proc-name) { + ... + } +.Ed +.Pp +Find someone else who is expressing similar data and follow their +field's and hierarchy. Remember the quote is not +.Dq Consistency is the hobgoblin of little minds +but +.Dq A foolish consistency is the hobgoblin of little minds. +.Ss Think about your users +Have empathy for your users, choosing clear and useful fields that +contain clear and useful data. You may need to augment the display +content with +.Xr xo_attr 3 +calls or "{e:}" fields to make the data useful. +.Ss Don't use an arbitrary number postfix +What does "errors2" mean? No one will know. "errors-after-restart" +would be a better choice. Think of you users, and think of the +future. If you make "errors2", the next guy will happily make +"errors3" and before you know it, someone will be asking what's the +difference between errors37 and errors63. +.Ss Be consistent, uniform, unsurprising, and predictable +Think of your field vocabulary as an API. You want it useful, +expressive, meaningful, direct, and obvious. You want the client +application's programmer to move between without the need to +understand a variety of opinions on how fields are named. They should +see the system as a single cohesive whole, not a sack of cats. +.Pp +Field names constitute the means by which client programmers interact +with our system. By choosing wise names now, you are making their +lives better. +.Pp +After using +.Xr xolint 1 +to find errors in your field descriptors, use +.Dq "xolint -V" +to spell check your field names and to detect different +names for the same data. +.Dq dropped-short +and +.Dq dropped-too-short +are both reasonable names, but using them both will lead users to ask the +difference between the two fields. If there isn't a difference, +use only one of the field names. If there is a difference, change the +names to make that difference more obvious. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_no_setlocale.3 b/contrib/libxo/libxo/xo_no_setlocale.3 new file mode 100644 index 0000000..94a1264 --- /dev/null +++ b/contrib/libxo/libxo/xo_no_setlocale.3 @@ -0,0 +1,63 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_no_setlocale +.Nd prevent implicit call to setlocale() +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_no_setlocale "void" +.Sh DESCRIPTION +.Em libxo +automatically initializes the locale based on setting of the +environment variables +.Em LC_CTYPE , +.Em LANG , +and +.Em LC_ALL . +The first of this +list of variables is used and if none of the variables, the locale +defaults to +.Em UTF-8. The caller may wish to avoid this behavior, and +can do so by calling the +.Fn xo_no_setlocale +function. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 , +.Xr xo_open_container 3 , +.Xr xo_open_list 3 , and +.Xr xo_format 5 . +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_open_container.3 b/contrib/libxo/libxo/xo_open_container.3 new file mode 100644 index 0000000..af54d05 --- /dev/null +++ b/contrib/libxo/libxo/xo_open_container.3 @@ -0,0 +1,216 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Sh NAME +.Nm xo_open_container +.Nm xo_open_container_h +.Nm xo_open_container_hd +.Nm xo_open_container_d +.Nm xo_close_container +.Nm xo_close_container_h +.Nm xo_close_container_hd +.Nm xo_close_container_d +.Nd open and close containers +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.Ft int +.Fn xo_open_container "const char *name" +.Ft int +.Fn xo_open_container_h "xo_handle_t *handle" "const char *name" +.Ft int +.Fn xo_open_container_hd "xo_handle_t *handle" "const char *name" +.Ft int +.Fn xo_open_container_d "const char *name" +.Ft int +.Fn xo_close_container "const char *name" +.Ft int +.Fn xo_close_container_h "xo_handle_t *handle" "const char *name" +.Ft int +.Fn xo_close_container_hd "xo_handle_t *handle" +.Ft int +.Fn xo_close_container_d "void" +.Sh DESCRIPTION +.Fa libxo +represents to types of hierarchy: +.Dq containers +and +.Dq lists . +A container appears once under a given parent where a list contains +instances that can appear multiple times. A container is used to hold +related fields and to give the data organization and scope. +The container has no value, but serves to +contain other nodes. +.Pp +To open a container, call +.Fn xo_open_container +or +.Fn xo_open_container_h . +The former uses the default handle and +the latter accepts a specific handle. +.Pp +To close a level, use the +.Fn xo_close_container +or +.Fn xo_close_container_h +functions. +.Pp +Each open call must have a matching close call. If the +.Fa XOF_WARN +flag is set and the name given does not match the name of +the currently open +container, a warning will be generated. +.Bd -literal -offset indent -compact + Example: + + xo_open_container("top"); + xo_open_container("system"); + xo_emit("{:host-name/%s%s%s", hostname, + domainname ? "." : "", domainname ?: ""); + xo_close_container("system"); + xo_close_container("top"); + + Sample Output: + Text: + my-host.example.org + XML: + <top> + <system> + <host-name>my-host.example.org</host-name> + </system> + </top> + JSON: + "top" : { + "system" : { + "host-name": "my-host.example.org" + } + } + HTML: + <div class="data" + data-tag="host-name">my-host.example.org</div> +.Ed +.SH EMITTING HIERARCHY +To create a container, use the +.Fn xo_open_container +and +.Fn xo_close_container +set of functions. +The +.Fa handle +parameter contains a handle such as returned by +.Xr xo_create 3 +or a +.Em NULL +to use the default handle. +The +.Fa name +parameter gives the name of the container, encoded in +.Em UTF-8 . +Since +.Em ASCII +is a proper subset of +.Em UTF-8 , +traditional C strings can be used directly. +.Pp +The close functions with the +.Dq _d +suffix are used in +.Dq Do The Right Thing +mode, where the name of the open containers, lists, and +instances are maintained internally by +.Em libxo +to allow the caller to +avoid keeping track of the open container name. +.Pp +Use the +.Em XOF_WARN +flag to generate a warning if the name given on the +close does not match the current open container. +.Pp +For TEXT and HTML output, containers are not rendered into output +text, though for HTML they are used when the +.Em XOF_XPATH +flag is set. +.Pp +.Bd -literal -offset indent -compact + EXAMPLE: + xo_open_container("system"); + xo_emit("The host name is {:host-name}\n", hn); + xo_close_container("system"); + XML: + <system><host-name>foo</host-name></system> +.Ed +.Sh DTRT MODE +Some user may find tracking the names of open containers, lists, and +instances inconvenient. +.Em libxo +offers +.Dq Do The Right Thing +mode, where +.Em libxo +will track the names of open containers, lists, and instances so +the close function can be called without a name. To enable +.Em DTRT +mode, +turn on the +.Em XOF_DTRT +flag prior to making any other +.Em libxo +output. +.Bd -literal -offset indent -compact + xo_set_flags(NULL, XOF_DTRT); +.Ed +Each open and close function has a version with the suffix +.Dq _d , +which will close the open container, list, or instance: +.Bd -literal -offset indent -compact + xo_open_container("top"); + ... + xo_close_container_d(); +.Ed +Note that the +.Em XOF_WARN +flag will also cause libxo to track open +containers, lists, and instances. +A warning is generated with the name given to the close function +and the name recorded do not match. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_open_list.3 b/contrib/libxo/libxo/xo_open_list.3 new file mode 100644 index 0000000..9a6a215 --- /dev/null +++ b/contrib/libxo/libxo/xo_open_list.3 @@ -0,0 +1,169 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Sh NAME +.Nm xo_open_list +.Nm xo_open_list_h +.Nm xo_open_list_hd +.Nm xo_open_list_d +.Nm xo_open_instance +.Nm xo_open_instance_h +.Nm xo_open_instance_hd +.Nm xo_open_instance_d +.Nm xo_close_instance +.Nm xo_close_instance_h +.Nm xo_close_instance_hd +.Nm xo_close_instance_d +.Nm xo_close_list +.Nm xo_close_list_h +.Nm xo_close_list_hd +.Nm xo_close_list_d +.Nd open and close lists and instances +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.Ft int +.Fn xo_open_list_h "xo_handle_t *xop" "const char *name" +.Ft int +.Fn xo_open_list "const char *name" +.Ft int +.Fn xo_open_list_hd "xo_handle_t *xop" "const char *name" +.Ft int +.Fn xo_open_list_d "const char *name" +.Ft int +.Fn xo_open_instance_h "xo_handle_t *xop" "const char *name" +.Ft int +.Fn xo_open_instance "const char *name" +.Ft int +.Fn xo_open_instance_hd "xo_handle_t *xop" "const char *name" +.Ft int +.Fn xo_open_instance_d "const char *name" +.Ft int +.Fn xo_close_instance_h "xo_handle_t *xop" "const char *name" +.Ft int +.Fn xo_close_instance "const char *name" +.Ft int +.Fn xo_close_instance_hd "xo_handle_t *xop" +.Ft int +.Fn xo_close_instance_d "void" +.Ft int +.Fn xo_close_list_h "xo_handle_t *xop" "const char *name" +.Ft int +.Fn xo_close_list "const char *name" +.Ft int +.Fn xo_close_list_hd "xo_handle_t *xop" +.Ft int +.Fn xo_close_list_d "void" +.Sh DESCRIPTION +Lists are sequences of instances of homogeneous data objects. Two +distinct levels of calls are needed to represent them in our output +styles. Calls must be made to open and close a list, and for each +instance of data in that list, calls must be make to open and close +that instance. +.Pp +The name given to all calls must be identical, and it is strong +suggested that the name be singular, not plural, as a matter of +style and usage expectations. +.Pp +A list is set of one or more instances that appear under the same +parent. The instances contains details about a specific object. One +can think of instances as objects or records. A call is needed to +open and close the list, while a distinct call is needed to open and +close each instance of the list: +.Bd -literal -offset indent -compact + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); + xo_close_instance("item"); + } + + xo_close_list("item"); +.Ed +Getting the list and instance calls correct is critical to the proper +generation of XML and JSON data. +.Pp +.Bd -literal -offset indent -compact + EXAMPLE: + xo_open_list("user"); + for (i = 0; i < num_users; i++) { + xo_open_instance("user"); + xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n", + pw[i].pw_name, pw[i].pw_uid, + pw[i].pw_gid, pw[i].pw_dir); + xo_close_instance("user"); + } + xo_close_list("user"); + TEXT: + phil:1001:1001:/home/phil + pallavi:1002:1002:/home/pallavi + XML: + <user> + <name>phil</name> + <uid>1001</uid> + <gid>1001</gid> + <home>/home/phil</home> + </user> + <user> + <name>pallavi</name> + <uid>1002</uid> + <gid>1002</gid> + <home>/home/pallavi</home> + </user> + JSON: + user: [ + { + "name": "phil", + "uid": 1001, + "gid": 1001, + "home": "/home/phil", + }, + { + "name": "pallavi", + "uid": 1002, + "gid": 1002, + "home": "/home/pallavi", + } + ] +.Ed +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_parse_args.3 b/contrib/libxo/libxo/xo_parse_args.3 new file mode 100644 index 0000000..a9b4cec --- /dev/null +++ b/contrib/libxo/libxo/xo_parse_args.3 @@ -0,0 +1,133 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_parse_args +.Nd detect, parse, and remove arguments for libxo +.Sh LIBRARY +.Nm libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft int +.Fn xo_parse_args "int argc" "char **argv" +.Sh DESCRIPTION +The +.Fn xo_parse_args +function is used to process command-line arguments. +.Em libxo -specific +options are processed and removed +from the argument list so the calling application does not +need to process them. If successful, a new value for argc +is returned. On failure, a message it emitted and -1 is returned. +.Bd -literal -offset indent + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); +.Ed +.Pp +Following the call to +.Fn xo_parse_args , +the application can process the remaining arguments in a normal manner. +.Pp +.Em libxo +uses command line options to trigger rendering behavior. The +following options are recognised: +.Pp +.Bl -tag -width "--libxo" +.It +\-\^\-libxo <options> +.It +\-\^\-libxo=<options> +.It +\-\^\-libxo:<brief-options> +.El +.Pp +Options is a comma-separated list of tokens that correspond to output +styles, flags, or features: +.Pp +.Bl -tag -width "12345678" +.It Sy "Token Action" +.It dtrt +Enable "Do The Right Thing" mode +.It html +Emit HTML output +.It indent=xx +Set the indentation level +.It info +Add info attributes (HTML) +.It json +Emit JSON output +.It keys +Emit the key attribute for keys (XML) +.It no-locale +Do not initialize the locale setting +.It no-top +Do not emit a top set of braces (JSON) +.It not-first +Pretend the 1st output item was not 1st (JSON) +.It pretty +Emit pretty-printed output +.It text +Emit TEXT output +.It units +Add the 'units' (XML) or 'data-units (HTML) attribute +.It warn +Emit warnings when libxo detects bad calls +.It warn-xml +Emit warnings in XML +.It xml +Emit XML output +.It xpath +Add XPath expressions (HTML) +.El +.Pp +The +.Dq brief-options +are single letter commands, designed for those with +too little patience to use real tokens. No comma separator is used. +.Bl -column "i<num>" +.It Sy "Token Action" +.It "H " "Enable HTML output (XO_STYLE_HTML)" +.It "I " "Enable info output (XOF_INFO)" +.It "i<num> " "Indent by <number>" +.It "J " "Enable JSON output (XO_STYLE_JSON)" +.It "P " "Enable pretty-printed output (XOF_PRETTY)" +.It "T " "Enable text output (XO_STYLE_TEXT)" +.It "W " "Enable warnings (XOF_WARN)" +.It "X " "Enable XML output (XO_STYLE_XML)" +.It "x " "Enable XPath data (XOF_XPATH)" +.El +.Pp +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_set_allocator.3 b/contrib/libxo/libxo/xo_set_allocator.3 new file mode 100644 index 0000000..508cc8e --- /dev/null +++ b/contrib/libxo/libxo/xo_set_allocator.3 @@ -0,0 +1,73 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Sy typedef void *(*xo_realloc_func_t)(void *, size_t); +.Pp +.Sy typedef void (*xo_free_func_t)(void *); +.Ft void +.Fn xo_set_allocator "xo_realloc_func_t realloc_func" "xo_free_func_t free_func" +.Sh DESCRIPTION +The +.Fn xo_set_allocator +function allows libxo to be used in environments +where the standard +.Xr realloc 3 +and +.Xr free 3 +functions are not available. +.Pp +.Fa realloc_func +should expect the same arguments as +.Xr realloc 3 +and return +a pointer to memory following the same convention. +.Fa free_func +will receive the same argument as +.Xr free 3 +and should release it, asappropriate for the environment. +.Pp +By default, the standard +.Xr realloc 3 +and +.Xr free 3 +functions are used. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_set_flags.3 b/contrib/libxo/libxo/xo_set_flags.3 new file mode 100644 index 0000000..a23de7b --- /dev/null +++ b/contrib/libxo/libxo/xo_set_flags.3 @@ -0,0 +1,128 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_set_flags "xo_handle_t *handle" "unsigned flags" +.Ft void +.Fn xo_clear_flags "xo_handle_t *handle" "xo_xof_flags_t flags" +.Sh DESCRIPTION +Use the +.Fn xo_set_flags +function to set the flags for a +.Em libxo +handle. To use the default handle, pass a NULL handle. +.Pp +The set of valid flags include: +.Bl -tag -width "XOF_UNDERSCORES" +.It Sy "Flag Description" +.It XOF_CLOSE_FP +Close file pointer on xo_destroy(). This +flag will trigger the call of the close_func +(provided via +.Fn xo_set_writer 3 ) +when the handle is destroyed. +.It XOF_DTRT +Enable "do the right thing" mode +.It XOF_INFO +Display info data attributes (HTML) +.It XOF_KEYS +Emit the key attribute (XML) +.It XOF_NO_ENV +Do not use the LIBXO_OPTIONS env var +.It XOF_PRETTY +Make 'pretty printed' output, with the +addition of indentation and newlines to enhance the readability of +XML, JSON, and HTML output. Text output is not affected. +.It XOF_UNDERSCORES +Replaces hyphens with underscores +.It XOF_UNITS +Display units (XML and HMTL) +.It XOF_WARN +Generate warnings for broken calls, triggering diagnostic +output (on standard error) when the library notices errors during +operations, or with arguments to functions. Without warning enabled, +such conditions are ignored. +Warnings allow developers to debug their interaction with libxo. +The function "xo_failure" can used as a breakpoint for a debugger, +regardless of whether warnings are enabled. +.It XOF_WARN_XML +Generate warnings in XML on stdout +.It XOF_XPATH +Emit XPath expressions (HTML) +.It XOF_COLUMNS +Force xo_emit to return columns used +.It XOF_FLUSH +Flush output after each xo_emit call +.El +.Pp +If the style is XO_STYLE_HTML, the following additional flags can be +used: +.Bl -tag -width "XOF_UNDERSCORES" +.It Sy "Flag Description" +.It XOF_XPATH +Emit "data-xpath" attributes +.It XOF_INFO +Emit additional informational fields for HTML +output. See +.Xr xo_set_info 3 +for details. +.El +.Pp +The +.Em XOF_XPATH +flag enables the emission of XPath expressions detailing +the hierarchy of XML elements used to encode the data field, if the +XPATH style of output were requested. +.Pp +If the style is XO_STYLE_XML, the following additional flags can be +used: +.Bl -tag -width "XOF_UNDERSCORES" +.It Sy "Flag Description" +.It XOF_KEYS +Add 'key' attribute to the XML encoding for +field definitions that use the 'k' modifier. The key attribute has +the value "key". +.El +.Pp +The xo_clear_flags() function turns off the given flags in a specific +handle. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_set_info.3 b/contrib/libxo/libxo/xo_set_info.3 new file mode 100644 index 0000000..dbb3c9c --- /dev/null +++ b/contrib/libxo/libxo/xo_set_info.3 @@ -0,0 +1,113 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_set_info "xo_handle_t *handle" "xo_info_t *info" "int count" +.Sh DESCRIPTION +HTML data can include additional information in attributes that +begin with "data-". To enable this, three things must occur: +.Pp +First the application must build an array of xo_info_t structures, +one per tag. The array must be sorted by name, since +.Em libxo +uses a +binary search to find the entry that matches names from format +instructions. +.Pp +The +.Em xo_info_t +structure is defined in +.Em <libxo/xo.h> : +.Bd -literal -offset indent + typedef struct xo_info_s { + const char *xi_name; /* Name of the element */ + const char *xi_type; /* Type of field */ + const char *xi_help; /* Description of field */ + } xo_info_t; +.Ed +.Pp +Second, the application must inform +.Em libxo +about this information using the +.Fn xo_set_info +call. Like other libxo calls, passing NULL for the handle tells +.Em libxo +to use the default handle. +.Pp +If the +.Fa count +is -1, +.Em libxo +will count the elements of +.Fa info , +but there +must be an empty element at the end. More typically, the number is +known to the application: +.Bd -literal -offset indent + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + }; + int info_count = (sizeof(info) / sizeof(info[0])); + ... + xo_set_info(NULL, info, info_count); +.Ed +.Pp +Third, the emitting of info must be triggered with the +.Em XOF_INFO +flag +using either the +.Fn xo_set_flags +function or the +.Dq --libxo=info +command line argument. +.Pp +The type and help values, if present, are emitted as the "data-type" +and "data-help" attributes: +.Bd -literal -offset indent + <div class="data" data-tag="sku" data-type="string" + data-help="Stock Keeping Unit">GRO-000-533</div> +.Ed +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_set_options.3 b/contrib/libxo/libxo/xo_set_options.3 new file mode 100644 index 0000000..af7e95c --- /dev/null +++ b/contrib/libxo/libxo/xo_set_options.3 @@ -0,0 +1,52 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft int +.Fn xo_set_options "xo_handle_t *xop" "const char *input" +.Sh DESCRIPTION +The +.Fn xo_set_options +function accepts a comma-separated list of styles +and flags and enables them for a specific handle. +The options are identical to those listed in +.Xr xo_parse_args 3 . +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_set_style.3 b/contrib/libxo/libxo/xo_set_style.3 new file mode 100644 index 0000000..83371ac --- /dev/null +++ b/contrib/libxo/libxo/xo_set_style.3 @@ -0,0 +1,72 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Fn xo_set_style "xo_handle_t *handle" "unsigned style" +.Ft int +.Fn xo_set_style_name "xo_handle_t *handle" "const char *style" +.Sh DESCRIPTION +Use the +.Fn xo_set_style +function to set the output style for a handle. +To use the default handle, pass a NULL handle. +The set of output styles used by +.Em libxo +is: +.Bl -column "XO_STYLE_TEXT12" +.It Sy "Flag Description" +.It "XO_STYLE_TEXT Traditional text output" +.It "XO_STYLE_XML XML encoded data" +.It "XO_STYLE_JSON JSON encoded data" +.It "XO_STYLE_HTML HTML encoded data" +.El +.Pp +The +.Fn xo_set_style_name +function can be used to set the style based on a name +encoded as a string. +The name can be any of the styles: "text", "xml", "json", or "html". +.Bd -literal -offset indent + EXAMPLE: + xo_set_style_name(NULL, "html"); +.Ed +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xo_set_writer.3 b/contrib/libxo/libxo/xo_set_writer.3 new file mode 100644 index 0000000..9185f10 --- /dev/null +++ b/contrib/libxo/libxo/xo_set_writer.3 @@ -0,0 +1,68 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo_emit +.Nd emit formatted output based on format string and arguments +.Sh LIBRARY +.Lb libxo +.Sh SYNOPSIS +.In libxo/xo.h +.Ft void +.Sy typedef int (*xo_write_func_t)(void *, const char *); +.Pp +.Sy typedef void (*xo_close_func_t)(void *); +.Fn xo_set_writer "xo_handle_t *handle" "void *opaque" + "xo_write_func_t write_func" + "xo_close_func_t close_func" +.Sh DESCRIPTION +The +.Fn xo_set_writer +function allows custom +.Dq write +functions +which can tailor how +.Em libxo +writes data. An +.Fa opaque +argument is +recorded and passed back to the +.Fa write_func +function, allowing the function +to acquire context information. The +.Fa close_func +function can +release this opaque data and any other resources as needed. +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/libxo/xoconfig.h.in b/contrib/libxo/libxo/xoconfig.h.in new file mode 100644 index 0000000..3fe7365 --- /dev/null +++ b/contrib/libxo/libxo/xoconfig.h.in @@ -0,0 +1,198 @@ +/* libxo/xoconfig.h.in. Generated from configure.ac by autoheader. */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Define to 1 if you have the `ctime' function. */ +#undef HAVE_CTIME + +/* Define to 1 if you have the <ctype.h> header file. */ +#undef HAVE_CTYPE_H + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `dlfunc' function. */ +#undef HAVE_DLFUNC + +/* Define to 1 if you have the <errno.h> header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `fdopen' function. */ +#undef HAVE_FDOPEN + +/* Define to 1 if you have the `flock' function. */ +#undef HAVE_FLOCK + +/* Define to 1 if you have the `getpass' function. */ +#undef HAVE_GETPASS + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Support printflike */ +#undef HAVE_PRINTFLIKE + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `srand' function. */ +#undef HAVE_SRAND + +/* Define to 1 if you have the `sranddev' function. */ +#undef HAVE_SRANDDEV + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdio.h> header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <stdtime/tzfile.h> header file. */ +#undef HAVE_STDTIME_TZFILE_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strcspn' function. */ +#undef HAVE_STRCSPN + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strspn' function. */ +#undef HAVE_STRSPN + +/* Define to 1 if you have the `sysctlbyname' function. */ +#undef HAVE_SYSCTLBYNAME + +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/sysctl.h> header file. */ +#undef HAVE_SYS_SYSCTL_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <tzfile.h> header file. */ +#undef HAVE_TZFILE_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Enable debugging */ +#undef LIBXO_DEBUG + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* 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 + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to rpl_realloc if the replacement function should be used. */ +#undef realloc + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t diff --git a/contrib/libxo/libxo/xoversion.h.in b/contrib/libxo/libxo/xoversion.h.in new file mode 100644 index 0000000..777e83e --- /dev/null +++ b/contrib/libxo/libxo/xoversion.h.in @@ -0,0 +1,38 @@ +/* + * $Id$ + * + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * + * xoversion.h -- compile time constants for libxo + * NOTE: This file is generated from xoversion.h.in. + */ + +#ifndef LIBXO_XOVERSION_H +#define LIBXO_XOVERSION_H + +/** + * The version string + */ +#define LIBXO_VERSION "@PACKAGE_VERSION@" + +/** + * The version number + */ +#define LIBXO_VERSION_NUMBER @LIBXO_VERSION_NUMBER@ + +/** + * The version number as a string + */ +#define LIBXO_VERSION_STRING "@LIBXO_VERSION_NUMBER@" + +/** + * The version number extra info as a string + */ +#define LIBXO_VERSION_EXTRA "@LIBXO_VERSION_EXTRA@" + +#endif /* LIBXO_XOVERSION_H */ diff --git a/contrib/libxo/m4/libtool.m4 b/contrib/libxo/m4/libtool.m4 new file mode 100644 index 0000000..44e0ecf --- /dev/null +++ b/contrib/libxo/m4/libtool.m4 @@ -0,0 +1,7982 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 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) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 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.58])dnl We use AC_INCLUDES_DEFAULT +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_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _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 + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which 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 "X${COLLECT_NAMES+set}" != Xset; 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: +# +# <var>='`$ECHO "$<var>" | $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\\"\\\`\\\\\\"" + ;; + *) + 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\\"\\\`\\\\\\"" + ;; + *) + 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 $lt_write_fail = 0 && 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 <bug-libtool@gnu.org>." + +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 "$silent" = yes && + 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 which 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 + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_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 "X${COLLECT_NAMES+set}" != Xset; 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) + + _LT_PROG_REPLACE_SHELLFNS + + 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' + TIMESTAMP='$TIMESTAMP' + 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 $_lt_result -eq 0; 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 $_lt_result -eq 0 && $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 "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; 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 "$lt_cv_ld_force_load" = "no"; 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 "$lt_cv_ld_force_load" = "yes"; 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*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; 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 "$lt_cv_apple_cc_single_mod" != "yes"; 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 "${lt_cv_aix_libpath+set}" = 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 which will find a shell with a builtin +# printf (which 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], +[ --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 "$GCC" = yes; 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 in which 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 "x$enable_libtool_lock" != xno && 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 which ABI we are using. + 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 which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; 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* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + 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*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|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" + ;; + ppc*-*linux*|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 x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + 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*) + 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 "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; 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 + 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" + # 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 x"[$]$2" = xyes; 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 x"[$]$2" = xyes; 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; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # 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"; 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 $i != 17 # 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 "$cross_compiling" = yes; 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 <dlfcn.h> +#endif + +#include <stdio.h> + +#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 -fvisbility=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 "x$enable_dlopen" != xyes; 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 + ]) + ;; + + *) + 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 "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && 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 "x$lt_cv_dlopen_self" = xyes; 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 "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; 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 "$hard_links" = no; 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 in which 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 "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; 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 "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; 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_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 +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; 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` + 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" + else + 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 "$host_cpu" = ia64; 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 + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.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}' + else + # 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' + fi + 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%'\''`; test $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} $libname${shared_ext}' + 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 + ;; + +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' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +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=yes + 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 "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + 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 "$lt_cv_prog_gnu_ld" = yes; 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 + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-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 + + # Append ld.so.conf contents 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' + ;; + +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*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + 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 + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +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 "$with_gnu_ld" = yes; 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=freebsd-elf + 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 "$with_gnu_ld" = yes; 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 "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_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], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which 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 which 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 "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; 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 "$with_gnu_ld" = yes; 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 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +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 "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _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 +# which 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. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && 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 + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +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) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + 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*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 + ;; +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 + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + 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 "$lt_cv_path_NM" != "no"; 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 /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + 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 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 "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# 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 "$GCC" = yes; 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 "$host_cpu" = ia64; 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 + +# 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 -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$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 -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/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 + # and D for any global 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};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print 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 con'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* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$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 "$pipe_works" = yes; 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_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_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 "$GXX" = yes; 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 "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + 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']) + ;; + 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 "$host_cpu" = ia64; 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 "$host_cpu" != ia64; 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) + 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*) + ;; + *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 "$GCC" = yes; 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 "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + 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']) + ;; + + 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 "$host_cpu" = ia64; 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 + ;; + + 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']) + ;; + + 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) + 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' + ;; + 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 which 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 AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + 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) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 + ;; + *) + _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 "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=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 "$with_gnu_ld" = yes; 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 "$lt_use_gnu_ld_interface" = yes; 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 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 "$host_cpu" != ia64; 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 <jrb3@best.com> 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 (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 + ;; + + 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 "$host_os" = linux-dietlibc; 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 "$tmp_diet" = no + 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' ;; + 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 "x$supports_anon_versioning" = xyes; 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 + 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 "x$supports_anon_versioning" = xyes; 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*) + 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 can not +*** 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 "$_LT_TAGVAR(ld_shlibs, $1)" = no; 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 "$GCC" = yes && 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 "$host_cpu" = ia64; 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 AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + 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) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + 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,' + + if test "$GCC" = yes; 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 "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + 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_use_runtimelinking" = yes; 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 "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; 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 "$with_gnu_ld" = yes; 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 + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + 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~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $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 "$GCC" = yes; 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 $output_objdir/$soname = $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 $output_objdir/$soname = $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 "$GCC" = yes && test "$with_gnu_ld" = no; 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 "$with_gnu_ld" = no; 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 "$GCC" = yes && test "$with_gnu_ld" = no; 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 "$with_gnu_ld" = no; 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 "$GCC" = yes; 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 "$lt_cv_irix_exported_symbol" = yes; 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 + 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 + ;; + + netbsd*) + 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*) + 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _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' + ;; + esac + 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 + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; 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 "$GCC" = yes; 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 "$GCC" = yes; 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 "$GCC" = yes; 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 "x$host_vendor" = xsequent; 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 "$GCC" = yes; 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 can NOT 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 "$GCC" = yes; 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 x$host_vendor = xsni; 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 "$_LT_TAGVAR(ld_shlibs, $1)" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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 which 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + 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 "$enable_shared" = yes || 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 "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; 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 "$_lt_caught_CXX_error" != yes; 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 "$GXX" = yes; 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 "$GXX" = yes; 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 "$with_gnu_ld" = yes; 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 "$host_cpu" = ia64; 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 + # need to do runtime linking. + 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 + ;; + 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,' + + if test "$GXX" = yes; 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 "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + 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_use_runtimelinking" = yes; 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 "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; 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 "$with_gnu_ld" = yes; 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 + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> 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~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $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 (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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) + ;; + + 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 + ;; + + gnu*) + ;; + + 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 $output_objdir/$soname = $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 "$GXX" = yes; 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 $output_objdir/$soname = $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 $with_gnu_ld = no; 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 "$GXX" = yes; then + if test $with_gnu_ld = no; 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 "$GXX" = yes; then + if test "$with_gnu_ld" = no; 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) + 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 "x$supports_anon_versioning" = xyes; 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 + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 "$GXX" = yes && test "$with_gnu_ld" = no; 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 "$GXX" = yes && test "$with_gnu_ld" = no; 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 $LDFLAGS $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 -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 $LDFLAGS $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 -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 can NOT 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 "$_LT_TAGVAR(ld_shlibs, $1)" = no && 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 "$_lt_caught_CXX_error" != yes + +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 ${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 +])# _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 $p = "-L" || + test $p = "-R"; 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 "$pre_test_object_deps_done" = no; 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 "$pre_test_object_deps_done" = no; 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)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +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 "X$F77" = "Xno"; 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 "$_lt_disable_F77" != yes; 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + 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 "$enable_shared" = yes || 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 "$_lt_disable_F77" != yes + +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 "X$FC" = "Xno"; 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 "$_lt_disable_FC" != yes; 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + 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 "$enable_shared" = yes || 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 "$_lt_disable_FC" != yes + +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 "x${GCJFLAGS+set}" = xset || 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 $lt_ac_count -gt 10 && 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], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +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_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which 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/contrib/libxo/m4/ltoptions.m4 b/contrib/libxo/m4/ltoptions.m4 new file mode 100644 index 0000000..5d9acd8 --- /dev/null +++ b/contrib/libxo/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 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 7 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_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_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=default]) + +test -z "$pic_mode" && 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/contrib/libxo/m4/ltsugar.m4 b/contrib/libxo/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/contrib/libxo/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 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/contrib/libxo/m4/ltversion.m4 b/contrib/libxo/m4/ltversion.m4 new file mode 100644 index 0000000..07a8602 --- /dev/null +++ b/contrib/libxo/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 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 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/contrib/libxo/m4/lt~obsolete.m4 b/contrib/libxo/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c573da9 --- /dev/null +++ b/contrib/libxo/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 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/contrib/libxo/packaging/libxo.pc.in b/contrib/libxo/packaging/libxo.pc.in new file mode 100644 index 0000000..b291d07 --- /dev/null +++ b/contrib/libxo/packaging/libxo.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + + +Name: libxo +Version: @VERSION@ +Description: The XML Output Library +Libs: @LIBXO_LIBDIR@ @LIBXO_LIBS@ +Cflags: @LIBXO_INCLUDEDIR@ diff --git a/contrib/libxo/packaging/libxo.spec.in b/contrib/libxo/packaging/libxo.spec.in new file mode 100644 index 0000000..e80634c --- /dev/null +++ b/contrib/libxo/packaging/libxo.spec.in @@ -0,0 +1,44 @@ +Name: @PACKAGE_NAME@ +Version: @PACKAGE_VERSION@ +Release: 1%{?dist} +Summary: The libxo library + +Prefix: /usr + +Vendor: Juniper Networks, Inc. +Packager: Phil Shafer <phil@juniper.net> +License: BSD + +Group: Development/Libraries +URL: https://github.com/Juniper/libxo +Source0: https://github.com/Juniper/@PACKAGE_NAME@/releases/@PACKAGE_VERSION@/@PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz + + +%description +Welcome to libxo, a library that generates text, XML, JSON, and HTML +from a single source code path. + +%prep +%setup -q + +%build +%configure +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +%make_install + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%files +%{_bindir}/* +%{_includedir}/libxo/* +%{_libdir}/* +%{_datadir}/doc/libxo/* +%docdir %{_datadir}/doc/libxo/* +%{_mandir}/*/* +%docdir %{_mandir}/*/* diff --git a/contrib/libxo/tests/Makefile.am b/contrib/libxo/tests/Makefile.am new file mode 100644 index 0000000..c69d511 --- /dev/null +++ b/contrib/libxo/tests/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +SUBDIRS=core xo + +test tests: + @(cur=`pwd` ; for dir in $(SUBDIRS) ; do \ + cd $$dir ; \ + $(MAKE) tests ; \ + cd $$cur ; \ + done) + +accept: + @(cur=`pwd` ; for dir in $(SUBDIRS) ; do \ + cd $$dir ; \ + $(MAKE) accept ; \ + cd $$cur ; \ + done) + +valgrind: + @echo '## Running the regression tests under Valgrind' + @echo '## Go get a cup of coffee it is gonna take a while ...' + ${MAKE} VALGRIND='valgrind -q' tests diff --git a/contrib/libxo/tests/core/Makefile.am b/contrib/libxo/tests/core/Makefile.am new file mode 100644 index 0000000..a87fcc5 --- /dev/null +++ b/contrib/libxo/tests/core/Makefile.am @@ -0,0 +1,107 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +AM_CFLAGS = -I${top_srcdir} -I${top_srcdir}/libxo + +# Ick: maintained by hand! +TEST_CASES = \ +test_01.c \ +test_02.c \ +test_03.c \ +test_04.c \ +test_05.c \ +test_06.c \ +test_07.c + +test_01_test_SOURCES = test_01.c +test_02_test_SOURCES = test_02.c +test_03_test_SOURCES = test_03.c +test_04_test_SOURCES = test_04.c +test_05_test_SOURCES = test_05.c +test_06_test_SOURCES = test_06.c +test_07_test_SOURCES = test_07.c + +# TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) + +bin_PROGRAMS = ${TEST_CASES:.c=.test} + +LDADD = \ + ${top_builddir}/libxo/libxo.la + +EXTRA_DIST = \ + ${TEST_CASES} \ + ${addprefix saved/, ${TEST_CASES:.c=.T.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.T.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.XP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.XP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.JP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HP.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HP.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.X.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.X.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.J.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.J.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.H.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.H.out}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HIPx.err}} \ + ${addprefix saved/, ${TEST_CASES:.c=.HIPx.out}} + +S2O = | ${SED} '1,/@@/d' + +all: + +valgrind: + @echo '## Running the regression tests under Valgrind' + ${MAKE} CHECKER='valgrind -q' tests + +#TEST_TRACE = set -x ; + +TEST_ONE = \ + LIBXO_OPTIONS=:W$$fmt \ + ${CHECKER} $$base.test ${TEST_OPTS} \ + > out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O} + +TEST_FORMATS = T XP JP HP X J H HIPx + +test tests: ${bin_PROGRAMS} + @${MKDIR} -p out + -@ ${TEST_TRACE} (for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .c` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${TEST_ONE}; \ + true; \ + done) \ + done) + +one: + -@(test=${TEST_CASE}; data=${TEST_DATA}; ${TEST_ONE} ; true) + +accept: + -@(for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .c` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${CP} out/$$base.$$fmt.out ${srcdir}/saved/$$base.$$fmt.out ; \ + ${CP} out/$$base.$$fmt.err ${srcdir}/saved/$$base.$$fmt.err ; \ + done) \ + done) + +.c.test: + $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -o $@ $< + +CLEANFILES = ${TEST_CASES:.c=.test} +CLEANDIRS = out + +clean-local: + rm -rf ${CLEANDIRS} diff --git a/contrib/libxo/tests/core/saved/test_01.H.err b/contrib/libxo/tests/core/saved/test_01.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.H.err diff --git a/contrib/libxo/tests/core/saved/test_01.H.out b/contrib/libxo/tests/core/saved/test_01.H.out new file mode 100644 index 0000000..e61eecc --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.H.out @@ -0,0 +1 @@ +<div class="line"><div class="title">Item </div><div class="title"> Total Sold</div><div class="title"> In Stock</div><div class="title"> On Order</div><div class="title"> SKU</div></div><div class="line"><div class="data" data-tag="name" data-key="key">gum </div><div class="data" data-tag="sold"> 1412</div><div class="data" data-tag="in-stock"> 54</div><div class="data" data-tag="on-order"> 10</div><div class="data" data-tag="sku" data-key="key"> GRO-000-415</div></div><div class="line"><div class="data" data-tag="name" data-key="key">rope </div><div class="data" data-tag="sold"> 85</div><div class="data" data-tag="in-stock"> 4</div><div class="data" data-tag="on-order"> 2</div><div class="data" data-tag="sku" data-key="key"> HRD-000-212</div></div><div class="line"><div class="data" data-tag="name" data-key="key">ladder </div><div class="data" data-tag="sold"> 0</div><div class="data" data-tag="in-stock"> 2</div><div class="data" data-tag="on-order"> 1</div><div class="data" data-tag="sku" data-key="key"> HRD-000-517</div></div><div class="line"><div class="data" data-tag="name" data-key="key">bolt </div><div class="data" data-tag="sold"> 4123</div><div class="data" data-tag="in-stock"> 144</div><div class="data" data-tag="on-order"> 42</div><div class="data" data-tag="sku" data-key="key"> HRD-000-632</div></div><div class="line"><div class="data" data-tag="name" data-key="key">water </div><div class="data" data-tag="sold"> 17</div><div class="data" data-tag="in-stock"> 14</div><div class="data" data-tag="on-order"> 2</div><div class="data" data-tag="sku" data-key="key"> GRO-000-2331</div></div><div class="line"></div><div class="line"></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">gum</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1412.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">54</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">10</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-415</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">rope</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">85.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">4</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-212</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">ladder</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">2</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">1</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-517</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">bolt</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">4123.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">144</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">42</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-632</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">water</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">17.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">14</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-2331</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">fish</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1321.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">45</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">1</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-533</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_01.HIPx.err b/contrib/libxo/tests/core/saved/test_01.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_01.HIPx.out b/contrib/libxo/tests/core/saved/test_01.HIPx.out new file mode 100644 index 0000000..c38eb04 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.HIPx.out @@ -0,0 +1,238 @@ +<div class="line"> + <div class="title">Item </div> + <div class="title"> Total Sold</div> + <div class="title"> In Stock</div> + <div class="title"> On Order</div> + <div class="title"> SKU</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">gum </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/sold" data-type="number" data-help="Number of items sold"> 1412</div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/in-stock" data-type="number" data-help="Number of items in stock"> 54</div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/on-order" data-type="number" data-help="Number of items on order"> 10</div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> GRO-000-415</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">rope </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/sold" data-type="number" data-help="Number of items sold"> 85</div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/in-stock" data-type="number" data-help="Number of items in stock"> 4</div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/on-order" data-type="number" data-help="Number of items on order"> 2</div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> HRD-000-212</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">ladder </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/sold" data-type="number" data-help="Number of items sold"> 0</div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/in-stock" data-type="number" data-help="Number of items in stock"> 2</div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/on-order" data-type="number" data-help="Number of items on order"> 1</div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> HRD-000-517</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">bolt </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/sold" data-type="number" data-help="Number of items sold"> 4123</div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/in-stock" data-type="number" data-help="Number of items in stock"> 144</div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/on-order" data-type="number" data-help="Number of items on order"> 42</div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> HRD-000-632</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">water </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/sold" data-type="number" data-help="Number of items sold"> 17</div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/in-stock" data-type="number" data-help="Number of items in stock"> 14</div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/on-order" data-type="number" data-help="Number of items on order"> 2</div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> GRO-000-2331</div> +</div> +<div class="line"> +</div> +<div class="line"> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">gum</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/sold" data-type="number" data-help="Number of items sold">1412.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/in-stock" data-type="number" data-help="Number of items in stock">54</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/on-order" data-type="number" data-help="Number of items on order">10</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-415</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">rope</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/sold" data-type="number" data-help="Number of items sold">85.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/in-stock" data-type="number" data-help="Number of items in stock">4</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/on-order" data-type="number" data-help="Number of items on order">2</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-212</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">ladder</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/sold" data-type="number" data-help="Number of items sold">0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/in-stock" data-type="number" data-help="Number of items in stock">2</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/on-order" data-type="number" data-help="Number of items on order">1</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-517</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">bolt</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/sold" data-type="number" data-help="Number of items sold">4123.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/in-stock" data-type="number" data-help="Number of items in stock">144</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/on-order" data-type="number" data-help="Number of items on order">42</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-632</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">water</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/sold" data-type="number" data-help="Number of items sold">17.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/in-stock" data-type="number" data-help="Number of items in stock">14</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/on-order" data-type="number" data-help="Number of items on order">2</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-2331</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">fish</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/sold" data-type="number" data-help="Number of items sold">1321.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/in-stock" data-type="number" data-help="Number of items in stock">45</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/on-order" data-type="number" data-help="Number of items on order">1</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-533</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_01.HP.err b/contrib/libxo/tests/core/saved/test_01.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.HP.err diff --git a/contrib/libxo/tests/core/saved/test_01.HP.out b/contrib/libxo/tests/core/saved/test_01.HP.out new file mode 100644 index 0000000..a887476 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.HP.out @@ -0,0 +1,238 @@ +<div class="line"> + <div class="title">Item </div> + <div class="title"> Total Sold</div> + <div class="title"> In Stock</div> + <div class="title"> On Order</div> + <div class="title"> SKU</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-key="key">gum </div> + <div class="data" data-tag="sold"> 1412</div> + <div class="data" data-tag="in-stock"> 54</div> + <div class="data" data-tag="on-order"> 10</div> + <div class="data" data-tag="sku" data-key="key"> GRO-000-415</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-key="key">rope </div> + <div class="data" data-tag="sold"> 85</div> + <div class="data" data-tag="in-stock"> 4</div> + <div class="data" data-tag="on-order"> 2</div> + <div class="data" data-tag="sku" data-key="key"> HRD-000-212</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-key="key">ladder </div> + <div class="data" data-tag="sold"> 0</div> + <div class="data" data-tag="in-stock"> 2</div> + <div class="data" data-tag="on-order"> 1</div> + <div class="data" data-tag="sku" data-key="key"> HRD-000-517</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-key="key">bolt </div> + <div class="data" data-tag="sold"> 4123</div> + <div class="data" data-tag="in-stock"> 144</div> + <div class="data" data-tag="on-order"> 42</div> + <div class="data" data-tag="sku" data-key="key"> HRD-000-632</div> +</div> +<div class="line"> + <div class="data" data-tag="name" data-key="key">water </div> + <div class="data" data-tag="sold"> 17</div> + <div class="data" data-tag="in-stock"> 14</div> + <div class="data" data-tag="on-order"> 2</div> + <div class="data" data-tag="sku" data-key="key"> GRO-000-2331</div> +</div> +<div class="line"> +</div> +<div class="line"> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-key="key">gum</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">1412.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">54</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">10</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-key="key">GRO-000-415</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-key="key">rope</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">85.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">4</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">2</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-key="key">HRD-000-212</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-key="key">ladder</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">2</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">1</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-key="key">HRD-000-517</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-key="key">bolt</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">4123.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">144</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">42</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-key="key">HRD-000-632</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-key="key">water</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">17.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">14</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">2</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-key="key">GRO-000-2331</div> +</div> +<div class="line"> + <div class="label">Item</div> + <div class="text"> '</div> + <div class="data" data-tag="name" data-key="key">fish</div> + <div class="text">':</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">Total sold</div> + <div class="text">: </div> + <div class="data" data-tag="sold">1321.0</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">In stock</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="in-stock">45</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">On order</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="on-order">1</div> +</div> +<div class="line"> + <div class="padding"> </div> + <div class="label">SKU</div> + <div class="text">: </div> + <div class="data" data-tag="sku" data-key="key">GRO-000-533</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_01.J.err b/contrib/libxo/tests/core/saved/test_01.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.J.err diff --git a/contrib/libxo/tests/core/saved/test_01.J.out b/contrib/libxo/tests/core/saved/test_01.J.out new file mode 100644 index 0000000..289a952 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.J.out @@ -0,0 +1,2 @@ +{"top": {"data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}} +} diff --git a/contrib/libxo/tests/core/saved/test_01.JP.err b/contrib/libxo/tests/core/saved/test_01.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.JP.err diff --git a/contrib/libxo/tests/core/saved/test_01.JP.out b/contrib/libxo/tests/core/saved/test_01.JP.out new file mode 100644 index 0000000..5675845 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.JP.out @@ -0,0 +1,93 @@ +{ + "top": { + "data": { + "item": [ + { + "sku": "GRO-000-415", + "name": "gum", + "sold": 1412, + "in-stock": 54, + "on-order": 10 + }, + { + "sku": "HRD-000-212", + "name": "rope", + "sold": 85, + "in-stock": 4, + "on-order": 2 + }, + { + "sku": "HRD-000-517", + "name": "ladder", + "sold": 0, + "in-stock": 2, + "on-order": 1 + }, + { + "sku": "HRD-000-632", + "name": "bolt", + "sold": 4123, + "in-stock": 144, + "on-order": 42 + }, + { + "sku": "GRO-000-2331", + "name": "water", + "sold": 17, + "in-stock": 14, + "on-order": 2 + } + ] + }, + "data": { + "item": [ + { + "sku": "GRO-000-415", + "name": "gum", + "sold": 1412.0, + "in-stock": 54, + "on-order": 10 + }, + { + "sku": "HRD-000-212", + "name": "rope", + "sold": 85.0, + "in-stock": 4, + "on-order": 2 + }, + { + "sku": "HRD-000-517", + "name": "ladder", + "sold": 0, + "in-stock": 2, + "on-order": 1 + }, + { + "sku": "HRD-000-632", + "name": "bolt", + "sold": 4123.0, + "in-stock": 144, + "on-order": 42 + }, + { + "sku": "GRO-000-2331", + "name": "water", + "sold": 17.0, + "in-stock": 14, + "on-order": 2 + } + ] + }, + "data": { + "item": [ + { + "sku": "GRO-000-533", + "name": "fish", + "sold": 1321.0, + "in-stock": 45, + "on-order": 1 + } + ] + } + } +} diff --git a/contrib/libxo/tests/core/saved/test_01.T.err b/contrib/libxo/tests/core/saved/test_01.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.T.err diff --git a/contrib/libxo/tests/core/saved/test_01.T.out b/contrib/libxo/tests/core/saved/test_01.T.out new file mode 100644 index 0000000..c2ad7a0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.T.out @@ -0,0 +1,38 @@ +Item Total Sold In Stock On Order SKU +gum 1412 54 10 GRO-000-415 +rope 85 4 2 HRD-000-212 +ladder 0 2 1 HRD-000-517 +bolt 4123 144 42 HRD-000-632 +water 17 14 2 GRO-000-2331 + + +Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 +Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 +Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 +Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 +Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 +Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 diff --git a/contrib/libxo/tests/core/saved/test_01.X.err b/contrib/libxo/tests/core/saved/test_01.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.X.err diff --git a/contrib/libxo/tests/core/saved/test_01.X.out b/contrib/libxo/tests/core/saved/test_01.X.out new file mode 100644 index 0000000..c3e07c8 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.X.out @@ -0,0 +1 @@ +<top><data><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data></top>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_01.XP.err b/contrib/libxo/tests/core/saved/test_01.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.XP.err diff --git a/contrib/libxo/tests/core/saved/test_01.XP.out b/contrib/libxo/tests/core/saved/test_01.XP.out new file mode 100644 index 0000000..49fc6da --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.XP.out @@ -0,0 +1,85 @@ +<top> + <data> + <item> + <sku key="key">GRO-000-415</sku> + <name key="key">gum</name> + <sold>1412</sold> + <in-stock>54</in-stock> + <on-order>10</on-order> + </item> + <item> + <sku key="key">HRD-000-212</sku> + <name key="key">rope</name> + <sold>85</sold> + <in-stock>4</in-stock> + <on-order>2</on-order> + </item> + <item> + <sku key="key">HRD-000-517</sku> + <name key="key">ladder</name> + <sold>0</sold> + <in-stock>2</in-stock> + <on-order>1</on-order> + </item> + <item> + <sku key="key">HRD-000-632</sku> + <name key="key">bolt</name> + <sold>4123</sold> + <in-stock>144</in-stock> + <on-order>42</on-order> + </item> + <item> + <sku key="key">GRO-000-2331</sku> + <name key="key">water</name> + <sold>17</sold> + <in-stock>14</in-stock> + <on-order>2</on-order> + </item> + </data> + <data> + <item> + <sku key="key">GRO-000-415</sku> + <name key="key">gum</name> + <sold>1412.0</sold> + <in-stock>54</in-stock> + <on-order>10</on-order> + </item> + <item> + <sku key="key">HRD-000-212</sku> + <name key="key">rope</name> + <sold>85.0</sold> + <in-stock>4</in-stock> + <on-order>2</on-order> + </item> + <item> + <sku key="key">HRD-000-517</sku> + <name key="key">ladder</name> + <sold>0</sold> + <in-stock>2</in-stock> + <on-order>1</on-order> + </item> + <item> + <sku key="key">HRD-000-632</sku> + <name key="key">bolt</name> + <sold>4123.0</sold> + <in-stock>144</in-stock> + <on-order>42</on-order> + </item> + <item> + <sku key="key">GRO-000-2331</sku> + <name key="key">water</name> + <sold>17.0</sold> + <in-stock>14</in-stock> + <on-order>2</on-order> + </item> + </data> + <data> + <item> + <sku key="key">GRO-000-533</sku> + <name key="key">fish</name> + <sold>1321.0</sold> + <in-stock>45</in-stock> + <on-order>1</on-order> + </item> + </data> +</top> diff --git a/contrib/libxo/tests/core/saved/test_01.err b/contrib/libxo/tests/core/saved/test_01.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.err diff --git a/contrib/libxo/tests/core/saved/test_01.out b/contrib/libxo/tests/core/saved/test_01.out new file mode 100644 index 0000000..c2ad7a0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_01.out @@ -0,0 +1,38 @@ +Item Total Sold In Stock On Order SKU +gum 1412 54 10 GRO-000-415 +rope 85 4 2 HRD-000-212 +ladder 0 2 1 HRD-000-517 +bolt 4123 144 42 HRD-000-632 +water 17 14 2 GRO-000-2331 + + +Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 +Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 +Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 +Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 +Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 +Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 diff --git a/contrib/libxo/tests/core/saved/test_02.H.err b/contrib/libxo/tests/core/saved/test_02.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.H.err diff --git a/contrib/libxo/tests/core/saved/test_02.H.out b/contrib/libxo/tests/core/saved/test_02.H.out new file mode 100644 index 0000000..60350b5 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.H.out @@ -0,0 +1,3 @@ +<div class="line"><div class="data" data-tag="mbuf-current">10</div><div class="text">/</div><div class="data" data-tag="mbuf-cache">20</div><div class="text">/</div><div class="data" data-tag="mbuf-total">30</div><div class="text"> </div><div class="note">mbufs <&> in use (current/cache/total)</div></div><div class="line"><div class="data" data-tag="distance" data-units="miles">50</div><div class="padding"> </div><div class="text"> from </div><div class="data" data-tag="location">Boston</div></div><div class="line"><div class="data" data-tag="memory" data-units="k">64</div><div class="text"> left out of </div><div class="data" data-tag="total" data-units="kb">640</div></div><div class="line"><div class="data" data-tag="memory" data-units="k">64</div><div class="text"> left out of </div><div class="data" data-tag="total" data-units="kilobytes">640</div></div><div class="line"><div class="title">beforeworkingafter:</div></div><div class="line"><div class="data" data-tag="some">string</div><div class="data" data-tag="ten">10</div><div class="data" data-tag="eleven">11</div></div><div class="line"><div class="data" data-tag="unknown">1010</div><div class="text"> </div><div class="note">packets here/there/everywhere</div></div><div class="line"><div class="text">(</div><div class="padding"> </div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="text">)</div></div><div class="line"><div class="text">(</div><div class="padding"> </div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="text">)</div></div><div class="line"><div class="text">(</div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="padding"> </div><div class="text">)</div></div><div class="line"><div class="text">(</div><div class="data" data-tag="min">15</div><div class="text">/</div><div class="data" data-tag="cur">20</div><div class="text">/</div><div class="data" data-tag="max">125</div><div class="padding"> </div><div class="text">)</div></div><div class="line"><div class="data" data-tag="flag">one</div><div class="text"> </div><div class="data" data-tag="flag">two</div><div class="text"> </div><div class="data" data-tag="flag">three</div></div><div class="line"><div class="text">1:</div><div class="data" data-tag="t1"> 1000</div><div class="text"> 2:</div><div class="data" data-tag="t2">test5000 </div><div class="text"> 3:</div><div class="data" data-tag="t3"> ten-longx</div><div class="text"> 4:</div><div class="data" data-tag="t4">xtest </div></div><div class="line"><div class="error">this is an error</div></div><div class="line"><div class="error">two more errors</div></div><div class="line"><div class="warning">this is an warning</div></div><div class="line"><div class="warning">two more warnings</div></div><div class="line"><div class="label">V1/V2 packets</div><div class="text">: </div><div class="data" data-tag="count">10</div></div><div class="line"><div class="data" data-tag="test">0004</div><div class="text"> </div><div class="label">tries</div></div><div class="line"><div class="message">improper use of profanity; ten yard penalty; first down +</div></div><div class="line"><div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_02.HIPx.err b/contrib/libxo/tests/core/saved/test_02.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_02.HIPx.out b/contrib/libxo/tests/core/saved/test_02.HIPx.out new file mode 100644 index 0000000..f4264f7 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.HIPx.out @@ -0,0 +1,125 @@ +<div class="line"> + <div class="data" data-tag="mbuf-current" data-xpath="/top/data/mbuf-current">10</div> + <div class="text">/</div> + <div class="data" data-tag="mbuf-cache" data-xpath="/top/data/mbuf-cache">20</div> + <div class="text">/</div> + <div class="data" data-tag="mbuf-total" data-xpath="/top/data/mbuf-total">30</div> + <div class="text"> </div> + <div class="note">mbufs <&> in use (current/cache/total)</div> +</div> +<div class="line"> + <div class="data" data-tag="distance" data-units="miles" data-xpath="/top/data/distance">50</div> + <div class="padding"> </div> + <div class="text"> from </div> + <div class="data" data-tag="location" data-xpath="/top/data/location">Boston</div> +</div> +<div class="line"> + <div class="data" data-tag="memory" data-units="k" data-xpath="/top/data/memory">64</div> + <div class="text"> left out of </div> + <div class="data" data-tag="total" data-units="kb" data-xpath="/top/data/total">640</div> +</div> +<div class="line"> + <div class="data" data-tag="memory" data-units="k" data-xpath="/top/data/memory">64</div> + <div class="text"> left out of </div> + <div class="data" data-tag="total" data-units="kilobytes" data-xpath="/top/data/total">640</div> +</div> +<div class="line"> + <div class="title">beforeworkingafter:</div> +</div> +<div class="line"> + <div class="data" data-tag="some" data-xpath="/top/data/some">string</div> + <div class="data" data-tag="ten" data-xpath="/top/data/ten">10</div> + <div class="data" data-tag="eleven" data-xpath="/top/data/eleven">11</div> +</div> +<div class="line"> + <div class="data" data-tag="unknown" data-xpath="/top/data/unknown">1010</div> + <div class="text"> </div> + <div class="note">packets here/there/everywhere</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="padding"> </div> + <div class="data" data-tag="min" data-xpath="/top/data/min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max" data-xpath="/top/data/max">125</div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="padding"> </div> + <div class="data" data-tag="min" data-xpath="/top/data/min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max" data-xpath="/top/data/max">125</div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="data" data-tag="min" data-xpath="/top/data/min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max" data-xpath="/top/data/max">125</div> + <div class="padding"> </div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="data" data-tag="min" data-xpath="/top/data/min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur" data-xpath="/top/data/cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max" data-xpath="/top/data/max">125</div> + <div class="padding"> </div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="data" data-tag="flag" data-xpath="/top/data/flag">one</div> + <div class="text"> </div> + <div class="data" data-tag="flag" data-xpath="/top/data/flag">two</div> + <div class="text"> </div> + <div class="data" data-tag="flag" data-xpath="/top/data/flag">three</div> +</div> +<div class="line"> + <div class="text">1:</div> + <div class="data" data-tag="t1" data-xpath="/top/data/t1"> 1000</div> + <div class="text"> 2:</div> + <div class="data" data-tag="t2" data-xpath="/top/data/t2">test5000 </div> + <div class="text"> 3:</div> + <div class="data" data-tag="t3" data-xpath="/top/data/t3"> ten-longx</div> + <div class="text"> 4:</div> + <div class="data" data-tag="t4" data-xpath="/top/data/t4">xtest </div> +</div> +<div class="line"> + <div class="error">this is an error</div> +</div> +<div class="line"> + <div class="error">two more errors</div> +</div> +<div class="line"> + <div class="warning">this is an warning</div> +</div> +<div class="line"> + <div class="warning">two more warnings</div> +</div> +<div class="line"> + <div class="label">V1/V2 packets</div> + <div class="text">: </div> + <div class="data" data-tag="count" data-xpath="/top/data/count">10</div> +</div> +<div class="line"> + <div class="data" data-tag="test" data-xpath="/top/data/test">0004</div> + <div class="text"> </div> + <div class="label">tries</div> +</div> +<div class="line"> + <div class="message">improper use of profanity; ten yard penalty; first down +</div> +</div> +<div class="line"> + <div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_02.HP.err b/contrib/libxo/tests/core/saved/test_02.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.HP.err diff --git a/contrib/libxo/tests/core/saved/test_02.HP.out b/contrib/libxo/tests/core/saved/test_02.HP.out new file mode 100644 index 0000000..1ccf369 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.HP.out @@ -0,0 +1,125 @@ +<div class="line"> + <div class="data" data-tag="mbuf-current">10</div> + <div class="text">/</div> + <div class="data" data-tag="mbuf-cache">20</div> + <div class="text">/</div> + <div class="data" data-tag="mbuf-total">30</div> + <div class="text"> </div> + <div class="note">mbufs <&> in use (current/cache/total)</div> +</div> +<div class="line"> + <div class="data" data-tag="distance" data-units="miles">50</div> + <div class="padding"> </div> + <div class="text"> from </div> + <div class="data" data-tag="location">Boston</div> +</div> +<div class="line"> + <div class="data" data-tag="memory" data-units="k">64</div> + <div class="text"> left out of </div> + <div class="data" data-tag="total" data-units="kb">640</div> +</div> +<div class="line"> + <div class="data" data-tag="memory" data-units="k">64</div> + <div class="text"> left out of </div> + <div class="data" data-tag="total" data-units="kilobytes">640</div> +</div> +<div class="line"> + <div class="title">beforeworkingafter:</div> +</div> +<div class="line"> + <div class="data" data-tag="some">string</div> + <div class="data" data-tag="ten">10</div> + <div class="data" data-tag="eleven">11</div> +</div> +<div class="line"> + <div class="data" data-tag="unknown">1010</div> + <div class="text"> </div> + <div class="note">packets here/there/everywhere</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="padding"> </div> + <div class="data" data-tag="min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max">125</div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="padding"> </div> + <div class="data" data-tag="min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max">125</div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="data" data-tag="min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max">125</div> + <div class="padding"> </div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="text">(</div> + <div class="data" data-tag="min">15</div> + <div class="text">/</div> + <div class="data" data-tag="cur">20</div> + <div class="text">/</div> + <div class="data" data-tag="max">125</div> + <div class="padding"> </div> + <div class="text">)</div> +</div> +<div class="line"> + <div class="data" data-tag="flag">one</div> + <div class="text"> </div> + <div class="data" data-tag="flag">two</div> + <div class="text"> </div> + <div class="data" data-tag="flag">three</div> +</div> +<div class="line"> + <div class="text">1:</div> + <div class="data" data-tag="t1"> 1000</div> + <div class="text"> 2:</div> + <div class="data" data-tag="t2">test5000 </div> + <div class="text"> 3:</div> + <div class="data" data-tag="t3"> ten-longx</div> + <div class="text"> 4:</div> + <div class="data" data-tag="t4">xtest </div> +</div> +<div class="line"> + <div class="error">this is an error</div> +</div> +<div class="line"> + <div class="error">two more errors</div> +</div> +<div class="line"> + <div class="warning">this is an warning</div> +</div> +<div class="line"> + <div class="warning">two more warnings</div> +</div> +<div class="line"> + <div class="label">V1/V2 packets</div> + <div class="text">: </div> + <div class="data" data-tag="count">10</div> +</div> +<div class="line"> + <div class="data" data-tag="test">0004</div> + <div class="text"> </div> + <div class="label">tries</div> +</div> +<div class="line"> + <div class="message">improper use of profanity; ten yard penalty; first down +</div> +</div> +<div class="line"> + <div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_02.J.err b/contrib/libxo/tests/core/saved/test_02.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.J.err diff --git a/contrib/libxo/tests/core/saved/test_02.J.out b/contrib/libxo/tests/core/saved/test_02.J.out new file mode 100644 index 0000000..621e061 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.J.out @@ -0,0 +1,2 @@ +{"top": {"data": {"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"min":15,"cur":20,"max":30,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125, "flag": ["one","two","three"],"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest","count":10,"test":4}} +} diff --git a/contrib/libxo/tests/core/saved/test_02.JP.err b/contrib/libxo/tests/core/saved/test_02.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.JP.err diff --git a/contrib/libxo/tests/core/saved/test_02.JP.out b/contrib/libxo/tests/core/saved/test_02.JP.out new file mode 100644 index 0000000..9479817 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.JP.out @@ -0,0 +1,40 @@ +{ + "top": { + "data": { + "mbuf-current": 10, + "mbuf-cache": 20, + "mbuf-total": 30, + "distance": 50, + "location": "Boston", + "memory": 64, + "total": 640, + "memory": 64, + "total": 640, + "ten": 10, + "eleven": 11, + "unknown": 1010, + "min": 15, + "cur": 20, + "max": 30, + "min": 15, + "cur": 20, + "max": 125, + "min": 15, + "cur": 20, + "max": 125, + "min": 15, + "cur": 20, + "max": 125, + "flag": [ + "one", "two", "three" + ], + "empty-tag": true, + "t1": "1000", + "t2": "test5000", + "t3": "ten-longx", + "t4": "xtest", + "count": 10, + "test": 4 + } + } +} diff --git a/contrib/libxo/tests/core/saved/test_02.T.err b/contrib/libxo/tests/core/saved/test_02.T.err new file mode 100644 index 0000000..80fabe3 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.T.err @@ -0,0 +1 @@ +Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> diff --git a/contrib/libxo/tests/core/saved/test_02.T.out b/contrib/libxo/tests/core/saved/test_02.T.out new file mode 100644 index 0000000..b37ba00 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.T.out @@ -0,0 +1,20 @@ +10/20/30 mbufs <&> in use (current/cache/total) +50 miles from Boston +64k left out of 640kb +64k left out of 640kilobytes +beforeworkingafter: +string1011 +1010 packets here/there/everywhere +( 15/20/125) +( 15/20/125) +(15/20/125 ) +(15/20/125 ) +one two three +1: 1000 2:test5000 3: ten-longx 4:xtest +this is an error +two more errors +this is an warning +two more warnings +V1/V2 packets: 10 +0004 tries +improper use of profanity; ten yard penalty; first down diff --git a/contrib/libxo/tests/core/saved/test_02.X.err b/contrib/libxo/tests/core/saved/test_02.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.X.err diff --git a/contrib/libxo/tests/core/saved/test_02.X.out b/contrib/libxo/tests/core/saved/test_02.X.out new file mode 100644 index 0000000..ff6d40c --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.X.out @@ -0,0 +1,3 @@ +<top><data><mbuf-current>10</mbuf-current><mbuf-cache>20</mbuf-cache><mbuf-total>30</mbuf-total><distance units="miles">50</distance><location>Boston</location><memory units="k">64</memory><total units="kb">640</total><memory units="k">64</memory><total units="kilobytes">640</total><ten>10</ten><eleven>11</eleven><unknown>1010</unknown><min>15</min><cur>20</cur><max>30</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><flag>one</flag><flag>two</flag><flag>three</flag><empty-tag></empty-tag><t1>1000</t1><t2>test5000</t2><t3>ten-longx</t3><t4>xtest</t4><error><message>this is an error</message></error><error><message>two more errors</message></error><warning><message>this is an warning</message></warning><warning><message>two more warnings</message></warning><count>10</count><test>4</test><message>improper use of profanity; ten yard penalty; first down</message> +<error><message>Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +</message></error></data></top>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_02.XP.err b/contrib/libxo/tests/core/saved/test_02.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.XP.err diff --git a/contrib/libxo/tests/core/saved/test_02.XP.out b/contrib/libxo/tests/core/saved/test_02.XP.out new file mode 100644 index 0000000..d32c730 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.XP.out @@ -0,0 +1,55 @@ +<top> + <data> + <mbuf-current>10</mbuf-current> + <mbuf-cache>20</mbuf-cache> + <mbuf-total>30</mbuf-total> + <distance units="miles">50</distance> + <location>Boston</location> + <memory units="k">64</memory> + <total units="kb">640</total> + <memory units="k">64</memory> + <total units="kilobytes">640</total> + <ten>10</ten> + <eleven>11</eleven> + <unknown>1010</unknown> + <min>15</min> + <cur>20</cur> + <max>30</max> + <min>15</min> + <cur>20</cur> + <max>125</max> + <min>15</min> + <cur>20</cur> + <max>125</max> + <min>15</min> + <cur>20</cur> + <max>125</max> + <flag>one</flag> + <flag>two</flag> + <flag>three</flag> + <empty-tag></empty-tag> + <t1>1000</t1> + <t2>test5000</t2> + <t3>ten-longx</t3> + <t4>xtest</t4> + <error> + <message>this is an error</message> + </error> + <error> + <message>two more errors</message> + </error> + <warning> + <message>this is an warning</message> + </warning> + <warning> + <message>two more warnings</message> + </warning> + <count>10</count> + <test>4</test> + <message>improper use of profanity; ten yard penalty; first down</message> + <error> + <message>Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> +</message> + </error> + </data> +</top> diff --git a/contrib/libxo/tests/core/saved/test_02.err b/contrib/libxo/tests/core/saved/test_02.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.err diff --git a/contrib/libxo/tests/core/saved/test_02.out b/contrib/libxo/tests/core/saved/test_02.out new file mode 100644 index 0000000..c2ad7a0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_02.out @@ -0,0 +1,38 @@ +Item Total Sold In Stock On Order SKU +gum 1412 54 10 GRO-000-415 +rope 85 4 2 HRD-000-212 +ladder 0 2 1 HRD-000-517 +bolt 4123 144 42 HRD-000-632 +water 17 14 2 GRO-000-2331 + + +Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 +Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 +Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 +Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 +Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 +Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 diff --git a/contrib/libxo/tests/core/saved/test_03.H.err b/contrib/libxo/tests/core/saved/test_03.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.H.err diff --git a/contrib/libxo/tests/core/saved/test_03.H.out b/contrib/libxo/tests/core/saved/test_03.H.out new file mode 100644 index 0000000..6b9ccc4 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.H.out @@ -0,0 +1 @@ +<div class="line"><div class="data" data-tag="first-name">Terry</div><div class="text"> </div><div class="data" data-tag="last-name">Jones</div><div class="text"> works in dept #</div><div class="data" data-tag="department">660</div></div><div class="line"><div class="data" data-tag="first-name">Leslie</div><div class="text"> </div><div class="data" data-tag="last-name">Patterson</div><div class="text"> works in dept #</div><div class="data" data-tag="department">341</div></div><div class="line"><div class="data" data-tag="first-name">Ashley</div><div class="text"> </div><div class="data" data-tag="last-name">Smith</div><div class="text"> works in dept #</div><div class="data" data-tag="department">1440</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_03.HIPx.err b/contrib/libxo/tests/core/saved/test_03.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_03.HIPx.out b/contrib/libxo/tests/core/saved/test_03.HIPx.out new file mode 100644 index 0000000..bfae221 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.HIPx.out @@ -0,0 +1,21 @@ +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Terry</div> + <div class="text"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Jones</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department">660</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Leslie</div> + <div class="text"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Patterson</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department">341</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Ashley</div> + <div class="text"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Smith</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department">1440</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_03.HP.err b/contrib/libxo/tests/core/saved/test_03.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.HP.err diff --git a/contrib/libxo/tests/core/saved/test_03.HP.out b/contrib/libxo/tests/core/saved/test_03.HP.out new file mode 100644 index 0000000..f8b072a --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.HP.out @@ -0,0 +1,21 @@ +<div class="line"> + <div class="data" data-tag="first-name">Terry</div> + <div class="text"> </div> + <div class="data" data-tag="last-name">Jones</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department">660</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Leslie</div> + <div class="text"> </div> + <div class="data" data-tag="last-name">Patterson</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department">341</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Ashley</div> + <div class="text"> </div> + <div class="data" data-tag="last-name">Smith</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department">1440</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_03.J.err b/contrib/libxo/tests/core/saved/test_03.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.J.err diff --git a/contrib/libxo/tests/core/saved/test_03.J.out b/contrib/libxo/tests/core/saved/test_03.J.out new file mode 100644 index 0000000..4ba1fb1 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.J.out @@ -0,0 +1,2 @@ +{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]} +} diff --git a/contrib/libxo/tests/core/saved/test_03.JP.err b/contrib/libxo/tests/core/saved/test_03.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.JP.err diff --git a/contrib/libxo/tests/core/saved/test_03.JP.out b/contrib/libxo/tests/core/saved/test_03.JP.out new file mode 100644 index 0000000..ff2d5b0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.JP.out @@ -0,0 +1,21 @@ +{ + "employees": { + "employee": [ + { + "first-name": "Terry", + "last-name": "Jones", + "department": 660 + }, + { + "first-name": "Leslie", + "last-name": "Patterson", + "department": 341 + }, + { + "first-name": "Ashley", + "last-name": "Smith", + "department": 1440 + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_03.T.err b/contrib/libxo/tests/core/saved/test_03.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.T.err diff --git a/contrib/libxo/tests/core/saved/test_03.T.out b/contrib/libxo/tests/core/saved/test_03.T.out new file mode 100644 index 0000000..da60fb7 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.T.out @@ -0,0 +1,3 @@ +Terry Jones works in dept #660 +Leslie Patterson works in dept #341 +Ashley Smith works in dept #1440 diff --git a/contrib/libxo/tests/core/saved/test_03.X.err b/contrib/libxo/tests/core/saved/test_03.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.X.err diff --git a/contrib/libxo/tests/core/saved/test_03.X.out b/contrib/libxo/tests/core/saved/test_03.X.out new file mode 100644 index 0000000..a626fb6 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.X.out @@ -0,0 +1 @@ +<employees><employee><first-name>Terry</first-name><last-name>Jones</last-name><department>660</department></employee><employee><first-name>Leslie</first-name><last-name>Patterson</last-name><department>341</department></employee><employee><first-name>Ashley</first-name><last-name>Smith</last-name><department>1440</department></employee></employees>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_03.XP.err b/contrib/libxo/tests/core/saved/test_03.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.XP.err diff --git a/contrib/libxo/tests/core/saved/test_03.XP.out b/contrib/libxo/tests/core/saved/test_03.XP.out new file mode 100644 index 0000000..b6e7641 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.XP.out @@ -0,0 +1,17 @@ +<employees> + <employee> + <first-name>Terry</first-name> + <last-name>Jones</last-name> + <department>660</department> + </employee> + <employee> + <first-name>Leslie</first-name> + <last-name>Patterson</last-name> + <department>341</department> + </employee> + <employee> + <first-name>Ashley</first-name> + <last-name>Smith</last-name> + <department>1440</department> + </employee> +</employees> diff --git a/contrib/libxo/tests/core/saved/test_03.err b/contrib/libxo/tests/core/saved/test_03.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.err diff --git a/contrib/libxo/tests/core/saved/test_03.out b/contrib/libxo/tests/core/saved/test_03.out new file mode 100644 index 0000000..da60fb7 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_03.out @@ -0,0 +1,3 @@ +Terry Jones works in dept #660 +Leslie Patterson works in dept #341 +Ashley Smith works in dept #1440 diff --git a/contrib/libxo/tests/core/saved/test_04.H.err b/contrib/libxo/tests/core/saved/test_04.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.H.err diff --git a/contrib/libxo/tests/core/saved/test_04.H.out b/contrib/libxo/tests/core/saved/test_04.H.out new file mode 100644 index 0000000..1758236 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.H.out @@ -0,0 +1 @@ +<div class="line"><div class="title">Last Name </div><div class="title">First Name </div><div class="title">Department</div></div><div class="line"><div class="data" data-tag="first-name">Terry </div><div class="data" data-tag="last-name">Jones </div><div class="data" data-tag="department"> 660</div></div><div class="line"><div class="data" data-tag="first-name">Leslie </div><div class="data" data-tag="last-name">Patterson </div><div class="data" data-tag="department"> 341</div></div><div class="line"><div class="data" data-tag="first-name">Ashley </div><div class="data" data-tag="last-name">Smith </div><div class="data" data-tag="department"> 1440</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_04.HIPx.err b/contrib/libxo/tests/core/saved/test_04.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_04.HIPx.out b/contrib/libxo/tests/core/saved/test_04.HIPx.out new file mode 100644 index 0000000..473113b --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.HIPx.out @@ -0,0 +1,20 @@ +<div class="line"> + <div class="title">Last Name </div> + <div class="title">First Name </div> + <div class="title">Department</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Terry </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Jones </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 660</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Leslie </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Patterson </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 341</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Ashley </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Smith </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 1440</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_04.HP.err b/contrib/libxo/tests/core/saved/test_04.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.HP.err diff --git a/contrib/libxo/tests/core/saved/test_04.HP.out b/contrib/libxo/tests/core/saved/test_04.HP.out new file mode 100644 index 0000000..d56f8f4 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.HP.out @@ -0,0 +1,20 @@ +<div class="line"> + <div class="title">Last Name </div> + <div class="title">First Name </div> + <div class="title">Department</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Terry </div> + <div class="data" data-tag="last-name">Jones </div> + <div class="data" data-tag="department"> 660</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Leslie </div> + <div class="data" data-tag="last-name">Patterson </div> + <div class="data" data-tag="department"> 341</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Ashley </div> + <div class="data" data-tag="last-name">Smith </div> + <div class="data" data-tag="department"> 1440</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_04.J.err b/contrib/libxo/tests/core/saved/test_04.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.J.err diff --git a/contrib/libxo/tests/core/saved/test_04.J.out b/contrib/libxo/tests/core/saved/test_04.J.out new file mode 100644 index 0000000..4ba1fb1 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.J.out @@ -0,0 +1,2 @@ +{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]} +} diff --git a/contrib/libxo/tests/core/saved/test_04.JP.err b/contrib/libxo/tests/core/saved/test_04.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.JP.err diff --git a/contrib/libxo/tests/core/saved/test_04.JP.out b/contrib/libxo/tests/core/saved/test_04.JP.out new file mode 100644 index 0000000..ff2d5b0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.JP.out @@ -0,0 +1,21 @@ +{ + "employees": { + "employee": [ + { + "first-name": "Terry", + "last-name": "Jones", + "department": 660 + }, + { + "first-name": "Leslie", + "last-name": "Patterson", + "department": 341 + }, + { + "first-name": "Ashley", + "last-name": "Smith", + "department": 1440 + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_04.T.err b/contrib/libxo/tests/core/saved/test_04.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.T.err diff --git a/contrib/libxo/tests/core/saved/test_04.T.out b/contrib/libxo/tests/core/saved/test_04.T.out new file mode 100644 index 0000000..aca80c4 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.T.out @@ -0,0 +1,4 @@ +Last Name First Name Department +Terry Jones 660 +Leslie Patterson 341 +Ashley Smith 1440 diff --git a/contrib/libxo/tests/core/saved/test_04.X.err b/contrib/libxo/tests/core/saved/test_04.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.X.err diff --git a/contrib/libxo/tests/core/saved/test_04.X.out b/contrib/libxo/tests/core/saved/test_04.X.out new file mode 100644 index 0000000..a626fb6 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.X.out @@ -0,0 +1 @@ +<employees><employee><first-name>Terry</first-name><last-name>Jones</last-name><department>660</department></employee><employee><first-name>Leslie</first-name><last-name>Patterson</last-name><department>341</department></employee><employee><first-name>Ashley</first-name><last-name>Smith</last-name><department>1440</department></employee></employees>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_04.XP.err b/contrib/libxo/tests/core/saved/test_04.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.XP.err diff --git a/contrib/libxo/tests/core/saved/test_04.XP.out b/contrib/libxo/tests/core/saved/test_04.XP.out new file mode 100644 index 0000000..b6e7641 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_04.XP.out @@ -0,0 +1,17 @@ +<employees> + <employee> + <first-name>Terry</first-name> + <last-name>Jones</last-name> + <department>660</department> + </employee> + <employee> + <first-name>Leslie</first-name> + <last-name>Patterson</last-name> + <department>341</department> + </employee> + <employee> + <first-name>Ashley</first-name> + <last-name>Smith</last-name> + <department>1440</department> + </employee> +</employees> diff --git a/contrib/libxo/tests/core/saved/test_05.H.err b/contrib/libxo/tests/core/saved/test_05.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.H.err diff --git a/contrib/libxo/tests/core/saved/test_05.H.out b/contrib/libxo/tests/core/saved/test_05.H.out new file mode 100644 index 0000000..b75d728 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.H.out @@ -0,0 +1 @@ +<div class="line"><div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div><div class="data" data-tag="v1">γιγνώσκειν</div><div class="text">, </div><div class="data" data-tag="v2">ὦ ἄνδρες ᾿Αθηναῖοι</div></div><div class="line"><div class="text">გთხოვთ </div><div class="data" data-tag="v1">ახლავე გაიაროთ რეგისტრაცია</div><div class="text"> </div><div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div></div><div class="line"><div class="title">First Name </div><div class="title">Last Name </div><div class="title">Department </div><div class="title">Time (%)</div></div><div class="line"><div class="data" data-tag="first-name">Jim</div><div class="text"> (</div><div class="data" data-tag="nic-name">"რეგტ"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">გთხოვთ ახ </div><div class="data" data-tag="department"> 431</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">Terry</div><div class="text"> (</div><div class="data" data-tag="nic-name">"<one"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Οὐχὶ ταὐτὰ παρ</div><div class="data" data-tag="department"> 660</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">Leslie</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Les"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Patterson </div><div class="data" data-tag="department"> 341</div><div class="data" data-tag="percent-time"> 60</div></div><div class="line"><div class="data" data-tag="first-name">Ashley</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Ash"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Meter & Smith </div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="first-name">0123456789</div><div class="text"> (</div><div class="data" data-tag="nic-name">"0123456789"</div><div class="text">)</div><div class="data" data-tag="last-name">01234567890123</div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="first-name">ახლა</div><div class="text"> (</div><div class="data" data-tag="nic-name">"გაიარო"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">საერთაშორისო </div><div class="data" data-tag="department"> 123</div><div class="data" data-tag="percent-time"> 90</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_05.HIPx.err b/contrib/libxo/tests/core/saved/test_05.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_05.HIPx.out b/contrib/libxo/tests/core/saved/test_05.HIPx.out new file mode 100644 index 0000000..2054de1 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.HIPx.out @@ -0,0 +1,77 @@ +<div class="line"> + <div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div> + <div class="data" data-tag="v1" data-xpath="/employees/v1">γιγνώσκειν</div> + <div class="text">, </div> + <div class="data" data-tag="v2" data-xpath="/employees/v2">ὦ ἄνδρες ᾿Αθηναῖοι</div> +</div> +<div class="line"> + <div class="text">გთხოვთ </div> + <div class="data" data-tag="v1" data-xpath="/employees/v1">ახლავე გაიაროთ რეგისტრაცია</div> + <div class="text"> </div> + <div class="data" data-tag="v2" data-xpath="/employees/v2">Unicode-ის მეათე საერთაშორისო</div> +</div> +<div class="line"> + <div class="title">First Name </div> + <div class="title">Last Name </div> + <div class="title">Department </div> + <div class="title">Time (%)</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Jim</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"რეგტ"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">გთხოვთ ახ </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 431</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Terry</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"<one"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Οὐχὶ ταὐτὰ παρ</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 660</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Leslie</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"Les"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Patterson </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 341</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 60</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Ashley</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"Ash"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Meter & Smith </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 1440</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">0123456789</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"0123456789"</div> + <div class="text">)</div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">01234567890123</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 1440</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">ახლა</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"გაიარო"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">საერთაშორისო </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 123</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 90</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_05.HP.err b/contrib/libxo/tests/core/saved/test_05.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.HP.err diff --git a/contrib/libxo/tests/core/saved/test_05.HP.out b/contrib/libxo/tests/core/saved/test_05.HP.out new file mode 100644 index 0000000..1c34b95 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.HP.out @@ -0,0 +1,77 @@ +<div class="line"> + <div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div> + <div class="data" data-tag="v1">γιγνώσκειν</div> + <div class="text">, </div> + <div class="data" data-tag="v2">ὦ ἄνδρες ᾿Αθηναῖοι</div> +</div> +<div class="line"> + <div class="text">გთხოვთ </div> + <div class="data" data-tag="v1">ახლავე გაიაროთ რეგისტრაცია</div> + <div class="text"> </div> + <div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div> +</div> +<div class="line"> + <div class="title">First Name </div> + <div class="title">Last Name </div> + <div class="title">Department </div> + <div class="title">Time (%)</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Jim</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"რეგტ"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">გთხოვთ ახ </div> + <div class="data" data-tag="department"> 431</div> + <div class="data" data-tag="percent-time"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Terry</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"<one"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">Οὐχὶ ταὐτὰ παρ</div> + <div class="data" data-tag="department"> 660</div> + <div class="data" data-tag="percent-time"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Leslie</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"Les"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">Patterson </div> + <div class="data" data-tag="department"> 341</div> + <div class="data" data-tag="percent-time"> 60</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Ashley</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"Ash"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">Meter & Smith </div> + <div class="data" data-tag="department"> 1440</div> + <div class="data" data-tag="percent-time"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">0123456789</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"0123456789"</div> + <div class="text">)</div> + <div class="data" data-tag="last-name">01234567890123</div> + <div class="data" data-tag="department"> 1440</div> + <div class="data" data-tag="percent-time"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">ახლა</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"გაიარო"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">საერთაშორისო </div> + <div class="data" data-tag="department"> 123</div> + <div class="data" data-tag="percent-time"> 90</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_05.J.err b/contrib/libxo/tests/core/saved/test_05.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.J.err diff --git a/contrib/libxo/tests/core/saved/test_05.J.out b/contrib/libxo/tests/core/saved/test_05.J.out new file mode 100644 index 0000000..5155489 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.J.out @@ -0,0 +1,2 @@ +{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო", "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"benefits":"full"}]} +} diff --git a/contrib/libxo/tests/core/saved/test_05.JP.err b/contrib/libxo/tests/core/saved/test_05.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.JP.err diff --git a/contrib/libxo/tests/core/saved/test_05.JP.out b/contrib/libxo/tests/core/saved/test_05.JP.out new file mode 100644 index 0000000..7d77d70 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.JP.out @@ -0,0 +1,56 @@ +{ + "employees": { + "v1": "γιγνώσκειν", + "v2": "ὦ ἄνδρες ᾿Αθηναῖοι", + "v1": "ახლავე გაიაროთ რეგისტრაცია", + "v2": "Unicode-ის მეათე საერთაშორისო", + "employee": [ + { + "first-name": "Jim", + "nic-name": "\"რეგტ\"", + "last-name": "გთხოვთ ახ", + "department": 431, + "percent-time": 90, + "benefits": "full" + }, + { + "first-name": "Terry", + "nic-name": "\"<one\"", + "last-name": "Οὐχὶ ταὐτὰ παρίσταταί μοι Jones", + "department": 660, + "percent-time": 90, + "benefits": "full" + }, + { + "first-name": "Leslie", + "nic-name": "\"Les\"", + "last-name": "Patterson", + "department": 341, + "percent-time": 60, + "benefits": "full" + }, + { + "first-name": "Ashley", + "nic-name": "\"Ash\"", + "last-name": "Meter & Smith", + "department": 1440, + "percent-time": 40 + }, + { + "first-name": "0123456789", + "nic-name": "\"0123456789\"", + "last-name": "012345678901234567890", + "department": 1440, + "percent-time": 40 + }, + { + "first-name": "ახლა", + "nic-name": "\"გაიარო\"", + "last-name": "საერთაშორისო", + "department": 123, + "percent-time": 90, + "benefits": "full" + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_05.T.err b/contrib/libxo/tests/core/saved/test_05.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.T.err diff --git a/contrib/libxo/tests/core/saved/test_05.T.out b/contrib/libxo/tests/core/saved/test_05.T.out new file mode 100644 index 0000000..c709f6c --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.T.out @@ -0,0 +1,9 @@ +Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι +გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო +First Name Last Name Department Time (%) +Jim ("რეგტ") გთხოვთ ახ 431 90 +Terry ("<one") Οὐχὶ ταὐτὰ παρ 660 90 +Leslie ("Les") Patterson 341 60 +Ashley ("Ash") Meter & Smith 1440 40 +0123456789 ("0123456789")01234567890123 1440 40 +ახლა ("გაიარო") საერთაშორისო 123 90 diff --git a/contrib/libxo/tests/core/saved/test_05.X.err b/contrib/libxo/tests/core/saved/test_05.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.X.err diff --git a/contrib/libxo/tests/core/saved/test_05.X.out b/contrib/libxo/tests/core/saved/test_05.X.out new file mode 100644 index 0000000..85ecbbc --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.X.out @@ -0,0 +1 @@ +<employees><v1>γιγνώσκειν</v1><v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2><v1>ახლავე გაიაროთ რეგისტრაცია</v1><v2>Unicode-ის მეათე საერთაშორისო</v2><employee><first-name>Jim</first-name><nic-name>"რეგტ"</nic-name><last-name>გთხოვთ ახ</last-name><department>431</department><percent-time>90</percent-time><benefits full-time="honest & for true">full</benefits></employee><employee><first-name>Terry</first-name><nic-name>"<one"</nic-name><last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name><department>660</department><percent-time>90</percent-time><benefits full-time="honest & for true">full</benefits></employee><employee><first-name>Leslie</first-name><nic-name>"Les"</nic-name><last-name>Patterson</last-name><department>341</department><percent-time>60</percent-time><benefits full-time="honest & for true">full</benefits></employee><employee><first-name>Ashley</first-name><nic-name>"Ash"</nic-name><last-name>Meter & Smith</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>0123456789</first-name><nic-name>"0123456789"</nic-name><last-name>012345678901234567890</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>ახლა</first-name><nic-name>"გაიარო"</nic-name><last-name>საერთაშორისო</last-name><department>123</department><percent-time>90</percent-time><benefits full-time="honest & for true">full</benefits></employee></employees>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_05.XP.err b/contrib/libxo/tests/core/saved/test_05.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.XP.err diff --git a/contrib/libxo/tests/core/saved/test_05.XP.out b/contrib/libxo/tests/core/saved/test_05.XP.out new file mode 100644 index 0000000..55507eb --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_05.XP.out @@ -0,0 +1,52 @@ +<employees> + <v1>γιγνώσκειν</v1> + <v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2> + <v1>ახლავე გაიაროთ რეგისტრაცია</v1> + <v2>Unicode-ის მეათე საერთაშორისო</v2> + <employee> + <first-name>Jim</first-name> + <nic-name>"რეგტ"</nic-name> + <last-name>გთხოვთ ახ</last-name> + <department>431</department> + <percent-time>90</percent-time> + <benefits full-time="honest & for true">full</benefits> + </employee> + <employee> + <first-name>Terry</first-name> + <nic-name>"<one"</nic-name> + <last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name> + <department>660</department> + <percent-time>90</percent-time> + <benefits full-time="honest & for true">full</benefits> + </employee> + <employee> + <first-name>Leslie</first-name> + <nic-name>"Les"</nic-name> + <last-name>Patterson</last-name> + <department>341</department> + <percent-time>60</percent-time> + <benefits full-time="honest & for true">full</benefits> + </employee> + <employee> + <first-name>Ashley</first-name> + <nic-name>"Ash"</nic-name> + <last-name>Meter & Smith</last-name> + <department>1440</department> + <percent-time>40</percent-time> + </employee> + <employee> + <first-name>0123456789</first-name> + <nic-name>"0123456789"</nic-name> + <last-name>012345678901234567890</last-name> + <department>1440</department> + <percent-time>40</percent-time> + </employee> + <employee> + <first-name>ახლა</first-name> + <nic-name>"გაიარო"</nic-name> + <last-name>საერთაშორისო</last-name> + <department>123</department> + <percent-time>90</percent-time> + <benefits full-time="honest & for true">full</benefits> + </employee> +</employees> diff --git a/contrib/libxo/tests/core/saved/test_06.H.err b/contrib/libxo/tests/core/saved/test_06.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.H.err diff --git a/contrib/libxo/tests/core/saved/test_06.H.out b/contrib/libxo/tests/core/saved/test_06.H.out new file mode 100644 index 0000000..6b9ccc4 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.H.out @@ -0,0 +1 @@ +<div class="line"><div class="data" data-tag="first-name">Terry</div><div class="text"> </div><div class="data" data-tag="last-name">Jones</div><div class="text"> works in dept #</div><div class="data" data-tag="department">660</div></div><div class="line"><div class="data" data-tag="first-name">Leslie</div><div class="text"> </div><div class="data" data-tag="last-name">Patterson</div><div class="text"> works in dept #</div><div class="data" data-tag="department">341</div></div><div class="line"><div class="data" data-tag="first-name">Ashley</div><div class="text"> </div><div class="data" data-tag="last-name">Smith</div><div class="text"> works in dept #</div><div class="data" data-tag="department">1440</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_06.HIPx.err b/contrib/libxo/tests/core/saved/test_06.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_06.HIPx.out b/contrib/libxo/tests/core/saved/test_06.HIPx.out new file mode 100644 index 0000000..bfae221 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.HIPx.out @@ -0,0 +1,21 @@ +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Terry</div> + <div class="text"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Jones</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department">660</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Leslie</div> + <div class="text"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Patterson</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department">341</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Ashley</div> + <div class="text"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Smith</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department">1440</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_06.HP.err b/contrib/libxo/tests/core/saved/test_06.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.HP.err diff --git a/contrib/libxo/tests/core/saved/test_06.HP.out b/contrib/libxo/tests/core/saved/test_06.HP.out new file mode 100644 index 0000000..f8b072a --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.HP.out @@ -0,0 +1,21 @@ +<div class="line"> + <div class="data" data-tag="first-name">Terry</div> + <div class="text"> </div> + <div class="data" data-tag="last-name">Jones</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department">660</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Leslie</div> + <div class="text"> </div> + <div class="data" data-tag="last-name">Patterson</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department">341</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Ashley</div> + <div class="text"> </div> + <div class="data" data-tag="last-name">Smith</div> + <div class="text"> works in dept #</div> + <div class="data" data-tag="department">1440</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_06.J.err b/contrib/libxo/tests/core/saved/test_06.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.J.err diff --git a/contrib/libxo/tests/core/saved/test_06.J.out b/contrib/libxo/tests/core/saved/test_06.J.out new file mode 100644 index 0000000..4ba1fb1 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.J.out @@ -0,0 +1,2 @@ +{"employees": {"employee": [{"first-name":"Terry","last-name":"Jones","department":660}, {"first-name":"Leslie","last-name":"Patterson","department":341}, {"first-name":"Ashley","last-name":"Smith","department":1440}]} +} diff --git a/contrib/libxo/tests/core/saved/test_06.JP.err b/contrib/libxo/tests/core/saved/test_06.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.JP.err diff --git a/contrib/libxo/tests/core/saved/test_06.JP.out b/contrib/libxo/tests/core/saved/test_06.JP.out new file mode 100644 index 0000000..ff2d5b0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.JP.out @@ -0,0 +1,21 @@ +{ + "employees": { + "employee": [ + { + "first-name": "Terry", + "last-name": "Jones", + "department": 660 + }, + { + "first-name": "Leslie", + "last-name": "Patterson", + "department": 341 + }, + { + "first-name": "Ashley", + "last-name": "Smith", + "department": 1440 + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_06.T.err b/contrib/libxo/tests/core/saved/test_06.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.T.err diff --git a/contrib/libxo/tests/core/saved/test_06.T.out b/contrib/libxo/tests/core/saved/test_06.T.out new file mode 100644 index 0000000..da60fb7 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.T.out @@ -0,0 +1,3 @@ +Terry Jones works in dept #660 +Leslie Patterson works in dept #341 +Ashley Smith works in dept #1440 diff --git a/contrib/libxo/tests/core/saved/test_06.X.err b/contrib/libxo/tests/core/saved/test_06.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.X.err diff --git a/contrib/libxo/tests/core/saved/test_06.X.out b/contrib/libxo/tests/core/saved/test_06.X.out new file mode 100644 index 0000000..a626fb6 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.X.out @@ -0,0 +1 @@ +<employees><employee><first-name>Terry</first-name><last-name>Jones</last-name><department>660</department></employee><employee><first-name>Leslie</first-name><last-name>Patterson</last-name><department>341</department></employee><employee><first-name>Ashley</first-name><last-name>Smith</last-name><department>1440</department></employee></employees>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_06.XP.err b/contrib/libxo/tests/core/saved/test_06.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.XP.err diff --git a/contrib/libxo/tests/core/saved/test_06.XP.out b/contrib/libxo/tests/core/saved/test_06.XP.out new file mode 100644 index 0000000..b6e7641 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_06.XP.out @@ -0,0 +1,17 @@ +<employees> + <employee> + <first-name>Terry</first-name> + <last-name>Jones</last-name> + <department>660</department> + </employee> + <employee> + <first-name>Leslie</first-name> + <last-name>Patterson</last-name> + <department>341</department> + </employee> + <employee> + <first-name>Ashley</first-name> + <last-name>Smith</last-name> + <department>1440</department> + </employee> +</employees> diff --git a/contrib/libxo/tests/core/saved/test_07.H.err b/contrib/libxo/tests/core/saved/test_07.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.H.err diff --git a/contrib/libxo/tests/core/saved/test_07.H.out b/contrib/libxo/tests/core/saved/test_07.H.out new file mode 100644 index 0000000..9fd042b --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.H.out @@ -0,0 +1 @@ +<div class="line"><div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div><div class="data" data-tag="v1">γιγνώσκειν</div><div class="text">, </div><div class="data" data-tag="v2">ὦ ἄνδρες ᾿Αθηναῖοι</div></div><div class="line"><div class="data" data-tag="columns">56</div></div><div class="line"><div class="data" data-tag="columns">2</div></div><div class="line"><div class="text">გთხოვთ </div><div class="data" data-tag="v1">ახლავე გაიაროთ რეგისტრაცია</div><div class="text"> </div><div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div></div><div class="line"><div class="data" data-tag="columns">63</div></div><div class="line"><div class="title">First Name </div><div class="title">Last Name </div><div class="title">Department </div><div class="title">Time (%)</div></div><div class="line"><div class="data" data-tag="columns">59</div></div><div class="line"><div class="data" data-tag="first-name">Jim</div><div class="text"> (</div><div class="data" data-tag="nic-name">"რეგტ"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">გთხოვთ ახ </div><div class="data" data-tag="department"> 431</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="columns">55</div></div><div class="line"><div class="data" data-tag="first-name">Terry</div><div class="text"> (</div><div class="data" data-tag="nic-name">"<one"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Οὐχὶ ταὐτὰ παρ</div><div class="data" data-tag="department"> 660</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="columns">55</div></div><div class="line"><div class="data" data-tag="first-name">Leslie</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Les"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Patterson </div><div class="data" data-tag="department"> 341</div><div class="data" data-tag="percent-time"> 60</div></div><div class="line"><div class="data" data-tag="columns">55</div></div><div class="line"><div class="data" data-tag="first-name">Ashley</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Ash"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Meter & Smith </div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="columns">55</div></div><div class="line"><div class="data" data-tag="first-name">0123456789</div><div class="text"> (</div><div class="data" data-tag="nic-name">"0123456789"</div><div class="text">)</div><div class="data" data-tag="last-name">01234567890123</div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="columns">55</div></div><div class="line"><div class="data" data-tag="first-name">ახლა</div><div class="text"> (</div><div class="data" data-tag="nic-name">"გაიარო"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">საერთაშორისო </div><div class="data" data-tag="department"> 123</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="columns">55</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_07.HIPx.err b/contrib/libxo/tests/core/saved/test_07.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.HIPx.err diff --git a/contrib/libxo/tests/core/saved/test_07.HIPx.out b/contrib/libxo/tests/core/saved/test_07.HIPx.out new file mode 100644 index 0000000..197c475 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.HIPx.out @@ -0,0 +1,107 @@ +<div class="line"> + <div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div> + <div class="data" data-tag="v1" data-xpath="/employees/v1">γιγνώσκειν</div> + <div class="text">, </div> + <div class="data" data-tag="v2" data-xpath="/employees/v2">ὦ ἄνδρες ᾿Αθηναῖοι</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/columns">56</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/columns">2</div> +</div> +<div class="line"> + <div class="text">გთხოვთ </div> + <div class="data" data-tag="v1" data-xpath="/employees/v1">ახლავე გაიაროთ რეგისტრაცია</div> + <div class="text"> </div> + <div class="data" data-tag="v2" data-xpath="/employees/v2">Unicode-ის მეათე საერთაშორისო</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/columns">63</div> +</div> +<div class="line"> + <div class="title">First Name </div> + <div class="title">Last Name </div> + <div class="title">Department </div> + <div class="title">Time (%)</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/columns">59</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Jim</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"რეგტ"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">გთხოვთ ახ </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 431</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/employee/columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Terry</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"<one"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Οὐχὶ ταὐτὰ παρ</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 660</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/employee/columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Leslie</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"Les"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Patterson </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 341</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 60</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/employee/columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">Ashley</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"Ash"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">Meter & Smith </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 1440</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/employee/columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">0123456789</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"0123456789"</div> + <div class="text">)</div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">01234567890123</div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 1440</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/employee/columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">ახლა</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"გაიარო"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">საერთაშორისო </div> + <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 123</div> + <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full & part time (%)"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="columns" data-xpath="/employees/employee/columns">55</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_07.HP.err b/contrib/libxo/tests/core/saved/test_07.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.HP.err diff --git a/contrib/libxo/tests/core/saved/test_07.HP.out b/contrib/libxo/tests/core/saved/test_07.HP.out new file mode 100644 index 0000000..a5ce61d --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.HP.out @@ -0,0 +1,107 @@ +<div class="line"> + <div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div> + <div class="data" data-tag="v1">γιγνώσκειν</div> + <div class="text">, </div> + <div class="data" data-tag="v2">ὦ ἄνδρες ᾿Αθηναῖοι</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">56</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">2</div> +</div> +<div class="line"> + <div class="text">გთხოვთ </div> + <div class="data" data-tag="v1">ახლავე გაიაროთ რეგისტრაცია</div> + <div class="text"> </div> + <div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">63</div> +</div> +<div class="line"> + <div class="title">First Name </div> + <div class="title">Last Name </div> + <div class="title">Department </div> + <div class="title">Time (%)</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">59</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Jim</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"რეგტ"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">გთხოვთ ახ </div> + <div class="data" data-tag="department"> 431</div> + <div class="data" data-tag="percent-time"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Terry</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"<one"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">Οὐχὶ ταὐτὰ παρ</div> + <div class="data" data-tag="department"> 660</div> + <div class="data" data-tag="percent-time"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Leslie</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"Les"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">Patterson </div> + <div class="data" data-tag="department"> 341</div> + <div class="data" data-tag="percent-time"> 60</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">Ashley</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"Ash"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">Meter & Smith </div> + <div class="data" data-tag="department"> 1440</div> + <div class="data" data-tag="percent-time"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">0123456789</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"0123456789"</div> + <div class="text">)</div> + <div class="data" data-tag="last-name">01234567890123</div> + <div class="data" data-tag="department"> 1440</div> + <div class="data" data-tag="percent-time"> 40</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">55</div> +</div> +<div class="line"> + <div class="data" data-tag="first-name">ახლა</div> + <div class="text"> (</div> + <div class="data" data-tag="nic-name">"გაიარო"</div> + <div class="text">)</div> + <div class="padding"> </div> + <div class="data" data-tag="last-name">საერთაშორისო </div> + <div class="data" data-tag="department"> 123</div> + <div class="data" data-tag="percent-time"> 90</div> +</div> +<div class="line"> + <div class="data" data-tag="columns">55</div> +</div> diff --git a/contrib/libxo/tests/core/saved/test_07.J.err b/contrib/libxo/tests/core/saved/test_07.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.J.err diff --git a/contrib/libxo/tests/core/saved/test_07.J.out b/contrib/libxo/tests/core/saved/test_07.J.out new file mode 100644 index 0000000..2c9a928 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.J.out @@ -0,0 +1,2 @@ +{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","columns":28,"columns":2,"v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","columns":55, "employee": ["columns":0, {"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"columns":23,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"columns":47,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"columns":25,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40,"columns":30}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40,"columns":49}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"columns":29,"benefits":"full"}]} +} diff --git a/contrib/libxo/tests/core/saved/test_07.JP.err b/contrib/libxo/tests/core/saved/test_07.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.JP.err diff --git a/contrib/libxo/tests/core/saved/test_07.JP.out b/contrib/libxo/tests/core/saved/test_07.JP.out new file mode 100644 index 0000000..f22b9e5 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.JP.out @@ -0,0 +1,66 @@ +{ + "employees": { + "v1": "γιγνώσκειν", + "v2": "ὦ ἄνδρες ᾿Αθηναῖοι", + "columns": 28, + "columns": 2, + "v1": "ახლავე გაიაროთ რეგისტრაცია", + "v2": "Unicode-ის მეათე საერთაშორისო", + "columns": 55, + "employee": [ + "columns": 0, + { + "first-name": "Jim", + "nic-name": "\"რეგტ\"", + "last-name": "გთხოვთ ახ", + "department": 431, + "percent-time": 90, + "columns": 23, + "benefits": "full" + }, + { + "first-name": "Terry", + "nic-name": "\"<one\"", + "last-name": "Οὐχὶ ταὐτὰ παρίσταταί μοι Jones", + "department": 660, + "percent-time": 90, + "columns": 47, + "benefits": "full" + }, + { + "first-name": "Leslie", + "nic-name": "\"Les\"", + "last-name": "Patterson", + "department": 341, + "percent-time": 60, + "columns": 25, + "benefits": "full" + }, + { + "first-name": "Ashley", + "nic-name": "\"Ash\"", + "last-name": "Meter & Smith", + "department": 1440, + "percent-time": 40, + "columns": 30 + }, + { + "first-name": "0123456789", + "nic-name": "\"0123456789\"", + "last-name": "012345678901234567890", + "department": 1440, + "percent-time": 40, + "columns": 49 + }, + { + "first-name": "ახლა", + "nic-name": "\"გაიარო\"", + "last-name": "საერთაშორისო", + "department": 123, + "percent-time": 90, + "columns": 29, + "benefits": "full" + } + ] + } +} diff --git a/contrib/libxo/tests/core/saved/test_07.T.err b/contrib/libxo/tests/core/saved/test_07.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.T.err diff --git a/contrib/libxo/tests/core/saved/test_07.T.out b/contrib/libxo/tests/core/saved/test_07.T.out new file mode 100644 index 0000000..5f4ff5c --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.T.out @@ -0,0 +1,19 @@ +Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι +56 +2 +გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო +63 +First Name Last Name Department Time (%) +59 +Jim ("რეგტ") გთხოვთ ახ 431 90 +55 +Terry ("<one") Οὐχὶ ταὐτὰ παρ 660 90 +55 +Leslie ("Les") Patterson 341 60 +55 +Ashley ("Ash") Meter & Smith 1440 40 +55 +0123456789 ("0123456789")01234567890123 1440 40 +55 +ახლა ("გაიარო") საერთაშორისო 123 90 +55 diff --git a/contrib/libxo/tests/core/saved/test_07.X.err b/contrib/libxo/tests/core/saved/test_07.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.X.err diff --git a/contrib/libxo/tests/core/saved/test_07.X.out b/contrib/libxo/tests/core/saved/test_07.X.out new file mode 100644 index 0000000..e5b70e0 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.X.out @@ -0,0 +1 @@ +<employees><v1>γιγνώσκειν</v1><v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2><columns>28</columns><columns>2</columns><v1>ახლავე გაიაროთ რეგისტრაცია</v1><v2>Unicode-ის მეათე საერთაშორისო</v2><columns>55</columns><columns>0</columns><employee><first-name>Jim</first-name><nic-name>"რეგტ"</nic-name><last-name>გთხოვთ ახ</last-name><department>431</department><percent-time>90</percent-time><columns>23</columns><benefits full-time="honest & for true">full</benefits></employee><employee><first-name>Terry</first-name><nic-name>"<one"</nic-name><last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name><department>660</department><percent-time>90</percent-time><columns>47</columns><benefits full-time="honest & for true">full</benefits></employee><employee><first-name>Leslie</first-name><nic-name>"Les"</nic-name><last-name>Patterson</last-name><department>341</department><percent-time>60</percent-time><columns>25</columns><benefits full-time="honest & for true">full</benefits></employee><employee><first-name>Ashley</first-name><nic-name>"Ash"</nic-name><last-name>Meter & Smith</last-name><department>1440</department><percent-time>40</percent-time><columns>30</columns></employee><employee><first-name>0123456789</first-name><nic-name>"0123456789"</nic-name><last-name>012345678901234567890</last-name><department>1440</department><percent-time>40</percent-time><columns>49</columns></employee><employee><first-name>ახლა</first-name><nic-name>"გაიარო"</nic-name><last-name>საერთაშორისო</last-name><department>123</department><percent-time>90</percent-time><columns>29</columns><benefits full-time="honest & for true">full</benefits></employee></employees>
\ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_07.XP.err b/contrib/libxo/tests/core/saved/test_07.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.XP.err diff --git a/contrib/libxo/tests/core/saved/test_07.XP.out b/contrib/libxo/tests/core/saved/test_07.XP.out new file mode 100644 index 0000000..b502650 --- /dev/null +++ b/contrib/libxo/tests/core/saved/test_07.XP.out @@ -0,0 +1,62 @@ +<employees> + <v1>γιγνώσκειν</v1> + <v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2> + <columns>28</columns> + <columns>2</columns> + <v1>ახლავე გაიაროთ რეგისტრაცია</v1> + <v2>Unicode-ის მეათე საერთაშორისო</v2> + <columns>55</columns> + <columns>0</columns> + <employee> + <first-name>Jim</first-name> + <nic-name>"რეგტ"</nic-name> + <last-name>გთხოვთ ახ</last-name> + <department>431</department> + <percent-time>90</percent-time> + <columns>23</columns> + <benefits full-time="honest & for true">full</benefits> + </employee> + <employee> + <first-name>Terry</first-name> + <nic-name>"<one"</nic-name> + <last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name> + <department>660</department> + <percent-time>90</percent-time> + <columns>47</columns> + <benefits full-time="honest & for true">full</benefits> + </employee> + <employee> + <first-name>Leslie</first-name> + <nic-name>"Les"</nic-name> + <last-name>Patterson</last-name> + <department>341</department> + <percent-time>60</percent-time> + <columns>25</columns> + <benefits full-time="honest & for true">full</benefits> + </employee> + <employee> + <first-name>Ashley</first-name> + <nic-name>"Ash"</nic-name> + <last-name>Meter & Smith</last-name> + <department>1440</department> + <percent-time>40</percent-time> + <columns>30</columns> + </employee> + <employee> + <first-name>0123456789</first-name> + <nic-name>"0123456789"</nic-name> + <last-name>012345678901234567890</last-name> + <department>1440</department> + <percent-time>40</percent-time> + <columns>49</columns> + </employee> + <employee> + <first-name>ახლა</first-name> + <nic-name>"გაიარო"</nic-name> + <last-name>საერთაშორისო</last-name> + <department>123</department> + <percent-time>90</percent-time> + <columns>29</columns> + <benefits full-time="honest & for true">full</benefits> + </employee> +</employees> diff --git a/contrib/libxo/tests/core/test_01.c b/contrib/libxo/tests/core/test_01.c new file mode 100644 index 0000000..164a38b --- /dev/null +++ b/contrib/libxo/tests/core/test_01.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xo.h" + +int +main (int argc, char **argv) +{ + static char base_grocery[] = "GRO"; + static char base_hardware[] = "HRD"; + struct item { + const char *i_title; + int i_sold; + int i_instock; + int i_onorder; + const char *i_sku_base; + int i_sku_num; + }; + struct item list[] = { + { "gum", 1412, 54, 10, base_grocery, 415 }, + { "rope", 85, 4, 2, base_hardware, 212 }, + { "ladder", 0, 2, 1, base_hardware, 517 }, + { "bolt", 4123, 144, 42, base_hardware, 632 }, + { "water", 17, 14, 2, base_grocery, 2331 }, + { NULL, 0, 0, 0, NULL, 0 } + }; + struct item list2[] = { + { "fish", 1321, 45, 1, base_grocery, 533 }, + { NULL, 0, 0, 0, NULL, 0 } + }; + struct item *ip; + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + { NULL, NULL, NULL }, + }; + int info_count = (sizeof(info) / sizeof(info[0])) - 1; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + for (argc = 1; argv[argc]; argc++) { + if (strcmp(argv[argc], "xml") == 0) + xo_set_style(NULL, XO_STYLE_XML); + else if (strcmp(argv[argc], "json") == 0) + xo_set_style(NULL, XO_STYLE_JSON); + else if (strcmp(argv[argc], "text") == 0) + xo_set_style(NULL, XO_STYLE_TEXT); + else if (strcmp(argv[argc], "html") == 0) + xo_set_style(NULL, XO_STYLE_HTML); + else if (strcmp(argv[argc], "pretty") == 0) + xo_set_flags(NULL, XOF_PRETTY); + else if (strcmp(argv[argc], "xpath") == 0) + xo_set_flags(NULL, XOF_XPATH); + else if (strcmp(argv[argc], "info") == 0) + xo_set_flags(NULL, XOF_INFO); + } + + xo_set_info(NULL, info, info_count); + xo_set_flags(NULL, XOF_KEYS); + + xo_open_container_h(NULL, "top"); + + xo_open_container("data"); + xo_open_list("item"); + + xo_emit("{T:Item/%-10s}{T:Total Sold/%12s}{T:In Stock/%12s}" + "{T:On Order/%12s}{T:SKU/%5s}\n"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{keq:sku/%s-%u/%s-000-%u}" + "{k:name/%-10s/%s}{n:sold/%12u/%u}{:in-stock/%12u/%u}" + "{:on-order/%12u/%u}{qkd:sku/%5s-000-%u/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num, + ip->i_title, ip->i_sold, ip->i_instock, ip->i_onorder, + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_emit("\n\n"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); + xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); + xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); + xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list2; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num); + xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock); + xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder); + xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_close_container_h(NULL, "top"); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/core/test_02.c b/contrib/libxo/tests/core/test_02.c new file mode 100644 index 0000000..abcb14b --- /dev/null +++ b/contrib/libxo/tests/core/test_02.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include "xo.h" + +int +main (int argc, char **argv) +{ + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + for (argc = 1; argv[argc]; argc++) { + if (strcmp(argv[argc], "xml") == 0) + xo_set_style(NULL, XO_STYLE_XML); + else if (strcmp(argv[argc], "json") == 0) + xo_set_style(NULL, XO_STYLE_JSON); + else if (strcmp(argv[argc], "text") == 0) + xo_set_style(NULL, XO_STYLE_TEXT); + else if (strcmp(argv[argc], "html") == 0) + xo_set_style(NULL, XO_STYLE_HTML); + else if (strcmp(argv[argc], "pretty") == 0) + xo_set_flags(NULL, XOF_PRETTY); + else if (strcmp(argv[argc], "xpath") == 0) + xo_set_flags(NULL, XOF_XPATH); + else if (strcmp(argv[argc], "info") == 0) + xo_set_flags(NULL, XOF_INFO); + } + + xo_set_flags(NULL, XOF_UNITS); /* Always test w/ this */ + + xo_open_container_h(NULL, "top"); + + xo_open_container("data"); + + xo_emit("{:mbuf-current/%u}/{:mbuf-cache/%u}/{:mbuf-total/%u} " + "{N:mbufs <&> in use (current\\/cache\\/total)}\n", + 10, 20, 30); + + xo_emit("{:distance/%u}{Uw:miles} from {:location}\n", 50, "Boston"); + xo_emit("{:memory/%u}{U:k} left out of {:total/%u}{U:kb}\n", 64, 640); + xo_emit("{:memory/%u}{U:/%s} left out of {:total/%u}{U:/%s}\n", + 64, "k", 640, "kilobytes"); + + xo_emit("{T:/before%safter:}\n", "working"); + + xo_emit("{d:some/%s}{:ten/%ju}{:eleven/%ju}\n", + "string", (uintmax_t) 10, (uintmax_t) 11); + + xo_emit("{:unknown/%u} " + "{N:/packet%s here\\/there\\/everywhere}\n", + 1010, "s"); + + xo_emit("({[:/%d}{n:min/15}/{n:cur/20}/{:max/%d}{]:})\n", 30, 125); + xo_emit("({[:30}{:min/%u}/{:cur/%u}/{:max/%u}{]:})\n", 15, 20, 125); + xo_emit("({[:-30}{n:min/15}/{n:cur/20}/{n:max/125}{]:})\n"); + xo_emit("({[:}{:min/%u}/{:cur/%u}/{:max/%u}{]:/%d})\n", 15, 20, 125, -30); + + xo_open_list("flag"); + xo_emit("{lq:flag/one} {lq:flag/two} {lq:flag/three}\n"); + xo_close_list("flag"); + + xo_emit("{e:empty-tag/}"); + xo_emit("1:{qt:t1/%*d} 2:{qt:t2/test%-*u} 3:{qt:t3/%10sx} 4:{qt:t4/x%-*.*s}\n", + 6, 1000, 8, 5000, "ten-long", 10, 10, "test"); + xo_emit("{E:this is an error}\n"); + xo_emit("{E:/%s more error%s}\n", "two", "s" ); + xo_emit("{W:this is an warning}\n"); + xo_emit("{W:/%s more warning%s}\n", "two", "s" ); + xo_emit("{L:/V1\\/V2 packet%s}: {:count/%u}\n", "s", 10); + + int test = 4; + xo_emit("{:test/%04d} {L:/tr%s}\n", test, (test == 1) ? "y" : "ies"); + + xo_message("improper use of profanity; %s; %s", + "ten yard penalty", "first down"); + + xo_error("Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"); + + xo_close_container("data"); + + xo_close_container_h(NULL, "top"); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/core/test_03.c b/contrib/libxo/tests/core/test_03.c new file mode 100644 index 0000000..0ab9699 --- /dev/null +++ b/contrib/libxo/tests/core/test_03.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xo.h" + +xo_info_t info[] = { + { "employee", "object", "Employee data" }, + { "first-name", "string", "First name of employee" }, + { "last-name", "string", "Last name of employee" }, + { "department", "number", "Department number" }, +}; +int info_count = (sizeof(info) / sizeof(info[0])); + +int +main (int argc, char **argv) +{ + struct employee { + const char *e_first; + const char *e_last; + unsigned e_dept; + } employees[] = { + { "Terry", "Jones", 660 }, + { "Leslie", "Patterson", 341 }, + { "Ashley", "Smith", 1440 }, + { NULL, NULL } + }, *ep = employees; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + xo_set_info(NULL, info, info_count); + + xo_open_container("employees"); + xo_open_list("employee"); + + for ( ; ep->e_first; ep++) { + xo_open_instance("employee"); + xo_emit("{:first-name} {:last-name} works in dept #{:department/%u}\n", + ep->e_first, ep->e_last, ep->e_dept); + xo_close_instance("employee"); + } + + xo_close_list("employee"); + xo_close_container("employees"); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/core/test_04.c b/contrib/libxo/tests/core/test_04.c new file mode 100644 index 0000000..5e25302 --- /dev/null +++ b/contrib/libxo/tests/core/test_04.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xo.h" + +xo_info_t info[] = { + { "employee", "object", "Employee data" }, + { "first-name", "string", "First name of employee" }, + { "last-name", "string", "Last name of employee" }, + { "department", "number", "Department number" }, +}; +int info_count = (sizeof(info) / sizeof(info[0])); + +int +main (int argc, char **argv) +{ + struct employee { + const char *e_first; + const char *e_last; + unsigned e_dept; + } employees[] = { + { "Terry", "Jones", 660 }, + { "Leslie", "Patterson", 341 }, + { "Ashley", "Smith", 1440 }, + { NULL, NULL } + }, *ep = employees; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + xo_set_info(NULL, info, info_count); + + xo_open_container("employees"); + xo_open_list("employee"); + + xo_emit("{T:Last Name/%-12s}{T:First Name/%-14s}{T:Department/%s}\n"); + for ( ; ep->e_first; ep++) { + xo_open_instance("employee"); + xo_emit("{:first-name/%-12s/%s}{:last-name/%-14s/%s}" + "{:department/%8u/%u}\n", + ep->e_first, ep->e_last, ep->e_dept); + xo_close_instance("employee"); + } + + xo_close_list("employee"); + xo_close_container("employees"); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/core/test_05.c b/contrib/libxo/tests/core/test_05.c new file mode 100644 index 0000000..61241b8 --- /dev/null +++ b/contrib/libxo/tests/core/test_05.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xo.h" + +xo_info_t info[] = { + { "employee", "object", "Employee data" }, + { "first-name", "string", "First name of employee" }, + { "last-name", "string", "Last name of employee" }, + { "department", "number", "Department number" }, + { "percent-time", "number", "Percentage of full & part time (%)" }, +}; +int info_count = (sizeof(info) / sizeof(info[0])); + +int +main (int argc, char **argv) +{ + struct employee { + const char *e_first; + const char *e_nic; + const char *e_last; + unsigned e_dept; + unsigned e_percent; + } employees[] = { + { "Jim", "რეგტ", "გთხოვთ ახ", 431, 90 }, + { "Terry", "<one", "Οὐχὶ ταὐτὰ παρίσταταί μοι Jones", 660, 90 }, + { "Leslie", "Les", "Patterson", 341,60 }, + { "Ashley", "Ash", "Meter & Smith", 1440, 40 }, + { "0123456789", "0123456789", "012345678901234567890", 1440, 40 }, + { "ახლა", "გაიარო", "საერთაშორისო", 123, 90 }, + { NULL, NULL } + }, *ep = employees; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + xo_set_info(NULL, info, info_count); + + xo_open_container("employees"); + + xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", + "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); + + xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n", + "ახლავე გაიაროთ რეგისტრაცია", + "Unicode-ის მეათე საერთაშორისო"); + + xo_open_list("employee"); + + xo_emit("{T:First Name/%-25s}{T:Last Name/%-14s}" + "{T:/%-12s}{T:Time (%)}\n", "Department"); + for ( ; ep->e_first; ep++) { + xo_open_instance("employee"); + xo_emit("{[:-25}{:first-name/%s} ({:nic-name/\"%s\"}){]:}" + "{:last-name/%-14..14s/%s}" + "{:department/%8u/%u}{:percent-time/%8u/%u}\n", + ep->e_first, ep->e_nic, ep->e_last, ep->e_dept, ep->e_percent); + if (ep->e_percent > 50) { + xo_attr("full-time", "%s", "honest & for true"); + xo_emit("{e:benefits/%s}", "full"); + } + xo_close_instance("employee"); + } + + xo_close_list("employee"); + xo_close_container("employees"); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/core/test_06.c b/contrib/libxo/tests/core/test_06.c new file mode 100644 index 0000000..82baab8 --- /dev/null +++ b/contrib/libxo/tests/core/test_06.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xo.h" + +xo_info_t info[] = { + { "employee", "object", "Employee data" }, + { "first-name", "string", "First name of employee" }, + { "last-name", "string", "Last name of employee" }, + { "department", "number", "Department number" }, +}; +int info_count = (sizeof(info) / sizeof(info[0])); + +int +main (int argc, char **argv) +{ + struct employee { + const char *e_first; + const char *e_last; + unsigned e_dept; + } employees[] = { + { "Terry", "Jones", 660 }, + { "Leslie", "Patterson", 341 }, + { "Ashley", "Smith", 1440 }, + { NULL, NULL } + }, *ep = employees; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + xo_set_info(NULL, info, info_count); + + xo_set_flags(NULL, XOF_DTRT); + + xo_open_container("employees"); + xo_open_list("employee"); + + for ( ; ep->e_first; ep++) { + xo_open_instance("employee"); + xo_emit("{:first-name} {:last-name} works in dept #{:department/%u}\n", + ep->e_first, ep->e_last, ep->e_dept); + xo_close_instance_d(); + } + + xo_close_list_d(); + xo_close_container_d(); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/core/test_07.c b/contrib/libxo/tests/core/test_07.c new file mode 100644 index 0000000..3ceba8e --- /dev/null +++ b/contrib/libxo/tests/core/test_07.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xo.h" + +xo_info_t info[] = { + { "employee", "object", "Employee data" }, + { "first-name", "string", "First name of employee" }, + { "last-name", "string", "Last name of employee" }, + { "department", "number", "Department number" }, + { "percent-time", "number", "Percentage of full & part time (%)" }, +}; +int info_count = (sizeof(info) / sizeof(info[0])); + +int +main (int argc, char **argv) +{ + struct employee { + const char *e_first; + const char *e_nic; + const char *e_last; + unsigned e_dept; + unsigned e_percent; + } employees[] = { + { "Jim", "რეგტ", "გთხოვთ ახ", 431, 90 }, + { "Terry", "<one", "Οὐχὶ ταὐτὰ παρίσταταί μοι Jones", 660, 90 }, + { "Leslie", "Les", "Patterson", 341,60 }, + { "Ashley", "Ash", "Meter & Smith", 1440, 40 }, + { "0123456789", "0123456789", "012345678901234567890", 1440, 40 }, + { "ახლა", "გაიარო", "საერთაშორისო", 123, 90 }, + { NULL, NULL } + }, *ep = employees; + int rc; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + xo_set_info(NULL, info, info_count); + xo_set_flags(NULL, XOF_COLUMNS); + + xo_open_container("employees"); + + rc = xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", + "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); + rc = xo_emit("{:columns/%d}\n", rc); + xo_emit("{:columns/%d}\n", rc); + + rc = xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n", + "ახლავე გაიაროთ რეგისტრაცია", + "Unicode-ის მეათე საერთაშორისო"); + xo_emit("{:columns/%d}\n", rc); + + xo_open_list("employee"); + + rc = xo_emit("{T:First Name/%-25s}{T:Last Name/%-14s}" + "{T:/%-12s}{T:Time (%)}\n", "Department"); + xo_emit("{:columns/%d}\n", rc); + for ( ; ep->e_first; ep++) { + xo_open_instance("employee"); + rc = xo_emit("{[:-25}{:first-name/%s} ({:nic-name/\"%s\"}){]:}" + "{:last-name/%-14..14s/%s}" + "{:department/%8u/%u}{:percent-time/%8u/%u}\n", + ep->e_first, ep->e_nic, ep->e_last, ep->e_dept, ep->e_percent); + xo_emit("{:columns/%d}\n", rc); + if (ep->e_percent > 50) { + xo_attr("full-time", "%s", "honest & for true"); + xo_emit("{e:benefits/%s}", "full"); + } + xo_close_instance("employee"); + } + + xo_close_list("employee"); + xo_close_container("employees"); + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/tests/xo/Makefile.am b/contrib/libxo/tests/xo/Makefile.am new file mode 100644 index 0000000..1687f09 --- /dev/null +++ b/contrib/libxo/tests/xo/Makefile.am @@ -0,0 +1,90 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +AM_CFLAGS = -I${top_srcdir} -I${top_srcdir}/libxo + +# Ick: maintained by hand! +TEST_CASES = \ +xo_01.sh + +X=\ +xo_02.sh \ +xo_03.sh \ +xo_04.sh \ +xo_05.sh \ +xo_06.sh + +# TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) + +EXTRA_DIST = \ + ${TEST_CASES} \ + ${addprefix saved/, ${TEST_CASES:.sh=.T.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.T.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.XP.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.XP.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.JP.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.JP.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HP.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HP.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.X.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.X.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.J.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.J.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.H.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.H.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HIPx.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HIPx.out}} + +S2O = | ${SED} '1,/@@/d' + +all: + +#TEST_TRACE = set -x ; + +XO=../../xo/xo + +TEST_ONE = \ + LIBXO_OPTIONS=:W$$fmt \ + ${CHECKER} sh ${srcdir}/$$base.sh ${XO} ${TEST_OPTS} \ + > out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O} + +TEST_FORMATS = T XP JP HP X J H HIPx + +test tests: ${bin_PROGRAMS} + @${MKDIR} -p out + -@ ${TEST_TRACE} (for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .sh` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${TEST_ONE}; \ + true; \ + done) \ + done) + +one: + -@(test=${TEST_CASE}; data=${TEST_DATA}; ${TEST_ONE} ; true) + +accept: + -@(for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .sh` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${CP} out/$$base.$$fmt.out ${srcdir}/saved/$$base.$$fmt.out ; \ + ${CP} out/$$base.$$fmt.err ${srcdir}/saved/$$base.$$fmt.err ; \ + done) \ + done) + +CLEANFILES = +CLEANDIRS = out + +clean-local: + rm -rf ${CLEANDIRS} diff --git a/contrib/libxo/tests/xo/saved/xo_01.H.err b/contrib/libxo/tests/xo/saved/xo_01.H.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.H.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.H.out b/contrib/libxo/tests/xo/saved/xo_01.H.out new file mode 100644 index 0000000..dd82a1c --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.H.out @@ -0,0 +1 @@ +<div class="line"><div class="text">Item </div><div class="data" data-tag="name">one</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">001</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">red</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">two</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">002</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">blue</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">three</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">003</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">green</div></div><div class="line"><div class="text">Item </div><div class="data" data-tag="name">four</div><div class="text"> is </div><div class="label">number</div><div class="padding"> </div><div class="data" data-tag="value">004</div><div class="text">, </div><div class="label">color</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="color">yellow</div></div>
\ No newline at end of file diff --git a/contrib/libxo/tests/xo/saved/xo_01.HIPx.err b/contrib/libxo/tests/xo/saved/xo_01.HIPx.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.HIPx.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.HIPx.out b/contrib/libxo/tests/xo/saved/xo_01.HIPx.out new file mode 100644 index 0000000..12e36b1 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.HIPx.out @@ -0,0 +1,52 @@ +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name" data-xpath="/top/item/name">one</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value" data-xpath="/top/item[name = 'one']/value">001</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color" data-xpath="/top/item[name = 'one']/color">red</div> +</div> +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name" data-xpath="/top/item/name">two</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value" data-xpath="/top/item[name = 'two']/value">002</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color" data-xpath="/top/item[name = 'two']/color">blue</div> +</div> +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name" data-xpath="/top/item/name">three</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value" data-xpath="/top/item[name = 'three']/value">003</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color" data-xpath="/top/item[name = 'three']/color">green</div> +</div> +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name" data-xpath="/top/item/name">four</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value" data-xpath="/top/item[name = 'four']/value">004</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color" data-xpath="/top/item[name = 'four']/color">yellow</div> +</div> diff --git a/contrib/libxo/tests/xo/saved/xo_01.HP.err b/contrib/libxo/tests/xo/saved/xo_01.HP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.HP.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.HP.out b/contrib/libxo/tests/xo/saved/xo_01.HP.out new file mode 100644 index 0000000..de91936 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.HP.out @@ -0,0 +1,52 @@ +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name">one</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value">001</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color">red</div> +</div> +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name">two</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value">002</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color">blue</div> +</div> +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name">three</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value">003</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color">green</div> +</div> +<div class="line"> + <div class="text">Item </div> + <div class="data" data-tag="name">four</div> + <div class="text"> is </div> + <div class="label">number</div> + <div class="padding"> </div> + <div class="data" data-tag="value">004</div> + <div class="text">, </div> + <div class="label">color</div> + <div class="decoration">:</div> + <div class="padding"> </div> + <div class="data" data-tag="color">yellow</div> +</div> diff --git a/contrib/libxo/tests/xo/saved/xo_01.J.err b/contrib/libxo/tests/xo/saved/xo_01.J.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.J.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.J.out b/contrib/libxo/tests/xo/saved/xo_01.J.out new file mode 100644 index 0000000..86ce4ef --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.J.out @@ -0,0 +1 @@ +"top": {"item": {"name":"one","value":1,"color":"red"}, "item": {"name":"two","value":2,"color":"blue"}, "item": {"name":"three","value":3,"color":"green"}, "item": {"name":"four","value":4,"color":"yellow"}} diff --git a/contrib/libxo/tests/xo/saved/xo_01.JP.err b/contrib/libxo/tests/xo/saved/xo_01.JP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.JP.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.JP.out b/contrib/libxo/tests/xo/saved/xo_01.JP.out new file mode 100644 index 0000000..5a25b17 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.JP.out @@ -0,0 +1,22 @@ +"top": { + "item": { + "name": "one", + "value": 1, + "color": "red" + }, + "item": { + "name": "two", + "value": 2, + "color": "blue" + }, + "item": { + "name": "three", + "value": 3, + "color": "green" + }, + "item": { + "name": "four", + "value": 4, + "color": "yellow" + } +} diff --git a/contrib/libxo/tests/xo/saved/xo_01.T.err b/contrib/libxo/tests/xo/saved/xo_01.T.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.T.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.T.out b/contrib/libxo/tests/xo/saved/xo_01.T.out new file mode 100644 index 0000000..ed2ea35 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.T.out @@ -0,0 +1,4 @@ +Item one is number 001, color: red +Item two is number 002, color: blue +Item three is number 003, color: green +Item four is number 004, color: yellow diff --git a/contrib/libxo/tests/xo/saved/xo_01.X.err b/contrib/libxo/tests/xo/saved/xo_01.X.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.X.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.X.out b/contrib/libxo/tests/xo/saved/xo_01.X.out new file mode 100644 index 0000000..7539566 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.X.out @@ -0,0 +1 @@ +<top><item><name>one</name><value>1</value><color>red</color></item><item><name>two</name><value>2</value><color>blue</color></item><item><name>three</name><value>3</value><color>green</color></item><item><name>four</name><value>4</value><color>yellow</color></item></top>
\ No newline at end of file diff --git a/contrib/libxo/tests/xo/saved/xo_01.XP.err b/contrib/libxo/tests/xo/saved/xo_01.XP.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.XP.err diff --git a/contrib/libxo/tests/xo/saved/xo_01.XP.out b/contrib/libxo/tests/xo/saved/xo_01.XP.out new file mode 100644 index 0000000..7f069c8 --- /dev/null +++ b/contrib/libxo/tests/xo/saved/xo_01.XP.out @@ -0,0 +1,22 @@ +<top> + <item> + <name>one</name> + <value>1</value> + <color>red</color> + </item> + <item> + <name>two</name> + <value>2</value> + <color>blue</color> + </item> + <item> + <name>three</name> + <value>3</value> + <color>green</color> + </item> + <item> + <name>four</name> + <value>4</value> + <color>yellow</color> + </item> +</top> diff --git a/contrib/libxo/tests/xo/xo_01.sh b/contrib/libxo/tests/xo/xo_01.sh new file mode 100755 index 0000000..8de9410 --- /dev/null +++ b/contrib/libxo/tests/xo/xo_01.sh @@ -0,0 +1,27 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +XO=$1 +shift + +XOP="${XO} --warn --depth 1 --leading-xpath /top" + +${XO} --open top + +NF= +for i in one:1:red two:2:blue three:3:green four:4:yellow ; do + set `echo $i | sed 's/:/ /g'` + ${XOP} ${NF} --wrap item \ + 'Item {k:name} is {Lw:number}{:value/%03d/%d}, {Lwc:color}{:color}\n' \ + $1 $2 $3 + NF=--not-first +done + +${XO} --close top
\ No newline at end of file diff --git a/contrib/libxo/warnings.mk b/contrib/libxo/warnings.mk new file mode 100644 index 0000000..c07ac37 --- /dev/null +++ b/contrib/libxo/warnings.mk @@ -0,0 +1,57 @@ +# +# $Id$ +# +# Copyright 2011, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. +# +# Commonly used sets of warnings +# + +MIN_WARNINGS?= -W -Wall + +LOW_WARNINGS?= ${MIN_WARNINGS} \ + -Wstrict-prototypes \ + -Wmissing-prototypes \ + -Wpointer-arith + +MEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror + +HIGH_WARNINGS?= ${MEDIUM_WARNINGS} \ + -Waggregate-return \ + -Wcast-align \ + -Wcast-qual \ + -Wchar-subscripts \ + -Wcomment \ + -Wformat \ + -Wimplicit \ + -Wmissing-declarations \ + -Wnested-externs \ + -Wparentheses \ + -Wreturn-type \ + -Wshadow \ + -Wswitch \ + -Wtrigraphs \ + -Wuninitialized \ + -Wunused \ + -Wwrite-strings + +HIGHER_WARNINGS?= ${HIGH_WARNINGS} \ + -Winline \ + -Wbad-function-cast \ + -Wpacked \ + -Wpadded \ + -Wstrict-aliasing + +ifeq "${LIBXO_WARNINGS}" "HIGH" +WARNINGS += ${HIGH_WARNINGS} +else +WARNINGS += ${LOW_WARNINGS} +endif + +ifeq "${GCC_WARNINGS}" "yes" +WARNINGS += -fno-inline-functions-called-once +endif diff --git a/contrib/libxo/xo/Makefile.am b/contrib/libxo/xo/Makefile.am new file mode 100644 index 0000000..247ef3b --- /dev/null +++ b/contrib/libxo/xo/Makefile.am @@ -0,0 +1,35 @@ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +include ${top_srcdir}/warnings.mk + +AM_CFLAGS = \ + -DLIBXO_XMLSOFT_NEED_PRIVATE \ + -I${top_builddir} \ + -I${top_srcdir} \ + -I${top_srcdir}/libxo \ + ${WARNINGS} + +LIBS = \ + ${LIBXO_LIBS} + +bin_PROGRAMS = xo + +xo_SOURCES = xo.c +#xo_LDADD = ../libxo/libxo.la +#xo_LDFLAGS = -static + +LDADD = \ + ${top_builddir}/libxo/libxo.la + +man_MANS = xo.1 + +EXTRA_DIST = xo.1 diff --git a/contrib/libxo/xo/xo.1 b/contrib/libxo/xo/xo.1 new file mode 100644 index 0000000..1833b0a --- /dev/null +++ b/contrib/libxo/xo/xo.1 @@ -0,0 +1,190 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xo +.Nd emit formatted output based on format string and arguments +.Sh SYNOPSIS +.Nm xo +.Op Fl options +.Op Ar argument... +.Sh DESCRIPTION +The +.Nm xo +utility allows command line access to the functionality of +the +.Em libxo +library. Using +.Nm xo , +shell scripts can emit +.Em XML , +.Em JSON , or +.Em HTML +using the same commands that emit text output. +.Pp +.Bl -tag -width "12345678901234567" +.It Fl "-close <path>" +Close tags for the given path +.It Fl "-depth <num>" +Set the depth for pretty printing +.It Fl "-help" +Display this help text +.It Fl "-html OR -H" +Generate HTML output +.It Fl "-json OR -J" +Generate JSON output +.It Fl "-leading-xpath <path>" +Add a prefix to generated XPaths (HTML) +.It Fl "-open <path>" +Open tags for the given path +.It Fl "-pretty OR -p" +Make 'pretty' output (add indent, newlines) +.It Fl "-style <style>" +Generate given style (xml, json, text, html) +.It Fl "-text OR -T" +Generate text output (the default style) +.It Fl "-version" +Display version information +.It Fl "-warn OR -W" +Display warnings in text on stderr +.It Fl "-warn-xml" +Display warnings in xml on stdout +.It Fl "-wrap <path>" +Wrap output in a set of containers +.It Fl "-xml OR -X" +Generate XML output +.It Fl "-xpath" +Add XPath data to HTML output); +.El +.Pp +The +.Nm xo +utility accepts a format string suitable for +.Xr xo_emit 3 +and a set of zero or more arguments used to supply data for that string. +.Bd -literal -offset indent + xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6 + + TEXT: + The fish weighs 6 pounds. + XML: + <name>fish</name> + <weight>6</weight> + JSON: + "name": "fish", + "weight": 6 + HTML: + <div class="line"> + <div class="text">The </div> + <div class="data" data-tag="name">fish</div> + <div class="text"> weighs </div> + <div class="data" data-tag="weight">6</div> + <div class="text"> pounds.</div> + </div> +.Ed +.Pp +The +.Fl "-wrap <path>" +option can be used to wrap emitted content in a +specific hierarchy. The path is a set of hierarchical names separated +by the '/' character. +.Bd -literal -offset indent + xo --wrap top/a/b/c '{:tag}' value + + XML: + <top> + <a> + <b> + <c> + <tag>value</tag> + </c> + </b> + </a> + </top> + JSON: + "top": { + "a": { + "b": { + "c": { + "tag": "value" + } + } + } + } +.Ed +.Pp +The +.Fl "\-open <path>" +and +.Fl "\-close <path>" +can be used to emit +hierarchical information without the matching close and open +tag. This allows a shell script to emit open tags, data, and +then close tags. The +.Fl \-depth +option may be used to set the +depth for indentation. The +.Fl "\-leading-xpath" +may be used to +prepend data to the XPath values used for HTML output style. +.Bd -literal -offset indent + #!/bin/sh + xo --open top/data + xo --depth 2 '{tag}' value + xo --close top/data + XML: + <top> + <data> + <tag>value</tag> + </data> + </top> + JSON: + "top": { + "data": { + "tag": "value" + } + } +.Ed +.Pp +.Sh EXAMPLE +.Bd -literal -offset indent + % xo 'The {:product} is {:status}\n' stereo "in route" + The stereo is in route + % xo -p -X 'The {:product} is {:status}\n' stereo "in route" + <product>stereo</product> + <status>in route</status> +.Ed +.Pp +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 11.0. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/xo/xo.c b/contrib/libxo/xo/xo.c new file mode 100644 index 0000000..698d9d6 --- /dev/null +++ b/contrib/libxo/xo/xo.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2014, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, July 2014 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +#include "xoconfig.h" +#include "xo.h" +#include "xoversion.h" + +#include <getopt.h> /* Include after xo.h for testing */ + +#ifndef UNUSED +#define UNUSED __attribute__ ((__unused__)) +#endif /* UNUSED */ + +static int opt_warn; /* Enable warnings */ + +static char **save_argv; +static char **checkpoint_argv; + +static char * +next_arg (void) +{ + char *cp = *save_argv; + + if (cp == NULL) + xo_errx(1, "missing argument"); + + save_argv += 1; + return cp; +} + +static void +prep_arg (char *fmt) +{ + char *cp, *fp; + + for (cp = fp = fmt; *cp; cp++, fp++) { + if (*cp != '\\') { + if (cp != fp) + *fp = *cp; + continue; + } + + switch (*++cp) { + case 'n': + *fp = '\n'; + break; + + case 'r': + *fp = '\r'; + break; + + case 'b': + *fp = '\b'; + break; + + case 'e': + *fp = '\e'; + break; + + default: + *fp = *cp; + } + } + + *fp = '\0'; +} + +static void +checkpoint (xo_handle_t *xop UNUSED, va_list vap UNUSED, int restore) +{ + if (restore) + save_argv = checkpoint_argv; + else + checkpoint_argv = save_argv; +} + +/* + * Our custom formatter is responsible for combining format string pieces + * with our command line arguments to build strings. This involves faking + * some printf-style logic. + */ +static int +formatter (xo_handle_t *xop, char *buf, int bufsiz, + const char *fmt, va_list vap UNUSED) +{ + int lflag = 0, hflag = 0, jflag = 0, tflag = 0, + zflag = 0, qflag = 0, star1 = 0, star2 = 0; + int rc = 0; + int w1 = 0, w2 = 0; + const char *cp; + + for (cp = fmt + 1; *cp; cp++) { + if (*cp == 'l') + lflag += 1; + else if (*cp == 'h') + hflag += 1; + else if (*cp == 'j') + jflag += 1; + else if (*cp == 't') + tflag += 1; + else if (*cp == 'z') + zflag += 1; + else if (*cp == 'q') + qflag += 1; + else if (*cp == '*') { + if (star1 == 0) + star1 = 1; + else + star2 = 1; + } else if (strchr("diouxXDOUeEfFgGaAcCsSp", *cp) != NULL) + break; + else if (*cp == 'n' || *cp == 'v') { + if (opt_warn) + xo_error_h(xop, "unsupported format: '%s'", fmt); + return -1; + } + } + + char fc = *cp; + + /* Handle "%*.*s" */ + if (star1) + w1 = strtol(next_arg(), NULL, 0); + if (star2 > 1) + w2 = strtol(next_arg(), NULL, 0); + + if (fc == 'D' || fc == 'O' || fc == 'U') + lflag = 1; + + if (strchr("diD", fc) != NULL) { + long long value = strtoll(next_arg(), NULL, 0); + if (star1 && star2) + rc = snprintf(buf, bufsiz, fmt, w1, w2, value); + else if (star1) + rc = snprintf(buf, bufsiz, fmt, w1, value); + else + rc = snprintf(buf, bufsiz, fmt, value); + + } else if (strchr("ouxXOUp", fc) != NULL) { + unsigned long long value = strtoull(next_arg(), NULL, 0); + if (star1 && star2) + rc = snprintf(buf, bufsiz, fmt, w1, w2, value); + else if (star1) + rc = snprintf(buf, bufsiz, fmt, w1, value); + else + rc = snprintf(buf, bufsiz, fmt, value); + + } else if (strchr("eEfFgGaA", fc) != NULL) { + double value = strtold(next_arg(), NULL); + if (star1 && star2) + rc = snprintf(buf, bufsiz, fmt, w1, w2, value); + else if (star1) + rc = snprintf(buf, bufsiz, fmt, w1, value); + else + rc = snprintf(buf, bufsiz, fmt, value); + + } else if (fc == 'C' || fc == 'c' || fc == 'S' || fc == 's') { + char *value = next_arg(); + if (star1 && star2) + rc = snprintf(buf, bufsiz, fmt, w1, w2, value); + else if (star1) + rc = snprintf(buf, bufsiz, fmt, w1, value); + else + rc = snprintf(buf, bufsiz, fmt, value); + } + + return rc; +} + +static void +print_version (void) +{ + fprintf(stderr, "libxo version %s%s\n", + xo_version, xo_version_extra); + fprintf(stderr, "xo version %s%s\n", + LIBXO_VERSION, LIBXO_VERSION_EXTRA); +} + +static void +print_help (void) +{ + fprintf(stderr, +"Usage: xo [options] format [fields]\n" +" --close <path> Close tags for the given path\n" +" --depth <num> Set the depth for pretty printing\n" +" --help Display this help text\n" +" --html OR -H Generate HTML output\n" +" --json OR -J Generate JSON output\n" +" --leading-xpath <path> OR -l <path> " + "Add a prefix to generated XPaths (HTML)\n" +" --open <path> Open tags for the given path\n" +" --pretty OR -p Make 'pretty' output (add indent, newlines)\n" +" --style <style> OR -s <style> " + "Generate given style (xml, json, text, html)\n" +" --text OR -T Generate text output (the default style)\n" +" --version Display version information\n" +" --warn OR -W Display warnings in text on stderr\n" +" --warn-xml Display warnings in xml on stdout\n" +" --wrap <path> Wrap output in a set of containers\n" +" --xml OR -X Generate XML output\n" +" --xpath Add XPath data to HTML output\n"); +} + +static struct opts { + int o_depth; + int o_help; + int o_not_first; + int o_xpath; + int o_version; + int o_warn_xml; + int o_wrap; +} opts; + +static struct option long_opts[] = { + { "close", required_argument, NULL, 'c' }, + { "depth", required_argument, &opts.o_depth, 1 }, + { "help", no_argument, &opts.o_help, 1 }, + { "html", no_argument, NULL, 'H' }, + { "json", no_argument, NULL, 'J' }, + { "leading-xpath", required_argument, NULL, 'l' }, + { "not-first", no_argument, &opts.o_not_first, 1 }, + { "open", required_argument, NULL, 'o' }, + { "option", required_argument, NULL, 'O' }, + { "pretty", no_argument, NULL, 'p' }, + { "style", required_argument, NULL, 's' }, + { "text", no_argument, NULL, 'T' }, + { "xml", no_argument, NULL, 'X' }, + { "xpath", no_argument, &opts.o_xpath, 1 }, + { "version", no_argument, &opts.o_version, 1 }, + { "warn", no_argument, NULL, 'W' }, + { "warn-xml", no_argument, &opts.o_warn_xml, 1 }, + { "wrap", required_argument, &opts.o_wrap, 1 }, + { NULL, 0, NULL, 0 } +}; + +int +main (int argc UNUSED, char **argv) +{ + char *fmt = NULL, *cp, *np; + char *opt_opener = NULL, *opt_closer = NULL, *opt_wrapper = NULL; + char *opt_options = NULL; + int opt_depth = 0; + int opt_not_first = 0; + int rc; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + return 1; + + while ((rc = getopt_long(argc, argv, "c:HJl:ps:TXW", + long_opts, NULL)) != -1) { + switch (rc) { + case 'c': + opt_closer = optarg; + xo_set_flags(NULL, XOF_IGNORE_CLOSE); + break; + + case 'H': + xo_set_style(NULL, XO_STYLE_HTML); + break; + + case 'J': + xo_set_style(NULL, XO_STYLE_JSON); + break; + + case 'l': + xo_set_leading_xpath(NULL, optarg); + break; + + case 'O': + opt_options = optarg; + break; + + case 'o': + opt_opener = optarg; + break; + + case 'p': + xo_set_flags(NULL, XOF_PRETTY); + break; + + case 's': + if (xo_set_style_name(NULL, optarg) < 0) + xo_errx(1, "unknown style: %s", optarg); + break; + + case 'T': + xo_set_style(NULL, XO_STYLE_TEXT); + break; + + case 'X': + xo_set_style(NULL, XO_STYLE_XML); + break; + + case 'W': + opt_warn = 1; + xo_set_flags(NULL, XOF_WARN); + break; + + case ':': + xo_errx(1, "missing argument"); + break; + + case 0: + if (opts.o_depth) { + opt_depth = atoi(optarg); + + } else if (opts.o_help) { + print_help(); + return 1; + + } else if (opts.o_not_first) { + opt_not_first = 1; + + } else if (opts.o_xpath) { + xo_set_flags(NULL, XOF_XPATH); + + } else if (opts.o_version) { + print_version(); + return 0; + + } else if (opts.o_warn_xml) { + opt_warn = 1; + xo_set_flags(NULL, XOF_WARN | XOF_WARN_XML); + + } else if (opts.o_wrap) { + opt_wrapper = optarg; + + } else { + print_help(); + return 1; + } + + bzero(&opts, sizeof(opts)); /* Reset all the options */ + break; + + default: + print_help(); + return 1; + } + } + + argc -= optind; + argv += optind; + + if (opt_options) { + rc = xo_set_options(NULL, opt_options); + if (rc < 0) + xo_errx(1, "invalid options: %s", opt_options); + } + + xo_set_formatter(NULL, formatter, checkpoint); + xo_set_flags(NULL, XOF_NO_VA_ARG); + xo_set_flags(NULL, XOF_NO_TOP); + + fmt = *argv++; + if (opt_opener == NULL && opt_closer == NULL && fmt == NULL) { + print_help(); + return 1; + } + + if (opt_not_first) + xo_set_flags(NULL, XOF_NOT_FIRST); + + if (opt_closer) { + opt_depth += 1; + for (cp = opt_closer; cp && *cp; cp = np) { + np = strchr(cp, '/'); + if (np == NULL) + break; + np += 1; + opt_depth += 1; + } + } + + if (opt_depth > 0) + xo_set_depth(NULL, opt_depth); + + if (opt_opener) { + for (cp = opt_opener; cp && *cp; cp = np) { + np = strchr(cp, '/'); + if (np) + *np = '\0'; + xo_open_container(cp); + if (np) + *np++ = '/'; + } + } + + if (opt_wrapper) { + for (cp = opt_wrapper; cp && *cp; cp = np) { + np = strchr(cp, '/'); + if (np) + *np = '\0'; + xo_open_container(cp); + if (np) + *np++ = '/'; + } + } + + if (fmt && *fmt) { + save_argv = argv; + prep_arg(fmt); + xo_emit(fmt); + } + + while (opt_wrapper) { + np = strrchr(opt_wrapper, '/'); + xo_close_container(np ? np + 1 : opt_wrapper); + if (np) + *np = '\0'; + else + opt_wrapper = NULL; + } + + while (opt_closer) { + np = strrchr(opt_closer, '/'); + xo_close_container(np ? np + 1 : opt_closer); + if (np) + *np = '\0'; + else + opt_closer = NULL; + } + + xo_finish(); + + return 0; +} diff --git a/contrib/libxo/xohtml/external/jquery.js b/contrib/libxo/xohtml/external/jquery.js new file mode 100644 index 0000000..eda55db --- /dev/null +++ b/contrib/libxo/xohtml/external/jquery.js @@ -0,0 +1,9300 @@ +/*! + * jQuery JavaScript Library v1.7 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu Nov 3 16:18:21 2011 -0400 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Check for digits + rdigit = /\d/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + return i === -1 ? + this.slice( i ) : + this.slice( i, +i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).unbind( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNumeric: function( obj ) { + return obj != null && rdigit.test( obj ) && !isNaN( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw msg; + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // The extra typeof function check is to prevent crashes + // in Safari 2 (See: #3039) + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + return deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var div = document.createElement( "div" ), + documentElement = document.documentElement, + all, + a, + select, + opt, + input, + marginDiv, + support, + fragment, + body, + testElementParent, + testElement, + testElementStyle, + tds, + events, + eventName, + i, + isSupported; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/><nav></nav>"; + + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName( "tbody" ).length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName( "link" ).length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure unknown elements (like HTML5 elems) are handled appropriately + unknownElems: !!div.getElementsByTagName( "nav" ).length, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + div.innerHTML = ""; + + // Figure out if the W3C box model works as expected + div.style.width = div.style.paddingLeft = "1px"; + + // We don't want to do body-related feature tests on frameset + // documents, which lack a body. So we use + // document.getElementsByTagName("body")[0], which is undefined in + // frameset documents, while document.body isn’t. (7398) + body = document.getElementsByTagName("body")[ 0 ]; + // We use our own, invisible, body unless the body is already present + // in which case we use a div (#9239) + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + jQuery.extend( testElementStyle, { + position: "absolute", + left: "-999px", + top: "-999px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + support.boxModel = div.offsetWidth === 2; + + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "<div style='width:4px;'></div>"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>"; + tds = div.getElementsByTagName( "td" ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( document.defaultView && document.defaultView.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + } ) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run fixed position tests at doc ready to avoid a crash + // related to the invisible body in IE8 + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop = 1, + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;", + vb = "visibility:hidden;border:0;", + style = "style='" + ptlm + "border:5px solid #000;padding:0;'", + html = "<div " + style + "><div></div></div>" + + "<table " + style + " cellpadding='0' cellspacing='0'>" + + "<tr><td></td></tr></table>"; + + // Reconstruct a container + body = document.getElementsByTagName("body")[0]; + if ( !body ) { + // Return for frameset docs that don't have a body + // These tests cannot be done + return; + } + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct a test element + testElement = document.createElement("div"); + testElement.style.cssText = ptlm + vb; + + testElement.innerHTML = html; + container.appendChild( testElement ); + outer = testElement.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + testElement = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); + + // Null connected elements to avoid leaks in IE + testElement = fragment = select = opt = body = marginDiv = div = input = null; + + return support; +})(); + +// Keep track of boxModel +jQuery.boxModel = jQuery.support.boxModel; + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ jQuery.expando ] = id = ++jQuery.uuid; + } else { + id = jQuery.expando; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support space separated names + if ( jQuery.isArray( name ) ) { + name = name; + } else if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ jQuery.expando ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); + } else { + elem[ jQuery.expando ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var $this = jQuery( this ), + args = [ parts[0], value ]; + + $this.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + $this.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return undefined; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( !("getAttribute" in elem) ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return undefined; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( elem.nodeType === 1 ) { + attrNames = ( value || "" ).split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ].toLowerCase(); + propName = jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rnamespaces = /\.(.*)$/, + rformElems = /^(?:textarea|input|select)$/i, + rperiod = /\./g, + rspaces = / /g, + rescape = /[^\w\s.|`]/g, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || elem.id === m[2]) && + (!m[3] || m[3].test( elem.className )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = hoverHack(types).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + namespace: namespaces.join(".") + }, handleObjIn ); + + // Delegated event; pre-analyze selector so it's processed quickly on event dispatch + if ( selector ) { + handleObj.quick = quickParse( selector ); + if ( !handleObj.quick && jQuery.expr.match.POS.test( selector ) ) { + handleObj.isPositional = true; + } + } + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = hoverHack( types || "" ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + namespaces = namespaces? "." + namespaces : ""; + for ( j in events ) { + jQuery.event.remove( elem, j + namespaces, handler, selector ); + } + return; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Only need to loop for special events or selective removal + if ( handler || namespaces || selector || special.remove ) { + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( !handler || handler.guid === handleObj.guid ) { + if ( !namespaces || namespaces.test( handleObj.namespace ) ) { + if ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + } + } + } else { + // Removing all events + eventType.length = 0; + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // triggerHandler() and global events don't bubble or run the default action + if ( onlyHandlers || !elem ) { + event.preventDefault(); + } + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + old = null; + for ( cur = elem.parentNode; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length; i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) ) { + handle.apply( cur, data ); + } + + if ( event.isPropagationStopped() ) { + break; + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + specialHandle = ( jQuery.event.special[ event.type ] || {} ).handle, + handlerQueue = [], + i, j, cur, ret, selMatch, matched, matches, handleObj, sel, hit, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + hit = selMatch[ sel ]; + + if ( handleObj.isPositional ) { + // Since .is() does not work for positionals; see http://jsfiddle.net/eJ4yd/3/ + hit = ( hit || (selMatch[ sel ] = jQuery( sel )) ).index( cur ) >= 0; + } else if ( hit === undefined ) { + hit = selMatch[ sel ] = ( handleObj.quick ? quickIs( cur, handleObj.quick ) : jQuery( cur ).is( sel ) ); + } + if ( hit ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement wheelDelta".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + focus: { + delegateType: "focusin", + noBubble: true + }, + blur: { + delegateType: "focusout", + noBubble: true + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = jQuery.event.special[ fix ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + oldType, ret; + + // For a real mouseover/out, always call the handler; for + // mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || handleObj.origType === event.type || (related !== target && !jQuery.contains( target, related )) ) { + oldType = event.type; + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = oldType; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + // Form was submitted, bubble the event up the tree + if ( this.parentNode ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.bind( name, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = "<a name='" + id + "'/>"; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = "<a href='#'></a>"; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "<p class='TEST'></p>"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "<div class='test e'></div><div class='test'></div>"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ), + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, args.join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( " " ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr article aside audio canvas datalist details figcaption figure footer " + + "header hgroup mark meter nav output progress section summary time video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /<tbody/i, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style)/i, + rnocache = /<(?:script|object|embed|option|style)/i, + rnoshimcache = new RegExp("<(?:" + nodeNames.replace(" ", "|") + ")", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, + wrapMap = { + option: [ 1, "<select multiple='multiple'>", "</select>" ], + legend: [ 1, "<fieldset>", "</fieldset>" ], + thead: [ 1, "<table>", "</table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], + area: [ 1, "<map>", "</map>" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize <link> and <script> tags normally +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "div<div>", "</div>" ]; +} + +jQuery.fn.extend({ + text: function( text ) { + if ( jQuery.isFunction(text) ) { + return this.each(function(i) { + var self = jQuery( this ); + + self.text( text.call(this, i, self.text()) ); + }); + } + + if ( typeof text !== "object" && text !== undefined ) { + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); + } + + return jQuery.text( this ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + return this.each(function() { + jQuery( this ).wrapAll( html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( this[0] && this[0].parentNode ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } else if ( arguments.length ) { + var set = jQuery(arguments[0]); + set.push.apply( set, this.toArray() ); + return this.pushStack( set, "before", arguments ); + } + }, + + after: function() { + if ( this[0] && this[0].parentNode ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } else if ( arguments.length ) { + var set = this.pushStack( this, "after", arguments ); + set.push.apply( set, jQuery(arguments[0]).toArray() ); + return set; + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + if ( value === undefined ) { + return this[0] && this[0].nodeType === 1 ? + this[0].innerHTML.replace(rinlinejQuery, "") : + null; + + // See if we can take a shortcut and just use innerHTML + } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && + !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { + + value = value.replace(rxhtmlTag, "<$1></$2>"); + + try { + for ( var i = 0, l = this.length; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + if ( this[i].nodeType === 1 ) { + jQuery.cleanData( this[i].getElementsByTagName("*") ); + this[i].innerHTML = value; + } + } + + // If using innerHTML throws an exception, use the fallback method + } catch(e) { + this.empty().append( value ); + } + + } else if ( jQuery.isFunction( value ) ) { + this.each(function(i){ + var self = jQuery( this ); + + self.html( value.call(this, i, self.html()) ); + }); + + } else { + this.empty().append( value ); + } + + return this; + }, + + replaceWith: function( value ) { + if ( this[0] && this[0].parentNode ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } else { + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + } + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + var results, first, fragment, parent, + value = args[0], + scripts = []; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback, true ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call(this, i, table ? self.html() : undefined); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + parent = value && value.parentNode; + + // If we're in a fragment, just use that instead of building a new one + if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { + results = { fragment: parent }; + + } else { + results = jQuery.buildFragment( args, this, scripts ); + } + + fragment = results.fragment; + + if ( fragment.childNodes.length === 1 ) { + first = fragment = fragment.firstChild; + } else { + first = fragment.firstChild; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { + callback.call( + table ? + root(this[i], first) : + this[i], + // Make sure that we do not leak memory by inadvertently discarding + // the original fragment (which might have attached data) instead of + // using it; in addition, use the original fragment object for the last + // item instead of first because it can end up being emptied incorrectly + // in certain situations (Bug #8070). + // Fragments from the fragment cache must always be cloned and never used + // in place. + results.cacheable || ( l > 1 && i < lastIndex ) ? + jQuery.clone( fragment, true, true ) : + fragment + ); + } + } + + if ( scripts.length ) { + jQuery.each( scripts, evalScript ); + } + } + + return this; + } +}); + +function root( elem, cur ) { + return jQuery.nodeName(elem, "table") ? + (elem.getElementsByTagName("tbody")[0] || + elem.appendChild(elem.ownerDocument.createElement("tbody"))) : + elem; +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 fail to clone children inside object elements that use + // the proprietary classid attribute value (rather than the type + // attribute) to identify the type of content to display + if ( nodeName === "object" ) { + dest.outerHTML = src.outerHTML; + + } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + if ( src.checked ) { + dest.defaultChecked = dest.checked = src.checked; + } + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, nodes, scripts ) { + var fragment, cacheable, cacheresults, doc, + first = args[ 0 ]; + + // nodes may contain either an explicit document object, + // a jQuery collection or context object. + // If nodes[0] contains a valid object to assign to doc + if ( nodes && nodes[0] ) { + doc = nodes[0].ownerDocument || nodes[0]; + } + + // Ensure that an attr object doesn't incorrectly stand in as a document object + // Chrome and Firefox seem to allow this to occur and will throw exception + // Fixes #8950 + if ( !doc.createDocumentFragment ) { + doc = document; + } + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (!jQuery.support.unknownElems && rnoshimcache.test( first )) ) { + + cacheable = true; + + cacheresults = jQuery.fragments[ first ]; + if ( cacheresults && cacheresults !== 1 ) { + fragment = cacheresults; + } + } + + if ( !fragment ) { + fragment = doc.createDocumentFragment(); + jQuery.clean( args, doc, fragment, scripts ); + } + + if ( cacheable ) { + jQuery.fragments[ first ] = cacheresults ? fragment : 1; + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var ret = [], + insert = jQuery( selector ), + parent = this.length === 1 && this[0].parentNode; + + if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { + insert[ original ]( this[0] ); + return this; + + } else { + for ( var i = 0, l = insert.length; i < l; i++ ) { + var elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( elem.type === "checkbox" || elem.type === "radio" ) { + elem.defaultChecked = elem.checked; + } +} +// Finds all inputs and passes them to fixDefaultChecked +function findInputs( elem ) { + var nodeName = ( elem.nodeName || "" ).toLowerCase(); + if ( nodeName === "input" ) { + fixDefaultChecked( elem ); + // Skip scripts, get other children + } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var clone = elem.cloneNode(true), + srcElements, + destElements, + i; + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName + // instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var checkScriptType; + + context = context || document; + + // !context.createElement fails in IE with an error but returns typeof 'object' + if ( typeof context.createElement === "undefined" ) { + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + } + + var ret = [], j; + + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1></$2>"); + + // Trim whitespace, otherwise indexOf won't work as expected + var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(), + wrap = wrapMap[ tag ] || wrapMap._default, + depth = wrap[0], + div = context.createElement("div"); + + // Append wrapper element to unknown element safe doc fragment + if ( context === document ) { + // Use the fragment we've already created for this document + safeFragment.appendChild( div ); + } else { + // Use a fragment created with the owner document + createSafeFragment( context ).appendChild( div ); + } + + // Go to html and back, then peel off extra wrappers + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted <tbody> from table fragments + if ( !jQuery.support.tbody ) { + + // String was a <table>, *may* have spurious <tbody> + var hasBody = rtbody.test(elem), + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare <thead> or <tfoot> + wrap[1] === "<table>" && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + } + } + + // Resets defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + var len; + if ( !jQuery.support.appendChecked ) { + if ( elem[0] && typeof (len = elem.length) === "number" ) { + for ( j = 0; j < len; j++ ) { + findInputs( elem[j] ); + } + } else { + findInputs( elem ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + ret = jQuery.merge( ret, elem ); + } + } + + if ( fragment ) { + checkScriptType = function( elem ) { + return !elem.type || rscriptType.test( elem.type ); + }; + for ( i = 0; ret[i]; i++ ) { + if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { + scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); + + } else { + if ( ret[i].nodeType === 1 ) { + var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); + + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + } + fragment.appendChild( ret[i] ); + } + } + } + + return ret; + }, + + cleanData: function( elems ) { + var data, id, + cache = jQuery.cache, + special = jQuery.event.special, + deleteExpando = jQuery.support.deleteExpando; + + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { + continue; + } + + id = elem[ jQuery.expando ]; + + if ( id ) { + data = cache[ id ]; + + if ( data && data.events ) { + for ( var type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + + // Null the DOM reference to avoid IE6/7/8 leak (#7054) + if ( data.handle ) { + data.handle.elem = null; + } + } + + if ( deleteExpando ) { + delete elem[ jQuery.expando ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); + } + + delete cache[ id ]; + } + } + } +}); + +function evalScript( i, elem ) { + if ( elem.src ) { + jQuery.ajax({ + url: elem.src, + async: false, + dataType: "script" + }); + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } +} + + + + +var ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + // fixed for IE9, see #8346 + rupper = /([A-Z]|^ms)/g, + rnumpx = /^-?\d+(?:px)?$/i, + rnum = /^-?\d/, + rrelNum = /^([\-+])=([\-+.\de]+)/, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssWidth = [ "Left", "Right" ], + cssHeight = [ "Top", "Bottom" ], + curCSS, + + getComputedStyle, + currentStyle; + +jQuery.fn.css = function( name, value ) { + // Setting 'undefined' is a no-op + if ( arguments.length === 2 && value === undefined ) { + return this; + } + + return jQuery.access( this, name, value, true, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }); +}; + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity", "opacity" ); + return ret === "" ? "1" : ret; + + } else { + return elem.style.opacity; + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, origName = jQuery.camelCase( name ), + style = elem.style, hooks = jQuery.cssHooks[ origName ]; + + name = jQuery.cssProps[ origName ] || origName; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra ) { + var ret, hooks; + + // Make sure that we're working with the right name + name = jQuery.camelCase( name ); + hooks = jQuery.cssHooks[ name ]; + name = jQuery.cssProps[ name ] || name; + + // cssFloat needs a special treatment + if ( name === "cssFloat" ) { + name = "float"; + } + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { + return ret; + + // Otherwise, if a way to get the computed value exists, use that + } else if ( curCSS ) { + return curCSS( elem, name ); + } + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var old = {}; + + // Remember the old values, and insert the new ones + for ( var name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + } +}); + +// DEPRECATED, Use jQuery.css() instead +jQuery.curCSS = jQuery.css; + +jQuery.each(["height", "width"], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + var val; + + if ( computed ) { + if ( elem.offsetWidth !== 0 ) { + return getWH( elem, name, extra ); + } else { + jQuery.swap( elem, cssShow, function() { + val = getWH( elem, name, extra ); + }); + } + + return val; + } + }, + + set: function( elem, value ) { + if ( rnumpx.test( value ) ) { + // ignore negative width and height values #1599 + value = parseFloat( value ); + + if ( value >= 0 ) { + return value + "px"; + } + + } else { + return value; + } + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( parseFloat( RegExp.$1 ) / 100 ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +jQuery(function() { + // This hook cannot be added until DOM ready because the support test + // for it is not run until after DOM ready + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + var ret; + jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + ret = curCSS( elem, "margin-right", "marginRight" ); + } else { + ret = elem.style.marginRight; + } + }); + return ret; + } + }; + } +}); + +if ( document.defaultView && document.defaultView.getComputedStyle ) { + getComputedStyle = function( elem, name ) { + var ret, defaultView, computedStyle; + + name = name.replace( rupper, "-$1" ).toLowerCase(); + + if ( !(defaultView = elem.ownerDocument.defaultView) ) { + return undefined; + } + + if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) { + ret = computedStyle.getPropertyValue( name ); + if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { + ret = jQuery.style( elem, name ); + } + } + + return ret; + }; +} + +if ( document.documentElement.currentStyle ) { + currentStyle = function( elem, name ) { + var left, rsLeft, uncomputed, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret === null && style && (uncomputed = style[ name ]) ) { + ret = uncomputed; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ( ret || 0 ); + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +curCSS = getComputedStyle || currentStyle; + +function getWH( elem, name, extra ) { + + // Start with offset property + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + which = name === "width" ? cssWidth : cssHeight; + + if ( val > 0 ) { + if ( extra !== "border" ) { + jQuery.each( which, function() { + if ( !extra ) { + val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } else { + val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + }); + } + + return val + "px"; + } + + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ] || 0; + } + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Add padding, border, margin + if ( extra ) { + jQuery.each( which, function() { + val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + if ( extra !== "padding" ) { + val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } + }); + } + + return val + "px"; +} + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + var width = elem.offsetWidth, + height = elem.offsetHeight; + + return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + + + + +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, + rselectTextarea = /^(?:select|textarea)/i, + rspacesAjax = /\s+/, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Document location + ajaxLocation, + + // Document location segments + ajaxLocParts, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + if ( jQuery.isFunction( func ) ) { + var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), + i = 0, + length = dataTypes.length, + dataType, + list, + placeBefore; + + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ), + selection; + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.extend({ + load: function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + + // Don't do a request if no elements are being requested + } else if ( !this.length ) { + return this; + } + + var off = url.indexOf( " " ); + if ( off >= 0 ) { + var selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // Default to a GET request + var type = "GET"; + + // If the second parameter was provided + if ( params ) { + // If it's a function + if ( jQuery.isFunction( params ) ) { + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( typeof params === "object" ) { + params = jQuery.param( params, jQuery.ajaxSettings.traditional ); + type = "POST"; + } + } + + var self = this; + + // Request the remote document + jQuery.ajax({ + url: url, + type: type, + dataType: "html", + data: params, + // Complete callback (responseText is used internally) + complete: function( jqXHR, status, responseText ) { + // Store the response as specified by the jqXHR object + responseText = jqXHR.responseText; + // If successful, inject the HTML into all the matched elements + if ( jqXHR.isResolved() ) { + // #4825: Get the actual response in case + // a dataFilter is present in ajaxSettings + jqXHR.done(function( r ) { + responseText = r; + }); + // See if a selector was specified + self.html( selector ? + // Create a dummy div to hold the results + jQuery("<div>") + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append(responseText.replace(rscript, "")) + + // Locate the specified elements + .find(selector) : + + // If not, just inject the full result + responseText ); + } + + if ( callback ) { + self.each( callback, [ responseText, status, jqXHR ] ); + } + } + }); + + return this; + }, + + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.bind( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // ifModified key + ifModifiedKey, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // The jqXHR state + state = 0, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || "abort"; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + var isSuccess, + success, + error, + statusText = nativeStatusText, + response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, + lastModified, + etag; + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { + jQuery.lastModified[ ifModifiedKey ] = lastModified; + } + if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { + jQuery.etag[ ifModifiedKey ] = etag; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + try { + success = ajaxConvert( s, response ); + statusText = "success"; + isSuccess = true; + } catch(e) { + // We have a parsererror + statusText = "parsererror"; + error = e; + } + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = "" + ( nativeStatusText || statusText ); + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.then( tmp, tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); + + // Determine if a cross-domain request is in order + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefiler, stop there + if ( state === 2 ) { + return false; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already + jqXHR.abort(); + return false; + + } + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + jQuery.error( e ); + } + } + } + + return jqXHR; + }, + + // Serialize an array of form elements or a set of + // key/values into a query string + param: function( a, traditional ) { + var s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : value; + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( var prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); + } +}); + +function buildParams( prefix, obj, traditional, add ) { + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && obj != null && typeof obj === "object" ) { + // Serialize object item. + for ( var name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} + +// This is still on the jQuery object... for now +// Want to move this to jQuery.ajax some day +jQuery.extend({ + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields, + ct, + type, + finalDataType, + firstDataType; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + var dataTypes = s.dataTypes, + converters = {}, + i, + key, + length = dataTypes.length, + tmp, + // Current and previous dataTypes + current = dataTypes[ 0 ], + prev, + // Conversion expression + conversion, + // Conversion function + conv, + // Conversion functions (transitive conversion) + conv1, + conv2; + + // For each dataType in the chain + for ( i = 1; i < length; i++ ) { + + // Create converters map + // with lowercased keys + if ( i === 1 ) { + for ( key in s.converters ) { + if ( typeof key === "string" ) { + converters[ key.toLowerCase() ] = s.converters[ key ]; + } + } + } + + // Get the dataTypes + prev = current; + current = dataTypes[ i ]; + + // If current is auto dataType, update it to prev + if ( current === "*" ) { + current = prev; + // If no auto and dataTypes are actually different + } else if ( prev !== "*" && prev !== current ) { + + // Get the converter + conversion = prev + " " + current; + conv = converters[ conversion ] || converters[ "* " + current ]; + + // If there is no direct converter, search transitively + if ( !conv ) { + conv2 = undefined; + for ( conv1 in converters ) { + tmp = conv1.split( " " ); + if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { + conv2 = converters[ tmp[1] + " " + current ]; + if ( conv2 ) { + conv1 = converters[ conv1 ]; + if ( conv1 === true ) { + conv = conv2; + } else if ( conv2 === true ) { + conv = conv1; + } + break; + } + } + } + } + // If we found no converter, dispatch an error + if ( !( conv || conv2 ) ) { + jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); + } + // If found converter is not an equivalence + if ( conv !== true ) { + // Convert with 1 or 2 converters accordingly + response = conv ? conv( response ) : conv2( conv1(response) ); + } + } + } + return response; +} + + + + +var jsc = jQuery.now(), + jsre = /(\=)\?(&|$)|\?\?/i; + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + return jQuery.expando + "_" + ( jsc++ ); + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var inspectData = s.contentType === "application/x-www-form-urlencoded" && + ( typeof s.data === "string" ); + + if ( s.dataTypes[ 0 ] === "jsonp" || + s.jsonp !== false && ( jsre.test( s.url ) || + inspectData && jsre.test( s.data ) ) ) { + + var responseContainer, + jsonpCallback = s.jsonpCallback = + jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, + previous = window[ jsonpCallback ], + url = s.url, + data = s.data, + replace = "$1" + jsonpCallback + "$2"; + + if ( s.jsonp !== false ) { + url = url.replace( jsre, replace ); + if ( s.url === url ) { + if ( inspectData ) { + data = data.replace( jsre, replace ); + } + if ( s.data === data ) { + // Add callback manually + url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; + } + } + } + + s.url = url; + s.data = data; + + // Install callback + window[ jsonpCallback ] = function( response ) { + responseContainer = [ response ]; + }; + + // Clean-up function + jqXHR.always(function() { + // Set callback back to previous value + window[ jsonpCallback ] = previous; + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( previous ) ) { + window[ jsonpCallback ]( responseContainer[ 0 ] ); + } + }); + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( jsonpCallback + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Delegate to script + return "script"; + } +}); + + + + +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); + + + + +var // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0, + xhrCallbacks; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var xhr = s.xhr(), + handle, + i; + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occured + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + responses.text = xhr.responseText; + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + // if we're in sync mode or it's in cache + // and has been retrieved directly (IE6 & IE7) + // we need to manually fire the callback + if ( !s.async || xhr.readyState === 4 ) { + callback(); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} + + + + +var elemdisplay = {}, + iframe, iframeDoc, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, + timerId, + fxAttrs = [ + // height animations + [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], + // width animations + [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], + // opacity animations + [ "opacity" ] + ], + fxNow; + +jQuery.fn.extend({ + show: function( speed, easing, callback ) { + var elem, display; + + if ( speed || speed === 0 ) { + return this.animate( genFx("show", 3), speed, easing, callback ); + + } else { + for ( var i = 0, j = this.length; i < j; i++ ) { + elem = this[ i ]; + + if ( elem.style ) { + display = elem.style.display; + + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { + display = elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( display === "" && jQuery.css(elem, "display") === "none" ) { + jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( i = 0; i < j; i++ ) { + elem = this[ i ]; + + if ( elem.style ) { + display = elem.style.display; + + if ( display === "" || display === "none" ) { + elem.style.display = jQuery._data( elem, "olddisplay" ) || ""; + } + } + } + + return this; + } + }, + + hide: function( speed, easing, callback ) { + if ( speed || speed === 0 ) { + return this.animate( genFx("hide", 3), speed, easing, callback); + + } else { + var elem, display, + i = 0, + j = this.length; + + for ( ; i < j; i++ ) { + elem = this[i]; + if ( elem.style ) { + display = jQuery.css( elem, "display" ); + + if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of the elements in a second loop + // to avoid the constant reflow + for ( i = 0; i < j; i++ ) { + if ( this[i].style ) { + this[i].style.display = "none"; + } + } + + return this; + } + }, + + // Save the old toggle function + _toggle: jQuery.fn.toggle, + + toggle: function( fn, fn2, callback ) { + var bool = typeof fn === "boolean"; + + if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { + this._toggle.apply( this, arguments ); + + } else if ( fn == null || bool ) { + this.each(function() { + var state = bool ? fn : jQuery(this).is(":hidden"); + jQuery(this)[ state ? "show" : "hide" ](); + }); + + } else { + this.animate(genFx("toggle", 3), fn, fn2, callback); + } + + return this; + }, + + fadeTo: function( speed, to, easing, callback ) { + return this.filter(":hidden").css("opacity", 0).show().end() + .animate({opacity: to}, speed, easing, callback); + }, + + animate: function( prop, speed, easing, callback ) { + var optall = jQuery.speed( speed, easing, callback ); + + if ( jQuery.isEmptyObject( prop ) ) { + return this.each( optall.complete, [ false ] ); + } + + // Do not change referenced properties as per-property easing will be lost + prop = jQuery.extend( {}, prop ); + + function doAnimation() { + // XXX 'this' does not always have a nodeName when running the + // test suite + + if ( optall.queue === false ) { + jQuery._mark( this ); + } + + var opt = jQuery.extend( {}, optall ), + isElement = this.nodeType === 1, + hidden = isElement && jQuery(this).is(":hidden"), + name, val, p, e, + parts, start, end, unit, + method; + + // will store per property easing and be used to determine when an animation is complete + opt.animatedProperties = {}; + + for ( p in prop ) { + + // property name normalization + name = jQuery.camelCase( p ); + if ( p !== name ) { + prop[ name ] = prop[ p ]; + delete prop[ p ]; + } + + val = prop[ name ]; + + // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) + if ( jQuery.isArray( val ) ) { + opt.animatedProperties[ name ] = val[ 1 ]; + val = prop[ name ] = val[ 0 ]; + } else { + opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; + } + + if ( val === "hide" && hidden || val === "show" && !hidden ) { + return opt.complete.call( this ); + } + + if ( isElement && ( name === "height" || name === "width" ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( this, "display" ) === "inline" && + jQuery.css( this, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) { + this.style.display = "inline-block"; + + } else { + this.style.zoom = 1; + } + } + } + } + + if ( opt.overflow != null ) { + this.style.overflow = "hidden"; + } + + for ( p in prop ) { + e = new jQuery.fx( this, opt, p ); + val = prop[ p ]; + + if ( rfxtypes.test( val ) ) { + + // Tracks whether to show or hide based on private + // data attached to the element + method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 ); + if ( method ) { + jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" ); + e[ method ](); + } else { + e[ val ](); + } + + } else { + parts = rfxnum.exec( val ); + start = e.cur(); + + if ( parts ) { + end = parseFloat( parts[2] ); + unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" ) { + jQuery.style( this, p, (end || 1) + unit); + start = ( (end || 1) / e.cur() ) * start; + jQuery.style( this, p, start + unit); + } + + // If a +=/-= token was provided, we're doing a relative animation + if ( parts[1] ) { + end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; + } + + e.custom( start, end, unit ); + + } else { + e.custom( start, val, "" ); + } + } + } + + // For JS strict compliance + return true; + } + + return optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + + stop: function( type, clearQueue, gotoEnd ) { + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var i, + hadTimers = false, + timers = jQuery.timers, + data = jQuery._data( this ); + + // clear marker counters if we know they won't be + if ( !gotoEnd ) { + jQuery._unmark( true, this ); + } + + function stopQueue( elem, data, i ) { + var hooks = data[ i ]; + jQuery.removeData( elem, i, true ); + hooks.stop( gotoEnd ); + } + + if ( type == null ) { + for ( i in data ) { + if ( data[ i ].stop && i.indexOf(".run") === i.length - 4 ) { + stopQueue( this, data, i ); + } + } + } else if ( data[ i = type + ".run" ] && data[ i ].stop ){ + stopQueue( this, data, i ); + } + + for ( i = timers.length; i--; ) { + if ( timers[ i ].elem === this && (type == null || timers[ i ].queue === type) ) { + if ( gotoEnd ) { + + // force the next step to be the last + timers[ i ]( true ); + } else { + timers[ i ].saveState(); + } + hadTimers = true; + timers.splice( i, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( !( gotoEnd && hadTimers ) ) { + jQuery.dequeue( this, type ); + } + }); + } + +}); + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout( clearFxNow, 0 ); + return ( fxNow = jQuery.now() ); +} + +function clearFxNow() { + fxNow = undefined; +} + +// Generate parameters to create a standard animation +function genFx( type, num ) { + var obj = {}; + + jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() { + obj[ this ] = type; + }); + + return obj; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx( "show", 1 ), + slideUp: genFx( "hide", 1 ), + slideToggle: genFx( "toggle", 1 ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.extend({ + speed: function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function( noUnmark ) { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } else if ( noUnmark !== false ) { + jQuery._unmark( this ); + } + }; + + return opt; + }, + + easing: { + linear: function( p, n, firstNum, diff ) { + return firstNum + diff * p; + }, + swing: function( p, n, firstNum, diff ) { + return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum; + } + }, + + timers: [], + + fx: function( elem, options, prop ) { + this.options = options; + this.elem = elem; + this.prop = prop; + + options.orig = options.orig || {}; + } + +}); + +jQuery.fx.prototype = { + // Simple function for setting a style value + update: function() { + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this ); + }, + + // Get the current size + cur: function() { + if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) { + return this.elem[ this.prop ]; + } + + var parsed, + r = jQuery.css( this.elem, this.prop ); + // Empty strings, null, undefined and "auto" are converted to 0, + // complex values such as "rotate(1rad)" are returned as is, + // simple values such as "10px" are parsed to Float. + return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; + }, + + // Start an animation from one number to another + custom: function( from, to, unit ) { + var self = this, + fx = jQuery.fx; + + this.startTime = fxNow || createFxNow(); + this.end = to; + this.now = this.start = from; + this.pos = this.state = 0; + this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); + + function t( gotoEnd ) { + return self.step( gotoEnd ); + } + + t.queue = this.options.queue; + t.elem = this.elem; + t.saveState = function() { + if ( self.options.hide && jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) { + jQuery._data( self.elem, "fxshow" + self.prop, self.start ); + } + }; + + if ( t() && jQuery.timers.push(t) && !timerId ) { + timerId = setInterval( fx.tick, fx.interval ); + } + }, + + // Simple 'show' function + show: function() { + var dataShow = jQuery._data( this.elem, "fxshow" + this.prop ); + + // Remember where we started, so that we can go back to it later + this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop ); + this.options.show = true; + + // Begin the animation + // Make sure that we start at a small width/height to avoid any flash of content + if ( dataShow !== undefined ) { + // This show is picking up where a previous hide or show left off + this.custom( this.cur(), dataShow ); + } else { + this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() ); + } + + // Start by showing the element + jQuery( this.elem ).show(); + }, + + // Simple 'hide' function + hide: function() { + // Remember where we started, so that we can go back to it later + this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop ); + this.options.hide = true; + + // Begin the animation + this.custom( this.cur(), 0 ); + }, + + // Each step of an animation + step: function( gotoEnd ) { + var p, n, complete, + t = fxNow || createFxNow(), + done = true, + elem = this.elem, + options = this.options; + + if ( gotoEnd || t >= options.duration + this.startTime ) { + this.now = this.end; + this.pos = this.state = 1; + this.update(); + + options.animatedProperties[ this.prop ] = true; + + for ( p in options.animatedProperties ) { + if ( options.animatedProperties[ p ] !== true ) { + done = false; + } + } + + if ( done ) { + // Reset the overflow + if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { + + jQuery.each( [ "", "X", "Y" ], function( index, value ) { + elem.style[ "overflow" + value ] = options.overflow[ index ]; + }); + } + + // Hide the element if the "hide" operation was done + if ( options.hide ) { + jQuery( elem ).hide(); + } + + // Reset the properties, if the item has been hidden or shown + if ( options.hide || options.show ) { + for ( p in options.animatedProperties ) { + jQuery.style( elem, p, options.orig[ p ] ); + jQuery.removeData( elem, "fxshow" + p, true ); + // Toggle data is no longer needed + jQuery.removeData( elem, "toggle" + p, true ); + } + } + + // Execute the complete function + // in the event that the complete function throws an exception + // we must ensure it won't be called twice. #5684 + + complete = options.complete; + if ( complete ) { + + options.complete = false; + complete.call( elem ); + } + } + + return false; + + } else { + // classical easing cannot be used with an Infinity duration + if ( options.duration == Infinity ) { + this.now = t; + } else { + n = t - this.startTime; + this.state = n / options.duration; + + // Perform the easing function, defaults to swing + this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration ); + this.now = this.start + ( (this.end - this.start) * this.pos ); + } + // Perform the next step of the animation + this.update(); + } + + return true; + } +}; + +jQuery.extend( jQuery.fx, { + tick: function() { + var timer, + timers = jQuery.timers, + i = 0; + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + }, + + interval: 13, + + stop: function() { + clearInterval( timerId ); + timerId = null; + }, + + speeds: { + slow: 600, + fast: 200, + // Default speed + _default: 400 + }, + + step: { + opacity: function( fx ) { + jQuery.style( fx.elem, "opacity", fx.now ); + }, + + _default: function( fx ) { + if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { + fx.elem.style[ fx.prop ] = fx.now + fx.unit; + } else { + fx.elem[ fx.prop ] = fx.now; + } + } + } +}); + +// Adds width/height step functions +// Do not set anything below 0 +jQuery.each([ "width", "height" ], function( i, prop ) { + jQuery.fx.step[ prop ] = function( fx ) { + jQuery.style( fx.elem, prop, Math.max(0, fx.now) ); + }; +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} + +// Try to restore the default display value of an element +function defaultDisplay( nodeName ) { + + if ( !elemdisplay[ nodeName ] ) { + + var body = document.body, + elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), + display = elem.css( "display" ); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // No iframe to use yet, so create it + if ( !iframe ) { + iframe = document.createElement( "iframe" ); + iframe.frameBorder = iframe.width = iframe.height = 0; + } + + body.appendChild( iframe ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" ); + iframeDoc.close(); + } + + elem = iframeDoc.createElement( nodeName ); + + iframeDoc.body.appendChild( elem ); + + display = jQuery.css( elem, "display" ); + body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + } + + return elemdisplay[ nodeName ]; +} + + + + +var rtable = /^t(?:able|d|h)$/i, + rroot = /^(?:body|html)$/i; + +if ( "getBoundingClientRect" in document.documentElement ) { + jQuery.fn.offset = function( options ) { + var elem = this[0], box; + + if ( options ) { + return this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + if ( !elem || !elem.ownerDocument ) { + return null; + } + + if ( elem === elem.ownerDocument.body ) { + return jQuery.offset.bodyOffset( elem ); + } + + try { + box = elem.getBoundingClientRect(); + } catch(e) {} + + var doc = elem.ownerDocument, + docElem = doc.documentElement; + + // Make sure we're not dealing with a disconnected DOM node + if ( !box || !jQuery.contains( docElem, elem ) ) { + return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; + } + + var body = doc.body, + win = getWindow(doc), + clientTop = docElem.clientTop || body.clientTop || 0, + clientLeft = docElem.clientLeft || body.clientLeft || 0, + scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, + scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, + top = box.top + scrollTop - clientTop, + left = box.left + scrollLeft - clientLeft; + + return { top: top, left: left }; + }; + +} else { + jQuery.fn.offset = function( options ) { + var elem = this[0]; + + if ( options ) { + return this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + if ( !elem || !elem.ownerDocument ) { + return null; + } + + if ( elem === elem.ownerDocument.body ) { + return jQuery.offset.bodyOffset( elem ); + } + + var computedStyle, + offsetParent = elem.offsetParent, + prevOffsetParent = elem, + doc = elem.ownerDocument, + docElem = doc.documentElement, + body = doc.body, + defaultView = doc.defaultView, + prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, + top = elem.offsetTop, + left = elem.offsetLeft; + + while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { + if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { + break; + } + + computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; + top -= elem.scrollTop; + left -= elem.scrollLeft; + + if ( elem === offsetParent ) { + top += elem.offsetTop; + left += elem.offsetLeft; + + if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { + top += parseFloat( computedStyle.borderTopWidth ) || 0; + left += parseFloat( computedStyle.borderLeftWidth ) || 0; + } + + prevOffsetParent = offsetParent; + offsetParent = elem.offsetParent; + } + + if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { + top += parseFloat( computedStyle.borderTopWidth ) || 0; + left += parseFloat( computedStyle.borderLeftWidth ) || 0; + } + + prevComputedStyle = computedStyle; + } + + if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { + top += body.offsetTop; + left += body.offsetLeft; + } + + if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { + top += Math.max( docElem.scrollTop, body.scrollTop ); + left += Math.max( docElem.scrollLeft, body.scrollLeft ); + } + + return { top: top, left: left }; + }; +} + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return null; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( ["Left", "Top"], function( i, name ) { + var method = "scroll" + name; + + jQuery.fn[ method ] = function( val ) { + var elem, win; + + if ( val === undefined ) { + elem = this[ 0 ]; + + if ( !elem ) { + return null; + } + + win = getWindow( elem ); + + // Return the scroll offset + return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : + jQuery.support.boxModel && win.document.documentElement[ method ] || + win.document.body[ method ] : + elem[ method ]; + } + + // Set the scroll offset + return this.each(function() { + win = getWindow( this ); + + if ( win ) { + win.scrollTo( + !i ? val : jQuery( win ).scrollLeft(), + i ? val : jQuery( win ).scrollTop() + ); + + } else { + this[ method ] = val; + } + }); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} + + + + +// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods +jQuery.each([ "Height", "Width" ], function( i, name ) { + + var type = name.toLowerCase(); + + // innerHeight and innerWidth + jQuery.fn[ "inner" + name ] = function() { + var elem = this[0]; + return elem ? + elem.style ? + parseFloat( jQuery.css( elem, type, "padding" ) ) : + this[ type ]() : + null; + }; + + // outerHeight and outerWidth + jQuery.fn[ "outer" + name ] = function( margin ) { + var elem = this[0]; + return elem ? + elem.style ? + parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : + this[ type ]() : + null; + }; + + jQuery.fn[ type ] = function( size ) { + // Get window width or height + var elem = this[0]; + if ( !elem ) { + return size == null ? null : this; + } + + if ( jQuery.isFunction( size ) ) { + return this.each(function( i ) { + var self = jQuery( this ); + self[ type ]( size.call( this, i, self[ type ]() ) ); + }); + } + + if ( jQuery.isWindow( elem ) ) { + // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode + // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat + var docElemProp = elem.document.documentElement[ "client" + name ], + body = elem.document.body; + return elem.document.compatMode === "CSS1Compat" && docElemProp || + body && body[ "client" + name ] || docElemProp; + + // Get document width or height + } else if ( elem.nodeType === 9 ) { + // Either scroll[Width/Height] or offset[Width/Height], whichever is greater + return Math.max( + elem.documentElement["client" + name], + elem.body["scroll" + name], elem.documentElement["scroll" + name], + elem.body["offset" + name], elem.documentElement["offset" + name] + ); + + // Get or set width or height on the element + } else if ( size === undefined ) { + var orig = jQuery.css( elem, type ), + ret = parseFloat( orig ); + + return jQuery.isNumeric( ret ) ? ret : orig; + + // Set the width or height on the element (default to pixels if value is unitless) + } else { + return this.css( type, typeof size === "string" ? size : size + "px" ); + } + }; + +}); + + +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; +})( window ); diff --git a/contrib/libxo/xohtml/external/jquery.qtip.css b/contrib/libxo/xohtml/external/jquery.qtip.css new file mode 100644 index 0000000..503bd35 --- /dev/null +++ b/contrib/libxo/xohtml/external/jquery.qtip.css @@ -0,0 +1,599 @@ +/* + * qTip2 - Pretty powerful tooltips - v2.1.1 + * http://qtip2.com + * + * Copyright (c) 2013 Craig Michael Thompson + * Released under the MIT, GPL licenses + * http://jquery.org/license + * + * Date: Thu Jul 11 2013 02:15 UTC+0000 + * Plugins: tips viewport + * Styles: basic css3 + */ +.qtip{ + position: absolute; + left: -28000px; + top: -28000px; + display: none; + + max-width: 280px; + min-width: 50px; + + font-size: 10.5px; + line-height: 12px; + + direction: ltr; + + box-shadow: none; + padding: 0; +} + + .qtip-content{ + position: relative; + padding: 5px 9px; + overflow: hidden; + + text-align: left; + word-wrap: break-word; + } + + .qtip-titlebar{ + position: relative; + padding: 5px 35px 5px 10px; + overflow: hidden; + + border-width: 0 0 1px; + font-weight: bold; + } + + .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; } + + /* Default close button class */ + .qtip-close{ + position: absolute; + right: -9px; top: -9px; + + cursor: pointer; + outline: medium none; + + border-width: 1px; + border-style: solid; + border-color: transparent; + } + + .qtip-titlebar .qtip-close{ + right: 4px; top: 50%; + margin-top: -9px; + } + + * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */ + + .qtip-titlebar .ui-icon, + .qtip-icon .ui-icon{ + display: block; + text-indent: -1000em; + direction: ltr; + } + + .qtip-icon, .qtip-icon .ui-icon{ + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + text-decoration: none; + } + + .qtip-icon .ui-icon{ + width: 18px; + height: 14px; + + line-height: 14px; + text-align: center; + text-indent: 0; + font: normal bold 10px/13px Tahoma,sans-serif; + + color: inherit; + background: transparent none no-repeat -100em -100em; + } + +/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ +.qtip-focus{} + +/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ +.qtip-hover{} + +/* Default tooltip style */ +.qtip-default{ + border-width: 1px; + border-style: solid; + border-color: #F1D031; + + background-color: #FFFFA3; + color: #555; +} + + .qtip-default .qtip-titlebar{ + background-color: #FFEF93; + } + + .qtip-default .qtip-icon{ + border-color: #CCC; + background: #F1F1F1; + color: #777; + } + + .qtip-default .qtip-titlebar .qtip-close{ + border-color: #AAA; + color: #111; + } + + + +/*! Light tooltip style */ +.qtip-light{ + background-color: white; + border-color: #E2E2E2; + color: #454545; +} + + .qtip-light .qtip-titlebar{ + background-color: #f1f1f1; + } + + +/*! Dark tooltip style */ +.qtip-dark{ + background-color: #505050; + border-color: #303030; + color: #f3f3f3; +} + + .qtip-dark .qtip-titlebar{ + background-color: #404040; + } + + .qtip-dark .qtip-icon{ + border-color: #444; + } + + .qtip-dark .qtip-titlebar .ui-state-hover{ + border-color: #303030; + } + + +/*! Cream tooltip style */ +.qtip-cream{ + background-color: #FBF7AA; + border-color: #F9E98E; + color: #A27D35; +} + + .qtip-cream .qtip-titlebar{ + background-color: #F0DE7D; + } + + .qtip-cream .qtip-close .qtip-icon{ + background-position: -82px 0; + } + + +/*! Red tooltip style */ +.qtip-red{ + background-color: #F78B83; + border-color: #D95252; + color: #912323; +} + + .qtip-red .qtip-titlebar{ + background-color: #F06D65; + } + + .qtip-red .qtip-close .qtip-icon{ + background-position: -102px 0; + } + + .qtip-red .qtip-icon{ + border-color: #D95252; + } + + .qtip-red .qtip-titlebar .ui-state-hover{ + border-color: #D95252; + } + + +/*! Green tooltip style */ +.qtip-green{ + background-color: #CAED9E; + border-color: #90D93F; + color: #3F6219; +} + + .qtip-green .qtip-titlebar{ + background-color: #B0DE78; + } + + .qtip-green .qtip-close .qtip-icon{ + background-position: -42px 0; + } + + +/*! Blue tooltip style */ +.qtip-blue{ + background-color: #E5F6FE; + border-color: #ADD9ED; + color: #5E99BD; +} + + .qtip-blue .qtip-titlebar{ + background-color: #D0E9F5; + } + + .qtip-blue .qtip-close .qtip-icon{ + background-position: -2px 0; + } + + + +.qtip-shadow{ + -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); + box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); +} + +/* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ +.qtip-rounded, +.qtip-tipsy, +.qtip-bootstrap{ + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +.qtip-rounded .qtip-titlebar{ + -moz-border-radius: 4px 4px 0 0; + -webkit-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +/* Youtube tooltip style */ +.qtip-youtube{ + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + + -webkit-box-shadow: 0 0 3px #333; + -moz-box-shadow: 0 0 3px #333; + box-shadow: 0 0 3px #333; + + color: white; + border-width: 0; + + background: #4A4A4A; + background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black)); + background-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%); + background-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%); + background-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%); + background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%); +} + + .qtip-youtube .qtip-titlebar{ + background-color: #4A4A4A; + background-color: rgba(0,0,0,0); + } + + .qtip-youtube .qtip-content{ + padding: .75em; + font: 12px arial,sans-serif; + + filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000); + -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"; + } + + .qtip-youtube .qtip-icon{ + border-color: #222; + } + + .qtip-youtube .qtip-titlebar .ui-state-hover{ + border-color: #303030; + } + + +/* jQuery TOOLS Tooltip style */ +.qtip-jtools{ + background: #232323; + background: rgba(0, 0, 0, 0.7); + background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323)); + background-image: -moz-linear-gradient(top, #717171, #232323); + background-image: -webkit-linear-gradient(top, #717171, #232323); + background-image: -ms-linear-gradient(top, #717171, #232323); + background-image: -o-linear-gradient(top, #717171, #232323); + + border: 2px solid #ddd; + border: 2px solid rgba(241,241,241,1); + + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + + -webkit-box-shadow: 0 0 12px #333; + -moz-box-shadow: 0 0 12px #333; + box-shadow: 0 0 12px #333; +} + + /* IE Specific */ + .qtip-jtools .qtip-titlebar{ + background-color: transparent; + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"; + } + .qtip-jtools .qtip-content{ + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"; + } + + .qtip-jtools .qtip-titlebar, + .qtip-jtools .qtip-content{ + background: transparent; + color: white; + border: 0 dashed transparent; + } + + .qtip-jtools .qtip-icon{ + border-color: #555; + } + + .qtip-jtools .qtip-titlebar .ui-state-hover{ + border-color: #333; + } + + +/* Cluetip style */ +.qtip-cluetip{ + -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); + -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); + box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); + + background-color: #D9D9C2; + color: #111; + border: 0 dashed transparent; +} + + .qtip-cluetip .qtip-titlebar{ + background-color: #87876A; + color: white; + border: 0 dashed transparent; + } + + .qtip-cluetip .qtip-icon{ + border-color: #808064; + } + + .qtip-cluetip .qtip-titlebar .ui-state-hover{ + border-color: #696952; + color: #696952; + } + + +/* Tipsy style */ +.qtip-tipsy{ + background: black; + background: rgba(0, 0, 0, .87); + + color: white; + border: 0 solid transparent; + + font-size: 11px; + font-family: 'Lucida Grande', sans-serif; + font-weight: bold; + line-height: 16px; + text-shadow: 0 1px black; +} + + .qtip-tipsy .qtip-titlebar{ + padding: 6px 35px 0 10px; + background-color: transparent; + } + + .qtip-tipsy .qtip-content{ + padding: 6px 10px; + } + + .qtip-tipsy .qtip-icon{ + border-color: #222; + text-shadow: none; + } + + .qtip-tipsy .qtip-titlebar .ui-state-hover{ + border-color: #303030; + } + + +/* Tipped style */ +.qtip-tipped{ + border: 3px solid #959FA9; + + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + + background-color: #F9F9F9; + color: #454545; + + font-weight: normal; + font-family: serif; + + font-size: 12px; +} + + .qtip-tipped .qtip-titlebar{ + border-bottom-width: 0; + + color: white; + background: #3A79B8; + background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D)); + background-image: -webkit-linear-gradient(top, #3A79B8, #2E629D); + background-image: -moz-linear-gradient(top, #3A79B8, #2E629D); + background-image: -ms-linear-gradient(top, #3A79B8, #2E629D); + background-image: -o-linear-gradient(top, #3A79B8, #2E629D); + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"; + + font-size: 14px; + } + + .qtip-tipped .qtip-icon{ + border: 2px solid #285589; + background: #285589; + } + + .qtip-tipped .qtip-icon .ui-icon{ + background-color: #FBFBFB; + color: #555; + } + + +/** + * Twitter Bootstrap style. + * + * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11. + * Does not work with IE 7. + */ +.qtip-bootstrap{ + /** Taken from Bootstrap body */ + font-size: 14px; + line-height: 20px; + color: #333333; + + /** Taken from Bootstrap .popover */ + padding: 1px; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + + .qtip-bootstrap .qtip-titlebar{ + /** Taken from Bootstrap .popover-title */ + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; + } + + .qtip-bootstrap .qtip-titlebar .qtip-close{ + /** + * Overrides qTip2: + * .qtip-titlebar .qtip-close{ + * [...] + * right: 4px; + * top: 50%; + * [...] + * border-style: solid; + * } + */ + right: 11px; + top: 45%; + border-style: none; + } + + .qtip-bootstrap .qtip-content{ + /** Taken from Bootstrap .popover-content */ + padding: 9px 14px; + } + + .qtip-bootstrap .qtip-icon{ + /** + * Overrides qTip2: + * .qtip-default .qtip-icon { + * border-color: #CCC; + * background: #F1F1F1; + * color: #777; + * } + */ + background: transparent; + } + + .qtip-bootstrap .qtip-icon .ui-icon{ + /** + * Overrides qTip2: + * .qtip-icon .ui-icon{ + * width: 18px; + * height: 14px; + * } + */ + width: auto; + height: auto; + + /* Taken from Bootstrap .close */ + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); + } + + .qtip-bootstrap .qtip-icon .ui-icon:hover{ + /* Taken from Bootstrap .close:hover */ + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); + } + + +/* IE9 fix - removes all filters */ +.qtip:not(.ie9haxors) div.qtip-content, +.qtip:not(.ie9haxors) div.qtip-titlebar{ + filter: none; + -ms-filter: none; +} + + + +.qtip .qtip-tip{ + margin: 0 auto; + overflow: hidden; + z-index: 10; + +} + + /* Opera bug #357 - Incorrect tip position + https://github.com/Craga89/qTip2/issues/367 */ + x:-o-prefocus, .qtip .qtip-tip{ + visibility: hidden; + } + + .qtip .qtip-tip, + .qtip .qtip-tip .qtip-vml, + .qtip .qtip-tip canvas{ + position: absolute; + + color: #123456; + background: transparent; + border: 0 dashed transparent; + } + + .qtip .qtip-tip canvas{ top: 0; left: 0; } + + .qtip .qtip-tip .qtip-vml{ + behavior: url(#default#VML); + display: inline-block; + visibility: visible; + } diff --git a/contrib/libxo/xohtml/external/jquery.qtip.js b/contrib/libxo/xohtml/external/jquery.qtip.js new file mode 100644 index 0000000..1159b4e --- /dev/null +++ b/contrib/libxo/xohtml/external/jquery.qtip.js @@ -0,0 +1,2656 @@ +/* + * qTip2 - Pretty powerful tooltips - v2.1.1 + * http://qtip2.com + * + * Copyright (c) 2013 Craig Michael Thompson + * Released under the MIT, GPL licenses + * http://jquery.org/license + * + * Date: Thu Jul 11 2013 02:15 UTC+0000 + * Plugins: tips viewport + * Styles: basic css3 + */ +/*global window: false, jQuery: false, console: false, define: false */ + +/* Cache window, document, undefined */ +(function( window, document, undefined ) { + +// Uses AMD or browser globals to create a jQuery plugin. +(function( factory ) { + "use strict"; + if(typeof define === 'function' && define.amd) { + define(['jquery', 'imagesloaded'], factory); + } + else if(jQuery && !jQuery.fn.qtip) { + factory(jQuery); + } +} +(function($) { + /* This currently causes issues with Safari 6, so for it's disabled */ + //"use strict"; // (Dis)able ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ + +;// Munge the primitives - Paul Irish tip +var TRUE = true, +FALSE = false, +NULL = null, + +// Common variables +X = 'x', Y = 'y', +WIDTH = 'width', +HEIGHT = 'height', + +// Positioning sides +TOP = 'top', +LEFT = 'left', +BOTTOM = 'bottom', +RIGHT = 'right', +CENTER = 'center', + +// Position adjustment types +FLIP = 'flip', +FLIPINVERT = 'flipinvert', +SHIFT = 'shift', + +// Shortcut vars +QTIP, PROTOTYPE, CORNER, CHECKS, +PLUGINS = {}, +NAMESPACE = 'qtip', +ATTR_HAS = 'data-hasqtip', +ATTR_ID = 'data-qtip-id', +WIDGET = ['ui-widget', 'ui-tooltip'], +SELECTOR = '.'+NAMESPACE, +INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '), + +CLASS_FIXED = NAMESPACE+'-fixed', +CLASS_DEFAULT = NAMESPACE + '-default', +CLASS_FOCUS = NAMESPACE + '-focus', +CLASS_HOVER = NAMESPACE + '-hover', +CLASS_DISABLED = NAMESPACE+'-disabled', + +replaceSuffix = '_replacedByqTip', +oldtitle = 'oldtitle', +trackingBound; + +// Browser detection +BROWSER = { + /* + * IE version detection + * + * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment + * Credit to James Padolsey for the original implemntation! + */ + ie: (function(){ + var v = 3, div = document.createElement('div'); + while ((div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->')) { + if(!div.getElementsByTagName('i')[0]) { break; } + } + return v > 4 ? v : NaN; + }()), + + /* + * iOS version detection + */ + iOS: parseFloat( + ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) + .replace('undefined', '3_2').replace('_', '.').replace('_', '') + ) || FALSE +}; + +;function QTip(target, options, id, attr) {
+ // Elements and ID
+ this.id = id;
+ this.target = target;
+ this.tooltip = NULL;
+ this.elements = elements = { target: target };
+
+ // Internal constructs
+ this._id = NAMESPACE + '-' + id;
+ this.timers = { img: {} };
+ this.options = options;
+ this.plugins = {};
+
+ // Cache object
+ this.cache = cache = {
+ event: {},
+ target: $(),
+ disabled: FALSE,
+ attr: attr,
+ onTooltip: FALSE,
+ lastClass: ''
+ };
+
+ // Set the initial flags
+ this.rendered = this.destroyed = this.disabled = this.waiting =
+ this.hiddenDuringWait = this.positioning = this.triggering = FALSE;
+}
+PROTOTYPE = QTip.prototype;
+
+PROTOTYPE.render = function(show) {
+ if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit
+
+ var self = this,
+ options = this.options,
+ cache = this.cache,
+ elements = this.elements,
+ text = options.content.text,
+ title = options.content.title,
+ button = options.content.button,
+ posOptions = options.position,
+ namespace = '.'+this._id+' ',
+ deferreds = [];
+
+ // Add ARIA attributes to target
+ $.attr(this.target[0], 'aria-describedby', this._id);
+
+ // Create tooltip element
+ this.tooltip = elements.tooltip = tooltip = $('<div/>', {
+ 'id': this._id,
+ 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, NAMESPACE + '-pos-' + options.position.my.abbrev() ].join(' '),
+ 'width': options.style.width || '',
+ 'height': options.style.height || '',
+ 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
+
+ /* ARIA specific attributes */
+ 'role': 'alert',
+ 'aria-live': 'polite',
+ 'aria-atomic': FALSE,
+ 'aria-describedby': this._id + '-content',
+ 'aria-hidden': TRUE
+ })
+ .toggleClass(CLASS_DISABLED, this.disabled)
+ .attr(ATTR_ID, this.id)
+ .data(NAMESPACE, this)
+ .appendTo(posOptions.container)
+ .append(
+ // Create content element
+ elements.content = $('<div />', {
+ 'class': NAMESPACE + '-content',
+ 'id': this._id + '-content',
+ 'aria-atomic': TRUE
+ })
+ );
+
+ // Set rendered flag and prevent redundant reposition calls for now
+ this.rendered = -1;
+ this.positioning = TRUE;
+
+ // Create title...
+ if(title) {
+ this._createTitle();
+
+ // Update title only if its not a callback (called in toggle if so)
+ if(!$.isFunction(title)) {
+ deferreds.push( this._updateTitle(title, FALSE) );
+ }
+ }
+
+ // Create button
+ if(button) { this._createButton(); }
+
+ // Set proper rendered flag and update content if not a callback function (called in toggle)
+ if(!$.isFunction(text)) {
+ deferreds.push( this._updateContent(text, FALSE) );
+ }
+ this.rendered = TRUE;
+
+ // Setup widget classes
+ this._setWidget();
+
+ // Assign passed event callbacks (before plugins!)
+ $.each(options.events, function(name, callback) {
+ $.isFunction(callback) && tooltip.bind(
+ (name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name])
+ .join(namespace)+namespace, callback
+ );
+ });
+
+ // Initialize 'render' plugins
+ $.each(PLUGINS, function(name) {
+ var instance;
+ if(this.initialize === 'render' && (instance = this(self))) {
+ self.plugins[name] = instance;
+ }
+ });
+
+ // Assign events
+ this._assignEvents();
+
+ // When deferreds have completed
+ $.when.apply($, deferreds).then(function() {
+ // tooltiprender event
+ self._trigger('render');
+
+ // Reset flags
+ self.positioning = FALSE;
+
+ // Show tooltip if not hidden during wait period
+ if(!self.hiddenDuringWait && (options.show.ready || show)) {
+ self.toggle(TRUE, cache.event, FALSE);
+ }
+ self.hiddenDuringWait = FALSE;
+ });
+
+ // Expose API
+ QTIP.api[this.id] = this;
+
+ return this;
+};
+
+PROTOTYPE.destroy = function(immediate) {
+ // Set flag the signify destroy is taking place to plugins
+ // and ensure it only gets destroyed once!
+ if(this.destroyed) { return this.target; }
+
+ function process() {
+ if(this.destroyed) { return; }
+ this.destroyed = TRUE;
+
+ var target = this.target,
+ title = target.attr(oldtitle);
+
+ // Destroy tooltip if rendered
+ if(this.rendered) {
+ this.tooltip.stop(1,0).find('*').remove().end().remove();
+ }
+
+ // Destroy all plugins
+ $.each(this.plugins, function(name) {
+ this.destroy && this.destroy();
+ });
+
+ // Clear timers and remove bound events
+ clearTimeout(this.timers.show);
+ clearTimeout(this.timers.hide);
+ this._unassignEvents();
+
+ // Remove api object and ARIA attributes
+ target.removeData(NAMESPACE).removeAttr(ATTR_ID)
+ .removeAttr('aria-describedby');
+
+ // Reset old title attribute if removed
+ if(this.options.suppress && title) {
+ target.attr('title', title).removeAttr(oldtitle);
+ }
+
+ // Remove qTip events associated with this API
+ this._unbind(target);
+
+ // Remove ID from used id objects, and delete object references
+ // for better garbage collection and leak protection
+ this.options = this.elements = this.cache = this.timers =
+ this.plugins = this.mouse = NULL;
+
+ // Delete epoxsed API object
+ delete QTIP.api[this.id];
+ }
+
+ // If an immediate destory is needed
+ if(immediate !== TRUE && this.rendered) {
+ tooltip.one('tooltiphidden', $.proxy(process, this));
+ !this.triggering && this.hide();
+ }
+
+ // If we're not in the process of hiding... process
+ else { process.call(this); }
+
+ return this.target;
+};
+
+;function invalidOpt(a) { + return a === NULL || $.type(a) !== 'object'; +} + +function invalidContent(c) { + return !( $.isFunction(c) || (c && c.attr) || c.length || ($.type(c) === 'object' && (c.jquery || c.then) )); +} + +// Option object sanitizer +function sanitizeOptions(opts) { + var content, text, ajax, once; + + if(invalidOpt(opts)) { return FALSE; } + + if(invalidOpt(opts.metadata)) { + opts.metadata = { type: opts.metadata }; + } + + if('content' in opts) { + content = opts.content; + + if(invalidOpt(content) || content.jquery || content.done) { + content = opts.content = { + text: (text = invalidContent(content) ? FALSE : content) + }; + } + else { text = content.text; } + + // DEPRECATED - Old content.ajax plugin functionality + // Converts it into the proper Deferred syntax + if('ajax' in content) { + ajax = content.ajax; + once = ajax && ajax.once !== FALSE; + delete content.ajax; + + content.text = function(event, api) { + var loading = text || $(this).attr(api.options.content.attr) || 'Loading...', + + deferred = $.ajax( + $.extend({}, ajax, { context: api }) + ) + .then(ajax.success, NULL, ajax.error) + .then(function(content) { + if(content && once) { api.set('content.text', content); } + return content; + }, + function(xhr, status, error) { + if(api.destroyed || xhr.status === 0) { return; } + api.set('content.text', status + ': ' + error); + }); + + return !once ? (api.set('content.text', loading), deferred) : loading; + }; + } + + if('title' in content) { + if(!invalidOpt(content.title)) { + content.button = content.title.button; + content.title = content.title.text; + } + + if(invalidContent(content.title || FALSE)) { + content.title = FALSE; + } + } + } + + if('position' in opts && invalidOpt(opts.position)) { + opts.position = { my: opts.position, at: opts.position }; + } + + if('show' in opts && invalidOpt(opts.show)) { + opts.show = opts.show.jquery ? { target: opts.show } : + opts.show === TRUE ? { ready: TRUE } : { event: opts.show }; + } + + if('hide' in opts && invalidOpt(opts.hide)) { + opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide }; + } + + if('style' in opts && invalidOpt(opts.style)) { + opts.style = { classes: opts.style }; + } + + // Sanitize plugin options + $.each(PLUGINS, function() { + this.sanitize && this.sanitize(opts); + }); + + return opts; +} + +// Setup builtin .set() option checks +CHECKS = PROTOTYPE.checks = { + builtin: { + // Core checks + '^id$': function(obj, o, v, prev) { + var id = v === TRUE ? QTIP.nextid : v, + new_id = NAMESPACE + '-' + id; + + if(id !== FALSE && id.length > 0 && !$('#'+new_id).length) { + this._id = new_id; + + if(this.rendered) { + this.tooltip[0].id = this._id; + this.elements.content[0].id = this._id + '-content'; + this.elements.title[0].id = this._id + '-title'; + } + } + else { obj[o] = prev; } + }, + '^prerender': function(obj, o, v) { + v && !this.rendered && this.render(this.options.show.ready); + }, + + // Content checks + '^content.text$': function(obj, o, v) { + this._updateContent(v); + }, + '^content.attr$': function(obj, o, v, prev) { + if(this.options.content.text === this.target.attr(prev)) { + this._updateContent( this.target.attr(v) ); + } + }, + '^content.title$': function(obj, o, v) { + // Remove title if content is null + if(!v) { return this._removeTitle(); } + + // If title isn't already created, create it now and update + v && !this.elements.title && this._createTitle(); + this._updateTitle(v); + }, + '^content.button$': function(obj, o, v) { + this._updateButton(v); + }, + '^content.title.(text|button)$': function(obj, o, v) { + this.set('content.'+o, v); // Backwards title.text/button compat + }, + + // Position checks + '^position.(my|at)$': function(obj, o, v){ + 'string' === typeof v && (obj[o] = new CORNER(v, o === 'at')); + }, + '^position.container$': function(obj, o, v){ + this.tooltip.appendTo(v); + }, + + // Show checks + '^show.ready$': function(obj, o, v) { + v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE)); + }, + + // Style checks + '^style.classes$': function(obj, o, v, p) { + this.tooltip.removeClass(p).addClass(v); + }, + '^style.width|height': function(obj, o, v) { + this.tooltip.css(o, v); + }, + '^style.widget|content.title': function() { + this._setWidget(); + }, + '^style.def': function(obj, o, v) { + this.tooltip.toggleClass(CLASS_DEFAULT, !!v); + }, + + // Events check + '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { + tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); + }, + + // Properties which require event reassignment + '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { + var posOptions = this.options.position; + + // Set tracking flag + tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); + + // Reassign events + this._unassignEvents(); + this._assignEvents(); + } + } +}; + +// Dot notation converter +function convertNotation(options, notation) { + var i = 0, obj, option = options, + + // Split notation into array + levels = notation.split('.'); + + // Loop through + while( option = option[ levels[i++] ] ) { + if(i < levels.length) { obj = option; } + } + + return [obj || options, levels.pop()]; +} + +PROTOTYPE.get = function(notation) { + if(this.destroyed) { return this; } + + var o = convertNotation(this.options, notation.toLowerCase()), + result = o[0][ o[1] ]; + + return result.precedance ? result.string() : result; +}; + +function setCallback(notation, args) { + var category, rule, match; + + for(category in this.checks) { + for(rule in this.checks[category]) { + if(match = (new RegExp(rule, 'i')).exec(notation)) { + args.push(match); + + if(category === 'builtin' || this.plugins[category]) { + this.checks[category][rule].apply( + this.plugins[category] || this, args + ); + } + } + } + } +} + +var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i, + rrender = /^prerender|show\.ready/i; + +PROTOTYPE.set = function(option, value) { + if(this.destroyed) { return this; } + + var rendered = this.rendered, + reposition = FALSE, + options = this.options, + checks = this.checks, + name; + + // Convert singular option/value pair into object form + if('string' === typeof option) { + name = option; option = {}; option[name] = value; + } + else { option = $.extend({}, option); } + + // Set all of the defined options to their new values + $.each(option, function(notation, value) { + if(!rendered && !rrender.test(notation)) { + delete option[notation]; return; + } + + // Set new obj value + var obj = convertNotation(options, notation.toLowerCase()), previous; + previous = obj[0][ obj[1] ]; + obj[0][ obj[1] ] = value && value.nodeType ? $(value) : value; + + // Also check if we need to reposition + reposition = rmove.test(notation) || reposition; + + // Set the new params for the callback + option[notation] = [obj[0], obj[1], value, previous]; + }); + + // Re-sanitize options + sanitizeOptions(options); + + /* + * Execute any valid callbacks for the set options + * Also set positioning flag so we don't get loads of redundant repositioning calls. + */ + this.positioning = TRUE; + $.each(option, $.proxy(setCallback, this)); + this.positioning = FALSE; + + // Update position if needed + if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) { + this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event ); + } + + return this; +}; + +;PROTOTYPE._update = function(content, element, reposition) { + var self = this, + cache = this.cache; + + // Make sure tooltip is rendered and content is defined. If not return + if(!this.rendered || !content) { return FALSE; } + + // Use function to parse content + if($.isFunction(content)) { + content = content.call(this.elements.target, cache.event, this) || ''; + } + + // Handle deferred content + if($.isFunction(content.then)) { + cache.waiting = TRUE; + return content.then(function(c) { + cache.waiting = FALSE; + return self._update(c, element); + }, NULL, function(e) { + return self._update(e, element); + }); + } + + // If content is null... return false + if(content === FALSE || (!content && content !== '')) { return FALSE; } + + // Append new content if its a DOM array and show it if hidden + if(content.jquery && content.length > 0) { + element.children().detach().end().append( content.css({ display: 'block' }) ); + } + + // Content is a regular string, insert the new content + else { element.html(content); } + + // If imagesLoaded is included, ensure images have loaded and return promise + cache.waiting = TRUE; + + return ( $.fn.imagesLoaded ? element.imagesLoaded() : $.Deferred().resolve($([])) ) + .done(function(images) { + cache.waiting = FALSE; + + // Reposition if rendered + if(images.length && self.rendered && self.tooltip[0].offsetWidth > 0) { + self.reposition(cache.event, !images.length); + } + }) + .promise(); +}; + +PROTOTYPE._updateContent = function(content, reposition) { + this._update(content, this.elements.content, reposition); +}; + +PROTOTYPE._updateTitle = function(content, reposition) { + if(this._update(content, this.elements.title, reposition) === FALSE) { + this._removeTitle(FALSE); + } +}; + +PROTOTYPE._createTitle = function() +{ + var elements = this.elements, + id = this._id+'-title'; + + // Destroy previous title element, if present + if(elements.titlebar) { this._removeTitle(); } + + // Create title bar and title elements + elements.titlebar = $('<div />', { + 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '') + }) + .append( + elements.title = $('<div />', { + 'id': id, + 'class': NAMESPACE + '-title', + 'aria-atomic': TRUE + }) + ) + .insertBefore(elements.content) + + // Button-specific events + .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { + $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); + }) + .delegate('.qtip-close', 'mouseover mouseout', function(event){ + $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); + }); + + // Create button if enabled + if(this.options.content.button) { this._createButton(); } +}; + +PROTOTYPE._removeTitle = function(reposition) +{ + var elements = this.elements; + + if(elements.title) { + elements.titlebar.remove(); + elements.titlebar = elements.title = elements.button = NULL; + + // Reposition if enabled + if(reposition !== FALSE) { this.reposition(); } + } +}; + +;PROTOTYPE.reposition = function(event, effect) { + if(!this.rendered || this.positioning || this.destroyed) { return this; } + + // Set positioning flag + this.positioning = TRUE; + + var cache = this.cache, + tooltip = this.tooltip, + posOptions = this.options.position, + target = posOptions.target, + my = posOptions.my, + at = posOptions.at, + viewport = posOptions.viewport, + container = posOptions.container, + adjust = posOptions.adjust, + method = adjust.method.split(' '), + elemWidth = tooltip.outerWidth(FALSE), + elemHeight = tooltip.outerHeight(FALSE), + targetWidth = 0, + targetHeight = 0, + type = tooltip.css('position'), + position = { left: 0, top: 0 }, + visible = tooltip[0].offsetWidth > 0, + isScroll = event && event.type === 'scroll', + win = $(window), + doc = container[0].ownerDocument, + mouse = this.mouse, + pluginCalculations, offset; + + // Check if absolute position was passed + if($.isArray(target) && target.length === 2) { + // Force left top and set position + at = { x: LEFT, y: TOP }; + position = { left: target[0], top: target[1] }; + } + + // Check if mouse was the target + else if(target === 'mouse' && ((event && event.pageX) || cache.event.pageX)) { + // Force left top to allow flipping + at = { x: LEFT, y: TOP }; + + // Use cached event if one isn't available for positioning + event = mouse && mouse.pageX && (adjust.mouse || !event || !event.pageX) ? mouse : + (event && (event.type === 'resize' || event.type === 'scroll') ? cache.event : + event && event.pageX && event.type === 'mousemove' ? event : + (!adjust.mouse || this.options.show.distance) && cache.origin && cache.origin.pageX ? cache.origin : + event) || event || cache.event || mouse || {}; + + // Calculate body and container offset and take them into account below + if(type !== 'static') { position = container.offset(); } + if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) { offset = $(doc.body).offset(); } + + // Use event coordinates for position + position = { + left: event.pageX - position.left + (offset && offset.left || 0), + top: event.pageY - position.top + (offset && offset.top || 0) + }; + + // Scroll events are a pain, some browsers + if(adjust.mouse && isScroll) { + position.left -= mouse.scrollX - win.scrollLeft(); + position.top -= mouse.scrollY - win.scrollTop(); + } + } + + // Target wasn't mouse or absolute... + else { + // Check if event targetting is being used + if(target === 'event' && event && event.target && event.type !== 'scroll' && event.type !== 'resize') { + cache.target = $(event.target); + } + else if(target !== 'event'){ + cache.target = $(target.jquery ? target : elements.target); + } + target = cache.target; + + // Parse the target into a jQuery object and make sure there's an element present + target = $(target).eq(0); + if(target.length === 0) { return this; } + + // Check if window or document is the target + else if(target[0] === document || target[0] === window) { + targetWidth = BROWSER.iOS ? window.innerWidth : target.width(); + targetHeight = BROWSER.iOS ? window.innerHeight : target.height(); + + if(target[0] === window) { + position = { + top: (viewport || target).scrollTop(), + left: (viewport || target).scrollLeft() + }; + } + } + + // Check if the target is an <AREA> element + else if(PLUGINS.imagemap && target.is('area')) { + pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE); + } + + // Check if the target is an SVG element + else if(PLUGINS.svg && target[0].ownerSVGElement) { + pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE); + } + + // Otherwise use regular jQuery methods + else { + targetWidth = target.outerWidth(FALSE); + targetHeight = target.outerHeight(FALSE); + position = target.offset(); + } + + // Parse returned plugin values into proper variables + if(pluginCalculations) { + targetWidth = pluginCalculations.width; + targetHeight = pluginCalculations.height; + offset = pluginCalculations.offset; + position = pluginCalculations.position; + } + + // Adjust position to take into account offset parents + position = this.reposition.offset(target, position, container); + + // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) + if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) || + (BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) || + (!BROWSER.iOS && type === 'fixed') + ){ + position.left -= win.scrollLeft(); + position.top -= win.scrollTop(); + } + + // Adjust position relative to target + if(!pluginCalculations || (pluginCalculations && pluginCalculations.adjustable !== FALSE)) { + position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; + position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; + } + } + + // Adjust position relative to tooltip + position.left += adjust.x + (my.x === RIGHT ? -elemWidth : my.x === CENTER ? -elemWidth / 2 : 0); + position.top += adjust.y + (my.y === BOTTOM ? -elemHeight : my.y === CENTER ? -elemHeight / 2 : 0); + + // Use viewport adjustment plugin if enabled + if(PLUGINS.viewport) { + position.adjusted = PLUGINS.viewport( + this, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight + ); + + // Apply offsets supplied by positioning plugin (if used) + if(offset && position.adjusted.left) { position.left += offset.left; } + if(offset && position.adjusted.top) { position.top += offset.top; } + } + + // Viewport adjustment is disabled, set values to zero + else { position.adjusted = { left: 0, top: 0 }; } + + // tooltipmove event + if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; } + delete position.adjusted; + + // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly + if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { + tooltip.css(position); + } + + // Use custom function if provided + else if($.isFunction(posOptions.effect)) { + posOptions.effect.call(tooltip, this, $.extend({}, position)); + tooltip.queue(function(next) { + // Reset attributes to avoid cross-browser rendering bugs + $(this).css({ opacity: '', height: '' }); + if(BROWSER.ie) { this.style.removeAttribute('filter'); } + + next(); + }); + } + + // Set positioning flag + this.positioning = FALSE; + + return this; +}; + +// Custom (more correct for qTip!) offset calculator +PROTOTYPE.reposition.offset = function(elem, pos, container) { + if(!container[0]) { return pos; } + + var ownerDocument = $(elem[0].ownerDocument), + quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat', + parent = container[0], + scrolled, position, parentOffset, overflow; + + function scroll(e, i) { + pos.left += i * e.scrollLeft(); + pos.top += i * e.scrollTop(); + } + + // Compensate for non-static containers offset + do { + if((position = $.css(parent, 'position')) !== 'static') { + if(position === 'fixed') { + parentOffset = parent.getBoundingClientRect(); + scroll(ownerDocument, -1); + } + else { + parentOffset = $(parent).position(); + parentOffset.left += (parseFloat($.css(parent, 'borderLeftWidth')) || 0); + parentOffset.top += (parseFloat($.css(parent, 'borderTopWidth')) || 0); + } + + pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0); + pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0); + + // If this is the first parent element with an overflow of "scroll" or "auto", store it + if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); } + } + } + while((parent = parent.offsetParent)); + + // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode) + if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) { + scroll(scrolled, 1); + } + + return pos; +}; + +// Corner class +var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) { + corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); + this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); + this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); + this.forceY = !!forceY; + + var f = corner.charAt(0); + this.precedance = (f === 't' || f === 'b' ? Y : X); +}).prototype; + +C.invert = function(z, center) { + this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z]; +}; + +C.string = function() { + var x = this.x, y = this.y; + return x === y ? x : this.precedance === Y || (this.forceY && y !== 'center') ? y+' '+x : x+' '+y; +}; + +C.abbrev = function() { + var result = this.string().split(' '); + return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''); +}; + +C.clone = function() { + return new CORNER( this.string(), this.forceY ); +};; +PROTOTYPE.toggle = function(state, event) { + var cache = this.cache, + options = this.options, + tooltip = this.tooltip; + + // Try to prevent flickering when tooltip overlaps show element + if(event) { + if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) && + options.show.target.add(event.target).length === options.show.target.length && + tooltip.has(event.relatedTarget).length) { + return this; + } + + // Cache event + cache.event = $.extend({}, event); + } + + // If we're currently waiting and we've just hidden... stop it + this.waiting && !state && (this.hiddenDuringWait = TRUE); + + // Render the tooltip if showing and it isn't already + if(!this.rendered) { return state ? this.render(1) : this; } + else if(this.destroyed || this.disabled) { return this; } + + var type = state ? 'show' : 'hide', + opts = this.options[type], + otherOpts = this.options[ !state ? 'show' : 'hide' ], + posOptions = this.options.position, + contentOptions = this.options.content, + width = this.tooltip.css('width'), + visible = this.tooltip[0].offsetWidth > 0, + animate = state || opts.target.length === 1, + sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, + identicalState, allow, showEvent, delay; + + // Detect state if valid one isn't provided + if((typeof state).search('boolean|number')) { state = !visible; } + + // Check if the tooltip is in an identical state to the new would-be state + identicalState = !tooltip.is(':animated') && visible === state && sameTarget; + + // Fire tooltip(show/hide) event and check if destroyed + allow = !identicalState ? !!this._trigger(type, [90]) : NULL; + + // If the user didn't stop the method prematurely and we're showing the tooltip, focus it + if(allow !== FALSE && state) { this.focus(event); } + + // If the state hasn't changed or the user stopped it, return early + if(!allow || identicalState) { return this; } + + // Set ARIA hidden attribute + $.attr(tooltip[0], 'aria-hidden', !!!state); + + // Execute state specific properties + if(state) { + // Store show origin coordinates + cache.origin = $.extend({}, this.mouse); + + // Update tooltip content & title if it's a dynamic function + if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); } + if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); } + + // Cache mousemove events for positioning purposes (if not already tracking) + if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { + $(document).bind('mousemove.'+NAMESPACE, this._storeMouse); + trackingBound = TRUE; + } + + // Update the tooltip position (set width first to prevent viewport/max-width issues) + if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); } + this.reposition(event, arguments[2]); + if(!width) { tooltip.css('width', ''); } + + // Hide other tooltips if tooltip is solo + if(!!opts.solo) { + (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo)) + .not(tooltip).not(opts.target).qtip('hide', $.Event('tooltipsolo')); + } + } + else { + // Clear show timer if we're hiding + clearTimeout(this.timers.show); + + // Remove cached origin on hide + delete cache.origin; + + // Remove mouse tracking event if not needed (all tracking qTips are hidden) + if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { + $(document).unbind('mousemove.'+NAMESPACE); + trackingBound = FALSE; + } + + // Blur the tooltip + this.blur(event); + } + + // Define post-animation, state specific properties + after = $.proxy(function() { + if(state) { + // Prevent antialias from disappearing in IE by removing filter + if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); } + + // Remove overflow setting to prevent tip bugs + tooltip.css('overflow', ''); + + // Autofocus elements if enabled + if('string' === typeof opts.autofocus) { + $(this.options.show.autofocus, tooltip).focus(); + } + + // If set, hide tooltip when inactive for delay period + this.options.show.target.trigger('qtip-'+this.id+'-inactive'); + } + else { + // Reset CSS states + tooltip.css({ + display: '', + visibility: '', + opacity: '', + left: '', + top: '' + }); + } + + // tooltipvisible/tooltiphidden events + this._trigger(state ? 'visible' : 'hidden'); + }, this); + + // If no effect type is supplied, use a simple toggle + if(opts.effect === FALSE || animate === FALSE) { + tooltip[ type ](); + after(); + } + + // Use custom function if provided + else if($.isFunction(opts.effect)) { + tooltip.stop(1, 1); + opts.effect.call(tooltip, this); + tooltip.queue('fx', function(n) { + after(); n(); + }); + } + + // Use basic fade function by default + else { tooltip.fadeTo(90, state ? 1 : 0, after); } + + // If inactive hide method is set, active it + if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); } + + return this; +}; + +PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); }; + +PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); }; + +;PROTOTYPE.focus = function(event) { + if(!this.rendered || this.destroyed) { return this; } + + var qtips = $(SELECTOR), + tooltip = this.tooltip, + curIndex = parseInt(tooltip[0].style.zIndex, 10), + newIndex = QTIP.zindex + qtips.length, + focusedElem; + + // Only update the z-index if it has changed and tooltip is not already focused + if(!tooltip.hasClass(CLASS_FOCUS)) { + // tooltipfocus event + if(this._trigger('focus', [newIndex], event)) { + // Only update z-index's if they've changed + if(curIndex !== newIndex) { + // Reduce our z-index's and keep them properly ordered + qtips.each(function() { + if(this.style.zIndex > curIndex) { + this.style.zIndex = this.style.zIndex - 1; + } + }); + + // Fire blur event for focused tooltip + qtips.filter('.' + CLASS_FOCUS).qtip('blur', event); + } + + // Set the new z-index + tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; + } + } + + return this; +}; + +PROTOTYPE.blur = function(event) { + if(!this.rendered || this.destroyed) { return this; } + + // Set focused status to FALSE + this.tooltip.removeClass(CLASS_FOCUS); + + // tooltipblur event + this._trigger('blur', [ this.tooltip.css('zIndex') ], event); + + return this; +}; + +;PROTOTYPE.disable = function(state) { + if(this.destroyed) { return this; } + + if('boolean' !== typeof state) { + state = !(this.tooltip.hasClass(CLASS_DISABLED) || this.disabled); + } + + if(this.rendered) { + this.tooltip.toggleClass(CLASS_DISABLED, state) + .attr('aria-disabled', state); + } + + this.disabled = !!state; + + return this; +}; + +PROTOTYPE.enable = function() { return this.disable(FALSE); }; + +;PROTOTYPE._createButton = function() +{ + var self = this, + elements = this.elements, + tooltip = elements.tooltip, + button = this.options.content.button, + isString = typeof button === 'string', + close = isString ? button : 'Close tooltip'; + + if(elements.button) { elements.button.remove(); } + + // Use custom button if one was supplied by user, else use default + if(button.jquery) { + elements.button = button; + } + else { + elements.button = $('<a />', { + 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'), + 'title': close, + 'aria-label': close + }) + .prepend( + $('<span />', { + 'class': 'ui-icon ui-icon-close', + 'html': '×' + }) + ); + } + + // Create button and setup attributes + elements.button.appendTo(elements.titlebar || tooltip) + .attr('role', 'button') + .click(function(event) { + if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); } + return FALSE; + }); +}; + +PROTOTYPE._updateButton = function(button) +{ + // Make sure tooltip is rendered and if not, return + if(!this.rendered) { return FALSE; } + + var elem = this.elements.button; + if(button) { this._createButton(); } + else { elem.remove(); } +}; + +;// Widget class creator +function createWidgetClass(cls) { + return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' '); +} + +// Widget class setter method +PROTOTYPE._setWidget = function() +{ + var on = this.options.style.widget, + elements = this.elements, + tooltip = elements.tooltip, + disabled = tooltip.hasClass(CLASS_DISABLED); + + tooltip.removeClass(CLASS_DISABLED); + CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled'; + tooltip.toggleClass(CLASS_DISABLED, disabled); + + tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on); + + if(elements.content) { + elements.content.toggleClass( createWidgetClass('content'), on); + } + if(elements.titlebar) { + elements.titlebar.toggleClass( createWidgetClass('header'), on); + } + if(elements.button) { + elements.button.toggleClass(NAMESPACE+'-icon', !on); + } +};;function showMethod(event) { + if(this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; } + + // Clear hide timers + clearTimeout(this.timers.show); + clearTimeout(this.timers.hide); + + // Start show timer + var callback = $.proxy(function(){ this.toggle(TRUE, event); }, this); + if(this.options.show.delay > 0) { + this.timers.show = setTimeout(callback, this.options.show.delay); + } + else{ callback(); } +} + +function hideMethod(event) { + if(this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; } + + // Check if new target was actually the tooltip element + var relatedTarget = $(event.relatedTarget), + ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0], + ontoTarget = relatedTarget[0] === this.options.show.target[0]; + + // Clear timers and stop animation queue + clearTimeout(this.timers.show); + clearTimeout(this.timers.hide); + + // Prevent hiding if tooltip is fixed and event target is the tooltip. + // Or if mouse positioning is enabled and cursor momentarily overlaps + if(this !== relatedTarget[0] && + (this.options.position.target === 'mouse' && ontoTooltip) || + (this.options.hide.fixed && ( + (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)) + )) + { + try { + event.preventDefault(); + event.stopImmediatePropagation(); + } catch(e) {} + + return; + } + + // If tooltip has displayed, start hide timer + var callback = $.proxy(function(){ this.toggle(FALSE, event); }, this); + if(this.options.hide.delay > 0) { + this.timers.hide = setTimeout(callback, this.options.hide.delay); + } + else{ callback(); } +} + +function inactiveMethod(event) { + if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return FALSE; } + + // Clear timer + clearTimeout(this.timers.inactive); + this.timers.inactive = setTimeout( + $.proxy(function(){ this.hide(event); }, this), this.options.hide.inactive + ); +} + +function repositionMethod(event) { + if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } +} + +// Store mouse coordinates +PROTOTYPE._storeMouse = function(event) { + this.mouse = { + pageX: event.pageX, + pageY: event.pageY, + type: 'mousemove', + scrollX: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft, + scrollY: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop + }; +}; + +// Bind events +PROTOTYPE._bind = function(targets, events, method, suffix, context) { + var ns = '.' + this._id + (suffix ? '-'+suffix : ''); + events.length && $(targets).bind( + (events.split ? events : events.join(ns + ' ')) + ns, + $.proxy(method, context || this) + ); +}; +PROTOTYPE._unbind = function(targets, suffix) { + $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : '')); +}; + +// Apply common event handlers using delegate (avoids excessive .bind calls!) +var ns = '.'+NAMESPACE; +function delegate(selector, events, method) { + $(document.body).delegate(selector, + (events.split ? events : events.join(ns + ' ')) + ns, + function() { + var api = QTIP.api[ $.attr(this, ATTR_ID) ]; + api && !api.disabled && method.apply(api, arguments); + } + ); +} + +$(function() { + delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) { + var state = event.type === 'mouseenter', + tooltip = $(event.currentTarget), + target = $(event.relatedTarget || event.target), + options = this.options; + + // On mouseenter... + if(state) { + // Focus the tooltip on mouseenter (z-index stacking) + this.focus(event); + + // Clear hide timer on tooltip hover to prevent it from closing + tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide); + } + + // On mouseleave... + else { + // Hide when we leave the tooltip and not onto the show target (if a hide event is set) + if(options.position.target === 'mouse' && options.hide.event && + options.show.target && !target.closest(options.show.target[0]).length) { + this.hide(event); + } + } + + // Add hover class + tooltip.toggleClass(CLASS_HOVER, state); + }); + + // Define events which reset the 'inactive' event handler + delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod); +}); + +// Event trigger +PROTOTYPE._trigger = function(type, args, event) { + var callback = $.Event('tooltip'+type); + callback.originalEvent = (event && $.extend({}, event)) || this.cache.event || NULL; + + this.triggering = TRUE; + this.tooltip.trigger(callback, [this].concat(args || [])); + this.triggering = FALSE; + + return !callback.isDefaultPrevented(); +}; + +// Event assignment method +PROTOTYPE._assignEvents = function() { + var options = this.options, + posOptions = options.position, + + tooltip = this.tooltip, + showTarget = options.show.target, + hideTarget = options.hide.target, + containerTarget = posOptions.container, + viewportTarget = posOptions.viewport, + documentTarget = $(document), + bodyTarget = $(document.body), + windowTarget = $(window), + + showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], + hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [], + toggleEvents = []; + + // Hide tooltips when leaving current window/frame (but not select/option elements) + if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') { + this._bind(documentTarget, ['mouseout', 'blur'], function(event) { + if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { + this.hide(event); + } + }); + } + + // Enable hide.fixed by adding appropriate class + if(options.hide.fixed) { + hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) ); + } + + /* + * Make sure hoverIntent functions properly by using mouseleave to clear show timer if + * mouseenter/mouseout is used for show.event, even if it isn't in the users options. + */ + else if(/mouse(over|enter)/i.test(options.show.event)) { + this._bind(hideTarget, 'mouseleave', function() { + clearTimeout(this.timers.show); + }); + } + + // Hide tooltip on document mousedown if unfocus events are enabled + if(('' + options.hide.event).indexOf('unfocus') > -1) { + this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) { + var elem = $(event.target), + enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0, + isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0; + + if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor && + !this.target.has(elem[0]).length && enabled + ) { + this.hide(event); + } + }); + } + + // Check if the tooltip hides when inactive + if('number' === typeof options.hide.inactive) { + // Bind inactive method to show target(s) as a custom event + this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod); + + // Define events which reset the 'inactive' event handler + this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod, '-inactive'); + } + + // Apply hide events (and filter identical show events) + hideEvents = $.map(hideEvents, function(type) { + var showIndex = $.inArray(type, showEvents); + + // Both events and targets are identical, apply events using a toggle + if((showIndex > -1 && hideTarget.add(showTarget).length === hideTarget.length)) { + toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); return; + } + + return type; + }); + + // Apply show/hide/toggle events + this._bind(showTarget, showEvents, showMethod); + this._bind(hideTarget, hideEvents, hideMethod); + this._bind(showTarget, toggleEvents, function(event) { + (this.tooltip[0].offsetWidth > 0 ? hideMethod : showMethod).call(this, event); + }); + + + // Mouse movement bindings + this._bind(showTarget.add(tooltip), 'mousemove', function(event) { + // Check if the tooltip hides when mouse is moved a certain distance + if('number' === typeof options.hide.distance) { + var origin = this.cache.origin || {}, + limit = this.options.hide.distance, + abs = Math.abs; + + // Check if the movement has gone beyond the limit, and hide it if so + if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { + this.hide(event); + } + } + + // Cache mousemove coords on show targets + this._storeMouse(event); + }); + + // Mouse positioning events + if(posOptions.target === 'mouse') { + // If mouse adjustment is on... + if(posOptions.adjust.mouse) { + // Apply a mouseleave event so we don't get problems with overlapping + if(options.hide.event) { + // Track if we're on the target or not + this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) { + this.cache.onTarget = event.type === 'mouseenter'; + }); + } + + // Update tooltip position on mousemove + this._bind(documentTarget, 'mousemove', function(event) { + // Update the tooltip position only if the tooltip is visible and adjustment is enabled + if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) { + this.reposition(event); + } + }); + } + } + + // Adjust positions of the tooltip on window resize if enabled + if(posOptions.adjust.resize || viewportTarget.length) { + this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod ); + } + + // Adjust tooltip position on scroll of the window or viewport element if present + if(posOptions.adjust.scroll) { + this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod ); + } +}; + +// Un-assignment method +PROTOTYPE._unassignEvents = function() { + var targets = [ + this.options.show.target[0], + this.options.hide.target[0], + this.rendered && this.tooltip[0], + this.options.position.container[0], + this.options.position.viewport[0], + this.options.position.container.closest('html')[0], // unfocus + window, + document + ]; + + // Check if tooltip is rendered + if(this.rendered) { + this._unbind($([]).pushStack( $.grep(targets, function(i) { + return typeof i === 'object'; + }))); + } + + // Tooltip isn't yet rendered, remove render event + else { $(targets[0]).unbind('.'+this._id+'-create'); } +}; + +;// Initialization method +function init(elem, id, opts) +{ + var obj, posOptions, attr, config, title, + + // Setup element references + docBody = $(document.body), + + // Use document body instead of document element if needed + newTarget = elem[0] === document ? docBody : elem, + + // Grab metadata from element if plugin is present + metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL, + + // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise + metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, + + // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, + html5 = elem.data(opts.metadata.name || 'qtipopts'); + + // If we don't get an object returned attempt to parse it manualyl without parseJSON + try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {} + + // Merge in and sanitize metadata + config = $.extend(TRUE, {}, QTIP.defaults, opts, + typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, + sanitizeOptions(metadata5 || metadata)); + + // Re-grab our positioning options now we've merged our metadata and set id to passed value + posOptions = config.position; + config.id = id; + + // Setup missing content if none is detected + if('boolean' === typeof config.content.text) { + attr = elem.attr(config.content.attr); + + // Grab from supplied attribute if available + if(config.content.attr !== FALSE && attr) { config.content.text = attr; } + + // No valid content was found, abort render + else { return FALSE; } + } + + // Setup target options + if(!posOptions.container.length) { posOptions.container = docBody; } + if(posOptions.target === FALSE) { posOptions.target = newTarget; } + if(config.show.target === FALSE) { config.show.target = newTarget; } + if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } + if(config.hide.target === FALSE) { config.hide.target = newTarget; } + if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } + + // Ensure we only use a single container + posOptions.container = posOptions.container.eq(0); + + // Convert position corner values into x and y strings + posOptions.at = new CORNER(posOptions.at, TRUE); + posOptions.my = new CORNER(posOptions.my); + + // Destroy previous tooltip if overwrite is enabled, or skip element if not + if(elem.data(NAMESPACE)) { + if(config.overwrite) { + elem.qtip('destroy'); + } + else if(config.overwrite === FALSE) { + return FALSE; + } + } + + // Add has-qtip attribute + elem.attr(ATTR_HAS, id); + + // Remove title attribute and store it if present + if(config.suppress && (title = elem.attr('title'))) { + // Final attr call fixes event delegatiom and IE default tooltip showing problem + elem.removeAttr('title').attr(oldtitle, title).attr('title', ''); + } + + // Initialize the tooltip and add API reference + obj = new QTip(elem, config, id, !!attr); + elem.data(NAMESPACE, obj); + + // Catch remove/removeqtip events on target element to destroy redundant tooltip + elem.one('remove.qtip-'+id+' removeqtip.qtip-'+id, function() { + var api; if((api = $(this).data(NAMESPACE))) { api.destroy(); } + }); + + return obj; +} + +// jQuery $.fn extension method +QTIP = $.fn.qtip = function(options, notation, newValue) +{ + var command = ('' + options).toLowerCase(), // Parse command + returned = NULL, + args = $.makeArray(arguments).slice(1), + event = args[args.length - 1], + opts = this[0] ? $.data(this[0], NAMESPACE) : NULL; + + // Check for API request + if((!arguments.length && opts) || command === 'api') { + return opts; + } + + // Execute API command if present + else if('string' === typeof options) + { + this.each(function() + { + var api = $.data(this, NAMESPACE); + if(!api) { return TRUE; } + + // Cache the event if possible + if(event && event.timeStamp) { api.cache.event = event; } + + // Check for specific API commands + if(notation && (command === 'option' || command === 'options')) { + if(newValue !== undefined || $.isPlainObject(notation)) { + api.set(notation, newValue); + } + else { + returned = api.get(notation); + return FALSE; + } + } + + // Execute API command + else if(api[command]) { + api[command].apply(api, args); + } + }); + + return returned !== NULL ? returned : this; + } + + // No API commands. validate provided options and setup qTips + else if('object' === typeof options || !arguments.length) + { + opts = sanitizeOptions($.extend(TRUE, {}, options)); + + // Bind the qTips + return QTIP.bind.call(this, opts, event); + } +}; + +// $.fn.qtip Bind method +QTIP.bind = function(opts, event) +{ + return this.each(function(i) { + var options, targets, events, namespace, api, id; + + // Find next available ID, or use custom ID if provided + id = $.isArray(opts.id) ? opts.id[i] : opts.id; + id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id; + + // Setup events namespace + namespace = '.qtip-'+id+'-create'; + + // Initialize the qTip and re-grab newly sanitized options + api = init($(this), id, opts); + if(api === FALSE) { return TRUE; } + else { QTIP.api[id] = api; } + options = api.options; + + // Initialize plugins + $.each(PLUGINS, function() { + if(this.initialize === 'initialize') { this(api); } + }); + + // Determine hide and show targets + targets = { show: options.show.target, hide: options.hide.target }; + events = { + show: $.trim('' + options.show.event).replace(/ /g, namespace+' ') + namespace, + hide: $.trim('' + options.hide.event).replace(/ /g, namespace+' ') + namespace + }; + + /* + * Make sure hoverIntent functions properly by using mouseleave as a hide event if + * mouseenter/mouseout is used for show.event, even if it isn't in the users options. + */ + if(/mouse(over|enter)/i.test(events.show) && !/mouse(out|leave)/i.test(events.hide)) { + events.hide += ' mouseleave' + namespace; + } + + /* + * Also make sure initial mouse targetting works correctly by caching mousemove coords + * on show targets before the tooltip has rendered. + * + * Also set onTarget when triggered to keep mouse tracking working + */ + targets.show.bind('mousemove'+namespace, function(event) { + api._storeMouse(event); + api.cache.onTarget = TRUE; + }); + + // Define hoverIntent function + function hoverIntent(event) { + function render() { + // Cache mouse coords,render and render the tooltip + api.render(typeof event === 'object' || options.show.ready); + + // Unbind show and hide events + targets.show.add(targets.hide).unbind(namespace); + } + + // Only continue if tooltip isn't disabled + if(api.disabled) { return FALSE; } + + // Cache the event data + api.cache.event = $.extend({}, event); + api.cache.target = event ? $(event.target) : [undefined]; + + // Start the event sequence + if(options.show.delay > 0) { + clearTimeout(api.timers.show); + api.timers.show = setTimeout(render, options.show.delay); + if(events.show !== events.hide) { + targets.hide.bind(events.hide, function() { clearTimeout(api.timers.show); }); + } + } + else { render(); } + } + + // Bind show events to target + targets.show.bind(events.show, hoverIntent); + + // Prerendering is enabled, create tooltip now + if(options.show.ready || options.prerender) { hoverIntent(event); } + }); +}; + +// Populated in render method +QTIP.api = {}; +;$.each({ + /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ + attr: function(attr, val) { + if(this.length) { + var self = this[0], + title = 'title', + api = $.data(self, 'qtip'); + + if(attr === title && api && 'object' === typeof api && api.options.suppress) { + if(arguments.length < 2) { + return $.attr(self, oldtitle); + } + + // If qTip is rendered and title was originally used as content, update it + if(api && api.options.content.attr === title && api.cache.attr) { + api.set('content.text', val); + } + + // Use the regular attr method to set, then cache the result + return this.attr(oldtitle, val); + } + } + + return $.fn['attr'+replaceSuffix].apply(this, arguments); + }, + + /* Allow clone to correctly retrieve cached title attributes */ + clone: function(keepData) { + var titles = $([]), title = 'title', + + // Clone our element using the real clone method + elems = $.fn['clone'+replaceSuffix].apply(this, arguments); + + // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false + if(!keepData) { + elems.filter('['+oldtitle+']').attr('title', function() { + return $.attr(this, oldtitle); + }) + .removeAttr(oldtitle); + } + + return elems; + } +}, function(name, func) { + if(!func || $.fn[name+replaceSuffix]) { return TRUE; } + + var old = $.fn[name+replaceSuffix] = $.fn[name]; + $.fn[name] = function() { + return func.apply(this, arguments) || old.apply(this, arguments); + }; +}); + +/* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). + * This snippet is taken directly from jQuery UI source code found here: + * http://code.jquery.com/ui/jquery-ui-git.js + */ +if(!$.ui) { + $['cleanData'+replaceSuffix] = $.cleanData; + $.cleanData = function( elems ) { + for(var i = 0, elem; (elem = $( elems[i] )).length; i++) { + if(elem.attr(ATTR_HAS)) { + try { elem.triggerHandler('removeqtip'); } + catch( e ) {} + } + } + $['cleanData'+replaceSuffix].apply(this, arguments); + }; +} + +;// qTip version +QTIP.version = '2.1.1'; + +// Base ID for all qTips +QTIP.nextid = 0; + +// Inactive events array +QTIP.inactiveEvents = INACTIVE_EVENTS; + +// Base z-index for all qTips +QTIP.zindex = 15000; + +// Define configuration defaults +QTIP.defaults = { + prerender: FALSE, + id: FALSE, + overwrite: TRUE, + suppress: TRUE, + content: { + text: TRUE, + attr: 'title', + title: FALSE, + button: FALSE + }, + position: { + my: 'top left', + at: 'bottom right', + target: FALSE, + container: FALSE, + viewport: FALSE, + adjust: { + x: 0, y: 0, + mouse: TRUE, + scroll: TRUE, + resize: TRUE, + method: 'flipinvert flipinvert' + }, + effect: function(api, pos, viewport) { + $(this).animate(pos, { + duration: 200, + queue: FALSE + }); + } + }, + show: { + target: FALSE, + event: 'mouseenter', + effect: TRUE, + delay: 90, + solo: FALSE, + ready: FALSE, + autofocus: FALSE + }, + hide: { + target: FALSE, + event: 'mouseleave', + effect: TRUE, + delay: 0, + fixed: FALSE, + inactive: FALSE, + leave: 'window', + distance: FALSE + }, + style: { + classes: '', + widget: FALSE, + width: FALSE, + height: FALSE, + def: TRUE + }, + events: { + render: NULL, + move: NULL, + show: NULL, + hide: NULL, + toggle: NULL, + visible: NULL, + hidden: NULL, + focus: NULL, + blur: NULL + } +}; + +;var TIP, + +// .bind()/.on() namespace +TIPNS = '.qtip-tip', + +// Common CSS strings +MARGIN = 'margin', +BORDER = 'border', +COLOR = 'color', +BG_COLOR = 'background-color', +TRANSPARENT = 'transparent', +IMPORTANT = ' !important', + +// Check if the browser supports <canvas/> elements +HASCANVAS = !!document.createElement('canvas').getContext, + +// Invalid colour values used in parseColours() +INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i; + +// Camel-case method, taken from jQuery source +// http://code.jquery.com/jquery-1.8.0.js +function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); } + +/* + * Modified from Modernizr's testPropsAll() + * http://modernizr.com/downloads/modernizr-latest.js + */ +var cssProps = {}, cssPrefixes = ["Webkit", "O", "Moz", "ms"]; +function vendorCss(elem, prop) { + var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), + props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '), + cur, val, i = 0; + + // If the property has already been mapped... + if(cssProps[prop]) { return elem.css(cssProps[prop]); } + + while((cur = props[i++])) { + if((val = elem.css(cur)) !== undefined) { + return cssProps[prop] = cur, val; + } + } +} + +// Parse a given elements CSS property into an int +function intCss(elem, prop) { + return parseInt(vendorCss(elem, prop), 10); +} + + +// VML creation (for IE only) +if(!HASCANVAS) { + createVML = function(tag, props, style) { + return '<qtipvml:'+tag+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(props||'')+ + ' style="behavior: url(#default#VML); '+(style||'')+ '" />'; + }; +} + + + +function Tip(qtip, options) { + this._ns = 'tip'; + this.options = options; + this.offset = options.offset; + this.size = [ options.width, options.height ]; + + // Initialize + this.init( (this.qtip = qtip) ); +} + +$.extend(Tip.prototype, { + init: function(qtip) { + var context, tip; + + // Create tip element and prepend to the tooltip + tip = this.element = qtip.elements.tip = $('<div />', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip); + + // Create tip drawing element(s) + if(HASCANVAS) { + // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()! + context = $('<canvas />').appendTo(this.element)[0].getContext('2d'); + + // Setup constant parameters + context.lineJoin = 'miter'; + context.miterLimit = 100; + context.save(); + } + else { + context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;'); + this.element.html(context + context); + + // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML + qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns); + } + + // Bind update events + qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this); + + // Create it + this.create(); + }, + + _swapDimensions: function() { + this.size[0] = this.options.height; + this.size[1] = this.options.width; + }, + _resetDimensions: function() { + this.size[0] = this.options.width; + this.size[1] = this.options.height; + }, + + _useTitle: function(corner) { + var titlebar = this.qtip.elements.titlebar; + return titlebar && ( + corner.y === TOP || (corner.y === CENTER && this.element.position().top + (this.size[1] / 2) + this.options.offset < titlebar.outerHeight(TRUE)) + ); + }, + + _parseCorner: function(corner) { + var my = this.qtip.options.position.my; + + // Detect corner and mimic properties + if(corner === FALSE || my === FALSE) { + corner = FALSE; + } + else if(corner === TRUE) { + corner = new CORNER( my.string() ); + } + else if(!corner.string) { + corner = new CORNER(corner); + corner.fixed = TRUE; + } + + return corner; + }, + + _parseWidth: function(corner, side, use) { + var elements = this.qtip.elements, + prop = BORDER + camel(side) + 'Width'; + + return (use ? intCss(use, prop) : ( + intCss(elements.content, prop) || + intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || + intCss(tooltip, prop) + )) || 0; + }, + + _parseRadius: function(corner) { + var elements = this.qtip.elements, + prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius'; + + return BROWSER.ie < 9 ? 0 : + intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || + intCss(elements.tooltip, prop) || 0; + }, + + _invalidColour: function(elem, prop, compare) { + var val = elem.css(prop); + return !val || (compare && val === elem.css(compare)) || INVALID.test(val) ? FALSE : val; + }, + + _parseColours: function(corner) { + var elements = this.qtip.elements, + tip = this.element.css('cssText', ''), + borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR), + colorElem = this._useTitle(corner) && elements.titlebar || elements.content, + css = this._invalidColour, color = []; + + // Attempt to detect the background colour from various elements, left-to-right precedance + color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) || + css(tooltip, BG_COLOR) || tip.css(BG_COLOR); + + // Attempt to detect the correct border side colour from various elements, left-to-right precedance + color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) || + css(elements.content, borderSide, COLOR) || css(tooltip, borderSide, COLOR) || tooltip.css(borderSide); + + // Reset background and border colours + $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';'); + + return color; + }, + + _calculateSize: function(corner) { + var y = corner.precedance === Y, + width = this.options[ y ? 'height' : 'width' ], + height = this.options[ y ? 'width' : 'height' ], + isCenter = corner.abbrev() === 'c', + base = width * (isCenter ? 0.5 : 1), + pow = Math.pow, + round = Math.round, + bigHyp, ratio, result, + + smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ), + hyp = [ (this.border / base) * smallHyp, (this.border / height) * smallHyp ]; + + hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) ); + hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) ); + + bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]); + ratio = bigHyp / smallHyp; + + result = [ round(ratio * width), round(ratio * height) ]; + + return y ? result : result.reverse(); + }, + + // Tip coordinates calculator + _calculateTip: function(corner) { + var width = this.size[0], height = this.size[1], + width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2), + + // Define tip coordinates in terms of height and width values + tips = { + br: [0,0, width,height, width,0], + bl: [0,0, width,0, 0,height], + tr: [0,height, width,0, width,height], + tl: [0,0, 0,height, width,height], + tc: [0,height, width2,0, width,height], + bc: [0,0, width,0, width2,height], + rc: [0,0, width,height2, 0,height], + lc: [width,0, width,height, 0,height2] + }; + + // Set common side shapes + tips.lt = tips.br; tips.rt = tips.bl; + tips.lb = tips.tr; tips.rb = tips.tl; + + return tips[ corner.abbrev() ]; + }, + + create: function() { + // Determine tip corner + var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner); + + // If we have a tip corner... + if( (this.enabled = !!this.corner && this.corner.abbrev() !== 'c') ) { + // Cache it + this.qtip.cache.corner = c.clone(); + + // Create it + this.update(); + } + + // Toggle tip element + this.element.toggle(this.enabled); + + return this.corner; + }, + + update: function(corner, position) { + if(!this.enabled) { return this; } + + var elements = this.qtip.elements, + tip = this.element, + inner = tip.children(), + options = this.options, + size = this.size, + mimic = options.mimic, + round = Math.round, + color, precedance, context, + coords, translate, newSize, border; + + // Re-determine tip if not already set + if(!corner) { corner = this.qtip.cache.corner || this.corner; } + + // Use corner property if we detect an invalid mimic value + if(mimic === FALSE) { mimic = corner; } + + // Otherwise inherit mimic properties from the corner object as necessary + else { + mimic = new CORNER(mimic); + mimic.precedance = corner.precedance; + + if(mimic.x === 'inherit') { mimic.x = corner.x; } + else if(mimic.y === 'inherit') { mimic.y = corner.y; } + else if(mimic.x === mimic.y) { + mimic[ corner.precedance ] = corner[ corner.precedance ]; + } + } + precedance = mimic.precedance; + + // Ensure the tip width.height are relative to the tip position + if(corner.precedance === X) { this._swapDimensions(); } + else { this._resetDimensions(); } + + // Update our colours + color = this.color = this._parseColours(corner); + + // Detect border width, taking into account colours + if(color[1] !== TRANSPARENT) { + // Grab border width + border = this.border = this._parseWidth(corner, corner[corner.precedance]); + + // If border width isn't zero, use border color as fill (1.0 style tips) + if(options.border && border < 1) { color[0] = color[1]; } + + // Set border width (use detected border width if options.border is true) + this.border = border = options.border !== TRUE ? options.border : border; + } + + // Border colour was invalid, set border to zero + else { this.border = border = 0; } + + // Calculate coordinates + coords = this._calculateTip(mimic); + + // Determine tip size + newSize = this.size = this._calculateSize(corner); + tip.css({ + width: newSize[0], + height: newSize[1], + lineHeight: newSize[1]+'px' + }); + + // Calculate tip translation + if(corner.precedance === Y) { + translate = [ + round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - size[0] - border : (newSize[0] - size[0]) / 2), + round(mimic.y === TOP ? newSize[1] - size[1] : 0) + ]; + } + else { + translate = [ + round(mimic.x === LEFT ? newSize[0] - size[0] : 0), + round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - size[1] - border : (newSize[1] - size[1]) / 2) + ]; + } + + // Canvas drawing implementation + if(HASCANVAS) { + // Set the canvas size using calculated size + inner.attr(WIDTH, newSize[0]).attr(HEIGHT, newSize[1]); + + // Grab canvas context and clear/save it + context = inner[0].getContext('2d'); + context.restore(); context.save(); + context.clearRect(0,0,3000,3000); + + // Set properties + context.fillStyle = color[0]; + context.strokeStyle = color[1]; + context.lineWidth = border * 2; + + // Draw the tip + context.translate(translate[0], translate[1]); + context.beginPath(); + context.moveTo(coords[0], coords[1]); + context.lineTo(coords[2], coords[3]); + context.lineTo(coords[4], coords[5]); + context.closePath(); + + // Apply fill and border + if(border) { + // Make sure transparent borders are supported by doing a stroke + // of the background colour before the stroke colour + if(tooltip.css('background-clip') === 'border-box') { + context.strokeStyle = color[0]; + context.stroke(); + } + context.strokeStyle = color[1]; + context.stroke(); + } + context.fill(); + } + + // VML (IE Proprietary implementation) + else { + // Setup coordinates string + coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] + + ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe'; + + // Setup VML-specific offset for pixel-perfection + translate[2] = border && /^(r|b)/i.test(corner.string()) ? + BROWSER.ie === 8 ? 2 : 1 : 0; + + // Set initial CSS + inner.css({ + coordsize: (size[0]+border) + ' ' + (size[1]+border), + antialias: ''+(mimic.string().indexOf(CENTER) > -1), + left: translate[0] - (translate[2] * Number(precedance === X)), + top: translate[1] - (translate[2] * Number(precedance === Y)), + width: size[0] + border, + height: size[1] + border + }) + .each(function(i) { + var $this = $(this); + + // Set shape specific attributes + $this[ $this.prop ? 'prop' : 'attr' ]({ + coordsize: (size[0]+border) + ' ' + (size[1]+border), + path: coords, + fillcolor: color[0], + filled: !!i, + stroked: !i + }) + .toggle(!!(border || i)); + + // Check if border is enabled and add stroke element + !i && $this.html( createVML( + 'stroke', 'weight="'+(border*2)+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"' + ) ); + }); + } + + // Position if needed + if(position !== FALSE) { this.calculate(corner); } + }, + + calculate: function(corner) { + if(!this.enabled) { return FALSE; } + + var self = this, + elements = this.qtip.elements, + tip = this.element, + userOffset = this.options.offset, + isWidget = this.qtip.tooltip.hasClass('ui-widget'), + position = { }, + precedance, size, corners; + + // Inherit corner if not provided + corner = corner || this.corner; + precedance = corner.precedance; + + // Determine which tip dimension to use for adjustment + size = this._calculateSize(corner); + + // Setup corners and offset array + corners = [ corner.x, corner.y ]; + if(precedance === X) { corners.reverse(); } + + // Calculate tip position + $.each(corners, function(i, side) { + var b, bc, br; + + if(side === CENTER) { + b = precedance === Y ? LEFT : TOP; + position[ b ] = '50%'; + position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset; + } + else { + b = self._parseWidth(corner, side, elements.tooltip); + bc = self._parseWidth(corner, side, elements.content); + br = self._parseRadius(corner); + + position[ side ] = Math.max(-self.border, i ? bc : (userOffset + (br > b ? br : -b))); + } + }); + + // Adjust for tip size + position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ]; + + // Set and return new position + tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position); + return position; + }, + + reposition: function(event, api, pos, viewport) { + if(!this.enabled) { return; } + + var cache = api.cache, + newCorner = this.corner.clone(), + adjust = pos.adjusted, + method = api.options.position.adjust.method.split(' '), + horizontal = method[0], + vertical = method[1] || method[0], + shift = { left: FALSE, top: FALSE, x: 0, y: 0 }, + offset, css = {}, props; + + // If our tip position isn't fixed e.g. doesn't adjust with viewport... + if(this.corner.fixed !== TRUE) { + // Horizontal - Shift or flip method + if(horizontal === SHIFT && newCorner.precedance === X && adjust.left && newCorner.y !== CENTER) { + newCorner.precedance = newCorner.precedance === X ? Y : X; + } + else if(horizontal !== SHIFT && adjust.left){ + newCorner.x = newCorner.x === CENTER ? (adjust.left > 0 ? LEFT : RIGHT) : (newCorner.x === LEFT ? RIGHT : LEFT); + } + + // Vertical - Shift or flip method + if(vertical === SHIFT && newCorner.precedance === Y && adjust.top && newCorner.x !== CENTER) { + newCorner.precedance = newCorner.precedance === Y ? X : Y; + } + else if(vertical !== SHIFT && adjust.top) { + newCorner.y = newCorner.y === CENTER ? (adjust.top > 0 ? TOP : BOTTOM) : (newCorner.y === TOP ? BOTTOM : TOP); + } + + // Update and redraw the tip if needed (check cached details of last drawn tip) + if(newCorner.string() !== cache.corner.string() && (cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left)) { + this.update(newCorner, FALSE); + } + } + + // Setup tip offset properties + offset = this.calculate(newCorner, adjust); + + // Readjust offset object to make it left/top + if(offset.right !== undefined) { offset.left = -offset.right; } + if(offset.bottom !== undefined) { offset.top = -offset.bottom; } + offset.user = this.offset; + + // Viewport "shift" specific adjustments + if(shift.left = (horizontal === SHIFT && !!adjust.left)) { + if(newCorner.x === CENTER) { + css[MARGIN+'-left'] = shift.x = offset[MARGIN+'-left'] - adjust.left; + } + else { + props = offset.right !== undefined ? + [ adjust.left, -offset.left ] : [ -adjust.left, offset.left ]; + + if( (shift.x = Math.max(props[0], props[1])) > props[0] ) { + pos.left -= adjust.left; + shift.left = FALSE; + } + + css[ offset.right !== undefined ? RIGHT : LEFT ] = shift.x; + } + } + if(shift.top = (vertical === SHIFT && !!adjust.top)) { + if(newCorner.y === CENTER) { + css[MARGIN+'-top'] = shift.y = offset[MARGIN+'-top'] - adjust.top; + } + else { + props = offset.bottom !== undefined ? + [ adjust.top, -offset.top ] : [ -adjust.top, offset.top ]; + + if( (shift.y = Math.max(props[0], props[1])) > props[0] ) { + pos.top -= adjust.top; + shift.top = FALSE; + } + + css[ offset.bottom !== undefined ? BOTTOM : TOP ] = shift.y; + } + } + + /* + * If the tip is adjusted in both dimensions, or in a + * direction that would cause it to be anywhere but the + * outer border, hide it! + */ + this.element.css(css).toggle( + !((shift.x && shift.y) || (newCorner.x === CENTER && shift.y) || (newCorner.y === CENTER && shift.x)) + ); + + // Adjust position to accomodate tip dimensions + pos.left -= offset.left.charAt ? offset.user : horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left : 0; + pos.top -= offset.top.charAt ? offset.user : vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top : 0; + + // Cache details + cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top; + cache.corner = newCorner.clone(); + }, + + destroy: function() { + // Unbind events + this.qtip._unbind(this.qtip.tooltip, this._ns); + + // Remove the tip element(s) + if(this.qtip.elements.tip) { + this.qtip.elements.tip.find('*') + .remove().end().remove(); + } + } +}); + +TIP = PLUGINS.tip = function(api) { + return new Tip(api, api.options.style.tip); +}; + +// Initialize tip on render +TIP.initialize = 'render'; + +// Setup plugin sanitization options +TIP.sanitize = function(options) { + if(options.style && 'tip' in options.style) { + opts = options.style.tip; + if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; } + if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; } + } +}; + +// Add new option checks for the plugin +CHECKS.tip = { + '^position.my|style.tip.(corner|mimic|border)$': function() { + // Make sure a tip can be drawn + this.create(); + + // Reposition the tooltip + this.qtip.reposition(); + }, + '^style.tip.(height|width)$': function(obj) { + // Re-set dimensions and redraw the tip + this.size = size = [ obj.width, obj.height ]; + this.update(); + + // Reposition the tooltip + this.qtip.reposition(); + }, + '^content.title|style.(classes|widget)$': function() { + this.update(); + } +}; + +// Extend original qTip defaults +$.extend(TRUE, QTIP.defaults, { + style: { + tip: { + corner: TRUE, + mimic: FALSE, + width: 6, + height: 6, + border: TRUE, + offset: 0 + } + } +}); + +;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight) +{ + var target = posOptions.target, + tooltip = api.elements.tooltip, + my = posOptions.my, + at = posOptions.at, + adjust = posOptions.adjust, + method = adjust.method.split(' '), + methodX = method[0], + methodY = method[1] || method[0], + viewport = posOptions.viewport, + container = posOptions.container, + cache = api.cache, + tip = api.plugins.tip, + adjusted = { left: 0, top: 0 }, + fixed, newMy, newClass; + + // If viewport is not a jQuery element, or it's the window/document or no adjustment method is used... return + if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') { + return adjusted; + } + + // Cache our viewport details + fixed = tooltip.css('position') === 'fixed'; + viewport = { + elem: viewport, + width: viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE), + height: viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE), + scrollleft: fixed ? 0 : viewport.scrollLeft(), + scrolltop: fixed ? 0 : viewport.scrollTop(), + offset: viewport.offset() || { left: 0, top: 0 } + }; + container = { + elem: container, + scrollLeft: container.scrollLeft(), + scrollTop: container.scrollTop(), + offset: container.offset() || { left: 0, top: 0 } + }; + + // Generic calculation method + function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) { + var initialPos = position[side1], + mySide = my[side], atSide = at[side], + isShift = type === SHIFT, + viewportScroll = -container.offset[side1] + viewport.offset[side1] + viewport['scroll'+side1], + myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2, + atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2, + tipLength = tip && tip.size ? tip.size[lengthName] || 0 : 0, + tipAdjust = tip && tip.corner && tip.corner.precedance === side && !isShift ? tipLength : 0, + overflow1 = viewportScroll - initialPos + tipAdjust, + overflow2 = initialPos + elemLength - viewport[lengthName] - viewportScroll + tipAdjust, + offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0); + + // shift + if(isShift) { + tipAdjust = tip && tip.corner && tip.corner.precedance === otherSide ? tipLength : 0; + offset = (mySide === side1 ? 1 : -1) * myLength - tipAdjust; + + // Adjust position but keep it within viewport dimensions + position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0; + position[side1] = Math.max( + -container.offset[side1] + viewport.offset[side1] + (tipAdjust && tip.corner[side] === CENTER ? tip.offset : 0), + initialPos - offset, + Math.min( + Math.max(-container.offset[side1] + viewport.offset[side1] + viewport[lengthName], initialPos + offset), + position[side1] + ) + ); + } + + // flip/flipinvert + else { + // Update adjustment amount depending on if using flipinvert or flip + adjust *= (type === FLIPINVERT ? 2 : 0); + + // Check for overflow on the left/top + if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) { + position[side1] -= offset + adjust; + newMy.invert(side, side1); + } + + // Check for overflow on the bottom/right + else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) { + position[side1] -= (mySide === CENTER ? -offset : offset) + adjust; + newMy.invert(side, side2); + } + + // Make sure we haven't made things worse with the adjustment and reset if so + if(position[side1] < viewportScroll && -position[side1] > overflow2) { + position[side1] = initialPos; newMy = my.clone(); + } + } + + return position[side1] - initialPos; + } + + // Set newMy if using flip or flipinvert methods + if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); } + + // Adjust position based onviewport and adjustment options + adjusted = { + left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0, + top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0 + }; + + // Set tooltip position class if it's changed + if(newMy && cache.lastClass !== (newClass = NAMESPACE + '-pos-' + newMy.abbrev())) { + tooltip.removeClass(api.cache.lastClass).addClass( (api.cache.lastClass = newClass) ); + } + + return adjusted; +};;})); +}( window, document )); + + diff --git a/contrib/libxo/xohtml/xohtml.css b/contrib/libxo/xohtml/xohtml.css new file mode 100644 index 0000000..655bf12 --- /dev/null +++ b/contrib/libxo/xohtml/xohtml.css @@ -0,0 +1,1016 @@ +/* + * $Id$ + * + * Copyright 2000, All rights reserved + * See ../Copyright for more information + */ + +#content-wrapper { + margin: 0 4px; +} + +#target-history .empty { + color: #d0d0d0; + text-align:center; +} + +#command-history .empty { + color: grey; + padding-left: 20px; +} + +#prefs { + font-size: 70%; +} + +div[data-key] { + color: red; +} + +div.decoration, div.default, div.header-line { + color: #505050; + font-family: monospace; + white-space: pre-wrap; +} + +div.line:first-child { + padding-top: 10px; +} + +div.padding { + white-space: pre-wrap; + font-family: monospace; + display: inline; +} + +div.label, div.note, div.text { + font-family: monospace; + white-space: pre-wrap; + display: inline; + vertical-align: middle; +/* + * font-weight: bold; + * color: #606060; + */ +} + +div.blank-line { + padding-top: 40px; +} + +div.title { + border-bottom: 2px solid black; + border-top: 2px solid #f0f0ff; + border-radius: 3px; + margin-top: 10px; + color: #1010a0; + background-color: #e0e0ff; + font-family: monospace; + display: inline; + vertical-align: middle; + white-space: pre-wrap; +} + +div.data { + font-family: monospace; +} + +div.line { + display: block; +} + +div.indented { + display: inline; +} + +div.indent { + display: inline; +} + +/* BEGIN LINES */ +div.line { + border: none; +} + +div.item { + border: none; +} + +div.pad { + border: none; +} + +div.blank-line { + border: 1px inset; +} + +div.item { + white-space: pre; +} +/* END LINES */ + +div.muxer-prompt { + padding: 2em; +} + +div.muxer-message, div.muxer-prompt form { + white-space: pre; + display: inline-block; + vertical-align: middle; +} + +div.muxer-buttons { + display: inline-block; + padding: 20px; +} + +div.text, div.decoration, div.data, div.header, div.pad, div.item { + font-family: monospace; + display: inline; + vertical-align: middle; + white-space: pre-wrap; +} + +div.blank-line { + margin: 5px; +} + +div.indentxxx { + padding-left: 2em; +} + +div.output, configuration-output, configuration-information { + font-family: monospace; + white-space: pre-wrap; +} + +div.header-line { + color: #ffffff; + background: none repeat scroll 0 0 #0D5995; + margin-top: 4px; + padding-top: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +div.header-line-empty { + color: #ffffff; + background: none repeat scroll 0 0 #0D5995; + padding-top: 4px; + padding-bottom: 2px; +} + + +/* + * juise rendering + */ + +div.hidden, +img.hidden, +button.hidden { + display: none; +} + +div.keeper-active div.icon-box img.keeper { + border: 1px solid #966535; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} + +div.icon-box img.keeper { + border: 1px solid #ffffff; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} + +div#debug-container { + background-color: #ccc; + border: 1px solid #d0d0ff; + bottom: 0; + color: blue; + display: none; + font-size: 70%; + position: fixed; + width: 100%; +} + +div#debug-log { + background-color: #ffffff; + max-height: 200px; + overflow-y: auto; + padding: 0 5px; + white-space: pre-wrap; +} + +div#header { + height: 30px; + padding: 0px 0px 40px 30px ; +} + +div#header-logo { + display: inline-block; + background: url(/images/logo.png) no-repeat; + height: 60px; + width: 150px; +} + +div#header-info { + display: table-cell; + height: 60px; + width: 60%; + background-color: #ffffff; + font-size: 80%; + padding-left: 10px; +} + +.prefsbtn { + background: rgb(230, 230, 230) url(/images/gear.png) no-repeat center; + margin-top: 5px; + min-height: 40px; + width: 40px; + border-radius: 2px; + cursor: pointer; + float: right; + box-shadow: 0 1px 1px #fff, + 0 -1px 1px #666, + inset 0 -1px 1px rgba(0,0,0,0.5), + inset 0 1px 1px rgba(255,255,255,0.8); +} + +.prefsbtn:hover { + background-color: #dde; +} + +div#header-actions { + height: 60px; + width: 200px; + display: table-cell; + padding-left: 10px; +} + +xdiv#header-actions div, +xdiv#header-info div { + display: inline-block; +} + +div#target-list { + display: none; + clear: both; +} + +div#target-title { + display: table-cell; + padding: 6px 1px 6px 0px; +} + +div#target-history { + border: 1px solid #659635; + position: absolute; + width: 25%; + padding-left: 0px; + padding-right: 0px; +} + +form#target-history-form { + margin-bottom: 0px; +} + +input#target-history-submit { + background: url(none); + margin-left: 2px; +} + +div.target-history-name { + display: inline-block; +} + +div.target-history-entry-parent:hover { + background: #659635; +} + +div.target-history-entry-parent:first-child { + border-top: 0px none; +} + +div.target-history-entry-parent { + border-top: 1px solid #659635; + padding-left: 8px; + padding-right: 8px; +} +div.target-history-entry { + display: inline-block; +} + +div.target-info { + display: inline-block; + font-family: Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: 12px; + margin-right: 10px; + margin-left: 10px; + padding: 5px 10px 5px 10px; +} + +div#target-contents, +div#target-contents-none { + display: table-cell; + font-family: Verdana, Arial, Helvetica, sans-serif ; +} + +div#target-contents-none { + padding-left: 10px; + font-size: 70%; +} + +div.target { + display: inline-block; + margin-left: 2px; + margin-right: 2px; +} + +div#command-history { + border: 1px solid #c0c0ff; + position: absolute; + width: 60em; + font-family: Verdana, Arial, Helvetica, sans-serif ; + font-family: monospace; + font-size: 12px; + background: #e0e0ff; + padding-left: 0px; + padding-right: 0px; +} + +div.command-history-entry:hover { + background: #c0c0ff; +} + +div.command-history-entry:first-child { + border-top: 0px none; +} + +div.command-history-entry { + border-top: 1px solid #c0c0ff; + padding-left: 8px; + padding-right: 8px; +} + +div#footer { + padding-top: 100px; + clear: both; + display: block; + height: 100px; + width: 100%; + font-size: 8; + text-align: center; +} + +div#input-history { + display: inline-block; + float: left; + margin-right: 5px; + position: relative; + width: 70%; +} + +div#input-top { + display: block; + height: 70px; + padding: 10px; + margin-bottom: 10px; + background-color: rgb(245, 245, 245); + border-bottom: rgb(200, 200, 200) solid 1px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); +} + +div#input-history .pulldown { + border: solid 1px rgb(180, 180, 200); + max-height: 300px; + overflow-y: auto; + padding: 0px; + width: 100%; +} + +div#mru-pulldown { + margin-top: 40px; + position: absolute; + width: 100%; + z-index: 9999; +} + +div#mru-pulldown .mru-item { + padding: 5px; +} + +div#mru-pulldown .mru-item:hover { + background: rgb(242, 244, 255); + cursor: pointer; + font-weight: 700; +} + +div#recent-devices { + margin-top: 10px; +} + +div#recent-devices a { + color: rgb(0, 50, 112); + cursor: pointer; + text-decoration: underline; +} + +div#input-top .logo { + float: left; + margin: 0px 10px 0px 10px; +} + +form#target-input-form, +form#command-input-form { + display: inline-block; +} + +div#target-top, +div#command-top { + display: inline-block; + float: left; + margin: 10px 5px 0px 0px; + width: 100%; +} + +div#command-top .input-box { + height: 32px; + min-width: 500px; + padding: 1px; + background-color: #fff; + width: 100%; +} + +div#command-top .focus-off { + border: solid 1px rgb(180, 180, 200); +} + +div#command-top .focus-on { + border: solid 1px rgb(180, 180, 200); + box-shadow: 0px 0px 8px rgba(100, 100, 200, 0.5); +} + +div#input-top .input-enter { + margin: 10px 0px 10px 0px; + float: left; +} + +input.command-input { + font-family: Verdana, Arial, Helvetica, sans-serif ; + font-family: monospace; + font-size: 12px; +} + +div#output-top { + margin-bottom: 20px; +} + +div.output-wrapper { +/* border: 1px solid blue; */ + margin-top: 5px; + background: white; + padding: 0px; +} + +div.output-header button { + margin-right: 4px; +} + +div.output-header { + padding: 4px; +} + +div.output-header div.target-value { + margin-left: 4px; +} + +div.output-header div.command-value { + margin-right: 4px; +} + +div.output-header div.target-value, +div.output-header div.command-value { + font-weight: normal; + font-size: 12px; +} + +div.target-value, +input.target-value { + display: inline-block; + font-size: 12px; + font-family: Verdana, Arial, Helvetica, sans-serif ; +} + +div.label, div.note { + display: inline; +/* + padding-left: 3px; + padding-right: 3px; +*/ + font-size: 12px; +} + +div.command-value, +input.command-value { + display: inline-block; + font-size: 14px; +} + +div.command-number { + display: inline-block; + font-size: 70%; + float: right; +} + +div#ember-view .output-content { + float: left; + position: relative; +} + +div.output-content { + display: block; + font-size: 12px; + padding: 10px; +} + +div.icon-box { + display: inline-block; + margin-right: 5px; +} + +div#debug-title { + display: inline-block; +} + +img.icon { + height: 16px; + vertical-align: middle; +} + +.buttonish { + text-align: center; + text-decoration: none; + text-shadow: -1px -1px 2px #777777; + text-shadow: rgba(10, 10, 10, 0.5) 1px 2px 2px; +} + +input.text-entry { + border: 0; + outline: 0; + height: 20px; + width: 100%; +} + +.rounded { + border: 1px solid #659635; + background: #99ca28; + padding: 2px 8px 2px 8px; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +.green { + color: #ffffff; + background: linear-gradient(top, + #5da331 0%, #659635 2%, #9bcb2a 97%, #cfe782 100%); + background: -moz-linear-gradient(top, + #5da331 0%, #659635 2%, #9bcb2a 97%, #cfe782 100%); + background: -webkit-linear-gradient(top, + #5da331 0%, #659635 2%, #9bcb2a 97%, #cfe782 100%); + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, + startColorstr='#659635', endColorstr='#9bcb2a'); +} + +.blue { + color: #0c0c0c; +/* + background: linear-gradient(top, + #a0a0ff 0%, #c8c8ff 10%, #d8d8ff 90%, #f0f0ff 100%); + background: -moz-linear-gradient(top, + #a0a0ff 0%, #c8c8ff 10%, #d8d8ff 90%, #f0f0ff 100%); + background: -webkit-linear-gradient(top, + #a0a0ff 0%, #c8c8ff 10%, #d8d8ff 90%, #f0f0ff 100%); + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, + startColorstr='#a0a0ff', endColorstr='#f0f0ff'); +*/ +} + +.jquery-checkbox { + line-height: 24px; +} + +ul.setupgrid { + padding: 0; + list-style: none; + margin: 0 auto; +} + +ul.setupgrid li { + float: left; + padding: 10px; + border: 1px solid #cbcad0; + margin: 0 5px 10px 5px; +} + +div.setupgrid { + font-family: 'GraublauWeb', arial, serif; + text-align: center; +} + +.setupgrid a { + height: 32px; + width: 64px; + display: block; + padding-top: 32px; + text-decoration: none; +} + +.setupgrid a#prefs-devices { + background: url(/images/prefs-devices.png) no-repeat center top; +} + +.setupgrid a#prefs-groups { + background: url(/images/prefs-groups.png) no-repeat center top; +} + +.setupgrid a#prefs-general { + background: url(/images/prefs-general.png) no-repeat center top; +} + +div.input { + background: #e0e0ff; + padding: 10px; +} + +div.parse { + background: #b0b0b0; + border: 1px solid black; +} + +div.input-debug { + background: #ffe0e0; + border-bottom: 1px solid black; + padding: 10px; + font-weight: bold; +} + +div.possibility-debug { + background: #ffe0e0; + padding: 10px; + border-bottom: 1px dotted red; +} + +div.match-debug { + display: inline-block; + padding: 5px; +} + +div.command-token, +div.command-token div { + display: inline-block; +} + +div.parse-details { +/* display: none; */ +} + +div.command-line { + font-weight: bold; +} + +div.match-details { + display: inline-block; +} + +div.possibility { +/* background: #ffe0e0; */ + padding: 10px; + border-bottom: 1px dotted red; +} + +div.parse-implicit-keyword, +div.parse-token, +div.parse-trailing, +div.parse-missing { + display: inline-block; +} + +div.parse-implicit-keyword, +div.parse-trailing, +div.parse-missing { + font-style: italic; + font-weight: normal; +} + +div.parse-token { + font-weight: bold; +} + +div.parse-mandatory { + color: red; + display: inline-block; +} + +div.parse-mandatory-value { + color: red; + font-style: italic; + display: inline-block; +} + +div.output-content div.parse:first-of-type { + display: none; +} + +div.command-help { + font-size: smaller; + font-style: italic; + padding-left: 20px; + padding-bottom: 5px; +} + +img.rendered { + float: left; + margin-right: 5px; + max-width: 16px; + vertical-align: middle; +} + +div.map-small { + width: 300px; + height: 200px; +} + +div.inline-dialog { + box-shadow: none; + margin-left: 20px; + position: relative; +} + +.inline-dialog .ui-dialog-titlebar-close { + display: none; +} + +div#prefs-title { + font-size: 120%; + font-weight: 600; +} + +div.prefs-item, +div.ui-yf-item { + display: table-row; +} + +div.prefs-item label, +div.ui-yf-item label { + padding-left: 10px; + padding-right: 5px; +} + +div.prefs-item label, +div.prefs-item input, +div.prefs-item div, +div.ui-yf-item label, +div.ui-yf-item input, +div.ui-yf-item div { + display: table-cell; +} + +div.dyn-form { + padding: 5px; + width: auto; +} + +div.dyn-form-wrapper { + display: inline-block; + border: 1px solid #ccc; + min-width: 400px; +} + +div.dyn-form-title { + background-color: #1478dc; + padding: 10px; + color: white; + font-size: 1.1em; +} + +div.dyn-form-item { + display: inline-block; + text-align: center; + padding: 2px 10px 2px 10px; +} + +div.dyn-form-message { + text-align: left; + padding: 5px 10px 5px 10px; +} + +div.dyn-form-item label { + float: left; + padding-left: 10px; + padding-right: 5px; +} + +div.dyn-form-buttons { + text-align: center; + padding: 5px 10px 10px 10px; +} + +div.dyn-form-item label, +div.dyn-form-item input, +div.dyn-form-item select, +div.dyn-form-item div { + float: left; + line-height: 20px; + margin-top: 5px; + min-width: 100px; + text-align: left; +} + +div.dyn-form-item input, +div.dyn-form-item select { + border: solid 1px #CCC; + margin-top: 5px; + width: auto; +} + +div.dyn-form-item .mandatory { + border-color: rgb(213, 119, 0); +} + +div.dyn-form-item .is-error { + border-color: rgb(213, 11, 0); +} + +div.dyn-form-item .is-error:focus { + border-color: rgb(213, 11, 0); +} + +div.dyn-form-item input:focus { + border: solid 1px rgb(180, 180, 200); + box-shadow: 0px 0px 3px rgba(100, 100, 200, 0.8); +} + +div.dyn-form-boolean { + margin-left: -40px; + text-align: left; + vertical-align: middle; +} + +div.dyn-form-item .dyn-radio-button { + margin-left: -30px; + margin-right: -40px; +} + +div.dyn-radiogroup { + border-bottom: 1px solid rgb(230, 230, 230); + border-top: 1px solid rgb(230, 230, 230); + padding: 5px; +} + +.dyn-dropdown-item { + max-height: 200px; + overflow-y: auto; +} + +.history-element .command { + font-size: 16px; +} + +.history-element .date { + color: rgb(130, 130, 130); + font-style: italic; +} + +.node { + stroke: #fff; + stroke-width: 1.5px; +} + +.link { + stroke: #444; + stroke-opacity: 0.6; + stroke-width: 2px; +} + +g.node text { + pointer-events: none; + font: 8px; + stroke: #000080; +} + +some.day { + background: -moz-linear-gradient(center top , #4B90C3, #0D63A3) + repeat scroll 0 0 transparent; +} + +.ui-autocomplete-divider { + border-bottom: 1px solid black; +} + +.ui-autocomplete { + max-height: 400px; + overflow-y: auto; + overflow-x: hidden; + padding-right: 20px; + width: 650px; +} + +ul.ui-autocomplete li.ui-menu-item { + font-family: monospace; +} + +ul.ui-autocomplete li.ui-menu-item a.label { + float: left; + font-weight: bold; +} + +ul.ui-autocomplete li.ui-menu-item a.help { + float: right; +} + +a.xpath-link { + text-decoration: none; +} + +div.xpath-wrapper { + margin-top: 8px; + padding-top: 5px; + border-top: solid 1px #c8c8c8; +} + +div.xpath { + display: none; + margin-top: 8px; +} + +/* + * Additional styles for messages + */ +.ui-state-info { + color: rgb(0, 94, 196); +} + +.ui-state-info .ui-icon { + background-image:url(/themes/clira/images/ui-icons_ffcf29_256x240.png); +} + +.ui-state-success { + color: rgb(45, 126, 0); +} + +.ui-state-success .ui-icon { + background-image:url(/themes/clira/images/ui-icons_ffcf29_256x240.png); +} + +.ui-state-warning { + color: rgb(179, 146, 14); +} + +.ui-state-warning .ui-icon { + background-image:url(/themes/clira/images/ui-icons_ffcf29_256x240.png); +} + +.stop_button { + background-color: #f24537; + background: -moz-linear-gradient( center top, #f24537 5%, #c62d1f 100% ); + background: -webkit-gradient( linear, left top, left bottom, color-stop(0.05, #f24537), color-stop(1, #c62d1f) ); + border: 1px solid #d02718; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + box-shadow: inset 0px 1px 0px 0px #f5978e; + color: #ffffff; + display: inline-block; + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f24537', endColorstr='#c62d1f'); + font-family: Courier New; + font-size: 10px; + font-style: normal; + font-weight: bold; + height: 16px; + line-height: 16px; + margin-left: 5px; + text-align: center; + text-decoration: none; + text-indent: 0.4px; + text-shadow: 1px 1px 0px #810e05; + width: 37px; +} + +.stop_button:hover { + background-color: #c62d1f; + background: -moz-linear-gradient( center top, #c62d1f 5%, #f24537 100% ); + background: -webkit-gradient( linear, left top, left bottom, color-stop(0.05, #c62d1f), color-stop(1, #f24537) ); + filter:progid: DXImageTransform.Microsoft.gradient(startColorstr='#c62d1f', endColorstr='#f24537'); +} + +.stop_button:active { + position: relative; + top: 1px; +} diff --git a/contrib/libxo/xohtml/xohtml.js b/contrib/libxo/xohtml/xohtml.js new file mode 100644 index 0000000..9e3d836 --- /dev/null +++ b/contrib/libxo/xohtml/xohtml.js @@ -0,0 +1,54 @@ +jQuery(function($) { + setTimeout(function() { + var $top = $("html body"); + $top.find('[class~="data"]').each(function() { + var help = $(this).attr('data-help'), + type = $(this).attr('data-type'), + xpath = $(this).attr('data-xpath'), + tag = $(this).attr('data-tag'), + output = ""; + if (help) { + output += "<b>Help</b>: " + help + "<br/>"; + } + if (type) { + output += "<b>Type</b>: " + type + "<br/>"; + } + if (xpath) { + output += "<div class='xpath-wrapper'>" + + "<a class='xpath-link' href='#'>" + + "show xpath</a><div class='xpath'>" + + xpath + "</div></div><br/>"; + } + if (output.length > 0) { + output = "<div>" + output + "</div>"; + } + + $(this).qtip({ + content: { + title: "<b>" + tag + "</b>", + text: function () { + var div = $(output); + div.find(".xpath-link") + .click(function() { + var xpath = $(this).next(); + if (xpath.is(":hidden")) { + xpath.show(); + $(this).text("hide xpath"); + } else { + xpath.hide(); + $(this).text("show xpath"); + } + return false; + }); + return div; + } + }, + hide: { + fixed: true, + delay: 300 + }, + style: "qtip-tipped" + }); + }); + }, 0); +});
\ No newline at end of file diff --git a/contrib/libxo/xohtml/xohtml.sh.in b/contrib/libxo/xohtml/xohtml.sh.in new file mode 100644 index 0000000..cbd3066 --- /dev/null +++ b/contrib/libxo/xohtml/xohtml.sh.in @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. +# Phil Shafer, July 2014 +# + +BASE=@XO_SHAREDIR@ +CMD=cat +DONE= + +while [ -z "$DONE" -a ! -z "$1" ]; do + case "$1" in + -b|--base) + shift; + BASE="$1"; + shift; + ;; + -c|--command) + shift; + CMD="$1"; + shift; + ;; + -f|--file) + shift; + FILE="$1"; + shift; + exec > "$FILE"; + ;; + *) + DONE=1; + ;; + esac +done + +echo "<html>\n<head>\n" +echo '<meta http-equiv="content-type" content="text/html; charset=utf-8"/>' +echo '<link rel="stylesheet" href="'$BASE'/xohtml.css">' +echo '<link rel="stylesheet" href="'$BASE'/external/jquery.qtip.css"/>' +echo '<script type="text/javascript" src="'$BASE'/external/jquery.js"></script>' +echo '<script type="text/javascript" src="'$BASE'/external/jquery.qtip.js"></script>' +echo '<script type="text/javascript" src="'$BASE'/xohtml.js"></script>' +echo '<script>' +echo '</script>' +echo "</head>\n<body>\n" + +$CMD + +echo "</body>\n</html>\n" + +exit 0 diff --git a/contrib/libxo/xolint/Makefile.am b/contrib/libxo/xolint/Makefile.am new file mode 100644 index 0000000..0f8ef62 --- /dev/null +++ b/contrib/libxo/xolint/Makefile.am @@ -0,0 +1,14 @@ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +man_MANS = xolint.1 + +EXTRA_DIST = xolint.1 xolint.pl + +install-exec-hook: + install ${srcdir}/xolint.pl ${bindir}/xolint diff --git a/contrib/libxo/xolint/xolint.1 b/contrib/libxo/xolint/xolint.1 new file mode 100644 index 0000000..b7ed130 --- /dev/null +++ b/contrib/libxo/xolint/xolint.1 @@ -0,0 +1,89 @@ +.\" # +.\" # Copyright (c) 2014, Juniper Networks, Inc. +.\" # All rights reserved. +.\" # This SOFTWARE is licensed under the LICENSE provided in the +.\" # ../Copyright file. By downloading, installing, copying, or +.\" # using the SOFTWARE, you agree to be bound by the terms of that +.\" # LICENSE. +.\" # Phil Shafer, July 2014 +.\" +.Dd July, 2014 +.Dt LIBXO 3 +.Os +.Sh NAME +.Nm xolint +.Nd detect errors in programs using xo_emit +.Sh SYNOPSIS +.Nm xolint +.Op Fl c +.Op Fl "C <flags>" +.Op Fl "d" +.Op Fl "D" +.Op Fl "I" +.Op Fl "p" +.Op Fl "V" +.Op Fl "X" +.Op Ar files... +.Sh DESCRIPTION +xolint is a tool for reporting common mistakes in format strings +in source code that invokes xo_emit(). It allows these errors +to be diagnosed at build time, rather than waiting until runtime. +.Pp +xolint takes the one or more C files as arguments, and reports +and errors, warning, or informational messages as needed. +.Bl -tag -width "C <flags>" +.It Fl c +Invoke 'cpp' against the input file +.It Fl "C <flags>" +Flags that are passed to 'cpp +.It Fl "d" +Enable debug output +.It Fl "D" +Generate documentation for all xolint messages +.It Fl "I" +Generate a table of xo_info_t structures. +.It Fl "p" +Print the offending lines after the error message is displayed +.It Fl "V" +Do not report errors, but instead print a complete list of +all field names, sorted alphabetically. The output can help spot +inconsistencies and spelling errors. +.It Fl "X" +Extract samples from xolint, suitable for internal testing. +.El +.Pp +Output message contain the source filename and line number, the +class of the message, the message, and, if +.Fl p +is given, the +line that contains the error: +.Bd -literal -offset indent + % xolint -t xolint.c + xolint.c: 16: error: anchor format should be "%d" + 16 xo_emit("{[:/%s}"); +.Ed +.Pp +.Sh ADDITIONAL DOCUMENTATION +.Pp +Complete documentation can be found on github: +.Bd -literal -offset indent +http://juniper.github.io/libxo/libxo-manual.html +.Ed +.Pp +libxo lives on github as: +.Bd -literal -offset indent +https://github.com/Juniper/libxo +.Ed +.Pp +The latest release of libxo is available at: +.Bd -literal -offset indent +https://github.com/Juniper/libxo/releases +.Ed +.Sh SEE ALSO +.Xr xo_emit 3 +.Sh HISTORY +The +.Fa libxo +library was added in FreeBSD 10.1. +.Sh AUTHOR +Phil Shafer diff --git a/contrib/libxo/xolint/xolint.pl b/contrib/libxo/xolint/xolint.pl new file mode 100755 index 0000000..8693e62 --- /dev/null +++ b/contrib/libxo/xolint/xolint.pl @@ -0,0 +1,556 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. +# Phil Shafer, August 2014 +# +# +# xolint -- a lint for inspecting xo_emit format strings +# +# Yes, that's a long way to go for a pun. + +%vocabulary = (); + +sub main { + while ($ARGV[0] =~ /^-/) { + $_ = shift @ARGV; + $opt_cpp = 1 if /^-c/; + $opt_cflags .= shift @ARGV if /^-C/; + $opt_debug = 1 if /^-d/; + extract_docs() if /^-D/; + $opt_info = $opt_vocabulary = 1 if /^-I/; + $opt_print = 1 if /^-p/; + $opt_vocabulary = 1 if /^-V/; + extract_samples() if /^-X/; + } + + for $file (@ARGV) { + parse_file($file); + } + + if ($opt_info) { + print "static xo_info_t xo_info_table[] = {\n"; + for $name (sort(keys(%vocabulary))) { + print " { \"", $name, "\", \"type\", \"desc\" },\n"; + } + print "};\n"; + print "static int xo_info_count = " + . "(sizeof(xo_info_table) / sizeof(xo_info_table[0]));\n\n"; + print "#define XO_SET_INFO() \\\n"; + print " xo_set_info(NULL, xo_info_table, xo_info_count)\n"; + } elsif ($opt_vocabulary) { + for $name (sort(keys(%vocabulary))) { + print $name, "\n"; + } + } +} + +sub extract_samples { + my $x = "\#" . "\@"; + my $cmd = "grep -B1 -i '$x Should be' $0 | grep xo_emit | sed 's/.*\#*\@//'"; + system($cmd); + exit(0); +} + +sub extract_docs { + my $x = "\#" . "\@"; + my $cmd = "grep -B1 '$x' $0"; + open INPUT, "$cmd |"; + local @input = <INPUT>; + close INPUT; + my $ln, $new = 0, $first = 1, $need_nl; + + for ($ln = 0; $ln <= $#input; $ln++) { + chomp($_ = $input[$ln]); + if (/^--/) { + $ln += 1; + $new = 1; + next; + } + if ($first) { + $new = 1; + $first = 0; + next; + } + + s/\s*\#\@\s*//; + + if ($new) { + if ($need_nl) { + print "\n\n"; + $need_nl = 0; + } + + print "*** '$_'\n\n"; + print "The message \"$_\" can be caused by code like:\n\n"; + $new = 0; + + } elsif (/xo_emit\s*\(/) { + s/^\s+//; + print " $_\n\n"; + + } elsif (/^Should be/i) { + print "This code should be replaced with code like:\n\n"; + + } else { + print "$_\n"; + $need_nl = 1; + } + } + + exit(0); +} + +sub parse_file { + local($file) = @_; + local($errors, $warnings, $info) = (0, 0, 0); + local $curfile = $file; + local $curln = 0; + + if ($opt_cpp) { + die "no such file" unless -f $file; + open INPUT, "cpp $opt_cflags $file |"; + } else { + open INPUT, $file || die "cannot open input file '$file'"; + } + local @input = <INPUT>; + close INPUT; + + local $ln, $rln, $line, $replay; + + for ($ln = 0; $ln < $#input; $ln++) { + $line = $input[$ln]; + $curln += 1; + + if ($line =~ /^\#/) { + my($num, $fn) = ($line =~ /\#\s*(\d+)\s+"(.+)"/); + ($curfile, $curln) = ($fn, $num) if $num; + next; + } + + next unless $line =~ /xo_emit\(/; + + @tokens = parse_tokens(); + print "token:\n '" . join("'\n '", @tokens) . "'\n" + if $opt_debug; + check_format($tokens[0]); + } + + print $file . ": $errors errors, $warnings warnings, $info info\n" + unless $opt_vocabulary; +} + +sub parse_tokens { + my $full = "$'"; + my @tokens = (); + my %pairs = ( "{" => "}", "[" => "]", "(" => ")" ); + my %quotes = ( "\"" => "\"", "'" => "'" ); + local @data = split(//, $full); + local @open = (); + local $current = ""; + my $quote = ""; + local $off = 0; + my $ch; + + $replay = $curln . " " . $line; + $rln = $ln + 1; + + for (;;) { + get_tokens() if $off > $#data; + die "out of data" if $off > $#data; + $ch = $data[$off++]; + + print "'$ch' ($quote) ($#open) [" . join("", @open) . "]\n" + if $opt_debug; + + last if $ch eq ";" && $#open < 0; + + if ($ch eq "," && $quote eq "" && $#open < 0) { + print "[$current]\n" if $opt_debug; + push @tokens, $current; + $current = ""; + next; + } + + next if $ch =~ /[ \t\n\r]/ && $quote eq "" && $#open < 0; + + $current .= $ch; + + if ($quote) { + if ($ch eq $quote) { + $quote = ""; + } + next; + } + if ($quotes{$ch}) { + $quote = $quotes{$ch}; + $current = substr($current, 0, -2) if $current =~ /""$/; + next; + } + + if ($pairs{$ch}) { + push @open, $pairs{$ch}; + next; + } + + if ($#open >= 0 && $ch eq $open[$#open]) { + pop @open; + next; + } + } + + push @tokens, substr($current, 0, -1); + return @tokens; +} + +sub get_tokens { + if ($ln + 1 < $#input) { + $line = $input[++$ln]; + $curln += 1; + $replay .= $curln . " " . $line; + @data = split(//, $line); + $off = 0; + } +} + +sub check_format { + my($format) = @_; + + return unless $format =~ /^".*"$/; + + my @data = split(//, $format); + my $ch; + my $braces = 0; + local $count = 0; + my $content = ""; + my $off; + my $phase = 0; + my @build = (); + local $last, $prev = ""; + + # Nukes quotes + pop @data; + shift @data; + + for (;;) { + last if $off > $#data; + $ch = $data[$off++]; + + if ($ch eq "\\") { + $ch = $data[$off++]; + $off += 1 if $ch eq "\\"; # double backslash: "\\/" + next; + } + + if ($braces) { + if ($ch eq "}") { + check_field(@build); + $braces = 0; + @build = (); + $phase = 0; + next; + } elsif ($phase == 0 && $ch eq ":") { + $phase += 1; + next; + } elsif ($ch eq "/") { + $phase += 1; + next; + } + + } else { + if ($ch eq "{") { + check_text($build[0]) if length($build[0]); + $braces = 1; + @build = (); + $last = $prev; + next; + } + } + + $prev = $ch; + $build[$phase] .= $ch; + } + + if ($braces) { + error("missing closing brace"); + check_field(@build); + } else { + check_text($build[0]) if length($build[0]); + } +} + +sub check_text { + my($text) = @_; + + print "checking text: [$text]\n" if $opt_debug; + + #@ A percent sign appearing in text is a literal + #@ xo_emit("cost: %d", cost); + #@ Should be: + #@ xo_emit("{L:cost}: {:cost/%d}", cost); + #@ This can be a bit surprising and could be a field that was not + #@ properly converted to a libxo-style format string. + info("a percent sign appearing in text is a literal") if $text =~ /%/; +} + +sub check_field { + my(@field) = @_; + print "checking field: [" . join("][", @field) . "]\n" if $opt_debug; + + if ($opt_vocabulary) { + $vocabulary{$field[1]} = 1 + if $field[1] && $field[0] !~ /[DELNPTUW\[\]]/; + return; + } + + #@ Last character before field definition is a field type + #@ A common typo: + #@ xo_emit("{T:Min} T{:Max}"); + #@ Should be: + #@ xo_emit("{T:Min} {T:Max}"); + #@ Twiddling the "{" and the field role is a common typo. + info("last character before field definition is a field type ($last)") + if $last =~ /[DELNPTUVW\[\]]/ && $field[0] !~ /[DELNPTUVW\[\]]/; + + #@ Encoding format uses different number of arguments + #@ xo_emit("{:name/%6.6s %%04d/%s}", name, number); + #@ Should be: + #@ xo_emit("{:name/%6.6s %04d/%s-%d}", name, number); + #@ Both format should consume the same number of arguments off the stack + my $cf = count_args($field[2]); + my $ce = count_args($field[3]); + warn("encoding format uses different number of arguments ($cf/$ce)") + if $ce >= 0 && $cf >= 0 && $ce != $cf; + + #@ Only one field role can be used + #@ xo_emit("{LT:Max}"); + #@ Should be: + #@ xo_emit("{T:Max}"); + my(@roles) = ($field[0] !~ /([DELNPTUVW\[\]]).*([DELNPTUVW\[\]])/); + error("only one field role can be used (" . join(", ", @roles) . ")") + if $#roles > 0; + + # Field is a note, label, or title + if ($field[0] =~ /[DLNT]/) { + + #@ Potential missing slash after N, L, or T with format + #@ xo_emit("{T:%6.6s}\n", "Max"); + #@ should be: + #@ xo_emit("{T:/%6.6s}\n", "Max"); + #@ The "%6.6s" will be a literal, not a field format. While + #@ it's possibly valid, it's likely a missing "/". + info("potential missing slash after N, L, or T with format") + if $field[1] =~ /%/; + + #@ Format cannot be given when content is present (roles: DNLT) + #@ xo_emit("{T:Max/%6.6s}", "Max"); + #@ Fields with the D, N, L, or T roles can't have both + #@ static literal content ("{T:Title}") and a + #@ format ("{T:/%s}"). + #@ This error will also occur when the content has a backslash + #@ in it, like "{N:Type of I/O}"; backslashes should be escaped, + #@ like "{N:Type of I\\/O}". Note the double backslash, one for + #@ handling 'C' strings, and one for libxo. + error("format cannot be given when content is present") + if $field[1] && $field[2]; + + #@ An encoding format cannot be given (roles: DNLT) + #@ xo_emit("{T:Max//%s}", "Max"); + #@ Fields with the D, N, L, and T roles are not emitted in + #@ the 'encoding' style (JSON, XML), so an encoding format + #@ would make no sense. + error("encoding format cannot be given when content is present") + if $field[3]; + } + + # A value field + if (length($field[0]) == 0 || $field[0] =~ /V/) { + + #@ Value field must have a name (as content)") + #@ xo_emit("{:/%s}", "value"); + #@ Should be: + #@ xo_emit("{:tag-name/%s}", "value"); + #@ The field name is used for XML and JSON encodings. These + #@ tags names are static and must appear directly in the + #@ field descriptor. + error("value field must have a name (as content)") + unless $field[1]; + + #@ Use hyphens, not underscores, for value field name + #@ xo_emit("{:no_under_scores}", "bad"); + #@ Should be: + #@ xo_emit("{:no-under-scores}", "bad"); + #@ Use of hyphens is traditional in XML, and the XOF_UNDERSCORES + #@ flag can be used to generate underscores in JSON, if desired. + #@ But the raw field name should use hyphens. + error("use hyphens, not underscores, for value field name") + if $field[1] =~ /_/; + + #@ Value field name cannot start with digit + #@ xo_emit("{:10-gig/}"); + #@ Should be: + #@ xo_emit("{:ten-gig/}"); + #@ XML element names cannot start with a digit. + error("value field name cannot start with digit") + if $field[1] =~ /^[0-9]/; + + #@ Value field name should be lower case + #@ xo_emit("{:WHY-ARE-YOU-SHOUTING}", "NO REASON"); + #@ Should be: + #@ xo_emit("{:why-are-you-shouting}", "no reason"); + #@ Lower case is more civilized. Even TLAs should be lower case + #@ to avoid scenarios where the differences between "XPath" and + #@ "Xpath" drive your users crazy. Lower case rules the seas. + error("value field name should be lower case") + if $field[1] =~ /[A-Z]/; + + #@ Value field name should be longer than two characters + #@ xo_emit("{:x}", "mumble"); + #@ Should be: + #@ xo_emit("{:something-meaningful}", "mumble"); + #@ Field names should be descriptive, and it's hard to + #@ be descriptive in less than two characters. Consider + #@ your users and try to make something more useful. + #@ Note that this error often occurs when the field type + #@ is placed after the colon ("{:T/%20s}"), instead of before + #@ it ("{T:/20s}"). + error("value field name should be longer than two characters") + if $field[1] =~ /[A-Z]/; + + #@ Value field name contains invalid character + #@ xo_emit("{:cost-in-$$/%u}", 15); + #@ Should be: + #@ xo_emit("{:cost-in-dollars/%u}", 15); + #@ An invalid character is often a sign of a typo, like "{:]}" + #@ instead of "{]:}". Field names are restricted to lower-case + #@ characters, digits, and hyphens. + error("value field name contains invalid character (" . $field[1] . ")") + unless $field[1] =~ /^[0-9a-z-]*$/; + } + + # A decoration field + if ($field[0] =~ /D/) { + + #@decoration field contains invalid character + #@ xo_emit("{D:not good}"); + #@ Should be: + #@ xo_emit("{D:((}{:good}{D:))}", "yes"); + #@ This is minor, but fields should use proper roles. Decoration + #@ fields are meant to hold puncuation and other characters used + #@ to decorate the content, typically to make it more readable + #@ to human readers. + warn("decoration field contains invalid character") + unless $field[1] =~ m:^[~!\@\#\$%^&\*\(\);\:\[\]\{\} ]+$:; + } + + if ($field[0] =~ /[\[\]]/) { + #@ Anchor content should be decimal width + #@ xo_emit("{[:mumble}"); + #@ Should be: + #@ xo_emit("{[:32}"); + #@ Anchors need an integer value to specify the width of + #@ the set of anchored fields. The value can be positive + #@ (for left padding/right justification) or negative (for + #@ right padding/left justification) and can appear in + #@ either the start or stop anchor field descriptor. + error("anchor content should be decimal width") + if $field[1] && $field[1] !~ /^-?\d+$/ ; + + #@ Anchor format should be "%d" + #@ xo_emit("{[:/%s}"); + #@ Should be: + #@ xo_emit("{[:/%d}"); + #@ Anchors only grok integer values, and if the value is not static, + #@ if must be in an 'int' argument, represented by the "%d" format. + #@ Anything else is an error. + error("anchor format should be \"%d\"") + if $field[2] && $field[2] ne "%d"; + + #@ Anchor cannot have both format and encoding format") + #@ xo_emit("{[:32/%d}"); + #@ Should be: + #@ xo_emit("{[:32}"); + #@ Anchors can have a static value or argument for the width, + #@ but cannot have both. + error("anchor cannot have both format and encoding format") + if $field[1] && $field[2]; + } +} + +sub count_args { + my($format) = @_; + + return -1 unless $format; + + my $in; + my($text, $ff, $fc, $rest); + for ($in = $format; $in; $in = $rest) { + ($text, $ff, $fc, $rest) = + ($in =~ /^([^%]*)(%[^%diouxXDOUeEfFgGaAcCsSp]*)([diouxXDOUeEfFgGaAcCsSp])(.*)$/); + unless ($ff) { + # Might be a "%%" + ($text, $ff, $rest) = ($in =~ /^([^%]*)(%%)(.*)$/); + if ($ff) { + check_text($text); + } else { + # Not sure what's going on here, but something's wrong... + error("invalid field format") if $in =~ /%/; + } + next; + } + + check_text($text); + check_field_format($ff, $fc); + } + + return 0; +} + +sub check_field_format { + my($ff, $fc) = @_; + + print "check_field_format: [$ff] [$fc]\n" if $opt_debug; + + my(@chunks) = split(/\./, $ff); + + #@ Max width only valid for strings + #@ xo_emit("{:tag/%2.4.6d}", 55); + #@ Should be: + #@ xo_emit("{:tag/%2.6d}", 55); + #@ libxo allows a true 'max width' in addition to the traditional + #@ printf-style 'max number of bytes to use for input'. But this + #@ is supported only for string values, since it makes no sense + #@ for non-strings. This error may occur from a typo, + #@ like "{:tag/%6..6d}" where only one period should be used. + error("max width only valid for strings") + if $#chunks >= 2 && $fc =~ /[sS]/; +} + +sub error { + return if $opt_vocabulary; + print STDERR $curfile . ": " .$curln . ": error: " . join(" ", @_) . "\n"; + print STDERR $replay . "\n" if $opt_print; + $errors += 1; +} + +sub warn { + return if $opt_vocabulary; + print STDERR $curfile . ": " .$curln . ": warning: " . join(" ", @_) . "\n"; + print STDERR $replay . "\n" if $opt_print; + $warnings += 1; +} + +sub info { + return if $opt_vocabulary; + print STDERR $curfile . ": " .$curln . ": info: " . join(" ", @_) . "\n"; + print STDERR $replay . "\n" if $opt_print; + $info += 1; +} + +main: { + main(); +} |