CORE_CFLAGS = $(AM_LIBAPR_CFLAGS) $(AM_LIBAPR_CPPFLAGS)
CORE_CFLAGS += $(AM_LIBAPU_CPPFLAGS)
-CORE_CFLAGS += -I$(switch_srcdir)/libs/libtpl-1.5/src
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include
if ENABLE_LIBYUV
CORE_CFLAGS += -I$(switch_srcdir)/libs/libyuv/include
endif
lib_LTLIBRARIES = libfreeswitch.la
-libfreeswitch_la_CFLAGS = $(CORE_CFLAGS) $(SQLITE_CFLAGS) $(GUMBO_CFLAGS) $(FVAD_CFLAGS) $(FREETYPE_CFLAGS) $(CURL_CFLAGS) $(PCRE_CFLAGS) $(SPEEX_CFLAGS) $(LIBEDIT_CFLAGS) $(openssl_CFLAGS) $(AM_CFLAGS)
+libfreeswitch_la_CFLAGS = $(CORE_CFLAGS) $(SQLITE_CFLAGS) $(GUMBO_CFLAGS) $(FVAD_CFLAGS) $(FREETYPE_CFLAGS) $(CURL_CFLAGS) $(PCRE_CFLAGS) $(SPEEX_CFLAGS) $(LIBEDIT_CFLAGS) $(openssl_CFLAGS) $(AM_CFLAGS) $(TPL_CFLAGS)
libfreeswitch_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) $(PLATFORM_CORE_LDFLAGS) -no-undefined
-libfreeswitch_la_LIBADD = $(CORE_LIBS) $(APR_LIBS) $(SQLITE_LIBS) $(GUMBO_LIBS) $(FVAD_LIBS) $(FREETYPE_LIBS) $(CURL_LIBS) $(PCRE_LIBS) $(SPEEX_LIBS) $(LIBEDIT_LIBS) $(openssl_LIBS) $(PLATFORM_CORE_LIBS)
+libfreeswitch_la_LIBADD = $(CORE_LIBS) $(APR_LIBS) $(SQLITE_LIBS) $(GUMBO_LIBS) $(FVAD_LIBS) $(FREETYPE_LIBS) $(CURL_LIBS) $(PCRE_LIBS) $(SPEEX_LIBS) $(LIBEDIT_LIBS) $(openssl_LIBS) $(PLATFORM_CORE_LIBS) $(TPL_LIBS)
libfreeswitch_la_DEPENDENCIES = $(BUILT_SOURCES)
if HAVE_PNG
libs/libteletone/src/libteletone_detect.h \
libs/libteletone/src/libteletone_generate.h \
libs/libteletone/src/libteletone.h \
- libs/libtpl-1.5/src/tpl.h \
src/include/switch_limit.h \
src/include/switch_odbc.h \
src/include/switch_pgsql.h \
src/switch_msrp.c \
src/switch_vad.c \
src/switch_vpx.c \
- libs/libtpl-1.5/src/tpl.c \
libs/libteletone/src/libteletone_detect.c \
libs/libteletone/src/libteletone_generate.c \
libs/miniupnpc/miniwget.c \
AM_CONDITIONAL([HAVE_FVAD],[true])],[
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_FVAD],[false])])
+PKG_CHECK_MODULES([TPL], [libtpl >= 1.5],[
+ AC_DEFINE([HAVE_LIBTPL],[1],[Define to 1 if you have libtpl])],[
+ AC_MSG_RESULT([no])])
+
PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.6.20])
PKG_CHECK_MODULES([CURL], [libcurl >= 7.19])
PKG_CHECK_MODULES([PCRE], [libpcre >= 7.8])
# configure options
libssl1.0-dev | libssl-dev, unixodbc-dev, libpq-dev,
libncurses5-dev, libjpeg62-turbo-dev | libjpeg-turbo8-dev | libjpeg62-dev | libjpeg8-dev,
- python-dev, python-all-dev, python-support (>= 0.90) | dh-python, erlang-dev,
+ python-dev, python-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
# documentation
doxygen,
# for APR (not essential for build)
+++ /dev/null
-Copyright (c) 2005-2010, Troy Hanson http://tpl.sourceforge.net
-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.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+++ /dev/null
-SUBDIRS = src
-EXTRA_DIST = LICENSE tests lang doc
+++ /dev/null
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = .
-DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(top_srcdir)/config/config.h.in \
- $(top_srcdir)/configure config/config.guess config/config.sub \
- config/depcomp config/install-sh config/ltmain.sh \
- config/missing
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
- configure.lineno config.status.lineno
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/config.h
-CONFIG_CLEAN_FILES =
-SOURCES =
-DIST_SOURCES =
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
- html-recursive info-recursive install-data-recursive \
- install-dvi-recursive install-exec-recursive \
- install-html-recursive install-info-recursive \
- install-pdf-recursive install-ps-recursive install-recursive \
- installcheck-recursive installdirs-recursive pdf-recursive \
- ps-recursive uninstall-recursive
-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
- distclean-recursive maintainer-clean-recursive
-ETAGS = etags
-CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- { test ! -d $(distdir) \
- || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -fr $(distdir); }; }
-DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
-distuninstallcheck_listfiles = find . -type f -print
-distcleancheck_listfiles = find . -type f -print
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-SUBDIRS = src
-EXTRA_DIST = LICENSE tests lang doc
-all: all-recursive
-
-.SUFFIXES:
-am--refresh:
- @:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
- cd $(srcdir) && $(AUTOMAKE) --foreign \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- echo ' $(SHELL) ./config.status'; \
- $(SHELL) ./config.status;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- $(SHELL) ./config.status --recheck
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
-
-config/config.h: config/stamp-h1
- @if test ! -f $@; then \
- rm -f config/stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) config/stamp-h1; \
- else :; fi
-
-config/stamp-h1: $(top_srcdir)/config/config.h.in $(top_builddir)/config.status
- @rm -f config/stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status config/config.h
-$(top_srcdir)/config/config.h.in: $(am__configure_deps)
- cd $(top_srcdir) && $(AUTOHEADER)
- rm -f config/stamp-h1
- touch $@
-
-distclean-hdr:
- -rm -f config/config.h config/stamp-h1
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-distclean-libtool:
- -rm -f libtool config.lt
-
-# This directory's subdirectories are mostly independent; you can cd
-# into them and run `make' without going through this Makefile.
-# To change the values of `make' variables: instead of editing Makefiles,
-# (1) if the variable is set in `config.status', edit `config.status'
-# (which will cause the Makefiles to be regenerated when you run `make');
-# (2) otherwise, pass the desired values on the `make' command line.
-$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- target=`echo $@ | sed s/-recursive//`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
- fi; test -z "$$fail"
-
-$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- rev=''; for subdir in $$list; do \
- if test "$$subdir" = "."; then :; else \
- rev="$$subdir $$rev"; \
- fi; \
- done; \
- rev="$$rev ."; \
- target=`echo $@ | sed s/-recursive//`; \
- for subdir in $$rev; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done && test -z "$$fail"
-tags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
- done
-ctags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
- done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
- include_option=--etags-include; \
- empty_fix=.; \
- else \
- include_option=--include; \
- empty_fix=; \
- fi; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test ! -f $$subdir/TAGS || \
- tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
- fi; \
- done; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- $(am__remove_distdir)
- test -d $(distdir) || mkdir $(distdir)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
- list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- distdir=`$(am__cd) $(distdir) && pwd`; \
- top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
- (cd $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$top_distdir" \
- distdir="$$distdir/$$subdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- distdir) \
- || exit 1; \
- fi; \
- done
- -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r $(distdir)
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
-
-dist-tarZ: distdir
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
-
-dist-shar: distdir
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
-
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && cd $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
- $(am__remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
-distuninstallcheck:
- @cd $(distuninstallcheck_dir) \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
-check-am: all-am
-check: check-recursive
-all-am: Makefile
-installdirs: installdirs-recursive
-installdirs-am:
-install: install-recursive
-install-exec: install-exec-recursive
-install-data: install-data-recursive
-uninstall: uninstall-recursive
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-recursive
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-recursive
-
-clean-am: clean-generic clean-libtool mostlyclean-am
-
-distclean: distclean-recursive
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-hdr \
- distclean-libtool distclean-tags
-
-dvi: dvi-recursive
-
-dvi-am:
-
-html: html-recursive
-
-info: info-recursive
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-recursive
-
-install-exec-am:
-
-install-html: install-html-recursive
-
-install-info: install-info-recursive
-
-install-man:
-
-install-pdf: install-pdf-recursive
-
-install-ps: install-ps-recursive
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-recursive
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf $(top_srcdir)/autom4te.cache
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-recursive
-
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-
-pdf: pdf-recursive
-
-pdf-am:
-
-ps: ps-recursive
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
- install-strip
-
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am am--refresh check check-am clean clean-generic \
- clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
- dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \
- distclean distclean-generic distclean-hdr distclean-libtool \
- distclean-tags distcleancheck distdir distuninstallcheck dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-am \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags tags-recursive uninstall uninstall-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
+++ /dev/null
-tpl: fast, easy serialization in C
-==============================================================================
-
-Documentation for tpl is available in the doc/ directory or at:
-
- http://tpl.sourceforge.net
-
-You can build tpl as a library, like so:
-
- ./configure
- make
- make install
-
-This installs libtpl.so and libtpl.a into a standard system library directory.
-You can customize the install directory using configure's "--prefix" option:
-
- ./configure --prefix=/some/directory
-
-For other options accepted by configure, run "./configure --help".
-
-NON-LIBRARY OPTION
-------------------
-Alternatively, if you don't want to muck around with libraries, you can simply
-copy these two files into your own C project and build them with your program:
-
- src/tpl.h
- src/tpl.c
-
-WINDOWS
--------
-You can build tpl as a DLL under Visual Studio 2008. Or you can use MinGW or
-Cygwin.
-
-SELF-TEST SUITE
----------------
-The automated self-test can be run by doing:
-
- cd tests
- make
-
-LICENSE
--------
-The BSD license applies to this software. The text is in the LICENSE file.
-
-CREDITS
--------
-Many people have contributed to tpl, both bits of code and ideas. Rather than
-listing them all here, at risk of omitting anyone- I just wish to say thank
-you. Some particular features are noted with contributors' names in the
-ChangeLog.
-
-Feel free to send me questions, comments or bug reports.
-
-Troy D. Hanson, February 5, 2010
-thanson@users.sourceforge.net
-
+++ /dev/null
-#!/bin/sh
-
-# THIS SCRIPT IS FOR PROJECT MAINTAINER ONLY
-# It is executed only to generate "configure"
-
-set -x
-aclocal -I config
-autoheader
-libtoolize --copy --force
-automake --foreign --add-missing --copy
-autoconf
+++ /dev/null
-AC_PREREQ(2.59)
-
-AC_INIT([libtpl], [1.4], [thanson@users.sourceforge.net])
-AC_CONFIG_SRCDIR(src/tpl.c)
-AC_CONFIG_AUX_DIR(config)
-AC_CONFIG_HEADERS(config/config.h)
-AM_INIT_AUTOMAKE
-AC_PROG_CC
-dnl next 4 lines are a hack to avoid libtool's
-dnl needless checks for C++ and Fortran compilers
-m4_undefine([AC_PROG_CXX])
-m4_defun([AC_PROG_CXX],[])
-m4_undefine([AC_PROG_F77])
-m4_defun([AC_PROG_F77],[])
-AC_PROG_LIBTOOL
-
-dnl detect Cygwin or MinGW and use mmap family replacements
-AC_CONFIG_LIBOBJ_DIR(src/win)
-case $host in
- *-*-mingw32* | *-*-cygwin* | *-*-windows*)
- AC_LIBOBJ(mmap)
- AC_MSG_NOTICE([using custom mmap for Cygwin/MinGW])
- ;;
-esac
-
-AC_CONFIG_FILES(src/win/Makefile src/Makefile Makefile)
-AC_OUTPUT
-
+++ /dev/null
-all: css userguide pdf changelog perl
-
-userguide: txt/userguide.txt
- asciidoc --unsafe --out-file=html/userguide.html -a linkcss=1 -a theme=tdh txt/userguide.txt
-
-changelog: txt/ChangeLog.txt
- asciidoc --out-file=html/ChangeLog.html txt/ChangeLog.txt
-
-.PHONY: pdf
-
-pdf: txt/userguide.txt
- a2x -f pdf $<
- mv txt/userguide.pdf pdf/
- cd html && ln -sf ../pdf/userguide.pdf userguide.pdf
- rm txt/userguide.xml
-
-perl: txt/perl.txt
- asciidoc --unsafe --out-file=html/perl.html -a linkcss=1 -a theme=tdh txt/perl.txt
-
-css: html/toc.css
- cat /etc/asciidoc/stylesheets/xhtml11.css html/toc.css > html/tdh.css
- cp /etc/asciidoc/stylesheets/xhtml11-quirks.css html/tdh-quirks.css
-
-docbook: txt/userguide.txt
- asciidoc -b docbook --out-file=/tmp/userguide.xml txt/userguide.txt
- xmlto -o html html-nochunks /tmp/userguide.xml
+++ /dev/null
-# maintainer notes
-
-# IE6 png gamma bug:
-# PNG images in IE6 display with wrong background colors,
-# solution: save PNG in Gimp *Without save gamma checked*
-
-#update sourceforge web site:
-#cd html
-#scp *.{html,css} thanson@shell.sourceforge.net:/home/groups/t/tp/tpl/htdocs
-#cd img
-#scp *.png *.jpg thanson@shell.sourceforge.net:/home/groups/t/tp/tpl/htdocs/img
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
-<meta name="generator" content="AsciiDoc 8.5.0" />\r
-<title>tpl ChangeLog</title>\r
-<style type="text/css">\r
-/* Debug borders */\r
-p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {\r
-/*\r
- border: 1px solid red;\r
-*/\r
-}\r
-\r
-body {\r
- margin: 1em 5% 1em 5%;\r
-}\r
-\r
-a {\r
- color: blue;\r
- text-decoration: underline;\r
-}\r
-a:visited {\r
- color: fuchsia;\r
-}\r
-\r
-em {\r
- font-style: italic;\r
- color: navy;\r
-}\r
-\r
-strong {\r
- font-weight: bold;\r
- color: #083194;\r
-}\r
-\r
-tt {\r
- color: navy;\r
-}\r
-\r
-h1, h2, h3, h4, h5, h6 {\r
- color: #527bbd;\r
- font-family: sans-serif;\r
- margin-top: 1.2em;\r
- margin-bottom: 0.5em;\r
- line-height: 1.3;\r
-}\r
-\r
-h1, h2, h3 {\r
- border-bottom: 2px solid silver;\r
-}\r
-h2 {\r
- padding-top: 0.5em;\r
-}\r
-h3 {\r
- float: left;\r
-}\r
-h3 + * {\r
- clear: left;\r
-}\r
-\r
-div.sectionbody {\r
- font-family: serif;\r
- margin-left: 0;\r
-}\r
-\r
-hr {\r
- border: 1px solid silver;\r
-}\r
-\r
-p {\r
- margin-top: 0.5em;\r
- margin-bottom: 0.5em;\r
-}\r
-\r
-ul, ol, li > p {\r
- margin-top: 0;\r
-}\r
-\r
-pre {\r
- padding: 0;\r
- margin: 0;\r
-}\r
-\r
-span#author {\r
- color: #527bbd;\r
- font-family: sans-serif;\r
- font-weight: bold;\r
- font-size: 1.1em;\r
-}\r
-span#email {\r
-}\r
-span#revnumber, span#revdate, span#revremark {\r
- font-family: sans-serif;\r
-}\r
-\r
-div#footer {\r
- font-family: sans-serif;\r
- font-size: small;\r
- border-top: 2px solid silver;\r
- padding-top: 0.5em;\r
- margin-top: 4.0em;\r
-}\r
-div#footer-text {\r
- float: left;\r
- padding-bottom: 0.5em;\r
-}\r
-div#footer-badges {\r
- float: right;\r
- padding-bottom: 0.5em;\r
-}\r
-\r
-div#preamble {\r
- margin-top: 1.5em;\r
- margin-bottom: 1.5em;\r
-}\r
-div.tableblock, div.imageblock, div.exampleblock, div.verseblock,\r
-div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,\r
-div.admonitionblock {\r
- margin-top: 0.25em;\r
- margin-bottom: 1.5em;\r
-}\r
-div.admonitionblock {\r
- margin-top: 2.5em;\r
- margin-bottom: 2.5em;\r
-}\r
-\r
-div.content { /* Block element content. */\r
- padding: 0;\r
-}\r
-\r
-/* Block element titles. */\r
-div.title, caption.title {\r
- color: #527bbd;\r
- font-family: sans-serif;\r
- font-weight: bold;\r
- text-align: left;\r
- margin-top: 1.0em;\r
- margin-bottom: 0.5em;\r
-}\r
-div.title + * {\r
- margin-top: 0;\r
-}\r
-\r
-td div.title:first-child {\r
- margin-top: 0.0em;\r
-}\r
-div.content div.title:first-child {\r
- margin-top: 0.0em;\r
-}\r
-div.content + div.title {\r
- margin-top: 0.0em;\r
-}\r
-\r
-div.sidebarblock > div.content {\r
- background: #ffffee;\r
- border: 1px solid silver;\r
- padding: 0.5em;\r
-}\r
-\r
-div.listingblock > div.content {\r
- border: 1px solid silver;\r
- background: #f4f4f4;\r
- padding: 0.5em;\r
-}\r
-\r
-div.quoteblock {\r
- padding-left: 2.0em;\r
- margin-right: 10%;\r
-}\r
-div.quoteblock > div.attribution {\r
- padding-top: 0.5em;\r
- text-align: right;\r
-}\r
-\r
-div.verseblock {\r
- padding-left: 2.0em;\r
- margin-right: 10%;\r
-}\r
-div.verseblock > div.content {\r
- white-space: pre;\r
-}\r
-div.verseblock > div.attribution {\r
- padding-top: 0.75em;\r
- text-align: left;\r
-}\r
-/* DEPRECATED: Pre version 8.2.7 verse style literal block. */\r
-div.verseblock + div.attribution {\r
- text-align: left;\r
-}\r
-\r
-div.admonitionblock .icon {\r
- vertical-align: top;\r
- font-size: 1.1em;\r
- font-weight: bold;\r
- text-decoration: underline;\r
- color: #527bbd;\r
- padding-right: 0.5em;\r
-}\r
-div.admonitionblock td.content {\r
- padding-left: 0.5em;\r
- border-left: 2px solid silver;\r
-}\r
-\r
-div.exampleblock > div.content {\r
- border-left: 2px solid silver;\r
- padding: 0.5em;\r
-}\r
-\r
-div.imageblock div.content { padding-left: 0; }\r
-span.image img { border-style: none; }\r
-a.image:visited { color: white; }\r
-\r
-dl {\r
- margin-top: 0.8em;\r
- margin-bottom: 0.8em;\r
-}\r
-dt {\r
- margin-top: 0.5em;\r
- margin-bottom: 0;\r
- font-style: normal;\r
- color: navy;\r
-}\r
-dd > *:first-child {\r
- margin-top: 0.1em;\r
-}\r
-\r
-ul, ol {\r
- list-style-position: outside;\r
-}\r
-ol.arabic {\r
- list-style-type: decimal;\r
-}\r
-ol.loweralpha {\r
- list-style-type: lower-alpha;\r
-}\r
-ol.upperalpha {\r
- list-style-type: upper-alpha;\r
-}\r
-ol.lowerroman {\r
- list-style-type: lower-roman;\r
-}\r
-ol.upperroman {\r
- list-style-type: upper-roman;\r
-}\r
-\r
-div.compact ul, div.compact ol,\r
-div.compact p, div.compact p,\r
-div.compact div, div.compact div {\r
- margin-top: 0.1em;\r
- margin-bottom: 0.1em;\r
-}\r
-\r
-div.tableblock > table {\r
- border: 3px solid #527bbd;\r
-}\r
-thead {\r
- font-family: sans-serif;\r
- font-weight: bold;\r
-}\r
-tfoot {\r
- font-weight: bold;\r
-}\r
-td > div.verse {\r
- white-space: pre;\r
-}\r
-p.table {\r
- margin-top: 0;\r
-}\r
-/* Because the table frame attribute is overriden by CSS in most browsers. */\r
-div.tableblock > table[frame="void"] {\r
- border-style: none;\r
-}\r
-div.tableblock > table[frame="hsides"] {\r
- border-left-style: none;\r
- border-right-style: none;\r
-}\r
-div.tableblock > table[frame="vsides"] {\r
- border-top-style: none;\r
- border-bottom-style: none;\r
-}\r
-\r
-\r
-div.hdlist {\r
- margin-top: 0.8em;\r
- margin-bottom: 0.8em;\r
-}\r
-div.hdlist tr {\r
- padding-bottom: 15px;\r
-}\r
-dt.hdlist1.strong, td.hdlist1.strong {\r
- font-weight: bold;\r
-}\r
-td.hdlist1 {\r
- vertical-align: top;\r
- font-style: normal;\r
- padding-right: 0.8em;\r
- color: navy;\r
-}\r
-td.hdlist2 {\r
- vertical-align: top;\r
-}\r
-div.hdlist.compact tr {\r
- margin: 0;\r
- padding-bottom: 0;\r
-}\r
-\r
-.comment {\r
- background: yellow;\r
-}\r
-\r
-@media print {\r
- div#footer-badges { display: none; }\r
-}\r
-\r
-div#toctitle {\r
- color: #527bbd;\r
- font-family: sans-serif;\r
- font-size: 1.1em;\r
- font-weight: bold;\r
- margin-top: 1.0em;\r
- margin-bottom: 0.1em;\r
-}\r
-\r
-div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {\r
- margin-top: 0;\r
- margin-bottom: 0;\r
-}\r
-div.toclevel2 {\r
- margin-left: 2em;\r
- font-size: 0.9em;\r
-}\r
-div.toclevel3 {\r
- margin-left: 4em;\r
- font-size: 0.9em;\r
-}\r
-div.toclevel4 {\r
- margin-left: 6em;\r
- font-size: 0.9em;\r
-}\r
-/* Workarounds for IE6's broken and incomplete CSS2. */\r
-\r
-div.sidebar-content {\r
- background: #ffffee;\r
- border: 1px solid silver;\r
- padding: 0.5em;\r
-}\r
-div.sidebar-title, div.image-title {\r
- color: #527bbd;\r
- font-family: sans-serif;\r
- font-weight: bold;\r
- margin-top: 0.0em;\r
- margin-bottom: 0.5em;\r
-}\r
-\r
-div.listingblock div.content {\r
- border: 1px solid silver;\r
- background: #f4f4f4;\r
- padding: 0.5em;\r
-}\r
-\r
-div.quoteblock-attribution {\r
- padding-top: 0.5em;\r
- text-align: right;\r
-}\r
-\r
-div.verseblock-content {\r
- white-space: pre;\r
-}\r
-div.verseblock-attribution {\r
- padding-top: 0.75em;\r
- text-align: left;\r
-}\r
-\r
-div.exampleblock-content {\r
- border-left: 2px solid silver;\r
- padding-left: 0.5em;\r
-}\r
-\r
-/* IE6 sets dynamically generated links as visited. */\r
-div#toc a:visited { color: blue; }\r
-</style>\r
-</head>\r
-<body>\r
-<div id="header">\r
-<h1>tpl ChangeLog</h1>\r
-</div>\r
-<h2 id="_version_1_5_2010_02_05">Version 1.5 (2010-02-05)</h2>\r
-<div class="sectionbody">\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-tpl now builds as a DLL under Microsoft Visual Studio! (thanks, degski and Zhang Yafei!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-there are now two download options: the <a href="http://downloads.sourceforge.net/tpl/libtpl-1.5.tar.bz2">tarball</a> and the Visual Studio <a href="http://downloads.sourceforge.net/tpl/tpl-1.5-vs2008.zip">solution</a>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-a crash in <tt>tpl_free</tt> on certain format strings has been fixed (thanks, Eric Rose!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-fixed a bug in <tt>tpl_dump</tt> on 64-bit, big-endian platforms\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-changed some pointer casts from <tt>long</tt> to <tt>uintptr_t</tt> since 64-bit Windows has 32-bit longs\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-tpl has been downloaded 4,195 times.\r
-</p>\r
-</li>\r
-</ul></div>\r
-</div>\r
-<h2 id="_version_1_4_2009_04_21">Version 1.4 (2009-04-21)</h2>\r
-<div class="sectionbody">\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-fixed-length arrays can now be multi-dimensional like <tt>i##</tt>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-fixed-length string arrays like <tt>s#</tt> are now supported\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-nested structures can now be expressed, using the dollar symbol, e.g. <tt>S(ci$(cc))</tt>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-<tt>tpl_dump</tt> can use a caller-allocated output buffer (<tt>TPL_MEM|TPL_PREALLOCD</tt>)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-<tt>tpl_load</tt> can tolerate excess space in input buffer (<tt>TPL_MEM|TPL_EXCESS_OK</tt>)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-implement <tt>TPL_FXLENS</tt> flag for <tt>tpl_peek</tt> to get lengths of fixed-length arrays\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-implement <tt>TPL_GETSIZE</tt> flag for <tt>tpl_dump</tt> to get dump size without dumping\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-fix success return code from <tt>tpl_dump(TPL_FD,...)</tt> (thanks, Max Lapan!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-deprecated the wildcard unpacking <tt>S(*)</tt> feature\r
-</p>\r
-</li>\r
-</ul></div>\r
-</div>\r
-<h2 id="_version_1_3_2009_02_10">Version 1.3 (2009-02-10)</h2>\r
-<div class="sectionbody">\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-added <tt>TPL_DATAPEEK</tt> mode for <tt>tpl_peek</tt>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added support for <tt>NULL</tt> strings\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added support for 16-bit integer types (<tt>j</tt>,<tt>v</tt>)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added <tt>tpl_jot</tt>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added support for fixed-length arrays of structures <tt>S(...)#</tt>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added support for pre-C99 compilers (thanks, Wei Wei!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-improved structure alignment calculation (thanks, Wu Yongwei!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added RPM spec file (thanks, Alessandro Ren!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-compiles cleanly with <tt>-Wall</tt> and <tt>-pedantic</tt> and with <tt>-O3</tt>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-made <a href="license.html">BSD license</a> terms even more permissive\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-test suite: exit with status zero when all tests pass\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added PDF user guide\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added <a href="http://troydhanson.wordpress.com/feed/">update news</a> <span class="image">\r
-<img src="img/rss.png" alt="(RSS)" />\r
-</span>\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-added <a href="http://apps.sourceforge.net/mediawiki/tpl/">tpl wiki</a>\r
-</p>\r
-</li>\r
-</ul></div>\r
-</div>\r
-<h2 id="_version_1_2_2007_04_27">Version 1.2 (2007-04-27)</h2>\r
-<div class="sectionbody">\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-Perl API and XML converter support 64-bit types\r
-</p>\r
-</li>\r
-</ul></div>\r
-</div>\r
-<h2 id="_version_1_1_2007_04_25">Version 1.1 (2007-04-25)</h2>\r
-<div class="sectionbody">\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-support for serializing C structures\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-support for serializing fixed-length arrays\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-MinGW support (thanks, Horea Haitonic!)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-revised User Guide\r
-</p>\r
-</li>\r
-</ul></div>\r
-</div>\r
-<h2 id="_version_1_0_2006_09_28">Version 1.0 (2006-09-28)</h2>\r
-<div class="sectionbody">\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-Initial version\r
-</p>\r
-</li>\r
-</ul></div>\r
-</div>\r
-<div id="footer">\r
-<div id="footer-text">\r
-Last updated 2010-02-05 19:31:37 PDT\r
-</div>\r
-</div>\r
-</body>\r
-</html>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="728px"
- height="90px"
- id="svg1323"
- sodipodi:version="0.32"
- inkscape:version="0.44"
- sodipodi:docbase="/home/thanson/code/tpl/trunk/doc/html/img"
- sodipodi:docname="banner.svg"
- inkscape:export-filename="/home/thanson/code/tpl/trunk/doc/html/img/banner.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs1325">
- <linearGradient
- id="linearGradient22211">
- <stop
- style="stop-color:#2e7ce0;stop-opacity:0;"
- offset="0"
- id="stop22237" />
- <stop
- id="stop22215"
- offset="1"
- style="stop-color:#2e7ce0;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient20106">
- <stop
- style="stop-color:#f0f3f7;stop-opacity:1;"
- offset="0"
- id="stop20108" />
- <stop
- style="stop-color:#f0f3f7;stop-opacity:0;"
- offset="1"
- id="stop20110" />
- </linearGradient>
- <linearGradient
- id="linearGradient19154">
- <stop
- style="stop-color:#005fd9;stop-opacity:1;"
- offset="0"
- id="stop19156" />
- <stop
- style="stop-color:#005fd9;stop-opacity:0;"
- offset="1"
- id="stop19158" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient19142">
- <stop
- style="stop-color:#4ec2f0;stop-opacity:1;"
- offset="0"
- id="stop19144" />
- <stop
- style="stop-color:#4ec2f0;stop-opacity:0;"
- offset="1"
- id="stop19146" />
- </linearGradient>
- <linearGradient
- id="linearGradient19132">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop19134" />
- <stop
- id="stop19140"
- offset="0.5"
- style="stop-color:#00d1f6;stop-opacity:0.49803922;" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop19136" />
- </linearGradient>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19142"
- id="radialGradient19150"
- cx="651"
- cy="50"
- fx="651"
- fy="50"
- r="49.5"
- gradientTransform="matrix(1,0,0,0.616162,1.124101e-15,19.19192)"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient19160"
- x1="588"
- y1="47"
- x2="722"
- y2="47"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient19224"
- gradientUnits="userSpaceOnUse"
- x1="588"
- y1="47"
- x2="722"
- y2="47"
- gradientTransform="matrix(5.590915,0,0,1.101015,-3310.4,161.4223)" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient20106"
- id="radialGradient20112"
- cx="125.1579"
- cy="213.03658"
- fx="125.1579"
- fy="213.03658"
- r="27.577164"
- gradientTransform="matrix(1,0,0,0.923077,0,16.38742)"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient20176"
- gradientUnits="userSpaceOnUse"
- x1="588"
- y1="47"
- x2="722"
- y2="47"
- gradientTransform="translate(-38.18377,318.1981)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient20203"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-38.18377,318.1981)"
- x1="588"
- y1="47"
- x2="722"
- y2="47" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient20269"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-38.18377,318.1981)"
- x1="588"
- y1="47"
- x2="722"
- y2="47" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient20389"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.755096,0,0,1.101015,-1053.937,335.4223)"
- x1="588"
- y1="47"
- x2="722"
- y2="47" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient22243"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.867037,0,0,1.101015,-1120.758,425.4223)"
- x1="588"
- y1="47"
- x2="722"
- y2="47" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient24137"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.755096,0,0,1.101015,-1052.937,435.4223)"
- x1="588"
- y1="47"
- x2="722"
- y2="47" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19154"
- id="linearGradient24144"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.755096,0,0,1.101015,-1049.937,270.4223)"
- x1="588"
- y1="47"
- x2="722"
- y2="47" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="497.48754"
- inkscape:cy="-4.5816549"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- inkscape:window-width="1176"
- inkscape:window-height="633"
- inkscape:window-x="23"
- inkscape:window-y="48" />
- <metadata
- id="metadata1328">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- id="layer1"
- inkscape:label="Layer 1"
- inkscape:groupmode="layer">
- <rect
- style="fill:#3c85e2;fill-opacity:1;fill-rule:nonzero;stroke:#ffcb53;stroke-width:4.0415926;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect20271"
- width="240.0993"
- height="77.071068"
- x="4.1015167"
- y="3.6345825"
- rx="29.60623" />
- <rect
- y="46.014687"
- x="-236.92256"
- height="16.982321"
- width="16.982321"
- id="rect24091"
- style="fill:#2fa4db;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- transform="scale(-1,1)" />
- <rect
- y="46.014687"
- x="-219.80927"
- height="16.982321"
- width="16.982321"
- id="rect24093"
- style="fill:#2fa4db;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- transform="scale(-1,1)" />
- <rect
- style="fill:#2fa4db;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect24095"
- width="16.982321"
- height="16.982321"
- x="-202.92258"
- y="46.014687"
- transform="scale(-1,1)" />
- <path
- sodipodi:type="arc"
- style="fill:#e33019;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24097"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- transform="translate(-102.0443,123.8305)" />
- <path
- transform="translate(-76.04438,87.8305)"
- sodipodi:type="arc"
- style="fill:#e38c19;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24099"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z" />
- <path
- transform="translate(-64.0444,105.8305)"
- sodipodi:type="arc"
- style="fill:#88dfdb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24101"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24103"
- style="fill:#79c71a;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="translate(-76.04438,123.8305)" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24105"
- style="fill:#f5e1a2;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="translate(-88.04433,105.8305)" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24107"
- style="fill:#d8643e;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(-1,0,0,1,460.1983,124.4007)" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24109"
- style="fill:#d8643e;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(-1,0,0,1,442.9488,124.4007)" />
- <path
- transform="matrix(-1,0,0,1,426.1983,124.4007)"
- sodipodi:type="arc"
- style="fill:#d8643e;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24111"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- d="M 146.68046,40.305464 L 153.06062,49.875694"
- id="path24113"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- d="M 146.68046,31.875694 L 153.06062,22.305464"
- id="path24115"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;marker-end:none;stroke-opacity:1"
- d="M 158.68046,22.305464 L 165.06062,31.875694"
- id="path24117"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 224.06859,54.660809 L 215.24887,54.660809"
- id="path24119"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 206.81911,54.660809 L 198.49837,54.660809"
- id="path24121"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- d="M 140.5923,40.305464 L 133.14878,49.875694"
- id="path24123"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 198.08195,67.740894 L 198.08195,67.740894"
- id="path24125"
- inkscape:connector-type="polyline" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24127"
- style="fill:#d8643e;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(-1,0,0,1,410.1983,124.4007)" />
- <path
- inkscape:connector-type="polyline"
- id="path24129"
- d="M 190.81911,54.660809 L 182.49837,54.660809"
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 170.23387,40.305398 L 175.92003,50.445833"
- id="path24131"
- inkscape:connector-type="polyline" />
- <text
- xml:space="preserve"
- style="font-size:57.24448395px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ff8900;fill-opacity:1;stroke:#ffc900;stroke-width:2.58558559px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.95530725;font-family:Bitstream Vera Sans Mono"
- x="13.482153"
- y="61.413116"
- id="text24133"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan24135"
- x="13.482153"
- y="61.413116"
- style="font-size:57.24448395px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ff8900;fill-opacity:1;stroke:#ffc900;stroke-opacity:0.95530725;font-family:Bitstream Vera Sans Mono">tpl</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:33.35416794px;font-style:normal;font-weight:normal;fill:#ff8900;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
- x="313.95825"
- y="31.16275"
- id="text24140"><tspan
- sodipodi:role="line"
- id="tspan24142"
- x="313.95825"
- y="31.16275"
- style="stroke:none;stroke-opacity:1">easily store and retrieve </tspan><tspan
- sodipodi:role="line"
- x="313.95825"
- y="72.85546"
- style="font-weight:bold;stroke:none;stroke-opacity:1"
- id="tspan1941">binary data in C</tspan><tspan
- sodipodi:role="line"
- x="313.95825"
- y="114.54817"
- style="stroke:none;stroke-opacity:1"
- id="tspan1939" /></text>
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="744.09448819"
- height="1052.3622047"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.43"
- sodipodi:docbase="/home/thanson/code/tpl/doc/html/img"
- sodipodi:docname="grad_cyan.svg">
- <defs
- id="defs4">
- <linearGradient
- id="linearGradient2194">
- <stop
- style="stop-color:#1190ed;stop-opacity:1;"
- offset="0"
- id="stop2196" />
- <stop
- style="stop-color:#f9f9f9;stop-opacity:0;"
- offset="1"
- id="stop2198" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient2184">
- <stop
- style="stop-color:#0000e0;stop-opacity:1;"
- offset="0"
- id="stop2186" />
- <stop
- style="stop-color:#0000e0;stop-opacity:0;"
- offset="1"
- id="stop2188" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2184"
- id="linearGradient2190"
- x1="76.642857"
- y1="679.50504"
- x2="523.35714"
- y2="679.50504"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2194"
- id="linearGradient2200"
- x1="335.5"
- y1="654.61218"
- x2="506"
- y2="654.61218"
- gradientUnits="userSpaceOnUse" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="2"
- inkscape:cx="488.2215"
- inkscape:cy="372.85714"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- inkscape:window-width="797"
- inkscape:window-height="575"
- inkscape:window-x="112"
- inkscape:window-y="25" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <rect
- style="opacity:0.96629214;fill:url(#linearGradient2200);fill-opacity:1.0;stroke:none;stroke-width:4.68499994;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect2192"
- width="170.5"
- height="9.5"
- x="335.5"
- y="649.86218"
- inkscape:export-filename="/home/thanson/code/tpl/doc/html/img/grad_cyan.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="105.05521"
- height="34.90324"
- id="svg2267"
- sodipodi:version="0.32"
- inkscape:version="0.44"
- version="1.0"
- sodipodi:docbase="/home/thanson/code/uthash/trunk/doc/html/img"
- sodipodi:docname="tpl-mini.svg">
- <defs
- id="defs3" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="63.027613"
- inkscape:cy="11.686998"
- inkscape:document-units="mm"
- inkscape:current-layer="layer1"
- width="118.44px"
- height="22.66px"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-width="916"
- inkscape:window-height="626"
- inkscape:window-x="15"
- inkscape:window-y="95">
- <sodipodi:guide
- orientation="horizontal"
- position="28.768574"
- id="guide2299" />
- </sodipodi:namedview>
- <metadata
- id="metadata2271">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-69.67658,-43.42744)">
- <rect
- style="fill:#3c85e2;fill-opacity:1;fill-rule:nonzero;stroke:#ffcb53;stroke-width:1.73912036;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect20271"
- width="103.31609"
- height="33.16412"
- x="70.546143"
- y="44.296997"
- rx="12.739729" />
- <rect
- y="62.533398"
- x="-170.73035"
- height="7.3075895"
- width="7.3075895"
- id="rect24091"
- style="fill:#2fa4db;fill-opacity:1;stroke:black;stroke-width:0.43030569;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- transform="scale(-1,1)" />
- <rect
- y="62.533398"
- x="-163.36638"
- height="7.3075895"
- width="7.3075895"
- id="rect24093"
- style="fill:#2fa4db;fill-opacity:1;stroke:black;stroke-width:0.43030569;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- transform="scale(-1,1)" />
- <rect
- style="fill:#2fa4db;fill-opacity:1;stroke:black;stroke-width:0.43030569;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect24095"
- width="7.3075895"
- height="7.3075895"
- x="-156.09996"
- y="62.533398"
- transform="scale(-1,1)" />
- <path
- sodipodi:type="arc"
- style="fill:#e33019;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24097"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- transform="matrix(0.430306,0,0,0.430306,24.87099,96.01799)" />
- <path
- transform="matrix(0.430306,0,0,0.430306,36.05889,80.52698)"
- sodipodi:type="arc"
- style="fill:#e38c19;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24099"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z" />
- <path
- transform="matrix(0.430306,0,0,0.430306,41.22256,88.27247)"
- sodipodi:type="arc"
- style="fill:#88dfdb;fill-opacity:1;fill-rule:nonzero;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24101"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24103"
- style="fill:#79c71a;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(0.430306,0,0,0.430306,36.05889,96.01799)" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24105"
- style="fill:#f5e1a2;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(0.430306,0,0,0.430306,30.89524,88.27247)" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24107"
- style="fill:#d8643e;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(-0.430306,0,0,0.430306,266.8073,96.26334)" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24109"
- style="fill:#d8643e;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(-0.430306,0,0,0.430306,259.3847,96.26334)" />
- <path
- transform="matrix(-0.430306,0,0,0.430306,252.1769,96.26334)"
- sodipodi:type="arc"
- style="fill:#d8643e;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path24111"
- sodipodi:cx="231.91481"
- sodipodi:cy="-69.739944"
- sodipodi:rx="3.7148824"
- sodipodi:ry="3.7148824"
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- d="M 131.89866,60.076683 L 134.64408,64.194808"
- id="path24113"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- d="M 131.89866,56.449305 L 134.64408,52.33118"
- id="path24115"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:square;stroke-linejoin:miter;marker-end:none;stroke-opacity:1"
- d="M 137.06234,52.33118 L 139.80775,56.449305"
- id="path24117"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 165.19922,66.25387 L 161.40404,66.25387"
- id="path24119"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 157.77667,66.25387 L 154.19622,66.25387"
- id="path24121"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- d="M 129.2789,60.076683 L 126.07591,64.194808"
- id="path24123"
- inkscape:connector-type="polyline" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 154.01702,71.882304 L 154.01702,71.882304"
- id="path24125"
- inkscape:connector-type="polyline" />
- <path
- d="M 235.62969 -69.739944 A 3.7148824 3.7148824 0 1 1 228.19993,-69.739944 A 3.7148824 3.7148824 0 1 1 235.62969 -69.739944 z"
- sodipodi:ry="3.7148824"
- sodipodi:rx="3.7148824"
- sodipodi:cy="-69.739944"
- sodipodi:cx="231.91481"
- id="path24127"
- style="fill:#d8643e;fill-opacity:1;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- sodipodi:type="arc"
- transform="matrix(-0.430306,0,0,0.430306,245.292,96.26334)" />
- <path
- inkscape:connector-type="polyline"
- id="path24129"
- d="M 150.89178,66.25387 L 147.31131,66.25387"
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.43030569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 142.03383,60.076654 L 144.48062,64.440141"
- id="path24131"
- inkscape:connector-type="polyline" />
- <text
- xml:space="preserve"
- style="font-size:24.63262939px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ff8900;fill-opacity:1;stroke:#ffc900;stroke-width:1.11259222px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.95530725;font-family:Bitstream Vera Sans Mono"
- x="74.58268"
- y="69.159424"
- id="text24133"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan24135"
- x="74.58268"
- y="69.159424"
- style="font-size:24.63262939px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ff8900;fill-opacity:1;stroke:#ffc900;stroke-width:1.11259222;stroke-opacity:0.95530725;font-family:Bitstream Vera Sans Mono">tpl</tspan></text>
- </g>
-</svg>
+++ /dev/null
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XTHML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <link rel="stylesheet" type="text/css" href="styles.css" />
- <title>tpl home page</title>
- </head>
- <body>
-
- <div id="banner">
- <img src="img/banner.png" alt="easy data storage and retrieval in C" />
- </div> <!-- banner -->
-
- <div id="topnav">
- <a href="http://sourceforge.net/projects/tpl/">sf.net summary page</a> >
- tpl home
- </div> <!-- topnav -->
-
- <hr />
- <div id="mid">
-
- <div id="nav">
-
-
- <h2>documentation</h2>
- <div><a href="userguide.html">user guide</a> (<a href="userguide.html">html</a>, <a href="userguide.pdf">pdf</a>)</div>
-
- <h2>download</h2>
- <h3>Linux, Mac OSX, Solaris, BSD</h3>
- <div><a href="http://downloads.sourceforge.net/tpl/libtpl-1.5.tar.bz2">libtpl-1.5.tar.bz2</a></div>
- <h3>Visual Studio 2008 Solution</h3>
- <div><a href="http://downloads.sourceforge.net/tpl/tpl-1.5-vs2008.zip">tpl-1.5-vs2008.zip</a></div>
-
- <h2>last release</h2>
- <div>February, 2010</div>
- <div><a href="ChangeLog.html">ChangeLog</a></div>
-
- <h2>license</h2>
- <div><a href="license.html">BSD revised</a></div>
-
- <h2>news feed</h2>
- <div><a href="http://troydhanson.wordpress.com/">updates blog</a> (<a href="http://troydhanson.wordpress.com/feed/">rss</a>)<img alt=" rss" src="img/rss.png"/></div>
-
- <h2>platforms</h2>
- <div>linux</div>
- <div>os x</div>
- <div>windows</div>
- <div>solaris</div>
- <div>openbsd</div>
-
- <h2>other projects</h2>
- <div><a href="http://uthash.sourceforge.net/">uthash</a></div>
- <div><a href="http://tkhanson.net/misc/">scripts & snippets</a></div>
-
- <h2>developer</h2>
- <div>Troy D. Hanson</div>
- <div>tdh at tkhanson.net</div>
-
- </div> <!-- nav -->
-
- <div id="main">
-
-<div>
-<div class="lead">Efficient serialization in C</div>
-You can use tpl to store and reload your C data quickly and easily.
-Tpl works with files, memory buffers and file descriptors so it's
-suitable for use as a file format, IPC message format or any scenario
-where you need to store and retrieve your data.
-</div>
-
-<div>
-<div class="lead">Express your data</div>
-Just express the type of data you are working with as a tpl format string. For
-example, if you have a list of numeric ids and corresponding usernames, your
-format string is <em>A(is)</em>. Map your C variables to the format string and
-then pack or unpack data. The format string lets you focus on your data,
-rather than the storage format.
-</div>
-
-<div class="listing">
-<table summary="example of storing and reloading an integer array">
-<tr>
-<th>
-Storing ids and usernames
-</th>
-<th>
-Reloading ids and usernames
-</th>
-</tr>
-<tr>
-<td>
-<div class="code">
-<pre>
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- int id=0;
- char *name, *names[] = { "joe", "bob", "cary" };
-
- tn = tpl_map("A(is)", &id, &name);
-
- for(name=names[0]; id < 3; name=names[++id]) {
- tpl_pack(tn,1);
- }
-
- tpl_dump(tn, TPL_FILE, "users.tpl");
- tpl_free(tn);
-}
-</pre>
-</div> <!-- code -->
-</td>
-<td>
-<div class="code">
-<pre>
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- int id;
- char *name;
-
- tn = tpl_map("A(is)", &id, &name);
- tpl_load(tn, TPL_FILE, "users.tpl");
-
- while ( tpl_unpack(tn,1) > 0 ) {
- printf("id %d, user %s\n", id, name);
- free(name);
- }
- tpl_free(tn);
-}
-</pre>
-</div> <!-- code -->
-</td>
-</tr>
-</table>
-</div> <!-- listing -->
-
-<div>
-<div class="lead">No library dependencies</div>
-Tpl does not make your software dependent on any libraries. You can compile its
-source code (one file) right into your program.
-</div>
-
-<div class="lead">For more information</div>
-For a more thorough explanation and more examples, please read the
-<a href="userguide.html">User Guide.</a>
-
-</div> <!-- main -->
-</div> <!-- mid -->
-
- <hr />
- <div id="footer">
- <a href="http://sourceforge.net/projects/tpl"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=157637&type=13" width="120" height="30" alt="SourceForge.net." /></a>
- <p>This project is hosted on SourceForge.net</p>
- <p>$Id: index.html 192 2009-04-24 10:35:30Z thanson $</p>
- </div> <!-- footer -->
-
- </body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XTHML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <link rel="stylesheet" type="text/css" href="styles.css" />
- <title>tpl home page</title>
- </head>
- <body>
-
- <div id="banner">
- <img src="img/banner.png" alt="serialization in C: easy data storage and retrieval" />
- </div> <!-- banner -->
-
- <div id="topnav">
- <a href="http://sourceforge.net/projects/tpl/">sf.net summary page</a> >
- <a href="index.html">tpl home</a> >
- BSD license
- </div> <!-- topnav -->
-
- <hr />
- <div id="mid">
-
-
- <div id="main">
-
-<pre>
-Copyright (c) 2005-2010, Troy D. Hanson http://tpl.sourceforge.net
-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.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-</pre>
-</div> <!-- main -->
-</div> <!-- mid -->
-
- <hr />
- <div id="footer">
- <a href="http://sourceforge.net/projects/tpl"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=157637&type=13" width="120" height="30" alt="SourceForge.net." /></a>
- <p>This project is hosted on SourceForge.net</p>
- <p>$Id: index.html 124 2007-04-27 06:41:36Z thanson $</p>
- </div> <!-- footer -->
-
- </body>
-
-</html>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
-<meta name="generator" content="AsciiDoc 8.3.4" />\r
-<title>tpl Perl API</title>\r
-<link rel="stylesheet" href="./tdh.css" type="text/css" />\r
-<link rel="stylesheet" href="./tdh-quirks.css" type="text/css" />\r
-</head>\r
-<body>\r
-<div id="header">\r
-<h1>tpl Perl API</h1>\r
-<span id="author">Troy D. Hanson</span><br />\r
-<span id="email"><tt><<a href="mailto:troydhanson@comcast.net">troydhanson@comcast.net</a>></tt></span><br />\r
-<span id="revision">version 1.1,</span>\r
-April 2007\r
-</div>\r
-<div id="preamble">\r
-<div class="sectionbody">\r
-<a style="float: right;" href="http://sourceforge.net/projects/tpl"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=157637&type=16" width="150" height="40" alt="SourceForge.net" /></a>\r
- <div id="topnav" style="font-size: 9pt; font-family: sans-serif;">\r
- <a style="padding: 8px;" href="http://sourceforge.net/projects/tpl/">sf.net summary page</a> >\r
- <a style="padding: 8px;" href="index.html">tpl home</a> >\r
- tpl Perl API\r
- <a style="padding: 8px;" href="userguide.pdf">[View PDF]</a>\r
- </div>\r
-</div>\r
-</div>\r
-<h2 id="_perl_api">Perl API</h2>\r
-<div class="sectionbody">\r
-<div id="toc"></div>\r
-<script>\r
-window.onload=generate_TOC\r
-\r
-/* Author: Mihai Bazon, September 2002\r
- * <a href="http://students.infoiasi.ro/~mishoo">http://students.infoiasi.ro/~mishoo</a>\r
- *\r
- * Table Of Content generator\r
- * Version: 0.4\r
- *\r
- * Feel free to use this script under the terms of the GNU General Public\r
- * License, as long as you do not remove or alter this notice.\r
- */\r
-\r
- /* modified by Troy D. Hanson, September 2006. License: GPL */\r
-\r
-function H_getText(el) {\r
- var text = "";\r
- for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
- if (i.nodeType == 3 /* Node.TEXT_NODE, IE doesn't speak constants */)\r
- text += i.data;\r
- else if (i.firstChild != null)\r
- text += H_getText(i);\r
- }\r
- return text;\r
-}\r
-\r
-function TOC_EL(el, text, level) {\r
- this.element = el;\r
- this.text = text;\r
- this.level = level;\r
-}\r
-\r
-function getHeadlines(el) {\r
- var l = new Array;\r
- var rx = /[hH]([2-3])/;\r
- // internal recursive function that scans the DOM tree\r
- var rec = function (el) {\r
- for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
- if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {\r
- if (rx.exec(i.tagName))\r
- l[l.length] = new TOC_EL(i, H_getText(i), parseInt(RegExp.$1));\r
- rec(i);\r
- }\r
- }\r
- }\r
- rec(el);\r
- return l;\r
-}\r
-\r
-function generate_TOC() {\r
- var parent = document.getElementById("toc");\r
- var toc_hdr = document.createElement("div");\r
- var toc_hdr_txt = document.createTextNode("CONTENTS");\r
- toc_hdr.appendChild(toc_hdr_txt);\r
- /* toc_hdr.setAttribute("id","hdr"); */\r
- toc_hdr.id = "hdr";\r
- parent.appendChild(toc_hdr);\r
- var hs = getHeadlines(document.getElementsByTagName("body")[0]);\r
- for (var i = 0; i < hs.length; ++i) {\r
- var hi = hs[i];\r
- var d = document.createElement("div");\r
- if (hi.element.id == "") hi.element.id = "gen" + i;\r
- var a = document.createElement("a");\r
- a.href = "#" + hi.element.id;\r
- a.appendChild(document.createTextNode(hi.text));\r
- d.appendChild(a);\r
- d.className = "level" + hi.level;\r
- parent.appendChild(d);\r
- /*\r
- if (hi.level == 3) {\r
- var dvtop = document.createElement("div");\r
- dvtop.className = "toplink";\r
- dvtop.appendChild(document.createTextNode("^top^"));\r
- dvtop.onclick=function(){scrollTo(0,0);};\r
- hi.element.appendChild(dvtop);\r
- }\r
- */\r
- }\r
-}\r
-</script>\r
-<div class="paragraph"><p>The Perl API for reading and writing tpl is nearly identical to the C API. This\r
-document will briefly explain the Perl API and provide examples. The chief\r
-motivation for having a Perl API is to communicate with C programs that use tpl.</p></div>\r
-<div class="admonitionblock">\r
-<table><tr>\r
-<td class="icon">\r
-<div class="title">Tip</div>\r
-</td>\r
-<td class="content">\r
-<div class="title">Start with the C API</div>This document assumes familiarity with the C API. The concepts of using tpl\r
-are not explained here. For an introduction to tpl and its C API, see the\r
-<a href="userguide.html">User Guide</a>.</td>\r
-</tr></table>\r
-</div>\r
-<h3 id="_tpl_pm">Tpl.pm</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The <tt>Tpl.pm</tt> file (in the <tt>lang/perl</tt>) directory contains the Perl module. You\r
-can copy it to another directory if you wish. Your Perl program may need to\r
-include a <tt>use lib</tt> statement to find the module.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>#!/usr/bin/perl\r
-use lib "/some/directory";\r
-use Tpl;</tt></pre>\r
-</div></div>\r
-<h3 id="_tpl_map">tpl_map</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This function resembles the C version, except that it’s invoked via the <tt>Tpl</tt>\r
-module, and it takes references to Perl variables after the format string.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>my $i;\r
-my $tpl = Tpl->tpl_map("A(i)",\$i);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The return value is a tpl object; all other API calls are object methods.\r
-Incidentally, there is no <tt>tpl_free()</tt> method corresponding to the C API.</p></div>\r
-<h4 id="_fixed_length_arrays">Fixed-length arrays</h4>\r
-<div class="paragraph"><p>Format strings such as <tt>i#</tt> denote a fixed-length array. In the Perl API,\r
-fixed-length arrays require two arguments: a list reference, and the fixed\r
-length. For example:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>my @x;\r
-my $tpl = Tpl->tpl_map("i#", \@x, 10);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>When fixed-length arrays are packed or unpacked, the specified number of\r
-elements will be copied from (or placed into) the designated list.</p></div>\r
-<h4 id="_structures">Structures</h4>\r
-<div class="paragraph"><p>Format strings containing <tt>S(…)</tt> are handled in the Perl API as if only the\r
-interior, parenthesized part was present. (It does not work like the C API). So\r
-simply ignore the <tt>S(…)</tt> and consider only its interior format characters when\r
-constructing the argument list:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>my ($str, $int);\r
-my $tpl = Tpl->tpl_map("S(si)", \$str, \$int);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>It really only makes sense to use <tt>S(…)</tt> in a format string in the Perl API if\r
-you are communicating with a C program that uses structures.</p></div>\r
-<h3 id="_tpl_pack">tpl_pack</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This is nearly identical to the C version. The only argument is the index\r
-number to pack.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$tpl->tpl_pack(1);</tt></pre>\r
-</div></div>\r
-<h3 id="_tpl_dump">tpl_dump</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This method is a little different than the C version. Given no arguments, it\r
-returns the tpl image; given one argument it writes a file with that name.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$tpl->tpl_dump("demo.tpl"); # writes demo.tpl</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Or,</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>my $img = $tpl->tpl_dump();</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The tpl image is a binary buffer. You can do whatever you want with it, such as\r
-write it to a socket or pipe (probably to C program listening on the other end),\r
-or save it somewhere and later re-load it using <tt>tpl_load()</tt>.</p></div>\r
-<h3 id="_tpl_load">tpl_load</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This method loads a tpl image from a file or from a Perl variable. It takes\r
-one argument. If it’s not a reference, it’s assumed to be a filename to load.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$tpl->tpl_load("demo.tpl");</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Otherwise, if the argument is a Perl reference, it’s construed as a variable\r
-containing the tpl image:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$tpl->tpl_load(\$img);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The method will <tt>die</tt> if the image is invalid or the file doesn’t exist. You\r
-can wrap it with <tt>eval</tt> to catch such errors:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>eval { $tpl->tpl_load(\$img); };\r
-print "failed to load\n" if $@;</tt></pre>\r
-</div></div>\r
-<h3 id="_tpl_unpack">tpl_unpack</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This is nearly identical to the C version. The only argument is the index\r
-number to unpack.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>$tpl->tpl_unpack(1);</tt></pre>\r
-</div></div>\r
-</div>\r
-<h2 id="_examples">Examples</h2>\r
-<div class="sectionbody">\r
-<h3 id="_integer_array">Integer array</h3><div style="clear:left"></div>\r
-<div class="listingblock">\r
-<div class="title">Packing A(i) to file</div>\r
-<div class="content">\r
-<pre><tt>#!/usr/bin/perl\r
-\r
-use strict;\r
-use warnings;\r
-\r
-use Tpl;\r
-\r
-my $i;\r
-my $tpl = Tpl->tpl_map("A(i)",\$i);\r
-for($i=0; $i<10; $i++) {\r
- $tpl->tpl_pack(1);\r
-}\r
-$tpl->tpl_dump("demo.tpl");</tt></pre>\r
-</div></div>\r
-<div class="listingblock">\r
-<div class="title">Unpacking A(i) from file</div>\r
-<div class="content">\r
-<pre><tt>#!/usr/bin/perl\r
-\r
-use strict;\r
-use warnings;\r
-\r
-use Tpl;\r
-\r
-my $j;\r
-my $tpl2 = Tpl->tpl_map("A(i)",\$j);\r
-$tpl2->tpl_load("demo.tpl");\r
-while($tpl2->tpl_unpack(1) > 0) {\r
- print "$j\n";\r
-}</tt></pre>\r
-</div></div>\r
-<h3 id="_message_passing">Message-passing</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>While the bulk of this example is socket handling, it demonstrates how you can\r
-use tpl as a message-passing format. In the real-world, you might have a C\r
-server and a Perl client, for example. In this example, we’ll code both a client\r
-and a server in Perl.</p></div>\r
-<div class="sidebarblock">\r
-<div class="sidebar-content">\r
-<div class="sidebar-title">A server that sums integers</div>\r
-<div class="paragraph"><p>Programming literature is rife with contrived examples so we will follow in that\r
-tradition. Our server will do no more than sum a list of integers. But in doing\r
-so it will demonstrate message passing adequately. Both its input (the integer\r
-array) and its output (an integer) are tpl images, passed over a TCP/IP socket.</p></div>\r
-</div></div>\r
-<h4 id="_server">Server</h4>\r
-<div class="paragraph"><p>The server waits for a connection from a client. When it gets one, it accepts\r
-the connection and immediately forks a child process to handle it. Then it goes\r
-back to waiting for another new connection.</p></div>\r
-<div class="paragraph"><p>The server child process handles the client by loading and unpacking the tpl\r
-image sent by the client (containing an array of integers). It calculates their\r
-sum and constructs a new tpl image containing the sum, which it sends back to\r
-the client.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Server</div>\r
-<div class="content">\r
-<pre><tt>#!/usr/bin/perl\r
-\r
-use strict;\r
-use warnings;\r
-\r
-use IO::Socket::INET;\r
-use Tpl;\r
-\r
-$SIG{CHLD} = "IGNORE"; # don't create zombies\r
-\r
-our $port = 2000;\r
-\r
-sub handle_client {\r
- my $client = shift;\r
-\r
- undef $/;\r
- my $request = <$client>; # get request (slurp)\r
-\r
- # read input array, and calculate total\r
- my ($i,$total);\r
- my $tpl = Tpl->tpl_map("A(i)", \$i);\r
- eval { $tpl->tpl_load(\$request); };\r
- die "received invalid tpl" if $@;\r
- $total += $i while $tpl->tpl_unpack(1) > 0;\r
-\r
- # formulate response and send\r
- my $tpl2 = Tpl->tpl_map("i", \$total);\r
- $tpl2->tpl_pack(0);\r
- my $response = $tpl2->tpl_dump();\r
- print $client $response;\r
- close $client;\r
-}\r
-\r
-my $server = IO::Socket::INET->new(LocalPort => $port,\r
- Type => SOCK_STREAM,\r
- Reuse => 1,\r
- Listen => 10 )\r
- or die "Can't listen on port $port: $!\n";\r
-\r
-while (1) {\r
- my $client = $server->accept();\r
- next unless $client;\r
- # new connection\r
- my $pid = fork;\r
- die "can't fork: $!\n" unless defined $pid;\r
- if ($pid > 0) {\r
- # parent\r
- close $client;\r
- } elsif ($pid == 0) {\r
- # child\r
- handle_client($client);\r
- exit(0);\r
- }\r
-}\r
-close ($server);</tt></pre>\r
-</div></div>\r
-<h4 id="_client">Client</h4>\r
-<div class="paragraph"><p>The client is a simpler program. It constructs the tpl image containing the\r
-integer array (taken from its command-line arguments), connects to the server\r
-and sends the tpl image to it, and then awaits the response tpl. The response\r
-containing the sum is loaded, unpacked and printed.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Client</div>\r
-<div class="content">\r
-<pre><tt>#!/usr/bin/perl\r
-\r
-use strict;\r
-use warnings;\r
-\r
-use IO::Socket::INET;\r
-use Tpl;\r
-\r
-our $port = 2000;\r
-\r
-# construct tpl\r
-my $i;\r
-my $tpl = Tpl->tpl_map("A(i)",\$i);\r
-$tpl->tpl_pack(1) while ($i=shift @ARGV);\r
-my $request = $tpl->tpl_dump();\r
-\r
-# send to server, get response\r
-my $socket = IO::Socket::INET->new("localhost:$port") or die "can't connect";\r
-print $socket $request;\r
-shutdown($socket,1); # done writing (half-close)\r
-undef $/;\r
-my $response = <$socket>; # get reply (slurp)\r
-\r
-# decode response (or print error)\r
-my $total;\r
-my $tpl2 = Tpl->tpl_map("i", \$total);\r
-eval { $tpl2->tpl_load(\$response); };\r
-die "invalid response\n" if $@;\r
-$tpl2->tpl_unpack(0);\r
-print "total is $total\n";</tt></pre>\r
-</div></div>\r
-<h4 id="_running_thise_example">Running thise example</h4>\r
-<div class="paragraph"><p>If the client and server programs are in <tt>client.pl</tt> and <tt>server.pl</tt>, then\r
-you can run the example by starting the server in one window:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>./server.pl</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Then run the client in another window. E.g.,</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>./client.pl 1 2 3 4 5</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The client runs and then exits, printing:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>total is 15</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>You can re-run the client with different arguments. When done, type <tt>Ctrl-C</tt> in\r
-the server window to terminate it.</p></div>\r
-</div>\r
-<div id="footer">\r
-<div id="footer-text">\r
-Version 1.1<br />\r
-Last updated 2009-04-30 21:22:12 EDT\r
-</div>\r
-</div>\r
-</body>\r
-</html>\r
+++ /dev/null
-#banner {
- /* font-size: x-large; */
- /* background: #ff00ff; */
- /* height: 100px; */
-}
-
-#topnav {
- /* background-image: url(img/grad_topnav.png); */
- /* background-repeat: repeat-y; */
- /* background-color: #af00af; */
- /* height: 25px; */
- margin: 10px 0px 10px 20px;
- padding: 3px;
- font-size: 9pt;
- font-family: sans-serif;
- /* border-style: solid; */
- /* border-width: 1px; */
-}
-
-
-#topnav {font-weight: bold}
-#topnav a {font-weight: normal}
-
-h1,p { margin: 0; } /* non-0 margin on firefox */
-
-#mid {
- background-image: url(img/grad_azure.png);
- background-repeat: repeat-y;
- /* background-color: #ffddaa; */
- padding-top: 20px;
- margin-bottom: 10px;
-}
-
-#mid img {
- padding-left: 10px;
- vertical-align: middle;
-}
-
-a img {
- border: 0
-}
-
-#nav {
- background-color: #fff8f1;
- margin-left: 10px;
- margin-top: 20px;
- float: left;
- padding: 10px;
- border-style: solid;
- border-width: 2px;
- font-family: sans-serif;
-}
-
-
-#nav h2 {
- font-weight: bold;
- font-size: 10pt;
-}
-
-#nav h3 {
- /* font-weight: bold; */
- padding-left: 5px;
- /* font-style: oblique; */
- font-family: sans-serif;
- font-size: 7pt;
-}
-
-#nav div {
- font-size: 9pt;
- padding-left: 15px;
-}
-
-#main {
- background: #ffffff;
- margin-top: 20px;
- margin-left: 170px;
- padding-left: 20px;
- height: 100%;
- /* font-family: sans-serif; */
-}
-
-#main h1 {
- font-family: sans-serif;
-}
-
-
-.listing {
- margin: 20px;
- font-family: sans-serif;
- font-weight: bold;
-}
-
-.code {
- padding: 10px;
- background: #f3f3f3;
- font-size: 8pt;
- font-weight: normal;
- width: 80%;
- border-style: solid;
- border-width: 1px;
-}
-
-.code pre {
- padding-left: 20px;
- padding-right: 80px;
-}
-
-#formatstrings {
- margin: 20px;
-}
-
-#footer {
- /* background: #00ffff; */
- margin-top: 5px;
- font-size: small;
- font-family: sans-serif;
-}
-
-em {
- font-weight: bold;
-}
-
-hr {
- height: 0.04em;
- background: black;
- margin: 0 10% 0 0;
-}
-
-#footer img {
- margin-right: 5px;
- float: right;
-}
-
-.lead {
- font-family: sans-serif;
- font-size: larger;
- font-weight: bold;
- /* font-style: oblique; */
- margin: 30px 30px 30px 0px;
- color: #1122dd;
-}
-
-ol {
- font-family: monospace;
- background: #dddddd;
- padding-top: 10px;
- padding-bottom: 10px;
- width: 80%;
- border-width: 1px;
- border-style: solid;
- /* font-size: smaller; */
-}
-
-#main #portrait {
- float: right;
- font-size: smaller;
- font-family: sans-serif;
- text-align: center;
- margin: 10px;
-}
+++ /dev/null
-/* Workarounds for IE6's broken and incomplete CSS2. */
-
-div.sidebar-content {
- background: #ffffee;
- border: 1px solid silver;
- padding: 0.5em;
-}
-div.sidebar-title, div.image-title {
- font-family: sans-serif;
- font-weight: bold;
- margin-top: 0.0em;
- margin-bottom: 0.5em;
-}
-
-div.listingblock div.content {
- border: 1px solid silver;
- background: #f4f4f4;
- padding: 0.5em;
-}
-
-div.quoteblock-content {
- padding-left: 2.0em;
-}
-
-div.exampleblock-content {
- border-left: 2px solid silver;
- padding-left: 0.5em;
-}
-
-/* IE6 sets dynamically generated links as visited. */
-div#toc a:visited { color: blue; }
+++ /dev/null
-/* Debug borders */
-p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
-/*
- border: 1px solid red;
-*/
-}
-
-body {
- margin: 1em 5% 1em 5%;
-}
-
-a {
- color: blue;
- text-decoration: underline;
-}
-a:visited {
- color: fuchsia;
-}
-
-em {
- font-style: italic;
-}
-
-strong {
- font-weight: bold;
-}
-
-tt {
- color: navy;
-}
-
-h1, h2, h3, h4, h5, h6 {
- color: #527bbd;
- font-family: sans-serif;
- margin-top: 1.2em;
- margin-bottom: 0.5em;
- line-height: 1.3;
-}
-
-h1, h2, h3 {
- border-bottom: 2px solid silver;
-}
-h2 {
- padding-top: 0.5em;
-}
-h3 {
- float: left;
-}
-h3 + * {
- clear: left;
-}
-
-div.sectionbody {
- font-family: serif;
- margin-left: 0;
-}
-
-hr {
- border: 1px solid silver;
-}
-
-p {
- margin-top: 0.5em;
- margin-bottom: 0.5em;
-}
-
-pre {
- padding: 0;
- margin: 0;
-}
-
-span#author {
- color: #527bbd;
- font-family: sans-serif;
- font-weight: bold;
- font-size: 1.1em;
-}
-span#email {
-}
-span#revision {
- font-family: sans-serif;
-}
-
-div#footer {
- font-family: sans-serif;
- font-size: small;
- border-top: 2px solid silver;
- padding-top: 0.5em;
- margin-top: 4.0em;
-}
-div#footer-text {
- float: left;
- padding-bottom: 0.5em;
-}
-div#footer-badges {
- float: right;
- padding-bottom: 0.5em;
-}
-
-div#preamble,
-div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
-div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
-div.admonitionblock {
- margin-right: 10%;
- margin-top: 1.5em;
- margin-bottom: 1.5em;
-}
-div.admonitionblock {
- margin-top: 2.5em;
- margin-bottom: 2.5em;
-}
-
-div.content { /* Block element content. */
- padding: 0;
-}
-
-/* Block element titles. */
-div.title, caption.title {
- font-family: sans-serif;
- font-weight: bold;
- text-align: left;
- margin-top: 1.0em;
- margin-bottom: 0.5em;
-}
-div.title + * {
- margin-top: 0;
-}
-
-td div.title:first-child {
- margin-top: 0.0em;
-}
-div.content div.title:first-child {
- margin-top: 0.0em;
-}
-div.content + div.title {
- margin-top: 0.0em;
-}
-
-div.sidebarblock > div.content {
- background: #ffffee;
- border: 1px solid silver;
- padding: 0.5em;
-}
-
-div.listingblock {
- margin-right: 0%;
-}
-div.listingblock > div.content {
- border: 1px solid silver;
- background: #f4f4f4;
- padding: 0.5em;
-}
-
-div.quoteblock > div.content {
- padding-left: 2.0em;
-}
-
-div.attribution {
- text-align: right;
-}
-div.verseblock + div.attribution {
- text-align: left;
-}
-
-div.admonitionblock .icon {
- vertical-align: top;
- font-size: 1.1em;
- font-weight: bold;
- text-decoration: underline;
- color: #527bbd;
- padding-right: 0.5em;
-}
-div.admonitionblock td.content {
- padding-left: 0.5em;
- border-left: 2px solid silver;
-}
-
-div.exampleblock > div.content {
- border-left: 2px solid silver;
- padding: 0.5em;
-}
-
-div.verseblock div.content {
- white-space: pre;
-}
-
-div.imageblock div.content { padding-left: 0; }
-div.imageblock img { border: 1px solid silver; }
-span.image img { border-style: none; }
-
-dl {
- margin-top: 0.8em;
- margin-bottom: 0.8em;
-}
-dt {
- margin-top: 0.5em;
- margin-bottom: 0;
- font-style: italic;
-}
-dd > *:first-child {
- margin-top: 0;
-}
-
-ul, ol {
- list-style-position: outside;
-}
-div.olist2 ol {
- list-style-type: lower-alpha;
-}
-
-div.tableblock > table {
- border: 3px solid #527bbd;
-}
-thead {
- font-family: sans-serif;
- font-weight: bold;
-}
-tfoot {
- font-weight: bold;
-}
-
-div.hlist {
- margin-top: 0.8em;
- margin-bottom: 0.8em;
-}
-div.hlist td {
- padding-bottom: 5px;
-}
-td.hlist1 {
- vertical-align: top;
- font-style: italic;
- padding-right: 0.8em;
-}
-td.hlist2 {
- vertical-align: top;
-}
-
-@media print {
- div#footer-badges { display: none; }
-}
-
-div#toctitle {
- color: #527bbd;
- font-family: sans-serif;
- font-size: 1.1em;
- font-weight: bold;
- margin-top: 1.0em;
- margin-bottom: 0.1em;
-}
-
-div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
- margin-top: 0;
- margin-bottom: 0;
-}
-div.toclevel2 {
- margin-left: 2em;
- font-size: 0.9em;
-}
-div.toclevel3 {
- margin-left: 4em;
- font-size: 0.9em;
-}
-div.toclevel4 {
- margin-left: 6em;
- font-size: 0.9em;
-}
-#toc {
- float: right;
- font-family: sans-serif;
- border: 1px solid #000;
- margin: 0px 0px 20px 20px;
- padding: 0px;
- background: #f0f0f0;
- font-size: 80%;
-}
-
-#toc #hdr {
- color:#ffffff;
- background:#98b1c4;
- text-align:center;
- margin-bottom:5px;
-}
-
-a img {
- border: 0
-}
-
-#toc a:visited, #toc a:link { color:#000; text-decoration: none }
-#toc a:hover { color:#00f; text-decoration: underline; }
-
-#toc .level2 { margin-left: 1em; margin-top: 2px; margin-bottom: 2px; text-decoration: underline; }
-#toc .level3 { margin-left: 2em; font-size: 0.8em }
-
-.toplink {
- float: right;
- font-size: 50%;
- cursor: pointer;
-}
-
-#topnav {font-weight: bold}
-#topnav a {font-weight: normal}
+++ /dev/null
-#toc {
- float: right;
- font-family: sans-serif;
- border: 1px solid #000;
- margin: 0px 0px 20px 20px;
- padding: 0px;
- background: #f0f0f0;
- font-size: 80%;
-}
-
-#toc #hdr {
- color:#ffffff;
- background:#98b1c4;
- text-align:center;
- margin-bottom:5px;
-}
-
-a img {
- border: 0
-}
-
-#toc a:visited, #toc a:link { color:#000; text-decoration: none }
-#toc a:hover { color:#00f; text-decoration: underline; }
-
-#toc .level2 { margin-left: 1em; margin-top: 2px; margin-bottom: 2px; text-decoration: underline; }
-#toc .level3 { margin-left: 2em; font-size: 0.8em }
-
-.toplink {
- float: right;
- font-size: 50%;
- cursor: pointer;
-}
-
-#topnav {font-weight: bold}
-#topnav a {font-weight: normal}
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
-<head>\r
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
-<meta name="generator" content="AsciiDoc 8.3.4" />\r
-<title>tpl User Guide</title>\r
-<link rel="stylesheet" href="./tdh.css" type="text/css" />\r
-<link rel="stylesheet" href="./tdh-quirks.css" type="text/css" />\r
-</head>\r
-<body>\r
-<div id="header">\r
-<h1>tpl User Guide</h1>\r
-<span id="author">Troy D. Hanson</span><br />\r
-<span id="email"><tt><<a href="mailto:thanson@users.sourceforge.net">thanson@users.sourceforge.net</a>></tt></span><br />\r
-<span id="revision">version 1.5,</span>\r
-February 2010\r
-</div>\r
-<div id="preamble">\r
-<div class="sectionbody">\r
-<a style="float: right;" href="http://sourceforge.net/projects/tpl"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=157637&type=16" width="150" height="40" alt="SourceForge.net" /></a>\r
- <div id="topnav" style="font-size: 9pt; font-family: sans-serif;">\r
- <a style="padding: 8px;" href="http://sourceforge.net/projects/tpl/">sf.net summary page</a> >\r
- <a style="padding: 8px;" href="index.html">tpl home</a> >\r
- tpl User Guide\r
- <a style="padding: 8px;" href="userguide.pdf">[View PDF]</a>\r
- </div>\r
-</div>\r
-</div>\r
-<h2 id="_overview">Overview</h2>\r
-<div class="sectionbody">\r
-<div id="toc"></div>\r
-<script>\r
-window.onload=generate_TOC\r
-\r
-/* Author: Mihai Bazon, September 2002\r
- * <a href="http://students.infoiasi.ro/~mishoo">http://students.infoiasi.ro/~mishoo</a>\r
- *\r
- * Table Of Content generator\r
- * Version: 0.4\r
- *\r
- * Feel free to use this script under the terms of the GNU General Public\r
- * License, as long as you do not remove or alter this notice.\r
- */\r
-\r
- /* modified by Troy D. Hanson, September 2006. License: GPL */\r
-\r
-function H_getText(el) {\r
- var text = "";\r
- for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
- if (i.nodeType == 3 /* Node.TEXT_NODE, IE doesn't speak constants */)\r
- text += i.data;\r
- else if (i.firstChild != null)\r
- text += H_getText(i);\r
- }\r
- return text;\r
-}\r
-\r
-function TOC_EL(el, text, level) {\r
- this.element = el;\r
- this.text = text;\r
- this.level = level;\r
-}\r
-\r
-function getHeadlines(el) {\r
- var l = new Array;\r
- var rx = /[hH]([2-3])/;\r
- // internal recursive function that scans the DOM tree\r
- var rec = function (el) {\r
- for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
- if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {\r
- if (rx.exec(i.tagName))\r
- l[l.length] = new TOC_EL(i, H_getText(i), parseInt(RegExp.$1));\r
- rec(i);\r
- }\r
- }\r
- }\r
- rec(el);\r
- return l;\r
-}\r
-\r
-function generate_TOC() {\r
- var parent = document.getElementById("toc");\r
- var toc_hdr = document.createElement("div");\r
- var toc_hdr_txt = document.createTextNode("CONTENTS");\r
- toc_hdr.appendChild(toc_hdr_txt);\r
- /* toc_hdr.setAttribute("id","hdr"); */\r
- toc_hdr.id = "hdr";\r
- parent.appendChild(toc_hdr);\r
- var hs = getHeadlines(document.getElementsByTagName("body")[0]);\r
- for (var i = 0; i < hs.length; ++i) {\r
- var hi = hs[i];\r
- var d = document.createElement("div");\r
- if (hi.element.id == "") hi.element.id = "gen" + i;\r
- var a = document.createElement("a");\r
- a.href = "#" + hi.element.id;\r
- a.appendChild(document.createTextNode(hi.text));\r
- d.appendChild(a);\r
- d.className = "level" + hi.level;\r
- parent.appendChild(d);\r
- /*\r
- if (hi.level == 3) {\r
- var dvtop = document.createElement("div");\r
- dvtop.className = "toplink";\r
- dvtop.appendChild(document.createTextNode("^top^"));\r
- dvtop.onclick=function(){scrollTo(0,0);};\r
- hi.element.appendChild(dvtop);\r
- }\r
- */\r
- }\r
-}\r
-</script>\r
-<h3 id="_serialization_in_c">Serialization in C</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Tpl is a library for serializing C data. The data is stored in its natural\r
-binary form. The API is small and tries to stay "out of the way".\r
-Tpl can serialize many C data types, including structures.</p></div>\r
-<h3 id="_uses_for_tpl">Uses for tpl</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Tpl makes a convenient file format. For example, suppose a program needs to\r
-store a list of user names and ids. This can be expressed using the format\r
-string <tt>A(si)</tt>. If the program needs two such lists (say, one for regular\r
-users and one for administrators) this could be expressed as <tt>A(si)A(si)</tt>. It\r
-is easy to read and write this kind of structured data using tpl.</p></div>\r
-<div class="paragraph"><p>Tpl can also be used as an IPC message format. It handles byte order issues\r
-and deframing individual messages off of a stream automatically.</p></div>\r
-<h3 id="_expressing_type">Expressing type</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The "data type" of a tpl is explicitly stated as a format string. There is\r
-never any ambiguity about the type of data stored in a tpl. Some examples:</p></div>\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-<tt>A(is)</tt> is a variable-length array of integer-string pairs\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-<tt>A(is)A(is)</tt> are two such arrays, completely independent of one another\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-<tt>S(ci)</tt> is a structure containing a char and integer\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-<tt>S(ci)#</tt> is a fixed-length array of the latter structure\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-<tt>A(A(i))</tt> is a nested array, that is, an array of integer arrays\r
-</p>\r
-</li>\r
-</ul></div>\r
-<h3 id="_the_tpl_image">The tpl image</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>A tpl image is the serialized form of a tpl, stored in a memory buffer or file,\r
-or written to a file descriptor.</p></div>\r
-<h4 id="_what_8217_s_in_a_tpl_image">What’s in a tpl image?</h4>\r
-<div class="paragraph"><p>There is no need to understand the internal structure of the tpl image. But for the\r
-curious, the image is a strictly defined binary buffer having two sections,\r
-a header and the data. The header encodes the length of the image, its\r
-format string, endian order and other flags. The data section contains the\r
-packed data.</p></div>\r
-<h4 id="_no_framing_needed">No framing needed</h4>\r
-<div class="paragraph"><p>A property of the tpl image is that consecutive images can be written to a stream\r
-without requiring any delimiter between them. The reader making use of\r
-<tt>tpl_gather</tt> (or <tt>tpl_load</tt> in <tt>TPL_FD</tt> mode) will obtain exactly one tpl image at\r
-a time. Therefore tpl images can be used as an IPC message format without any\r
-higher-level framing protocol.</p></div>\r
-<h4 id="_data_portability">Data portability</h4>\r
-<div class="paragraph"><p>A tpl image generated on one kind of CPU will generally be portable to other\r
-CPU types when tpl is used properly. This may be a surprise considering that\r
-tpl is a binary format. But tpl has been carefully designed to make this work.\r
-Each <a href="#types">format character</a> has an associated explicitly-sized type. For\r
-integer and floating point types, whose "endian" or byte-order convention varies\r
-from one CPU to another, tpl automatically and transparently corrects the\r
-endian order (if needed) during the unpacking process. Floating point numbers\r
-present their own <a href="#trouble_with_double">special difficulties</a>. <em>No guarantees\r
-are made with regard to floating point portability.</em> That said, because many\r
-modern CPU’s use IEEE 754 floating point representation, data is likely to be\r
-portable among them.</p></div>\r
-<h3 id="_xml_and_perl">XML and Perl</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p><em>Note: The <tt>tplxml</tt> utility and the Perl module are currently unsupported in tpl 1.5.</em></p></div>\r
-<h4 id="_xml">XML</h4>\r
-<div class="paragraph"><p>While a tpl image is a binary entity, you can view any tpl image in XML format\r
-using the included <tt>tplxml</tt> utility, located in the <tt>lang/perl</tt> directory.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tplxml file.tpl > file.xml\r
-tplxml file.xml > file.tpl</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The utility is bidirectional, as shown. The file extension is not important;\r
-<tt>tplxml</tt> inspects its input to see if it’s tpl or XML. You can also pipe data\r
-into it instead of giving it a filename. The <tt>tplxml</tt> utility is slow. Its\r
-purpose is two-fold: debugging (manual inspection of the data in a tpl), and\r
-interoperability with XML-based programs. The resulting XML is often ten times\r
-the size of the original binary tpl image.</p></div>\r
-<h4 id="_perl">Perl</h4>\r
-<div class="paragraph"><p>There is a Perl module in <tt>lang/perl/Tpl.pm</tt>. The <a href="perl.html">Perl API</a>\r
-is convenient for writing Perl scripts that interoperate with C programs, and\r
-need to pass structured data back and forth. It is written in pure Perl.</p></div>\r
-<h3 id="_platforms">Platforms</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The tpl software was developed for POSIX systems and has been tested on 32- and 64-bit\r
-platforms including:</p></div>\r
-<div class="ulist"><ul>\r
-<li>\r
-<p>\r
-Linux\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-Solaris\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-Mac OS X\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-OpenBSD\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
-Windows using Visual Studio 2008 or 2010, or Cygwin or MinGW\r
-</p>\r
-</li>\r
-</ul></div>\r
-<h3 id="_bsd_licensed">BSD licensed</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This software is made available under the\r
-<a href="license.html">revised BSD license</a>.\r
-It is free and open source.</p></div>\r
-<h3 id="_download">Download</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Please follow the link to download on the\r
-<a href="http://tpl.sourceforge.net">tpl website</a>.</p></div>\r
-<h3 id="_getting_help">Getting help</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>If you need help, you are welcome to email the author at\r
-<a href="mailto:thanson@users.sourceforge.net">thanson@users.sourceforge.net</a>.</p></div>\r
-<h3 id="_resources">Resources</h3><div style="clear:left"></div>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-News\r
-</dt>\r
-<dd>\r
-<p>\r
- The author has a news feed for <a href="http://troydhanson.wordpress.com/feed/">software updates</a> <span class="image">\r
-<img src="img/rss.png" alt="(RSS)" title="(RSS)" />\r
-</span>.\r
-</p>\r
-</dd>\r
-</dl></div>\r
-</div>\r
-<h2 id="_build_and_install">Build and install</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>Tpl has no dependencies on libraries other than the system C library. You\r
-can simply copy the tpl source into your project, so you have no dependencies.\r
-Alternatively, you can build tpl as a library and link it to your program.</p></div>\r
-<h3 id="_as_source">As source</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The simplest way to use tpl is to copy the source files <tt>tpl.h</tt> and <tt>tpl.c</tt>\r
-(from the <tt>src/</tt> directory) right into your project, and build them with the\r
-rest of your source files. No special compiler flags are required.</p></div>\r
-<h3 id="_as_a_library">As a library</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Alternatively, to build tpl as a library, from the top-level directory, run:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>./configure\r
-make\r
-make install</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>This installs a static library <tt>libtpl.a</tt> and a shared library (e.g.,\r
-<tt>libtpl.so</tt>), if your system supports them, in standard places. The installation\r
-directory can be customized using <tt>./configure --prefix=/some/directory</tt>. Run\r
-<tt>configure --help</tt> for further options.</p></div>\r
-<h4 id="_test_suite">Test suite</h4>\r
-<div class="paragraph"><p>You can compile and run the built-in test suite by running:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>cd tests/\r
-make</tt></pre>\r
-</div></div>\r
-<h3 id="_on_windows">On Windows</h3><div style="clear:left"></div>\r
-<h4 id="_dll">DLL</h4>\r
-<div class="paragraph"><p>On the tpl home page, a Visual Studio 2008 solution package is available for\r
-download. This zip file contains pre-built 32- and 64-bit versions of tpl as a\r
-DLL. If you like, you can build the DLL yourself using VS2008 or VS2010 (the\r
-free Express Edition is sufficient) by opening the solution file and choosing\r
-Build Solution.</p></div>\r
-<h4 id="_non_dll_usage">Non-DLL usage</h4>\r
-<div class="paragraph"><p>Alternatively, tpl can be used directly (instead of as a DLL) by compiling\r
-the tpl sources right into your program. To do this, add <tt>tpl.c</tt>, <tt>tpl.h</tt>,\r
-<tt>win/mman.h</tt> and <tt>win/mmap.c</tt> to your program’s source and header files and\r
-add the preprocessor definition <tt>TPL_NOLIB</tt>.</p></div>\r
-<h4 id="_mingw_cygwin">MinGW/Cygwin</h4>\r
-<div class="paragraph"><p>Prior to tpl release 1.5, using tpl on Windows required building it with MinGW\r
-or Cygwin. This is no longer necessary. If you want to build it that way anyway,\r
-use the non-Windows (i.e. tar.bz2) tpl download and follow the "configure; make;\r
-make install" approach.</p></div>\r
-</div>\r
-<h2 id="_api_concepts">API concepts</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>To use tpl, you need to know the order in which to call the API functions, and\r
-the background concepts of format string, arrays and index numbers.</p></div>\r
-<h3 id="_order_of_functions">Order of functions</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Creating a tpl is always the first step, and freeing it is the last step. In\r
-between, you either pack and dump the tpl (if you’re serializing data) or you\r
-load a tpl image and unpack it (if you’re deserializing data).</p></div>\r
-<div class="tableblock">\r
-<table rules="none"\r
-width="50%"\r
-frame="border"\r
-cellspacing="0" cellpadding="4">\r
-<caption class="title">Order of usage</caption>\r
-<col width="9%" />\r
-<col width="45%" />\r
-<col width="45%" />\r
-<thead valign="top">\r
-<tr>\r
-<th align="center">Step </th>\r
-<th align="center"> If you’re serializing…</th>\r
-<th align="center"> If you’re deserializing…</th>\r
-</tr>\r
-</thead>\r
-<tbody valign="top">\r
-<tr>\r
-<td align="center"><p class="table">1.</p></td>\r
-<td align="center"><p class="table"><tt>tpl_map()</tt></p></td>\r
-<td align="center"><p class="table"><tt>tpl_map()</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">2.</p></td>\r
-<td align="center"><p class="table"><tt>tpl_pack()</tt></p></td>\r
-<td align="center"><p class="table"><tt>tpl_load()</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">3.</p></td>\r
-<td align="center"><p class="table"><tt>tpl_dump()</tt></p></td>\r
-<td align="center"><p class="table"><tt>tpl_unpack()</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">4.</p></td>\r
-<td align="center"><p class="table"><tt>tpl_free()</tt></p></td>\r
-<td align="center"><p class="table"><tt>tpl_free()</tt></p></td>\r
-</tr>\r
-</tbody>\r
-</table>\r
-</div>\r
-<h3 id="format">Format string</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>When a tpl is created using <tt>tpl_map()</tt>, its data type is expressed as a format\r
-string. Each character in the format string has an associated argument of a\r
-specific type. For example, this is how a format string and its arguments are\r
-passed in to <tt>tpl_map</tt>:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tpl_node *tn;\r
-char c;\r
-int i[10];\r
-tn = tpl_map("ci#", &c, i, 10); /* ci# is our format string */</tt></pre>\r
-</div></div>\r
-<div class="tableblock" id="types">\r
-<table rules="none"\r
-width="90%"\r
-frame="border"\r
-cellspacing="0" cellpadding="4">\r
-<caption class="title">Supported format characters</caption>\r
-<col width="11%" />\r
-<col width="44%" />\r
-<col width="44%" />\r
-<thead valign="top">\r
-<tr>\r
-<th align="center">Type </th>\r
-<th align="left"> Description </th>\r
-<th align="left"> Required argument type</th>\r
-</tr>\r
-</thead>\r
-<tbody valign="top">\r
-<tr>\r
-<td align="center"><p class="table"><tt>j</tt></p></td>\r
-<td align="left"><p class="table">16-bit signed int</p></td>\r
-<td align="left"><p class="table">int16_t* or equivalent</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>v</tt></p></td>\r
-<td align="left"><p class="table">16-bit unsigned int</p></td>\r
-<td align="left"><p class="table">uint16_t* or equivalent</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>i</tt></p></td>\r
-<td align="left"><p class="table">32-bit signed int</p></td>\r
-<td align="left"><p class="table">int32_t* or equivalent</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>u</tt></p></td>\r
-<td align="left"><p class="table">32-bit unsigned int</p></td>\r
-<td align="left"><p class="table">uint32_t* or equivalent</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>I</tt></p></td>\r
-<td align="left"><p class="table">64-bit signed int</p></td>\r
-<td align="left"><p class="table">int64_t* or equivalent</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>U</tt></p></td>\r
-<td align="left"><p class="table">64-bit unsigned int</p></td>\r
-<td align="left"><p class="table">uint64_t* or equivalent</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>c</tt></p></td>\r
-<td align="left"><p class="table">character (byte)</p></td>\r
-<td align="left"><p class="table">char*</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>s</tt></p></td>\r
-<td align="left"><p class="table">string</p></td>\r
-<td align="left"><p class="table">char**</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>f</tt></p></td>\r
-<td align="left"><p class="table">64-bit double precision float</p></td>\r
-<td align="left"><p class="table">double* (varies by platform)</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>#</tt></p></td>\r
-<td align="left"><p class="table">array length; modifies preceding <tt>iujvIUcsf</tt> or <tt>S(…)</tt></p></td>\r
-<td align="left"><p class="table">int</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>B</tt></p></td>\r
-<td align="left"><p class="table">binary buffer (arbitrary-length)</p></td>\r
-<td align="left"><p class="table">tpl_bin*</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>S</tt></p></td>\r
-<td align="left"><p class="table">structure (…)</p></td>\r
-<td align="left"><p class="table">struct *</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>$</tt></p></td>\r
-<td align="left"><p class="table">nested structure (…)</p></td>\r
-<td align="left"><p class="table">none</p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table"><tt>A</tt></p></td>\r
-<td align="left"><p class="table">array (…)</p></td>\r
-<td align="left"><p class="table">none</p></td>\r
-</tr>\r
-</tbody>\r
-</table>\r
-</div>\r
-<h4 id="_explicit_sizes">Explicit sizes</h4>\r
-<div class="paragraph"><p>The sizes of data types such as <tt>long</tt> and <tt>double</tt> vary by platform. This must\r
-be kept in mind because most tpl format characters require a pointer argument to\r
-a specific-sized type, listed above. You can use explicit-sized types such as\r
-<tt>int32_t</tt> (defined in <tt>inttypes.h</tt>) in your program if you find this helpful.</p></div>\r
-<h5 id="trouble_with_double">The trouble with double</h5>\r
-<div class="paragraph"><p>Unfortunately there are no standard explicit-sized floating-point types-- no\r
-<tt>float64_t</tt>, for example. If you plan to serialize <tt>double</tt> on your platform\r
-using tpl’s <tt>f</tt> format character, first be sure that your <tt>double</tt> is 64 bits.\r
-Second, if you plan to deserialize it on a different kind of CPU, be sure that\r
-both CPU’s use the same floating-point representation such as IEEE 754.</p></div>\r
-<h3 id="arrays">Arrays</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Arrays come in two kinds: <strong>fixed-length</strong> and <strong>variable-length</strong> arrays.\r
-Intuitively, they can be thought of like conventional C arrays and linked lists.\r
-In general, use fixed-length arrays if possible, and variable-length arrays\r
-if necessary. The variable-length arrays support more complex data types, and\r
-give or receive the elements to your program one by one.</p></div>\r
-<h4 id="_fixed_length_vs_variable_length_arrays">Fixed-length vs. Variable-length arrays</h4>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-Notation\r
-</dt>\r
-<dd>\r
-<p>\r
- Fixed-length arrays are denoted like <tt>i#</tt> (a simple type followed by one or\r
- more <tt>#</tt> signs), but variable-length arrays are denoted like <tt>A(i)</tt>.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-Element handling\r
-</dt>\r
-<dd>\r
-<p>\r
- All the elements of a fixed-length array are packed or unpacked at once. But\r
- the elements of a variable-length array are packed or unpacked one by one.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-Array length\r
-</dt>\r
-<dd>\r
-<p>\r
- The number of elements in a fixed-length array is specified before use--\r
- before any data is packed. But variable-length arrays do not have a fixed\r
- element count. They can have any number of elements packed into them. When\r
- unpacking a variable-length array, they are unpacked one by one until they\r
- are exhausted.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-Element types\r
-</dt>\r
-<dd>\r
-<p>\r
- Elements of fixed-length arrays can be the integer, byte, double, string\r
- types or structures. (This excludes format characters <tt>BA</tt>). Fixed-length\r
- arrays can also be multi-dimensional like <tt>i##</tt>. Variable-length arrays can\r
- have simple or complex elements-- for example, an array of ints <tt>A(i)</tt>, an\r
- array of int/double pairs <tt>A(if)</tt>, or even nested arrays like <tt>A(A(if))</tt>.\r
-</p>\r
-</dd>\r
-</dl></div>\r
-<div class="paragraph"><p>Before explaining all the concepts, it’s illustrative to see how both kinds of\r
-arrays are used. Let’s pack the integers 0 through 9 both ways.</p></div>\r
-<div class="listingblock" id="fixed_pack">\r
-<div class="title">Packing 0-9 as a fixed-length array</div>\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-int main() {\r
- tpl_node *tn;\r
- int x[] = {0,1,2,3,4,5,6,7,8,9};\r
-\r
- tn = tpl_map("i#", x, 10);\r
- tpl_pack(tn,0); /* pack all 10 elements at once */\r
- tpl_dump(tn, TPL_FILE, "/tmp/fixed.tpl");\r
- tpl_free(tn);\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Note that the length of the fixed-length array (10) was passed as an argument to\r
-<tt>tpl_map()</tt>. The corresponding unpacking <a href="#fixed_unpack">example</a> is listed\r
-further below. Now let’s see how we would pack 0-9 as a variable-length array:</p></div>\r
-<div class="listingblock">\r
-<div class="title">Packing 0-9 as a variable-length array</div>\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-int main() {\r
- tpl_node *tn;\r
- int x;\r
-\r
- tn = tpl_map("A(i)", &x);\r
- for(x = 0; x < 10; x++) tpl_pack(tn,1); /* pack one element at a time */\r
- tpl_dump(tn, TPL_FILE, "/tmp/variable.tpl");\r
- tpl_free(tn);\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Notice how we called <tt>tpl_pack</tt> in a loop, once for each element 0-9. Again,\r
-there is a corresponding unpacking <a href="#var_unpack">example</a> shown later in the\r
-guide. You might also notice that this time, we passed 1 as the final argument\r
-to tpl_pack. This is an index number designating which variable-length array\r
-we’re packing. In this case, there is only one.</p></div>\r
-<h4 id="index">Index numbers</h4>\r
-<div class="paragraph"><p>Index numbers identify a particular variable-length array in the format string.\r
-Each <tt>A(…)</tt> in a format string has its own index number. The index numbers\r
-are assigned left-to-right starting from 1. Examples:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>A(i) /* index number 1 */\r
-A(i)A(i) /* index numbers 1 and 2 */\r
-A(A(i)) /* index numbers 1 and 2 (order is independent of nesting) */</tt></pre>\r
-</div></div>\r
-<h5 id="_special_index_number_0">Special index number 0</h5>\r
-<div class="paragraph"><p>The special index number 0 designates all the format characters that are not\r
-inside an <tt>A(…)</tt>. Examples of what index 0 does (and does not) designate:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>S(ius) /* index 0 designates the whole thing */\r
-iA(c)u /* index 0 designates the i and the u */\r
-c#A(i)S(ci) /* index 0 designates the c# and the S(ci) */</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>An index number is passed to <tt>tpl_pack</tt> and <tt>tpl_unpack</tt> to specify which\r
-variable-length array (or non-array, in the case of index number 0) to act upon.</p></div>\r
-<h3 id="_integers">Integers</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The array examples <a href="#fixed_pack">above</a> demonstrated how integers could be\r
-packed. We’ll show some further examples here of unpacking integers and dealing\r
-with multi-dimensional arrays. The same program could be used to demonstrate\r
-working with byte, 16-bit shorts, 32-bit or 64-bit signed and unsigned integers\r
-with only a change to the data type and the format character.</p></div>\r
-<div class="listingblock" id="fixed_unpack">\r
-<div class="title">Unpacking 0-9 from a fixed-length array</div>\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-int main() {\r
- tpl_node *tn;\r
- int x[10];\r
-\r
- tn = tpl_map("i#", x, 10);\r
- tpl_load(tn, TPL_FILE, "/tmp/fixed.tpl");\r
- tpl_unpack(tn,0); /* unpack all 10 elements at once */\r
- tpl_free(tn);\r
- /* now do something with x[0]...x[9].. (not shown */\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>For completeness, let’s also see how to unpack a variable-length integer array.</p></div>\r
-<div class="listingblock" id="var_unpack">\r
-<div class="title">Unpacking 0-9 from a variable-length array</div>\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-int main() {\r
- tpl_node *tn;\r
- int x;\r
-\r
- tn = tpl_map("A(i)", &x);\r
- tpl_load(tn, TPL_FILE, "/tmp/variable.tpl");\r
- while (tpl_unpack(tn,1) > 0) printf("%d\n",x); /* unpack one by one */\r
- tpl_free(tn);\r
-}</tt></pre>\r
-</div></div>\r
-<h4 id="multidim_int">Multi-dimensional arrays</h4>\r
-<div class="paragraph"><p>A multi-dimensional matrix of integers can be packed and unpacked the same way\r
-as any fixed-length array.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>int xy[XDIM][YDIM];\r
-...\r
-tn = tpl_map("i##", xy, XDIM, YDIM);\r
-tpl_pack(tn, 0);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>This single call to <tt>tpl_pack</tt> packs the entire matrix.</p></div>\r
-<h3 id="_strings">Strings</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Tpl can serialize C strings. A different format is used for <tt>char*</tt> vs. <tt>char[ ]</tt>\r
-as described below. Let’s look at <tt>char*</tt> first:</p></div>\r
-<div class="listingblock">\r
-<div class="title">Packing a string</div>\r
-<div class="content">\r
-<pre><tt> #include "tpl.h"\r
-\r
- int main() {\r
- tpl_node *tn;\r
- char *s = "hello, world!";\r
- tn = tpl_map("s", &s);\r
- tpl_pack(tn,0); /* copies "hello, world!" into the tpl */\r
- tpl_dump(tn,TPL_FILE,"string.tpl");\r
- tpl_free(tn);\r
- }</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The <tt>char*</tt> must point to a null-terminated string or be a <tt>NULL</tt> pointer.</p></div>\r
-<div class="paragraph"><p>When deserializing (unpacking) a C string, space for it will be allocated\r
-automatically, but you are responsible for freeing it (unless it is <tt>NULL</tt>):</p></div>\r
-<div class="listingblock">\r
-<div class="title">Unpacking a string</div>\r
-<div class="content">\r
-<pre><tt> #include "tpl.h"\r
-\r
- int main() {\r
- tpl_node *tn;\r
- char *s;\r
- tn = tpl_map("s", &s);\r
- tpl_load(tn,TPL_FILE,"string.tpl");\r
- tpl_unpack(tn,0); /* allocates space, points s to "hello, world!" */\r
- printf("unpacked %s\n", s);\r
- free(s); /* our responsibility to free s */\r
- tpl_free(tn);\r
- }</tt></pre>\r
-</div></div>\r
-<h4 id="_char_vs_char">char* vs char[ ]</h4>\r
-<div class="paragraph"><p>The <tt>s</tt> format character is only for use with <tt>char*</tt> types. In the example\r
-above, <tt>s</tt> is a <tt>char*</tt>. If it had been a <tt>char s[14]</tt>, we would use the format\r
-characters <tt>c#</tt> to pack or unpack it, as a fixed-length character array. (This\r
-unpacks the characters "in-place", instead of into a dynamically allocated\r
-buffer). Also, a fixed-length buffer described by <tt>c#</tt> need not be\r
-null-terminated.</p></div>\r
-<h4 id="_arrays_of_strings">Arrays of strings</h4>\r
-<div class="paragraph"><p>You can use fixed- or variable-length arrays of strings in tpl. An example of\r
-packing a fixed-length two-dimensional array of strings is shown here.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>char *labels[2][3] = { {"one", "two", "three"},\r
- {"eins", "zwei", "drei" } };\r
-tpl_node *tn;\r
-tn = tpl_map("s##", labels, 2, 3);\r
-tpl_pack(tn,0);\r
-tpl_dump(tn,TPL_FILE,filename);\r
-tpl_free(tn);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Later, when unpacking these strings, the programmer must remember to free them\r
-one by one, after they are no longer needed.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>char *olabels[2][3];\r
-int i,j;</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map("s##", olabels, 2, 3);\r
-tpl_load(tn,TPL_FILE,filename);\r
-tpl_unpack(tn,0);\r
-tpl_free(tn);</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>for(i=0;i<2;i++) {\r
- for(j=0;j<3;j++) {\r
- printf("%s\n", olabels[i][j]);\r
- free(olabels[i][j]);\r
- }\r
-}</tt></pre>\r
-</div></div>\r
-<h3 id="_binary_buffers">Binary buffers</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Packing an arbitrary-length binary buffer (tpl format character <tt>B</tt>) makes use\r
-of the <tt>tpl_bin</tt> structure. You must declare this structure and populate it\r
-with the address and length of the binary buffer to be packed.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Packing a binary buffer</div>\r
-<div class="content">\r
-<pre><tt> #include "tpl.h"\r
- #include <sys/time.h>\r
-\r
- int main() {\r
- tpl_node *tn;\r
- tpl_bin tb;\r
-\r
- /* we'll use a timeval as our guinea pig */\r
- struct timeval tv;\r
- gettimeofday(&tv,NULL);\r
-\r
- tn = tpl_map( "B", &tb );\r
- tb.sz = sizeof(struct timeval); /* size of buffer to pack */\r
- tb.addr = &tv; /* address of buffer to pack */\r
- tpl_pack( tn, 0 );\r
- tpl_dump(tn, TPL_FILE, "bin.tpl");\r
- tpl_free(tn);\r
- }</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>When you unpack a binary buffer, tpl will automatically allocate it, and will\r
-populate your <tt>tpl_bin</tt> structure with its address and length. You are\r
-responsible for eventually freeing the buffer.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Unpacking a binary buffer</div>\r
-<div class="content">\r
-<pre><tt> #include "tpl.h"\r
-\r
- int main() {\r
- tpl_node *tn;\r
- tpl_bin tb;\r
-\r
- tn = tpl_map( "B", &tb );\r
- tpl_load( tn, TPL_FILE, "bin.tpl" );\r
- tpl_unpack( tn, 0 );\r
- tpl_free(tn);\r
-\r
- printf("binary buffer of length %d at address %p\n", tb.sz, tb.addr);\r
- free(tb.addr); /* our responsibility to free it */\r
- }</tt></pre>\r
-</div></div>\r
-<h3 id="_structures">Structures</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>You can use tpl to pack and unpack structures, and arrays of structures.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>struct ci {\r
- char c;\r
- int i;\r
-};\r
-struct ci s = {'a', 1};</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map("S(ci)", &s); /* pass structure address */\r
-tpl_pack(tn, 0);\r
-tpl_dump(tn, TPL_FILE, "struct.tpl");\r
-tpl_free(tn);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>As shown, omit the individual arguments for the format characters inside the\r
-parenthesis. The exception is for fixed-length arrays; when <tt>S(…)</tt> contains a\r
-<tt>#</tt> character, its length argument is required: <tt>tpl_map("S(f#i)", &s, 10);</tt></p></div>\r
-<div class="paragraph"><p>When using the <tt>S(…)</tt> format, the only characters allowed inside the\r
-parentheses are <tt>iujvcsfIU#$()</tt>.</p></div>\r
-<h4 id="_structure_arrays">Structure arrays</h4>\r
-<div class="paragraph"><p>Arrays of structures are the same as simple arrays. Fixed- or variable- length\r
-arrays are supported.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>struct ci sa[100], one;</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map("S(ci)#", sa, 100); /* fixed-length array of 100 structures */\r
-tn = tpl_map("A(S(ci))", &one); /* variable-length array (one at a time)*/</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The differences between fixed- and variable-length arrays are explained in the\r
-<a href="#arrays">Arrays</a> section.</p></div>\r
-<h4 id="_nested_structures">Nested structures</h4>\r
-<div class="paragraph"><p>When dealing with nested structures, the outermost structure uses the <tt>S</tt> format\r
-character, and the inner nested structures use the <tt>$</tt> format. Only the\r
-<em>outermost</em> structure’s address is given to <tt>tpl_map</tt>.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>struct inner_t {\r
- char a;\r
-}</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>struct outer_t {\r
- char b;\r
- struct inner_t i;\r
-}</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tpl_node *tn;\r
-struct outer_t outer = {'b', {'a'}};</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map("S(c$(c))", &outer);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Structures can nest to any level. Currently tpl does not support fixed-length\r
-array suffixes on inner structures. However the outermost structure can have a\r
-length suffix even if it contains some nested structures.</p></div>\r
-<h3 id="_linked_lists">Linked lists</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>While tpl has no specific data type for a linked list, the technique for\r
-packing them is illustrated here. First describe your list element as a\r
-format string and then surround it with <tt>A(…)</tt> to describe it as\r
-variable-length array. Then, using a temporary variable, iterate over each\r
-list element, copying it to the temporary variable and packing it.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>struct element {\r
- char c;\r
- int i;\r
- struct element *next;\r
-}</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>struct element *list, *i, tmp;\r
-tpl_node *tn;</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>/* add some elements to list.. (not shown)*/</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map("A(ci)", &tmp);\r
-for(i = list; i != NULL; i=i->next) {\r
- tmp = *i;\r
- tpl_pack(tn, 1);\r
-}\r
-tpl_dump(tn,TPL_FILE,"list.tpl");\r
-tpl_free(tn);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Unpacking is similar. The <tt>for</tt> loop is just replaced with:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>while( tpl_unpack(tn,1) > 0) {\r
- struct element *newelt = malloc(sizeof(struct element));\r
- *newelt = tmp;\r
- add_to_list(list, newelt);\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>As you can see, tpl does not reinstate the whole list at once-- just one\r
-element at a time. You need to link the elements manually. A future release of\r
-tpl may support <em>pointer swizzling</em> to make this easier.</p></div>\r
-</div>\r
-<h2 id="_api">API</h2>\r
-<div class="sectionbody">\r
-<h3 id="tpl_map">tpl_map</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The only way to create a tpl is to call <tt>tpl_map()</tt>. The first argument is the\r
-<a href="#format">format string</a>. This is followed by a list of arguments as required by\r
-the particular characters in the format string. E.g,</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tpl_node *tn;\r
-int i;\r
-tn = tpl_map( "A(i)", &i );</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The function creates a mapping between the items in the format string and the C\r
-program variables whose addresses are given. Later, the C variables will be read\r
-or written as the tpl is packed or unpacked.</p></div>\r
-<div class="paragraph"><p>This function returns a <tt>tpl_node*</tt> on success, or <tt>NULL</tt> on failure.</p></div>\r
-<h3 id="tpl_pack">tpl_pack</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The function <tt>tpl_pack()</tt> packs data into a tpl. The arguments to\r
-<tt>tpl_pack()</tt> are a <tt>tpl_node*</tt> and an <a href="#index">index number</a>.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map("A(i)A(c)", &i, &c);\r
-for(i=0; i<10; i++) tpl_pack(tn, 1); /* pack 0-9 into index 1 */\r
-for(c='a; c<='z'; c++) tpl_pack(tn, 2); /* pack a-z into index 2 */</tt></pre>\r
-</div></div>\r
-<div class="sidebarblock">\r
-<div class="sidebar-content">\r
-<div class="sidebar-title">Data is copied when packed</div>\r
-<div class="paragraph"><p>Every call to <tt>tpl_pack()</tt> immediately <em>copies</em> the data being packed. Thus\r
-the program is free to immediately overwrite or re-use the packed variables.</p></div>\r
-</div></div>\r
-<h4 id="_index_number_0">Index number 0</h4>\r
-<div class="paragraph"><p>It is necessary to pack index number 0 only if the format string contains\r
-characters that are not inside an <tt>A(…)</tt>, such as the <tt>i</tt> in the format string\r
-<tt>iA(c)</tt>.</p></div>\r
-<h4 id="_variable_length_arrays">Variable-length arrays</h4>\r
-<h5 id="_adding_elements_to_an_array">Adding elements to an array</h5>\r
-<div class="paragraph"><p>To add elements to a variable-length array, call <tt>tpl_pack()</tt> repeatedly. Each\r
-call adds another element to the array.</p></div>\r
-<h5 id="_zero_length_arrays_are_ok">Zero-length arrays are ok</h5>\r
-<div class="paragraph"><p>It’s perfectly acceptable to pack nothing into a variable-length array,\r
-resulting in a zero-length array.</p></div>\r
-<h5 id="nested_pack">Packing nested arrays</h5>\r
-<div class="paragraph"><p>In a format string containing a nested, variable-length array, such as\r
-<tt>A(A(s))</tt>, the inner, child array should be packed prior to the parent array.</p></div>\r
-<div class="paragraph"><p>When you pack a parent array, a "snapshot" of the current child array is placed\r
-into the parent’s new element. Packing a parent array also empties the child\r
-array. This way, you can pack new data into the child, then pack the parent\r
-again. This creates distinct parent elements which each contain distinct child\r
-arrays.</p></div>\r
-<div class="admonitionblock">\r
-<table><tr>\r
-<td class="icon">\r
-<div class="title">Tip</div>\r
-</td>\r
-<td class="content">When dealing with nested arrays like <tt>A(A(i))</tt>, <em>pack</em> them from the "inside\r
-out" (child first), but <em>unpack</em> them from the "outside in" (parent first).</td>\r
-</tr></table>\r
-</div>\r
-<div class="paragraph"><p>The example below creates a tpl having the format string <tt>A(A(c))</tt>.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Packing nested arrays</div>\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-\r
-int main() {\r
- char c;\r
- tpl_node *tn;\r
-\r
- tn = tpl_map("A(A(c))", &c);\r
-\r
- for(c='a'; c<'c'; c++) tpl_pack(tn,2); /* pack child (twice) */\r
- tpl_pack(tn, 1); /* pack parent */\r
-\r
- for(c='1'; c<'4'; c++) tpl_pack(tn,2); /* pack child (three times) */\r
- tpl_pack(tn, 1); /* pack parent */\r
-\r
- tpl_dump(tn, TPL_FILE, "test40.tpl");\r
- tpl_free(tn);\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>This creates a nested array in which the parent has two elements: the first\r
-element is the two-element nested array <em>a</em>, <em>b</em>; and the second element is\r
-the three-element nested array <em>1</em>, <em>2</em>, <em>3</em>.\r
-The <a href="#nested_unpack">nested unpacking example</a> shows how this tpl is unpacked.</p></div>\r
-<h3 id="tpl_dump">tpl_dump</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>After packing a tpl, <tt>tpl_dump()</tt> is used to write the tpl image to a file,\r
-memory buffer or file descriptor. The corresponding modes are shown below. A\r
-final mode is for querying the output size without actually performing the dump.</p></div>\r
-<div class="tableblock">\r
-<table rules="none"\r
-width="80%"\r
-frame="border"\r
-cellspacing="0" cellpadding="4">\r
-<col width="30%" />\r
-<col width="70%" />\r
-<thead valign="top">\r
-<tr>\r
-<th align="center">Write to… </th>\r
-<th align="left">Usage</th>\r
-</tr>\r
-</thead>\r
-<tbody valign="top">\r
-<tr>\r
-<td align="center"><p class="table">file</p></td>\r
-<td align="left"><p class="table"><tt>tpl_dump(tn, TPL_FILE, "file.tpl" );</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">file descriptor</p></td>\r
-<td align="left"><p class="table"><tt>tpl_dump(tn, TPL_FD, 2);</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">memory</p></td>\r
-<td align="left"><p class="table"><tt>tpl_dump(tn, TPL_MEM, &addr, &len );</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">caller’s memory</p></td>\r
-<td align="left"><p class="table"><tt>tpl_dump(tn, TPL_MEM|TPL_PREALLOCD, buf, sizeof(buf));</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="center"><p class="table">just get size</p></td>\r
-<td align="left"><p class="table"><tt>tpl_dump(tn, TPL_GETSIZE, &sz);</tt></p></td>\r
-</tr>\r
-</tbody>\r
-</table>\r
-</div>\r
-<div class="paragraph"><p>The first argument is the <tt>tpl_node*</tt> and the second is one of these constants:</p></div>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-<tt>TPL_FILE</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Writes the tpl to a file whose name is given in the following argument.\r
- The file is created with permissions 664 (<tt>rw-rw-r--</tt>) unless further\r
- restricted by the process <tt>umask</tt>.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-<tt>TPL_FD</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Writes the tpl to the file descriptor given in the following argument.\r
- The descriptor can be either blocking or non-blocking, but will busy-loop\r
- if non-blocking and the contents cannot be written immediately.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-<tt>TPL_MEM</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Writes the tpl to a memory buffer. The following two arguments must be a\r
- <tt>void**</tt> and a <tt>size_t*</tt>. The function will allocate a buffer and store\r
- its address and length into these locations. The caller is responsible to\r
- <tt>free()</tt> the buffer when done using it.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-<tt>TPL_MEM|TPL_PREALLOCD</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Writes the tpl to a memory buffer that the caller has already allocated or\r
- declared. The following two arguments must be a <tt>void*</tt> and a <tt>size_t</tt>\r
- specifying the buffer address and size respectively. (If the buffer is of\r
- insufficient size to receive the tpl dump, the function will return -1).\r
- This mode can be useful in conjunction with <tt>tpl_load</tt> in <tt>TPL_EXCESS_OK</tt>\r
- mode, as shown <a href="#excess_ok">here.</a>\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-<tt>TPL_GETSIZE</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- This special mode does not actually dump the tpl. Instead it places the size\r
- that the dump <em>would</em> require into the <tt>uint32_t</tt> pointed to by the\r
- following argument.\r
-</p>\r
-</dd>\r
-</dl></div>\r
-<div class="paragraph"><p>The return value is 0 on success, or -1 on error.</p></div>\r
-<div class="paragraph"><p>The <tt>tpl_dump()</tt> function does not free the tpl. Use <tt>tpl_free()</tt> to release\r
-the tpl’s resources when done.</p></div>\r
-<div class="admonitionblock">\r
-<table><tr>\r
-<td class="icon">\r
-<div class="title">Tip</div>\r
-</td>\r
-<td class="content">\r
-<div class="title">Back-to-back tpl images require no delimiter</div>If you want to store a series of tpl images, or transmit sequential tpl images\r
-over a socket (perhaps as messages to another program), you can simply dump them\r
-sequentially without needing to add any delimiter for the individual tpl images.\r
-Tpl images are internally delimited, so <tt>tpl_load</tt> will read just one at a time\r
-even if multiple images are contiguous.</td>\r
-</tr></table>\r
-</div>\r
-<h3 id="tpl_load">tpl_load</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This API function reads a previously-dumped tpl image from a file, memory\r
-buffer or file descriptor, and prepares it for subsequent unpacking. The format\r
-string specified in the preceding call to <tt>tpl_map()</tt> will be cross-checked\r
-for equality with the format string stored in the tpl image.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map( "A(i)", &i );\r
-tpl_load( tn, TPL_FILE, "demo.tpl" );</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The first argument to <tt>tpl_load()</tt> is the <tt>tpl_node*</tt>. The second argument is\r
-one of the constants:</p></div>\r
-<div class="dlist"><dl>\r
-<dt class="hdlist1">\r
-<tt>TPL_FILE</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Loads the tpl from the file named in the following argument. It is also\r
- possible to bitwise-OR this flag with <tt>TPL_EXCESS_OK</tt> as explained below.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-<tt>TPL_MEM</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Loads the tpl from a memory buffer. The following two arguments must be a\r
- <tt>void*</tt> and a <tt>size_t</tt>, specifying the buffer address and size,\r
- respectively. The caller must not free the memory buffer until after\r
- freeing the tpl with <tt>tpl_free()</tt>. (If the caller wishes to hand over\r
- responsibility for freeing the memory buffer, so that it’s automatically\r
- freed along with the tpl when <tt>tpl_free()</tt> is called, the constant\r
- <tt>TPL_UFREE</tt> may be bitwise-OR’d with <tt>TPL_MEM</tt> to achieve this).\r
- Furthermore, <tt>TPL_MEM</tt> may be bitwise-OR’d with <tt>TPL_EXCESS_OK</tt>, explained\r
- below.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
-<tt>TPL_FD</tt>\r
-</dt>\r
-<dd>\r
-<p>\r
- Loads the tpl from the file descriptor given in the following argument.\r
- The descriptor is read until one complete tpl image is loaded; no bytes\r
- past the end of the tpl image will be read. The descriptor can be either\r
- blocking or non-blocking, but will busy-loop if non-blocking and the\r
- contents cannot be read immediately.\r
-</p>\r
-</dd>\r
-</dl></div>\r
-<div class="paragraph"><p>During loading, the tpl image will be extensively checked for internal validity.</p></div>\r
-<div class="paragraph"><p>This function returns 0 on success or -1 on error.</p></div>\r
-<h4 id="excess_ok"><tt>TPL_EXCESS_OK</tt></h4>\r
-<div class="paragraph"><p>When reading a tpl image from a file or memory (but not from a file descriptor)\r
-the size of the file or memory buffer must exactly equal that of the tpl image\r
-stored therein. In other words, no excess trailing data beyond the tpl image is\r
-permitted. The bit flag <tt>TPL_EXCESS_OK</tt> can be OR’d with <tt>TPL_MEM</tt> or <tt>TPL_FILE</tt>\r
-to relax this requirement.</p></div>\r
-<div class="paragraph"><p>A situation where this flag can be useful is in conjunction with <tt>tpl_dump</tt> in\r
-the <tt>TPL_MEM|TPL_PREALLOCD</tt> mode. In this example, the program does not concern\r
-itself with the actual tpl size as long as <tt>LEN</tt> is sufficiently large.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>char buf[LEN]; /* will store and read tpl images here */\r
-...\r
-tpl_dump(tn, TPL_MEM|TPL_PREALLOCD, buf, LEN);\r
-...\r
-tpl_load(tn, TPL_MEM|TPL_EXCESS_OK, buf, LEN);</tt></pre>\r
-</div></div>\r
-<h3 id="tpl_unpack">tpl_unpack</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The <tt>tpl_unpack()</tt> function unpacks data from the tpl. When data is unpacked,\r
-it is copied to the C program variables originally specified in <tt>tpl_map()</tt>.\r
-The first argument to <tt>tpl_unpack</tt> is the <tt>tpl_node*</tt> for the tpl and the\r
-second argument is an <a href="#index">index number</a>.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tn = tpl_map( "A(i)A(c)", &i, &c );\r
-tpl_load( tn, TPL_FILE, "nested.tpl" );\r
-while (tpl_unpack( tn, 1) > 0) printf("i is %d\n", i); /* unpack index 1 */\r
-while (tpl_unpack( tn, 2) > 0) printf("c is %c\n", c); /* unpack index 2 */</tt></pre>\r
-</div></div>\r
-<h4 id="_index_number_0_2">Index number 0</h4>\r
-<div class="paragraph"><p>It is necessary to unpack index number 0 only if the format string contains\r
-characters that are not inside an <tt>A(…)</tt>, such as the <tt>i</tt> in the format string\r
-<tt>iA(c)</tt>.</p></div>\r
-<h4 id="_variable_length_arrays_2">Variable-length arrays</h4>\r
-<h5 id="_unpacking_elements_from_an_array">Unpacking elements from an array</h5>\r
-<div class="paragraph"><p>For variable-length arrays, each call to <tt>tpl_unpack()</tt> unpacks another element.\r
-The return value can be used to tell when you’re done: if it’s positive, an\r
-element was unpacked; if it’s 0, nothing was unpacked because there are no more\r
-elements. A negative retun value indicates an error (e.g. invalid index number).\r
-In this document, we usually unpack variable-length arrays using a <tt>while</tt> loop:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>while( tpl_unpack( tn, 1 ) > 0 ) {\r
- /* got another element */\r
-}</tt></pre>\r
-</div></div>\r
-<h5 id="_array_length">Array length</h5>\r
-<div class="paragraph"><p>When unpacking a variable-length array, it may be convenient to know ahead of\r
-time how many elements will need to be unpacked. You can use <tt>tpl_Alen()</tt> to\r
-get this number.</p></div>\r
-<h5 id="nested_unpack">Unpacking nested arrays</h5>\r
-<div class="paragraph"><p>In a format string containing a nested variable-length array such as <tt>A(A(s))</tt>,\r
-unpack the outer, parent array before unpacking the child array.</p></div>\r
-<div class="paragraph"><p>When you unpack a parent array, it prepares the child array for unpacking.\r
-After unpacking the elements of the child array, the program can repeat the\r
-process by unpacking another parent element, then the child elements, and so on.\r
-The example below unpacks a tpl having the format string <tt>A(A(c))</tt>.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Unpacking nested arrays</div>\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-#include <stdio.h>\r
-\r
-int main() {\r
- char c;\r
- tpl_node *tn;\r
-\r
- tn = tpl_map("A(A(c))", &c);\r
-\r
- tpl_load(tn, TPL_FILE, "test40.tpl");\r
- while (tpl_unpack(tn,1) > 0) {\r
- while (tpl_unpack(tn,2) > 0) printf("%c ",c);\r
- printf("\n");\r
- }\r
- tpl_free(tn);\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The file <tt>test40.tpl</tt> is from the <a href="#nested_pack">nested packing example</a>. When\r
-run, this program prints:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>a b\r
-1 2 3</tt></pre>\r
-</div></div>\r
-<h3 id="tpl_free">tpl_free</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>The final step for any tpl is to release it using <tt>tpl_free()</tt>. Its only\r
-argument is the the <tt>tpl_node*</tt> to free.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tpl_free( tn );</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>This function does not return a value (it is <tt>void</tt>).</p></div>\r
-<h3 id="tpl_alen">tpl_Alen</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This function takes a <tt>tpl_node*</tt> and an index number and returns an <tt>int</tt>\r
-specifying the number of elements in the variable-length array.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>num_elements = tpl_Alen(tn, index);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>This is mainly useful for programs that unpack data and need to know ahead of\r
-time the number of elements that will need to be unpacked. (It returns the\r
-current number of elements; it will decrease as elements are unpacked).</p></div>\r
-<h3 id="tpl_peek">tpl_peek</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This function peeks into a file or a memory buffer containing a tpl image and\r
-and returns a copy of its format string. It can also peek at the lengths of\r
-any fixed-length arrays in the format string, or it can also peek into the data\r
-stored in the tpl.</p></div>\r
-<h4 id="_format_peek">Format peek</h4>\r
-<div class="paragraph"><p>The format string can be obtained\r
-like this:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>fmt = tpl_peek(TPL_FILE, "file.tpl");\r
-fmt = tpl_peek(TPL_MEM, addr, sz);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>On success, a copy of the format string is returned. The caller must eventually\r
-free it. On error, such as a non-existent file, or an invalid tpl image, it\r
-returns <tt>NULL</tt>.</p></div>\r
-<h4 id="_array_length_peek">Array length peek</h4>\r
-<div class="paragraph"><p>The lengths of all fixed-length arrays in the format string can be queried using\r
-the <tt>TPL_FXLENS</tt> mode. It provides the number of such fixed-length arrays and\r
-their lengths. If the former is non-zero, the caller must free the latter array\r
-when finished. The format string itself must also be freed.</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>uint32_t num_fxlens, *fxlens, j;\r
-fmt = tpl_peek(TPL_FILE|TPL_FXLENS, filename, &num_fxlens, &fxlens);\r
-if (fmt) {\r
- printf("format %s, num_fxlens %u\n", fmt, num_fxlens);\r
- for(j=0; j<num_fxlens; j++) printf("fxlens[%u] %u\n", j, fxlens[j]);\r
- if (num_fxlens > 0) free(fxlens);\r
- free(fmt);\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The <tt>TPL_FXLENS</tt> mode is mutually exclusive with <tt>TPL_DATAPEEK</tt>.</p></div>\r
-<h4 id="_data_peek">Data peek</h4>\r
-<div class="paragraph"><p>To peek into the data, additional arguments are used. This is a quick\r
-alternative to mapping, loading and unpacking the tpl, but peeking is limited\r
-to the data in index 0. In other words, no peeking into <tt>A(…)</tt> types.\r
-Suppose the tpl image in <tt>file.tpl</tt> has the format string <tt>siA(i)</tt>. Then the\r
-index 0 format characters are <tt>si</tt>. This is how to peek at their content:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>char *s;\r
-int i;\r
-fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "file.tpl", "si", &s, &i);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>Now <tt>s</tt>, <tt>i</tt>, and <tt>fmt</tt> have been populated with data. The caller must\r
-eventually free <tt>fmt</tt> and <tt>s</tt> because they are allocated strings.\r
-Of course, it works with <tt>TPL_MEM</tt> as well as <tt>TPL_FILE</tt>. Notice that\r
-<tt>TPL_DATAPEEK</tt> was OR’d with the mode. You can also specify <em>any leading\r
-portion</em> of the index 0 format if you don’t want to peek at the whole thing:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "file.tpl", "s", &s);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The <tt>TPL_DATAPEEK</tt> mode is mutually exclusive with <tt>TPL_FXLENS</tt>.</p></div>\r
-<h5 id="_structure_peek">Structure peek</h5>\r
-<div class="paragraph"><p>Lastly you can peek into <tt>S(…)</tt> structures in index 0, but omit the\r
-surrounding <tt>S(…)</tt> in the format, and specify an argument to receive\r
-each structure member individually. You can specify any leading portion\r
-of the structure format. For example if <tt>struct.tpl</tt> has the format string\r
-<tt>S(si)</tt>, you can peek at its data in these ways:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "struct.tpl", "s", &s);\r
-fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "struct.tpl", "si", &s, &i);</tt></pre>\r
-</div></div>\r
-<h3 id="tpl_jot">tpl_jot</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>This is a quick shortcut for generating a tpl. It can be used instead of the\r
-usual "map, pack, dump, and free" lifecycle. With <tt>tpl_jot</tt> all those steps are\r
-handled for you. It only works for simple formats-- namely, those without\r
-<tt>A(…)</tt> in their format string. Here is how it is used:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>char *hello = "hello", *world = "world";\r
-tpl_jot( TPL_FILE, "file.tpl", "ss", &hello, &world);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>It supports the three standard modes, <tt>TPL_FILE</tt>, <tt>TPL_FD</tt> and <tt>TPL_MEM</tt>.\r
-It returns -1 on failure (such as a bad format string or error writing the\r
-file) or 0 on success.</p></div>\r
-<h3 id="hooks">tpl_hook</h3><div style="clear:left"></div>\r
-<div class="paragraph"><p>Most users will just leave these hooks at their default values. You can change\r
-these hook values if you want to modify tpl’s internal memory management and\r
-error reporting behavior.</p></div>\r
-<div class="paragraph"><p>A global structure called <tt>tpl_hook</tt> encapsulates the hooks. A program can\r
-reconfigure any hook by specifying an alternative function whose prototype\r
-matches the default. For example:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>#include "tpl.h"\r
-extern tpl_hook_t tpl_hook;</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>int main() {\r
- tpl_hook.oops = printf;\r
- ...\r
-}</tt></pre>\r
-</div></div>\r
-<div class="tableblock">\r
-<table rules="none"\r
-width="90%"\r
-frame="border"\r
-cellspacing="0" cellpadding="4">\r
-<caption class="title">Configurable hooks</caption>\r
-<col width="33%" />\r
-<col width="33%" />\r
-<col width="33%" />\r
-<thead valign="top">\r
-<tr>\r
-<th align="left">Hook </th>\r
-<th align="left">Description </th>\r
-<th align="left"> Default</th>\r
-</tr>\r
-</thead>\r
-<tbody valign="top">\r
-<tr>\r
-<td align="left"><p class="table"><tt>tpl_hook.oops</tt></p></td>\r
-<td align="left"><p class="table">log error messages</p></td>\r
-<td align="left"><p class="table"><tt>tpl_oops</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="left"><p class="table"><tt>tpl_hook.malloc</tt></p></td>\r
-<td align="left"><p class="table">allocate memory</p></td>\r
-<td align="left"><p class="table"><tt>malloc</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="left"><p class="table"><tt>tpl_hook.realloc</tt></p></td>\r
-<td align="left"><p class="table">reallocate memory</p></td>\r
-<td align="left"><p class="table"><tt>realloc</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="left"><p class="table"><tt>tpl_hook.free</tt></p></td>\r
-<td align="left"><p class="table">free memory</p></td>\r
-<td align="left"><p class="table"><tt>free</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="left"><p class="table"><tt>tpl_hook.fatal</tt></p></td>\r
-<td align="left"><p class="table">log fatal message and exit</p></td>\r
-<td align="left"><p class="table"><tt>tpl_fatal</tt></p></td>\r
-</tr>\r
-<tr>\r
-<td align="left"><p class="table"><tt>tpl_hook.gather_max</tt></p></td>\r
-<td align="left"><p class="table">tpl_gather max image size</p></td>\r
-<td align="left"><p class="table"><tt>0 (unlimited)</tt></p></td>\r
-</tr>\r
-</tbody>\r
-</table>\r
-</div>\r
-<h4 id="_the_oops_hook">The oops hook</h4>\r
-<div class="paragraph"><p>The <tt>oops</tt> has the same prototype as <tt>printf</tt>. The built-in default oops\r
-handling function writes the error message to <tt>stderr</tt>.</p></div>\r
-<h4 id="_the_fatal_hook">The fatal hook</h4>\r
-<div class="paragraph"><p>The fatal hook is invoked when a tpl function cannot continue because of an out-\r
-of-memory condition or some other usage violation or inconsistency. It has this\r
-prototype:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>void fatal_fcn(char *fmt, ...);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The <tt>fatal</tt> hook must not return. It must either exit, <em>or</em> if the program needs\r
-to handle the failure and keep executing, <tt>setjmp</tt> and <tt>longjmp</tt> can be used.\r
-The default behavior is to <tt>exit(-1)</tt>.</p></div>\r
-<div class="listingblock">\r
-<div class="title">Using longjmp in a fatal error handler</div>\r
-<div class="content">\r
-<pre><tt>#include <setjmp.h>\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-#include "tpl.h"\r
-\r
-jmp_buf env;\r
-extern tpl_hook_t tpl_hook;\r
-\r
-void catch_fatal(char *fmt, ...) {\r
- va_list ap;\r
-\r
- va_start(ap, fmt);\r
- vfprintf(stderr, fmt, ap);\r
- va_end(ap);\r
- longjmp(env,-1); /* return to setjmp point */\r
-}\r
-\r
-int main() {\r
- int err;\r
- tpl_node *tn;\r
- tpl_hook.fatal = catch_fatal; /* install fatal handler */\r
-\r
- err = setjmp(env); /* on error, control will return here */\r
- if (err) {\r
- printf("caught error!\n");\r
- return -1;\r
- }\r
-\r
- tn = tpl_map("@"); /* generate a fatal error */\r
- printf("program ending, without error\n");\r
- return 0;\r
-}</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>This example is included in <tt>tests/test123.c</tt>. When run, this program prints:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>unsupported option @\r
-failed to parse @\r
-caught error!</tt></pre>\r
-</div></div>\r
-<h3 id="_tpl_gather">tpl_gather</h3><div style="clear:left"></div>\r
-<div class="sidebarblock">\r
-<div class="sidebar-content">\r
-<div class="sidebar-title">Most programs don’t need this</div>\r
-<div class="paragraph"><p>Normally, <tt>tpl_load()</tt> is used to read a tpl image having an expected format\r
-string. A more generic operation is to acquire a tpl image whose format string is\r
-unknown. E.g., a generic message-receiving function might gather tpl images of\r
-varying format and route them to their final destination. This is the purpose of\r
-<tt>tpl_gather</tt>. It produces a memory buffer containing one tpl image. If there\r
-are multiple contiguous images in the input, it gathers exactly one image at a\r
-time.</p></div>\r
-</div></div>\r
-<div class="paragraph"><p>The prototype for this function is:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>int tpl_gather( int mode, ...);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The <tt>mode</tt> argument is one of three constants listed below, which must be\r
-followed by the mode-specific required arguments:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>TPL_GATHER_BLOCKING, int fd, void **img, size_t *sz\r
-TPL_GATHER_NONBLOCKING, int fd, tpl_gather_t **gs, tpl_gather_cb *cb, void *data\r
-TPL_GATHER_MEM, void *addr, size_t sz, tpl_gather_t **gs, tpl_gather_cb *cb, void *data</tt></pre>\r
-</div></div>\r
-<div class="admonitionblock">\r
-<table><tr>\r
-<td class="icon">\r
-<div class="title">Note</div>\r
-</td>\r
-<td class="content">\r
-<div class="title"><tt>tpl_hook.gather_max</tt></div>All modes honor <tt>tpl_hook.gather_max</tt>, specifying the maximum byte size for a\r
-tpl image to be gathered (the default is unlimited, signified by 0). If a source\r
-attempts to send a tpl image larger than this maximum, whatever partial image\r
-has been read will be discarded, and no further reading will take place; in this\r
-case <tt>tpl_gather</tt> will return a negative (error) value to inform the caller that\r
-it should stop gathering from this source, and close the originating file\r
-descriptor if there is one. (The whole idea is to prevent untrusted sources from\r
-sending extremely large tpl images which would consume too much memory.)</td>\r
-</tr></table>\r
-</div>\r
-<h4 id="_tt_tpl_gather_blocking_tt"><tt>TPL_GATHER_BLOCKING</tt></h4>\r
-<div class="paragraph"><p>In this mode, <tt>tpl_gather</tt> blocks while reading file descriptor <tt>fd</tt> until one\r
-complete tpl image is read. No bytes past the end of the tpl image will be read.\r
-The address of the buffer containing the image is returned in <tt>img</tt> and its size\r
-is placed in <tt>sz</tt>. The caller is responsible for eventually freeing the buffer.\r
-The function returns 1 on success, 0 on end-of-file, or a negative number on\r
-error.</p></div>\r
-<h4 id="_tt_tpl_gather_nonblocking_tt"><tt>TPL_GATHER_NONBLOCKING</tt></h4>\r
-<div class="paragraph"><p>This mode is for non-blocking, event-driven programs that implement their\r
-own file descriptor readability testing using <tt>select()</tt> or the like. In this\r
-mode, tpl images are gathered in chunks as data becomes readable. Whenever a\r
-full tpl image has been gathered, it invokes a caller-specified callback to do\r
-something with the image. The arguments are the file descriptor <tt>fd</tt> which the\r
-caller has determined to be readable and which must be in non-blocking mode, a\r
-pointer to a file-descriptor-specific handle which the caller has declared\r
-(explained below); a callback to invoke when a tpl image has been read; and an\r
-opaque pointer that will passed to the callback.</p></div>\r
-<div class="paragraph"><p>For each file descriptor on which <tt>tpl_gather</tt> will be used, the caller must\r
-declare a <tt>tpl_gather_t*</tt> and initialize it to <tt>NULL</tt>. Thereafter it will be\r
-used internally by <tt>tpl_gather</tt> whenever data is readable on the descriptor.</p></div>\r
-<div class="paragraph"><p>The callback will only be invoked whenever <tt>tpl_gather()</tt> has accumulated one\r
-complete tpl image. It must have this prototype:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>int (tpl_gather_cb)(void *img, size_t sz, void *data);</tt></pre>\r
-</div></div>\r
-<div class="paragraph"><p>The callback can do anything with the tpl image but it must not free it. It can\r
-be copied if it needs to survive past the callback’s return. The callback should\r
-return 0 under normal circumstances, or a negative number to abort; that is,\r
-returning a negative number causes <tt>tpl_gather</tt> itself to discard any remaining\r
-full or partial tpl images that have been read, and to return a negative number\r
-(-4 in particular) to signal its caller to close the file descriptor.</p></div>\r
-<div class="paragraph"><p>The return value of <tt>tpl_gather()</tt> is negative if an error occured or 0 if a\r
-normal EOF was encountered-- both cases require that the caller close the file\r
-descriptor (and stop monitoring it for readability, obviously). If the return\r
-value is positive, the function succeeded in gathering whatever data was\r
-currently readable, which may have been a partial tpl image, or one or more\r
-complete images.</p></div>\r
-<h5 id="_typical_usage">Typical Usage</h5>\r
-<div class="paragraph"><p>The program will have established a file descriptor in non-blocking mode and\r
-be monitoring it for readability, using <tt>select()</tt>. Whenever it’s readable, the\r
-program calls <tt>tpl_gather()</tt>. In skeletal terms:</p></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>tpl_gather_t *gt=NULL;\r
-int rc;</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>void fd_is_readable(int fd) {\r
- rc = tpl_gather( TPL_GATHER_NONBLOCKING, fd, &gt, callback, NULL );\r
- if (rc <= 0) {\r
- close(fd); /* got eof or fatal */\r
- stop_watching_fd(fd);\r
- }\r
-}</tt></pre>\r
-</div></div>\r
-<div class="literalblock">\r
-<div class="content">\r
-<pre><tt>int callback( void *img, size_t sz, void *data ) {\r
- printf("got a tpl image\n"); /* do something with img. do not free it. */\r
- return 0; /* normal (no error) */\r
-}</tt></pre>\r
-</div></div>\r
-<h4 id="_tt_tpl_gather_mem_tt"><tt>TPL_GATHER_MEM</tt></h4>\r
-<div class="paragraph"><p>This mode is identical to <tt>TPL_GATHER_NONBLOCKING</tt> except that it gathers from a\r
-memory buffer instead of from a file descriptor. In other words, if some other\r
-layer of code-- say, a decryption function (that is decrypting fixed-size\r
-blocks) produces tpl fragments one-by-one, this mode can be used to reconstitute\r
-the tpl images and invoke the callback for each one. Its parameters are the same\r
-as for the <tt>TPL_GATHER_NONBLOCKING</tt> mode except that instead of a file\r
-descriptor, it takes a buffer address and size. The return values are also the\r
-same as for <tt>TPL_GATHER_NONBLOCKING</tt> noting of course there is no file\r
-descriptor to close on a non-positive return value.</p></div>\r
-</div>\r
-<div id="footer">\r
-<div id="footer-text">\r
-Version 1.5<br />\r
-Last updated 2010-02-05 04:37:37 EDT\r
-</div>\r
-</div>\r
-</body>\r
-</html>\r
+++ /dev/null
-tpl ChangeLog
-=============
-
-Version 1.5 (2010-02-05)
---------------------------
-* tpl now builds as a DLL under Microsoft Visual Studio! (thanks, degski and Zhang Yafei!)
-* there are now two download options: the http://downloads.sourceforge.net/tpl/libtpl-1.5.tar.bz2[tarball] and the Visual Studio http://downloads.sourceforge.net/tpl/tpl-1.5-vs2008.zip[solution]
-* a crash in `tpl_free` on certain format strings has been fixed (thanks, Eric Rose!)
-* fixed a bug in `tpl_dump` on 64-bit, big-endian platforms
-* changed some pointer casts from `long` to `uintptr_t` since 64-bit Windows has 32-bit longs
-* tpl has been downloaded 4,195 times.
-
-
-Version 1.4 (2009-04-21)
---------------------------
-* fixed-length arrays can now be multi-dimensional like `i##`
-* fixed-length string arrays like `s#` are now supported
-* nested structures can now be expressed, using the dollar symbol, e.g. `S(ci$(cc))`
-* `tpl_dump` can use a caller-allocated output buffer (`TPL_MEM|TPL_PREALLOCD`)
-* `tpl_load` can tolerate excess space in input buffer (`TPL_MEM|TPL_EXCESS_OK`)
-* implement `TPL_FXLENS` flag for `tpl_peek` to get lengths of fixed-length arrays
-* implement `TPL_GETSIZE` flag for `tpl_dump` to get dump size without dumping
-* fix success return code from `tpl_dump(TPL_FD,...)` (thanks, Max Lapan!)
-* deprecated the wildcard unpacking `S(*)` feature
-
-Version 1.3 (2009-02-10)
---------------------------
-* added `TPL_DATAPEEK` mode for `tpl_peek`
-* added support for `NULL` strings
-* added support for 16-bit integer types (`j`,`v`)
-* added `tpl_jot`
-* added support for fixed-length arrays of structures `S(...)#`
-* added support for pre-C99 compilers (thanks, Wei Wei!)
-* improved structure alignment calculation (thanks, Wu Yongwei!)
-* added RPM spec file (thanks, Alessandro Ren!)
-* compiles cleanly with `-Wall` and `-pedantic` and with `-O3`
-* made link:license.html[BSD license] terms even more permissive
-* test suite: exit with status zero when all tests pass
-* added PDF user guide
-* added http://troydhanson.wordpress.com/feed/[update news] image:img/rss.png[(RSS)]
-* added http://apps.sourceforge.net/mediawiki/tpl/[tpl wiki]
-
-Version 1.2 (2007-04-27)
---------------------------
-* Perl API and XML converter support 64-bit types
-
-Version 1.1 (2007-04-25)
---------------------------
-* support for serializing C structures
-* support for serializing fixed-length arrays
-* MinGW support (thanks, Horea Haitonic!)
-* revised User Guide
-
-Version 1.0 (2006-09-28)
---------------------------
-* Initial version
-
-// vim: set tw=80 wm=2 nowrap syntax=asciidoc:
-
+++ /dev/null
-Compiling libtpl.a and libtpl.so
---------------------------------
-
-********************************************************************************
-Normally in the top-level directory you simply run:
-
- ./configure
- make
- make install
-
-The rest of the document is not needed if you use this method.
-********************************************************************************
-
-
-Manual compilation of static and shared library on a GNU Linux system:
-----------------------------------------------------------------------
-
-First cd into the "src" directory.
-
-Static library
-~~~~~~~~~~~~~~
-You can build the static library `libtpl.a` using these commands:
-
- cc -c tpl.c
- ar rc libtpl.a tpl.o
- ranlib libtpl.a
-
-Dynamic library
-~~~~~~~~~~~~~~
-You can build the dynamic library `libtpl.so` using these commands:
-
- cc -fpic -c tpl.c
- cc -shared -o libtpl.so tpl.o
-
-Keep in mind that you need to set the `LD_LIBRARY_PATH` environment variable
-to include the directory where `libtpl.so` is installed in order for your
-program to run. Alternatively you can put `libtpl.so` in a standard place like
-`/usr/lib` and regenerate `ld.so.cache` using `ldconfig`.
+++ /dev/null
-tpl examples
-============
-Troy D. Hanson <troydhanson@comcast.net>>
-v1.0, October 2006
-
-include::sflogo.txt[]
-include::topnav.txt[]
-
-Examples
---------
-include::toc.txt[]
-
-This document is a set of representative examples demonstrating how to use
-tpl. If you're looking for a more explanatory document, please read the
-link:userguide.html[User Guide].
-
-An integer array
-~~~~~~~~~~~~~~~~
-
-.Storing an array of integers to file
--------------------------------------------------------------------------------
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map( "A(i)", &i );
- for( i=0; i<10; i++ ) {
- tpl_pack( tn, 1 );
- }
- tpl_dump( tn, TPL_FILE, "demo.tpl" );
- tpl_free( tn );
-}
--------------------------------------------------------------------------------
-
-A program that unpacks this tpl data file is shown below.
-
-.Re-reading an array of integers from file
--------------------------------------------------------------------------------
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map( "A(i)", &i );
- tpl_load( tn, TPL_FILE, "demo.tpl" );
- while (tpl_unpack( tn, 1 ) > 0) {
- printf("%d ", i);
- }
- tpl_free( tn );
-}
--------------------------------------------------------------------------------
-
-When run, this program prints:
-
- 0 1 2 3 4 5 6 7 8 9
-
-
-A nested array
-~~~~~~~~~~~~~~
-
-.Packing nested arrays
---------------------------------------------------------------------------------
-#include "tpl.h"
-
-int main() {
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(A(c))", &c);
-
- for(c='a'; c<'c'; c++) tpl_pack(tn,2);
- tpl_pack(tn, 1);
-
- for(c='1'; c<'4'; c++) tpl_pack(tn,2);
- tpl_pack(tn, 1);
-
- tpl_dump(tn, TPL_FILE, "test40.tpl");
- tpl_free(tn);
-}
---------------------------------------------------------------------------------
-
-This creates a nested array in which the parent has two elements: the first
-element is the two-element nested array 'a', 'b'; and the second element is
-the three-element nested array '1', '2', '3'.
-
-.Unpacking nested arrays
---------------------------------------------------------------------------------
-#include "tpl.h"
-#include <stdio.h>
-
-int main() {
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(A(c))", &c);
-
- tpl_load(tn, TPL_FILE, "test40.tpl");
- while (tpl_unpack(tn,1) > 0) {
- while (tpl_unpack(tn,2) > 0) printf("%c ",c);
- printf("\n");
- }
- tpl_free(tn);
-}
---------------------------------------------------------------------------------
-
-
-When run, this program prints:
-
- a b
- 1 2 3
-
-A string array
-~~~~~~~~~~~~~~
-
-.Packing a string array
--------------------------------------------------------------------------------
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- char *s;
-
- tn = tpl_map( "A(s)", &s );
-
- s = "bob";
- tpl_pack(tn, 1);
-
- s = "betty";
- tpl_pack(tn, 1);
-
- tpl_dump(tn, TPL_FILE, "strings.tpl");
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-.Unpacking a string array
--------------------------------------------------------------------------------
- #include <stdio.h>
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- char *s;
-
- tn = tpl_map( "A(s)", &s );
- tpl_load( tn, TPL_FILE, "strings.tpl" );
-
- while (tpl_unpack( tn, 1 ) > 0) {
- printf("%s\n", s);
- free(s); /* important! */
- }
-
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-When run, this program prints:
-
- bob
- betty
-
-Integer/string pairs
-~~~~~~~~~~~~~~~~~~~~
-
-.Packing integer/string pairs
--------------------------------------------------------------------------------
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- int id;
- char *name, *names[] = { "joe", "bob", "mary" };
-
- tn = tpl_map("A(is)", &id, &name);
-
- for(id=0,name=names[id]; id < 3; name=names[++id])
- tpl_pack(tn,1);
-
- tpl_dump(tn, TPL_FILE, "/tmp/test35.tpl");
- tpl_free(tn);
-}
--------------------------------------------------------------------------------
-
-.Unpacking integer/string pairs
--------------------------------------------------------------------------------
-#include <stdio.h>
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- int id;
- char *name;
-
- tn = tpl_map("A(is)", &id, &name);
- tpl_load(tn, TPL_FILE, "/tmp/test35.tpl");
-
- while ( tpl_unpack(tn,1) > 0 )
- printf("id %d, user %s\n", id, name);
-
- tpl_free(tn);
-}
--------------------------------------------------------------------------------
-
-When run, this program prints:
-
- id 0, user joe
- id 1, user bob
- id 2, user mary
-
-A binary buffer
-~~~~~~~~~~~~~~~
-
-.Packing a binary buffer
--------------------------------------------------------------------------------
- #include "tpl.h"
- #include <sys/time.h>
-
- int main() {
- tpl_node *tn;
- tpl_bin tb;
- struct timeval tv; /* we'll pack this structure as raw binary */
- gettimeofday(&tv,NULL); /* populate the structure with some data */
-
- tn = tpl_map( "B", &tb );
- tb.sz = sizeof(struct timeval);
- tb.addr = &tv;
- tpl_pack( tn, 0 );
-
- tpl_dump(tn, TPL_FILE, "bin.tpl");
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-
-.Unpacking a binary buffer
--------------------------------------------------------------------------------
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- tpl_bin tb;
-
- tn = tpl_map( "B", &tb );
- tpl_load( tn, TPL_FILE, "bin.tpl" );
-
- tpl_unpack( tn, 0 );
- printf("binary buffer of length %d at address %p\n", tb.sz, tb.addr);
- free(tb.addr); /* important! */
-
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-
-Simple pipe IPC
-~~~~~~~~~~~~~~~
-
-This is a simple example of inter-process communication (IPC) over a pipe.
-
-.IPC over a pipe
--------------------------------------------------------------------------------
-int main() {
- tpl_node *tn;
- unsigned i, sum=0;
- int fd[2], pid;
-
- pipe(fd);
- if ( (pid = fork()) == 0) { /* child */
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd[0]);
- while (tpl_unpack(tn,1) > 0) sum += i;
- tpl_free(tn);
- printf("sum is %d\n", sum);
-
- } else if (pid > 0) { /* parent */
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10000;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd[1] );
- tpl_free(tn);
-
- waitpid(pid,NULL,0);
- }
-}
--------------------------------------------------------------------------------
-
-The child unpacks the integers in the message, and sums them, printing:
-
- 49995000
-
-The example above (with `#include` headers omitted here) is included in the
-file `tests/test28.c`.
+++ /dev/null
-For future reference these are some API design ideas- not working code!
-
---------------------------------------------------------------------------------
-Java API ideas
---------------------------------------------------------------------------------
-http://www.ioplex.com/~miallen/encdec/ (binary pack/unpack utilities)
-
-The Java API would take an object, and a list of field names, then use the
-Java Reflection API to read or write those fields during packing and
-unpacking.
-
-I.e. if you are going to unpack a tpl with format string A(if), you
-might create a Java class that has two instance variables (an int and
-a double). Then you create an object of that class, and pass it to
-tpl_map (or perhaps a constructor for the Tpl class), like
-
-class Unpacker {
- int count;
- double weight;
-}
-...
-Unpacker up = new Unpacker();
-Tpl tn = new Tpl("A(if)", up, "count", "weight");
-tn.tpl_unpack(1); // stores unpacked values into count,weight using Reflection
-
---------------------------------------------------------------------------------
-Ruby API ideas
---------------------------------------------------------------------------------
-#!/usr/local/ruby/bin/ruby -w
-
-class Tpl < Hash
- def initialize(fmt, *args)
- @fmt = fmt
- @args = args
- end
-
- def pack
- @args.each {|key| puts "#{key} #{self[key]}"}
- end
-end
-
-
-p = Tpl.new("A(i)", :id);
-10.times do |i|
- p[:id] = i
- p.pack
-end
-p.dump("/tmp/file.tpl") # p.dump(arg) checks arg.respond_to?(:write)
-
-p = Tpl.new("A(i)", :id);
-p.load("/tmp/file.tpl")
-p.unpack(1) {|h| puts h[:id]}
+++ /dev/null
-tpl Perl API
-============
-Troy D. Hanson <troydhanson@comcast.net>
-v1.1, April 2007
-
-include::sflogo.txt[]
-include::topnav.txt[]
-
-Perl API
---------
-include::toc.txt[]
-
-The Perl API for reading and writing tpl is nearly identical to the C API. This
-document will briefly explain the Perl API and provide examples. The chief
-motivation for having a Perl API is to communicate with C programs that use tpl.
-
-[TIP]
-.Start with the C API
-This document assumes familiarity with the C API. The concepts of using tpl
-are not explained here. For an introduction to tpl and its C API, see the
-link:userguide.html[User Guide].
-
-Tpl.pm
-~~~~~~
-The `Tpl.pm` file (in the `lang/perl`) directory contains the Perl module. You
-can copy it to another directory if you wish. Your Perl program may need to
-include a `use lib` statement to find the module.
-
- #!/usr/bin/perl
- use lib "/some/directory";
- use Tpl;
-
-tpl_map
-~~~~~~~
-This function resembles the C version, except that it's invoked via the `Tpl`
-module, and it takes references to Perl variables after the format string.
-
- my $i;
- my $tpl = Tpl->tpl_map("A(i)",\$i);
-
-The return value is a tpl object; all other API calls are object methods.
-Incidentally, there is no `tpl_free()` method corresponding to the C API.
-
-Fixed-length arrays
-^^^^^^^^^^^^^^^^^^^
-Format strings such as `i#` denote a fixed-length array. In the Perl API,
-fixed-length arrays require two arguments: a list reference, and the fixed
-length. For example:
-
- my @x;
- my $tpl = Tpl->tpl_map("i#", \@x, 10);
-
-When fixed-length arrays are packed or unpacked, the specified number of
-elements will be copied from (or placed into) the designated list.
-
-Structures
-^^^^^^^^^^
-Format strings containing `S(...)` are handled in the Perl API as if only the
-interior, parenthesized part was present. (It does not work like the C API). So
-simply ignore the `S(...)` and consider only its interior format characters when
-constructing the argument list:
-
- my ($str, $int);
- my $tpl = Tpl->tpl_map("S(si)", \$str, \$int);
-
-It really only makes sense to use `S(...)` in a format string in the Perl API if
-you are communicating with a C program that uses structures.
-
-tpl_pack
-~~~~~~~~
-This is nearly identical to the C version. The only argument is the index
-number to pack.
-
- $tpl->tpl_pack(1);
-
-tpl_dump
-~~~~~~~~
-This method is a little different than the C version. Given no arguments, it
-returns the tpl image; given one argument it writes a file with that name.
-
- $tpl->tpl_dump("demo.tpl"); # writes demo.tpl
-
-Or,
-
- my $img = $tpl->tpl_dump();
-
-The tpl image is a binary buffer. You can do whatever you want with it, such as
-write it to a socket or pipe (probably to C program listening on the other end),
-or save it somewhere and later re-load it using `tpl_load()`.
-
-tpl_load
-~~~~~~~~
-This method loads a tpl image from a file or from a Perl variable. It takes
-one argument. If it's not a reference, it's assumed to be a filename to load.
-
- $tpl->tpl_load("demo.tpl");
-
-Otherwise, if the argument is a Perl reference, it's construed as a variable
-containing the tpl image:
-
- $tpl->tpl_load(\$img);
-
-The method will `die` if the image is invalid or the file doesn't exist. You
-can wrap it with `eval` to catch such errors:
-
- eval { $tpl->tpl_load(\$img); };
- print "failed to load\n" if $@;
-
-tpl_unpack
-~~~~~~~~~~
-This is nearly identical to the C version. The only argument is the index
-number to unpack.
-
- $tpl->tpl_unpack(1);
-
-Examples
---------
-
-Integer array
-~~~~~~~~~~~~~
-
-.Packing A(i) to file
---------------------------------------------------------------------------------
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-for($i=0; $i<10; $i++) {
- $tpl->tpl_pack(1);
-}
-$tpl->tpl_dump("demo.tpl");
---------------------------------------------------------------------------------
-
-.Unpacking A(i) from file
---------------------------------------------------------------------------------
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use Tpl;
-
-my $j;
-my $tpl2 = Tpl->tpl_map("A(i)",\$j);
-$tpl2->tpl_load("demo.tpl");
-while($tpl2->tpl_unpack(1) > 0) {
- print "$j\n";
-}
---------------------------------------------------------------------------------
-
-Message-passing
-~~~~~~~~~~~~~~~
-While the bulk of this example is socket handling, it demonstrates how you can
-use tpl as a message-passing format. In the real-world, you might have a C
-server and a Perl client, for example. In this example, we'll code both a client
-and a server in Perl.
-
-.A server that sums integers
-********************************************************************************
-Programming literature is rife with contrived examples so we will follow in that
-tradition. Our server will do no more than sum a list of integers. But in doing
-so it will demonstrate message passing adequately. Both its input (the integer
-array) and its output (an integer) are tpl images, passed over a TCP/IP socket.
-********************************************************************************
-
-Server
-^^^^^^
-The server waits for a connection from a client. When it gets one, it accepts
-the connection and immediately forks a child process to handle it. Then it goes
-back to waiting for another new connection.
-
-The server child process handles the client by loading and unpacking the tpl
-image sent by the client (containing an array of integers). It calculates their
-sum and constructs a new tpl image containing the sum, which it sends back to
-the client.
-
-.Server
---------------------------------------------------------------------------------
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use IO::Socket::INET;
-use Tpl;
-
-$SIG{CHLD} = "IGNORE"; # don't create zombies
-
-our $port = 2000;
-
-sub handle_client {
- my $client = shift;
-
- undef $/;
- my $request = <$client>; # get request (slurp)
-
- # read input array, and calculate total
- my ($i,$total);
- my $tpl = Tpl->tpl_map("A(i)", \$i);
- eval { $tpl->tpl_load(\$request); };
- die "received invalid tpl" if $@;
- $total += $i while $tpl->tpl_unpack(1) > 0;
-
- # formulate response and send
- my $tpl2 = Tpl->tpl_map("i", \$total);
- $tpl2->tpl_pack(0);
- my $response = $tpl2->tpl_dump();
- print $client $response;
- close $client;
-}
-
-my $server = IO::Socket::INET->new(LocalPort => $port,
- Type => SOCK_STREAM,
- Reuse => 1,
- Listen => 10 )
- or die "Can't listen on port $port: $!\n";
-
-while (1) {
- my $client = $server->accept();
- next unless $client;
- # new connection
- my $pid = fork;
- die "can't fork: $!\n" unless defined $pid;
- if ($pid > 0) {
- # parent
- close $client;
- } elsif ($pid == 0) {
- # child
- handle_client($client);
- exit(0);
- }
-}
-close ($server);
---------------------------------------------------------------------------------
-
-Client
-^^^^^^
-
-The client is a simpler program. It constructs the tpl image containing the
-integer array (taken from its command-line arguments), connects to the server
-and sends the tpl image to it, and then awaits the response tpl. The response
-containing the sum is loaded, unpacked and printed.
-
-.Client
---------------------------------------------------------------------------------
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use IO::Socket::INET;
-use Tpl;
-
-our $port = 2000;
-
-# construct tpl
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-$tpl->tpl_pack(1) while ($i=shift @ARGV);
-my $request = $tpl->tpl_dump();
-
-# send to server, get response
-my $socket = IO::Socket::INET->new("localhost:$port") or die "can't connect";
-print $socket $request;
-shutdown($socket,1); # done writing (half-close)
-undef $/;
-my $response = <$socket>; # get reply (slurp)
-
-# decode response (or print error)
-my $total;
-my $tpl2 = Tpl->tpl_map("i", \$total);
-eval { $tpl2->tpl_load(\$response); };
-die "invalid response\n" if $@;
-$tpl2->tpl_unpack(0);
-print "total is $total\n";
---------------------------------------------------------------------------------
-
-Running thise example
-^^^^^^^^^^^^^^^^^^^^^
-If the client and server programs are in `client.pl` and `server.pl`, then
-you can run the example by starting the server in one window:
-
- ./server.pl
-
-Then run the client in another window. E.g.,
-
- ./client.pl 1 2 3 4 5
-
-The client runs and then exits, printing:
-
- total is 15
-
-You can re-run the client with different arguments. When done, type `Ctrl-C` in
-the server window to terminate it.
-
-// vim: set tw=80 wm=2 syntax=asciidoc:
-
+++ /dev/null
-ifdef::backend-xhtml11[]
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-<a style="float: right;" href="http://sourceforge.net/projects/tpl"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=157637&type=16" width="150" height="40" alt="SourceForge.net" /></a>
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-endif::backend-xhtml11[]
+++ /dev/null
-ifdef::backend-xhtml11[]
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-<div id="toc"></div>
-<script>
-window.onload=generate_TOC
-
-/* Author: Mihai Bazon, September 2002
- * http://students.infoiasi.ro/~mishoo
- *
- * Table Of Content generator
- * Version: 0.4
- *
- * Feel free to use this script under the terms of the GNU General Public
- * License, as long as you do not remove or alter this notice.
- */
-
- /* modified by Troy D. Hanson, September 2006. License: GPL */
-
-function H_getText(el) {
- var text = "";
- for (var i = el.firstChild; i != null; i = i.nextSibling) {
- if (i.nodeType == 3 /* Node.TEXT_NODE, IE doesn't speak constants */)
- text += i.data;
- else if (i.firstChild != null)
- text += H_getText(i);
- }
- return text;
-}
-
-function TOC_EL(el, text, level) {
- this.element = el;
- this.text = text;
- this.level = level;
-}
-
-function getHeadlines(el) {
- var l = new Array;
- var rx = /[hH]([2-3])/;
- // internal recursive function that scans the DOM tree
- var rec = function (el) {
- for (var i = el.firstChild; i != null; i = i.nextSibling) {
- if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
- if (rx.exec(i.tagName))
- l[l.length] = new TOC_EL(i, H_getText(i), parseInt(RegExp.$1));
- rec(i);
- }
- }
- }
- rec(el);
- return l;
-}
-
-function generate_TOC() {
- var parent = document.getElementById("toc");
- var toc_hdr = document.createElement("div");
- var toc_hdr_txt = document.createTextNode("CONTENTS");
- toc_hdr.appendChild(toc_hdr_txt);
- /* toc_hdr.setAttribute("id","hdr"); */
- toc_hdr.id = "hdr";
- parent.appendChild(toc_hdr);
- var hs = getHeadlines(document.getElementsByTagName("body")[0]);
- for (var i = 0; i < hs.length; ++i) {
- var hi = hs[i];
- var d = document.createElement("div");
- if (hi.element.id == "") hi.element.id = "gen" + i;
- var a = document.createElement("a");
- a.href = "#" + hi.element.id;
- a.appendChild(document.createTextNode(hi.text));
- d.appendChild(a);
- d.className = "level" + hi.level;
- parent.appendChild(d);
- /*
- if (hi.level == 3) {
- var dvtop = document.createElement("div");
- dvtop.className = "toplink";
- dvtop.appendChild(document.createTextNode("^top^"));
- dvtop.onclick=function(){scrollTo(0,0);};
- hi.element.appendChild(dvtop);
- }
- */
- }
-}
-</script>
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-endif::backend-xhtml11[]
+++ /dev/null
-ifdef::backend-xhtml11[]
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- <div id="topnav" style="font-size: 9pt; font-family: sans-serif;">
- <a style="padding: 8px;" href="http://sourceforge.net/projects/tpl/">sf.net summary page</a> >
- <a style="padding: 8px;" href="index.html">tpl home</a> >
- {doctitle}
- <a style="padding: 8px;" href="userguide.pdf">[View PDF]</a>
- </div>
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-endif::backend-xhtml11[]
+++ /dev/null
-tpl User Guide
-==============
-Troy D. Hanson <thanson@users.sourceforge.net>
-v1.5, February 2010
-
-include::sflogo.txt[]
-include::topnav.txt[]
-
-Overview
---------
-include::toc.txt[]
-
-Serialization in C
-~~~~~~~~~~~~~~~~~~
-Tpl is a library for serializing C data. The data is stored in its natural
-binary form. The API is small and tries to stay "out of the way".
-Tpl can serialize many C data types, including structures.
-
-Uses for tpl
-~~~~~~~~~~~~
-Tpl makes a convenient file format. For example, suppose a program needs to
-store a list of user names and ids. This can be expressed using the format
-string `A(si)`. If the program needs two such lists (say, one for regular
-users and one for administrators) this could be expressed as `A(si)A(si)`. It
-is easy to read and write this kind of structured data using tpl.
-
-Tpl can also be used as an IPC message format. It handles byte order issues
-and deframing individual messages off of a stream automatically.
-
-Expressing type
-~~~~~~~~~~~~~~~
-The "data type" of a tpl is explicitly stated as a format string. There is
-never any ambiguity about the type of data stored in a tpl. Some examples:
-
-* `A(is)` is a variable-length array of integer-string pairs
-* `A(is)A(is)` are two such arrays, completely independent of one another
-* `S(ci)` is a structure containing a char and integer
-* `S(ci)#` is a fixed-length array of the latter structure
-* `A(A(i))` is a nested array, that is, an array of integer arrays
-
-The tpl image
-~~~~~~~~~~~~~
-A tpl image is the serialized form of a tpl, stored in a memory buffer or file,
-or written to a file descriptor.
-
-What's in a tpl image?
-^^^^^^^^^^^^^^^^^^^^^^
-There is no need to understand the internal structure of the tpl image. But for the
-curious, the image is a strictly defined binary buffer having two sections,
-a header and the data. The header encodes the length of the image, its
-format string, endian order and other flags. The data section contains the
-packed data.
-
-No framing needed
-^^^^^^^^^^^^^^^^^
-A property of the tpl image is that consecutive images can be written to a stream
-without requiring any delimiter between them. The reader making use of
-`tpl_gather` (or `tpl_load` in `TPL_FD` mode) will obtain exactly one tpl image at
-a time. Therefore tpl images can be used as an IPC message format without any
-higher-level framing protocol.
-
-Data portability
-^^^^^^^^^^^^^^^^
-A tpl image generated on one kind of CPU will generally be portable to other
-CPU types when tpl is used properly. This may be a surprise considering that
-tpl is a binary format. But tpl has been carefully designed to make this work.
-Each <<types,format character>> has an associated explicitly-sized type. For
-integer and floating point types, whose "endian" or byte-order convention varies
-from one CPU to another, tpl automatically and transparently corrects the
-endian order (if needed) during the unpacking process. Floating point numbers
-present their own <<trouble_with_double,special difficulties>>. 'No guarantees
-are made with regard to floating point portability.' That said, because many
-modern CPU's use IEEE 754 floating point representation, data is likely to be
-portable among them.
-
-XML and Perl
-~~~~~~~~~~~~
-'Note: The `tplxml` utility and the Perl module are currently unsupported in tpl 1.5.'
-
-XML
-^^^
-While a tpl image is a binary entity, you can view any tpl image in XML format
-using the included `tplxml` utility, located in the `lang/perl` directory.
-
- tplxml file.tpl > file.xml
- tplxml file.xml > file.tpl
-
-The utility is bidirectional, as shown. The file extension is not important;
-`tplxml` inspects its input to see if it's tpl or XML. You can also pipe data
-into it instead of giving it a filename. The `tplxml` utility is slow. Its
-purpose is two-fold: debugging (manual inspection of the data in a tpl), and
-interoperability with XML-based programs. The resulting XML is often ten times
-the size of the original binary tpl image.
-
-Perl
-^^^^
-There is a Perl module in `lang/perl/Tpl.pm`. The link:perl.html[Perl API]
-is convenient for writing Perl scripts that interoperate with C programs, and
-need to pass structured data back and forth. It is written in pure Perl.
-
-Platforms
-~~~~~~~~~
-The tpl software was developed for POSIX systems and has been tested on 32- and 64-bit
-platforms including:
-
- * Linux
- * Solaris
- * Mac OS X
- * OpenBSD
- * Windows using Visual Studio 2008 or 2010, or Cygwin or MinGW
-
-BSD licensed
-~~~~~~~~~~~~
-This software is made available under the
-link:license.html[revised BSD license].
-It is free and open source.
-
-Download
-~~~~~~~~
-Please follow the link to download on the
-http://tpl.sourceforge.net[tpl website].
-
-Getting help
-~~~~~~~~~~~~
-If you need help, you are welcome to email the author at
-mailto:thanson@users.sourceforge.net[].
-
-Resources
-~~~~~~~~~
-News::
- The author has a news feed for http://troydhanson.wordpress.com/feed/[software updates] image:img/rss.png[(RSS)].
-
-Build and install
------------------
-
-Tpl has no dependencies on libraries other than the system C library. You
-can simply copy the tpl source into your project, so you have no dependencies.
-Alternatively, you can build tpl as a library and link it to your program.
-
-As source
-~~~~~~~~~
-The simplest way to use tpl is to copy the source files `tpl.h` and `tpl.c`
-(from the `src/` directory) right into your project, and build them with the
-rest of your source files. No special compiler flags are required.
-
-As a library
-~~~~~~~~~~~~
-Alternatively, to build tpl as a library, from the top-level directory, run:
-
- ./configure
- make
- make install
-
-This installs a static library `libtpl.a` and a shared library (e.g.,
-`libtpl.so`), if your system supports them, in standard places. The installation
-directory can be customized using `./configure --prefix=/some/directory`. Run
-`configure --help` for further options.
-
-Test suite
-^^^^^^^^^^
-You can compile and run the built-in test suite by running:
-
- cd tests/
- make
-
-On Windows
-~~~~~~~~~~
-
-DLL
-^^^
-On the tpl home page, a Visual Studio 2008 solution package is available for
-download. This zip file contains pre-built 32- and 64-bit versions of tpl as a
-DLL. If you like, you can build the DLL yourself using VS2008 or VS2010 (the
-free Express Edition is sufficient) by opening the solution file and choosing
-Build Solution.
-
-Non-DLL usage
-^^^^^^^^^^^^^
-Alternatively, tpl can be used directly (instead of as a DLL) by compiling
-the tpl sources right into your program. To do this, add `tpl.c`, `tpl.h`,
-`win/mman.h` and `win/mmap.c` to your program's source and header files and
-add the preprocessor definition `TPL_NOLIB`.
-
-MinGW/Cygwin
-^^^^^^^^^^^^
-Prior to tpl release 1.5, using tpl on Windows required building it with MinGW
-or Cygwin. This is no longer necessary. If you want to build it that way anyway,
-use the non-Windows (i.e. tar.bz2) tpl download and follow the "configure; make;
-make install" approach.
-
-API concepts
-------------
-To use tpl, you need to know the order in which to call the API functions, and
-the background concepts of format string, arrays and index numbers.
-
-Order of functions
-~~~~~~~~~~~~~~~~~~
-Creating a tpl is always the first step, and freeing it is the last step. In
-between, you either pack and dump the tpl (if you're serializing data) or you
-load a tpl image and unpack it (if you're deserializing data).
-
-.Order of usage
-[width="50%",cols="^1,^5m,^5m",grid="none",options="header"]
-|===============================================================================
-|Step | If you're serializing...| If you're deserializing...
-| 1. | tpl_map() | tpl_map()
-| 2. | tpl_pack() | tpl_load()
-| 3. | tpl_dump() | tpl_unpack()
-| 4. | tpl_free() | tpl_free()
-|===============================================================================
-
-[[format]]
-Format string
-~~~~~~~~~~~~~
-When a tpl is created using `tpl_map()`, its data type is expressed as a format
-string. Each character in the format string has an associated argument of a
-specific type. For example, this is how a format string and its arguments are
-passed in to `tpl_map`:
-
- tpl_node *tn;
- char c;
- int i[10];
- tn = tpl_map("ci#", &c, i, 10); /* ci# is our format string */
-
-[[types]]
-.Supported format characters
-[width="90%",grid="none",options="header",cols="5^m,20,20"]
-|================================================================================
-|Type | Description | Required argument type
-| j | 16-bit signed int | int16_t* or equivalent
-| v | 16-bit unsigned int | uint16_t* or equivalent
-| i | 32-bit signed int | int32_t* or equivalent
-| u | 32-bit unsigned int | uint32_t* or equivalent
-| I | 64-bit signed int | int64_t* or equivalent
-| U | 64-bit unsigned int | uint64_t* or equivalent
-| c | character (byte) | char*
-| s | string | char**
-| f | 64-bit double precision float | double* (varies by platform)
-| # | array length; modifies preceding `iujvIUcsf` or `S(...)`| int
-| B | binary buffer (arbitrary-length) | tpl_bin*
-| S | structure (...) | struct *
-| $ | nested structure (...) | none
-| A | array (...) | none
-|================================================================================
-
-Explicit sizes
-^^^^^^^^^^^^^^
-The sizes of data types such as `long` and `double` vary by platform. This must
-be kept in mind because most tpl format characters require a pointer argument to
-a specific-sized type, listed above. You can use explicit-sized types such as
-`int32_t` (defined in `inttypes.h`) in your program if you find this helpful.
-
-[[trouble_with_double]]
-The trouble with double
-+++++++++++++++++++++++
-Unfortunately there are no standard explicit-sized floating-point types-- no
-`float64_t`, for example. If you plan to serialize `double` on your platform
-using tpl's `f` format character, first be sure that your `double` is 64 bits.
-Second, if you plan to deserialize it on a different kind of CPU, be sure that
-both CPU's use the same floating-point representation such as IEEE 754.
-
-[[arrays]]
-Arrays
-~~~~~~
-Arrays come in two kinds: *fixed-length* and *variable-length* arrays.
-Intuitively, they can be thought of like conventional C arrays and linked lists.
-In general, use fixed-length arrays if possible, and variable-length arrays
-if necessary. The variable-length arrays support more complex data types, and
-give or receive the elements to your program one by one.
-
-Fixed-length vs. Variable-length arrays
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Notation::
- Fixed-length arrays are denoted like `i#` (a simple type followed by one or
- more `#` signs), but variable-length arrays are denoted like `A(i)`.
-Element handling::
- All the elements of a fixed-length array are packed or unpacked at once. But
- the elements of a variable-length array are packed or unpacked one by one.
-Array length::
- The number of elements in a fixed-length array is specified before use--
- before any data is packed. But variable-length arrays do not have a fixed
- element count. They can have any number of elements packed into them. When
- unpacking a variable-length array, they are unpacked one by one until they
- are exhausted.
-Element types::
- Elements of fixed-length arrays can be the integer, byte, double, string
- types or structures. (This excludes format characters `BA`). Fixed-length
- arrays can also be multi-dimensional like `i##`. Variable-length arrays can
- have simple or complex elements-- for example, an array of ints `A(i)`, an
- array of int/double pairs `A(if)`, or even nested arrays like `A(A(if))`.
-
-Before explaining all the concepts, it's illustrative to see how both kinds of
-arrays are used. Let's pack the integers 0 through 9 both ways.
-
-//|================================================================================
-//|Fixed-length array packing | Variable-length array packing
-//|#include "tpl.h" | #include "tpl.h"
-//|int main() { | int main() {
-//| tpl_node *tn; | tpl_node *tn;
-//| int x[] = {0,1,2,3,4,5,6,7,8,9}; | int x;
-//| |
-//| tn = tpl_map("i#", x, 10); | tn = tpl_map("A(i)", &x);
-//| /* pack all 10 elements at once */ | /* pack one element at a time */
-//| tpl_pack(tn,0); | for(x = 0; x < 10; x++) tpl_pack(tn,1);
-//| tpl_dump(tn, TPL_FILE, "/tmp/fixed.tpl");| tpl_dump(tn, TPL_FILE, "/tmp/variable.tpl");
-//| tpl_free(tn); | tpl_free(tn);
-//|} | }
-//|================================================================================
-
-[[fixed_pack]]
-.Packing 0-9 as a fixed-length array
--------------------------------------------------------------------------------
-#include "tpl.h"
-int main() {
- tpl_node *tn;
- int x[] = {0,1,2,3,4,5,6,7,8,9};
-
- tn = tpl_map("i#", x, 10);
- tpl_pack(tn,0); /* pack all 10 elements at once */
- tpl_dump(tn, TPL_FILE, "/tmp/fixed.tpl");
- tpl_free(tn);
-}
--------------------------------------------------------------------------------
-
-Note that the length of the fixed-length array (10) was passed as an argument to
-`tpl_map()`. The corresponding unpacking <<fixed_unpack,example>> is listed
-further below. Now let's see how we would pack 0-9 as a variable-length array:
-
-.Packing 0-9 as a variable-length array
--------------------------------------------------------------------------------
-#include "tpl.h"
-int main() {
- tpl_node *tn;
- int x;
-
- tn = tpl_map("A(i)", &x);
- for(x = 0; x < 10; x++) tpl_pack(tn,1); /* pack one element at a time */
- tpl_dump(tn, TPL_FILE, "/tmp/variable.tpl");
- tpl_free(tn);
-}
--------------------------------------------------------------------------------
-
-Notice how we called `tpl_pack` in a loop, once for each element 0-9. Again,
-there is a corresponding unpacking <<var_unpack,example>> shown later in the
-guide. You might also notice that this time, we passed 1 as the final argument
-to tpl_pack. This is an index number designating which variable-length array
-we're packing. In this case, there is only one.
-
-[[index]]
-Index numbers
-^^^^^^^^^^^^^
-Index numbers identify a particular variable-length array in the format string.
-Each `A(...)` in a format string has its own index number. The index numbers
-are assigned left-to-right starting from 1. Examples:
-
- A(i) /* index number 1 */
- A(i)A(i) /* index numbers 1 and 2 */
- A(A(i)) /* index numbers 1 and 2 (order is independent of nesting) */
-
-Special index number 0
-++++++++++++++++++++++
-The special index number 0 designates all the format characters that are not
-inside an `A(...)`. Examples of what index 0 does (and does not) designate:
-
- S(ius) /* index 0 designates the whole thing */
- iA(c)u /* index 0 designates the i and the u */
- c#A(i)S(ci) /* index 0 designates the c# and the S(ci) */
-
-An index number is passed to `tpl_pack` and `tpl_unpack` to specify which
-variable-length array (or non-array, in the case of index number 0) to act upon.
-
-Integers
-~~~~~~~~
-The array examples <<fixed_pack,above>> demonstrated how integers could be
-packed. We'll show some further examples here of unpacking integers and dealing
-with multi-dimensional arrays. The same program could be used to demonstrate
-working with byte, 16-bit shorts, 32-bit or 64-bit signed and unsigned integers
-with only a change to the data type and the format character.
-
-[[fixed_unpack]]
-.Unpacking 0-9 from a fixed-length array
---------------------------------------------------------------------------------
-#include "tpl.h"
-int main() {
- tpl_node *tn;
- int x[10];
-
- tn = tpl_map("i#", x, 10);
- tpl_load(tn, TPL_FILE, "/tmp/fixed.tpl");
- tpl_unpack(tn,0); /* unpack all 10 elements at once */
- tpl_free(tn);
- /* now do something with x[0]...x[9].. (not shown */
-}
---------------------------------------------------------------------------------
-
-For completeness, let's also see how to unpack a variable-length integer array.
-
-[[var_unpack]]
-.Unpacking 0-9 from a variable-length array
--------------------------------------------------------------------------------
-#include "tpl.h"
-int main() {
- tpl_node *tn;
- int x;
-
- tn = tpl_map("A(i)", &x);
- tpl_load(tn, TPL_FILE, "/tmp/variable.tpl");
- while (tpl_unpack(tn,1) > 0) printf("%d\n",x); /* unpack one by one */
- tpl_free(tn);
-}
--------------------------------------------------------------------------------
-
-[[multidim_int]]
-Multi-dimensional arrays
-^^^^^^^^^^^^^^^^^^^^^^^^
-A multi-dimensional matrix of integers can be packed and unpacked the same way
-as any fixed-length array.
-
- int xy[XDIM][YDIM];
- ...
- tn = tpl_map("i##", xy, XDIM, YDIM);
- tpl_pack(tn, 0);
-
-This single call to `tpl_pack` packs the entire matrix.
-
-Strings
-~~~~~~~
-Tpl can serialize C strings. A different format is used for `char*` vs. `char[ ]`
-as described below. Let's look at `char*` first:
-
-.Packing a string
--------------------------------------------------------------------------------
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- char *s = "hello, world!";
- tn = tpl_map("s", &s);
- tpl_pack(tn,0); /* copies "hello, world!" into the tpl */
- tpl_dump(tn,TPL_FILE,"string.tpl");
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-The `char*` must point to a null-terminated string or be a `NULL` pointer.
-
-When deserializing (unpacking) a C string, space for it will be allocated
-automatically, but you are responsible for freeing it (unless it is `NULL`):
-
-.Unpacking a string
--------------------------------------------------------------------------------
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- char *s;
- tn = tpl_map("s", &s);
- tpl_load(tn,TPL_FILE,"string.tpl");
- tpl_unpack(tn,0); /* allocates space, points s to "hello, world!" */
- printf("unpacked %s\n", s);
- free(s); /* our responsibility to free s */
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-char* vs char[ ]
-^^^^^^^^^^^^^^^^
-The `s` format character is only for use with `char*` types. In the example
-above, `s` is a `char*`. If it had been a `char s[14]`, we would use the format
-characters `c#` to pack or unpack it, as a fixed-length character array. (This
-unpacks the characters "in-place", instead of into a dynamically allocated
-buffer). Also, a fixed-length buffer described by `c#` need not be
-null-terminated.
-
-Arrays of strings
-^^^^^^^^^^^^^^^^^
-You can use fixed- or variable-length arrays of strings in tpl. An example of
-packing a fixed-length two-dimensional array of strings is shown here.
-
- char *labels[2][3] = { {"one", "two", "three"},
- {"eins", "zwei", "drei" } };
- tpl_node *tn;
- tn = tpl_map("s##", labels, 2, 3);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
-Later, when unpacking these strings, the programmer must remember to free them
-one by one, after they are no longer needed.
-
- char *olabels[2][3];
- int i,j;
-
- tn = tpl_map("s##", olabels, 2, 3);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- for(i=0;i<2;i++) {
- for(j=0;j<3;j++) {
- printf("%s\n", olabels[i][j]);
- free(olabels[i][j]);
- }
- }
-
-Binary buffers
-~~~~~~~~~~~~~~
-Packing an arbitrary-length binary buffer (tpl format character `B`) makes use
-of the `tpl_bin` structure. You must declare this structure and populate it
-with the address and length of the binary buffer to be packed.
-
-.Packing a binary buffer
--------------------------------------------------------------------------------
- #include "tpl.h"
- #include <sys/time.h>
-
- int main() {
- tpl_node *tn;
- tpl_bin tb;
-
- /* we'll use a timeval as our guinea pig */
- struct timeval tv;
- gettimeofday(&tv,NULL);
-
- tn = tpl_map( "B", &tb );
- tb.sz = sizeof(struct timeval); /* size of buffer to pack */
- tb.addr = &tv; /* address of buffer to pack */
- tpl_pack( tn, 0 );
- tpl_dump(tn, TPL_FILE, "bin.tpl");
- tpl_free(tn);
- }
--------------------------------------------------------------------------------
-
-When you unpack a binary buffer, tpl will automatically allocate it, and will
-populate your `tpl_bin` structure with its address and length. You are
-responsible for eventually freeing the buffer.
-
-.Unpacking a binary buffer
--------------------------------------------------------------------------------
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- tpl_bin tb;
-
- tn = tpl_map( "B", &tb );
- tpl_load( tn, TPL_FILE, "bin.tpl" );
- tpl_unpack( tn, 0 );
- tpl_free(tn);
-
- printf("binary buffer of length %d at address %p\n", tb.sz, tb.addr);
- free(tb.addr); /* our responsibility to free it */
- }
--------------------------------------------------------------------------------
-
-Structures
-~~~~~~~~~~
-You can use tpl to pack and unpack structures, and arrays of structures.
-
- struct ci {
- char c;
- int i;
- };
- struct ci s = {'a', 1};
-
- tn = tpl_map("S(ci)", &s); /* pass structure address */
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_FILE, "struct.tpl");
- tpl_free(tn);
-
-As shown, omit the individual arguments for the format characters inside the
-parenthesis. The exception is for fixed-length arrays; when `S(...)` contains a
-`#` character, its length argument is required: `tpl_map("S(f#i)", &s, 10);`
-
-When using the `S(...)` format, the only characters allowed inside the
-parentheses are `iujvcsfIU#$()`.
-
-Structure arrays
-^^^^^^^^^^^^^^^^
-Arrays of structures are the same as simple arrays. Fixed- or variable- length
-arrays are supported.
-
- struct ci sa[100], one;
-
- tn = tpl_map("S(ci)#", sa, 100); /* fixed-length array of 100 structures */
- tn = tpl_map("A(S(ci))", &one); /* variable-length array (one at a time)*/
-
-The differences between fixed- and variable-length arrays are explained in the
-<<arrays,Arrays>> section.
-
-Nested structures
-^^^^^^^^^^^^^^^^^
-When dealing with nested structures, the outermost structure uses the `S` format
-character, and the inner nested structures use the `$` format. Only the
-'outermost' structure's address is given to `tpl_map`.
-
- struct inner_t {
- char a;
- }
-
- struct outer_t {
- char b;
- struct inner_t i;
- }
-
- tpl_node *tn;
- struct outer_t outer = {'b', {'a'}};
-
- tn = tpl_map("S(c$(c))", &outer);
-
-Structures can nest to any level. Currently tpl does not support fixed-length
-array suffixes on inner structures. However the outermost structure can have a
-length suffix even if it contains some nested structures.
-
-Linked lists
-~~~~~~~~~~~~
-While tpl has no specific data type for a linked list, the technique for
-packing them is illustrated here. First describe your list element as a
-format string and then surround it with `A(...)` to describe it as
-variable-length array. Then, using a temporary variable, iterate over each
-list element, copying it to the temporary variable and packing it.
-
- struct element {
- char c;
- int i;
- struct element *next;
- }
-
- struct element *list, *i, tmp;
- tpl_node *tn;
-
- /* add some elements to list.. (not shown)*/
-
- tn = tpl_map("A(ci)", &tmp);
- for(i = list; i != NULL; i=i->next) {
- tmp = *i;
- tpl_pack(tn, 1);
- }
- tpl_dump(tn,TPL_FILE,"list.tpl");
- tpl_free(tn);
-
-Unpacking is similar. The `for` loop is just replaced with:
-
- while( tpl_unpack(tn,1) > 0) {
- struct element *newelt = malloc(sizeof(struct element));
- *newelt = tmp;
- add_to_list(list, newelt);
- }
-
-As you can see, tpl does not reinstate the whole list at once-- just one
-element at a time. You need to link the elements manually. A future release of
-tpl may support 'pointer swizzling' to make this easier.
-
-API
----
-
-[[tpl_map]]
-tpl_map
-~~~~~~~
-The only way to create a tpl is to call `tpl_map()`. The first argument is the
-<<format,format string>>. This is followed by a list of arguments as required by
-the particular characters in the format string. E.g,
-
- tpl_node *tn;
- int i;
- tn = tpl_map( "A(i)", &i );
-
-The function creates a mapping between the items in the format string and the C
-program variables whose addresses are given. Later, the C variables will be read
-or written as the tpl is packed or unpacked.
-
-This function returns a `tpl_node*` on success, or `NULL` on failure.
-
-[[tpl_pack]]
-tpl_pack
-~~~~~~~~
-The function `tpl_pack()` packs data into a tpl. The arguments to
-`tpl_pack()` are a `tpl_node*` and an <<index,index number>>.
-
- tn = tpl_map("A(i)A(c)", &i, &c);
- for(i=0; i<10; i++) tpl_pack(tn, 1); /* pack 0-9 into index 1 */
- for(c='a; c<='z'; c++) tpl_pack(tn, 2); /* pack a-z into index 2 */
-
-.Data is copied when packed
-********************************************************************************
-Every call to `tpl_pack()` immediately 'copies' the data being packed. Thus
-the program is free to immediately overwrite or re-use the packed variables.
-********************************************************************************
-
-Index number 0
-^^^^^^^^^^^^^^
-It is necessary to pack index number 0 only if the format string contains
-characters that are not inside an `A(...)`, such as the `i` in the format string
-`iA(c)`.
-
-Variable-length arrays
-^^^^^^^^^^^^^^^^^^^^^^
-
-Adding elements to an array
-+++++++++++++++++++++++++++
-To add elements to a variable-length array, call `tpl_pack()` repeatedly. Each
-call adds another element to the array.
-
-Zero-length arrays are ok
-+++++++++++++++++++++++++
-It's perfectly acceptable to pack nothing into a variable-length array,
-resulting in a zero-length array.
-
-[[nested_pack]]
-Packing nested arrays
-+++++++++++++++++++++
-In a format string containing a nested, variable-length array, such as
-`A(A(s))`, the inner, child array should be packed prior to the parent array.
-
-When you pack a parent array, a "snapshot" of the current child array is placed
-into the parent's new element. Packing a parent array also empties the child
-array. This way, you can pack new data into the child, then pack the parent
-again. This creates distinct parent elements which each contain distinct child
-arrays.
-
-[TIP]
-When dealing with nested arrays like `A(A(i))`, 'pack' them from the "inside
-out" (child first), but 'unpack' them from the "outside in" (parent first).
-
-The example below creates a tpl having the format string `A(A(c))`.
-
-.Packing nested arrays
---------------------------------------------------------------------------------
-#include "tpl.h"
-
-int main() {
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(A(c))", &c);
-
- for(c='a'; c<'c'; c++) tpl_pack(tn,2); /* pack child (twice) */
- tpl_pack(tn, 1); /* pack parent */
-
- for(c='1'; c<'4'; c++) tpl_pack(tn,2); /* pack child (three times) */
- tpl_pack(tn, 1); /* pack parent */
-
- tpl_dump(tn, TPL_FILE, "test40.tpl");
- tpl_free(tn);
-}
---------------------------------------------------------------------------------
-
-This creates a nested array in which the parent has two elements: the first
-element is the two-element nested array 'a', 'b'; and the second element is
-the three-element nested array '1', '2', '3'.
-The <<nested_unpack,nested unpacking example>> shows how this tpl is unpacked.
-
-[[tpl_dump]]
-tpl_dump
-~~~~~~~~
-After packing a tpl, `tpl_dump()` is used to write the tpl image to a file,
-memory buffer or file descriptor. The corresponding modes are shown below. A
-final mode is for querying the output size without actually performing the dump.
-
-[width="80%",options="header",cols="30^d,70m",grid="none"]
-|================================================================================
-|Write to... |Usage
-|file |tpl_dump(tn, TPL_FILE, "file.tpl" );
-|file descriptor |tpl_dump(tn, TPL_FD, 2);
-|memory |tpl_dump(tn, TPL_MEM, &addr, &len );
-|caller's memory |tpl_dump(tn, TPL_MEM\|TPL_PREALLOCD, buf, sizeof(buf));
-|just get size |tpl_dump(tn, TPL_GETSIZE, &sz);
-|================================================================================
-
-The first argument is the `tpl_node*` and the second is one of these constants:
-
-`TPL_FILE`::
- Writes the tpl to a file whose name is given in the following argument.
- The file is created with permissions 664 (`rw-rw-r--`) unless further
- restricted by the process `umask`.
-`TPL_FD`::
- Writes the tpl to the file descriptor given in the following argument.
- The descriptor can be either blocking or non-blocking, but will busy-loop
- if non-blocking and the contents cannot be written immediately.
-`TPL_MEM`::
- Writes the tpl to a memory buffer. The following two arguments must be a
- `void\*\*` and a `size_t*`. The function will allocate a buffer and store
- its address and length into these locations. The caller is responsible to
- `free()` the buffer when done using it.
-`TPL_MEM|TPL_PREALLOCD`::
- Writes the tpl to a memory buffer that the caller has already allocated or
- declared. The following two arguments must be a `void*` and a `size_t`
- specifying the buffer address and size respectively. (If the buffer is of
- insufficient size to receive the tpl dump, the function will return -1).
- This mode can be useful in conjunction with `tpl_load` in `TPL_EXCESS_OK`
- mode, as shown <<excess_ok,here.>>
-`TPL_GETSIZE`::
- This special mode does not actually dump the tpl. Instead it places the size
- that the dump 'would' require into the `uint32_t` pointed to by the
- following argument.
-
-The return value is 0 on success, or -1 on error.
-
-The `tpl_dump()` function does not free the tpl. Use `tpl_free()` to release
-the tpl's resources when done.
-
-[TIP]
-.Back-to-back tpl images require no delimiter
-If you want to store a series of tpl images, or transmit sequential tpl images
-over a socket (perhaps as messages to another program), you can simply dump them
-sequentially without needing to add any delimiter for the individual tpl images.
-Tpl images are internally delimited, so `tpl_load` will read just one at a time
-even if multiple images are contiguous.
-
-[[tpl_load]]
-tpl_load
-~~~~~~~~
-This API function reads a previously-dumped tpl image from a file, memory
-buffer or file descriptor, and prepares it for subsequent unpacking. The format
-string specified in the preceding call to `tpl_map()` will be cross-checked
-for equality with the format string stored in the tpl image.
-
- tn = tpl_map( "A(i)", &i );
- tpl_load( tn, TPL_FILE, "demo.tpl" );
-
-The first argument to `tpl_load()` is the `tpl_node*`. The second argument is
-one of the constants:
-
-`TPL_FILE`::
- Loads the tpl from the file named in the following argument. It is also
- possible to bitwise-OR this flag with `TPL_EXCESS_OK` as explained below.
-`TPL_MEM`::
- Loads the tpl from a memory buffer. The following two arguments must be a
- `void*` and a `size_t`, specifying the buffer address and size,
- respectively. The caller must not free the memory buffer until after
- freeing the tpl with `tpl_free()`. (If the caller wishes to hand over
- responsibility for freeing the memory buffer, so that it's automatically
- freed along with the tpl when `tpl_free()` is called, the constant
- `TPL_UFREE` may be bitwise-OR'd with `TPL_MEM` to achieve this).
- Furthermore, `TPL_MEM` may be bitwise-OR'd with `TPL_EXCESS_OK`, explained
- below.
-`TPL_FD`::
- Loads the tpl from the file descriptor given in the following argument.
- The descriptor is read until one complete tpl image is loaded; no bytes
- past the end of the tpl image will be read. The descriptor can be either
- blocking or non-blocking, but will busy-loop if non-blocking and the
- contents cannot be read immediately.
-
-During loading, the tpl image will be extensively checked for internal validity.
-
-This function returns 0 on success or -1 on error.
-
-[[excess_ok]]
-`TPL_EXCESS_OK`
-^^^^^^^^^^^^^^^
-When reading a tpl image from a file or memory (but not from a file descriptor)
-the size of the file or memory buffer must exactly equal that of the tpl image
-stored therein. In other words, no excess trailing data beyond the tpl image is
-permitted. The bit flag `TPL_EXCESS_OK` can be OR'd with `TPL_MEM` or `TPL_FILE`
-to relax this requirement.
-
-A situation where this flag can be useful is in conjunction with `tpl_dump` in
-the `TPL_MEM|TPL_PREALLOCD` mode. In this example, the program does not concern
-itself with the actual tpl size as long as `LEN` is sufficiently large.
-
- char buf[LEN]; /* will store and read tpl images here */
- ...
- tpl_dump(tn, TPL_MEM|TPL_PREALLOCD, buf, LEN);
- ...
- tpl_load(tn, TPL_MEM|TPL_EXCESS_OK, buf, LEN);
-
-
-
-
-[[tpl_unpack]]
-tpl_unpack
-~~~~~~~~~~
-The `tpl_unpack()` function unpacks data from the tpl. When data is unpacked,
-it is copied to the C program variables originally specified in `tpl_map()`.
-The first argument to `tpl_unpack` is the `tpl_node*` for the tpl and the
-second argument is an <<index,index number>>.
-
- tn = tpl_map( "A(i)A(c)", &i, &c );
- tpl_load( tn, TPL_FILE, "nested.tpl" );
- while (tpl_unpack( tn, 1) > 0) printf("i is %d\n", i); /* unpack index 1 */
- while (tpl_unpack( tn, 2) > 0) printf("c is %c\n", c); /* unpack index 2 */
-
-Index number 0
-^^^^^^^^^^^^^^
-It is necessary to unpack index number 0 only if the format string contains
-characters that are not inside an `A(...)`, such as the `i` in the format string
-`iA(c)`.
-
-Variable-length arrays
-^^^^^^^^^^^^^^^^^^^^^^
-
-Unpacking elements from an array
-++++++++++++++++++++++++++++++++
-For variable-length arrays, each call to `tpl_unpack()` unpacks another element.
-The return value can be used to tell when you're done: if it's positive, an
-element was unpacked; if it's 0, nothing was unpacked because there are no more
-elements. A negative retun value indicates an error (e.g. invalid index number).
-In this document, we usually unpack variable-length arrays using a `while` loop:
-
- while( tpl_unpack( tn, 1 ) > 0 ) {
- /* got another element */
- }
-
-Array length
-++++++++++++
-When unpacking a variable-length array, it may be convenient to know ahead of
-time how many elements will need to be unpacked. You can use `tpl_Alen()` to
-get this number.
-
-[[nested_unpack]]
-Unpacking nested arrays
-+++++++++++++++++++++++
-In a format string containing a nested variable-length array such as `A(A(s))`,
-unpack the outer, parent array before unpacking the child array.
-
-When you unpack a parent array, it prepares the child array for unpacking.
-After unpacking the elements of the child array, the program can repeat the
-process by unpacking another parent element, then the child elements, and so on.
-The example below unpacks a tpl having the format string `A(A(c))`.
-
-.Unpacking nested arrays
---------------------------------------------------------------------------------
-#include "tpl.h"
-#include <stdio.h>
-
-int main() {
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(A(c))", &c);
-
- tpl_load(tn, TPL_FILE, "test40.tpl");
- while (tpl_unpack(tn,1) > 0) {
- while (tpl_unpack(tn,2) > 0) printf("%c ",c);
- printf("\n");
- }
- tpl_free(tn);
-}
---------------------------------------------------------------------------------
-
-The file `test40.tpl` is from the <<nested_pack,nested packing example>>. When
-run, this program prints:
-
- a b
- 1 2 3
-
-[[tpl_free]]
-tpl_free
-~~~~~~~~
-The final step for any tpl is to release it using `tpl_free()`. Its only
-argument is the the `tpl_node*` to free.
-
- tpl_free( tn );
-
-This function does not return a value (it is `void`).
-
-[[tpl_alen]]
-tpl_Alen
-~~~~~~~~
-This function takes a `tpl_node*` and an index number and returns an `int`
-specifying the number of elements in the variable-length array.
-
- num_elements = tpl_Alen(tn, index);
-
-This is mainly useful for programs that unpack data and need to know ahead of
-time the number of elements that will need to be unpacked. (It returns the
-current number of elements; it will decrease as elements are unpacked).
-
-[[tpl_peek]]
-tpl_peek
-~~~~~~~~
-This function peeks into a file or a memory buffer containing a tpl image and
-and returns a copy of its format string. It can also peek at the lengths of
-any fixed-length arrays in the format string, or it can also peek into the data
-stored in the tpl.
-
-Format peek
-^^^^^^^^^^^
-The format string can be obtained
-like this:
-
- fmt = tpl_peek(TPL_FILE, "file.tpl");
- fmt = tpl_peek(TPL_MEM, addr, sz);
-
-On success, a copy of the format string is returned. The caller must eventually
-free it. On error, such as a non-existent file, or an invalid tpl image, it
-returns `NULL`.
-
-Array length peek
-^^^^^^^^^^^^^^^^^
-The lengths of all fixed-length arrays in the format string can be queried using
-the `TPL_FXLENS` mode. It provides the number of such fixed-length arrays and
-their lengths. If the former is non-zero, the caller must free the latter array
-when finished. The format string itself must also be freed.
-
- uint32_t num_fxlens, *fxlens, j;
- fmt = tpl_peek(TPL_FILE|TPL_FXLENS, filename, &num_fxlens, &fxlens);
- if (fmt) {
- printf("format %s, num_fxlens %u\n", fmt, num_fxlens);
- for(j=0; j<num_fxlens; j++) printf("fxlens[%u] %u\n", j, fxlens[j]);
- if (num_fxlens > 0) free(fxlens);
- free(fmt);
- }
-
-The `TPL_FXLENS` mode is mutually exclusive with `TPL_DATAPEEK`.
-
-
-Data peek
-^^^^^^^^^
-To peek into the data, additional arguments are used. This is a quick
-alternative to mapping, loading and unpacking the tpl, but peeking is limited
-to the data in index 0. In other words, no peeking into `A(...)` types.
-Suppose the tpl image in `file.tpl` has the format string `siA(i)`. Then the
-index 0 format characters are `si`. This is how to peek at their content:
-
- char *s;
- int i;
- fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "file.tpl", "si", &s, &i);
-
-Now `s`, `i`, and `fmt` have been populated with data. The caller must
-eventually free `fmt` and `s` because they are allocated strings.
-Of course, it works with `TPL_MEM` as well as `TPL_FILE`. Notice that
-`TPL_DATAPEEK` was OR'd with the mode. You can also specify 'any leading
-portion' of the index 0 format if you don't want to peek at the whole thing:
-
- fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "file.tpl", "s", &s);
-
-The `TPL_DATAPEEK` mode is mutually exclusive with `TPL_FXLENS`.
-
-Structure peek
-++++++++++++++
-Lastly you can peek into `S(...)` structures in index 0, but omit the
-surrounding `S(...)` in the format, and specify an argument to receive
-each structure member individually. You can specify any leading portion
-of the structure format. For example if `struct.tpl` has the format string
-`S(si)`, you can peek at its data in these ways:
-
- fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "struct.tpl", "s", &s);
- fmt = tpl_peek(TPL_FILE | TPL_DATAPEEK, "struct.tpl", "si", &s, &i);
-
-[[tpl_jot]]
-tpl_jot
-~~~~~~~
-This is a quick shortcut for generating a tpl. It can be used instead of the
-usual "map, pack, dump, and free" lifecycle. With `tpl_jot` all those steps are
-handled for you. It only works for simple formats-- namely, those without
-`A(...)` in their format string. Here is how it is used:
-
- char *hello = "hello", *world = "world";
- tpl_jot( TPL_FILE, "file.tpl", "ss", &hello, &world);
-
-It supports the three standard modes, `TPL_FILE`, `TPL_FD` and `TPL_MEM`.
-It returns -1 on failure (such as a bad format string or error writing the
-file) or 0 on success.
-
-[[hooks]]
-tpl_hook
-~~~~~~~~
-Most users will just leave these hooks at their default values. You can change
-these hook values if you want to modify tpl's internal memory management and
-error reporting behavior.
-
-A global structure called `tpl_hook` encapsulates the hooks. A program can
-reconfigure any hook by specifying an alternative function whose prototype
-matches the default. For example:
-
- #include "tpl.h"
- extern tpl_hook_t tpl_hook;
-
- int main() {
- tpl_hook.oops = printf;
- ...
- }
-
-.Configurable hooks
-[width="90%",options="header",cols="m,d,m",grid="none"]
-|================================================================================
-|Hook |Description | Default
-|tpl_hook.oops |log error messages | tpl_oops
-|tpl_hook.malloc |allocate memory | malloc
-|tpl_hook.realloc |reallocate memory | realloc
-|tpl_hook.free |free memory | free
-|tpl_hook.fatal |log fatal message and exit | tpl_fatal
-|tpl_hook.gather_max |tpl_gather max image size | 0 (unlimited)
-|================================================================================
-
-The oops hook
-^^^^^^^^^^^^^
-The `oops` has the same prototype as `printf`. The built-in default oops
-handling function writes the error message to `stderr`.
-
-The fatal hook
-^^^^^^^^^^^^^^
-The fatal hook is invoked when a tpl function cannot continue because of an out-
-of-memory condition or some other usage violation or inconsistency. It has this
-prototype:
-
- void fatal_fcn(char *fmt, ...);
-
-The `fatal` hook must not return. It must either exit, 'or' if the program needs
-to handle the failure and keep executing, `setjmp` and `longjmp` can be used.
-The default behavior is to `exit(-1)`.
-
-.Using longjmp in a fatal error handler
---------------------------------------------------------------------------------
-#include <setjmp.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include "tpl.h"
-
-jmp_buf env;
-extern tpl_hook_t tpl_hook;
-
-void catch_fatal(char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- longjmp(env,-1); /* return to setjmp point */
-}
-
-int main() {
- int err;
- tpl_node *tn;
- tpl_hook.fatal = catch_fatal; /* install fatal handler */
-
- err = setjmp(env); /* on error, control will return here */
- if (err) {
- printf("caught error!\n");
- return -1;
- }
-
- tn = tpl_map("@"); /* generate a fatal error */
- printf("program ending, without error\n");
- return 0;
-}
---------------------------------------------------------------------------------
-
-This example is included in `tests/test123.c`. When run, this program prints:
-
- unsupported option @
- failed to parse @
- caught error!
-
-
-tpl_gather
-~~~~~~~~~~
-
-.Most programs don't need this
-********************************************************************************
-Normally, `tpl_load()` is used to read a tpl image having an expected format
-string. A more generic operation is to acquire a tpl image whose format string is
-unknown. E.g., a generic message-receiving function might gather tpl images of
-varying format and route them to their final destination. This is the purpose of
-`tpl_gather`. It produces a memory buffer containing one tpl image. If there
-are multiple contiguous images in the input, it gathers exactly one image at a
-time.
-********************************************************************************
-
-The prototype for this function is:
-
- int tpl_gather( int mode, ...);
-
-The `mode` argument is one of three constants listed below, which must be
-followed by the mode-specific required arguments:
-
- TPL_GATHER_BLOCKING, int fd, void **img, size_t *sz
- TPL_GATHER_NONBLOCKING, int fd, tpl_gather_t **gs, tpl_gather_cb *cb, void *data
- TPL_GATHER_MEM, void *addr, size_t sz, tpl_gather_t **gs, tpl_gather_cb *cb, void *data
-
-[NOTE]
-.`tpl_hook.gather_max`
-All modes honor `tpl_hook.gather_max`, specifying the maximum byte size for a
-tpl image to be gathered (the default is unlimited, signified by 0). If a source
-attempts to send a tpl image larger than this maximum, whatever partial image
-has been read will be discarded, and no further reading will take place; in this
-case `tpl_gather` will return a negative (error) value to inform the caller that
-it should stop gathering from this source, and close the originating file
-descriptor if there is one. (The whole idea is to prevent untrusted sources from
-sending extremely large tpl images which would consume too much memory.)
-
-
-`TPL_GATHER_BLOCKING`
-^^^^^^^^^^^^^^^^^^^
-In this mode, `tpl_gather` blocks while reading file descriptor `fd` until one
-complete tpl image is read. No bytes past the end of the tpl image will be read.
-The address of the buffer containing the image is returned in `img` and its size
-is placed in `sz`. The caller is responsible for eventually freeing the buffer.
-The function returns 1 on success, 0 on end-of-file, or a negative number on
-error.
-
-`TPL_GATHER_NONBLOCKING`
-^^^^^^^^^^^^^^^^^^^^^^
-This mode is for non-blocking, event-driven programs that implement their
-own file descriptor readability testing using `select()` or the like. In this
-mode, tpl images are gathered in chunks as data becomes readable. Whenever a
-full tpl image has been gathered, it invokes a caller-specified callback to do
-something with the image. The arguments are the file descriptor `fd` which the
-caller has determined to be readable and which must be in non-blocking mode, a
-pointer to a file-descriptor-specific handle which the caller has declared
-(explained below); a callback to invoke when a tpl image has been read; and an
-opaque pointer that will passed to the callback.
-
-For each file descriptor on which `tpl_gather` will be used, the caller must
-declare a `tpl_gather_t*` and initialize it to `NULL`. Thereafter it will be
-used internally by `tpl_gather` whenever data is readable on the descriptor.
-
-The callback will only be invoked whenever `tpl_gather()` has accumulated one
-complete tpl image. It must have this prototype:
-
- int (tpl_gather_cb)(void *img, size_t sz, void *data);
-
-The callback can do anything with the tpl image but it must not free it. It can
-be copied if it needs to survive past the callback's return. The callback should
-return 0 under normal circumstances, or a negative number to abort; that is,
-returning a negative number causes `tpl_gather` itself to discard any remaining
-full or partial tpl images that have been read, and to return a negative number
-(-4 in particular) to signal its caller to close the file descriptor.
-
-The return value of `tpl_gather()` is negative if an error occured or 0 if a
-normal EOF was encountered-- both cases require that the caller close the file
-descriptor (and stop monitoring it for readability, obviously). If the return
-value is positive, the function succeeded in gathering whatever data was
-currently readable, which may have been a partial tpl image, or one or more
-complete images.
-
-Typical Usage
-+++++++++++++
-The program will have established a file descriptor in non-blocking mode and
-be monitoring it for readability, using `select()`. Whenever it's readable, the
-program calls `tpl_gather()`. In skeletal terms:
-
- tpl_gather_t *gt=NULL;
- int rc;
-
- void fd_is_readable(int fd) {
- rc = tpl_gather( TPL_GATHER_NONBLOCKING, fd, >, callback, NULL );
- if (rc <= 0) {
- close(fd); /* got eof or fatal */
- stop_watching_fd(fd);
- }
- }
-
- int callback( void *img, size_t sz, void *data ) {
- printf("got a tpl image\n"); /* do something with img. do not free it. */
- return 0; /* normal (no error) */
- }
-
-`TPL_GATHER_MEM`
-^^^^^^^^^^^^^^
-This mode is identical to `TPL_GATHER_NONBLOCKING` except that it gathers from a
-memory buffer instead of from a file descriptor. In other words, if some other
-layer of code-- say, a decryption function (that is decrypting fixed-size
-blocks) produces tpl fragments one-by-one, this mode can be used to reconstitute
-the tpl images and invoke the callback for each one. Its parameters are the same
-as for the `TPL_GATHER_NONBLOCKING` mode except that instead of a file
-descriptor, it takes a buffer address and size. The return values are also the
-same as for `TPL_GATHER_NONBLOCKING` noting of course there is no file
-descriptor to close on a non-positive return value.
-
-
-// vim: set tw=80 wm=2 syntax=asciidoc:
-
+++ /dev/null
-package Tpl;
-
-# Copyright (c) 2005-2007, Troy Hanson http://tpl.sourceforge.net
-# 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.
-# * Neither the name of the copyright holder nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use strict;
-use warnings;
-use Config; # to get the size of "double" on this platform
-
-use bytes; # always use byte (not unicode char) offsets w/tpl images
-
-our $VERSION = 1.1;
-
-# tpl object is a reference to a hash with these keys:
-#
-# A(0):
-# ... :
-# A(n):
-#
-# where each A(i) refers to an A node, except A(0) is the root node.
-#
-# For each hash key (A node or root node), the value of that key is
-# a list reference. The members are of the list are the node's children.
-# They're represented as "Ai" (for A nodes) where i is a positive integer;
-# for non-A nodes the representation is [type,addr] e.g. [ "i", \$some_integer]
-#
-# For example,
-# Tpl->map("iA(ib)", \$x, \$y, \$z);
-# returns a tpl object which is a reference to a hash with these keys/values:
-#
-# $self->{A0} = [ [ "i", \$x ], "A1" ];
-# $self->{A1} = [ [ "i", \$y ], [ "b", \$z ] ];
-#
-# Now if A1 (that is, the "A(ib)" node) is packed, the tpl object acquires
-# another hash key/value:
-# $self->{P1} = [ $binary_int, $binary_byte ];
-# and repeated calls to pack A1 append further $binary elements.
-#
-sub tpl_map {
- my $invocant = shift;
- my $class = ref($invocant) || $invocant;
- my $fmt = shift;
- my @astack = (0); # stack of current A node's lineage in tpl tree
- my $a_count=0; # running count of A's, thus an index of them
- my $self = {}; # populate below
- my ($lparen_level,$expect_lparen,$in_structure)=(0,0,0);
- for (my $i=0; $i < length $fmt; $i++) {
- my $c = substr($fmt,$i,1);
- if ($c eq 'A') {
- $a_count++;
- push @{ $self->{"A" . $astack[-1]} }, "A$a_count";
- push @astack, $a_count;
- $expect_lparen=1;
- } elsif ($c eq '(') {
- die "invalid format $fmt" unless $expect_lparen;
- $expect_lparen=0;
- $lparen_level++;
- } elsif ($c eq ')') {
- $lparen_level--;
- die "invalid format $fmt" if $lparen_level < 0;
- die "invalid format $fmt" if substr($fmt,$i-1,1) eq '(';
- if ($in_structure && ($in_structure-1 == $lparen_level)) {
- $in_structure=0;
- } else {
- pop @astack; # rparen ends A() type, not S() type
- }
- } elsif ($c eq 'S') {
- # in perl we just parse and ignore the S() construct
- $expect_lparen=1;
- $in_structure=1+$lparen_level; # so we can tell where S fmt ends
- } elsif ($c =~ /^(i|u|B|s|c|f|I|U)$/) {
- die "invalid format $fmt" if $expect_lparen;
- my $r = shift;
- die "no reference for $c (position $i of $fmt)" unless ref($r);
- if (($c eq "f") and ($Config{doublesize} != 8)) {
- die "double not 8 bytes on this platform";
- }
- if (($c =~ /(U|I)/) and not defined ($Config{use64bitint})) {
- die "Tpl.pm: this 32-bit Perl can't pack/unpack 64-bit I/U integers\n";
- }
- push @{ $self->{"A" . $astack[-1]} }, [ $c , $r ];
- } elsif ($c eq "#") {
- # test for previous iucfIU
- die "unallowed length modifer" unless $self->{"A" . $astack[-1]}->[-1]->[0] =~ /^(i|u|c|I|U|f)$/;
- my $n = shift;
- die "non-numeric # length modifer" unless $n =~ /^\d+$/;
- push @{ $self->{"A" . $astack[-1]}->[-1] }, $n;
- push @{ $self->{"#"}}, $n; # master array of octothorpe lengths
- } else {
- die "invalid character $c in format $fmt";
- }
- }
- die "invalid format $fmt" if $lparen_level != 0;
- $self->{fmt} = $fmt;
- bless $self;
- return $self;
-}
-
-sub tpl_format {
- my $self = shift;
- return $self->{fmt};
-}
-
-sub tpl_pack {
- my $self = shift;
- my $i = shift;
- die "invalid index" unless defined $self->{"A$i"};
- die "tpl for unpacking only" if defined $self->{"loaded"};
- $self->{"packed"}++;
- $self->{"P$i"} = undef if $i == 0; # node 0 doesn't accumulate
- my @bb;
- foreach my $node (@{ $self->{"A$i"} }) {
- if (ref($node)) {
- my ($type,$addr,$fxlen) = @{ $node };
- if (defined $fxlen) { # octothorpic array
- push @bb, CORE::pack("l$fxlen",@$addr) if $type eq "i"; # int
- push @bb, CORE::pack("L$fxlen",@$addr) if $type eq "u"; # uint
- push @bb, CORE::pack("C$fxlen",@$addr) if $type eq "c"; # byte
- push @bb, CORE::pack("d$fxlen",@$addr) if $type eq "f"; # double
- push @bb, CORE::pack("q$fxlen",@$addr) if $type eq "I"; # int64
- push @bb, CORE::pack("Q$fxlen",@$addr) if $type eq "U"; # uint64
- } else {
- # non-octothorpic singleton
- push @bb, CORE::pack("l",$$addr) if $type eq "i"; # int
- push @bb, CORE::pack("L",$$addr) if $type eq "u"; # uint
- push @bb, CORE::pack("C",$$addr) if $type eq "c"; # byte
- push @bb, CORE::pack("d",$$addr) if $type eq "f"; # double (8 byte)
- push @bb, CORE::pack("q",$$addr) if $type eq "I"; # int64
- push @bb, CORE::pack("Q",$$addr) if $type eq "U"; # uint64
- if ($type =~ /^(B|s)$/) { # string/binary
- push @bb, CORE::pack("L", length($$addr));
- push @bb, CORE::pack("a*", $$addr);
- }
- }
- } elsif ($node =~ /^A(\d+)$/) {
- # encode array length (int) and the array data into one scalar
- my $alen = pack("l", scalar @{ $self->{"P$1"} or [] });
- my $abod = (join "", @{ $self->{"P$1"} or [] });
- push @bb, $alen . $abod;
- $self->{"P$1"} = undef;
- } else {
- die "internal error; invalid node symbol $node";
- }
- }
- push @{ $self->{"P$i"} }, (join "", @bb);
-}
-
-sub big_endian {
- return (CORE::unpack("C", CORE::pack("L",1)) == 1) ? 0 : 1;
-}
-
-sub tpl_dump {
- my $self = shift;
- my $filename = shift;
-
- $self->tpl_pack(0) if not defined $self->{"P0"};
- my $format = $self->tpl_format;
- my $octothorpe_lens = CORE::pack("L*", @{ $self->{"#"} or [] });
- my $data = (join "", @{ $self->{"P0"} });
- my $ov_len = length($format) + 1 + length($octothorpe_lens) + length($data) + 8;
- my $flags = big_endian() ? 1 : 0;
- my $preamble = CORE::pack("CLZ*", $flags, $ov_len, $format);
- my $tpl = "tpl" . $preamble . $octothorpe_lens . $data;
- return $tpl unless $filename;
-
- # here for file output
- open TPL, ">$filename" or die "can't open $filename: $!";
- print TPL $tpl;
- close TPL;
-}
-
-sub tpl_peek {
- my $invocant = shift;
- my $class = ref($invocant) || $invocant;
- my $tplhandle = shift;
- my $tpl;
-
- if (ref($tplhandle)) {
- $tpl = $$tplhandle;
- } else {
- open TPL, "<$tplhandle" or die "can't open $tplhandle: $!";
- undef $/; # slurp
- $tpl = <TPL>;
- close TPL;
- }
- die "invalid tpl file" unless ($tpl =~ /^tpl/);
- return (unpack("Z*", substr($tpl,8)));
-}
-
-sub tpl_load {
- my $self = shift;
- my $tplhandle = shift;
-
- die "tpl for packing only" if $self->{"packed"};
- die "tpl reloading not supported" if $self->{"loaded"};
-
- # read tpl image from file or was it passed directly via ref?
- my $tpl;
- if (ref($tplhandle)) {
- $tpl = $$tplhandle;
- } else {
- open TPL, "<$tplhandle" or die "can't open $tplhandle: $!";
- undef $/; # slurp
- $tpl = <TPL>;
- close TPL;
- }
-
- $self->{"TI"} = $tpl;
- $self->{"TL"} = length $tpl;
- # verify preamble
- die "invalid image -1" unless length($tpl) >= 9;
- die "invalid image -2" unless $tpl =~ /^tpl/;
- my $flags = CORE::unpack("C", substr($tpl,3,1));
- $self->{"xendian"} = 1 if (big_endian() != ($flags & 1));
- $self->{"UF"} = ($flags & 1) ? "N" : "V";
- my $ov_len = CORE::unpack($self->{"UF"}, substr($tpl,4,4));
- die "invalid image -3" unless $ov_len == length($tpl);
- my $format = CORE::unpack("Z*", substr($tpl,8));
- die "format mismatch" unless $format eq $self->tpl_format();
- my @octothorpe_lens = @{ $self->{"#"} or [] };
- my $ol = 8 + length($format) + 1; # start of octothorpe lengths
- for (my $i=0; $i < (scalar @octothorpe_lens); $i++) {
- my $len = CORE::unpack($self->{"UF"}, substr($tpl,$ol,4));
- my $olen = $octothorpe_lens[$i];
- die "fixed-length array size mismatch" unless $olen == $len;
- $ol += 4;
- }
- my $dv = $ol; # start of packed data
- my $len = $self->serlen("A0",$dv);
- die "invalid image -4" if $len == -1;
- die "invalid image -5" if (length($tpl) != $len + $dv);
- $self->{"C0"} = $dv;
- $self->{"loaded"} = 1;
- $self->unpackA0; # prepare root child nodes for use
-}
-
-# byte reverse a word (any length)
-sub reversi {
- my $word = shift;
- my @w = split //, $word;
- my $r = join "", (reverse @w);
- return $r;
-}
-
-#
-# while unpacking, the object has these keys in its hash:
-# C0
-# C1
-# ...
-# C<n>
-# These are indices (into the tpl image $self->{"TI"}) from which node n
-# is being unpacked. I.e. as array elements of node n are unpacked, C<n>
-# advances through the tpl image.
-#
-# Similarly, elements
-# N1
-# N2
-# ...
-# N<n>
-# refer to the remaining array count for node n.
-#
-sub tpl_unpack {
- my $self = shift;
- my $n = shift;
- my $ax = "A$n";
- my $cx = "C$n";
- my $nx = "N$n";
- my $rc;
-
- die "tpl for packing only" if $self->{"packed"};
- die "tpl not loaded" unless $self->{"loaded"};
-
- # decrement count for non root array nodes
- if ($n > 0) {
- return 0 if $self->{$nx} <= 0;
- $rc = $self->{$nx}--;
- }
-
- for my $c (@{ $self->{$ax} }) {
- if (ref($c)) {
- my ($type,$addr,$fxlen) = @$c;
- if (defined $fxlen) { # octothorpic unpack
- @{ $addr } = (); # empty existing list before pushing elements
- for(my $i=0; $i < $fxlen; $i++) {
- if ($type eq "u") { # uint
- push @{ $addr }, CORE::unpack($self->{"UF"},
- substr($self->{"TI"},$self->{$cx},4));
- $self->{$cx} += 4;
- } elsif ($type eq "i") { #int (see note below re:signed int)
- my $intbytes = substr($self->{"TI"},$self->{$cx},4);
- $intbytes = reversi($intbytes) if $self->{"xendian"};
- push @{ $addr }, CORE::unpack("l", $intbytes);
- $self->{$cx} += 4;
- } elsif ($type eq "c") { # byte
- push @{ $addr }, CORE::unpack("C",
- substr($self->{"TI"},$self->{$cx},1));
- $self->{$cx} += 1;
- } elsif ($type eq "f") { # double
- my $double_bytes = substr($self->{"TI"},$self->{$cx},8);
- $double_bytes = reversi($double_bytes) if $self->{"xendian"};
- push @{ $addr }, CORE::unpack("d", $double_bytes );
- $self->{$cx} += 8;
- } elsif ($type eq "I") { #int64
- my $intbytes = substr($self->{"TI"},$self->{$cx},8);
- $intbytes = reversi($intbytes) if $self->{"xendian"};
- push @{ $addr }, CORE::unpack("q", $intbytes);
- $self->{$cx} += 8;
- } elsif ($type eq "U") { #uint64
- my $intbytes = substr($self->{"TI"},$self->{$cx},8);
- $intbytes = reversi($intbytes) if $self->{"xendian"};
- push @{ $addr }, CORE::unpack("Q", $intbytes);
- $self->{$cx} += 8;
- }
- }
- } else {
- # non-octothorpe (singleton)
- if ($type eq "u") { # uint
- ${$addr} = CORE::unpack($self->{"UF"},
- substr($self->{"TI"},$self->{$cx},4));
- $self->{$cx} += 4;
- } elsif ($type eq "i") { # int
- # while perl's N or V conversions unpack an unsigned
- # long from either big or little endian format
- # respectively, when it comes to *signed* int, perl
- # only has 'l' (which assumes native endianness).
- # So we have to manually reverse the bytes in a
- # cross-endian 'int' unpacking scenario.
- my $intbytes = substr($self->{"TI"},$self->{$cx},4);
- $intbytes = reversi($intbytes) if $self->{"xendian"};
- ${$addr} = CORE::unpack("l", $intbytes);
- $self->{$cx} += 4;
- } elsif ($type eq 'c') { # byte
- ${$c->[1]} = CORE::unpack("C",
- substr($self->{"TI"},$self->{$cx},1));
- $self->{$cx} += 1;
- } elsif ($type eq 'f') { # double
- ${$addr} = CORE::unpack("d",
- substr($self->{"TI"},$self->{$cx},8));
- $self->{$cx} += 8;
- } elsif ($type =~ /^(B|s)$/) { # string/binary
- my $slen = CORE::unpack($self->{"UF"},
- substr($self->{"TI"},$self->{$cx},4));
- $self->{$cx} += 4;
- ${$addr} = CORE::unpack("a$slen",
- substr($self->{"TI"},$self->{$cx},$slen));
- $self->{$cx} += $slen;
- } elsif ($type eq "I") { # int64
- my $intbytes = substr($self->{"TI"},$self->{$cx},8);
- $intbytes = reversi($intbytes) if $self->{"xendian"};
- ${$addr} = CORE::unpack("q", $intbytes);
- $self->{$cx} += 8;
- } elsif ($type eq "U") { # uint64
- my $intbytes = substr($self->{"TI"},$self->{$cx},8);
- $intbytes = reversi($intbytes) if $self->{"xendian"};
- ${$addr} = CORE::unpack("Q", $intbytes);
- $self->{$cx} += 8;
- } else { die "internal error"; }
- }
- } elsif ($c =~ /^A(\d+)$/) {
- my $alen = $self->serlen($c,$self->{$cx});
- $self->{"N$1"} = CORE::unpack($self->{"UF"},
- substr($self->{"TI"},$self->{$cx},4)); # get array count
- $self->{"C$1"} = $self->{$cx} + 4; # set array node's data start
- $self->{$cx} += $alen; # step over array node's data
- } else { die "internal error"; }
- }
-
- return $rc;
-}
-
-# specialized function to prepare root's child A nodes for initial use
-sub unpackA0 {
- my $self = shift;
- my $ax = "A0";
- my $cx = "C0";
- my $c0 = $self->{$cx};
-
- for my $c (@{ $self->{$ax} }) {
- next if ref($c); # skip non-A nodes
- if ($c =~ /^A(\d+)$/) {
- my $alen = $self->serlen($c,$c0);
- $self->{"N$1"} = CORE::unpack($self->{"UF"},
- substr($self->{"TI"},$c0,4)); # get array count
- $self->{"C$1"} = $c0 + 4; # set array node's data start
- $c0 += $alen; # step over array node's data
- } else { die "internal error"; }
- }
-}
-
-# ascertain serialized length of given node by walking
-sub serlen {
- my $self = shift;
- my $ax = shift;
- my $dv = shift;
-
- my $len = 0;
-
- my $num;
- if ($ax eq "A0") {
- $num = 1;
- } else {
- return -1 unless $self->{"TL"} >= $dv + 4;
- $num = CORE::unpack($self->{"UF"},substr($self->{"TI"},$dv,4));
- $dv += 4;
- $len += 4;
- }
-
- while ($num-- > 0) {
- for my $c (@{ $self->{$ax} }) {
- if (ref($c)) {
- my $n = 1;
- $n = $c->[2] if (@$c > 2); # octothorpic array length
- if ($c->[0] =~ /^(i|u)$/) { # int/uint
- return -1 unless $self->{"TL"} >= $dv + 4*$n;
- $len += 4*$n;
- $dv += 4*$n;
- } elsif ($c->[0] eq "c") { # byte
- return -1 unless $self->{"TL"} >= $dv + 1*$n;
- $len += 1*$n;
- $dv += 1*$n;
- } elsif ($c->[0] eq "f") { # double
- return -1 unless $self->{"TL"} >= $dv + 8*$n;
- $len += 8*$n;
- $dv += 8*$n;
- } elsif ($c->[0] =~ /(I|U)/) { # int64/uint64
- return -1 unless $self->{"TL"} >= $dv + 8*$n;
- $len += 8*$n;
- $dv += 8*$n;
- } elsif ($c->[0] =~ /^(B|s)$/) { # string/binary
- return -1 unless $self->{"TL"} >= $dv + 4;
- my $slen = CORE::unpack($self->{"UF"},
- substr($self->{"TI"},$dv,4));
- $len += 4;
- $dv += 4;
- return -1 unless $self->{"TL"} >= $dv + $slen;
- $len += $slen;
- $dv += $slen;
- } else { die "internal error" }
- } elsif ($c =~ /^A/) {
- my $alen = $self->serlen($c,$dv);
- return -1 if $alen == -1;
- $dv += $alen;
- $len += $alen;
- } else { die "internal error"; }
- }
- }
- return $len;
-}
-
-1
+++ /dev/null
-all: run_tests
-
-run_tests:
- perl ./do_tests
-
-.PHONY: clean
-
-clean:
- rm -f test*.out
+++ /dev/null
-Run 'make' to run the tests.
-
-Run 'make clean' to clean up the temporary files.
-
-Description of tests
-=============================================================================
-test1 pack A(i) to file, unpack
-test2 pack A(i) to memory, unpack
-test3 pack A(i) to memory, pipe through tplxml (to make XML)
-test4 pack A(i) to file, convert to XML, convert back to tpl (using tplxml)
-test5 pack A(b) to file, unpack
-test6 pack A(b) to memory, pipe through tplxml (to make XML)
-test7 pack A(b) to file, convert to XML, convert back to tpl (using tplxml)
-test8 pack A(s) (has embedded &, < and > in strings to test quoting in XML)
-test9 pack A(u) to file, unpack
-test10 pack A(u) to memory, convert via tplxml
-test11 pack format B using a four-byte binary buffer, unpack and print
-test12 pack A(d) to file, unpack
-test13 pack A(d) to memory, convert via tplxml
-test14 unpack big-endian i (-2) (on little-endian machine, tests reversi)
-test15 unpack little-endian i (-3) (on big-endian machine, tests reversi)
-test16 pack to mem format B using a four-byte binary buffer, unpack and print
-test17 pack and unpack S(ic)
-test18 pack and unpack i#
-test19 pack and unpack i#i#
-test20 pack A(S(ci#)) to file, convert to XML, then back to tpl (cf test81.c)
-test21 Tpl->tpl_peek in-memory image
-test22 Tpl->tpl_peek file image
-test23 test I/U (only succeeds on 64-bit perl)
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use IO::Socket::INET;
-use lib "..";
-use Tpl;
-
-our $port = 2000;
-
-# construct tpl
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-$tpl->tpl_pack(1) while ($i=shift @ARGV);
-my $request = $tpl->tpl_dump();
-
-# send to server, get response
-my $socket = IO::Socket::INET->new("localhost:$port") or die "can't connect";
-print $socket $request;
-shutdown($socket,1); # done writing (half-close)
-undef $/;
-my $response = <$socket>; # get reply (slurp)
-
-# decode response (or print error)
-my $total;
-my $tpl2 = Tpl->tpl_map("i", \$total);
-eval { $tpl2->tpl_load(\$response); };
-die "invalid response\n" if $@;
-$tpl2->tpl_unpack(0);
-print "total is $total\n";
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-my @tests;
-for (glob "test*[0-9]") {
- push @tests, $_ if -e "$_.ans";
-}
-
-my $num_failed=0;
-
-for my $test (@tests) {
- `./$test > $test.out`;
- `diff $test.out $test.ans`;
- print "$test failed\n" if $?;
- $num_failed++ if $?;
-}
-
-print scalar @tests . " tests conducted, $num_failed failed.\n";
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use IO::Socket::INET;
-use lib "..";
-use Tpl;
-
-$SIG{CHLD} = "IGNORE"; # don't create zombies
-
-our $port = 2000;
-
-sub handle_client {
- my $client = shift;
-
- undef $/;
- my $request = <$client>; # get request (slurp)
-
- # read input array, and calculate total
- my ($i,$total);
- my $tpl = Tpl->tpl_map("A(i)", \$i);
- eval { $tpl->tpl_load(\$request); };
- die "received invalid tpl" if $@;
- $total += $i while $tpl->tpl_unpack(1) > 0;
-
- # formulate response and send
- my $tpl2 = Tpl->tpl_map("i", \$total);
- $tpl2->tpl_pack(0);
- my $response = $tpl2->tpl_dump();
- print $client $response;
- close $client;
-}
-
-my $server = IO::Socket::INET->new(LocalPort => $port,
- Type => SOCK_STREAM,
- Reuse => 1,
- Listen => 10 )
- or die "Can't listen on port $port: $!\n";
-
-while (1) {
- my $client = $server->accept();
- next unless $client;
- # new connection
- my $pid = fork;
- die "can't fork: $!\n" unless defined $pid;
- if ($pid > 0) {
- #p arent
- close $client;
- } elsif ($pid == 0) {
- # child
- handle_client($client);
- exit(0);
- }
-}
-close ($server);
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-$tpl->tpl_dump($tmp1);
-
-my $j;
-my $tpl2 = Tpl->tpl_map("A(i)",\$j);
-$tpl2->tpl_load($tmp1);
-while($tpl2->tpl_unpack(1) > 0) { print "$j\n" }
-
+++ /dev/null
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(u)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-my $img = $tpl->tpl_dump();
-
-open TPLXML, "|../tplxml" or die "can't open tplxml: $!";
-print TPLXML $img;
-close TPLXML;
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
- <!DOCTYPE tplxml [
- <!ELEMENT tplxml (A|i|u|I|U|B|s|c|f|fx)*>
- <!ATTLIST tplxml
- format CDATA #REQUIRED
- fxlens CDATA #REQUIRED
- >
- <!ELEMENT i (#PCDATA)>
- <!ELEMENT u (#PCDATA)>
- <!ELEMENT I (#PCDATA)>
- <!ELEMENT U (#PCDATA)>
- <!ELEMENT B (#PCDATA)>
- <!ELEMENT s (#PCDATA)>
- <!ELEMENT c (#PCDATA)>
- <!ELEMENT f (#PCDATA)>
- <!ELEMENT A (el)*>
- <!ELEMENT el (A|i|u|I|U|B|s|c|f|fx)+>
- <!ELEMENT fx (i|u|I|U|c|f)*>
- ]>
-<tplxml format="A(u)" fxlens="">
- <A>
- <el>
- <u>0</u>
- </el>
- <el>
- <u>1</u>
- </el>
- <el>
- <u>2</u>
- </el>
- <el>
- <u>3</u>
- </el>
- <el>
- <u>4</u>
- </el>
- <el>
- <u>5</u>
- </el>
- <el>
- <u>6</u>
- </el>
- <el>
- <u>7</u>
- </el>
- <el>
- <u>8</u>
- </el>
- <el>
- <u>9</u>
- </el>
- </A>
-</tplxml>
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("B",\$i);
-$i = pack("CCCC", 0xA, 0xB, 0xC, 0xD);
-$tpl->tpl_pack(0);
-$tpl->tpl_dump($tmp1);
-
-
-$tpl = Tpl->tpl_map("B",\$i);
-$tpl->tpl_load($tmp1);
-$tpl->tpl_unpack(0);
-print "$i\n";
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(f)",\$i);
-for($i=0; $i<10.0; $i+=2/3.0) { $tpl->tpl_pack(1); }
-$tpl->tpl_dump($tmp1);
-
-my $j;
-my $tpl2 = Tpl->tpl_map("A(f)",\$j);
-$tpl2->tpl_load($tmp1);
-while($tpl2->tpl_unpack(1) > 0) { printf("%.6f\n", $j); }
-
+++ /dev/null
-0.000000
-0.666667
-1.333333
-2.000000
-2.666667
-3.333333
-4.000000
-4.666667
-5.333333
-6.000000
-6.666667
-7.333333
-8.000000
-8.666667
-9.333333
-10.000000
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(f)",\$i);
-for($i=0; $i<10.0; $i+=2/3.0) { $tpl->tpl_pack(1); }
-my $img = $tpl->tpl_dump();
-
-open TPLXML, "|../tplxml" or die "can't open tplxml: $!";
-print TPLXML $img;
-close TPLXML;
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
- <!DOCTYPE tplxml [
- <!ELEMENT tplxml (A|i|u|I|U|B|s|c|f|fx)*>
- <!ATTLIST tplxml
- format CDATA #REQUIRED
- fxlens CDATA #REQUIRED
- >
- <!ELEMENT i (#PCDATA)>
- <!ELEMENT u (#PCDATA)>
- <!ELEMENT I (#PCDATA)>
- <!ELEMENT U (#PCDATA)>
- <!ELEMENT B (#PCDATA)>
- <!ELEMENT s (#PCDATA)>
- <!ELEMENT c (#PCDATA)>
- <!ELEMENT f (#PCDATA)>
- <!ELEMENT A (el)*>
- <!ELEMENT el (A|i|u|I|U|B|s|c|f|fx)+>
- <!ELEMENT fx (i|u|I|U|c|f)*>
- ]>
-<tplxml format="A(f)" fxlens="">
- <A>
- <el>
- <f>0</f>
- </el>
- <el>
- <f>0.666666666666667</f>
- </el>
- <el>
- <f>1.33333333333333</f>
- </el>
- <el>
- <f>2</f>
- </el>
- <el>
- <f>2.66666666666667</f>
- </el>
- <el>
- <f>3.33333333333333</f>
- </el>
- <el>
- <f>4</f>
- </el>
- <el>
- <f>4.66666666666667</f>
- </el>
- <el>
- <f>5.33333333333333</f>
- </el>
- <el>
- <f>6</f>
- </el>
- <el>
- <f>6.66666666666667</f>
- </el>
- <el>
- <f>7.33333333333333</f>
- </el>
- <el>
- <f>8</f>
- </el>
- <el>
- <f>8.66666666666667</f>
- </el>
- <el>
- <f>9.33333333333333</f>
- </el>
- <el>
- <f>10</f>
- </el>
- </A>
-</tplxml>
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $tmp1 = "test14.tpl";
-
-my $j;
-my $tpl2 = Tpl->tpl_map("i",\$j);
-$tpl2->tpl_load($tmp1);
-$tpl2->tpl_unpack(0);
-print "$j\n";
-
-
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $tmp1 = "test15.tpl";
-
-my $j;
-my $tpl2 = Tpl->tpl_map("i",\$j);
-$tpl2->tpl_load($tmp1);
-$tpl2->tpl_unpack(0);
-print "$j\n";
-
-
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $i;
-my $tpl = Tpl->tpl_map("B",\$i);
-$i = pack("CCCC", 0xA, 0xB, 0xC, 0xD);
-$tpl->tpl_pack(0);
-my $img = $tpl->tpl_dump();
-
-
-$tpl = Tpl->tpl_map("B",\$i);
-$tpl->tpl_load(\$img);
-$tpl->tpl_unpack(0);
-print "$i\n";
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my ($i,$j)=(1,ord('a'));
-my $tpl = Tpl->tpl_map("S(ic)",\$i, \$j);
-$tpl->tpl_pack(0);
-$tpl->tpl_dump($tmp1);
-
-($i,$j)=(-9,"x");
-my $tpl2 = Tpl->tpl_map("S(ic)",\$i,\$j);
-$tpl2->tpl_load($tmp1);
-$tpl2->tpl_unpack(0);
-$j = chr($j);
-print "$i,$j\n";
-
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my @i=(1,2,3,4);
-my $tpl = Tpl->tpl_map("i#",\@i, 3);
-$tpl->tpl_pack(0);
-$tpl->tpl_dump($tmp1);
-
-my @j;
-my $tpl2 = Tpl->tpl_map("i#",\@j,3);
-$tpl2->tpl_load($tmp1);
-$tpl2->tpl_unpack(0);
-print "$_\n" for @j;
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my @i=(1,2,3,4);
-my @j=(-1,-2,-3, -4);
-my $tpl = Tpl->tpl_map("i#i#",\@i, 3, \@j, 4);
-$tpl->tpl_pack(0);
-$tpl->tpl_dump($tmp1);
-
-my (@x,@y);
-my $tpl2 = Tpl->tpl_map("i#i#",\@x, 3, \@y, 4);
-$tpl2->tpl_load($tmp1);
-$tpl2->tpl_unpack(0);
-print "$_\n" for @x;
-print "$_\n" for @y;
+++ /dev/null
-1
-2
-3
--1
--2
--3
--4
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-my $img = $tpl->tpl_dump();
-
-my $j;
-my $tpl2 = Tpl->tpl_map("A(i)",\$j);
-$tpl2->tpl_load(\$img);
-while($tpl2->tpl_unpack(1) > 0) { print "$j\n" }
-
+++ /dev/null
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-my $tmp2 = "$pwd/$0_2.out";
-my $tmp3 = "$pwd/$0_3.out";
-
-my ($c,@i);
-my $tpl = Tpl->tpl_map("A(S(ci#))",\$c,\@i,10);
-
-# make element 1
-$c = 97;
-@i = (0,1,2,3,4,5,6,7,8,9);
-$tpl->tpl_pack(1);
-
-# make element 2
-$c = 98;
-@i = (1,2,3,4,5,6,7,8,9,10);
-$tpl->tpl_pack(1);
-
-$tpl->tpl_dump($tmp1);
-
-
-`../tplxml $tmp1 > $tmp2`; # convert tpl to xml
-`../tplxml $tmp2 > $tmp3`; # convert xml back to tpl
-`diff $tmp1 $tmp3`;
-print "tpl files ", ($? ? "differ" : "identical"), "\n";
-
+++ /dev/null
-tpl files identical
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-my $img = $tpl->tpl_dump();
-
-my $fmt = Tpl->tpl_peek(\$img);
-print("$fmt\n");
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my @i=(1,2,3,4);
-my @j=(-1,-2,-3, -4);
-my $tpl = Tpl->tpl_map("i#i#",\@i, 3, \@j, 4);
-$tpl->tpl_pack(0);
-$tpl->tpl_dump($tmp1);
-
-my $fmt = Tpl->tpl_peek($tmp1);
-print "$fmt\n";
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-# this test only works on 64-bit Perl
-
-my ($i,$j) = (-4294967296,4294967296); # 2^32 (can't fit in a 32-bit value)
-my $tpl = Tpl->tpl_map("IU",\$i,\$j);
-$tpl->tpl_pack(0);
-my $img = $tpl->tpl_dump();
-
-my ($x,$y);
-my $tpl2 = Tpl->tpl_map("IU",\$x,\$y);
-$tpl2->tpl_load(\$img);
-$tpl2->tpl_unpack(0);
-print "$x $y\n";
-
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-my $img = $tpl->tpl_dump();
-
-open TPLXML, "|../tplxml" or die "can't open tplxml: $!";
-print TPLXML $img;
-close TPLXML;
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
- <!DOCTYPE tplxml [
- <!ELEMENT tplxml (A|i|u|I|U|B|s|c|f|fx)*>
- <!ATTLIST tplxml
- format CDATA #REQUIRED
- fxlens CDATA #REQUIRED
- >
- <!ELEMENT i (#PCDATA)>
- <!ELEMENT u (#PCDATA)>
- <!ELEMENT I (#PCDATA)>
- <!ELEMENT U (#PCDATA)>
- <!ELEMENT B (#PCDATA)>
- <!ELEMENT s (#PCDATA)>
- <!ELEMENT c (#PCDATA)>
- <!ELEMENT f (#PCDATA)>
- <!ELEMENT A (el)*>
- <!ELEMENT el (A|i|u|I|U|B|s|c|f|fx)+>
- <!ELEMENT fx (i|u|I|U|c|f)*>
- ]>
-<tplxml format="A(i)" fxlens="">
- <A>
- <el>
- <i>0</i>
- </el>
- <el>
- <i>1</i>
- </el>
- <el>
- <i>2</i>
- </el>
- <el>
- <i>3</i>
- </el>
- <el>
- <i>4</i>
- </el>
- <el>
- <i>5</i>
- </el>
- <el>
- <i>6</i>
- </el>
- <el>
- <i>7</i>
- </el>
- <el>
- <i>8</i>
- </el>
- <el>
- <i>9</i>
- </el>
- </A>
-</tplxml>
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-my $tmp2 = "$pwd/$0_2.out";
-my $tmp3 = "$pwd/$0_3.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(i)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-$tpl->tpl_dump($tmp1);
-
-
-`../tplxml $tmp1 > $tmp2`; # convert tpl to xml
-`../tplxml $tmp2 > $tmp3`; # convert xml back to tpl
-`diff $tmp1 $tmp3`;
-print "tpl files ", ($? ? "differ" : "identical"), "\n";
-
+++ /dev/null
-tpl files identical
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(c)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-$tpl->tpl_dump($tmp1);
-
-my $j;
-my $tpl2 = Tpl->tpl_map("A(c)",\$j);
-$tpl2->tpl_load($tmp1);
-while($tpl2->tpl_unpack(1) > 0) { printf("%d\n", $j); }
-
+++ /dev/null
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $i;
-my $tpl = Tpl->tpl_map("A(c)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-my $img = $tpl->tpl_dump();
-
-open TPLXML, "|../tplxml" or die "can't open tplxml: $!";
-print TPLXML $img;
-close TPLXML;
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
- <!DOCTYPE tplxml [
- <!ELEMENT tplxml (A|i|u|I|U|B|s|c|f|fx)*>
- <!ATTLIST tplxml
- format CDATA #REQUIRED
- fxlens CDATA #REQUIRED
- >
- <!ELEMENT i (#PCDATA)>
- <!ELEMENT u (#PCDATA)>
- <!ELEMENT I (#PCDATA)>
- <!ELEMENT U (#PCDATA)>
- <!ELEMENT B (#PCDATA)>
- <!ELEMENT s (#PCDATA)>
- <!ELEMENT c (#PCDATA)>
- <!ELEMENT f (#PCDATA)>
- <!ELEMENT A (el)*>
- <!ELEMENT el (A|i|u|I|U|B|s|c|f|fx)+>
- <!ELEMENT fx (i|u|I|U|c|f)*>
- ]>
-<tplxml format="A(c)" fxlens="">
- <A>
- <el>
- <c>0</c>
- </el>
- <el>
- <c>1</c>
- </el>
- <el>
- <c>2</c>
- </el>
- <el>
- <c>3</c>
- </el>
- <el>
- <c>4</c>
- </el>
- <el>
- <c>5</c>
- </el>
- <el>
- <c>6</c>
- </el>
- <el>
- <c>7</c>
- </el>
- <el>
- <c>8</c>
- </el>
- <el>
- <c>9</c>
- </el>
- </A>
-</tplxml>
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-my $tmp2 = "$pwd/$0_2.out";
-my $tmp3 = "$pwd/$0_3.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(c)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-$tpl->tpl_dump($tmp1);
-
-
-`../tplxml $tmp1 > $tmp2`; # convert tpl to xml
-`../tplxml $tmp2 > $tmp3`; # convert xml back to tpl
-`diff $tmp1 $tmp3`;
-print "tpl files ", ($? ? "differ" : "identical"), "\n";
-
+++ /dev/null
-tpl files identical
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-my $tmp2 = "$pwd/$0_2.out";
-my $tmp3 = "$pwd/$0_3.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(s)",\$i);
-for (qw(normal has&ersand <anglebrackets>)) {
- $i = $_;
- $tpl->tpl_pack(1);
-}
-$tpl->tpl_dump($tmp1);
-
-
-`../tplxml $tmp1 > $tmp2`; # convert tpl to xml
-`../tplxml $tmp2 > $tmp3`; # convert xml back to tpl
-`diff $tmp1 $tmp3`;
-print "tpl files ", ($? ? "differ" : "identical"), "\n";
-
+++ /dev/null
-tpl files identical
+++ /dev/null
-#!/usr/bin/perl
-#
-use strict;
-use warnings;
-
-use lib "..";
-use Tpl;
-
-my $pwd = `pwd`;
-chomp $pwd;
-
-my $tmp1 = "$pwd/$0_1.out";
-
-my $i;
-my $tpl = Tpl->tpl_map("A(u)",\$i);
-for($i=0; $i<10; $i++) { $tpl->tpl_pack(1); }
-$tpl->tpl_dump($tmp1);
-
-my $j;
-my $tpl2 = Tpl->tpl_map("A(u)",\$j);
-$tpl2->tpl_load($tmp1);
-while($tpl2->tpl_unpack(1) > 0) { print "$j\n" }
-
+++ /dev/null
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
+++ /dev/null
-#!/usr/bin/perl
-
-# tplfmt
-# by Troy Hanson Feb 2006
-# print the format string of a tpl image file
-
-use strict;
-use warnings;
-
-sub peek_fmt {
- my $buf = shift;
- die "invalid tpl file" unless ($$buf =~ /^tpl/);
- return (unpack("Z*", substr($$buf,8)));
-}
-
-die "usage: $0 <file> [<file> ...]" unless (@ARGV > 0);
-
-undef $/; # slurp
-for (@ARGV) {
- open TPL, "<$_" or die "can't open $_: $!";
- my $tpl = <TPL>;
- print "$_: ", peek_fmt(\$tpl), "\n";
- close TPL;
-}
+++ /dev/null
-#!/usr/bin/perl
-
-# tplxml
-# by Troy Hanson 27 Feb 2006
-# convert between tpl and XML
-
-# Copyright (c) 2005-2006, Troy Hanson http://tpl.sourceforge.net
-# 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.
-# * Neither the name of the copyright holder nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use strict;
-use warnings;
-use XML::Parser;
-use FindBin;
-use lib "$FindBin::Bin"; #locate Tpl.pm in same directory as tplxml
-use Tpl;
-use bytes;
-
-sub quote_chars {
- my $str = shift;
- $$str =~ s/&/&/g; #order matters
- $$str =~ s/</</g;
- $$str =~ s/>/>/g;
-}
-sub unquote_chars {
- my $str = shift;
- $$str =~ s/</</g;
- $$str =~ s/>/>/g;
- $$str =~ s/&/&/g;
-}
-sub hex_chars {
- my $str = shift;
- my $hex;
- for(my $i=0; $i < length $$str; $i++) {
- my $byte = unpack("C",substr($$str,$i,1));
- $hex .= sprintf("%02x", $byte);
- }
- $$str = $hex;
-}
-sub unhex_chars {
- my $str = shift;
- my $bytes;
- for(my $i=0; $i < length $$str; $i+=2) {
- my $hexbyte = substr($$str,$i,2);
- $bytes .= pack("C", hex($hexbyte));
- }
- $$str= $bytes;
-}
-
-sub tpl2xml {
- my $src = shift;
- my (@out,@args);
-
- # build list of references to hold output of unpacking
- my ($fmt,@fxlens) = peek_fmt($src);
- for(my ($i,$j,$k)=(0,0,0);$i<length($fmt);$i++) {
- push @args, [] if substr($fmt,$i,2) =~ /^[iucfIU]\#$/; # octothorpic
- push @args, \$out[$j++] if substr($fmt,$i,2) =~ /^[iuBscfIU][^\#]*$/;
- push @args, $fxlens[$k++] if substr($fmt,$i,1) eq "#";
- }
-
- my $tpl = Tpl->tpl_map($fmt,@args);
- $tpl->tpl_load($src);
- $tpl->tpl_unpack(0);
-
- # construct xml preamble
- my $pre = qq{<?xml version="1.0" encoding="utf-8" ?>
- <!DOCTYPE tplxml [
- <!ELEMENT tplxml (A|i|u|I|U|B|s|c|f|fx)*>
- <!ATTLIST tplxml
- format CDATA #REQUIRED
- fxlens CDATA #REQUIRED
- >
- <!ELEMENT i (#PCDATA)>
- <!ELEMENT u (#PCDATA)>
- <!ELEMENT I (#PCDATA)>
- <!ELEMENT U (#PCDATA)>
- <!ELEMENT B (#PCDATA)>
- <!ELEMENT s (#PCDATA)>
- <!ELEMENT c (#PCDATA)>
- <!ELEMENT f (#PCDATA)>
- <!ELEMENT A (el)*>
- <!ELEMENT el (A|i|u|I|U|B|s|c|f|fx)+>
- <!ELEMENT fx (i|u|I|U|c|f)*>
- ]>\n};
- print $pre;
- my $fxattr = join ",", @fxlens;
- print qq{<tplxml format="$fmt" fxlens="$fxattr">\n};
- tpl2xml_node($tpl,"A0",1);
- print qq{</tplxml>\n};
-}
-
-sub tpl2xml_node {
- my $tpl = shift;
- my $node = shift;
- my $indent = shift;
- my $i = " " x $indent;
- for my $c (@{ $tpl->{$node} }) {
- if (ref($c)) {
- my ($type,$addr,$fxlen) = @$c;
- quote_chars $addr if $type eq 's';
- hex_chars $addr if $type eq 'B';
- if (not defined $fxlen) {
- print qq{$i<$type>$$addr</$type>\n}; # singleton
- } else {
- # all elements of octothorpic fixed-len array
- print qq{$i<fx>\n};
- print qq{$i <$type>$addr->[$_]</$type>\n} for (0..$fxlen-1);
- print qq{$i</fx>\n};
- }
- } else {
- # A node
- print qq{$i<A>\n};
- my $idx = $1 if $c =~ /^A(\d+)$/;
- while($tpl->tpl_unpack($idx) > 0) {
- print qq{$i<el>\n};
- tpl2xml_node($tpl,$c,$indent+1);
- print qq{$i</el>\n};
- }
- print qq{$i</A>\n};
- }
- }
-}
-
-sub xml2tpl {
- my $src = shift;
- my $p = new XML::Parser( Style => 'Tree' );
- my $tree = $p->parse($$src);
- die "not a tpl xml document" unless $tree->[0] eq 'tplxml';
- die "no format attribute" unless defined $tree->[1][0]->{format};
- my $fmt = $tree->[1][0]->{format};
- die "no fxlens attribute" unless defined $tree->[1][0]->{fxlens};
- my @fxlens = split /,/, $tree->[1][0]->{fxlens};
-
- # build list of references to variables for use in packing
- my (@args,@out);
- for(my ($i,$j,$k)=(0,0,0);$i<length($fmt);$i++) {
- push @args, [] if substr($fmt,$i,2) =~ /^[iucfIU]\#$/; # octothorpic
- push @args, \$out[$j++] if substr($fmt,$i,2) =~ /^[iuBscfIU][^\#]*$/;
- push @args, $fxlens[$k++] if substr($fmt,$i,1) eq "#";
- }
-
- my $tpl = Tpl->tpl_map($fmt,@args);
- xml2tpl_dfs($tpl,$tree->[1]);
- $tpl->tpl_pack(0);
- print $tpl->tpl_dump;
-}
-
-sub xml2tpl_dfs {
- my $tpl = shift;
- my $xml = shift;
-
- my @next = @$xml; # ($attr,@tagvals) = $$xml;
- shift @next; # discard <tplxml> attributes
- my @tpltoks = @{ $tpl->{"A0"} }; #expected tokens when parsing
-
- TAG: while (@next) {
- my $xmltag = shift @next;
- my $xmlval = shift @next;
-
- # skip whitespace/newlines embedded between tags
- next TAG if ($xmltag eq "0" and $xmlval =~ /^\s+$/);
-
- # pack if necessary. consume tokens by look-ahead until non-pack token.
- while (@tpltoks > 0 and $tpltoks[0] =~ /^P(\d+)$/) {
- shift @tpltoks;
- $tpl->tpl_pack($1);
- }
-
- # If tpl format specifies a non-array type should appear at this point
- # in the XML tree, then validate the type matches the format and assign
- # the value from the XML to the variable from which it'll be packed
- my $tpltoken = shift @tpltoks;
- my $octothorpic=0;
- if (ref $tpltoken) {
- my ($tpltype,$tpladdr,$fxlen) = @$tpltoken;
-
- # This block is how we handle octothorpic (fixed length) arrays.
- # If $fxlen is defined then an octothorpic <fx> node is expected.
- # After finding the <fx> node we put its subnodes (the array elements)
- # onto the @next array for immediate parsing and we use $fxlen:$remaining
- # as a signet version of the $fxlen to induce the element-processing loop.
- if (defined $fxlen) {
- if ($fxlen =~ /^(\d+):(\d+)$/) { # $1==orig $fxlen, $2==remain $fxlen
- $octothorpic=1;
- unshift @tpltoks, [$tpltype, $tpladdr, $1.":".($2-1)] if $2 > 1;
- } else { # octothorpic array expected; look for <fx> parent node
- die "expected '<fx>' but got '<$xmltag>'" unless $xmltag eq 'fx';
- @{ $tpladdr } = (); # Empty accumulator array for octothorpic values
- unshift @tpltoks, [$tpltype, $tpladdr, "$fxlen:$fxlen"]; # x:x signet
- shift @$xmlval; # discard 'A' attributes
- unshift @next, @$xmlval; #parse xml subtree now (dfs)
- next TAG; # proceed to children of <fx> node
- }
- }
-
- if ($tpltype ne $xmltag) {
- die "mismatch: xml has '$xmltag' where format specifies '$tpltype'";
- }
- # expect @$xmlval to be ({},0,'value') i.e. a single, terminal text node
- if (@$xmlval > 3 || $xmlval->[1] ne '0') {
- die "error: xml tag '$xmltag' cannot enclose sub-tags";
- }
- if ($octothorpic) {
- push @{ $tpladdr }, $xmlval->[2];
- } else {
- $$tpladdr = $xmlval->[2];
- }
- unquote_chars $tpladdr if $tpltype eq 's';
- unhex_chars $tpladdr if $tpltype eq 'B';
- } elsif ($tpltoken =~ /^A(\d+)$/) {
- # tpl format specifies an array should appear at this point in the XML
- if ($xmltag ne 'A') {
- die "mismatch: xml has '$xmltag' where format specifies 'A'";
- }
- shift @$xmlval; # discard 'A' attributes
-
- # form token that means "replace me with tokens from A(n), x times"
- # (where x is the number of elements contained by this array).
- my $array_count=0;
- for(my $i=0; $i < @$xmlval; $i+=2) {
- $array_count++ if $xmlval->[$i] eq 'el';
- }
-
- unshift @tpltoks, "N$1:$array_count" if $array_count > 0;
- unshift @next, @$xmlval; #parse xml subtree now (dfs)
- } elsif ($tpltoken =~ /^N(\d+):(\d+)$/) {
- if ($xmltag ne "el") {
- die "mismatch: xml has '$xmltag' where array 'el' is expected";
- }
- # prepend A$1's tokens (and decremented N:count) to expected tokens
- my ($n,$elsleft) = ($1, ($2 - 1));
- unshift @tpltoks, "N$n:$elsleft" if $elsleft > 0;
- unshift @tpltoks, "P$n"; # "pack me now" token
- unshift @tpltoks, @{ $tpl->{"A$1"} };
-
- shift @$xmlval; # discard 'el' attributes
- unshift @next, @$xmlval; # proceed to parse el subtree (dfs)
- } else {
- die "internal error, unexpected token $tpltoken";
- }
- }
-
- # pack if necessary. consume tokens by look-ahead until non-pack token.
- while (@tpltoks > 0 and $tpltoks[0] =~ /^P(\d+)$/) {
- shift @tpltoks;
- $tpl->tpl_pack($1);
- }
-
- if (@tpltoks > 0) {
- die "error: end of xml document reached but format requires more data";
- }
-}
-
-sub peek_fmt {
- my $buf = shift;
- die "invalid tpl file" unless ($$buf =~ /^tpl/);
- my $flags = CORE::unpack("C", substr($$buf,3,1));
- my $UF = ($flags & 1) ? "N" : "V"; # big or little endian fxlens
- my $fmt = (CORE::unpack("Z*", substr($$buf,8)));
- my $num_octothorpes = scalar (my @o = ($fmt =~ /#/g));
- my @fxlens;
- my $fx = 8 + length($fmt) + 1;
- for(my $i=0; $i < $num_octothorpes; $i++) {
- my $fxlen_bytes = substr($$buf,$fx,4);
- my $fxlen = unpack($UF, $fxlen_bytes);
- push @fxlens, $fxlen;
- $fx += 4;
- }
- return ($fmt,@fxlens);
-}
-
-##########################################################################
-# Slurp input file, auto-detect if conversion is to tpl or XML, and run.
-##########################################################################
-
-undef $/;
-my $src = <>;
-our $to = (substr($src,0,3) eq "tpl") ? "xml" : "tpl";
-xml2tpl(\$src) if $to eq "tpl";
-tpl2xml(\$src) if $to eq "xml";
-
+++ /dev/null
-SUBDIRS = win
-lib_LTLIBRARIES = libtpl.la
-libtpl_la_SOURCES = tpl.c
-include_HEADERS = tpl.h
-libtpl_la_LDFLAGS = -no-undefined -version-info 0:0:0
-libtpl_la_LIBADD = win/libwinmmap.la
-
+++ /dev/null
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src
-DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/config.h
-CONFIG_CLEAN_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libtpl_la_DEPENDENCIES = win/libwinmmap.la
-am_libtpl_la_OBJECTS = tpl.lo
-libtpl_la_OBJECTS = $(am_libtpl_la_OBJECTS)
-libtpl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libtpl_la_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libtpl_la_SOURCES)
-DIST_SOURCES = $(libtpl_la_SOURCES)
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
- html-recursive info-recursive install-data-recursive \
- install-dvi-recursive install-exec-recursive \
- install-html-recursive install-info-recursive \
- install-pdf-recursive install-ps-recursive install-recursive \
- installcheck-recursive installdirs-recursive pdf-recursive \
- ps-recursive uninstall-recursive
-includeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(include_HEADERS)
-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
- distclean-recursive maintainer-clean-recursive
-ETAGS = etags
-CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-SUBDIRS = win
-lib_LTLIBRARIES = libtpl.la
-libtpl_la_SOURCES = tpl.c
-include_HEADERS = tpl.h
-libtpl_la_LDFLAGS = -no-undefined -version-info 0:0:0
-libtpl_la_LIBADD = win/libwinmmap.la
-all: all-recursive
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-libLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
- done
-
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libtpl.la: $(libtpl_la_OBJECTS) $(libtpl_la_DEPENDENCIES)
- $(libtpl_la_LINK) -rpath $(libdir) $(libtpl_la_OBJECTS) $(libtpl_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpl.Plo@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-install-includeHEADERS: $(include_HEADERS)
- @$(NORMAL_INSTALL)
- test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
- @list='$(include_HEADERS)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
- $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
- done
-
-uninstall-includeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(include_HEADERS)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
- rm -f "$(DESTDIR)$(includedir)/$$f"; \
- done
-
-# This directory's subdirectories are mostly independent; you can cd
-# into them and run `make' without going through this Makefile.
-# To change the values of `make' variables: instead of editing Makefiles,
-# (1) if the variable is set in `config.status', edit `config.status'
-# (which will cause the Makefiles to be regenerated when you run `make');
-# (2) otherwise, pass the desired values on the `make' command line.
-$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- target=`echo $@ | sed s/-recursive//`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
- fi; test -z "$$fail"
-
-$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- rev=''; for subdir in $$list; do \
- if test "$$subdir" = "."; then :; else \
- rev="$$subdir $$rev"; \
- fi; \
- done; \
- rev="$$rev ."; \
- target=`echo $@ | sed s/-recursive//`; \
- for subdir in $$rev; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done && test -z "$$fail"
-tags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
- done
-ctags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
- done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
- include_option=--etags-include; \
- empty_fix=.; \
- else \
- include_option=--include; \
- empty_fix=; \
- fi; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test ! -f $$subdir/TAGS || \
- tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
- fi; \
- done; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
- list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- distdir=`$(am__cd) $(distdir) && pwd`; \
- top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
- (cd $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$top_distdir" \
- distdir="$$distdir/$$subdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- distdir) \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-recursive
-all-am: Makefile $(LTLIBRARIES) $(HEADERS)
-installdirs: installdirs-recursive
-installdirs-am:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-recursive
-install-exec: install-exec-recursive
-install-data: install-data-recursive
-uninstall: uninstall-recursive
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-recursive
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-recursive
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
- mostlyclean-am
-
-distclean: distclean-recursive
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-recursive
-
-dvi-am:
-
-html: html-recursive
-
-info: info-recursive
-
-info-am:
-
-install-data-am: install-includeHEADERS
-
-install-dvi: install-dvi-recursive
-
-install-exec-am: install-libLTLIBRARIES
-
-install-html: install-html-recursive
-
-install-info: install-info-recursive
-
-install-man:
-
-install-pdf: install-pdf-recursive
-
-install-ps: install-ps-recursive
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-recursive
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-recursive
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-recursive
-
-pdf-am:
-
-ps: ps-recursive
-
-ps-am:
-
-uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
-
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
- install-strip
-
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am check check-am clean clean-generic \
- clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \
- distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am \
- install-includeHEADERS install-info install-info-am \
- install-libLTLIBRARIES install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs installdirs-am maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags tags-recursive uninstall uninstall-am \
- uninstall-includeHEADERS uninstall-libLTLIBRARIES
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
+++ /dev/null
-/*
-Copyright (c) 2005-2010, Troy D. Hanson http://tpl.sourceforge.net
-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.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define TPL_VERSION 1.5
-
-//static const char id[]="$Id: tpl.c 192 2009-04-24 10:35:30Z thanson $";
-
-
-#include <stdlib.h> /* malloc */
-#include <stdarg.h> /* va_list */
-#include <string.h> /* memcpy, memset, strchr */
-#include <stdio.h> /* printf (tpl_hook.oops default function) */
-
-#ifndef _WIN32
-#include <unistd.h> /* for ftruncate */
-#else
-#include <io.h>
-#define ftruncate(x,y) _chsize(x,y)
-#endif
-#include <sys/types.h> /* for 'open' */
-#include <sys/stat.h> /* for 'open' */
-#include <fcntl.h> /* for 'open' */
-#include <errno.h>
-#ifndef _WIN32
-#include <inttypes.h> /* uint32_t, uint64_t, etc */
-#else
-typedef unsigned short ushort;
-typedef __int16 int16_t;
-typedef __int32 int32_t;
-typedef __int64 int64_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-#endif
-
-
-#if ( defined __CYGWIN__ || defined __MINGW32__ || defined _WIN32 )
-#include "win/mman.h" /* mmap */
-#else
-#include <sys/mman.h> /* mmap */
-#endif
-
-#include "tpl.h"
-
-#define TPL_GATHER_BUFLEN 8192
-#define TPL_MAGIC "tpl"
-
-/* macro to add a structure to a doubly-linked list */
-#define DL_ADD(head,add) \
- do { \
- if (head) { \
- (add)->prev = (head)->prev; \
- (head)->prev->next = (add); \
- (head)->prev = (add); \
- (add)->next = NULL; \
- } else { \
- (head)=(add); \
- (head)->prev = (head); \
- (head)->next = NULL; \
- } \
- } while (0);
-
-#define fatal_oom() tpl_hook.fatal("out of memory\n")
-
-/* bit flags (internal). preceded by the external flags in tpl.h */
-#define TPL_WRONLY (1 << 9) /* app has initiated tpl packing */
-#define TPL_RDONLY (1 << 10) /* tpl was loaded (for unpacking) */
-#define TPL_XENDIAN (1 << 11) /* swap endianness when unpacking */
-#define TPL_OLD_STRING_FMT (1 << 12) /* tpl has strings in 1.2 format */
-
-/* values for the flags byte that appears after the magic prefix */
-#define TPL_SUPPORTED_BITFLAGS 3
-#define TPL_FL_BIGENDIAN (1 << 0)
-#define TPL_FL_NULLSTRINGS (1 << 1)
-
-/* char values for node type */
-#define TPL_TYPE_ROOT 0
-#define TPL_TYPE_INT32 1
-#define TPL_TYPE_UINT32 2
-#define TPL_TYPE_BYTE 3
-#define TPL_TYPE_STR 4
-#define TPL_TYPE_ARY 5
-#define TPL_TYPE_BIN 6
-#define TPL_TYPE_DOUBLE 7
-#define TPL_TYPE_INT64 8
-#define TPL_TYPE_UINT64 9
-#define TPL_TYPE_INT16 10
-#define TPL_TYPE_UINT16 11
-#define TPL_TYPE_POUND 12
-
-/* error codes */
-#define ERR_NOT_MINSIZE (-1)
-#define ERR_MAGIC_MISMATCH (-2)
-#define ERR_INCONSISTENT_SZ (-3)
-#define ERR_FMT_INVALID (-4)
-#define ERR_FMT_MISSING_NUL (-5)
-#define ERR_FMT_MISMATCH (-6)
-#define ERR_FLEN_MISMATCH (-7)
-#define ERR_INCONSISTENT_SZ2 (-8)
-#define ERR_INCONSISTENT_SZ3 (-9)
-#define ERR_INCONSISTENT_SZ4 (-10)
-#define ERR_UNSUPPORTED_FLAGS (-11)
-
-/* access to A(...) nodes by index */
-typedef struct tpl_pidx {
- struct tpl_node *node;
- struct tpl_pidx *next,*prev;
-} tpl_pidx;
-
-/* A(...) node datum */
-typedef struct tpl_atyp {
- uint32_t num; /* num elements */
- size_t sz; /* size of each backbone's datum */
- struct tpl_backbone *bb,*bbtail;
- void *cur;
-} tpl_atyp;
-
-/* backbone to extend A(...) lists dynamically */
-typedef struct tpl_backbone {
- struct tpl_backbone *next;
- /* when this structure is malloc'd, extra space is alloc'd at the
- * end to store the backbone "datum", and data points to it. */
-#if __STDC_VERSION__ < 199901
- char *data;
-#else
- char data[];
-#endif
-} tpl_backbone;
-
-/* mmap record */
-typedef struct tpl_mmap_rec {
- int fd;
- void *text;
- size_t text_sz;
-} tpl_mmap_rec;
-
-/* root node datum */
-typedef struct tpl_root_data {
- int flags;
- tpl_pidx *pidx;
- tpl_mmap_rec mmap;
- char *fmt;
- int *fxlens, num_fxlens;
-} tpl_root_data;
-
-/* node type to size mapping */
-struct tpl_type_t {
- char c;
- int sz;
-};
-
-
-/* Internal prototypes */
-static tpl_node *tpl_node_new(tpl_node *parent);
-static tpl_node *tpl_find_i(tpl_node *n, int i);
-static void *tpl_cpv(void *datav, void *data, size_t sz);
-static void *tpl_extend_backbone(tpl_node *n);
-static char *tpl_fmt(tpl_node *r);
-static void *tpl_dump_atyp(tpl_node *n, tpl_atyp* at, void *dv);
-static size_t tpl_ser_osz(tpl_node *n);
-static void tpl_free_atyp(tpl_node *n,tpl_atyp *atyp);
-static int tpl_dump_to_mem(tpl_node *r, void *addr, size_t sz);
-static int tpl_mmap_file(char *filename, tpl_mmap_rec *map_rec);
-static int tpl_mmap_output_file(char *filename, size_t sz, void **text_out);
-static int tpl_cpu_bigendian(void);
-static int tpl_needs_endian_swap(void *);
-static void tpl_byteswap(void *word, int len);
-static void tpl_fatal(char *fmt, ...);
-static int tpl_serlen(tpl_node *r, tpl_node *n, void *dv, size_t *serlen);
-static int tpl_unpackA0(tpl_node *r);
-static int tpl_oops(const char *fmt, ...);
-static int tpl_gather_mem( char *buf, size_t len, tpl_gather_t **gs, tpl_gather_cb *cb, void *data);
-static int tpl_gather_nonblocking( int fd, tpl_gather_t **gs, tpl_gather_cb *cb, void *data);
-static int tpl_gather_blocking(int fd, void **img, size_t *sz);
-static tpl_node *tpl_map_va(char *fmt, va_list ap);
-
-/* This is used internally to help calculate padding when a 'double'
- * follows a smaller datatype in a structure. Normally under gcc
- * on x86, d will be aligned at +4, however use of -malign-double
- * causes d to be aligned at +8 (this is actually faster on x86).
- * Also SPARC and x86_64 seem to align always on +8.
- */
-struct tpl_double_alignment_detector {
- char a;
- double d; /* some platforms align this on +4, others on +8 */
-};
-
-/* this is another case where alignment varies. mac os x/gcc was observed
- * to align the int64_t at +4 under -m32 and at +8 under -m64 */
-struct tpl_int64_alignment_detector {
- int i;
- int64_t j; /* some platforms align this on +4, others on +8 */
-};
-
-typedef struct {
- size_t inter_elt_len; /* padded inter-element len; i.e. &a[1].field - &a[0].field */
- tpl_node *iter_start_node; /* node to jump back to, as we start each new iteration */
- size_t iternum; /* current iteration number (total req'd. iter's in n->num) */
-} tpl_pound_data;
-
-/* Hooks for customizing tpl mem alloc, error handling, etc. Set defaults. */
-tpl_hook_t tpl_hook = {
- /* .oops = */ tpl_oops,
- /* .malloc = */ malloc,
- /* .realloc = */ realloc,
- /* .free = */ free,
- /* .fatal = */ tpl_fatal,
- /* .gather_max = */ 0 /* max tpl size (bytes) for tpl_gather */
-};
-
-static const char tpl_fmt_chars[] = "AS($)BiucsfIUjv#"; /* valid format chars */
-//static const char tpl_S_fmt_chars[] = "iucsfIUjv#$()"; /* valid within S(...) */
-static const char tpl_datapeek_ok_chars[] = "iucsfIUjv"; /* valid in datapeek */
-static const struct tpl_type_t tpl_types[] = {
- /* [TPL_TYPE_ROOT] = */ {'r', 0},
- /* [TPL_TYPE_INT32] = */ {'i', sizeof(int32_t)},
- /* [TPL_TYPE_UINT32] = */ {'u', sizeof(uint32_t)},
- /* [TPL_TYPE_BYTE] = */ {'c', sizeof(char)},
- /* [TPL_TYPE_STR] = */ {'s', sizeof(char*)},
- /* [TPL_TYPE_ARY] = */ {'A', 0},
- /* [TPL_TYPE_BIN] = */ {'B', 0},
- /* [TPL_TYPE_DOUBLE] = */ {'f', 8}, /* not sizeof(double) as that varies */
- /* [TPL_TYPE_INT64] = */ {'I', sizeof(int64_t)},
- /* [TPL_TYPE_UINT64] = */ {'U', sizeof(uint64_t)},
- /* [TPL_TYPE_INT16] = */ {'j', sizeof(int16_t)},
- /* [TPL_TYPE_UINT16] = */ {'v', sizeof(uint16_t)},
- /* [TPL_TYPE_POUND] = */ {'#', 0},
-};
-
-/* default error-reporting function. Just writes to stderr. */
-static int tpl_oops(const char *fmt, ...) {
- va_list ap;
- va_start(ap,fmt);
- vfprintf(stderr,fmt,ap);
- va_end(ap);
- return 0;
-}
-
-
-static tpl_node *tpl_node_new(tpl_node *parent) {
- tpl_node *n;
- if ((n=tpl_hook.malloc(sizeof(tpl_node))) == NULL) {
- fatal_oom();
- }
- n->addr=NULL;
- n->data=NULL;
- n->num=1;
- n->ser_osz=0;
- n->children=NULL;
- n->next=NULL;
- n->parent=parent;
- return n;
-}
-
-/* Used in S(..) formats to pack several fields from a structure based on
- * only the structure address. We need to calculate field addresses
- * manually taking into account the size of the fields and intervening padding.
- * The wrinkle is that double is not normally aligned on x86-32 but the
- * -malign-double compiler option causes it to be. Double are aligned
- * on Sparc, and apparently on 64 bit x86. We use a helper structure
- * to detect whether double is aligned in this compilation environment.
- */
-char *calc_field_addr(tpl_node *parent, int type,char *struct_addr, int ordinal) {
- tpl_node *prev;
- int offset;
- int align_sz;
-
- if (ordinal == 1) return struct_addr; /* first field starts on structure address */
-
- /* generate enough padding so field addr is divisible by it's align_sz. 4, 8, etc */
- prev = parent->children->prev;
- switch(type) {
- case TPL_TYPE_DOUBLE:
- align_sz = sizeof(struct tpl_double_alignment_detector) > 12 ? 8 : 4;
- break;
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- align_sz = sizeof(struct tpl_int64_alignment_detector) > 12 ? 8 : 4;
- break;
- default:
- align_sz = tpl_types[type].sz;
- break;
- }
- offset = ((uintptr_t)prev->addr - (uintptr_t)struct_addr)
- + (tpl_types[prev->type].sz * prev->num);
- offset = (offset + align_sz - 1) / align_sz * align_sz;
- return struct_addr + offset;
-}
-
-TPL_API tpl_node *tpl_map(char *fmt,...) {
- va_list ap;
- tpl_node *tn;
-
- va_start(ap,fmt);
- tn = tpl_map_va(fmt, ap);
- va_end(ap);
- return tn;
-}
-
-static tpl_node *tpl_map_va(char *fmt, va_list ap) {
- int lparen_level=0,expect_lparen=0,t=0,in_structure=0,ordinal=0;
- int in_nested_structure=0;
- char *c, *peek, *struct_addr=NULL, *struct_next;
- tpl_node *root,*parent,*n=NULL,*preceding,*iter_start_node=NULL,
- *struct_widest_node=NULL, *np; tpl_pidx *pidx;
- tpl_pound_data *pd;
- int *fxlens, num_fxlens, pound_num, pound_prod, applies_to_struct;
- int contig_fxlens[10]; /* temp space for contiguous fxlens */
- int num_contig_fxlens, i, j;
- ptrdiff_t inter_elt_len=0; /* padded element length of contiguous structs in array */
-
-
- root = tpl_node_new(NULL);
- root->type = TPL_TYPE_ROOT;
- root->data = (tpl_root_data*)tpl_hook.malloc(sizeof(tpl_root_data));
- if (!root->data) fatal_oom();
- memset((tpl_root_data*)root->data,0,sizeof(tpl_root_data));
-
- /* set up root nodes special ser_osz to reflect overhead of preamble */
- root->ser_osz = sizeof(uint32_t); /* tpl leading length */
- root->ser_osz += strlen(fmt) + 1; /* fmt + NUL-terminator */
- root->ser_osz += 4; /* 'tpl' magic prefix + flags byte */
-
- parent=root;
-
- c=fmt;
- while (*c != '\0') {
- switch (*c) {
- case 'c':
- case 'i':
- case 'u':
- case 'j':
- case 'v':
- case 'I':
- case 'U':
- case 'f':
- if (*c=='c') t=TPL_TYPE_BYTE;
- else if (*c=='i') t=TPL_TYPE_INT32;
- else if (*c=='u') t=TPL_TYPE_UINT32;
- else if (*c=='j') t=TPL_TYPE_INT16;
- else if (*c=='v') t=TPL_TYPE_UINT16;
- else if (*c=='I') t=TPL_TYPE_INT64;
- else if (*c=='U') t=TPL_TYPE_UINT64;
- else if (*c=='f') t=TPL_TYPE_DOUBLE;
-
- if (expect_lparen) goto fail;
- n = tpl_node_new(parent);
- n->type = t;
- if (in_structure) {
- if (ordinal == 1) {
- /* for S(...)# iteration. Apply any changes to case 's' too!!! */
- iter_start_node = n;
- struct_widest_node = n;
- }
- if (tpl_types[n->type].sz > tpl_types[struct_widest_node->type].sz) {
- struct_widest_node = n;
- }
- n->addr = calc_field_addr(parent,n->type,struct_addr,ordinal++);
- } else n->addr = (void*)va_arg(ap,void*);
- n->data = tpl_hook.malloc(tpl_types[t].sz);
- if (!n->data) fatal_oom();
- if (n->parent->type == TPL_TYPE_ARY)
- ((tpl_atyp*)(n->parent->data))->sz += tpl_types[t].sz;
- DL_ADD(parent->children,n);
- break;
- case 's':
- if (expect_lparen) goto fail;
- n = tpl_node_new(parent);
- n->type = TPL_TYPE_STR;
- if (in_structure) {
- if (ordinal == 1) {
- iter_start_node = n; /* for S(...)# iteration */
- struct_widest_node = n;
- }
- if (tpl_types[n->type].sz > tpl_types[struct_widest_node->type].sz) {
- struct_widest_node = n;
- }
- n->addr = calc_field_addr(parent,n->type,struct_addr,ordinal++);
- } else n->addr = (void*)va_arg(ap,void*);
- n->data = tpl_hook.malloc(sizeof(char*));
- if (!n->data) fatal_oom();
- *(char**)(n->data) = NULL;
- if (n->parent->type == TPL_TYPE_ARY)
- ((tpl_atyp*)(n->parent->data))->sz += sizeof(void*);
- DL_ADD(parent->children,n);
- break;
- case '#':
- /* apply a 'num' to preceding atom */
- if (!parent->children) goto fail;
- preceding = parent->children->prev; /* first child's prev is 'last child'*/
- t = preceding->type;
- applies_to_struct = (*(c-1) == ')') ? 1 : 0;
- if (!applies_to_struct) {
- if (!(t == TPL_TYPE_BYTE || t == TPL_TYPE_INT32 ||
- t == TPL_TYPE_UINT32 || t == TPL_TYPE_DOUBLE ||
- t == TPL_TYPE_UINT64 || t == TPL_TYPE_INT64 ||
- t == TPL_TYPE_UINT16 || t == TPL_TYPE_INT16 ||
- t == TPL_TYPE_STR )) goto fail;
- }
- /* count up how many contiguous # and form their product */
- pound_prod=1;
- num_contig_fxlens=0;
- for(peek=c; *peek == '#'; peek++) {
- pound_num = va_arg(ap, int);
- if (pound_num < 1) {
- tpl_hook.fatal("non-positive iteration count %d\n", pound_num);
- }
- if (num_contig_fxlens >= (sizeof(contig_fxlens)/sizeof(contig_fxlens[0]))) {
- tpl_hook.fatal("contiguous # exceeds hardcoded limit\n");
- }
- contig_fxlens[num_contig_fxlens++] = pound_num;
- pound_prod *= pound_num;
- }
- /* increment c to skip contiguous # so its points to last one */
- c = peek-1;
- /* differentiate atom-# from struct-# by noting preceding rparen */
- if (applies_to_struct) { /* insert # node to induce looping */
- n = tpl_node_new(parent);
- n->type = TPL_TYPE_POUND;
- n->num = pound_prod;
- n->data = tpl_hook.malloc(sizeof(tpl_pound_data));
- if (!n->data) fatal_oom();
- pd = (tpl_pound_data*)n->data;
- pd->inter_elt_len = inter_elt_len;
- pd->iter_start_node = iter_start_node;
- pd->iternum = 0;
- DL_ADD(parent->children,n);
- /* multiply the 'num' and data space on each atom in the structure */
- for(np = iter_start_node; np != n; np = np->next) {
- if (n->parent->type == TPL_TYPE_ARY) {
- ((tpl_atyp*)(n->parent->data))->sz +=
- tpl_types[np->type].sz * (np->num * (n->num - 1));
- }
- np->data = tpl_hook.realloc(np->data, tpl_types[np->type].sz *
- np->num * n->num);
- if (!np->data) fatal_oom();
- memset(np->data, 0, tpl_types[np->type].sz * np->num * n->num);
- }
- } else { /* simple atom-# form does not require a loop */
- preceding->num = pound_prod;
- preceding->data = tpl_hook.realloc(preceding->data,
- tpl_types[t].sz * preceding->num);
- if (!preceding->data) fatal_oom();
- memset(preceding->data,0,tpl_types[t].sz * preceding->num);
- if (n->parent->type == TPL_TYPE_ARY) {
- ((tpl_atyp*)(n->parent->data))->sz += tpl_types[t].sz *
- (preceding->num-1);
- }
- }
- root->ser_osz += (sizeof(uint32_t) * num_contig_fxlens);
-
- j = ((tpl_root_data*)root->data)->num_fxlens; /* before incrementing */
- (((tpl_root_data*)root->data)->num_fxlens) += num_contig_fxlens;
- num_fxlens = ((tpl_root_data*)root->data)->num_fxlens; /* new value */
- fxlens = ((tpl_root_data*)root->data)->fxlens;
- fxlens = tpl_hook.realloc(fxlens, sizeof(int) * num_fxlens);
- if (!fxlens) fatal_oom();
- ((tpl_root_data*)root->data)->fxlens = fxlens;
- for(i=0; i < num_contig_fxlens; i++) fxlens[j++] = contig_fxlens[i];
-
- break;
- case 'B':
- if (expect_lparen) goto fail;
- if (in_structure) goto fail;
- n = tpl_node_new(parent);
- n->type = TPL_TYPE_BIN;
- n->addr = (tpl_bin*)va_arg(ap,void*);
- n->data = tpl_hook.malloc(sizeof(tpl_bin*));
- if (!n->data) fatal_oom();
- *((tpl_bin**)n->data) = NULL;
- if (n->parent->type == TPL_TYPE_ARY)
- ((tpl_atyp*)(n->parent->data))->sz += sizeof(tpl_bin);
- DL_ADD(parent->children,n);
- break;
- case 'A':
- if (in_structure) goto fail;
- n = tpl_node_new(parent);
- n->type = TPL_TYPE_ARY;
- DL_ADD(parent->children,n);
- parent = n;
- expect_lparen=1;
- pidx = (tpl_pidx*)tpl_hook.malloc(sizeof(tpl_pidx));
- if (!pidx) fatal_oom();
- pidx->node = n;
- pidx->next = NULL;
- DL_ADD(((tpl_root_data*)(root->data))->pidx,pidx);
- /* set up the A's tpl_atyp */
- n->data = (tpl_atyp*)tpl_hook.malloc(sizeof(tpl_atyp));
- if (!n->data) fatal_oom();
- ((tpl_atyp*)(n->data))->num = 0;
- ((tpl_atyp*)(n->data))->sz = 0;
- ((tpl_atyp*)(n->data))->bb = NULL;
- ((tpl_atyp*)(n->data))->bbtail = NULL;
- ((tpl_atyp*)(n->data))->cur = NULL;
- if (n->parent->type == TPL_TYPE_ARY)
- ((tpl_atyp*)(n->parent->data))->sz += sizeof(void*);
- break;
- case 'S':
- if (in_structure) goto fail;
- expect_lparen=1;
- ordinal=1; /* index upcoming atoms in S(..) */
- in_structure=1+lparen_level; /* so we can tell where S fmt ends */
- struct_addr = (char*)va_arg(ap,void*);
- break;
- case '$': /* nested structure */
- if (!in_structure) goto fail;
- expect_lparen=1;
- in_nested_structure++;
- break;
- case ')':
- lparen_level--;
- if (lparen_level < 0) goto fail;
- if (*(c-1) == '(') goto fail;
- if (in_nested_structure) in_nested_structure--;
- else if (in_structure && (in_structure-1 == lparen_level)) {
- /* calculate delta between contiguous structures in array */
- struct_next = calc_field_addr(parent, struct_widest_node->type,
- struct_addr, ordinal++);
- inter_elt_len = struct_next - struct_addr;
- in_structure=0;
- }
- else parent = parent->parent; /* rparen ends A() type, not S() type */
- break;
- case '(':
- if (!expect_lparen) goto fail;
- expect_lparen=0;
- lparen_level++;
- break;
- default:
- tpl_hook.oops("unsupported option %c\n", *c);
- goto fail;
- }
- c++;
- }
- if (lparen_level != 0) goto fail;
-
- /* copy the format string, save for convenience */
- ((tpl_root_data*)(root->data))->fmt = tpl_hook.malloc(strlen(fmt)+1);
- if (((tpl_root_data*)(root->data))->fmt == NULL)
- fatal_oom();
- memcpy(((tpl_root_data*)(root->data))->fmt,fmt,strlen(fmt)+1);
-
- return root;
-
-fail:
- tpl_hook.oops("failed to parse %s\n", fmt);
- tpl_free(root);
- return NULL;
-}
-
-static int tpl_unmap_file( tpl_mmap_rec *mr) {
-
- if ( munmap( mr->text, mr->text_sz ) == -1 ) {
- tpl_hook.oops("Failed to munmap: %s\n", strerror(errno));
- }
- close(mr->fd);
- mr->text = NULL;
- mr->text_sz = 0;
- return 0;
-}
-
-static void tpl_free_keep_map(tpl_node *r) {
- int mmap_bits = (TPL_RDONLY|TPL_FILE);
- int ufree_bits = (TPL_MEM|TPL_UFREE);
- tpl_node *nxtc,*c;
- int find_next_node=0,looking,i;
- size_t sz;
-
- /* For mmap'd files, or for 'ufree' memory images , do appropriate release */
- if ((((tpl_root_data*)(r->data))->flags & mmap_bits) == mmap_bits) {
- tpl_unmap_file( &((tpl_root_data*)(r->data))->mmap);
- } else if ((((tpl_root_data*)(r->data))->flags & ufree_bits) == ufree_bits) {
- tpl_hook.free( ((tpl_root_data*)(r->data))->mmap.text );
- }
-
- c = r->children;
- if (c) {
- while(c->type != TPL_TYPE_ROOT) { /* loop until we come back to root node */
- switch (c->type) {
- case TPL_TYPE_BIN:
- /* free any binary buffer hanging from tpl_bin */
- if ( *((tpl_bin**)(c->data)) ) {
- if ( (*((tpl_bin**)(c->data)))->addr ) {
- tpl_hook.free( (*((tpl_bin**)(c->data)))->addr );
- }
- *((tpl_bin**)c->data) = NULL; /* reset tpl_bin */
- }
- find_next_node=1;
- break;
- case TPL_TYPE_STR:
- /* free any packed (copied) string */
- for(i=0; i < c->num; i++) {
- char *str = ((char**)c->data)[i];
- if (str) {
- tpl_hook.free(str);
- ((char**)c->data)[i] = NULL;
- }
- }
- find_next_node=1;
- break;
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- case TPL_TYPE_POUND:
- find_next_node=1;
- break;
- case TPL_TYPE_ARY:
- c->ser_osz = 0; /* zero out the serialization output size */
-
- sz = ((tpl_atyp*)(c->data))->sz; /* save sz to use below */
- tpl_free_atyp(c,c->data);
-
- /* make new atyp */
- c->data = (tpl_atyp*)tpl_hook.malloc(sizeof(tpl_atyp));
- if (!c->data) fatal_oom();
- ((tpl_atyp*)(c->data))->num = 0;
- ((tpl_atyp*)(c->data))->sz = sz; /* restore bb datum sz */
- ((tpl_atyp*)(c->data))->bb = NULL;
- ((tpl_atyp*)(c->data))->bbtail = NULL;
- ((tpl_atyp*)(c->data))->cur = NULL;
-
- c = c->children;
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
-
- if (find_next_node) {
- find_next_node=0;
- looking=1;
- while(looking) {
- if (c->next) {
- nxtc=c->next;
- c=nxtc;
- looking=0;
- } else {
- if (c->type == TPL_TYPE_ROOT) break; /* root node */
- else {
- nxtc=c->parent;
- c=nxtc;
- }
- }
- }
- }
- }
- }
-
- ((tpl_root_data*)(r->data))->flags = 0; /* reset flags */
-}
-
-TPL_API void tpl_free(tpl_node *r) {
- int mmap_bits = (TPL_RDONLY|TPL_FILE);
- int ufree_bits = (TPL_MEM|TPL_UFREE);
- tpl_node *nxtc,*c;
- int find_next_node=0,looking,i;
- tpl_pidx *pidx,*pidx_nxt;
-
- /* For mmap'd files, or for 'ufree' memory images , do appropriate release */
- if ((((tpl_root_data*)(r->data))->flags & mmap_bits) == mmap_bits) {
- tpl_unmap_file( &((tpl_root_data*)(r->data))->mmap);
- } else if ((((tpl_root_data*)(r->data))->flags & ufree_bits) == ufree_bits) {
- tpl_hook.free( ((tpl_root_data*)(r->data))->mmap.text );
- }
-
- c = r->children;
- if (c) {
- while(c->type != TPL_TYPE_ROOT) { /* loop until we come back to root node */
- switch (c->type) {
- case TPL_TYPE_BIN:
- /* free any binary buffer hanging from tpl_bin */
- if ( *((tpl_bin**)(c->data)) ) {
- if ( (*((tpl_bin**)(c->data)))->sz != 0 ) {
- tpl_hook.free( (*((tpl_bin**)(c->data)))->addr );
- }
- tpl_hook.free(*((tpl_bin**)c->data)); /* free tpl_bin */
- }
- tpl_hook.free(c->data); /* free tpl_bin* */
- find_next_node=1;
- break;
- case TPL_TYPE_STR:
- /* free any packed (copied) string */
- for(i=0; i < c->num; i++) {
- char *str = ((char**)c->data)[i];
- if (str) {
- tpl_hook.free(str);
- ((char**)c->data)[i] = NULL;
- }
- }
- tpl_hook.free(c->data);
- find_next_node=1;
- break;
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- case TPL_TYPE_POUND:
- tpl_hook.free(c->data);
- find_next_node=1;
- break;
- case TPL_TYPE_ARY:
- tpl_free_atyp(c,c->data);
- if (c->children) c = c->children; /* normal case */
- else find_next_node=1; /* edge case, handle bad format A() */
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
-
- if (find_next_node) {
- find_next_node=0;
- looking=1;
- while(looking) {
- if (c->next) {
- nxtc=c->next;
- tpl_hook.free(c);
- c=nxtc;
- looking=0;
- } else {
- if (c->type == TPL_TYPE_ROOT) break; /* root node */
- else {
- nxtc=c->parent;
- tpl_hook.free(c);
- c=nxtc;
- }
- }
- }
- }
- }
- }
-
- /* free root */
- for(pidx=((tpl_root_data*)(r->data))->pidx; pidx; pidx=pidx_nxt) {
- pidx_nxt = pidx->next;
- tpl_hook.free(pidx);
- }
- tpl_hook.free(((tpl_root_data*)(r->data))->fmt);
- if (((tpl_root_data*)(r->data))->num_fxlens > 0) {
- tpl_hook.free(((tpl_root_data*)(r->data))->fxlens);
- }
- tpl_hook.free(r->data); /* tpl_root_data */
- tpl_hook.free(r);
-}
-
-
-/* Find the i'th packable ('A' node) */
-static tpl_node *tpl_find_i(tpl_node *n, int i) {
- int j=0;
- tpl_pidx *pidx;
- if (n->type != TPL_TYPE_ROOT) return NULL;
- if (i == 0) return n; /* packable 0 is root */
- for(pidx=((tpl_root_data*)(n->data))->pidx; pidx; pidx=pidx->next) {
- if (++j == i) return pidx->node;
- }
- return NULL;
-}
-
-static void *tpl_cpv(void *datav, void *data, size_t sz) {
- if (sz>0) memcpy(datav,data,sz);
- return (void*)((uintptr_t)datav + sz);
-}
-
-static void *tpl_extend_backbone(tpl_node *n) {
- tpl_backbone *bb;
- bb = (tpl_backbone*)tpl_hook.malloc(sizeof(tpl_backbone) +
- ((tpl_atyp*)(n->data))->sz ); /* datum hangs on coattails of bb */
- if (!bb) fatal_oom();
-#if __STDC_VERSION__ < 199901
- bb->data = (char*)((uintptr_t)bb + sizeof(tpl_backbone));
-#endif
- memset(bb->data,0,((tpl_atyp*)(n->data))->sz);
- bb->next = NULL;
- /* Add the new backbone to the tail, also setting head if necessary */
- if (((tpl_atyp*)(n->data))->bb == NULL) {
- ((tpl_atyp*)(n->data))->bb = bb;
- ((tpl_atyp*)(n->data))->bbtail = bb;
- } else {
- ((tpl_atyp*)(n->data))->bbtail->next = bb;
- ((tpl_atyp*)(n->data))->bbtail = bb;
- }
-
- ((tpl_atyp*)(n->data))->num++;
- return bb->data;
-}
-
-/* Get the format string corresponding to a given tpl (root node) */
-static char *tpl_fmt(tpl_node *r) {
- return ((tpl_root_data*)(r->data))->fmt;
-}
-
-/* Get the fmt # lengths as a contiguous buffer of ints (length num_fxlens) */
-static int *tpl_fxlens(tpl_node *r, int *num_fxlens) {
- *num_fxlens = ((tpl_root_data*)(r->data))->num_fxlens;
- return ((tpl_root_data*)(r->data))->fxlens;
-}
-
-/* called when serializing an 'A' type node into a buffer which has
- * already been set up with the proper space. The backbone is walked
- * which was obtained from the tpl_atyp header passed in.
- */
-static void *tpl_dump_atyp(tpl_node *n, tpl_atyp* at, void *dv) {
- tpl_backbone *bb;
- tpl_node *c;
- void *datav;
- uint32_t slen;
- tpl_bin *binp;
- char *strp;
- tpl_atyp *atypp;
- tpl_pound_data *pd;
- int i;
- size_t itermax;
-
- /* handle 'A' nodes */
- dv = tpl_cpv(dv,&at->num,sizeof(uint32_t)); /* array len */
- for(bb=at->bb; bb; bb=bb->next) {
- datav = bb->data;
- c=n->children;
- while(c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- dv = tpl_cpv(dv,datav,tpl_types[c->type].sz * c->num);
- datav = (void*)((uintptr_t)datav + tpl_types[c->type].sz * c->num);
- break;
- case TPL_TYPE_BIN:
- /* dump the buffer length followed by the buffer */
- memcpy(&binp,datav,sizeof(tpl_bin*)); /* cp to aligned */
- slen = binp->sz;
- dv = tpl_cpv(dv,&slen,sizeof(uint32_t));
- dv = tpl_cpv(dv,binp->addr,slen);
- datav = (void*)((uintptr_t)datav + sizeof(tpl_bin*));
- break;
- case TPL_TYPE_STR:
- /* dump the string length followed by the string */
- for(i=0; i < c->num; i++) {
- memcpy(&strp,datav,sizeof(char*)); /* cp to aligned */
- slen = strp ? (strlen(strp)+1) : 0;
- dv = tpl_cpv(dv,&slen,sizeof(uint32_t));
- if (slen > 1) dv = tpl_cpv(dv,strp,slen-1);
- datav = (void*)((uintptr_t)datav + sizeof(char*));
- }
- break;
- case TPL_TYPE_ARY:
- memcpy(&atypp,datav,sizeof(tpl_atyp*)); /* cp to aligned */
- dv = tpl_dump_atyp(c,atypp,dv);
- datav = (void*)((uintptr_t)datav + sizeof(void*));
- break;
- case TPL_TYPE_POUND:
- /* iterate over the preceding nodes */
- pd = (tpl_pound_data*)c->data;
- itermax = c->num;
- if (++(pd->iternum) < itermax) {
- c = pd->iter_start_node;
- continue;
- } else { /* loop complete. */
- pd->iternum = 0;
- }
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- c=c->next;
- }
- }
- return dv;
-}
-
-/* figure the serialization output size needed for tpl whose root is n*/
-static size_t tpl_ser_osz(tpl_node *n) {
- tpl_node *c, *np;
- size_t sz, itermax;
- tpl_bin *binp;
- char *strp;
- tpl_pound_data *pd;
- int i;
-
- /* handle the root node ONLY (subtree's ser_osz have been bubbled-up) */
- if (n->type != TPL_TYPE_ROOT) {
- tpl_hook.fatal("internal error: tpl_ser_osz on non-root node\n");
- }
-
- sz = n->ser_osz; /* start with fixed overhead, already stored */
- c=n->children;
- while (c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- sz += tpl_types[c->type].sz * c->num;
- break;
- case TPL_TYPE_BIN:
- sz += sizeof(uint32_t); /* binary buf len */
- memcpy(&binp,c->data,sizeof(tpl_bin*)); /* cp to aligned */
- sz += binp->sz;
- break;
- case TPL_TYPE_STR:
- for(i=0; i < c->num; i++) {
- sz += sizeof(uint32_t); /* string len */
- memcpy(&strp,&((char**)c->data)[i],sizeof(char*)); /* cp to aligned */
- sz += strp ? strlen(strp) : 0;
- }
- break;
- case TPL_TYPE_ARY:
- sz += sizeof(uint32_t); /* array len */
- sz += c->ser_osz; /* bubbled-up child array ser_osz */
- break;
- case TPL_TYPE_POUND:
- /* iterate over the preceding nodes */
- itermax = c->num;
- pd = (tpl_pound_data*)c->data;
- if (++(pd->iternum) < itermax) {
- for(np=pd->iter_start_node; np != c; np = np->next) {
- np->data = (char*)(np->data) +
- (tpl_types[np->type].sz * np->num);
- }
- c = pd->iter_start_node;
- continue;
- } else { /* loop complete. */
- pd->iternum = 0;
- for(np=pd->iter_start_node; np != c; np = np->next) {
- np->data = (char*)(np->data) - ((itermax-1) *
- tpl_types[np->type].sz *
- np->num);
- }
- }
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- c=c->next;
- }
- return sz;
-}
-
-
-TPL_API int tpl_dump(tpl_node *r, int mode, ...) {
- va_list ap;
- char *filename, *bufv;
- void **addr_out,*buf, *pa_addr;
- int fd,rc=0;
- size_t sz,*sz_out, pa_sz;
-
- if (((tpl_root_data*)(r->data))->flags & TPL_RDONLY) { /* unusual */
- tpl_hook.oops("error: tpl_dump called for a loaded tpl\n");
- return -1;
- }
-
- sz = tpl_ser_osz(r); /* compute the size needed to serialize */
-
- va_start(ap,mode);
- if (mode & TPL_FILE) {
- filename = va_arg(ap,char*);
- fd = tpl_mmap_output_file(filename, sz, &buf);
- if (fd == -1) rc = -1;
- else {
- rc = tpl_dump_to_mem(r,buf,sz);
- if (msync(buf,sz,MS_SYNC) == -1) {
- tpl_hook.oops("msync failed on fd %d: %s\n", fd, strerror(errno));
- }
- if (munmap(buf, sz) == -1) {
- tpl_hook.oops("munmap failed on fd %d: %s\n", fd, strerror(errno));
- }
- close(fd);
- }
- } else if (mode & TPL_FD) {
- fd = va_arg(ap, int);
- if ( (buf = tpl_hook.malloc(sz)) == NULL) fatal_oom();
- tpl_dump_to_mem(r,buf,sz);
- bufv = buf;
- do {
- rc = write(fd,bufv,sz);
- if (rc > 0) {
- sz -= rc;
- bufv += rc;
- } else if (rc == -1) {
- if (errno == EINTR || errno == EAGAIN) continue;
- tpl_hook.oops("error writing to fd %d: %s\n", fd, strerror(errno));
- free(buf);
- return -1;
- }
- } while (sz > 0);
- free(buf);
- rc = 0;
- } else if (mode & TPL_MEM) {
- if (mode & TPL_PREALLOCD) { /* caller allocated */
- pa_addr = (void*)va_arg(ap, void*);
- pa_sz = va_arg(ap, size_t);
- if (pa_sz < sz) {
- tpl_hook.oops("tpl_dump: buffer too small, need %d bytes\n", sz);
- return -1;
- }
- rc=tpl_dump_to_mem(r,pa_addr,sz);
- } else { /* we allocate */
- addr_out = (void**)va_arg(ap, void*);
- sz_out = va_arg(ap, size_t*);
- if ( (buf = tpl_hook.malloc(sz)) == NULL) fatal_oom();
- *sz_out = sz;
- *addr_out = buf;
- rc=tpl_dump_to_mem(r,buf,sz);
- }
- } else if (mode & TPL_GETSIZE) {
- sz_out = va_arg(ap, size_t*);
- *sz_out = sz;
- } else {
- tpl_hook.oops("unsupported tpl_dump mode %d\n", mode);
- rc=-1;
- }
- va_end(ap);
- return rc;
-}
-
-/* This function expects the caller to have set up a memory buffer of
- * adequate size to hold the serialized tpl. The sz parameter must be
- * the result of tpl_ser_osz(r).
- */
-static int tpl_dump_to_mem(tpl_node *r,void *addr,size_t sz) {
- uint32_t slen, sz32;
- int *fxlens, num_fxlens, i;
- void *dv;
- char *fmt,flags;
- tpl_node *c, *np;
- tpl_pound_data *pd;
- size_t itermax;
-
- fmt = tpl_fmt(r);
- flags = 0;
- if (tpl_cpu_bigendian()) flags |= TPL_FL_BIGENDIAN;
- if (strchr(fmt,'s')) flags |= TPL_FL_NULLSTRINGS;
- sz32 = sz;
-
- dv = addr;
- dv = tpl_cpv(dv,TPL_MAGIC,3); /* copy tpl magic prefix */
- dv = tpl_cpv(dv,&flags,1); /* copy flags byte */
- dv = tpl_cpv(dv,&sz32,sizeof(uint32_t));/* overall length (inclusive) */
- dv = tpl_cpv(dv,fmt,strlen(fmt)+1); /* copy format with NUL-term */
- fxlens = tpl_fxlens(r,&num_fxlens);
- dv = tpl_cpv(dv,fxlens,num_fxlens*sizeof(uint32_t));/* fmt # lengths */
-
- /* serialize the tpl content, iterating over direct children of root */
- c = r->children;
- while (c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- dv = tpl_cpv(dv,c->data,tpl_types[c->type].sz * c->num);
- break;
- case TPL_TYPE_BIN:
- slen = (*(tpl_bin**)(c->data))->sz;
- dv = tpl_cpv(dv,&slen,sizeof(uint32_t)); /* buffer len */
- dv = tpl_cpv(dv,(*(tpl_bin**)(c->data))->addr,slen); /* buf */
- break;
- case TPL_TYPE_STR:
- for(i=0; i < c->num; i++) {
- char *str = ((char**)c->data)[i];
- slen = str ? strlen(str)+1 : 0;
- dv = tpl_cpv(dv,&slen,sizeof(uint32_t)); /* string len */
- if (slen>1) dv = tpl_cpv(dv,str,slen-1); /*string*/
- }
- break;
- case TPL_TYPE_ARY:
- dv = tpl_dump_atyp(c,(tpl_atyp*)c->data,dv);
- break;
- case TPL_TYPE_POUND:
- pd = (tpl_pound_data*)c->data;
- itermax = c->num;
- if (++(pd->iternum) < itermax) {
-
- /* in start or midst of loop. advance data pointers. */
- for(np=pd->iter_start_node; np != c; np = np->next) {
- np->data = (char*)(np->data) +
- (tpl_types[np->type].sz * np->num);
- }
- /* do next iteration */
- c = pd->iter_start_node;
- continue;
-
- } else { /* loop complete. */
-
- /* reset iteration index and addr/data pointers. */
- pd->iternum = 0;
- for(np=pd->iter_start_node; np != c; np = np->next) {
- np->data = (char*)(np->data) - ((itermax-1) *
- tpl_types[np->type].sz *
- np->num);
- }
-
- }
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- c = c->next;
- }
-
- return 0;
-}
-
-static int tpl_cpu_bigendian() {
- unsigned i = 1;
- char *c;
- c = (char*)&i;
- return (c[0] == 1 ? 0 : 1);
-}
-
-
-/*
- * algorithm for sanity-checking a tpl image:
- * scan the tpl whilst not exceeding the buffer size (bufsz) ,
- * formulating a calculated (expected) size of the tpl based
- * on walking its data. When calcsize has been calculated it
- * should exactly match the buffer size (bufsz) and the internal
- * recorded size (intlsz)
- */
-static int tpl_sanity(tpl_node *r, int excess_ok) {
- uint32_t intlsz;
- int found_nul=0,rc, octothorpes=0, num_fxlens, *fxlens, flen;
- void *d, *dv;
- char intlflags, *fmt, c, *mapfmt;
- size_t bufsz, serlen;
-
- d = ((tpl_root_data*)(r->data))->mmap.text;
- bufsz = ((tpl_root_data*)(r->data))->mmap.text_sz;
-
- dv = d;
- if (bufsz < (4 + sizeof(uint32_t) + 1)) return ERR_NOT_MINSIZE; /* min sz: magic+flags+len+nul */
- if (memcmp(dv,TPL_MAGIC, 3) != 0) return ERR_MAGIC_MISMATCH; /* missing tpl magic prefix */
- if (tpl_needs_endian_swap(dv)) ((tpl_root_data*)(r->data))->flags |= TPL_XENDIAN;
- dv = (void*)((uintptr_t)dv + 3);
- memcpy(&intlflags,dv,sizeof(char)); /* extract flags */
- if (intlflags & ~TPL_SUPPORTED_BITFLAGS) return ERR_UNSUPPORTED_FLAGS;
- /* TPL1.3 stores strings with a "length+1" prefix to discern NULL strings from
- empty strings from non-empty strings; TPL1.2 only handled the latter two.
- So we need to be mindful of which string format we're reading from. */
- if (!(intlflags & TPL_FL_NULLSTRINGS)) {
- ((tpl_root_data*)(r->data))->flags |= TPL_OLD_STRING_FMT;
- }
- dv = (void*)((uintptr_t)dv + 1);
- memcpy(&intlsz,dv,sizeof(uint32_t)); /* extract internal size */
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&intlsz, sizeof(uint32_t));
- if (!excess_ok && (intlsz != bufsz)) return ERR_INCONSISTENT_SZ; /* inconsisent buffer/internal size */
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
-
- /* dv points to the start of the format string. Look for nul w/in buf sz */
- fmt = (char*)dv;
- while ((uintptr_t)dv-(uintptr_t)d < bufsz && !found_nul) {
- if ( (c = *(char*)dv) != '\0') {
- if (strchr(tpl_fmt_chars,c) == NULL)
- return ERR_FMT_INVALID; /* invalid char in format string */
- if ( (c = *(char*)dv) == '#') octothorpes++;
- dv = (void*)((uintptr_t)dv + 1);
- }
- else found_nul = 1;
- }
- if (!found_nul) return ERR_FMT_MISSING_NUL; /* runaway format string */
- dv = (void*)((uintptr_t)dv + 1); /* advance to octothorpe lengths buffer */
-
- /* compare the map format to the format of this tpl image */
- mapfmt = tpl_fmt(r);
- rc = strcmp(mapfmt,fmt);
- if (rc != 0) return ERR_FMT_MISMATCH;
-
- /* compare octothorpe lengths in image to the mapped values */
- if ((((uintptr_t)dv + (octothorpes * 4)) - (uintptr_t)d) > bufsz) return ERR_INCONSISTENT_SZ4;
- fxlens = tpl_fxlens(r,&num_fxlens); /* mapped fxlens */
- while(num_fxlens--) {
- memcpy(&flen,dv,sizeof(uint32_t)); /* stored flen */
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) tpl_byteswap(&flen, sizeof(uint32_t));
- if (flen != *fxlens) return ERR_FLEN_MISMATCH;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- fxlens++;
- }
-
- /* dv now points to beginning of data */
- rc = tpl_serlen(r,r,dv,&serlen); /* get computed serlen of data part */
- if (rc == -1) return ERR_INCONSISTENT_SZ2; /* internal inconsistency in tpl image */
- serlen += ((uintptr_t)dv - (uintptr_t)d); /* add back serlen of preamble part */
- if (excess_ok && (bufsz < serlen)) return ERR_INCONSISTENT_SZ3;
- if (!excess_ok && (serlen != bufsz)) return ERR_INCONSISTENT_SZ3; /* buffer/internal sz exceeds serlen */
- return 0;
-}
-
-static void *tpl_find_data_start(void *d) {
- int octothorpes=0;
- d = (void*)((uintptr_t)d + 4); /* skip TPL_MAGIC and flags byte */
- d = (void*)((uintptr_t)d + 4); /* skip int32 overall len */
- while(*(char*)d != '\0') {
- if (*(char*)d == '#') octothorpes++;
- d = (void*)((uintptr_t)d + 1);
- }
- d = (void*)((uintptr_t)d + 1); /* skip NUL */
- d = (void*)((uintptr_t)d + (octothorpes * sizeof(uint32_t))); /* skip # array lens */
- return d;
-}
-
-static int tpl_needs_endian_swap(void *d) {
- char *c;
- int cpu_is_bigendian;
- c = (char*)d;
- cpu_is_bigendian = tpl_cpu_bigendian();
- return ((c[3] & TPL_FL_BIGENDIAN) == cpu_is_bigendian) ? 0 : 1;
-}
-
-static size_t tpl_size_for(char c) {
- int i;
- for(i=0; i < sizeof(tpl_types)/sizeof(tpl_types[0]); i++) {
- if (tpl_types[i].c == c) return tpl_types[i].sz;
- }
- return 0;
-}
-
-TPL_API char* tpl_peek(int mode, ...) {
- va_list ap;
- int xendian=0,found_nul=0,old_string_format=0;
- char *filename=NULL, *datapeek_f=NULL, *datapeek_c, *datapeek_s;
- void *addr=NULL, *dv, *datapeek_p=NULL;
- size_t sz=0, fmt_len, first_atom, num_fxlens=0;
- uint32_t datapeek_ssz, datapeek_csz, datapeek_flen;
- tpl_mmap_rec mr = {0,NULL,0};
- char *fmt,*fmt_cpy=NULL,c;
- uint32_t intlsz, **fxlens=NULL, *num_fxlens_out=NULL, *fxlensv;
-
- va_start(ap,mode);
- if ((mode & TPL_FXLENS) && (mode & TPL_DATAPEEK)) {
- tpl_hook.oops("TPL_FXLENS and TPL_DATAPEEK mutually exclusive\n");
- goto fail;
- }
- if (mode & TPL_FILE) filename = va_arg(ap,char *);
- else if (mode & TPL_MEM) {
- addr = va_arg(ap,void *);
- sz = va_arg(ap,size_t);
- } else {
- tpl_hook.oops("unsupported tpl_peek mode %d\n", mode);
- goto fail;
- }
- if (mode & TPL_DATAPEEK) {
- datapeek_f = va_arg(ap, char*);
- }
- if (mode & TPL_FXLENS) {
- num_fxlens_out = va_arg(ap,uint32_t *);
- fxlens = va_arg(ap,uint32_t **);
- *num_fxlens_out = 0;
- *fxlens = NULL;
- }
-
- if (mode & TPL_FILE) {
- if (tpl_mmap_file(filename, &mr) != 0) {
- tpl_hook.oops("tpl_peek failed for file %s\n", filename);
- goto fail;
- }
- addr = mr.text;
- sz = mr.text_sz;
- }
-
- dv = addr;
- if (sz < (4 + sizeof(uint32_t) + 1)) goto fail; /* min sz */
- if (memcmp(dv,TPL_MAGIC, 3) != 0) goto fail; /* missing tpl magic prefix */
- if (tpl_needs_endian_swap(dv)) xendian=1;
- if ((((char*)dv)[3] & TPL_FL_NULLSTRINGS)==0) old_string_format=1;
- dv = (void*)((uintptr_t)dv + 4);
- memcpy(&intlsz,dv,sizeof(uint32_t)); /* extract internal size */
- if (xendian) tpl_byteswap(&intlsz, sizeof(uint32_t));
- if (intlsz != sz) goto fail; /* inconsisent buffer/internal size */
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
-
- /* dv points to the start of the format string. Look for nul w/in buf sz */
- fmt = (char*)dv;
- while ((uintptr_t)dv-(uintptr_t)addr < sz && !found_nul) {
- if ( (c = *(char*)dv) == '\0') {
- found_nul = 1;
- } else if (c == '#') {
- num_fxlens++;
- }
- dv = (void*)((uintptr_t)dv + 1);
- }
- if (!found_nul) goto fail; /* runaway format string */
- fmt_len = (char*)dv - fmt; /* include space for \0 */
- fmt_cpy = tpl_hook.malloc(fmt_len);
- if (fmt_cpy == NULL) {
- fatal_oom();
- }
- memcpy(fmt_cpy, fmt, fmt_len);
-
- /* retrieve the octothorpic lengths if requested */
- if (num_fxlens > 0) {
- if (sz < ((uintptr_t)dv + (num_fxlens * sizeof(uint32_t)) - (uintptr_t)addr)) {
- goto fail;
- }
- }
- if ((mode & TPL_FXLENS) && (num_fxlens > 0)) {
- *fxlens = tpl_hook.malloc(num_fxlens * sizeof(uint32_t));
- if (*fxlens == NULL) tpl_hook.fatal("out of memory");
- *num_fxlens_out = num_fxlens;
- fxlensv = *fxlens;
- while(num_fxlens--) {
- memcpy(fxlensv,dv,sizeof(uint32_t));
- if (xendian) tpl_byteswap(fxlensv, sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- fxlensv++;
- }
- }
- /* if caller requested, peek into the specified data elements */
- if (mode & TPL_DATAPEEK) {
-
- first_atom = strspn(fmt, "S()"); /* skip any leading S() */
-
- datapeek_flen = strlen(datapeek_f);
- if (strspn(datapeek_f, tpl_datapeek_ok_chars) < datapeek_flen) {
- tpl_hook.oops("invalid TPL_DATAPEEK format: %s\n", datapeek_f);
- tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */
- goto fail;
- }
-
- if (strncmp( &fmt[first_atom], datapeek_f, datapeek_flen) != 0) {
- tpl_hook.oops("TPL_DATAPEEK format mismatches tpl iamge\n");
- tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */
- goto fail;
- }
-
- /* advance to data start, then copy out requested elements */
- dv = (void*)((uintptr_t)dv + (num_fxlens * sizeof(uint32_t)));
- for(datapeek_c = datapeek_f; *datapeek_c != '\0'; datapeek_c++) {
- datapeek_p = va_arg(ap, void*);
- if (*datapeek_c == 's') { /* special handling for strings */
- if ((uintptr_t)dv-(uintptr_t)addr + sizeof(uint32_t) > sz) {
- tpl_hook.oops("tpl_peek: tpl has insufficient length\n");
- tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */
- goto fail;
- }
- memcpy(&datapeek_ssz,dv,sizeof(uint32_t)); /* get slen */
- if (xendian) tpl_byteswap(&datapeek_ssz, sizeof(uint32_t));
- if (old_string_format) datapeek_ssz++;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t)); /* adv. to str */
- if (datapeek_ssz == 0) datapeek_s = NULL;
- else {
- if ((uintptr_t)dv-(uintptr_t)addr + datapeek_ssz-1 > sz) {
- tpl_hook.oops("tpl_peek: tpl has insufficient length\n");
- tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */
- goto fail;
- }
- datapeek_s = tpl_hook.malloc(datapeek_ssz);
- if (datapeek_s == NULL) fatal_oom();
- memcpy(datapeek_s, dv, datapeek_ssz-1);
- datapeek_s[datapeek_ssz-1] = '\0';
- dv = (void*)((uintptr_t)dv + datapeek_ssz-1);
- }
- *(char**)datapeek_p = datapeek_s;
- } else {
- datapeek_csz = tpl_size_for(*datapeek_c);
- if ((uintptr_t)dv-(uintptr_t)addr + datapeek_csz > sz) {
- tpl_hook.oops("tpl_peek: tpl has insufficient length\n");
- tpl_hook.free(fmt_cpy); fmt_cpy = NULL; /* fail */
- goto fail;
- }
- memcpy(datapeek_p, dv, datapeek_csz);
- if (xendian) tpl_byteswap(datapeek_p, datapeek_csz);
- dv = (void*)((uintptr_t)dv + datapeek_csz);
- }
- }
- }
-
-fail:
- va_end(ap);
- if ((mode & TPL_FILE) && mr.text != NULL) tpl_unmap_file( &mr );
- return fmt_cpy;
-}
-
-/* tpl_jot(TPL_FILE, "file.tpl", "si", &s, &i); */
-/* tpl_jot(TPL_MEM, &buf, &sz, "si", &s, &i); */
-/* tpl_jot(TPL_FD, fd, "si", &s, &i); */
-TPL_API int tpl_jot(int mode, ...) {
- va_list ap;
- char *filename, *fmt;
- size_t *sz;
- int fd, rc=0;
- void **buf;
- tpl_node *tn;
-
- va_start(ap,mode);
- if (mode & TPL_FILE) {
- filename = va_arg(ap,char*);
- fmt = va_arg(ap,char*);
- tn = tpl_map_va(fmt, ap);
- if (tn == NULL) { rc=-1; goto fail;}
- tpl_pack(tn, 0);
- rc = tpl_dump(tn, TPL_FILE, filename);
- tpl_free(tn);
- } else if (mode & TPL_MEM) {
- buf = va_arg(ap,void*);
- sz = va_arg(ap,size_t*);
- fmt = va_arg(ap,char*);
- tn = tpl_map_va(fmt,ap);
- if (tn == NULL) { rc=-1; goto fail;}
- tpl_pack(tn,0);
- rc = tpl_dump(tn, TPL_MEM, buf, sz);
- tpl_free(tn);
- } else if (mode & TPL_FD) {
- fd = va_arg(ap,int);
- fmt = va_arg(ap,char*);
- tn = tpl_map_va(fmt,ap);
- if (tn == NULL) { rc=-1; goto fail;}
- tpl_pack(tn,0);
- rc = tpl_dump(tn, TPL_FD, fd);
- tpl_free(tn);
- } else {
- tpl_hook.fatal("invalid tpl_jot mode\n");
- }
-
-fail:
- va_end(ap);
- return rc;
-}
-
-TPL_API int tpl_load(tpl_node *r, int mode, ...) {
- va_list ap;
- int rc=0,fd=0;
- char *filename=NULL;
- void *addr;
- size_t sz;
-
- va_start(ap,mode);
- if (mode & TPL_FILE) filename = va_arg(ap,char *);
- else if (mode & TPL_MEM) {
- addr = va_arg(ap,void *);
- sz = va_arg(ap,size_t);
- } else if (mode & TPL_FD) {
- fd = va_arg(ap,int);
- } else {
- tpl_hook.oops("unsupported tpl_load mode %d\n", mode);
- return -1;
- }
- va_end(ap);
-
- if (r->type != TPL_TYPE_ROOT) {
- tpl_hook.oops("error: tpl_load to non-root node\n");
- return -1;
- }
- if (((tpl_root_data*)(r->data))->flags & (TPL_WRONLY|TPL_RDONLY)) {
- /* already packed or loaded, so reset it as if newly mapped */
- tpl_free_keep_map(r);
- }
- if (mode & TPL_FILE) {
- if (tpl_mmap_file(filename, &((tpl_root_data*)(r->data))->mmap) != 0) {
- tpl_hook.oops("tpl_load failed for file %s\n", filename);
- return -1;
- }
- if ( (rc = tpl_sanity(r, (mode & TPL_EXCESS_OK))) != 0) {
- if (rc == ERR_FMT_MISMATCH) {
- tpl_hook.oops("%s: format signature mismatch\n", filename);
- } else if (rc == ERR_FLEN_MISMATCH) {
- tpl_hook.oops("%s: array lengths mismatch\n", filename);
- } else {
- tpl_hook.oops("%s: not a valid tpl file\n", filename);
- }
- tpl_unmap_file( &((tpl_root_data*)(r->data))->mmap );
- return -1;
- }
- ((tpl_root_data*)(r->data))->flags = (TPL_FILE | TPL_RDONLY);
- } else if (mode & TPL_MEM) {
- ((tpl_root_data*)(r->data))->mmap.text = addr;
- ((tpl_root_data*)(r->data))->mmap.text_sz = sz;
- if ( (rc = tpl_sanity(r, (mode & TPL_EXCESS_OK))) != 0) {
- if (rc == ERR_FMT_MISMATCH) {
- tpl_hook.oops("format signature mismatch\n");
- } else {
- tpl_hook.oops("not a valid tpl file\n");
- }
- return -1;
- }
- ((tpl_root_data*)(r->data))->flags = (TPL_MEM | TPL_RDONLY);
- if (mode & TPL_UFREE) ((tpl_root_data*)(r->data))->flags |= TPL_UFREE;
- } else if (mode & TPL_FD) {
- /* if fd read succeeds, resulting mem img is used for load */
- if (tpl_gather(TPL_GATHER_BLOCKING,fd,&addr,&sz) > 0) {
- return tpl_load(r, TPL_MEM|TPL_UFREE, addr, sz);
- } else return -1;
- } else {
- tpl_hook.oops("invalid tpl_load mode %d\n", mode);
- return -1;
- }
- /* this applies to TPL_MEM or TPL_FILE */
- if (tpl_needs_endian_swap(((tpl_root_data*)(r->data))->mmap.text))
- ((tpl_root_data*)(r->data))->flags |= TPL_XENDIAN;
- tpl_unpackA0(r); /* prepare root A nodes for use */
- return 0;
-}
-
-TPL_API int tpl_Alen(tpl_node *r, int i) {
- tpl_node *n;
-
- n = tpl_find_i(r,i);
- if (n == NULL) {
- tpl_hook.oops("invalid index %d to tpl_unpack\n", i);
- return -1;
- }
- if (n->type != TPL_TYPE_ARY) return -1;
- return ((tpl_atyp*)(n->data))->num;
-}
-
-static void tpl_free_atyp(tpl_node *n, tpl_atyp *atyp) {
- tpl_backbone *bb,*bbnxt;
- tpl_node *c;
- void *dv;
- tpl_bin *binp;
- tpl_atyp *atypp;
- char *strp;
- size_t itermax;
- tpl_pound_data *pd;
- int i;
-
- bb = atyp->bb;
- while (bb) {
- bbnxt = bb->next;
- dv = bb->data;
- c=n->children;
- while (c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz*c->num);
- break;
- case TPL_TYPE_BIN:
- memcpy(&binp,dv,sizeof(tpl_bin*)); /* cp to aligned */
- if (binp->addr) tpl_hook.free( binp->addr ); /* free buf */
- tpl_hook.free(binp); /* free tpl_bin */
- dv = (void*)((uintptr_t)dv + sizeof(tpl_bin*));
- break;
- case TPL_TYPE_STR:
- for(i=0; i < c->num; i++) {
- memcpy(&strp,dv,sizeof(char*)); /* cp to aligned */
- if (strp) tpl_hook.free(strp); /* free string */
- dv = (void*)((uintptr_t)dv + sizeof(char*));
- }
- break;
- case TPL_TYPE_POUND:
- /* iterate over the preceding nodes */
- itermax = c->num;
- pd = (tpl_pound_data*)c->data;
- if (++(pd->iternum) < itermax) {
- c = pd->iter_start_node;
- continue;
- } else { /* loop complete. */
- pd->iternum = 0;
- }
- break;
- case TPL_TYPE_ARY:
- memcpy(&atypp,dv,sizeof(tpl_atyp*)); /* cp to aligned */
- tpl_free_atyp(c,atypp); /* free atyp */
- dv = (void*)((uintptr_t)dv + sizeof(void*));
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- c=c->next;
- }
- tpl_hook.free(bb);
- bb = bbnxt;
- }
- tpl_hook.free(atyp);
-}
-
-/* determine (by walking) byte length of serialized r/A node at address dv
- * returns 0 on success, or -1 if the tpl isn't trustworthy (fails consistency)
- */
-static int tpl_serlen(tpl_node *r, tpl_node *n, void *dv, size_t *serlen) {
- uint32_t slen;
- int num = 0,fidx;
- tpl_node *c;
- size_t len=0, alen, buf_past, itermax;
- tpl_pound_data *pd;
-
- buf_past = ((uintptr_t)((tpl_root_data*)(r->data))->mmap.text +
- ((tpl_root_data*)(r->data))->mmap.text_sz);
-
- if (n->type == TPL_TYPE_ROOT) num = 1;
- else if (n->type == TPL_TYPE_ARY) {
- if ((uintptr_t)dv + sizeof(uint32_t) > buf_past) return -1;
- memcpy(&num,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&num, sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- len += sizeof(uint32_t);
- } else tpl_hook.fatal("internal error in tpl_serlen\n");
-
- while (num-- > 0) {
- c=n->children;
- while (c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- for(fidx=0; fidx < c->num; fidx++) { /* octothorpe support */
- if ((uintptr_t)dv + tpl_types[c->type].sz > buf_past) return -1;
- dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz);
- len += tpl_types[c->type].sz;
- }
- break;
- case TPL_TYPE_BIN:
- len += sizeof(uint32_t);
- if ((uintptr_t)dv + sizeof(uint32_t) > buf_past) return -1;
- memcpy(&slen,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&slen, sizeof(uint32_t));
- len += slen;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- if ((uintptr_t)dv + slen > buf_past) return -1;
- dv = (void*)((uintptr_t)dv + slen);
- break;
- case TPL_TYPE_STR:
- for(fidx=0; fidx < c->num; fidx++) { /* octothorpe support */
- len += sizeof(uint32_t);
- if ((uintptr_t)dv + sizeof(uint32_t) > buf_past) return -1;
- memcpy(&slen,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&slen, sizeof(uint32_t));
- if (!(((tpl_root_data*)(r->data))->flags & TPL_OLD_STRING_FMT))
- slen = (slen>1) ? (slen-1) : 0;
- len += slen;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- if ((uintptr_t)dv + slen > buf_past) return -1;
- dv = (void*)((uintptr_t)dv + slen);
- }
- break;
- case TPL_TYPE_ARY:
- if ( tpl_serlen(r,c,dv, &alen) == -1) return -1;
- dv = (void*)((uintptr_t)dv + alen);
- len += alen;
- break;
- case TPL_TYPE_POUND:
- /* iterate over the preceding nodes */
- itermax = c->num;
- pd = (tpl_pound_data*)c->data;
- if (++(pd->iternum) < itermax) {
- c = pd->iter_start_node;
- continue;
- } else { /* loop complete. */
- pd->iternum = 0;
- }
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- c=c->next;
- }
- }
- *serlen = len;
- return 0;
-}
-
-static int tpl_mmap_output_file(char *filename, size_t sz, void **text_out) {
- void *text;
- int fd,perms;
-
-#ifndef _WIN32
- perms = S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH; /* ug+w o+r */
- fd=open(filename,O_CREAT|O_TRUNC|O_RDWR,perms);
-#else
- perms = _S_IWRITE;
- fd=_open(filename,_O_CREAT|_O_TRUNC|_O_RDWR,perms);
-#endif
-
- if ( fd == -1 ) {
- tpl_hook.oops("Couldn't open file %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- text = mmap(0, sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (text == MAP_FAILED) {
- tpl_hook.oops("Failed to mmap %s: %s\n", filename, strerror(errno));
- close(fd);
- return -1;
- }
- if (ftruncate(fd,sz) == -1) {
- tpl_hook.oops("ftruncate failed: %s\n", strerror(errno));
- munmap( text, sz );
- close(fd);
- return -1;
- }
- *text_out = text;
- return fd;
-}
-
-static int tpl_mmap_file(char *filename, tpl_mmap_rec *mr) {
- struct stat stat_buf;
-
- if ( (mr->fd = open(filename, O_RDONLY)) == -1 ) {
- tpl_hook.oops("Couldn't open file %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- if ( fstat(mr->fd, &stat_buf) == -1) {
- close(mr->fd);
- tpl_hook.oops("Couldn't stat file %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- mr->text_sz = (size_t)stat_buf.st_size;
- mr->text = mmap(0, stat_buf.st_size, PROT_READ, MAP_PRIVATE, mr->fd, 0);
- if (mr->text == MAP_FAILED) {
- close(mr->fd);
- tpl_hook.oops("Failed to mmap %s: %s\n", filename, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-TPL_API int tpl_pack(tpl_node *r, int i) {
- tpl_node *n, *child, *np;
- void *datav=NULL;
- size_t sz, itermax;
- uint32_t slen;
- char *str;
- tpl_bin *bin;
- tpl_pound_data *pd;
- int fidx;
-
- n = tpl_find_i(r,i);
- if (n == NULL) {
- tpl_hook.oops("invalid index %d to tpl_pack\n", i);
- return -1;
- }
-
- if (((tpl_root_data*)(r->data))->flags & TPL_RDONLY) {
- /* convert to an writeable tpl, initially empty */
- tpl_free_keep_map(r);
- }
-
- ((tpl_root_data*)(r->data))->flags |= TPL_WRONLY;
-
- if (n->type == TPL_TYPE_ARY) datav = tpl_extend_backbone(n);
- child = n->children;
- while(child) {
- switch(child->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- /* no need to use fidx iteration here; we can copy multiple values in one memcpy */
- memcpy(child->data,child->addr,tpl_types[child->type].sz * child->num);
- if (datav) datav = tpl_cpv(datav,child->data,tpl_types[child->type].sz * child->num);
- if (n->type == TPL_TYPE_ARY) n->ser_osz += tpl_types[child->type].sz * child->num;
- break;
- case TPL_TYPE_BIN:
- /* copy the buffer to be packed */
- slen = ((tpl_bin*)child->addr)->sz;
- if (slen >0) {
- str = tpl_hook.malloc(slen);
- if (!str) fatal_oom();
- memcpy(str,((tpl_bin*)child->addr)->addr,slen);
- } else str = NULL;
- /* and make a tpl_bin to point to it */
- bin = tpl_hook.malloc(sizeof(tpl_bin));
- if (!bin) fatal_oom();
- bin->addr = str;
- bin->sz = slen;
- /* now pack its pointer, first deep freeing any pre-existing bin */
- if (*(tpl_bin**)(child->data) != NULL) {
- if ((*(tpl_bin**)(child->data))->sz != 0) {
- tpl_hook.free( (*(tpl_bin**)(child->data))->addr );
- }
- tpl_hook.free(*(tpl_bin**)(child->data));
- }
- memcpy(child->data,&bin,sizeof(tpl_bin*));
- if (datav) {
- datav = tpl_cpv(datav, &bin, sizeof(tpl_bin*));
- *(tpl_bin**)(child->data) = NULL;
- }
- if (n->type == TPL_TYPE_ARY) {
- n->ser_osz += sizeof(uint32_t); /* binary buf len word */
- n->ser_osz += bin->sz; /* binary buf */
- }
- break;
- case TPL_TYPE_STR:
- for(fidx=0; fidx < child->num; fidx++) {
- /* copy the string to be packed. slen includes \0. this
- block also works if the string pointer is NULL. */
- char *caddr = ((char**)child->addr)[fidx];
- char **cdata = &((char**)child->data)[fidx];
- slen = caddr ? (strlen(caddr) + 1) : 0;
- if (slen) {
- str = tpl_hook.malloc(slen);
- if (!str) fatal_oom();
- memcpy(str,caddr,slen); /* include \0 */
- } else {
- str = NULL;
- }
- /* now pack its pointer, first freeing any pre-existing string */
- if (*cdata != NULL) {
- tpl_hook.free(*cdata);
- }
- memcpy(cdata,&str,sizeof(char*));
- if (datav) {
- datav = tpl_cpv(datav, &str, sizeof(char*));
- *cdata = NULL;
- }
- if (n->type == TPL_TYPE_ARY) {
- n->ser_osz += sizeof(uint32_t); /* string len word */
- if (slen>1) n->ser_osz += slen-1;/* string (without nul) */
- }
- }
- break;
- case TPL_TYPE_ARY:
- /* copy the child's tpl_atype* and reset it to empty */
- if (datav) {
- sz = ((tpl_atyp*)(child->data))->sz;
- datav = tpl_cpv(datav, &child->data, sizeof(void*));
- child->data = tpl_hook.malloc(sizeof(tpl_atyp));
- if (!child->data) fatal_oom();
- ((tpl_atyp*)(child->data))->num = 0;
- ((tpl_atyp*)(child->data))->sz = sz;
- ((tpl_atyp*)(child->data))->bb = NULL;
- ((tpl_atyp*)(child->data))->bbtail = NULL;
- }
- /* parent is array? then bubble up child array's ser_osz */
- if (n->type == TPL_TYPE_ARY) {
- n->ser_osz += sizeof(uint32_t); /* array len word */
- n->ser_osz += child->ser_osz; /* child array ser_osz */
- child->ser_osz = 0; /* reset child array ser_osz */
- }
- break;
-
- case TPL_TYPE_POUND:
- /* we need to iterate n times over preceding nodes in S(...).
- * we may be in the midst of an iteration each time or starting. */
- pd = (tpl_pound_data*)child->data;
- itermax = child->num;
-
- /* itermax is total num of iterations needed */
- /* pd->iternum is current iteration index */
- /* pd->inter_elt_len is element-to-element len of contiguous structs */
- /* pd->iter_start_node is where we jump to at each iteration. */
-
- if (++(pd->iternum) < itermax) {
-
- /* in start or midst of loop. advance addr/data pointers. */
- for(np=pd->iter_start_node; np != child; np = np->next) {
- np->data = (char*)(np->data) +
- (tpl_types[np->type].sz * np->num);
- np->addr = (char*)(np->addr) + pd->inter_elt_len;
- }
- /* do next iteration */
- child = pd->iter_start_node;
- continue;
-
- } else { /* loop complete. */
-
- /* reset iteration index and addr/data pointers. */
- pd->iternum = 0;
- for(np=pd->iter_start_node; np != child; np = np->next) {
- np->data = (char*)(np->data) - ((itermax-1) *
- tpl_types[np->type].sz *
- np->num);
- np->addr = (char*)(np->addr) - ((itermax-1) * pd->inter_elt_len);
- }
-
- }
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- child=child->next;
- }
- return 0;
-}
-
-TPL_API int tpl_unpack(tpl_node *r, int i) {
- tpl_node *n, *c, *np;
- uint32_t slen;
- int rc=1, fidx;
- char *str;
- void *dv=NULL, *caddr;
- size_t A_bytes, itermax;
- tpl_pound_data *pd;
- void *img;
- size_t sz;
-
-
- /* handle unusual case of tpl_pack,tpl_unpack without an
- * intervening tpl_dump. do a dump/load implicitly. */
- if (((tpl_root_data*)(r->data))->flags & TPL_WRONLY) {
- if (tpl_dump(r,TPL_MEM,&img,&sz) != 0) return -1;
- if (tpl_load(r,TPL_MEM|TPL_UFREE,img,sz) != 0) {
- tpl_hook.free(img);
- return -1;
- };
- }
-
- n = tpl_find_i(r,i);
- if (n == NULL) {
- tpl_hook.oops("invalid index %d to tpl_unpack\n", i);
- return -1;
- }
-
- /* either root node or an A node */
- if (n->type == TPL_TYPE_ROOT) {
- dv = tpl_find_data_start( ((tpl_root_data*)(n->data))->mmap.text );
- } else if (n->type == TPL_TYPE_ARY) {
- if (((tpl_atyp*)(n->data))->num <= 0) return 0; /* array consumed */
- else rc = ((tpl_atyp*)(n->data))->num--;
- dv = ((tpl_atyp*)(n->data))->cur;
- if (!dv) tpl_hook.fatal("must unpack parent of node before node itself\n");
- }
-
- c = n->children;
- while (c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- /* unpack elements of cross-endian octothorpic array individually */
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN) {
- for(fidx=0; fidx < c->num; fidx++) {
- caddr = (void*)((uintptr_t)c->addr + (fidx * tpl_types[c->type].sz));
- memcpy(caddr,dv,tpl_types[c->type].sz);
- tpl_byteswap(caddr, tpl_types[c->type].sz);
- dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz);
- }
- } else {
- /* bulk unpack ok if not cross-endian */
- memcpy(c->addr, dv, tpl_types[c->type].sz * c->num);
- dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz * c->num);
- }
- break;
- case TPL_TYPE_BIN:
- memcpy(&slen,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&slen, sizeof(uint32_t));
- if (slen > 0) {
- str = (char*)tpl_hook.malloc(slen);
- if (!str) fatal_oom();
- } else str=NULL;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- if (slen>0) memcpy(str,dv,slen);
- memcpy(&(((tpl_bin*)c->addr)->addr),&str,sizeof(void*));
- memcpy(&(((tpl_bin*)c->addr)->sz),&slen,sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + slen);
- break;
- case TPL_TYPE_STR:
- for(fidx=0; fidx < c->num; fidx++) {
- memcpy(&slen,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&slen, sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_OLD_STRING_FMT)
- slen += 1;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- if (slen) { /* slen includes \0 */
- str = (char*)tpl_hook.malloc(slen);
- if (!str) fatal_oom();
- if (slen>1) memcpy(str,dv,slen-1);
- str[slen-1] = '\0'; /* nul terminate */
- dv = (void*)((uintptr_t)dv + slen-1);
- } else str=NULL;
- memcpy(&((char**)c->addr)[fidx],&str,sizeof(char*));
- }
- break;
- case TPL_TYPE_POUND:
- /* iterate over preceding nodes */
- pd = (tpl_pound_data*)c->data;
- itermax = c->num;
- if (++(pd->iternum) < itermax) {
- /* in start or midst of loop. advance addr/data pointers. */
- for(np=pd->iter_start_node; np != c; np = np->next) {
- np->addr = (char*)(np->addr) + pd->inter_elt_len;
- }
- /* do next iteration */
- c = pd->iter_start_node;
- continue;
-
- } else { /* loop complete. */
-
- /* reset iteration index and addr/data pointers. */
- pd->iternum = 0;
- for(np=pd->iter_start_node; np != c; np = np->next) {
- np->addr = (char*)(np->addr) - ((itermax-1) * pd->inter_elt_len);
- }
-
- }
- break;
- case TPL_TYPE_ARY:
- if (tpl_serlen(r,c,dv, &A_bytes) == -1)
- tpl_hook.fatal("internal error in unpack\n");
- memcpy( &((tpl_atyp*)(c->data))->num, dv, sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&((tpl_atyp*)(c->data))->num, sizeof(uint32_t));
- ((tpl_atyp*)(c->data))->cur = (void*)((uintptr_t)dv+sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + A_bytes);
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
-
- c = c->next;
- }
- if (n->type == TPL_TYPE_ARY) ((tpl_atyp*)(n->data))->cur = dv; /* next element */
- return rc;
-}
-
-/* Specialized function that unpacks only the root's A nodes, after tpl_load */
-static int tpl_unpackA0(tpl_node *r) {
- tpl_node *n, *c;
- uint32_t slen;
- int rc=1,fidx,i;
- void *dv;
- size_t A_bytes, itermax;
- tpl_pound_data *pd;
-
- n = r;
- dv = tpl_find_data_start( ((tpl_root_data*)(r->data))->mmap.text);
-
- c=n->children;
- while (c) {
- switch (c->type) {
- case TPL_TYPE_BYTE:
- case TPL_TYPE_DOUBLE:
- case TPL_TYPE_INT32:
- case TPL_TYPE_UINT32:
- case TPL_TYPE_INT64:
- case TPL_TYPE_UINT64:
- case TPL_TYPE_INT16:
- case TPL_TYPE_UINT16:
- for(fidx=0;fidx < c->num; fidx++) {
- dv = (void*)((uintptr_t)dv + tpl_types[c->type].sz);
- }
- break;
- case TPL_TYPE_BIN:
- memcpy(&slen,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&slen, sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + slen);
- break;
- case TPL_TYPE_STR:
- for(i=0; i<c->num; i++) {
- memcpy(&slen,dv,sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&slen, sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_OLD_STRING_FMT)
- slen += 1;
- dv = (void*)((uintptr_t)dv + sizeof(uint32_t));
- if (slen>1) dv = (void*)((uintptr_t)dv + slen-1);
- }
- break;
- case TPL_TYPE_POUND:
- /* iterate over the preceding nodes */
- itermax = c->num;
- pd = (tpl_pound_data*)c->data;
- if (++(pd->iternum) < itermax) {
- c = pd->iter_start_node;
- continue;
- } else { /* loop complete. */
- pd->iternum = 0;
- }
- break;
- case TPL_TYPE_ARY:
- if ( tpl_serlen(r,c,dv, &A_bytes) == -1)
- tpl_hook.fatal("internal error in unpackA0\n");
- memcpy( &((tpl_atyp*)(c->data))->num, dv, sizeof(uint32_t));
- if (((tpl_root_data*)(r->data))->flags & TPL_XENDIAN)
- tpl_byteswap(&((tpl_atyp*)(c->data))->num, sizeof(uint32_t));
- ((tpl_atyp*)(c->data))->cur = (void*)((uintptr_t)dv+sizeof(uint32_t));
- dv = (void*)((uintptr_t)dv + A_bytes);
- break;
- default:
- tpl_hook.fatal("unsupported format character\n");
- break;
- }
- c=c->next;
- }
- return rc;
-}
-
-/* In-place byte order swapping of a word of length "len" bytes */
-static void tpl_byteswap(void *word, int len) {
- int i;
- char c, *w;
- w = (char*)word;
- for(i=0; i<len/2; i++) {
- c = w[i];
- w[i] = w[len-1-i];
- w[len-1-i] = c;
- }
-}
-
-static void tpl_fatal(char *fmt, ...) {
- va_list ap;
- char exit_msg[100];
-
- va_start(ap,fmt);
- vsnprintf(exit_msg, 100, fmt, ap);
- va_end(ap);
-
- tpl_hook.oops("%s", exit_msg);
- exit(-1);
-}
-
-TPL_API int tpl_gather(int mode, ...) {
- va_list ap;
- int fd,rc=0;
- size_t *szp,sz;
- void **img,*addr,*data;
- tpl_gather_t **gs;
- tpl_gather_cb *cb;
-
- va_start(ap,mode);
- switch (mode) {
- case TPL_GATHER_BLOCKING:
- fd = va_arg(ap,int);
- img = va_arg(ap,void*);
- szp = va_arg(ap,size_t*);
- rc = tpl_gather_blocking(fd,img,szp);
- break;
- case TPL_GATHER_NONBLOCKING:
- fd = va_arg(ap,int);
- gs = (tpl_gather_t**)va_arg(ap,void*);
- cb = (tpl_gather_cb*)va_arg(ap,tpl_gather_cb*);
- data = va_arg(ap,void*);
- rc = tpl_gather_nonblocking(fd,gs,cb,data);
- break;
- case TPL_GATHER_MEM:
- addr = va_arg(ap,void*);
- sz = va_arg(ap,size_t);
- gs = (tpl_gather_t**)va_arg(ap,void*);
- cb = (tpl_gather_cb*)va_arg(ap,tpl_gather_cb*);
- data = va_arg(ap,void*);
- rc = tpl_gather_mem(addr,sz,gs,cb,data);
- break;
- default:
- tpl_hook.fatal("unsupported tpl_gather mode %d\n",mode);
- break;
- }
- va_end(ap);
- return rc;
-}
-
-/* dequeue a tpl by reading until one full tpl image is obtained.
- * We take care not to read past the end of the tpl.
- * This is intended as a blocking call i.e. for use with a blocking fd.
- * It can be given a non-blocking fd, but the read spins if we have to wait.
- */
-static int tpl_gather_blocking(int fd, void **img, size_t *sz) {
- char preamble[8];
- int i=0, rc;
- uint32_t tpllen;
-
- do {
- rc = read(fd,&preamble[i],8-i);
- i += (rc>0) ? rc : 0;
- } while ((rc==-1 && (errno==EINTR||errno==EAGAIN)) || (rc>0 && i<8));
-
- if (rc<0) {
- tpl_hook.oops("tpl_gather_fd_blocking failed: %s\n", strerror(errno));
- return -1;
- } else if (rc == 0) {
- /* tpl_hook.oops("tpl_gather_fd_blocking: eof\n"); */
- return 0;
- } else if (i != 8) {
- tpl_hook.oops("internal error\n");
- return -1;
- }
-
- if (preamble[0] == 't' && preamble[1] == 'p' && preamble[2] == 'l') {
- memcpy(&tpllen,&preamble[4],4);
- if (tpl_needs_endian_swap(preamble)) tpl_byteswap(&tpllen,4);
- } else {
- tpl_hook.oops("tpl_gather_fd_blocking: non-tpl input\n");
- return -1;
- }
-
- /* malloc space for remainder of tpl image (overall length tpllen)
- * and read it in
- */
- if (tpl_hook.gather_max > 0 &&
- tpllen > tpl_hook.gather_max) {
- tpl_hook.oops("tpl exceeds max length %d\n",
- tpl_hook.gather_max);
- return -2;
- }
- *sz = tpllen;
- if ( (*img = tpl_hook.malloc(tpllen)) == NULL) {
- fatal_oom();
- }
-
- memcpy(*img,preamble,8); /* copy preamble to output buffer */
- i=8;
- do {
- rc = read(fd,&((*(char**)img)[i]),tpllen-i);
- i += (rc>0) ? rc : 0;
- } while ((rc==-1 && (errno==EINTR||errno==EAGAIN)) || (rc>0 && i<tpllen));
-
- if (rc<0) {
- tpl_hook.oops("tpl_gather_fd_blocking failed: %s\n", strerror(errno));
- tpl_hook.free(*img);
- return -1;
- } else if (rc == 0) {
- /* tpl_hook.oops("tpl_gather_fd_blocking: eof\n"); */
- tpl_hook.free(*img);
- return 0;
- } else if (i != tpllen) {
- tpl_hook.oops("internal error\n");
- tpl_hook.free(*img);
- return -1;
- }
-
- return 1;
-}
-
-/* Used by select()-driven apps which want to gather tpl images piecemeal */
-/* the file descriptor must be non-blocking for this functino to work. */
-static int tpl_gather_nonblocking( int fd, tpl_gather_t **gs, tpl_gather_cb *cb, void *data) {
- char buf[TPL_GATHER_BUFLEN], *img, *tpl;
- int rc, keep_looping, cbrc=0;
- size_t catlen;
- uint32_t tpllen;
-
- while (1) {
- rc = read(fd,buf,TPL_GATHER_BUFLEN);
- if (rc == -1) {
- if (errno == EINTR) continue; /* got signal during read, ignore */
- if (errno == EAGAIN) return 1; /* nothing to read right now */
- else {
- tpl_hook.oops("tpl_gather failed: %s\n", strerror(errno));
- if (*gs) {
- tpl_hook.free((*gs)->img);
- tpl_hook.free(*gs);
- *gs = NULL;
- }
- return -1; /* error, caller should close fd */
- }
- } else if (rc == 0) {
- if (*gs) {
- tpl_hook.oops("tpl_gather: partial tpl image precedes EOF\n");
- tpl_hook.free((*gs)->img);
- tpl_hook.free(*gs);
- *gs = NULL;
- }
- return 0; /* EOF, caller should close fd */
- } else {
- /* concatenate any partial tpl from last read with new buffer */
- if (*gs) {
- catlen = (*gs)->len + rc;
- if (tpl_hook.gather_max > 0 &&
- catlen > tpl_hook.gather_max) {
- tpl_hook.free( (*gs)->img );
- tpl_hook.free( (*gs) );
- *gs = NULL;
- tpl_hook.oops("tpl exceeds max length %d\n",
- tpl_hook.gather_max);
- return -2; /* error, caller should close fd */
- }
- if ( (img = tpl_hook.realloc((*gs)->img, catlen)) == NULL) {
- fatal_oom();
- }
- memcpy(img + (*gs)->len, buf, rc);
- tpl_hook.free(*gs);
- *gs = NULL;
- } else {
- img = buf;
- catlen = rc;
- }
- /* isolate any full tpl(s) in img and invoke cb for each */
- tpl = img;
- keep_looping = (tpl+8 < img+catlen) ? 1 : 0;
- while (keep_looping) {
- if (strncmp("tpl", tpl, 3) != 0) {
- tpl_hook.oops("tpl prefix invalid\n");
- if (img != buf) tpl_hook.free(img);
- tpl_hook.free(*gs);
- *gs = NULL;
- return -3; /* error, caller should close fd */
- }
- memcpy(&tpllen,&tpl[4],4);
- if (tpl_needs_endian_swap(tpl)) tpl_byteswap(&tpllen,4);
- if (tpl+tpllen <= img+catlen) {
- cbrc = (cb)(tpl,tpllen,data); /* invoke cb for tpl image */
- tpl += tpllen; /* point to next tpl image */
- if (cbrc < 0) keep_looping = 0;
- else keep_looping = (tpl+8 < img+catlen) ? 1 : 0;
- } else keep_looping=0;
- }
- /* check if app callback requested closure of tpl source */
- if (cbrc < 0) {
- tpl_hook.oops("tpl_fd_gather aborted by app callback\n");
- if (img != buf) tpl_hook.free(img);
- if (*gs) tpl_hook.free(*gs);
- *gs = NULL;
- return -4;
- }
- /* store any leftover, partial tpl fragment for next read */
- if (tpl == img && img != buf) {
- /* consumed nothing from img!=buf */
- if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) {
- fatal_oom();
- }
- (*gs)->img = tpl;
- (*gs)->len = catlen;
- } else if (tpl < img+catlen) {
- /* consumed 1+ tpl(s) from img!=buf or 0 from img==buf */
- if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) {
- fatal_oom();
- }
- if ( ((*gs)->img = tpl_hook.malloc(img+catlen - tpl)) == NULL ) {
- fatal_oom();
- }
- (*gs)->len = img+catlen - tpl;
- memcpy( (*gs)->img, tpl, img+catlen - tpl);
- /* free partially consumed concat buffer if used */
- if (img != buf) tpl_hook.free(img);
- } else { /* tpl(s) fully consumed */
- /* free consumed concat buffer if used */
- if (img != buf) tpl_hook.free(img);
- }
- }
- }
-}
-
-/* gather tpl piecemeal from memory buffer (not fd) e.g., from a lower-level api */
-static int tpl_gather_mem( char *buf, size_t len, tpl_gather_t **gs, tpl_gather_cb *cb, void *data) {
- char *img, *tpl;
- int keep_looping, cbrc=0;
- size_t catlen;
- uint32_t tpllen;
-
- /* concatenate any partial tpl from last read with new buffer */
- if (*gs) {
- catlen = (*gs)->len + len;
- if (tpl_hook.gather_max > 0 &&
- catlen > tpl_hook.gather_max) {
- tpl_hook.free( (*gs)->img );
- tpl_hook.free( (*gs) );
- *gs = NULL;
- tpl_hook.oops("tpl exceeds max length %d\n",
- tpl_hook.gather_max);
- return -2; /* error, caller should stop accepting input from source*/
- }
- if ( (img = tpl_hook.realloc((*gs)->img, catlen)) == NULL) {
- fatal_oom();
- }
- memcpy(img + (*gs)->len, buf, len);
- tpl_hook.free(*gs);
- *gs = NULL;
- } else {
- img = buf;
- catlen = len;
- }
- /* isolate any full tpl(s) in img and invoke cb for each */
- tpl = img;
- keep_looping = (tpl+8 < img+catlen) ? 1 : 0;
- while (keep_looping) {
- if (strncmp("tpl", tpl, 3) != 0) {
- tpl_hook.oops("tpl prefix invalid\n");
- if (img != buf) tpl_hook.free(img);
- tpl_hook.free(*gs);
- *gs = NULL;
- return -3; /* error, caller should stop accepting input from source*/
- }
- memcpy(&tpllen,&tpl[4],4);
- if (tpl_needs_endian_swap(tpl)) tpl_byteswap(&tpllen,4);
- if (tpl+tpllen <= img+catlen) {
- cbrc = (cb)(tpl,tpllen,data); /* invoke cb for tpl image */
- tpl += tpllen; /* point to next tpl image */
- if (cbrc < 0) keep_looping = 0;
- else keep_looping = (tpl+8 < img+catlen) ? 1 : 0;
- } else keep_looping=0;
- }
- /* check if app callback requested closure of tpl source */
- if (cbrc < 0) {
- tpl_hook.oops("tpl_mem_gather aborted by app callback\n");
- if (img != buf) tpl_hook.free(img);
- if (*gs) tpl_hook.free(*gs);
- *gs = NULL;
- return -4;
- }
- /* store any leftover, partial tpl fragment for next read */
- if (tpl == img && img != buf) {
- /* consumed nothing from img!=buf */
- if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) {
- fatal_oom();
- }
- (*gs)->img = tpl;
- (*gs)->len = catlen;
- } else if (tpl < img+catlen) {
- /* consumed 1+ tpl(s) from img!=buf or 0 from img==buf */
- if ( (*gs = tpl_hook.malloc(sizeof(tpl_gather_t))) == NULL ) {
- fatal_oom();
- }
- if ( ((*gs)->img = tpl_hook.malloc(img+catlen - tpl)) == NULL ) {
- fatal_oom();
- }
- (*gs)->len = img+catlen - tpl;
- memcpy( (*gs)->img, tpl, img+catlen - tpl);
- /* free partially consumed concat buffer if used */
- if (img != buf) tpl_hook.free(img);
- } else { /* tpl(s) fully consumed */
- /* free consumed concat buffer if used */
- if (img != buf) tpl_hook.free(img);
- }
- return 1;
-}
+++ /dev/null
-/*
-Copyright (c) 2005-2010, Troy D. Hanson http://tpl.sourceforge.net
-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.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef TPL_H
-#define TPL_H
-
-#include <stddef.h> /* size_t */
-
-#ifdef __INTEL_COMPILER
-#include <tbb/tbbmalloc_proxy.h>
-#endif /* Intel Compiler efficient memcpy etc */
-
-#ifdef _MSC_VER
-typedef unsigned int uint32_t;
-#else
-#include <inttypes.h> /* uint32_t */
-#endif
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-#ifdef _WIN32
-#ifdef TPL_EXPORTS
-#define TPL_API __declspec(dllexport)
-#else /* */
-#ifdef TPL_NOLIB
-#define TPL_API
-#else
-#define TPL_API __declspec(dllimport)
-#endif /* TPL_NOLIB */
-#endif /* TPL_EXPORTS*/
-#else
-#define TPL_API
-#endif
-
-/* bit flags (external) */
-#define TPL_FILE (1 << 0)
-#define TPL_MEM (1 << 1)
-#define TPL_PREALLOCD (1 << 2)
-#define TPL_EXCESS_OK (1 << 3)
-#define TPL_FD (1 << 4)
-#define TPL_UFREE (1 << 5)
-#define TPL_DATAPEEK (1 << 6)
-#define TPL_FXLENS (1 << 7)
-#define TPL_GETSIZE (1 << 8)
-/* do not add flags here without renumbering the internal flags! */
-
-/* flags for tpl_gather mode */
-#define TPL_GATHER_BLOCKING 1
-#define TPL_GATHER_NONBLOCKING 2
-#define TPL_GATHER_MEM 3
-
-/* Hooks for error logging, memory allocation functions and fatal */
-typedef int (tpl_print_fcn)(const char *fmt, ...);
-typedef void *(tpl_malloc_fcn)(size_t sz);
-typedef void *(tpl_realloc_fcn)(void *ptr, size_t sz);
-typedef void (tpl_free_fcn)(void *ptr);
-typedef void (tpl_fatal_fcn)(char *fmt, ...);
-
-typedef struct tpl_hook_t {
- tpl_print_fcn *oops;
- tpl_malloc_fcn *malloc;
- tpl_realloc_fcn *realloc;
- tpl_free_fcn *free;
- tpl_fatal_fcn *fatal;
- size_t gather_max;
-} tpl_hook_t;
-
-typedef struct tpl_node {
- int type;
- void *addr;
- void *data; /* r:tpl_root_data*. A:tpl_atyp*. ow:szof type */
- int num; /* length of type if its a C array */
- size_t ser_osz; /* serialization output size for subtree */
- struct tpl_node *children; /* my children; linked-list */
- struct tpl_node *next,*prev; /* my siblings (next child of my parent) */
- struct tpl_node *parent; /* my parent */
-} tpl_node;
-
-/* used when un/packing 'B' type (binary buffers) */
-typedef struct tpl_bin {
- void *addr;
- uint32_t sz;
-} tpl_bin;
-
-/* for async/piecemeal reading of tpl images */
-typedef struct tpl_gather_t {
- char *img;
- int len;
-} tpl_gather_t;
-
-/* Callback used when tpl_gather has read a full tpl image */
-typedef int (tpl_gather_cb)(void *img, size_t sz, void *data);
-
-/* Prototypes */
-TPL_API tpl_node *tpl_map(char *fmt,...); /* define tpl using format */
-TPL_API void tpl_free(tpl_node *r); /* free a tpl map */
-TPL_API int tpl_pack(tpl_node *r, int i); /* pack the n'th packable */
-TPL_API int tpl_unpack(tpl_node *r, int i); /* unpack the n'th packable */
-TPL_API int tpl_dump(tpl_node *r, int mode, ...); /* serialize to mem/file */
-TPL_API int tpl_load(tpl_node *r, int mode, ...); /* set mem/file to unpack */
-TPL_API int tpl_Alen(tpl_node *r, int i); /* array len of packable i */
-TPL_API char* tpl_peek(int mode, ...); /* sneak peek at format string */
-TPL_API int tpl_gather( int mode, ...); /* non-blocking image gather */
-TPL_API int tpl_jot(int mode, ...); /* quick write a simple tpl */
-
-#if defined __cplusplus
- }
-#endif
-
-#endif /* TPL_H */
-
+++ /dev/null
-noinst_LTLIBRARIES = libwinmmap.la
-noinst_HEADERS = mman.h
-libwinmmap_la_SOURCES = nonempty.c
-libwinmmap_la_LIBADD = @LTLIBOBJS@
+++ /dev/null
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/win
-DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in mmap.c
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config/config.h
-CONFIG_CLEAN_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-libwinmmap_la_DEPENDENCIES = @LTLIBOBJS@
-am_libwinmmap_la_OBJECTS = nonempty.lo
-libwinmmap_la_OBJECTS = $(am_libwinmmap_la_OBJECTS)
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libwinmmap_la_SOURCES)
-DIST_SOURCES = $(libwinmmap_la_SOURCES)
-HEADERS = $(noinst_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-noinst_LTLIBRARIES = libwinmmap.la
-noinst_HEADERS = mman.h
-libwinmmap_la_SOURCES = nonempty.c
-libwinmmap_la_LIBADD = @LTLIBOBJS@
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/win/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/win/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-clean-noinstLTLIBRARIES:
- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libwinmmap.la: $(libwinmmap_la_OBJECTS) $(libwinmmap_la_DEPENDENCIES)
- $(LINK) $(libwinmmap_la_OBJECTS) $(libwinmmap_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mmap.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nonempty.Plo@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(HEADERS)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -rf $(DEPDIR) ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf $(DEPDIR) ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
+++ /dev/null
-This directory contains functions that are missing on the Windows platform. In
-particular, mmap, munmap, and msync are not available on Windows. These
-replacements are used on both Cygwin and MinGW. (On Cygwin the built-in mmap
-has no write support, and is not used).
-
-mmap.c
-mman.h
-
-Special thanks to Horea Haitonic for contributing mmap.c and mman.h.
-
-April 2007
+++ /dev/null
-#ifndef _MMAN_H_
-#define _MMAN_H_
-
-/* Protections */
-#define PROT_NONE 0x00 /* no permissions */
-#define PROT_READ 0x01 /* pages can be read */
-#define PROT_WRITE 0x02 /* pages can be written */
-#define PROT_EXEC 0x04 /* pages can be executed */
-
-/* Sharing type and options */
-#define MAP_SHARED 0x0001 /* share changes */
-#define MAP_PRIVATE 0x0002 /* changes are private */
-#define MAP_COPY MAP_PRIVATE /* Obsolete */
-#define MAP_FIXED 0x0010 /* map addr must be exactly as requested */
-#define MAP_RENAME 0x0020 /* Sun: rename private pages to file */
-#define MAP_NORESERVE 0x0040 /* Sun: don't reserve needed swap area */
-#define MAP_INHERIT 0x0080 /* region is retained after exec */
-#define MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change file size */
-#define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */
-#define MAP_STACK 0x0400 /* region grows down, like a stack */
-
-/* Error returned from mmap() */
-#define MAP_FAILED ((void *)-1)
-
-/* Flags to msync */
-#define MS_ASYNC 0x01 /* perform asynchronous writes */
-#define MS_SYNC 0x02 /* perform synchronous writes */
-#define MS_INVALIDATE 0x04 /* invalidate cached data */
-
-/* File modes for 'open' not defined in MinGW32 (not used by mmap) */
-#ifndef S_IWGRP
-#define S_IWGRP 0
-#define S_IRGRP 0
-#define S_IROTH 0
-#endif
-
-/**
- * Map a file to a memory region
- */
-void *mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset);
-
-/**
- * Unmap a memory region
- */
-int munmap(void *addr, int len);
-
-/**
- * Synchronize a mapped region
- */
-int msync(char *addr, int len, int flags);
-
-#endif /* _MMAN_H_ */
+++ /dev/null
-#include <stdlib.h>
-#include <windows.h>
-#ifdef _WIN32
-#include <io.h>
-#endif
-#include <errno.h>
-#include "mman.h"
-
-static const char id[]="$Id: tpl.c 107 2007-04-20 17:11:29Z thanson $";
-
-/**
- * @brief Map a file to a memory region
- *
- * This function emulates the POSIX mmap() using CreateFileMapping() and
- * MapViewOfFile()
- *
- * @param addr the suggested start address (if != 0)
- * @param len length of the region
- * @param prot region accesibility, bitwise OR of PROT_READ, PROT_WRITE, PROT_EXEC
- * @param flags mapping type and options (ignored)
- * @param fd object to be mapped into memory
- * @param offset offset into mapped object
- * @return pointer to the memory region, or NULL in case of error
- */
-void *mmap(void *addr, unsigned int len, int prot, int flags, int fd, unsigned int offset)
-{
- DWORD wprot;
- DWORD waccess;
- HANDLE h;
- void *region;
-
- /* Translate read/write/exec flags into WIN32 constants */
- switch (prot) {
- case PROT_READ:
- wprot = PAGE_READONLY;
- break;
- case PROT_EXEC:
- wprot = PAGE_EXECUTE_READ;
- break;
- case PROT_READ | PROT_EXEC:
- wprot = PAGE_EXECUTE_READ;
- break;
- case PROT_WRITE:
- wprot = PAGE_READWRITE;
- break;
- case PROT_READ | PROT_WRITE:
- wprot = PAGE_READWRITE;
- break;
- case PROT_READ | PROT_WRITE | PROT_EXEC:
- wprot = PAGE_EXECUTE_READWRITE;
- break;
- case PROT_WRITE | PROT_EXEC:
- wprot = PAGE_EXECUTE_READWRITE;
- break;
- }
-
- /* Obtaing handle to map region */
- h = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, wprot, 0, len, 0);
- if (h == NULL) {
- DWORD error = GetLastError();
-
- /* Try and translate some error codes */
- switch (error) {
- case ERROR_ACCESS_DENIED:
- case ERROR_INVALID_ACCESS:
- errno = EACCES;
- break;
- case ERROR_OUTOFMEMORY:
- case ERROR_NOT_ENOUGH_MEMORY:
- errno = ENOMEM;
- break;
- default:
- errno = EINVAL;
- break;
- }
- return MAP_FAILED;
- }
-
-
- /* Translate sharing options into WIN32 constants */
- switch (wprot) {
- case PAGE_READONLY:
- waccess = FILE_MAP_READ;
- break;
- case PAGE_READWRITE:
- waccess = FILE_MAP_WRITE;
- break;
- }
-
- /* Map file and return pointer */
- region = MapViewOfFile(h, waccess, 0, 0, 0);
- if (region == NULL) {
- DWORD error = GetLastError();
-
- /* Try and translate some error codes */
- switch (error) {
- case ERROR_ACCESS_DENIED:
- case ERROR_INVALID_ACCESS:
- errno = EACCES;
- break;
- case ERROR_INVALID_HANDLE:
- errno = EBADF;
- break;
- default:
- errno = EINVAL;
- break;
- }
- CloseHandle(h);
- return MAP_FAILED;
- }
-
- /* All fine */
- return region;
-}
-
-
-/**
- * @brief Unmap a memory region
- *
- * This is a wrapper around UnmapViewOfFile in the win32 API
- *
- * @param addr start address
- * @param len length of the region
- * @return 0 for success, -1 for error
- */
-int munmap(void *addr, int len)
-{
- if (UnmapViewOfFile(addr)) {
- return 0;
- }
- else {
- errno = EINVAL;
- return -1;
- }
-}
-
-
-/**
- * Synchronize a mapped region
- *
- * This is a wrapper around FlushViewOfFile
- *
- * @param addr start address
- * @param len number of bytes to flush
- * @param flags sync options -- currently ignored
- * @return 0 for success, -1 for error
- */
-int msync(char *addr, int len, int flags)
-{
- if (FlushViewOfFile(addr, len) == 0) {
- DWORD error = GetLastError();
-
- /* Try and translate some error codes */
- switch (error) {
- case ERROR_INVALID_PARAMETER:
- errno = EINVAL;
- break;
- case ERROR_WRITE_FAULT:
- errno = EIO;
- break;
- default:
- errno = EINVAL;
- break;
- }
- return -1;
- }
-
- /* Success */
- return 0;
-}
+++ /dev/null
-/* This function exists solely to prevent libwinmmap.la from being empty. Empty
- * libraries cause problems on some platforms, e.g. Mac OS X. */
-
-int tpl_nonempty(int i) {
- return i+1;
-}
+++ /dev/null
-# Makefile for tpl built-in test suite
-#
-# This Makefile has three useful targets:
-#
-# all (default):
-# Build and run all self-tests by compiling tpl into each test.
-#
-# Note: On Cygwin/MinGW, compiling the tpl source directly into the tests is
-# not supported (as they use 'replacement' functions which get included only
-# in libtpl), so on these platforms the 'alt' target is the default.
-#
-# alt:
-# Build and run all the self-tests by linking them with libtpl, which must
-# have been created beforehand (by running 'configure; make' in the
-# top-level directory); a reminder will be printed if you have not done so.
-#
-# Note, libtool will create wrappers around each test to accomodate the
-# pre-installed state of ../src/libtpl.la. In a real program, you'd link
-# against an installed libtpl.la, and these wrappers would not be used.
-#
-# clean:
-# Clean up all the compiled bits.
-#
-PROGS = test1 test2 test3 test4 test5 test6 test7 test8 \
- test9 test10 test11 test12 test13 test14 test15 test16 \
- test17 test18 test19 test20 test21 test22 test23 test24 \
- test25 test26 test27 test28 test29 test30 test31 test32 \
- test33 test34 test35 test36 test37 test38 test39 test40 \
- test41 test42 test43 test44 test45 test46 test47 test48 \
- test49 test50 test51 test52 test53 test54 test55 test56 \
- test57 test58 test59 test60 test61 test62 test63 test64 \
- test65 test66 test67 test68 test69 test70 test71 test72 \
- test73 test74 test75 test76 test77 test78 test79 test80 \
- test81 test82 test83 test84 test85 test86 test87 test88 \
- test89 test90 test91 test92 test93 test94 test95 test96 \
- test97 test98 test99 test100 test101 test102 test103 test104 \
- test105 test106 test107 test108 test109 test110 test111 test112 \
- test113 test114 test115 test116 test117 test118 test119 test120 \
- test121 test122 test123 test124
-
-TPLSRC = ../src
-CFLAGS = -I$(TPLSRC) -g
-CFLAGS += -pedantic
-CFLAGS += -Wall
-#CFLAGS += -m32
-#CFLAGS += -m64
-CFLAGS += -O3
-#For testing without C99 feature support
-#CFLAGS += -std=c89
-
-# Prefer 64-bit compilation on Mac OS X (not necessary, just faster)
-ifneq ($(strip $(shell $(CC) -v 2>&1 |egrep "i[0-9]+-apple-darwin")),)
- CFLAGS += -m64
-endif
-
-# detect Cygwin or MinGW
-ifneq ($(strip $(shell $(CC) -v 2>&1 |egrep "cygwin|mingw")),)
- TESTS=./do_tests.cygwin
- # divert to the alt target; use tpl as a lib for Cygwin/Mingw
- TARGET=alt
-else
- TESTS=./do_tests
- TARGET=$(PROGS) run_tests
-endif
-
-all: $(TARGET)
-
-tpl.o : $(TPLSRC)/tpl.c $(TPLSRC)/tpl.h
- $(CC) -c $(CFLAGS) $(TPLSRC)/tpl.c
-
-$(PROGS) : tpl.o
- $(CC) $(CFLAGS) -o $@ $(@).c tpl.o
-
-run_tests:
- perl $(TESTS)
-
-# This target can be used to compile the tests as dependent on
-# the tpl library (rather than compiling in the tpl source).
-alt: mkalttests run_tests
-
-mkalttests:
- @$(MAKE) -f Makefile.alt PROGS="$(PROGS)"
-
-.PHONY: clean
-
-clean:
- rm -f $(PROGS) tpl.o test*.out test*.err test*.exe
- rm -rf $(PROGS) test*.dSYM
+++ /dev/null
-# This Makefile.alt is subordinate to Makefile (usage: make alt)
-# Its distinction is that it builds the test programs by linking
-# them with libtpl rather than by compiling tpl.c into the tests.
-SRC = ../src
-LIBTOOL = ../libtool
-LTLIB = $(SRC)/libtpl.la
-CFLAGS = -I$(SRC) -g
-
-# We have an alternate basic test for MinGW
-ifneq ($(strip $(shell $(CC) -v 2>&1 |grep "mingw")),)
- TARGET=mingw
-else
- TARGET=$(PROGS)
-endif
-
-all: $(TARGET)
-
-
-$(PROGS) : $(LTLIB)
- $(CC) -c $(CFLAGS) $(@).c
- $(LIBTOOL) --mode=link --tag=CC $(CC) -o $@ $(@).o $(LTLIB)
-
-$(LTLIB) :
- @echo "you must first run 'configure; make' in the top-level directory"
- @exit 1
-
-mingw :
- @echo ""
- @echo "MinGW has its own test suite. Please run make -f Makefile.mingw"
- @echo ""
- @exit 1
+++ /dev/null
-# This makes a small Mingw test program. The standard test suite
-# is incompatible with MinGW because it uses UNIX facilities such
-# as pipe/fork and the /tmp directory, not features of Windows.
-SRC = ../src
-LIBTOOL = ../libtool
-LTLIB = $(SRC)/libtpl.la
-CFLAGS = -I$(SRC) -g
-
-PROG = mgwtest
-
-all: $(PROG)
-
-$(PROG) : $(LTLIB)
- $(CC) -c $(CFLAGS) $(@).c
- $(LIBTOOL) --mode=link --tag=CC $(CC) -o $@ $(@).o $(LTLIB) -mwindows
- @echo "you can now run windows application: $@"
-
-$(LTLIB) :
- @echo "you must first run 'configure; make' in the top-level directory"
- @exit 1
-
-.PHONY: clean
-
-clean:
- rm $(PROG) $(PROG).exe $(PROG).o $(PROG).tpl
+++ /dev/null
-Run "make" in this directory to build the tests and run them.
-
-test1: serialize int into memory, unserialize
-test2: serialize int into file, unserialize
-test3: serialize A(i) into file, unserialize
-test4: serialize A(i) into memory, unserialize
-test5: serialize A(A(i)) into memory, unserialize
-test6: serialize string into memory, unserialize
-test7: serialize A(s) into file, unserialize
-test8: serialize cA(c) into file, unserialize
-test9: unpack big-endian tpl data file of A(i)
-test10: unpack little-endian tpl data file of A(i)
-test11: try to load a corrupt tpl image w/invalid chars
-test12: try to load a corrupt tpl image w/runaway format string
-test13: try to load a corrupt tpl image w/internal A length -1
-test14: try to load a corrupt tpl image w/internal A length +1
-test15: try to load a corrupt tpl image w/invalid magic
-test16: try to load a corrupt tpl image w/invalid len
-test17: try to load a good tpl but whose format mismatches map
-test18: try to map a tpl with malformed format- unbalanced parens: missing )
-test19: try to map a tpl with malformed format- unbalanced parens: extra )
-test20: try to map a tpl with malformed format- empty A()
-test21: serialize A(ii) into file, unserialize
-test22: serialize A(u) into file, unserialize
-test23: serialize A(u) into file, read tpl from fd using TPL_FD
-test24: read A(u) tpl file with extra trailing bytes, ok in TPL_FD mode
-test25: same A(u) tpl file with extra trailing bytes, not ok in TPL_FILE mode
-test26: test non-blocking tpl_gather using async read of 3 tpls across 2 pipes
-test27: test tpl_dump() of A(u) to file using TPL_FD, unserialize
-test28: parent writes A(u) tpl to child through pipe, both use TPL_FD mode
-test29: parent writes consecutive A(u) tpl then A(c) tpl to child through pipe
-test30: test pack B (binary buffer) and unpack
-test31: test pack B (binary buffer) of 0-length and unpack
-test32: test pack A(B) and unpack
-test33: test pack f (double) and unpack
-test34: test pack A(f) and unpack
-test35: pack A(is)
-test36: unpack A(is)
-test37: pack A(A(i)) [example from man page]
-test38: unpack A(A(i)) [example from man page]
-test39: try to load a tpl with an unsupported bit flag set
-test40: pack char array - userguide example
-test41: unpack char arrray - userguide example
-test42: test non-aligned pointers in backbone (under Solaris dbx, check -all)
-test43: test non-aligned pointers in backbone (under Solaris dbx, check -all)
-test44: test non-aligned pointers in backbone (under Solaris dbx, check -all)
-test46: test correct-size of backbone "double" datum (Solaris dbx, check -all)
-test47: store A(i) to file - userguide example
-test48: read A(i) from file - userguide example
-test49: write A(s) - userguide example
-test50: read A(s) - userguide example
-test51: test tpl_mem_gather (_0: 1 tpl; _1: 2 tpls; _2/_3/_4: 1 tpl in 3 parts)
-test52: A(A(i)): pack an int; pack parent; pack int; don't pack parent; ser_osz
-test53: A(A(i)): pack an int; pack parent; pack parent; 0-length 2nd parent el.
-test54: test callback negative return value for tpl_mem_gather
-test55: test callback negative return value for tpl_fd_gather
-test56: test static string using c# format pack/unpack in mem
-test57: test pack static string using c# to file
-test58: test unpack static string using c# from file
-test59: test alignment using cc#cc# pack/unpack in mem
-test60: test pack-then-load (implicit intervening free, using tpl_free_keep_map)
-test61: test load-then-load (implicit intervening free, using tpl_free_keep_map)
-test62: test load-then-pack (implicit intervening free, using tpl_free_keep_map)
-test63: test pack-then-unpack (implicit dump/load) then pack-then-unpack again
-test64: pack level 0 types, change and re-pack level 0 types, test implicit free
-test65: pack int[] using format character #
-test66: pack two separate int[] using format character #
-test67: test expected failure if format strings agree but array lengths mismatch
-test68: test octothorpe support by packing,unpacking two fixed lengths arrays
-test69: test octothorpic array support A(i#i#)
-test70: test S(...) structure pack and unpack
-test71: test cS(...) pack/unpack when preceded by non-structure byte
-test72: test wildcard structure unpack
-test73: test wildcard structure unpack
-test74: test wildcard structure unpack
-test75: test sc# (string and byte array)
-test76: test S(sc#) (structure of last)
-test77: test S(sc#) (structure of last) with wildcard unpack
-test78: pack A(i)c
-test79: unpack A(i)c
-test80: pack and unpack A(S(ci#))
-test81: pack and unpack A(S(ci#))
-test82: pack cA(i#)S(cf#)A(ci#)
-test83: unpack cA(i#)S(cf#)A(ci#)
-test84: repeat test83 with both big and little endian input files
-test85: tpl_peek at file
-test86: tpl_peek at in-memory tpl
-test87: test tpl_gather(TPL_GATHER_FD_BLOCKING)
-test88: test packing S(ic#f)
-test89: test unpacking S(ic#f) as S(*)
-test90: pack and unpack I
-test91: pack and unpack U
-test92: pack and unpack A(cIcU)
-test93: pack and unpack NULL string
-test94: pack and unpack A(s) with some null
-test95: pack and unpack null string, empty string, non-empty string
-test96: pack and unpack A(null string, empty string, non-empty string)
-test97: pack and unapck 16-bit int/uint (j,v)
-test98: pack and unapck 16-bit int/uint A(j,v)
-test99: data peek at c in complex format
-test100: data peek at i inside S(ic)
-test101: data peek at c inside S(ic) [expected failure test]
-test102: data peek at c in simple format c
-test103: data peek at iscsi in S(iscsiu)
-test104: data peek at iscsi in S(iscsiu) with NULL string pointer
-test105: tpl_jot then unpack by normal then by tpl_peek
-test106: test IS(Iiuijc#)#iiii
-test107: test S(ic#)#
-test108: test IS(Iiuijc#)#iiii
-test109: test S(cijc)# where next structure elt alignment based on i
-test110: test ssssiiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiii
-test111: test S(icfv#)#
-test112: test S(ic#fv#)#
-test113: test icS(ic#fv#)#ci
-test114: test multi-dimension i##
-test115: test S(s)#, S(si)#, S(c#si)#
-test116: test cs#i
-test117: test cA(s#)i
-test118: test tpl_peek(TPL_FXLENS) with cA(i#)S(cf#)A(ci#)
-test119: test tpl_dump(tn,TPL_GETSIZE,&sz);
-test120: test TPL_PREALLOCD and TPL_EXCESS_OK flags
-test121: test s##
-test122: test S(ic#f$(ci))
-test123: setjmp/longjmp based fatal error handler
-test124: test A(S(c#)s) as per bug report from Eric Rose
+++ /dev/null
-#!/bin/sh
-
-# This script works with Solaris Studio 11
-# version of dbx which supports "check -all" and
-# "check -access" run modes, at least on Sparc.
-# These detect access or alignment violations or
-# leftover unfreed memory. TDH 29Dec06
-
-DBX=/opt/SUNWspro/bin/dbx
-OUT=/tmp/dbx.out.$$
-
-echo "Writing $OUT..."
-
-for f in test? test??
-do
- echo $f
- ${DBX} $f 1>>${OUT} 2>&1 <<EOF
-check -all
-run
-EOF
-
-egrep 'mar|rua|rui|wui|wua|maw' ${OUT}
-
-done
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-my @tests;
-for (glob "test*[0-9]") {
- push @tests, $_ if -e "$_.ans";
-}
-
-my $num_failed=0;
-
-for my $test (@tests) {
- `./$test > $test.out 2> $test.err`;
- `diff $test.out $test.ans`;
- print "$test failed\n" if $?;
- $num_failed++ if $?;
- unlink "$test.err" if -z "$test.err";
-}
-
-print scalar @tests . " tests conducted, $num_failed failed.\n";
-exit $num_failed;
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-my @tests;
-for (glob "test*[0-9].exe") {
- push @tests, "$_" if -e substr($_, 0, - 4).".ans";
-}
-
-my $num_failed=0;
-
-for my $test (@tests) {
- `./$test > $test.out`;
- my $ansfile = substr($test, 0, - 4).".ans";
- `diff $test.out $ansfile`;
- print "$test failed\n" if $?;
- $num_failed++ if $?;
-}
-
-print scalar @tests . " tests conducted, $num_failed failed.\n";
+++ /dev/null
-#include <stdio.h>
-#include <inttypes.h>
-
-/* try compiling this with -m32 vs -m64
- *
- * with mac os x and gcc,
- * on -m32 the int64_t gets aligned at +4
- * on -m64 the int64_t gets aligned at +8
- */
-
-static const struct s_t {
- int i;
- int64_t j;
-} s;
-
-int main() {
- if ((long)&s.j % 8 != 0) printf("non-aligned int64\n");
- else printf("aligned int64\n");
-}
+++ /dev/null
-#include <stdio.h>
-
-/* try compiling this with and without aligned doubles
- *
- * cc -malign-double -o malign malign.c
- * cc -mno-align-double -o malign malign.c
- *
- * on x86, double is not normally aligned (unless -malign-double is used).
- * but on Sparc, or x86-64, double is aligned.
- */
-
-static const struct s_t {
- char a;
- double d;
-} s;
-
-int main() {
- if ((long)&s.d % 8 != 0) printf("-mno-align-double\n");
- else printf("-malign-double\n");
-}
+++ /dev/null
-#include <windows.h>
-#include "tpl.h"
-
-int WINAPI WinMain (HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- PSTR szCmdLine,
- int iCmdShow)
-{
- char *status;
- int rc=0,i,j;
- tpl_node *tn;
- void *img;
- size_t sz;
-
- tn = tpl_map("A(i)", &i);
- for(i=0; i<10; i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_MEM,&img, &sz);
- tpl_free(tn);
-
- j=0;
- tn = tpl_map("A(i)", &i);
- tpl_load(tn,TPL_MEM,img,sz);
- while(tpl_unpack(tn,1) > 0) {
- if (i != j++) {
- rc = -1;
- break;
- }
- }
- tpl_free(tn);
-
- MessageBox (NULL, (rc==0)?"Test1 passed":"Test1 failed",
- "MinGW Tpl Test", MB_OK);
-
- /* Test 2 */
- tn = tpl_map("A(i)", &i);
- for(i=0; i<10; i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"mgwtest.tpl");
- tpl_free(tn);
-
- j=0;
- tn = tpl_map("A(i)", &i);
- tpl_load(tn,TPL_FILE,"mgwtest.tpl");
- while(tpl_unpack(tn,1) > 0) {
- if (i != j++) {
- rc = -1;
- break;
- }
- }
- tpl_free(tn);
-
- MessageBox (NULL, (rc==0)?"Test2 passed":"Test2 failed",
- "MinGW Tpl Test", MB_OK);
-
- return (0);
-}
-
+++ /dev/null
-SRCDIR=../../src
-CPPFLAGS = -I$(SRCDIR)
-
-PROGS = other1
-all: $(PROGS) run_tests
-
-tpl.c:
- cp $(SRCDIR)/tpl.c .
-
-other1: other1.o tpl.o
- g++ -o other1 other1.o tpl.o
-
-
-.PHONY: clean run_tests
-
-clean:
- rm -f *.o $(PROGS) *.out
- rm -f tpl.c
-
-run_tests:
- perl ./do_tests
+++ /dev/null
-Assorted other tests that are not part of the standard test suite.
-other1: a C++ program using "this" as a structure pointer
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-my @tests;
-for (glob "other*[0-9]") {
- push @tests, $_ if -e "$_.ans";
-}
-
-my $num_failed=0;
-
-for my $test (@tests) {
- `./$test > $test.out 2> $test.err`;
- `diff $test.out $test.ans`;
- print "$test failed\n" if $?;
- $num_failed++ if $?;
- unlink "$test.err" if -z "$test.err";
-}
-
-print scalar @tests . " tests conducted, $num_failed failed.\n";
-exit $num_failed;
+++ /dev/null
-buffer: tpl
-i: 9999
-c: this is a test string.
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include "tpl.h"
-main() {
-void *buffer;
-size_t bsize;
-
-struct ci {
- int i;
- char c[30];
-
- void pack( void **buffer, size_t *size )
- {
- tpl_node *tn = tpl_map("S(ic#)", this, 30); /* pass structure address */
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_MEM, buffer, size);
- tpl_free(tn);
- }
-
- void unpack( void *buffer, size_t size )
- {
- tpl_node *tn = tpl_map("S(ic#)", this, 30);
- tpl_load(tn, TPL_MEM, buffer, size);
- tpl_unpack( tn, 0 );
- tpl_free(tn);
- }
-};
-
-struct ci s = {9999, "this is a test string."};
-
-s.pack(&buffer, &bsize);
-printf("buffer: %s\n", (char *)buffer);
-
-struct ci b = { -1, "" };
-
-b.unpack(buffer, bsize);
-
-printf("i: %d\n", b.i);
-printf("c: %s\n", b.c);
-}
+++ /dev/null
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-
-use Config;
-
-#print "$_: ", ($Config{$_} or ""), "\n" for keys %Config;
-#exit;
-
-my @types = qw(char short int long longlong double);
-for (@types) {
- my $bytes = $Config{"${_}size"};
- my $bits = $bytes * 8;
- printf "size of %-10s: %5d bytes (%d bits)\n", $_, $bytes, $bits;;
-}
-
-print qq/
- These sizes reflect the platform and compiler options with
- which Perl was built on this system. The sizes may change
- if different compiler options are used.
-/;
-
+++ /dev/null
-#include <windows.h>
-#include "tpl.h"
-
-int WINAPI WinMain (HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- PSTR szCmdLine,
- int iCmdShow)
-{
- MessageBox (NULL, "Hello", "Hello Demo", MB_OK);
- return (0);
-}
-
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,j=-1;
- void *addr;
- size_t sz;
-
- tn = tpl_map("i",&i);
- i=1;
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_MEM,&addr,&sz);
- tpl_free(tn);
-
- tn = tpl_map("i",&j);
- tpl_load(tn,TPL_MEM,addr,sz);
- tpl_unpack(tn,0);
- printf("j is %d\n", j);
- tpl_free(tn);
- free(addr);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test10.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-fmt: S(ic)
-p: 1
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename = "/tmp/test100.tpl";
-int main() {
- tpl_node *tn;
- struct {
- int i;
- char c;
- } s;
- int p;
- char *fmt;
-
- tn = tpl_map("S(ic)", &s);
- s.i = 1; s.c = '^';
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_FILE, filename);
- tpl_free(tn);
-
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, filename, "i", &p);
- if (fmt) {
- printf("fmt: %s\n", fmt);
- printf("p: %d\n", p);
- }
-
- return 0;
-}
+++ /dev/null
-fmt: S(ic)
-p: 1
+++ /dev/null
-TPL_DATAPEEK format mismatches tpl iamge
-peek failed
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-extern tpl_hook_t tpl_hook;
-const char *filename = "/tmp/test101.tpl";
-int main() {
- tpl_node *tn;
- struct {
- int i;
- char c;
- } s;
- char *fmt, q;
- tpl_hook.oops = printf;
-
- tn = tpl_map("S(ic)", &s);
- s.i = 1; s.c = '^';
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_FILE, filename);
- tpl_free(tn);
-
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, filename, "c", &q);
- if (fmt) {
- printf("fmt: %s\n", fmt);
- printf("q: %c\n", q);
- } else {
- printf("peek failed\n");
- }
-
- return 0;
-}
+++ /dev/null
-TPL_DATAPEEK format mismatches tpl iamge
-peek failed
+++ /dev/null
-fmt: c
-q: !
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename = "/tmp/test102.tpl";
-int main() {
- tpl_node *tn;
- char *fmt,p,q;
-
- tn = tpl_map("c", &p);
- p = '!';
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_FILE, filename);
- tpl_free(tn);
-
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, filename, "c", &q);
- if (fmt) {
- printf("fmt: %s\n", fmt);
- printf("q: %c\n", q);
- }
-
- return 0;
-}
+++ /dev/null
-fmt: c
-q: !
+++ /dev/null
-fmt: S(iscsiu)
-pi: 1, ps: hello, pc: ^, pt: world, pi: 2
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename = "/tmp/test103.tpl";
-int main() {
- tpl_node *tn;
- struct {
- int i;
- char *s;
- char c;
- char *t;
- int j;
- unsigned u;
- } s;
- char *fmt, *ps, pc, *pt;
- int pi, pj;
-
- tn = tpl_map("S(iscsiu)", &s);
- s.i = 1; s.s = "hello"; s.c = '^'; s.t = "world"; s.j = 2; s.u = 3;
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_FILE, filename);
- tpl_free(tn);
-
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, filename, "iscsi",&pi,&ps,&pc,&pt,&pj);
- if (fmt) {
- printf("fmt: %s\n", fmt);
- printf("pi: %d, ps: %s, pc: %c, pt: %s, pi: %d\n", pi,ps,pc,pt,pj);
- } else {
- printf("peek failed\n");
- }
-
- return 0;
-}
+++ /dev/null
-fmt: S(iscsiu)
-pi: 1, ps: hello, pc: ^, pt: world, pi: 2
+++ /dev/null
-fmt: S(iscsiu)
-pi: 1, ps: NULL, pc: ^, pt: world, pi: 2
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename = "/tmp/test104.tpl";
-int main() {
- tpl_node *tn;
- struct {
- int i;
- char *s;
- char c;
- char *t;
- int j;
- unsigned u;
- } s;
- char *fmt, *ps, pc, *pt;
- int pi, pj;
-
- tn = tpl_map("S(iscsiu)", &s);
- s.i = 1; s.s = NULL; s.c = '^'; s.t = "world"; s.j = 2; s.u = 3;
- tpl_pack(tn, 0);
- tpl_dump(tn, TPL_FILE, filename);
- tpl_free(tn);
-
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, filename, "iscsi",&pi,&ps,&pc,&pt,&pj);
- if (fmt) {
- printf("fmt: %s\n", fmt);
- printf("pi: %d, ps: %s, pc: %c, pt: %s, pi: %d\n",pi,ps?ps:"NULL",pc,pt,pj);
- } else {
- printf("peek failed\n");
- }
-
- return 0;
-}
+++ /dev/null
-fmt: S(iscsiu)
-pi: 1, ps: NULL, pc: ^, pt: world, pi: 2
+++ /dev/null
-i: 1, s: hello, w: world, c: $
-i: 1, s: hello, w: world, c: $
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename = "/tmp/test105.tpl";
-
-int main() {
- int i=1;
- char *s="hello",*w="world",c='$', *fmt;
- tpl_node *tn;
-
- tpl_jot(TPL_FILE, filename, "issc", &i, &s, &w, &c);
-
- i = 0; s = NULL; w = NULL; c = 0;
-
- /* unpack the normal way */
- tn = tpl_map("issc", &i, &s, &w, &c);
- tpl_load(tn, TPL_FILE, filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("i: %d, s: %s, w: %s, c: %c\n", i, s, w, c);
-
- i = 0; s = NULL; w = NULL; c = 0;
-
- /* unpack the quick way */
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, filename, "issc", &i, &s, &w, &c);
- printf("i: %d, s: %s, w: %s, c: %c\n", i, s, w, c);
-
- return 0;
-}
+++ /dev/null
-i: 1, s: hello, w: world, c: $
-i: 1, s: hello, w: world, c: $
+++ /dev/null
-testing with TPL_FILE:
-1000
- 0, 0, 0, 5000, 15, Deepak
- 1, 5, 10, 6000, 18, Deepak
- 2, 10, 20, 7000, 21, Deepak
- 3, 15, 30, 8000, 24, Deepak
- 4, 20, 40, 9000, 27, Deepak
- 5, 25, 50, 10000, 30, Deepak
- 6, 30, 60, 11000, 33, Deepak
- 7, 35, 70, 12000, 36, Deepak
- 8, 40, 80, 13000, 39, Deepak
-9,23,43,16
-testing with TPL_FD:
-1000
- 0, 0, 0, 5000, 15, Deepak
- 1, 5, 10, 6000, 18, Deepak
- 2, 10, 20, 7000, 21, Deepak
- 3, 15, 30, 8000, 24, Deepak
- 4, 20, 40, 9000, 27, Deepak
- 5, 25, 50, 10000, 30, Deepak
- 6, 30, 60, 11000, 33, Deepak
- 7, 35, 70, 12000, 36, Deepak
- 8, 40, 80, 13000, 39, Deepak
-9,23,43,16
+++ /dev/null
-#include "tpl.h"
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-
-#define SUM_LENGTH 16
-#define MS_COUNT 9
-struct sum_buf {
- int64_t offset;
- int len;
- uint32_t sum1;
- int chain;
- uint16_t flags;
- char sum2[SUM_LENGTH];
-};
-
-struct sum_struct {
- int64_t flength;
- struct sum_buf *sums;
- int count;
- int blength;
- int remainder;
- int s2length;
-};
-
-const char *filename = "/tmp/test106.tpl";
-
-int pack(int use_fd)
-{
- tpl_node *tn;
- struct sum_struct ms;
- int fd=-1,j;
- unsigned perms;
-
- perms = S_IRUSR|S_IWUSR;
- if (use_fd) {
- if ( (fd=open( filename,O_WRONLY|O_CREAT,perms)) == -1) {
- printf("failed to open %s: %s", filename, strerror(errno));
- return(-1);
- }
- }
-
- ms.flength = 1000;
- ms.count = MS_COUNT;
- ms.blength = 23;
- ms.remainder = 43;
- ms.s2length = 16;
-
- ms.sums = (struct sum_buf*) malloc((sizeof(struct sum_buf))*ms.count);
-
- for(j=0;j<ms.count;j++)
- {
- ms.sums[j].offset = (uint64_t) j;
- ms.sums[j].len = j*5;
- ms.sums[j].sum1 = j*10;
- ms.sums[j].chain = j*1000+5000;
- ms.sums[j].flags = j*3 + 15;
- memset(ms.sums[j].sum2,0,SUM_LENGTH);
- strcpy(ms.sums[j].sum2,"Deepak");
- }
-
- tn = tpl_map( "IS(Iiuijc#)#iiii", &ms.flength,ms.sums,SUM_LENGTH,
- ms.count,&ms.count,&ms.blength,&ms.remainder,&ms.s2length);
- tpl_pack( tn, 0 );
-
- if (use_fd) {
- tpl_dump(tn,TPL_FD, fd);
- close(fd);
- } else {
- tpl_dump(tn,TPL_FILE,filename);
- }
-
- tpl_free( tn );
-
- return 0;
-}
-
-int unpack(int use_fd) {
- tpl_node *tn;
- struct sum_struct ms;
- unsigned perms;
- int fd=-1,i;
-
- perms = S_IRUSR|S_IWUSR;
- if (use_fd) {
- if ( (fd=open( filename,O_RDONLY,perms)) == -1) {
- printf("failed to open %s: %s", filename, strerror(errno));
- return(-1);
- }
- }
-
- ms.sums = (struct sum_buf*) malloc((sizeof(struct sum_buf))*MS_COUNT);
-
- tn = tpl_map( "IS(Iiuijc#)#iiii", &ms.flength,ms.sums,SUM_LENGTH,
- MS_COUNT,&ms.count,&ms.blength,&ms.remainder,&ms.s2length);
- if (use_fd) tpl_load(tn, TPL_FD, fd);
- else tpl_load(tn, TPL_FILE, filename);
- tpl_unpack(tn, 0 );
- tpl_free( tn );
- if (use_fd) close(fd);
-
- printf("%d\n", (int)(ms.flength));
- for(i=0; i < MS_COUNT; i++) {
- printf(" %d, %d, %u, %d, %d, %s\n", (int)(ms.sums[i].offset), ms.sums[i].len, ms.sums[i].sum1, ms.sums[i].chain, (int)(ms.sums[i].flags), ms.sums[i].sum2);
- }
- printf("%d,%d,%d,%d\n", ms.count, ms.blength, ms.remainder, ms.s2length);
-
- return 0;
-}
-
-int main() {
- printf("testing with TPL_FILE:\n");
- pack(0);
- unpack(0);
-
- printf("testing with TPL_FD:\n");
- pack(1);
- unpack(1);
-
- return 0;
-}
+++ /dev/null
-testing with TPL_FILE:
-1000
- 0, 0, 0, 5000, 15, Deepak
- 1, 5, 10, 6000, 18, Deepak
- 2, 10, 20, 7000, 21, Deepak
- 3, 15, 30, 8000, 24, Deepak
- 4, 20, 40, 9000, 27, Deepak
- 5, 25, 50, 10000, 30, Deepak
- 6, 30, 60, 11000, 33, Deepak
- 7, 35, 70, 12000, 36, Deepak
- 8, 40, 80, 13000, 39, Deepak
-9,23,43,16
-testing with TPL_FD:
-1000
- 0, 0, 0, 5000, 15, Deepak
- 1, 5, 10, 6000, 18, Deepak
- 2, 10, 20, 7000, 21, Deepak
- 3, 15, 30, 8000, 24, Deepak
- 4, 20, 40, 9000, 27, Deepak
- 5, 25, 50, 10000, 30, Deepak
- 6, 30, 60, 11000, 33, Deepak
- 7, 35, 70, 12000, 36, Deepak
- 8, 40, 80, 13000, 39, Deepak
-9,23,43,16
+++ /dev/null
-0 cat
-1 dog
-2 eel
-3 emu
-4 ant
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <string.h>
-
-typedef struct {
- int i;
- char c[4];
-} test_t;
-
-const char *filename = "/tmp/test107.tpl";
-
-int main() {
- test_t s[5], t[5];
- tpl_node *tn;
- int i;
-
- s[0].i = 0; strcpy(s[0].c, "cat");
- s[1].i = 1; strcpy(s[1].c, "dog");
- s[2].i = 2; strcpy(s[2].c, "eel");
- s[3].i = 3; strcpy(s[3].c, "emu");
- s[4].i = 4; strcpy(s[4].c, "ant");
-
- tn = tpl_map("S(ic#)#", &s, 4, 5);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("S(ic#)#", &t, 4, 5);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- for(i=0; i < 5; i++) {
- printf("%d %s\n", s[i].i, s[i].c);
- }
-
- return 0;
-}
+++ /dev/null
-0 cat
-1 dog
-2 eel
-3 emu
-4 ant
+++ /dev/null
-structure matches original
-other fields match original
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-typedef struct {
- int64_t j;
- int l1;
- unsigned l2;
- int i;
- int16_t h;
- char c[4];
-} test_t;
-
-const char *filename = "/tmp/test108.tpl";
-
-int main() {
- test_t s[5], t[5];
- tpl_node *tn;
- int w=10,x=20,y=30,z=40,W,X,Y,Z;
- uint64_t b=10,B;
-
- memset(s, 0, sizeof(s));
- memset(t, 0, sizeof(t));
-
- s[0].j=0; s[0].i=0; s[0].l1= 0; s[0].l2=0; s[0].h= 0; strcpy(s[0].c, "cat");
- s[1].j=100; s[1].i=1; s[1].l1=-1; s[1].l2=10; s[1].h=1000; strcpy(s[1].c, "dog");
- s[2].j=200; s[2].i=2; s[2].l1=-2; s[2].l2=20; s[2].h=2000; strcpy(s[2].c, "eel");
- s[3].j=300; s[3].i=3; s[3].l1=-3; s[3].l2=30; s[3].h=3000; strcpy(s[3].c, "emu");
- s[4].j=400; s[4].i=4; s[4].l1=-4; s[4].l2=40; s[4].h=4000; strcpy(s[4].c, "ant");
-
- tn = tpl_map("IS(Iiuijc#)#iiii", &b, s, 4, 5, &w, &x, &y, &z);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("IS(Iiuijc#)#iiii", &B, t, 4, 5, &W, &X, &Y, &Z);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- if (memcmp(t,s,sizeof(t)) == 0) printf("structure matches original\n");
- else printf("structure mismatches original\n");
-
- if (b==B && w==W && x==X && y==Y && z==Z) printf("other fields match original\n");
- else printf("other fields mismatch originals\n");
-
- return 0;
-}
+++ /dev/null
-structure matches original
-other fields match original
+++ /dev/null
-sizeof(s): 12
-structures match
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-#include <inttypes.h>
-
-const char *filename = "/tmp/test109.tpl";
-
-typedef struct {
- char c;
- uint32_t i;
- uint16_t j;
- char d;
-} spad;
-
-int main() {
- tpl_node *tn;
- spad s = {'a', 1, 2, 'b'}, t = {'?', 0, 0, '!'};;
-
- printf("sizeof(s): %d\n", (int)sizeof(s));;
- tn = tpl_map("S(cijc)", &s);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("S(cijc)", &t);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- if (s.c==t.c && s.i==t.i && s.j==t.j && s.d==t.d)
- printf("structures match\n");
- else
- printf("structures mismatch\n");
-
- return 0;
-}
+++ /dev/null
-sizeof(s): 12
-structures match
+++ /dev/null
-test11.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test11.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test11.tpl: not a valid tpl file
+++ /dev/null
-structures match
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "tpl.h"
-#include <inttypes.h>
-
-const char *filename = "/tmp/test110.tpl";
-
-int nstrcmp(const char *a, const char *b) {
- if (a==NULL || b==NULL) return (a==NULL && b==NULL)?0:1;
- return strcmp(a,b);
-}
-
-int main() {
- tpl_node *tn;
-
- char *s1,*s2,*s3,*s4;
- int i5,i6,i7,i8,i9,
- i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20,
- i21,i22,i23,i24,i25,i26,i27,i28,i29,i30,i31,i32,i33;
- double f34,f35,f36;
- int i37,i38,i39,i40;
-
- char *S1,*S2,*S3,*S4;
- int I5,I6,I7,I8,I9,
- I10,I11,I12,I13,I14,I15,I16,I17,I18,I19,I20,
- I21,I22,I23,I24,I25,I26,I27,I28,I29,I30,I31,I32,I33;
- double F34,F35,F36;
- int I37,I38,I39,I40;
-
- s1=NULL;s2=NULL;s3="testing";s4="some_string";
- i5=5;i6=6;i7=7;i8=8;i9=9;
- i10=10;i11=11;i12=12;i13=13;i14=14;i15=15;i16=16;i17=17;i18=18;i19=19;i20=20;
- i21=21;i22=22;i23=23;i24=24;i25=25;i26=26;i27=27;i28=28;i29=29;i30=30;i31=31;
- i32=32;i33=33;
- f34=34.0;f35=35.0;f36=36.0;
- i37=37;i38=38;i39=39;i40=40;
-
-
- tn = tpl_map("ssssiiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiii",
- &s1,&s2,&s3,&s4,
- &i5,&i6,&i7,&i8,&i9,
- &i10,&i11,&i12,&i13,&i14,&i15,&i16,&i17,&i18,&i19,&i20,
- &i21,&i22,&i23,&i24,&i25,&i26,&i27,&i28,&i29,&i30,&i31,&i32,&i33,
- &f34,&f35,&f36,
- &i37,&i38,&i39,&i40);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("ssssiiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiii",
- &S1,&S2,&S3,&S4,
- &I5,&I6,&I7,&I8,&I9,
- &I10,&I11,&I12,&I13,&I14,&I15,&I16,&I17,&I18,&I19,&I20,
- &I21,&I22,&I23,&I24,&I25,&I26,&I27,&I28,&I29,&I30,&I31,&I32,&I33,
- &F34,&F35,&F36,
- &I37,&I38,&I39,&I40);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- if (
- !nstrcmp(s1,S1) && !nstrcmp(s2,S2) && !nstrcmp(s3,S3) && !nstrcmp(s4,S4) &&
- i5==I5 && i6==I6 && i7==I7 && i8==I8 && i9==I9 && i10==I10 && i11==I11 &&
- i12==I12 && i13==I13 && i14==I14 && i15==I15 && i16==I16 && i17==I17 &&
- i18==I18 && i19==I19 && i20==I20 && i21==I21 && i22==I22 && i23==I23 &&
- i24==I24 && i25==I25 && i26==I26 && i27==I27 && i28==I28 && i29==I29 &&
- i30==I30 && i31==I31 && i32==I32 && i33==I33 && f34==F34 && f35==F35 &&
- f36==F36 && i37==I37 && i38==I38 && i39==I39 && i40==I40
- ) {
- printf("structures match\n");
- free(S1); free(S2); free(S3); free(S4);
- }
- else
- printf("structures mismatch\n");
-
- return 0;
-}
+++ /dev/null
-structures match
+++ /dev/null
-structures match
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include "tpl.h"
-
-const char *filename = "/tmp/test111.tpl";
-
-#define NUM 100
-
-struct st {
- int i;
- char c;
- double f;
- uint16_t v[2];
-};
-
-
-int main() {
- struct st s[NUM], d[NUM];
- tpl_node *tn;
- int i;
-
- memset(s, 0, sizeof(s)); /* clear s */
- memset(d, 0, sizeof(d)); /* clear d */
-
- /* fill s with random stuff */
- for(i=0; i < NUM; i++) {
- s[i].i = i; s[i].c='a'+i; s[i].f = 3.14159 * i; s[i].v[0] = NUM*i; s[i].v[1] = NUM+i;
- }
-
- tn = tpl_map("S(icfv#)#", s, 2, NUM);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("S(icfv#)#", d, 2, NUM);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- /* see if the result is the same as the s */
- printf("structures %s\n", (!memcmp(d,s,sizeof(d)))? "match" : "mismatch");
- return 0;
-}
-
+++ /dev/null
-structures match
+++ /dev/null
-structures match
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include "tpl.h"
-
-const char *filename = "/tmp/test112.tpl";
-
-#define NUM 10
-
-struct st {
- int i;
- char c[8];
- double f;
- uint16_t v[2];
-};
-
-
-int main() {
- struct st s[NUM], d[NUM];
- tpl_node *tn;
- int i;
-
- memset(s, 0, sizeof(s)); /* clear s */
- memset(d, 0, sizeof(d)); /* clear d */
-
- /* fill s with random stuff */
- for(i=0; i < NUM; i++) {
- s[i].i = i; s[i].f = 3.14159 * i; s[i].v[0] = NUM*i; s[i].v[1] = NUM+i;
- strncpy(s[i].c, "abcdefg",8);
- s[i].c[0] += 1;
- }
-
- tn = tpl_map("S(ic#fv#)#", s, 8, 2, NUM);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("S(ic#fv#)#", d, 8, 2, NUM);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- /* see if the result is the same as the s */
- printf("structures %s\n", (!memcmp(d,s,sizeof(d)))? "match" : "mismatch");
- return 0;
-}
-
+++ /dev/null
-structures match
+++ /dev/null
-structures match
-A matches
-B matches
-C matches
-D matches
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include "tpl.h"
-
-const char *filename = "/tmp/test113.tpl";
-
-#define NUM 10
-
-struct st {
- int i;
- char c[8];
- double f;
- uint16_t v[2];
-};
-
-
-int main() {
- struct st s[NUM], t[NUM];
- tpl_node *tn;
- int i;
- int a=5,d=8, A, D;
- char b='6',c='7', B, C;
-
- memset(s, 0, sizeof(s)); /* clear s */
- memset(t, 0, sizeof(t)); /* clear t */
-
- /* fill s with random stuff */
- for(i=0; i < NUM; i++) {
- s[i].i = i; s[i].f = 3.14159 * i; s[i].v[0] = NUM*i; s[i].v[1] = NUM+i;
- strncpy(s[i].c, "abcdefg",8);
- s[i].c[0] += 1;
- }
-
- tn = tpl_map("icS(ic#fv#)#ci", &a, &b, s, 8, 2, NUM, &c, &d);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("icS(ic#fv#)#ci", &A, &B, t, 8, 2, NUM, &C, &D);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- /* see if the result is the same as the s */
- printf("structures %s\n", (!memcmp(t,s,sizeof(d)))? "match" : "mismatch");
- printf("A %s\n", (a==A)? "matches" : "mismatches");
- printf("B %s\n", (b==B)? "matches" : "mismatches");
- printf("C %s\n", (c==C)? "matches" : "mismatches");
- printf("D %s\n", (d==D)? "matches" : "mismatches");
- return 0;
-}
-
+++ /dev/null
-structures match
-A matches
-B matches
-C matches
-D matches
+++ /dev/null
-matrices match
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include "tpl.h"
-
-#define XDIM 10
-#define YDIM 2
-
-const char *filename = "/tmp/test114.tpl";
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int xy[XDIM][YDIM], XY[XDIM][YDIM];
- int i,j;
-
- tpl_hook.oops = printf;
-
- for(i=0; i<XDIM; i++) {
- for(j=0; j<YDIM; j++) {
- xy[i][j] = i+j;
- XY[i][j] = 0;
- }
- }
-
- tn = tpl_map("i##", xy, XDIM, YDIM);
- if (!tn) {
- printf("tpl_map failed; exiting\n");
- return -1;
- }
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("i##", XY, XDIM, YDIM);
- if (!tn) {
- printf("tpl_map failed; exiting\n");
- return -1;
- }
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- printf("matrices %s\n", (!memcmp(xy,XY,sizeof(xy))) ? "match" : "mismatch");
- return 0;
-}
+++ /dev/null
-matrices match
+++ /dev/null
-hello, world0
-hello, world1
-hello, world2
-hello, world3
-hello, world4
-hello, world5
-hello, world6
-hello, world7
-hello, world8
-hello, world9
-hello, world0, 0
-hello, world1, 1
-hello, world2, 2
-hello, world3, 3
-hello, world4, 4
-hello, world5, 5
-hello, world6, 6
-hello, world7, 7
-hello, world8, 8
-hello, world9, 9
-hello, world0, 0
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world1, 1
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world2, 2
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world3, 3
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world4, 4
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world5, 5
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world6, 6
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world7, 7
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world8, 8
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world9, 9
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "tpl.h"
-
-#define COUNT 10
-#define BUF_SIZE 256
-const char *filename = "/tmp/test115.tpl";
-
-typedef struct {
- char* s;
-} s1_t;
-
-
-typedef struct {
- char* s;
- int i;
-} s2_t;
-
-
-typedef struct {
- char c[BUF_SIZE];
- char* s;
- int i;
-} s3_t;
-
-
-const char hw[]="hello, world!";
-
-int main ()
-{
- tpl_node* tn;
- s1_t* s1, *S1;
- s2_t* s2, *S2;
- s3_t* s3, *S3;
- int i;
-
- /* case 1: */
- s1 = (s1_t*)calloc (sizeof (s1_t), COUNT);
- for(i=0; i < COUNT; i++) {
- s1[i].s = malloc(sizeof(hw));
- memcpy(s1[i].s, hw, sizeof(hw));
- s1[i].s[sizeof(hw)-2]='0'+i;
- }
- tn = tpl_map ("S(s)#", s1, COUNT);
- tpl_pack (tn, 0);
- tpl_dump (tn, TPL_FILE, filename);
- tpl_free (tn);
- for(i=0; i < COUNT; i++) free(s1[i].s);
-
- S1 = (s1_t*)calloc (sizeof (s1_t), COUNT);
- memset(S1, 0xff, sizeof(s1_t)*COUNT);
- tn = tpl_map ("S(s)#", S1, COUNT);
- tpl_load (tn, TPL_FILE, filename);
- tpl_unpack (tn, 0);
- tpl_free (tn);
-
- for(i=0; i<COUNT; i++) {
- printf("%s\n", S1[i].s);
- }
-
-
- /* case 2: */
- s2 = (s2_t*)calloc (sizeof (s2_t), COUNT);
- for(i=0; i < COUNT; i++) {
- s2[i].s = malloc(sizeof(hw));
- memcpy(s2[i].s, hw, sizeof(hw));
- s2[i].s[sizeof(hw)-2]='0'+i;
- s2[i].i=i;
- }
- tn = tpl_map ("S(si)#", s2, COUNT);
- tpl_pack (tn, 0);
- tpl_dump (tn, TPL_FILE, filename);
- tpl_free (tn);
- for(i=0; i < COUNT; i++) free(s2[i].s);
-
- S2 = (s2_t*)calloc (sizeof (s2_t), COUNT);
- memset(S2, 0xff, sizeof(s2_t)*COUNT);
- tn = tpl_map ("S(si)#", S2, COUNT);
- tpl_load (tn, TPL_FILE, filename);
- tpl_unpack (tn, 0);
- tpl_free (tn);
-
- for(i=0; i<COUNT; i++) {
- printf("%s, %u\n", S2[i].s, S2[i].i);
- }
-
-
- /* case 3: */
- s3 = (s3_t*)calloc (sizeof (s3_t), COUNT);
- for(i=0; i < COUNT; i++) {
- memset(s3[i].c, 'a', BUF_SIZE);
- s3[i].c[BUF_SIZE-1]='\0';
- s3[i].s = malloc(sizeof(hw));
- memcpy(s3[i].s, hw, sizeof(hw));
- s3[i].s[sizeof(hw)-2]='0'+i;
- s3[i].i=i;
- }
- tn = tpl_map ("S(c#si)#", s3, BUF_SIZE, COUNT);
- tpl_pack (tn, 0);
- tpl_dump (tn, TPL_FILE, filename);
- tpl_free (tn);
-
- S3 = (s3_t*)calloc (sizeof (s3_t), COUNT);
- memset(S3, 0xff, sizeof(s3_t)*COUNT);
- tn = tpl_map ("S(c#si)#", S3, BUF_SIZE, COUNT);
- tpl_load (tn, TPL_FILE, filename);
- tpl_unpack (tn, 0);
- tpl_free (tn);
-
- for(i=0; i<COUNT; i++) {
- printf("%s, %u\n", S3[i].s, S3[i].i);
- printf("%s\n", S3[i].c);
- }
-
- return 0;
-}
-
+++ /dev/null
-hello, world0
-hello, world1
-hello, world2
-hello, world3
-hello, world4
-hello, world5
-hello, world6
-hello, world7
-hello, world8
-hello, world9
-hello, world0, 0
-hello, world1, 1
-hello, world2, 2
-hello, world3, 3
-hello, world4, 4
-hello, world5, 5
-hello, world6, 6
-hello, world7, 7
-hello, world8, 8
-hello, world9, 9
-hello, world0, 0
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world1, 1
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world2, 2
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world3, 3
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world4, 4
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world5, 5
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world6, 6
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world7, 7
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world8, 8
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-hello, world9, 9
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+++ /dev/null
-1 a
-alpha
-beta
-gamma
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-#define NUM_STRS 3
-
-const char *filename = "/tmp/test116.tpl";
-
-int main() {
- tpl_node *tn;
- int i,d=1,D=-1;
- char c='a', C='0';
- char *strs[NUM_STRS] = {"alpha", "beta", "gamma"};
- char *STRS[NUM_STRS] = {"femto", "nano", "centi"};
-
- tn = tpl_map("cs#i", &c, strs, NUM_STRS, &d);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("cs#i", &C, STRS, NUM_STRS, &D);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- printf("%d %c\n", D, C);
- for(i=0;i<NUM_STRS;i++) printf("%s\n", STRS[i]);
-
- return 0;
-}
+++ /dev/null
-1 a
-alpha
-beta
-gamma
+++ /dev/null
-apple
-bpple
-cpple
-apple
-bpple
-cpple
-apple
-bpple
-cpple
-1 a
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "tpl.h"
-
-#define NUM_STRS 3
-#define NUM_ELMT 3
-#define STR "apple"
-#define SLEN 5
-
-const char *filename = "/tmp/test117.tpl";
-
-int main() {
- tpl_node *tn;
- int i,j,d=1,D=-1;
- char c='a', C='0';
- char *strs[NUM_STRS];
- char *STRS[NUM_STRS];
-
- tn = tpl_map("cA(s#)i", &c, strs, NUM_STRS, &d);
- for(i=0; i<NUM_ELMT; i++) { /* pack the same thing this many times*/
- for(j=0; j<NUM_STRS; j++) {/* each time just tweaking them a bit */
- strs[j] = malloc( SLEN+1 );
- memcpy(strs[j], STR, SLEN+1);
- strs[j][0] = 'a'+j;
- }
- tpl_pack(tn,1);
- }
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("cA(s#)i", &C, STRS, NUM_STRS, &D);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- while(tpl_unpack(tn,1)>0) {
- for(i=0;i<NUM_STRS;i++) {
- printf("%s\n", STRS[i]);
- free(STRS[i]);
- }
- }
- tpl_free(tn);
-
- printf("%d %c\n", D, C);
-
- return 0;
-}
+++ /dev/null
-apple
-bpple
-cpple
-apple
-bpple
-cpple
-apple
-bpple
-cpple
-1 a
+++ /dev/null
-format cA(i#)S(cf#)A(ci#)
-num_fxlens 3
-fxlens[0] 10
-fxlens[1] 5
-fxlens[2] 8
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define ILEN 10
-#define KLEN 8
-#define FLEN 5
-
-struct st {
- char c;
- double f[FLEN];
-};
-
-const char *filename = "/tmp/test118.tpl";
-
-int main() {
- tpl_node *tn;
- /* some meaningless test data */
- struct st s = {'z', {0.9, 0.8, 0.7, 0.6, 0.5 }};
- int j;
- int i[ILEN] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
- int k[KLEN] = {100, 200, 300, 400, 500, 600, 700, 800};
- char a = '&';
- char b = 'x';
- const char *fmt;
- uint32_t num_fxlens, *fxlens;
-
- tn = tpl_map("cA(i#)S(cf#)A(ci#)", &a, i, ILEN, &s, FLEN, &b, k, KLEN);
- tpl_pack(tn,0);
-
- tpl_pack(tn,1);
- for(j=0; j < ILEN; j++) i[j]--;
- tpl_pack(tn,1);
- for(j=0; j < ILEN; j++) i[j]--;
- tpl_pack(tn,1);
-
- tpl_pack(tn,2);
- b++;
- for(j=0; j < KLEN; j++) k[j] += 50;
- tpl_pack(tn,2);
- b++;
- for(j=0; j < KLEN; j++) k[j] += 50;
- tpl_pack(tn,2);
-
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- /* now peek at the fxlens */
- fmt = tpl_peek(TPL_FILE|TPL_FXLENS, filename, &num_fxlens, &fxlens);
- printf("format %s\n", fmt);
- printf("num_fxlens %u\n", num_fxlens);
- for(j=0; j<num_fxlens; j++) printf("fxlens[%u] %u\n", j, fxlens[j]);
- if (num_fxlens>0) free(fxlens);
- return(0);
-}
+++ /dev/null
-format cA(i#)S(cf#)A(ci#)
-num_fxlens 3
-fxlens[0] 10
-fxlens[1] 5
-fxlens[2] 8
+++ /dev/null
-size is 1726
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include "tpl.h"
-
-const char *filename = "/tmp/test119.tpl";
-
-#define NUM 100
-
-struct st {
- int i;
- char c;
- double f;
- uint16_t v[2];
-};
-
-
-int main() {
- struct st s[NUM], d[NUM];
- tpl_node *tn;
- int i;
- uint32_t sz=0;
-
- memset(s, 0, sizeof(s)); /* clear s */
- memset(d, 0, sizeof(d)); /* clear d */
-
- /* fill s with random stuff */
- for(i=0; i < NUM; i++) {
- s[i].i = i; s[i].c='a'+i; s[i].f = 3.14159 * i; s[i].v[0] = NUM*i; s[i].v[1] = NUM+i;
- }
-
- tn = tpl_map("S(icfv#)#", s, 2, NUM);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_GETSIZE,&sz);
- tpl_free(tn);
-
- printf("size is %u\n", sz);
-
- return 0;
-}
-
+++ /dev/null
-size is 1726
+++ /dev/null
-test12.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test12.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test12.tpl: not a valid tpl file
+++ /dev/null
-testing undersized output buffer... -1
-testing sufficient output buffer... 0
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,rc,j;
- char toosmall[10];
- char buf[60];
-
- tn = tpl_map("A(i)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- rc=tpl_dump(tn,TPL_MEM|TPL_PREALLOCD,toosmall,sizeof(toosmall));
- printf("testing undersized output buffer... %d \n", rc);
- rc=tpl_dump(tn,TPL_MEM|TPL_PREALLOCD,buf,sizeof(buf));
- printf("testing sufficient output buffer... %d \n", rc);
- tpl_free(tn);
-
- tn = tpl_map("A(i)",&j);
- tpl_load(tn,TPL_MEM|TPL_EXCESS_OK,buf,sizeof(buf));
- while (tpl_unpack(tn,1) > 0) printf("j is %d\n", j);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-tpl_dump: buffer too small, need 57 bytes
+++ /dev/null
-testing undersized output buffer... -1
-testing sufficient output buffer... 0
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
+++ /dev/null
-one
-two
-three
-eins
-zwei
-drei
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-const char *filename = "/tmp/test121.tpl";
-int main() {
- char *labels[2][3] = { {"one", "two", "three"},
- {"eins", "zwei", "drei" } };
- char *olabels[2][3] = { {NULL,NULL,NULL }, {NULL,NULL,NULL}};
- int i,j;
-
- tpl_node *tn;
- tn = tpl_map("s##", labels, 2, 3);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- tn = tpl_map("s##", olabels, 2, 3);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- for(i=0;i<2;i++) {
- for(j=0;j<3;j++) {
- printf("%s\n", olabels[i][j]);
- free(olabels[i][j]);
- }
- }
-
- return 0;
-}
+++ /dev/null
-one
-two
-three
-eins
-zwei
-drei
+++ /dev/null
-1 abc 3.140000 a 1
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "tpl.h"
-
-const char *filename = "/tmp/test122.tpl";
-
-typedef struct {
- char c;
- int i;
-} inner_t;
-
-typedef struct {
- int i;
- char c[3];
- double f;
- inner_t inner;
-} outer;
-
-int main() {
- tpl_node *tn;
- outer ms = {1, {'a','b','c'}, 3.14, {'a',1}};
- outer os;
-
- tn = tpl_map( "S(ic#f$(ci))", &ms, 3);
- tpl_pack( tn, 0 );
- tpl_dump( tn, TPL_FILE, filename );
- tpl_free( tn );
-
- memset(&os, 0, sizeof(outer));
- tn = tpl_map( "S(ic#f$(ci))", &os, 3);
- tpl_load( tn, TPL_FILE, filename );
- tpl_unpack( tn, 0 );
- tpl_free( tn );
-
- printf("%d %c%c%c %f %c %d\n", os.i, os.c[0],os.c[1],os.c[2],os.f,
- os.inner.c, os.inner.i);
-
- return(0);
-}
+++ /dev/null
-1 abc 3.140000 a 1
+++ /dev/null
-caught error!
+++ /dev/null
-#include <setjmp.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include "tpl.h"
-
-jmp_buf env;
-extern tpl_hook_t tpl_hook;
-
-int catch_oops(const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- longjmp(env,-1); /* return to setjmp point */
- return 0; /* not reached */
-}
-
-int main() {
- int err;
- tpl_node *tn;
- tpl_hook.oops = catch_oops; /* install fatal handler */
-
- err = setjmp(env); /* on error, control will return here */
- if (err) {
- printf("caught error!\n");
- return -1;
- }
-
- tn = tpl_map("@"); /* generate a fatal error */
- printf("program ending, without error\n");
- return 0;
-}
+++ /dev/null
-unsupported option @
+++ /dev/null
-caught error!
+++ /dev/null
-mapped
-freed
-abcdefghi first
-jklmnopqr second
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include "tpl.h"
-#define LEN 10
-
-const char *filename = "/tmp/test124.tpl";
-
-typedef struct {
- char name[LEN];
-} test_t;
-int main() {
- test_t t;
- char *s;
- tpl_node *tn;
-
- tn = tpl_map("A(S(c#)s)", &t, LEN, &s);
- printf("mapped\n");
-
- memcpy(t.name,"abcdefghi\0",10);
- s="first";
- tpl_pack(tn,1);
-
- memcpy(t.name,"jklmnopqr\0",10);
- s="second";
- tpl_pack(tn,1);
-
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
- printf("freed\n");
-
- tn = tpl_map("A(S(c#)s)", &t, LEN, &s);
- tpl_load(tn,TPL_FILE,filename);
- while(tpl_unpack(tn,1) > 0) {
- printf("%s %s\n", t.name, s);
- }
- tpl_free(tn);
- return 0;
-}
+++ /dev/null
-mapped
-freed
-abcdefghi first
-jklmnopqr second
+++ /dev/null
-test13.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test13.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test13.tpl: not a valid tpl file
+++ /dev/null
-test14.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test14.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test14.tpl: not a valid tpl file
+++ /dev/null
-test15.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test15.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test15.tpl: not a valid tpl file
+++ /dev/null
-test16.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test16.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test16.tpl: not a valid tpl file
+++ /dev/null
-test17.tpl: format signature mismatch
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(c)",&i);
- tpl_load(tn,TPL_FILE,"test17.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test17.tpl: format signature mismatch
+++ /dev/null
-failed to parse A(i
-tpl map failed
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i=-1;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i",&i);
- printf("tpl map %s\n", tn ? "succeeded" : "failed");
- return(0);
-}
+++ /dev/null
-failed to parse A(i
-tpl map failed
+++ /dev/null
-failed to parse A(i))
-tpl map failed
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i=-1;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i))",&i);
- printf("tpl map %s\n", tn ? "succeeded" : "failed");
- return(0);
-}
+++ /dev/null
-failed to parse A(i))
-tpl map failed
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,j=-1;
-
- tn = tpl_map("i",&i);
- i=1;
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test2.tpl");
- tpl_free(tn);
-
- tn = tpl_map("i",&j);
- tpl_load(tn,TPL_FILE,"/tmp/test2.tpl");
- tpl_unpack(tn,0);
- printf("j is %d\n", j);
- tpl_free(tn);
- return(0);
-
-}
+++ /dev/null
-failed to parse iA()
-tpl map failed
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("iA()",&i);
- printf("tpl map %s\n", tn ? "succeeded" : "failed");
- return(0);
-}
+++ /dev/null
-failed to parse iA()
-tpl map failed
+++ /dev/null
-i,j are 0,1
-i,j are 2,3
-i,j are 4,5
-i,j are 6,7
-i,j are 8,9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,j=-1;
-
- tn = tpl_map("A(ii)",&i,&j);
- for(i=0,j=1;i<10;i+=2,j+=2) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test21.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(ii)",&i,&j);
- tpl_load(tn,TPL_FILE,"/tmp/test21.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i,j are %d,%d\n", i,j);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i,j are 0,1
-i,j are 2,3
-i,j are 4,5
-i,j are 6,7
-i,j are 8,9
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- unsigned i;
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test22.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn,TPL_FILE,"/tmp/test22.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int main() {
- tpl_node *tn;
- unsigned i;
- char *file = "/tmp/test23.tpl";
- int fd;
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE, file);
- tpl_free(tn);
-
- if ( (fd=open( file,O_RDONLY)) == -1) {
- printf("failed to open %s: %s", file, strerror(errno));
- }
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd);
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int main() {
- tpl_node *tn;
- unsigned i;
- char *file = "test24.tpl";
- int fd;
-
- if ( (fd=open( file,O_RDONLY)) == -1) {
- printf("failed to open %s: %s", file, strerror(errno));
- exit(-1);
- }
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd);
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-test25.tpl: not a valid tpl file
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- unsigned i;
- char *file = "test25.tpl";
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(u)",&i);
- if (tpl_load(tn, TPL_FILE, file) < 0 ) {
- tpl_free(tn);
- exit(-1);
- }
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test25.tpl: not a valid tpl file
+++ /dev/null
-3 tpls gathered.
-999045 is their sum.
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/select.h>
-#include "tpl.h"
-
-#define DEBUG 0
-
-int num_tpls = 0, sum_tpls = 0;
-
-int tpl_cb(void *tpl, size_t tpllen, void*data) {
- int i;
- tpl_node *tn;
-
- if (DEBUG) printf("obtained tpl of length %d\n", (int)tpllen);
- tn = tpl_map("A(i)", &i);
- tpl_load(tn, TPL_MEM, tpl, tpllen);
- num_tpls++;
- while (tpl_unpack(tn,1) > 0) sum_tpls += i;
- tpl_free(tn);
- return 0;
-
-}
-
-int main() {
- FILE *f1,*f2;
- int fdflags,fd,fd1,fd2;
- int selrc, maxfd;
- tpl_gather_t *gs1=NULL,*gs2=NULL,**gs;
-
- struct timeval tv;
- fd_set rset;
-
- f1 = popen("cat test26_0.tpl;sleep 1; cat test26_1.tpl", "r");
- fd1 = fileno(f1);
- fdflags = fcntl(fd1, F_GETFL, 0);
- fcntl( fd1, F_SETFL, fdflags | O_NONBLOCK);
-
- f2 = popen("cat test26_2.tpl;sleep 1; cat test26_3.tpl", "r");
- fd2 = fileno(f2);
- fdflags = fcntl(fd2, F_GETFL, 0);
- fcntl( fd2, F_SETFL, fdflags | O_NONBLOCK);
-
- while (1) {
- FD_ZERO( &rset );
- if (fd1 >= 0) FD_SET( fd1, &rset );
- if (fd2 >= 0) FD_SET( fd2, &rset );
-
- if (fd1 == -1 && fd2 == -1) {
- printf("%d tpls gathered.\n",num_tpls);
- printf("%d is their sum.\n",sum_tpls);
- return(0);
- }
-
- maxfd=0;
- if (fd1>maxfd) maxfd = fd1;
- if (fd2>maxfd) maxfd = fd2;
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
-
- selrc = select(maxfd+1, &rset, NULL, NULL, &tv );
- if (selrc == -1) {
- perror("select()");
- } else if (selrc) {
- for(fd=0;fd<maxfd+1;fd++) {
- if ( FD_ISSET(fd, &rset) ) {
- if (DEBUG) printf("fd %d readable\n", fd);
- gs = (fd1 == fd) ? &gs1 : &gs2;
- if (tpl_gather(TPL_GATHER_NONBLOCKING,fd,gs,tpl_cb,NULL) <= 0) {
- if (fd1 == fd) {pclose(f1); fd1 = -1; }
- if (fd2 == fd) {pclose(f2); fd2 = -1; }
- } else {
- if (DEBUG) printf("tpl_gather >0\n");
- }
- }
- }
- } else {
- if (DEBUG) printf("timeout\n");
- }
- }
- return(0);
-}
+++ /dev/null
-3 tpls gathered.
-999045 is their sum.
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int main() {
- tpl_node *tn;
- unsigned i,perms;
- char *file = "/tmp/test27.tpl";
- int fd;
-
- perms = S_IRUSR|S_IWUSR;
- if ( (fd=open( file,O_RDWR|O_CREAT|O_TRUNC,perms)) == -1) {
- printf("failed to open %s: %s", file, strerror(errno));
- exit(-1);
- }
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd);
- tpl_free(tn);
-
- lseek(fd,0,SEEK_SET); /* re-position fd to start of file */
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd);
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-sum is 49995000
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int main() {
- tpl_node *tn;
- unsigned i, sum=0;
- int fd[2], pid;
-
- pipe(fd);
- if ( (pid = fork()) == 0) { /* child */
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd[0]);
- while (tpl_unpack(tn,1) > 0) sum += i;
- tpl_free(tn);
- printf("sum is %d\n", sum);
-
- } else if (pid > 0) { /* parent */
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10000;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd[1] );
- tpl_free(tn);
-
- waitpid(pid,NULL,0);
-
- } else if (pid == -1) {
- perror("fork error");
- }
- return(0);
-}
+++ /dev/null
-sum is 49995000
+++ /dev/null
-sum is 49995000
-abcdefghijklmnopqrstuvwxyz
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int main() {
- tpl_node *tn;
- unsigned i, sum=0;
- int fd[2], pid;
- char c;
-
- pipe(fd);
- if ( (pid = fork()) == 0) { /* child */
-
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd[0]);
- while (tpl_unpack(tn,1) > 0) sum += i;
- tpl_free(tn);
- printf("sum is %d\n", sum);
-
- tn = tpl_map("A(c)",&c);
- tpl_load(tn, TPL_FD, fd[0]);
- while (tpl_unpack(tn,1) > 0) printf("%c",c);
- tpl_free(tn);
- printf("\n");
-
- } else if (pid > 0) { /* parent */
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10000;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd[1] );
- tpl_free(tn);
-
- tn = tpl_map("A(c)",&c);
- for(c='a';c<='z';c++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd[1] );
- tpl_free(tn);
-
- waitpid(pid,NULL,0);
-
- } else if (pid == -1) {
- perror("fork error");
- }
- return(0);
-}
+++ /dev/null
-sum is 49995000
-abcdefghijklmnopqrstuvwxyz
+++ /dev/null
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,j=-1;
-
- tn = tpl_map("A(i)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test3.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(i)",&j);
- tpl_load(tn,TPL_FILE,"/tmp/test3.tpl");
- while (tpl_unpack(tn,1) > 0) printf("j is %d\n", j);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
+++ /dev/null
-buffer length: 4
-good
+++ /dev/null
-#include "tpl.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-int main(int argc, char*argv[]) {
- tpl_bin bin;
- tpl_node *tn;
- int i;
- char *file = "/tmp/test30.tpl";
- char str[10];
-
- strcpy(str,"good egg");
- bin.addr = str;
- bin.sz = 4; /* just going to pack 'good' (no NUL) */
-
- tn = tpl_map("B", &bin);
- tpl_pack(tn,0);
- memset(str,0,10); /* just to test that buf was copied */
- tpl_dump(tn,TPL_FILE,file);
- tpl_free(tn);
-
- bin.addr = NULL;
- bin.sz = 0;
-
- tn = tpl_map("B", &bin);
- tpl_load(tn,TPL_FILE,file);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- /* print the buffer char-by-char ; its not a nul-termd string */
- printf("buffer length: %u\n", bin.sz);
- for(i=0; i < bin.sz; i++) printf("%c", ((char*)bin.addr)[i]);
- printf("\n");
-
- if (bin.sz > 0)
- free(bin.addr); /* malloc'd for us by tpl_unpack, we must free */
- return(0);
-}
-
+++ /dev/null
-buffer length: 4
-good
+++ /dev/null
-buffer length: 0
-
+++ /dev/null
-#include "tpl.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-int main(int argc, char*argv[]) {
- tpl_bin bin;
- tpl_node *tn;
- int i;
- char *file = "/tmp/test31.tpl";
-
- bin.addr = NULL;
- bin.sz = 0;
-
- tn = tpl_map("B", &bin);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,file);
- tpl_free(tn);
-
- /* load these two fields with bogus values to test that tpl_unpack
- * sets them back to NULL, and 0 respectively. */
- bin.addr = file;
- bin.sz = 4;
-
- tn = tpl_map("B", &bin);
- tpl_load(tn,TPL_FILE,file);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- /* print the buffer char-by-char ; its not a nul-termd string */
- printf("buffer length: %u\n", bin.sz);
- for(i=0; i < bin.sz; i++) printf("%c", ((char*)bin.addr)[i]);
- printf("\n");
-
- if (bin.sz > 0)
- free(bin.addr); /* malloc'd for us by tpl_unpack, we must free */
- return(0);
-}
-
+++ /dev/null
-buffer length: 0
-
+++ /dev/null
-buffer length: 4
-good
-buffer length: 4
-ood
-buffer length: 4
-od e
-buffer length: 4
-d eg
-buffer length: 4
- egg
+++ /dev/null
-#include "tpl.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-int main(int argc, char*argv[]) {
- tpl_bin bin;
- tpl_node *tn;
- int i;
- char *file = "/tmp/test32.tpl";
- char str[10];
-
- strcpy(str,"good egg");
- bin.addr = str;
- bin.sz = 4; /* just going to pack 'good' (no NUL) */
-
- tn = tpl_map("A(B)", &bin);
- for(i=0; i < 5; i++) {
- tpl_pack(tn,1);
- bin.addr = (char*)(bin.addr) + 1;
- }
- memset(str,0,10); /* just to test that buf was copied */
- tpl_dump(tn,TPL_FILE,file);
- tpl_free(tn);
-
- bin.addr = NULL;
- bin.sz = 0;
-
- tn = tpl_map("A(B)", &bin);
- tpl_load(tn,TPL_FILE,file);
- while (tpl_unpack(tn,1) > 0) {
- /* print the buffer char-by-char ; its not a nul-termd string */
- printf("buffer length: %u\n", bin.sz);
- for(i=0; i < bin.sz; i++) printf("%c", ((char*)bin.addr)[i]);
- printf("\n");
-
- if (bin.sz > 0)
- free(bin.addr); /* malloc'd for us by tpl_unpack, we must free */
- }
- tpl_free(tn);
- return(0);
-
-}
-
+++ /dev/null
-buffer length: 4
-good
-buffer length: 4
-ood
-buffer length: 4
-od e
-buffer length: 4
-d eg
-buffer length: 4
- egg
+++ /dev/null
-sizeof(double) is 8
-y is 1.000000
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- double x,y;
-
- printf("sizeof(double) is %d\n", (int)sizeof(double));
-
- tn = tpl_map("f",&x);
- x=1.0;
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test33.tpl");
- tpl_free(tn);
-
- tn = tpl_map("f",&y);
- tpl_load(tn,TPL_FILE,"/tmp/test33.tpl");
- tpl_unpack(tn,0);
- printf("y is %.6f\n", y);
- tpl_free(tn);
-
- return(0);
-}
+++ /dev/null
-sizeof(double) is 8
-y is 1.000000
+++ /dev/null
-sizeof(double) is 8
-y is 1.000000
-y is 1.666667
-y is 2.333333
-y is 3.000000
-y is 3.666667
-y is 4.333333
-y is 5.000000
-y is 5.666667
-y is 6.333333
-y is 7.000000
-y is 7.666667
-y is 8.333333
-y is 9.000000
-y is 9.666667
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- double x,y;
-
- printf("sizeof(double) is %d\n", (int)sizeof(double));
-
- tn = tpl_map("A(f)",&x);
- for( x=1.0; x < 10.0; x += 2/3.0) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test34.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(f)",&y);
- tpl_load(tn,TPL_FILE,"/tmp/test34.tpl");
- while (tpl_unpack(tn,1) > 0) printf("y is %.6f\n", y);
- tpl_free(tn);
-
- return(0);
-}
+++ /dev/null
-sizeof(double) is 8
-y is 1.000000
-y is 1.666667
-y is 2.333333
-y is 3.000000
-y is 3.666667
-y is 4.333333
-y is 5.000000
-y is 5.666667
-y is 6.333333
-y is 7.000000
-y is 7.666667
-y is 8.333333
-y is 9.000000
-y is 9.666667
+++ /dev/null
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- int id;
- char *name, *names[] = { "joe", "bob", "cary" };
-
- tn = tpl_map("A(is)", &id, &name);
-
- for(id=0,name=names[id]; id < 3; name=names[++id])
- tpl_pack(tn,1);
-
- tpl_dump(tn, TPL_FILE, "/tmp/test35.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-id 0, user joe
-id 1, user bob
-id 2, user cary
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- int id;
- char *name;
-
- tn = tpl_map("A(is)", &id, &name);
- tpl_load(tn, TPL_FILE, "/tmp/test35.tpl");
-
- while ( tpl_unpack(tn,1) > 0 ) {
- printf("id %d, user %s\n", id, name);
- free(name);
- }
-
- tpl_free(tn);
- return(0);
-}
-
-
+++ /dev/null
-id 0, user joe
-id 1, user bob
-id 2, user cary
+++ /dev/null
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,j;
-
- tn = tpl_map("A(A(i))",&j);
-
- for(i=2;i<4;i++) {
-
- for(j=i; j < 10*i; j *= i) {
- tpl_pack(tn,2);
- }
- tpl_pack(tn,1);
- }
-
- tpl_dump(tn, TPL_FILE, "/tmp/test37.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-unpacking index 1:
- unpacking index 2: j is 2
- unpacking index 2: j is 4
- unpacking index 2: j is 8
- unpacking index 2: j is 16
-unpacking index 1:
- unpacking index 2: j is 3
- unpacking index 2: j is 9
- unpacking index 2: j is 27
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int j;
-
- tn = tpl_map("A(A(i))",&j);
- tpl_load(tn,TPL_FILE, "/tmp/test37.tpl");
-
- while (tpl_unpack(tn,1) > 0) {
- printf("unpacking index 1:\n");
- while (tpl_unpack(tn,2) > 0) {
- printf(" unpacking index 2: j is %d\n", j);
- }
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-unpacking index 1:
- unpacking index 2: j is 2
- unpacking index 2: j is 4
- unpacking index 2: j is 8
- unpacking index 2: j is 16
-unpacking index 1:
- unpacking index 2: j is 3
- unpacking index 2: j is 9
- unpacking index 2: j is 27
+++ /dev/null
-test39.tpl: not a valid tpl file
-load failed (rc=-1)
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i, rc;
-
- tpl_hook.oops = printf;
-
- tn = tpl_map("A(i)",&i);
- rc = tpl_load(tn,TPL_FILE,"test39.tpl");
- printf("load %s (rc=%d)\n", (rc >= 0 ? "ok" : "failed"), rc);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-test39.tpl: not a valid tpl file
-load failed (rc=-1)
+++ /dev/null
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i,j=-1;
- void *addr;
- int sz;
-
- tn = tpl_map("A(i)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_MEM,&addr,&sz);
- tpl_free(tn);
-
- tn = tpl_map("A(i)",&j);
- tpl_load(tn,TPL_MEM,addr,sz);
- while (tpl_unpack(tn,1) > 0) printf("j is %d\n", j);
- tpl_free(tn);
- free(addr);
- return(0);
-}
+++ /dev/null
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
+++ /dev/null
-#include "tpl.h"
-
-int main() {
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(A(c))", &c);
-
- for(c='a'; c<'c'; c++) tpl_pack(tn,2);
- tpl_pack(tn, 1);
-
- for(c='1'; c<'4'; c++) tpl_pack(tn,2);
- tpl_pack(tn, 1);
-
- tpl_dump(tn, TPL_FILE, "/tmp/test40.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-a b
-1 2 3
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-int main() {
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(A(c))", &c);
-
- tpl_load(tn, TPL_FILE, "/tmp/test40.tpl");
- while (tpl_unpack(tn,1) > 0) {
- while (tpl_unpack(tn,2) > 0) printf("%c ",c);
- printf("\n");
- }
- tpl_free(tn);
- return(0);
-}
-
+++ /dev/null
-a b
-1 2 3
+++ /dev/null
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- char id;
- char *name, *names[] = { "joe", "bob", "cary" };
-
- tn = tpl_map("A(cs)", &id, &name);
-
- for(id=0,name=names[(int)id]; id < 3; name=names[(int)++id])
- tpl_pack(tn,1);
-
- tpl_dump(tn, TPL_FILE, "/tmp/test42.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- char id;
- tpl_bin bin;
-
- char *junk = "0123456789";
- bin.sz = 10;
- bin.addr = junk;
-
- tn = tpl_map("A(cB)", &id, &bin);
-
- for(id=0; id < 3; ++id)
- tpl_pack(tn,1); /* pack same bin buffer, doesn't matter */
-
- tpl_dump(tn, TPL_FILE, "/tmp/test43.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-#include "tpl.h"
-
-int main(int argc, char *argv[]) {
- tpl_node *tn;
- char id,j;
- tpl_bin bin;
-
- char *junk = "0123456789";
- bin.sz = 10;
- bin.addr = junk;
-
- tn = tpl_map("A(cA(B))", &id, &bin);
-
- for(id=0; id < 3; ++id) {
- for(j=0;j<2;j++)
- tpl_pack(tn,2); /* pack same bin buffer, doesn't matter */
- tpl_pack(tn,1);
- }
-
- tpl_dump(tn, TPL_FILE, "/tmp/test44.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-x is 0.500000
-y is 0.500000
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- double x=0.5,y=0.0;
-
- tn = tpl_map("f",&x);
- tpl_pack(tn,0);
- printf("x is %f\n", x);
- tpl_dump(tn,TPL_FILE,"/tmp/test45.tpl");
- tpl_free(tn);
-
- tn = tpl_map("f",&y);
- tpl_load(tn,TPL_FILE,"/tmp/test45.tpl");
- tpl_unpack(tn,0);
- printf("y is %f\n", y);
- tpl_free(tn);
- return(0);
-
-}
+++ /dev/null
-x is 0.500000
-y is 0.500000
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- double x;
-
- tn = tpl_map("A(f)",&x);
- for(x=0.0;x<1.0;x+=0.2) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test46.tpl");
- tpl_free(tn);
-
- return(0);
-}
+++ /dev/null
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map( "A(i)", &i );
- for( i=0; i<10; i++ ) {
- tpl_pack( tn, 1 );
- }
- tpl_dump( tn, TPL_FILE, "/tmp/test47.tpl" );
- tpl_free( tn );
- return(0);
-}
+++ /dev/null
-0 1 2 3 4 5 6 7 8 9
\ No newline at end of file
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map( "A(i)", &i );
- tpl_load( tn, TPL_FILE, "/tmp/test47.tpl" );
- while (tpl_unpack( tn, 1 ) > 0) {
- printf("%d ", i);
- }
- tpl_free( tn );
- return(0);
-}
+++ /dev/null
-0 1 2 3 4 5 6 7 8 9
\ No newline at end of file
+++ /dev/null
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- char *s;
-
- tn = tpl_map( "A(s)", &s );
-
- s = "bob";
- tpl_pack(tn, 1);
-
- s = "betty";
- tpl_pack(tn, 1);
-
- tpl_dump(tn, TPL_FILE, "/tmp/test49.tpl");
- tpl_free(tn);
- return(0);
- }
+++ /dev/null
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 16
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 16
-j is 17
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 16
-j is 17
-j is 18
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int o,i,j=-1;
- void *addr;
- int sz;
-
- tn = tpl_map("A(A(i))",&i);
- for(o=0;o<10;o++) {
- for(i=o; i < o+10; i++) tpl_pack(tn,2);
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_MEM,&addr,&sz);
- tpl_free(tn);
-
- tn = tpl_map("A(A(i))",&j);
- tpl_load(tn,TPL_MEM,addr,sz);
- while (tpl_unpack(tn,1) > 0) {
- while (tpl_unpack(tn,2) > 0) printf("j is %d\n", j);
- }
- tpl_free(tn);
- free(addr);
- return(0);
-}
+++ /dev/null
-j is 0
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 1
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 2
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 3
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 4
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 5
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 6
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 7
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 16
-j is 8
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 16
-j is 17
-j is 9
-j is 10
-j is 11
-j is 12
-j is 13
-j is 14
-j is 15
-j is 16
-j is 17
-j is 18
+++ /dev/null
-bob
-betty
+++ /dev/null
- #include <stdio.h>
- #include <stdlib.h>
- #include "tpl.h"
-
- int main() {
- tpl_node *tn;
- char *s;
-
- tn = tpl_map( "A(s)", &s );
- tpl_load( tn, TPL_FILE, "/tmp/test49.tpl" );
-
- while (tpl_unpack( tn, 1 ) > 0) {
- printf("%s\n", s);
- free(s); /* important! */
- }
-
- tpl_free(tn);
- return(0);
- }
+++ /dev/null
-bob
-betty
+++ /dev/null
-num_tpls: 4, sum: 180
+++ /dev/null
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "tpl.h"
-
-#define DEBUG 0
-#define FILE_BUFLEN 500
-
-int num_tpls = 0, sum_tpls = 0;
-
-int tpl_cb(void *tpl, size_t tpllen, void*data) {
- int i;
- tpl_node *tn;
-
- if (DEBUG) printf("obtained tpl of length %d\n", (int)tpllen);
- tn = tpl_map("A(i)", &i);
- tpl_load(tn, TPL_MEM, tpl, tpllen);
- num_tpls++;
- while (tpl_unpack(tn,1) > 0) sum_tpls += i;
- tpl_free(tn);
- return 0;
-
-}
-
-int main(int argc, char *argv[]) {
- char *files[] = {"test51_0.tpl", "test51_1.tpl", "test51_2.tpl", "test51_3.tpl","test51_4.tpl", NULL};
- char **f;
- char buf[FILE_BUFLEN];
- int rc,fd;
- tpl_gather_t *gs=NULL;
-
- for (f = files; *f; f++) {
- if (DEBUG) printf("file is %s\n", *f);
- if ( ( fd = open(*f, O_RDONLY) ) == -1) {
- printf("error - can't open %s: %s\n", *f, strerror(errno));
- exit(-1);
- }
- rc = read(fd,&buf,FILE_BUFLEN); /* read whole file (no points for style) */
- if (rc == -1) {
- printf("error - can't read %s: %s\n", *f, strerror(errno));
- exit(-1);
- }
- if (tpl_gather(TPL_GATHER_MEM,buf, rc, &gs, tpl_cb, NULL) <= 0) {
- printf("tpl_gather_mem returned <= 0, exiting\n");
- exit(-1);
- }
- close(fd);
- }
- printf("num_tpls: %d, sum: %d\n", num_tpls, sum_tpls);
- return(0);
-}
+++ /dev/null
-num_tpls: 4, sum: 180
+++ /dev/null
-----------
---> j is 1
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int j;
-
- tn = tpl_map("A(A(i))",&j);
-
- j=1;
- tpl_pack(tn,2);
- tpl_pack(tn,1);
- j=2;
- tpl_pack(tn,2);
- /* omit packing parent */
-
- tpl_dump(tn, TPL_FILE, "/tmp/test52.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(A(i))",&j);
- tpl_load(tn, TPL_FILE, "/tmp/test52.tpl");
- while(tpl_unpack(tn,1) > 0) {
- printf("----------\n");
- while(tpl_unpack(tn,2) > 0) {
- printf("--> j is %d\n", j);
- }
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-----------
---> j is 1
+++ /dev/null
-----------
---> j is 1
-----------
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int j;
-
- tn = tpl_map("A(A(i))",&j);
-
- j=1;
- tpl_pack(tn,2);
- tpl_pack(tn,1);
- /* j=2; */
- /* tpl_pack(tn,2); */
- tpl_pack(tn,1); /* pack zero-length nested array */
-
- tpl_dump(tn, TPL_FILE, "/tmp/test53.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(A(i))",&j);
- tpl_load(tn, TPL_FILE, "/tmp/test53.tpl");
- while(tpl_unpack(tn,1) > 0) {
- printf("----------\n");
- while(tpl_unpack(tn,2) > 0) {
- printf("--> j is %d\n", j);
- }
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-----------
---> j is 1
-----------
+++ /dev/null
-tpl_mem_gather aborted by app callback
-tpl_gather_mem returned <= 0, exiting
+++ /dev/null
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "tpl.h"
-
-#define DEBUG 0
-#define FILE_BUFLEN 500
-
-extern tpl_hook_t tpl_hook;
-int num_tpls = 0, sum_tpls = 0;
-
-int tpl_cb(void *tpl, size_t tpllen, void*data) {
- int i;
- tpl_node *tn;
-
- tpl_hook.oops = printf;
-
- if (DEBUG) printf("obtained tpl of length %d\n", (int)tpllen);
- tn = tpl_map("A(i)", &i);
- tpl_load(tn, TPL_MEM, tpl, tpllen);
- num_tpls++;
- while (tpl_unpack(tn,1) > 0) sum_tpls += i;
- tpl_free(tn);
- /* this next line is a hack to test the callback's ability
- * to abort further tpl processing by returning < 0 */
- if (num_tpls == 3) return -1;
- return 0;
-
-}
-
-int main(int argc, char *argv[]) {
- char *files[] = {"test54_0.tpl", "test54_1.tpl", "test54_2.tpl", "test54_3.tpl","test54_4.tpl", NULL};
- char **f;
- char buf[FILE_BUFLEN];
- int rc,fd;
- tpl_gather_t *gs=NULL;
-
- for (f = files; *f; f++) {
- if (DEBUG) printf("file is %s\n", *f);
- if ( ( fd = open(*f, O_RDONLY) ) == -1) {
- printf("error - can't open %s: %s\n", *f, strerror(errno));
- exit(-1);
- }
- rc = read(fd,&buf,FILE_BUFLEN); /* read whole file (no points for style) */
- if (rc == -1) {
- printf("error - can't read %s: %s\n", *f, strerror(errno));
- exit(-1);
- }
- if (tpl_gather(TPL_GATHER_MEM,buf, rc, &gs, tpl_cb, NULL) <= 0) {
- printf("tpl_gather_mem returned <= 0, exiting\n");
- exit(-1);
- }
- close(fd);
- }
- printf("num_tpls: %d, sum: %d\n", num_tpls, sum_tpls);
- return(0);
-}
+++ /dev/null
-tpl_mem_gather aborted by app callback
-tpl_gather_mem returned <= 0, exiting
+++ /dev/null
-tpl_fd_gather aborted by app callback
-2 tpls gathered.
-499545 is their sum.
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/select.h>
-#include "tpl.h"
-
-#define DEBUG 0
-
-extern tpl_hook_t tpl_hook;
-int num_tpls = 0, sum_tpls = 0;
-
-int tpl_cb(void *tpl, size_t tpllen, void*data) {
- int i;
- tpl_node *tn;
-
- tpl_hook.oops = printf;
-
- if (DEBUG) printf("obtained tpl of length %d\n", (int)tpllen);
- tn = tpl_map("A(i)", &i);
- tpl_load(tn, TPL_MEM, tpl, tpllen);
- num_tpls++;
- while (tpl_unpack(tn,1) > 0) sum_tpls += i;
- tpl_free(tn);
- /* this next line is a hack to test the callback's ability
- * to abort further tpl processing by returning < 0 */
- if (num_tpls == 1) return -1;
- return 0;
-
-}
-
-int main() {
- FILE *f1,*f2;
- int fdflags,fd,fd1,fd2;
- int selrc, maxfd;
- tpl_gather_t *gs1=NULL,*gs2=NULL,**gs;
- struct timeval tv;
- fd_set rset;
-
-
- f1 = popen("cat test26_0.tpl;sleep 1; cat test26_1.tpl", "r");
- fd1 = fileno(f1);
- fdflags = fcntl(fd1, F_GETFL, 0);
- fcntl( fd1, F_SETFL, fdflags | O_NONBLOCK);
-
- f2 = popen("cat test26_2.tpl;sleep 1; cat test26_3.tpl", "r");
- fd2 = fileno(f2);
- fdflags = fcntl(fd2, F_GETFL, 0);
- fcntl( fd2, F_SETFL, fdflags | O_NONBLOCK);
-
- while (1) {
- FD_ZERO( &rset );
- if (fd1 >= 0) FD_SET( fd1, &rset );
- if (fd2 >= 0) FD_SET( fd2, &rset );
-
- if (fd1 == -1 && fd2 == -1) {
- printf("%d tpls gathered.\n",num_tpls);
- printf("%d is their sum.\n",sum_tpls);
- return(0);
- }
-
- maxfd=0;
- if (fd1>maxfd) maxfd = fd1;
- if (fd2>maxfd) maxfd = fd2;
-
- tv.tv_sec = 5;
- tv.tv_usec = 0;
-
- selrc = select(maxfd+1, &rset, NULL, NULL, &tv );
- if (selrc == -1) {
- perror("select()");
- } else if (selrc) {
- for(fd=0;fd<maxfd+1;fd++) {
- if ( FD_ISSET(fd, &rset) ) {
- if (DEBUG) printf("fd %d readable\n", fd);
- gs = (fd1 == fd) ? &gs1 : &gs2;
- if (tpl_gather(TPL_GATHER_NONBLOCKING,fd,gs,tpl_cb,NULL) <= 0) {
- if (fd1 == fd) {pclose(f1); fd1 = -1; }
- if (fd2 == fd) {pclose(f2); fd2 = -1; }
- } else {
- if (DEBUG) printf("tpl_gather >0\n");
- }
- }
- }
- } else {
- if (DEBUG) printf("timeout\n");
- }
- }
- return(0);
-}
+++ /dev/null
-tpl_fd_gather aborted by app callback
-2 tpls gathered.
-499545 is their sum.
+++ /dev/null
-hs2.s1 length: 5
-hs2.s1: draco
-hs2.s2 length: 2
-hs2.s2: po
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define S1_LEN 6
-#define S2_LEN 4
-
-struct has_strings {
- char a;
- char s1[S1_LEN];
- char s2[S2_LEN];
-};
-
-int main(int argc,char*argv[]) {
- tpl_node *tn;
- struct has_strings hs,hs2;
- void *img;
- size_t sz;
-
- strncpy(hs.s1, "draco",S1_LEN);
- strncpy(hs.s2, "po",S2_LEN);
-
- tn = tpl_map("c#c#", hs.s1, S1_LEN, hs.s2, S2_LEN);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_MEM,&img,&sz);
- tpl_free(tn);
-
- /* unpack */
-
- tn = tpl_map("c#c#", hs2.s1, S1_LEN, hs2.s2, S2_LEN);
- tpl_load(tn,TPL_MEM,img,sz);
- tpl_unpack(tn,0);
- tpl_free(tn);
- free(img);
-
- printf("hs2.s1 length: %d\n", (int)strlen(hs2.s1));
- printf("hs2.s1: %s\n", hs2.s1);
- printf("hs2.s2 length: %d\n", (int)strlen(hs2.s2));
- printf("hs2.s2: %s\n", hs2.s2);
- return(0);
-}
+++ /dev/null
-hs2.s1 length: 5
-hs2.s1: draco
-hs2.s2 length: 2
-hs2.s2: po
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define S1_LEN 6
-#define S2_LEN 4
-
-struct has_strings {
- char a;
- char s1[S1_LEN];
- char s2[S2_LEN];
-};
-
-int main(int argc,char*argv[]) {
- tpl_node *tn;
- struct has_strings hs;
-
- strncpy(hs.s1, "draco",S1_LEN);
- strncpy(hs.s2, "po",S2_LEN);
-
- tn = tpl_map("c#c#", hs.s1, S1_LEN, hs.s2, S2_LEN);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test57.tpl");
- tpl_free(tn);
-
- return(0);
-}
+++ /dev/null
-hs.s1 length: 5
-hs.s1: draco
-hs.s2 length: 2
-hs.s2: po
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define S1_LEN 6
-#define S2_LEN 4
-
-struct has_strings {
- char a;
- char s1[S1_LEN];
- char s2[S2_LEN];
-};
-
-int main(int argc,char*argv[]) {
- tpl_node *tn;
- struct has_strings hs;
-
- tn = tpl_map("c#c#", hs.s1, S1_LEN, hs.s2, S2_LEN);
- tpl_load(tn,TPL_FILE,"/tmp/test57.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- printf("hs.s1 length: %d\n", (int)strlen(hs.s1));
- printf("hs.s1: %s\n", hs.s1);
- printf("hs.s2 length: %d\n", (int)strlen(hs.s2));
- printf("hs.s2: %s\n", hs.s2);
-
- return(0);
-}
+++ /dev/null
-hs.s1 length: 5
-hs.s1: draco
-hs.s2 length: 2
-hs.s2: po
+++ /dev/null
-hs2.a: t
-hs2.s1 length: 5
-hs2.s1: draco
-hs2.b: h
-hs2.s2 length: 2
-hs2.s2: po
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define S1_LEN 6
-#define S2_LEN 4
-
-struct has_strings {
- char a;
- char s1[S1_LEN];
- char b;
- char s2[S2_LEN];
-};
-
-int main(int argc,char*argv[]) {
- tpl_node *tn;
- struct has_strings hs,hs2;
- void *img;
- size_t sz;
-
- strncpy(hs.s1, "draco",S1_LEN);
- strncpy(hs.s2, "po",S2_LEN);
- hs.a = 't';
- hs.b = 'h';
-
- tn = tpl_map("cc#cc#", &hs.a, hs.s1, S1_LEN, &hs.b, hs.s2, S2_LEN);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_MEM,&img,&sz);
- tpl_free(tn);
-
- /* unpack */
-
- tn = tpl_map("cc#cc#", &hs2.a, hs2.s1, S1_LEN, &hs2.b, hs2.s2, S2_LEN);
- tpl_load(tn,TPL_MEM,img,sz);
- tpl_unpack(tn,0);
- tpl_free(tn);
- free(img);
-
- printf("hs2.a: %c\n", hs2.a);
- printf("hs2.s1 length: %d\n", (int)strlen(hs2.s1));
- printf("hs2.s1: %s\n", hs2.s1);
- printf("hs2.b: %c\n", hs2.b);
- printf("hs2.s2 length: %d\n", (int)strlen(hs2.s2));
- printf("hs2.s2: %s\n", hs2.s2);
- return(0);
-}
+++ /dev/null
-hs2.a: t
-hs2.s1 length: 5
-hs2.s1: draco
-hs2.b: h
-hs2.s2 length: 2
-hs2.s2: po
+++ /dev/null
-t is hello, world!
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- char *s,*t;
- void *addr;
- int sz;
-
- tn = tpl_map("s",&s);
- s = "hello, world!";
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_MEM,&addr,&sz);
- tpl_free(tn);
-
- tn = tpl_map("s",&t);
- tpl_load(tn,TPL_MEM,addr,sz);
- tpl_unpack(tn,0);
- printf("t is %s\n", t);
- free(t);
- tpl_free(tn);
- free(addr);
- return(0);
-}
+++ /dev/null
-t is hello, world!
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map("A(i)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test60.tpl");
-
- /* test load-after-pack: implicit free via tpl_free_keep_map() */
- tpl_load(tn,TPL_FILE,"/tmp/test60.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
-i is 10
-i is 11
-i is 12
-i is 13
-i is 14
-i is 15
-i is 16
-i is 17
-i is 18
-i is 19
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test61_0.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- /* test load-then-load: implicit free via tpl_free_keep_map */
- tpl_load(tn, TPL_FILE,"test61_1.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
-i is 10
-i is 11
-i is 12
-i is 13
-i is 14
-i is 15
-i is 16
-i is 17
-i is 18
-i is 19
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
-i is 0
-i is -1
-i is -2
-i is -3
-i is -4
-i is -5
-i is -6
-i is -7
-i is -8
-i is -9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test62_0.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- /* test load-then-pack (then load): implicit free via tpl_free_keep_map */
- for(i=0;i>-10;i--) tpl_pack(tn,1);
- tpl_dump(tn, TPL_FILE,"/tmp/test62_1.tpl");
- tpl_load(tn,TPL_FILE,"/tmp/test62_1.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
-i is 0
-i is -1
-i is -2
-i is -3
-i is -4
-i is -5
-i is -6
-i is -7
-i is -8
-i is -9
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
-i is 0
-i is -1
-i is -2
-i is -3
-i is -4
-i is -5
-i is -6
-i is -7
-i is -8
-i is -9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map("A(i)",&i);
- for(i=0;i<10;i++) tpl_pack(tn,1);
-
- /* test pack-then-unpack without dump/load; implicit dump/load*/
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- /* implicit conversion back to output tpl (discards previous data in tpl */
- for(i=0;i>-10;i--) tpl_pack(tn,1);
-
- /* one more implicit conversion */
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
-
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
-i is 0
-i is -1
-i is -2
-i is -3
-i is -4
-i is -5
-i is -6
-i is -7
-i is -8
-i is -9
+++ /dev/null
-s is beta
-sh.str is delta
-bin.addr is zeta, size 5
+++ /dev/null
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "tpl.h"
-
-struct str_holder {
- char str[10];
-};
-
-
-/* the real purpose of this test is to be run under dbx "check -all"
- * mode to ensure the level-0 data are freed when replaced (i.e. the
- * level 0 nodes are packed more than once, this is an edge case but
- * the required behavior is to free the previously-packed data when
- * packing the new replacement data). Do the test for s,S,and B types.
- */
-int main() {
- tpl_node *tn;
- char *s;
- struct str_holder sh;
- tpl_bin bin;
-
- /* test a replacement pack (s type) of the level 0 node */
- tn = tpl_map("s", &s);
- s = "alpha";
- tpl_pack(tn,0); /* copies alpha */
- s = "beta";
- tpl_pack(tn,0); /* should free alpha, copy beta */
- tpl_dump(tn,TPL_FILE,"/tmp/test64_0.tpl");
- tpl_free(tn);
-
- /* print out dumped tpl */
- s = "";
- tn = tpl_map("s", &s);
- tpl_load(tn,TPL_FILE,"/tmp/test64_0.tpl");
- tpl_unpack(tn,0);
- printf("s is %s\n", s);
- free(s);
- tpl_free(tn);
-
- /* test replacement pack (S type) of the level 0 node */
- tn = tpl_map("c#", sh.str, 10);
- strncpy(sh.str, "gamma", 10);
- tpl_pack(tn,0); /* copies gamma */
- strncpy(sh.str, "delta", 10);
- tpl_pack(tn,0); /* should free gamma, copy delta */
- tpl_dump(tn,TPL_FILE,"/tmp/test64_1.tpl");
- tpl_free(tn);
-
- /* print out dumped tpl */
- sh.str[0] = '\0';
- tn = tpl_map("c#", sh.str, 10);
- tpl_load(tn,TPL_FILE,"/tmp/test64_1.tpl");
- tpl_unpack(tn,0);
- printf("sh.str is %s\n", sh.str);
- tpl_free(tn);
-
- /* test replacement pack (B type) of the level 0 node */
- tn = tpl_map("B", &bin);
- bin.addr = "epsilon";
- bin.sz = strlen("epsilon")+1;
- tpl_pack(tn,0); /* copies epsilon */
- bin.addr = "zeta";
- bin.sz = strlen("zeta")+1;
- tpl_pack(tn,0); /* should free epsilon, copy zeta */
- tpl_dump(tn,TPL_FILE,"/tmp/test64_2.tpl");
- tpl_free(tn);
-
- /* print out dumped tpl */
- bin.addr = "";
- bin.sz = 1;
- tn = tpl_map("B", &bin);
- tpl_load(tn,TPL_FILE,"/tmp/test64_2.tpl");
- tpl_unpack(tn,0);
- printf("bin.addr is %s, size %d\n", (char*)(bin.addr), bin.sz);
- free(bin.addr);
- tpl_free(tn);
- return(0);
-
-}
+++ /dev/null
-s is beta
-sh.str is delta
-bin.addr is zeta, size 5
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define TEST_LEN 10
-
-int main() {
- tpl_node *tn;
- int i[TEST_LEN] = {1,2,3,4,5,6,7,8,9,10};
-
- tn = tpl_map("i#", i, TEST_LEN);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test65.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define TEST_LEN1 10
-#define TEST_LEN2 5
-
-int main() {
- tpl_node *tn;
- int i[TEST_LEN1] = {1,2,3,4,5,6,7,8,9,10};
- int j[TEST_LEN2] = {5,4,3,2,1};
-
- tn = tpl_map("i#i#", i, TEST_LEN1, j, TEST_LEN2);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test66.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-load succeeded
-/tmp/test67.tpl: array lengths mismatch
-load failed
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define TEST_LEN1 10
-#define TEST_LEN2 5
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i[TEST_LEN1] = {1,2,3,4,5,6,7,8,9,10};
- int j[TEST_LEN2] = {5,4,3,2,1};
-
- tpl_hook.oops = printf; /* errors to printf */
-
- tn = tpl_map("i#i#", i, TEST_LEN1, j, TEST_LEN2);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test67.tpl");
- tpl_free(tn);
-
- /* Expect success on the next line */
- tn = tpl_map("i#i#", i, TEST_LEN1, j, TEST_LEN2);
- if (tpl_load(tn,TPL_FILE,"/tmp/test67.tpl") < 0) {
- printf("load failed\n");
- } else {
- printf("load succeeded\n");
- }
- tpl_free(tn);
-
- /* Expect failure on the next line (TEST_LEN2 != TEST_LEN2-1) */
- tn = tpl_map("i#i#", i, TEST_LEN1, j, (TEST_LEN2 - 1));
- if (tpl_load(tn,TPL_FILE,"/tmp/test67.tpl") < 0) {
- printf("load failed\n");
- } else {
- printf("load succeeded\n");
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-load succeeded
-/tmp/test67.tpl: array lengths mismatch
-load failed
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define TEST_LEN1 10
-#define TEST_LEN2 5
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i[TEST_LEN1] = {1,2,3,4,5,6,7,8,9,10};
- int j[TEST_LEN2] = {5,4,3,2,1};
- int i2[TEST_LEN1];
- int j2[TEST_LEN2];
- int x;
-
- tpl_hook.oops = printf; /* errors to printf */
-
- tn = tpl_map("i#i#", i, TEST_LEN1, j, TEST_LEN2);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test68.tpl");
- tpl_free(tn);
-
- tn = tpl_map("i#i#", i2, TEST_LEN1, j2, TEST_LEN2);
- tpl_load(tn,TPL_FILE,"/tmp/test68.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- for(x=0;x<TEST_LEN1;x++) {
- if (i[x] != i2[x]) printf("mismatch (i)!\n");
- }
- for(x=0;x<TEST_LEN2;x++) {
- if (j[x] != j2[x]) printf("mismatch (j)!\n");
- }
- return(0);
-}
+++ /dev/null
-2 3 4 5 6 7 8 9 10 11
-4 3 2 1 0
-3 4 5 6 7 8 9 10 11 12
-3 2 1 0 -1
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define TEST_LEN1 10
-#define TEST_LEN2 5
-
-extern tpl_hook_t tpl_hook;
-
-int main() {
- tpl_node *tn;
- int i[TEST_LEN1] = {1,2,3,4,5,6,7,8,9,10};
- int j[TEST_LEN2] = {5,4,3,2,1};
- int i2[TEST_LEN1];
- int j2[TEST_LEN2];
- int x,y;
-
- tpl_hook.oops = printf; /* errors to printf */
-
- tn = tpl_map("A(i#i#)", i, TEST_LEN1, j, TEST_LEN2);
- for(y=0; y < 2; y++) {
- for(x=0; x < TEST_LEN1; x++) i[x] += 1;
- for(x=0; x < TEST_LEN2; x++) j[x] -= 1;
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_FILE,"/tmp/test69.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(i#i#)", i2, TEST_LEN1, j2, TEST_LEN2);
- tpl_load(tn,TPL_FILE,"/tmp/test69.tpl");
- while (tpl_unpack(tn,1) > 0) {
- for(x=0; x < TEST_LEN1; x++) printf("%d ", i2[x]);
- printf("\n");
- for(x=0; x < TEST_LEN2; x++) printf("%d ", j2[x]);
- printf("\n");
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-2 3 4 5 6 7 8 9 10 11
-4 3 2 1 0
-3 4 5 6 7 8 9 10 11 12
-3 2 1 0 -1
+++ /dev/null
-t is wonderful
-t is prince of peace
-t is counselor
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- char *strs[] = { "wonderful", "prince of peace", "counselor", NULL };
- int i;
- char *s, *t;
-
- tn = tpl_map("A(s)",&s);
- for(i=0; strs[i] != NULL; i++) {
- s = strs[i];
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_FILE,"/tmp/test7.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(s)",&t);
- tpl_load(tn,TPL_FILE,"/tmp/test7.tpl");
- while (tpl_unpack(tn,1) > 0) {
- printf("t is %s\n", t);
- free(t);
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-t is wonderful
-t is prince of peace
-t is counselor
+++ /dev/null
-a
-1
-hi
-o
-matilda
-y
-3.140000
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "tpl.h"
-
-struct ms_t {
- char c;
- int i;
- char s[2];
- char o;
- char *x;
- char y;
- double d;
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms = {/*.c =*/ 'a', /*.i =*/ 1, /*.s =*/ {'h','i'}, /*.o =*/ 'o', /*.x =*/ "matilda", /*.y =*/ 'y', /*.d =*/ 3.14 };
- struct ms_t ms2;
-
- tn = tpl_map("S(cic#cscf)", &ms, 2);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test70.tpl");
- tpl_free(tn);
-
- memset(&ms2,0,sizeof(struct ms_t));
- tn = tpl_map("S(cic#cscf)", &ms2, 2);
- tpl_load(tn,TPL_FILE,"/tmp/test70.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("%c\n%d\n%c%c\n%c\n%s\n%c\n%f\n", ms2.c, ms2.i, ms2.s[0], ms2.s[1], ms2.o, ms2.x, ms2.y, ms2.d);
- free(ms2.x);
- return(0);
-}
+++ /dev/null
-a
-1
-hi
-o
-matilda
-y
-3.140000
+++ /dev/null
-#
-1
-hi
-o
-matilda
-y
-3.140000
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "tpl.h"
-
-struct ms_t {
- int i;
- char s[2];
- char o;
- char *x;
- char y;
- double d;
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms = { /*.i =*/ 1, /*.s =*/ {'h','i'}, /*.o =*/ 'o', /*.x =*/ "matilda", /*.y =*/ 'y', /*.d =*/ 3.14 };
- struct ms_t ms2;
- char b = '#', b2;
-
- tn = tpl_map("cS(ic#cscf)", &b, &ms, 2);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test71.tpl");
- tpl_free(tn);
-
- memset(&ms2,0,sizeof(struct ms_t));
- tn = tpl_map("cS(ic#cscf)", &b2, &ms2, 2);
- tpl_load(tn,TPL_FILE,"/tmp/test71.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("%c\n%d\n%c%c\n%c\n%s\n%c\n%f\n", b2, ms2.i, ms2.s[0], ms2.s[1], ms2.o, ms2.x, ms2.y, ms2.d);
- free(ms2.x);
- return(0);
-}
+++ /dev/null
-#
-1
-hi
-o
-matilda
-y
-3.140000
+++ /dev/null
-a
-1
-hi
-o
-matilda
-y
-3.140000
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "tpl.h"
-
-struct ms_t {
- char c;
- int i;
- char s[2];
- char o;
- char *x;
- char y;
- double d;
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms = {/*.c =*/ 'a', /*.i =*/ 1, /*.s =*/ {'h','i'}, /*.o =*/ 'o', /*.x =*/ "matilda", /*.y =*/ 'y', /*.d =*/ 3.14 };
- struct ms_t ms2;
-
- tn = tpl_map("S(cic#cscf)", &ms, 2);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test72.tpl");
- tpl_free(tn);
-
- memset(&ms2,0,sizeof(struct ms_t));
- tn = tpl_map("S(cic#cscf)", &ms2, 2);
- tpl_load(tn,TPL_FILE,"/tmp/test72.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("%c\n%d\n%c%c\n%c\n%s\n%c\n%f\n", ms2.c, ms2.i, ms2.s[0], ms2.s[1], ms2.o, ms2.x, ms2.y, ms2.d);
- free(ms2.x);
- return(0);
-}
+++ /dev/null
-a
-1
-hi
-o
-matilda
-y
-3.140000
+++ /dev/null
-a
-1
-hi
-o
-matilda
-tdh
-3.140000
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "tpl.h"
-
-struct ms_t {
- char c;
- int i;
- char s[2];
- char o;
- char *x;
- char y[3];
- double d;
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms = {/*.c =*/ 'a', /*.i =*/ 1, /*.s =*/ {'h','i'}, /*.o =*/ 'o', /*.x =*/ "matilda", /*.y =*/ {'t','d','h'}, /*.d =*/ 3.14 };
- struct ms_t ms2;
-
- tn = tpl_map("S(cic#csc#f)", &ms, 2, 3);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test73.tpl");
- tpl_free(tn);
-
- memset(&ms2,0,sizeof(struct ms_t));
- tn = tpl_map("S(cic#csc#f)", &ms2, 2, 3);
- tpl_load(tn,TPL_FILE,"/tmp/test73.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("%c\n%d\n%c%c\n%c\n%s\n%c%c%c\n%f\n", ms2.c, ms2.i, ms2.s[0], ms2.s[1], ms2.o, ms2.x, ms2.y[0],ms2.y[1],ms2.y[2], ms2.d);
- free(ms2.x);
- return(0);
-}
+++ /dev/null
-a
-1
-hi
-o
-matilda
-tdh
-3.140000
+++ /dev/null
-1234
-0.00
-1.50
-3.00
-4.50
-6.00
-7.50
-9.00
-10.50
-12.00
-13.50
-15.00
-16.50
-18.00
-19.50
-21.00
-22.50
-24.00
-25.50
-27.00
-28.50
-30.00
-31.50
-33.00
-34.50
-36.00
-37.50
-39.00
-40.50
-42.00
-43.50
-45.00
-46.50
-48.00
-49.50
-51.00
-52.50
-54.00
-55.50
-57.00
-58.50
-60.00
-61.50
-63.00
-64.50
-66.00
-67.50
-69.00
-70.50
-72.00
-73.50
-75.00
-76.50
-78.00
-79.50
-81.00
-82.50
-84.00
-85.50
-87.00
-88.50
-90.00
-91.50
-93.00
-94.50
-96.00
-97.50
-99.00
-100.50
-102.00
-103.50
-105.00
-106.50
-108.00
-109.50
-111.00
-112.50
-114.00
-115.50
-117.00
-118.50
-120.00
-121.50
-123.00
-124.50
-126.00
-127.50
-129.00
-130.50
-132.00
-133.50
-135.00
-136.50
-138.00
-139.50
-141.00
-142.50
-144.00
-145.50
-147.00
-148.50
-150.00
-151.50
-153.00
-154.50
-156.00
-157.50
-159.00
-160.50
-162.00
-163.50
-165.00
-166.50
-168.00
-169.50
-171.00
-172.50
-174.00
-175.50
-177.00
-178.50
-180.00
-181.50
-183.00
-184.50
-186.00
-187.50
-189.00
-190.50
-192.00
-193.50
-195.00
-196.50
-198.00
-199.50
-201.00
-202.50
-204.00
-205.50
-207.00
-208.50
-210.00
-211.50
-213.00
-214.50
-216.00
-217.50
-219.00
-220.50
-222.00
-223.50
-225.00
-226.50
-228.00
-229.50
-231.00
-232.50
-234.00
-235.50
-237.00
-238.50
-240.00
-241.50
-243.00
-244.50
-246.00
-247.50
-249.00
-250.50
-252.00
-253.50
-255.00
-256.50
-258.00
-259.50
-261.00
-262.50
-264.00
-265.50
-267.00
-268.50
-270.00
-271.50
-273.00
-274.50
-276.00
-277.50
-279.00
-280.50
-282.00
-283.50
-285.00
-286.50
-288.00
-289.50
-291.00
-292.50
-294.00
-295.50
-297.00
-298.50
-0.00
-0.50
-1.00
-1.50
-2.00
-2.50
-3.00
-3.50
-4.00
-4.50
-5.00
-5.50
-6.00
-6.50
-7.00
-7.50
-8.00
-8.50
-9.00
-9.50
-10.00
-10.50
-11.00
-11.50
-12.00
-12.50
-13.00
-13.50
-14.00
-14.50
-15.00
-15.50
-16.00
-16.50
-17.00
-17.50
-18.00
-18.50
-19.00
-19.50
-20.00
-20.50
-21.00
-21.50
-22.00
-22.50
-23.00
-23.50
-24.00
-24.50
-25.00
-25.50
-26.00
-26.50
-27.00
-27.50
-28.00
-28.50
-29.00
-29.50
-30.00
-30.50
-31.00
-31.50
-32.00
-32.50
-33.00
-33.50
-34.00
-34.50
-35.00
-35.50
-36.00
-36.50
-37.00
-37.50
-38.00
-38.50
-39.00
-39.50
-40.00
-40.50
-41.00
-41.50
-42.00
-42.50
-43.00
-43.50
-44.00
-44.50
-45.00
-45.50
-46.00
-46.50
-47.00
-47.50
-48.00
-48.50
-49.00
-49.50
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include "tpl.h"
-
-#define F1_LEN 200
-#define F2_LEN 100
-
-struct ms_t {
- int i;
- double f1[F1_LEN];
- double f2[F2_LEN];
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms, ms2;
- int i;
-
- ms.i = 1234;
- for(i=0; i < F1_LEN; i++) ms.f1[i] = i * 1.5;
- for(i=0; i < F2_LEN; i++) ms.f2[i] = i * 0.5;
-
- tn = tpl_map("S(if#f#)", &ms, F1_LEN, F2_LEN);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,"/tmp/test74.tpl");
- tpl_free(tn);
-
- memset(&ms2,0,sizeof(struct ms_t));
- tn = tpl_map("S(if#f#)", &ms2, F1_LEN, F2_LEN);
- tpl_load(tn,TPL_FILE,"/tmp/test74.tpl");
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- printf("%d\n", ms2.i);
- for(i=0; i < F1_LEN; i++) printf("%.2f\n", ms2.f1[i]);
- for(i=0; i < F2_LEN; i++) printf("%.2f\n", ms2.f2[i]);
-
- return(0);
-}
+++ /dev/null
-1234
-0.00
-1.50
-3.00
-4.50
-6.00
-7.50
-9.00
-10.50
-12.00
-13.50
-15.00
-16.50
-18.00
-19.50
-21.00
-22.50
-24.00
-25.50
-27.00
-28.50
-30.00
-31.50
-33.00
-34.50
-36.00
-37.50
-39.00
-40.50
-42.00
-43.50
-45.00
-46.50
-48.00
-49.50
-51.00
-52.50
-54.00
-55.50
-57.00
-58.50
-60.00
-61.50
-63.00
-64.50
-66.00
-67.50
-69.00
-70.50
-72.00
-73.50
-75.00
-76.50
-78.00
-79.50
-81.00
-82.50
-84.00
-85.50
-87.00
-88.50
-90.00
-91.50
-93.00
-94.50
-96.00
-97.50
-99.00
-100.50
-102.00
-103.50
-105.00
-106.50
-108.00
-109.50
-111.00
-112.50
-114.00
-115.50
-117.00
-118.50
-120.00
-121.50
-123.00
-124.50
-126.00
-127.50
-129.00
-130.50
-132.00
-133.50
-135.00
-136.50
-138.00
-139.50
-141.00
-142.50
-144.00
-145.50
-147.00
-148.50
-150.00
-151.50
-153.00
-154.50
-156.00
-157.50
-159.00
-160.50
-162.00
-163.50
-165.00
-166.50
-168.00
-169.50
-171.00
-172.50
-174.00
-175.50
-177.00
-178.50
-180.00
-181.50
-183.00
-184.50
-186.00
-187.50
-189.00
-190.50
-192.00
-193.50
-195.00
-196.50
-198.00
-199.50
-201.00
-202.50
-204.00
-205.50
-207.00
-208.50
-210.00
-211.50
-213.00
-214.50
-216.00
-217.50
-219.00
-220.50
-222.00
-223.50
-225.00
-226.50
-228.00
-229.50
-231.00
-232.50
-234.00
-235.50
-237.00
-238.50
-240.00
-241.50
-243.00
-244.50
-246.00
-247.50
-249.00
-250.50
-252.00
-253.50
-255.00
-256.50
-258.00
-259.50
-261.00
-262.50
-264.00
-265.50
-267.00
-268.50
-270.00
-271.50
-273.00
-274.50
-276.00
-277.50
-279.00
-280.50
-282.00
-283.50
-285.00
-286.50
-288.00
-289.50
-291.00
-292.50
-294.00
-295.50
-297.00
-298.50
-0.00
-0.50
-1.00
-1.50
-2.00
-2.50
-3.00
-3.50
-4.00
-4.50
-5.00
-5.50
-6.00
-6.50
-7.00
-7.50
-8.00
-8.50
-9.00
-9.50
-10.00
-10.50
-11.00
-11.50
-12.00
-12.50
-13.00
-13.50
-14.00
-14.50
-15.00
-15.50
-16.00
-16.50
-17.00
-17.50
-18.00
-18.50
-19.00
-19.50
-20.00
-20.50
-21.00
-21.50
-22.00
-22.50
-23.00
-23.50
-24.00
-24.50
-25.00
-25.50
-26.00
-26.50
-27.00
-27.50
-28.00
-28.50
-29.00
-29.50
-30.00
-30.50
-31.00
-31.50
-32.00
-32.50
-33.00
-33.50
-34.00
-34.50
-35.00
-35.50
-36.00
-36.50
-37.00
-37.50
-38.00
-38.50
-39.00
-39.50
-40.00
-40.50
-41.00
-41.50
-42.00
-42.50
-43.00
-43.50
-44.00
-44.50
-45.00
-45.50
-46.00
-46.50
-47.00
-47.50
-48.00
-48.50
-49.00
-49.50
+++ /dev/null
-string
-byte array
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define S2_LEN 10
-
-struct example {
- char *s1; /* s1 is a pointer */
- char s2[S2_LEN]; /* s2 is a byte array */
-};
-
-int main() {
- tpl_node *tn;
- int i;
- struct example dst, src = {
- /* .s1 = */ "string",
- /* .s2 = */ {'b','y','t','e',' ','a','r','r','a','y'}
- };
-
- tn = tpl_map( "sc#", &src.s1, &src.s2, S2_LEN);
- tpl_pack( tn, 0 );
- tpl_dump( tn, TPL_FILE, "/tmp/test75.tpl" );
- tpl_free( tn );
-
- /* unpack it now into another struct */
-
- tn = tpl_map( "sc#", &dst.s1, &dst.s2, S2_LEN);
- tpl_load( tn, TPL_FILE, "/tmp/test75.tpl" );
- tpl_unpack( tn, 0 );
- tpl_free( tn );
-
- printf("%s\n", dst.s1);
- for(i=0; i < S2_LEN; i++) printf("%c", dst.s2[i]);
- printf("\n");
-
- free(dst.s1); /* tpl allocated it for us; we must free it */
- return(0);
-}
+++ /dev/null
-string
-byte array
+++ /dev/null
-string
-byte array
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define S2_LEN 10
-
-struct example {
- char *s1; /* s1 is a pointer */
- char s2[S2_LEN]; /* s2 is a byte array */
-};
-
-int main() {
- tpl_node *tn;
- int i;
- struct example dst, src = {
- /* .s1 = */ "string",
- /* .s2 = */ {'b','y','t','e',' ','a','r','r','a','y'}
- };
-
- tn = tpl_map( "S(sc#)", &src, S2_LEN); /* NOTE S(...) */
- tpl_pack( tn, 0 );
- tpl_dump( tn, TPL_FILE, "/tmp/test76.tpl" );
- tpl_free( tn );
-
- /* unpack it now into another struct */
-
- tn = tpl_map( "S(sc#)", &dst, S2_LEN); /* NOTE S(...) */
- tpl_load( tn, TPL_FILE, "/tmp/test76.tpl" );
- tpl_unpack( tn, 0 );
- tpl_free( tn );
-
- printf("%s\n", dst.s1);
- for(i=0; i < S2_LEN; i++) printf("%c", dst.s2[i]);
- printf("\n");
-
- free(dst.s1); /* tpl allocated it for us; we must free it */
- return(0);
-}
+++ /dev/null
-string
-byte array
+++ /dev/null
-string
-byte array
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-#define S2_LEN 10
-
-struct example {
- char *s1; /* s1 is a pointer */
- char s2[S2_LEN]; /* s2 is a byte array */
-};
-
-int main() {
- tpl_node *tn;
- int i;
- struct example dst, src = {
- /* .s1 = */ "string",
- /* .s2 = */ {'b','y','t','e',' ','a','r','r','a','y'}
- };
-
- tn = tpl_map( "S(sc#)", &src, S2_LEN); /* NOTE S(...) */
- tpl_pack( tn, 0 );
- tpl_dump( tn, TPL_FILE, "/tmp/test77.tpl" );
- tpl_free( tn );
-
- /* unpack it now into another struct */
-
- tn = tpl_map( "S(sc#)", &dst, S2_LEN);
- tpl_load( tn, TPL_FILE, "/tmp/test77.tpl" );
- tpl_unpack( tn, 0 );
- tpl_free( tn );
-
- printf("%s\n", dst.s1);
- for(i=0; i < S2_LEN; i++) printf("%c", dst.s2[i]);
- printf("\n");
-
- free(dst.s1); /* tpl allocated it for us; we must free it */
- return(0);
-}
+++ /dev/null
-string
-byte array
+++ /dev/null
-#include "tpl.h"
-
-int main() {
- int i;
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(i)c", &i, &c);
-
- /* pack index number 0 (char c) */
- c = 'a';
- tpl_pack(tn, 0);
-
- /* pack A(i) (that is, index number 1) a few times */
- i = 3;
- tpl_pack(tn, 1);
- i = 4;
- tpl_pack(tn, 1);
-
- tpl_dump(tn, TPL_FILE, "/tmp/test78.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-got a
-got 3
-got 4
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- int i;
- char c;
- tpl_node *tn;
-
- tn = tpl_map("A(i)c", &i, &c);
- tpl_load(tn, TPL_FILE, "/tmp/test78.tpl");
-
- /* unpack index number 0 (char c) */
- tpl_unpack(tn, 0);
- printf("got %c\n", c);
-
- /* unpack A(i) (that is, index number 1) til we run out of elements */
- while (tpl_unpack(tn, 1) > 0) {
- printf("got %d\n", i);
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-got a
-got 3
-got 4
+++ /dev/null
-d is ff, e is 61
-d is ff, e is 62
-d is ff, e is 63
-d is ff, e is 64
-d is ff, e is 65
-d is ff, e is 66
-d is ff, e is 67
-d is ff, e is 68
-d is ff, e is 69
-d is ff, e is 6a
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- unsigned int i;
- unsigned char b,c;
- unsigned char d,e;
-
- tn = tpl_map("cA(c)",&b,&c);
- b = 255;
- tpl_pack(tn,0);
- for (i=0; i < 10; i++) {
- c = 'a' + i;
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_FILE,"/tmp/test8.tpl");
- tpl_free(tn);
-
- tn = tpl_map("cA(c)",&d,&e);
- tpl_load(tn,TPL_FILE,"/tmp/test8.tpl");
- tpl_unpack(tn,0);
- while (tpl_unpack(tn,1) > 0)
- printf("d is %x, e is %x\n", (unsigned)d, (unsigned)e);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-d is ff, e is 61
-d is ff, e is 62
-d is ff, e is 63
-d is ff, e is 64
-d is ff, e is 65
-d is ff, e is 66
-d is ff, e is 67
-d is ff, e is 68
-d is ff, e is 69
-d is ff, e is 6a
+++ /dev/null
-a 0 1 2 3 4 5 6 7 8 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-#define ILEN 10
-
-struct st {
- char c;
- int i[ILEN];
-};
-
-int main() {
- struct st dst, s = {'a', {0,1,2,3,4,5,6,7,8,9}};
- tpl_node *tn;
- int j;
-
- tn = tpl_map("A(S(ci#))", &s, ILEN);
- tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,"/tmp/test80.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(S(ci#))", &dst, ILEN);
- tpl_load(tn,TPL_FILE,"/tmp/test80.tpl");
- while (tpl_unpack(tn,1) > 0) {
- printf("%c ", dst.c);
- for(j=0;j<ILEN;j++) printf("%d ", dst.i[j]);
- printf("\n");
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-a 0 1 2 3 4 5 6 7 8 9
+++ /dev/null
-a 0 1 2 3 4 5 6 7 8 9
-b 1 2 3 4 5 6 7 8 9 10
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-#define ILEN 10
-
-struct st {
- char c;
- int i[ILEN];
-};
-
-int main() {
- struct st dst, s = {'a', {0,1,2,3,4,5,6,7,8,9}};
- tpl_node *tn;
- int j;
-
- tn = tpl_map("A(S(ci#))", &s, ILEN);
- tpl_pack(tn,1);
-
- /* fiddle with the fields and pack another element */
- s.c++;
- for(j=0;j<ILEN;j++) s.i[j]++;
- tpl_pack(tn,1);
-
- tpl_dump(tn,TPL_FILE,"/tmp/test81.tpl");
- tpl_free(tn);
-
- tn = tpl_map("A(S(ci#))", &dst, ILEN);
- tpl_load(tn,TPL_FILE,"/tmp/test81.tpl");
- while (tpl_unpack(tn,1) > 0) {
- printf("%c ", dst.c);
- for(j=0;j<ILEN;j++) printf("%d ", dst.i[j]);
- printf("\n");
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-a 0 1 2 3 4 5 6 7 8 9
-b 1 2 3 4 5 6 7 8 9 10
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-#define ILEN 10
-#define KLEN 8
-#define FLEN 5
-
-struct st {
- char c;
- double f[FLEN];
-};
-
-int main() {
- tpl_node *tn;
- /* some meaningless test data */
- struct st s = {'z', {0.9, 0.8, 0.7, 0.6, 0.5 }};
- int j;
- int i[ILEN] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
- int k[KLEN] = {100, 200, 300, 400, 500, 600, 700, 800};
- char a = '&';
- char b = 'x';
-
- tn = tpl_map("cA(i#)S(cf#)A(ci#)", &a, i, ILEN, &s, FLEN, &b, k, KLEN);
- tpl_pack(tn,0);
-
- tpl_pack(tn,1);
- for(j=0; j < ILEN; j++) i[j]--;
- tpl_pack(tn,1);
- for(j=0; j < ILEN; j++) i[j]--;
- tpl_pack(tn,1);
-
- tpl_pack(tn,2);
- b++;
- for(j=0; j < KLEN; j++) k[j] += 50;
- tpl_pack(tn,2);
- b++;
- for(j=0; j < KLEN; j++) k[j] += 50;
- tpl_pack(tn,2);
-
- tpl_dump(tn,TPL_FILE,"/tmp/test82.tpl");
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-& z 0.90 0.80 0.70 0.60 0.50
--1 -2 -3 -4 -5 -6 -7 -8 -9 -10
--2 -3 -4 -5 -6 -7 -8 -9 -10 -11
--3 -4 -5 -6 -7 -8 -9 -10 -11 -12
-x 100 200 300 400 500 600 700 800
-y 150 250 350 450 550 650 750 850
-z 200 300 400 500 600 700 800 900
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-#define ILEN 10
-#define KLEN 8
-#define FLEN 5
-
-struct st {
- char c;
- double f[FLEN];
-};
-
-int main() {
- tpl_node *tn;
- /* some meaningless test data */
- struct st s;
- int j;
- int i[ILEN];
- int k[KLEN];
- char a;
- char b;
-
- tn = tpl_map("cA(i#)S(cf#)A(ci#)", &a, i, ILEN, &s, FLEN, &b, k, KLEN);
- tpl_load(tn,TPL_FILE,"/tmp/test82.tpl");
-
- tpl_unpack(tn,0);
- printf("%c %c %.2f %.2f %.2f %.2f %.2f \n", a, s.c, s.f[0], s.f[1], s.f[2], s.f[3], s.f[4]);
-
- while( tpl_unpack(tn,1) > 0) {
- for(j=0;j<ILEN;j++) printf("%d ", i[j]);
- printf("\n");
- }
-
- while( tpl_unpack(tn,2) > 0) {
- printf("%c ", b);
- for(j=0;j<KLEN;j++) printf("%d ", k[j]);
- printf("\n");
- }
-
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-& z 0.90 0.80 0.70 0.60 0.50
--1 -2 -3 -4 -5 -6 -7 -8 -9 -10
--2 -3 -4 -5 -6 -7 -8 -9 -10 -11
--3 -4 -5 -6 -7 -8 -9 -10 -11 -12
-x 100 200 300 400 500 600 700 800
-y 150 250 350 450 550 650 750 850
-z 200 300 400 500 600 700 800 900
+++ /dev/null
-& z 0.90 0.80 0.70 0.60 0.50
--1 -2 -3 -4 -5 -6 -7 -8 -9 -10
--2 -3 -4 -5 -6 -7 -8 -9 -10 -11
--3 -4 -5 -6 -7 -8 -9 -10 -11 -12
-x 100 200 300 400 500 600 700 800
-y 150 250 350 450 550 650 750 850
-z 200 300 400 500 600 700 800 900
-& z 0.90 0.80 0.70 0.60 0.50
--1 -2 -3 -4 -5 -6 -7 -8 -9 -10
--2 -3 -4 -5 -6 -7 -8 -9 -10 -11
--3 -4 -5 -6 -7 -8 -9 -10 -11 -12
-x 100 200 300 400 500 600 700 800
-y 150 250 350 450 550 650 750 850
-z 200 300 400 500 600 700 800 900
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-#define ILEN 10
-#define KLEN 8
-#define FLEN 5
-
-struct st {
- char c;
- double f[FLEN];
-};
-
-int main() {
- tpl_node *tn;
- /* some meaningless test data */
- struct st s;
- int j;
- int i[ILEN];
- int k[KLEN];
- char a;
- char b;
-
- tn = tpl_map("cA(i#)S(cf#)A(ci#)", &a, i, ILEN, &s, FLEN, &b, k, KLEN);
- tpl_load(tn,TPL_FILE,"test84_0.tpl");
-
- tpl_unpack(tn,0);
- printf("%c %c %.2f %.2f %.2f %.2f %.2f \n", a, s.c, s.f[0], s.f[1], s.f[2], s.f[3], s.f[4]);
-
- while( tpl_unpack(tn,1) > 0) {
- for(j=0;j<ILEN;j++) printf("%d ", i[j]);
- printf("\n");
- }
-
- while( tpl_unpack(tn,2) > 0) {
- printf("%c ", b);
- for(j=0;j<KLEN;j++) printf("%d ", k[j]);
- printf("\n");
- }
-
- tpl_free(tn);
-
- /* use the big-endian input file and repeat */
-
- tn = tpl_map("cA(i#)S(cf#)A(ci#)", &a, i, ILEN, &s, FLEN, &b, k, KLEN);
- tpl_load(tn,TPL_FILE,"test84_1.tpl");
-
- tpl_unpack(tn,0);
- printf("%c %c %.2f %.2f %.2f %.2f %.2f \n", a, s.c, s.f[0], s.f[1], s.f[2], s.f[3], s.f[4]);
-
- while( tpl_unpack(tn,1) > 0) {
- for(j=0;j<ILEN;j++) printf("%d ", i[j]);
- printf("\n");
- }
-
- while( tpl_unpack(tn,2) > 0) {
- printf("%c ", b);
- for(j=0;j<KLEN;j++) printf("%d ", k[j]);
- printf("\n");
- }
-
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-& z 0.90 0.80 0.70 0.60 0.50
--1 -2 -3 -4 -5 -6 -7 -8 -9 -10
--2 -3 -4 -5 -6 -7 -8 -9 -10 -11
--3 -4 -5 -6 -7 -8 -9 -10 -11 -12
-x 100 200 300 400 500 600 700 800
-y 150 250 350 450 550 650 750 850
-z 200 300 400 500 600 700 800 900
-& z 0.90 0.80 0.70 0.60 0.50
--1 -2 -3 -4 -5 -6 -7 -8 -9 -10
--2 -3 -4 -5 -6 -7 -8 -9 -10 -11
--3 -4 -5 -6 -7 -8 -9 -10 -11 -12
-x 100 200 300 400 500 600 700 800
-y 150 250 350 450 550 650 750 850
-z 200 300 400 500 600 700 800 900
+++ /dev/null
-cA(i#)S(cf#)A(ci#)
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- char *fmt;
- fmt = tpl_peek(TPL_FILE, "test85.tpl");
- if (fmt) {
- printf("%s\n",fmt);
- free(fmt);
- }
- return 0;
-}
+++ /dev/null
-cA(i#)S(cf#)A(ci#)
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int o,i;
- void *addr;
- int sz;
- char *fmt;
-
- tn = tpl_map("A(A(i))",&i);
- for(o=0;o<10;o++) {
- for(i=o; i < o+10; i++) tpl_pack(tn,2);
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_MEM,&addr,&sz);
- tpl_free(tn);
-
- fmt = tpl_peek(TPL_MEM, addr, sz);
- if (fmt) {
- printf("%s\n",fmt);
- free(fmt);
- }
- free(addr);
- return(0);
-}
+++ /dev/null
-sum is 49995000
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-int main() {
- tpl_node *tn;
- unsigned i, sum=0;
- int fd[2], pid,rc;
- void *img;
- size_t sz;
-
- pipe(fd);
- if ( (pid = fork()) == 0) { /* child */
-
- rc = tpl_gather(TPL_GATHER_BLOCKING,fd[0],&img,&sz);
- if (rc != 1) {
- printf("error: rc non-zero: %d\n", rc);
- exit(-1);
- }
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_MEM, img,sz);
- while (tpl_unpack(tn,1) > 0) sum += i;
- tpl_free(tn);
- printf("sum is %d\n", sum);
-
- } else if (pid > 0) { /* parent */
-
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10000;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd[1] );
- tpl_free(tn);
-
- close(fd[1]);
- waitpid(pid,NULL,0);
-
- } else if (pid == -1) {
- perror("fork error");
- }
- return(0);
-}
+++ /dev/null
-sum is 49995000
+++ /dev/null
-#include "tpl.h"
-
-struct ms_t {
- int i;
- char c[3];
- double f;
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms = {1, {'a','b','c'}, 3.14};
-
- tn = tpl_map( "S(ic#f)", &ms, 3);
- tpl_pack( tn, 0 );
- tpl_dump( tn, TPL_FILE, "/tmp/test88.tpl" );
- tpl_free( tn );
- return(0);
-}
+++ /dev/null
-1
-abc
-3.14
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-struct ms_t {
- int i;
- char c[3];
- double f;
-};
-
-int main() {
- tpl_node *tn;
- struct ms_t ms;
-
- tn = tpl_map( "S(ic#f)", &ms, 3);
- tpl_load( tn, TPL_FILE, "/tmp/test88.tpl" );
- tpl_unpack( tn, 0 );
- tpl_free( tn );
-
- printf("%d\n%c%c%c\n%.2f\n", ms.i, ms.c[0],ms.c[1],ms.c[2], ms.f);
- return(0);
-}
+++ /dev/null
-1
-abc
-3.14
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-#include <stdio.h>
-#include "tpl.h"
-
-int main() {
- tpl_node *tn;
- int i;
-
- tn = tpl_map("A(i)",&i);
- tpl_load(tn,TPL_FILE,"test9.tpl");
- while (tpl_unpack(tn,1) > 0) printf("i is %d\n", i);
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-i is 0
-i is 1
-i is 2
-i is 3
-i is 4
-i is 5
-i is 6
-i is 7
-i is 8
-i is 9
+++ /dev/null
-cn is equal to cn2
+++ /dev/null
-#include <stdio.h>
-#include <stdint.h>
-
-#include <tpl.h>
-
-int main ( int n , char* a [ ] )
-{
-
- tpl_node* tn ;
- int64_t cn = 100,cn2 ;
-
- tn = tpl_map ( "I" , &cn ) ;
- tpl_pack ( tn , 0 ) ;
- tpl_dump ( tn , TPL_FILE , "/tmp/test90.tpl" ) ;
- tpl_free ( tn ) ;
-
- tn = tpl_map ( "I" , &cn2 ) ;
- tpl_load ( tn , TPL_FILE , "/tmp/test90.tpl" ) ;
- tpl_unpack ( tn , 0 ) ;
- printf("cn is %sequal to cn2\n", (cn == cn2) ? "" : "not");
- tpl_free ( tn ) ;
- return ( 0 ) ;
-}
+++ /dev/null
-cn is equal to cn2
+++ /dev/null
-cn is equal to cn2
+++ /dev/null
-#include <stdio.h>
-#include <stdint.h>
-
-#include <tpl.h>
-
-int main ( int n , char* a [ ] )
-{
-
- tpl_node* tn ;
- uint64_t cn = 100, cn2 ;
-
- tn = tpl_map ( "U" , &cn ) ;
- tpl_pack ( tn , 0 ) ;
- tpl_dump ( tn , TPL_FILE , "/tmp/test91.tpl" ) ;
- tpl_free ( tn ) ;
-
- tn = tpl_map ( "U" , &cn2 ) ;
- tpl_load ( tn , TPL_FILE , "/tmp/test91.tpl" ) ;
- tpl_unpack ( tn , 0 ) ;
- printf("cn is %sequal to cn2\n", (cn == cn2) ? "" : "not");
- tpl_free ( tn ) ;
- return ( 0 ) ;
-}
+++ /dev/null
-cn is equal to cn2
+++ /dev/null
-#include <stdio.h>
-#include <stdint.h>
-
-#include <tpl.h>
-
-int main ( int n , char* a [ ] )
-{
-
- tpl_node* tn ;
- char c='a',c2='b',c3,c4;
- int64_t cn = -100, cn2 ;
- uint64_t ucn = 200, ucn2;
-
- tn = tpl_map ( "A(cIcU)" , &c, &cn, &c2, &ucn ) ;
- tpl_pack ( tn , 1 ) ;
- c += 1;
- cn -= 1;
- c2 += 1;
- ucn += 1;
- tpl_pack ( tn , 1 ) ;
- tpl_dump ( tn , TPL_FILE , "/tmp/test92.tpl" ) ;
- tpl_free ( tn ) ;
-
- tn = tpl_map ( "A(cIcU)" , &c3, &cn2, &c4, &ucn2 ) ;
- tpl_load(tn,TPL_FILE,"/tmp/test92.tpl");
- /* Hesitant to rely on portability of %lld to print int64_t.
- At least on MinGW it is questionable. */
- /*
- * while (tpl_unpack(tn,1) > 0) {
- * printf("%c %lld %c %llu\n", c3, cn2, c4, ucn2);
- * }
- */
- tpl_unpack(tn,1);
- if (c3 != 'a' || cn2 != -100 || c4 != 'b' || ucn2 != 200) printf("unpack error 1\n");
- tpl_unpack(tn,1);
- if (c3 != 'b' || cn2 != -101 || c4 != 'c' || ucn2 != 201) printf("unpack error 2\n");
- return ( 0 ) ;
-
-}
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename="/tmp/test93.tpl";
-int main() {
- tpl_node *tn;
- char *s = NULL;
- tn = tpl_map("s", &s);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- s = (char*)0x1; /* overwritten below */
- tn = tpl_map("s", &s);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("s %s null\n", (s==NULL?"is":"is NOT"));
- return(0);
-}
-
+++ /dev/null
-s is hello
-s is NULL
-s is hello
-s is NULL
-s is hello
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename="/tmp/test94.tpl";
-int main() {
- tpl_node *tn;
- int i;
- char *s = NULL;
- tn = tpl_map("A(s)", &s);
- for(i=0;i<5;i++) {
- s = (i&1) ? NULL : "hello"; /* odd i are NULL string */
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- s = (char*)0x1; /* overwritten below */
- tn = tpl_map("A(s)", &s);
- tpl_load(tn,TPL_FILE,filename);
- while( tpl_unpack(tn,1) > 0) {
- printf("s is %s\n", (s?s:"NULL"));
- }
- tpl_free(tn);
- return(0);
-}
-
+++ /dev/null
-s is hello
-s is NULL
-s is hello
-s is NULL
-s is hello
+++ /dev/null
-s1 NULL
-s2
-s3 hello
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename="/tmp/test95.tpl";
-int main() {
- tpl_node *tn;
- char *s1 = NULL, *s2 = "", *s3 = "hello";
- tn = tpl_map("sss", &s1, &s2, &s3);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- s1 = s2 = s3 = (char*)0x1; /* overwritten below */
- tn = tpl_map("sss", &s1, &s2, &s3);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
- printf("s1 %s\n", s1?s1:"NULL");
- printf("s2 %s\n", s2?s2:"NULL");
- printf("s3 %s\n", s3?s3:"NULL");
- return(0);
-}
-
+++ /dev/null
-s1 NULL
-s2
-s3 hello
+++ /dev/null
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-
-const char *filename="/tmp/test96.tpl";
-int main() {
- tpl_node *tn;
- int i;
- char *s1 = NULL, *s2 = "", *s3 = "hello";
- tn = tpl_map("A(sss)", &s1, &s2, &s3);
- for(i=0;i<5;i++) {
- tpl_pack(tn,1);
- }
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- s1 = s2 = s3 = (char*)0x1; /* overwritten below */
- tn = tpl_map("A(sss)", &s1, &s2, &s3);
- tpl_load(tn,TPL_FILE,filename);
- while( tpl_unpack(tn,1) > 0) {
- printf("s1 %s\n", s1?s1:"NULL");
- printf("s2 %s\n", s2?s2:"NULL");
- printf("s3 %s\n", s3?s3:"NULL");
- }
- tpl_free(tn);
- return(0);
-}
-
+++ /dev/null
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
-s1 NULL
-s2
-s3 hello
+++ /dev/null
-j is -128, v is 65535
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <inttypes.h>
-
-const char *filename = "/tmp/test97.tpl";
-
-int main() {
- tpl_node *tn;
- int16_t j = -128;
- uint16_t v=65535;
-
- tn = tpl_map("jv", &j, &v);
- tpl_pack(tn,0);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- j = v = 0;
-
- tn = tpl_map("jv", &j, &v);
- tpl_load(tn,TPL_FILE,filename);
- tpl_unpack(tn,0);
- tpl_free(tn);
-
- printf("j is %d, v is %d\n", (int)j, (int)v);
- return(0);
-
-}
+++ /dev/null
-j is -128, v is 65535
+++ /dev/null
-j is -128, v is 65535
-j is -129, v is 65534
-j is -130, v is 65533
+++ /dev/null
-#include "tpl.h"
-#include <stdio.h>
-#include <inttypes.h>
-
-const char *filename = "/tmp/test98.tpl";
-
-int main() {
- tpl_node *tn;
- int16_t j = -128;
- uint16_t v=65535;
-
- tn = tpl_map("A(jv)", &j, &v);
- tpl_pack(tn,1); j -= 1; v-= 1;
- tpl_pack(tn,1); j -= 1; v-= 1;
- tpl_pack(tn,1);
- tpl_dump(tn,TPL_FILE,filename);
- tpl_free(tn);
-
- j = v = 0;
-
- tn = tpl_map("A(jv)", &j, &v);
- tpl_load(tn,TPL_FILE,filename);
- while (tpl_unpack(tn,1) > 0) {
- printf("j is %d, v is %d\n", (int)j, (int)v);
- }
- tpl_free(tn);
- return(0);
-}
+++ /dev/null
-j is -128, v is 65535
-j is -129, v is 65534
-j is -130, v is 65533
+++ /dev/null
-cA(i#)S(cf#)A(ci#)
-&
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-
-int main() {
- char *fmt, c;
- fmt = tpl_peek(TPL_FILE|TPL_DATAPEEK, "test99.tpl", "c", &c);
- if (fmt) {
- printf("%s\n",fmt);
- free(fmt);
- printf("%c\n", c);
- }
- return 0;
-}
+++ /dev/null
-cA(i#)S(cf#)A(ci#)
-&
+++ /dev/null
-TPLSRC = ../../src
-PROGS = test1
-
-# Thread support requires compiler-specific options
-# ----------------------------------------------------------------------------
-# GNU
-CFLAGS = -I$(TPLSRC) -g -pthread
-# Solaris (Studio 11 on Sparc Ultra3)
-#CFLAGS = -I$(TPLSRC) -g -mt
-# ----------------------------------------------------------------------------
-
-all: $(PROGS) run_tests
-
-tpl.o : $(TPLSRC)/tpl.c $(TPLSRC)/tpl.h
- $(CC) -c $(CFLAGS) $(TPLSRC)/tpl.c
-
-$(PROGS) : tpl.o
- $(CC) $(CFLAGS) -o $@ $(@).c tpl.o
-
-run_tests: $(PROGS)
- perl ../do_tests
-
-.PHONY: clean
-
-clean:
- rm -f $(PROGS) tpl.o test*.out
+++ /dev/null
-Tests for using tpl in threaded programs.
-
-thread_ipc.c a thread version of the pipe IPC test ../test28.c
+++ /dev/null
-sum is 49995000
-thread result: 0 null
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "tpl.h"
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <pthread.h>
-
-int fd[2];
-
-void *thread_routine( void *arg ) {
- tpl_node *tn;
- int i,sum=0;
-
- /* child */
- tn = tpl_map("A(u)",&i);
- tpl_load(tn, TPL_FD, fd[0]);
- while (tpl_unpack(tn,1) > 0) sum += i;
- tpl_free(tn);
- printf("sum is %d\n", sum);
- return NULL;
-}
-
-int main() {
- tpl_node *tn;
- unsigned i;
- int status;
- pthread_t thread_id;
- void *thread_result;
-
- pipe(fd);
- if ( status = pthread_create( &thread_id, NULL, thread_routine, NULL )) {
- printf("failure: status %d\n", status);
- exit(-1);
- }
- /* parent */
- tn = tpl_map("A(u)",&i);
- for(i=0;i<10000;i++) tpl_pack(tn,1);
- tpl_dump(tn,TPL_FD, fd[1] );
- tpl_free(tn);
-
- status = pthread_join( thread_id, &thread_result );
- printf("thread result: %d %s\n", status, thread_result ? "non-null":"null");
-}
*/
#include <switch.h>
-#include <switch_event.h>
-#include "tpl.h"
#include "private/switch_core_pvt.h"
+#include <switch_event.h>
+#ifdef HAVE_LIBTPL
+#include <tpl.h>
+#endif
//#define SWITCH_EVENT_RECYCLE
#define DISPATCH_QUEUE_LEN 10000
SWITCH_DECLARE(switch_status_t) switch_event_binary_deserialize(switch_event_t **eventp, void **data, switch_size_t len, switch_bool_t destroy)
{
+#ifdef HAVE_LIBTPL
switch_event_t *event;
tpl_node *tn;
switch_serial_event_t e;
event->body = e.body;
- while(tpl_unpack(tn, 1)) {
+ while (tpl_unpack(tn, 1)) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, sh.name, sh.value);
}
*data = NULL;
return SWITCH_STATUS_SUCCESS;
+#else
+ return SWITCH_STATUS_FALSE;
+#endif
}
SWITCH_DECLARE(switch_status_t) switch_event_binary_serialize(switch_event_t *event, void **data, switch_size_t *len)
{
+#ifdef HAVE_LIBTPL
tpl_node *tn;
switch_serial_event_t e;
switch_serial_event_header_t sh;
tpl_free(tn);
return SWITCH_STATUS_SUCCESS;
+#else
+ return SWITCH_STATUS_FALSE;
+#endif
}
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\..\libs\libtpl-1.5\src\tpl.c">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</TreatWarningAsError>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</TreatWarningAsError>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</TreatWarningAsError>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</TreatWarningAsError>
- </ClCompile>
- <ClCompile Include="..\..\libs\libtpl-1.5\src\win\mmap.c">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</TreatWarningAsError>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</TreatWarningAsError>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</TreatWarningAsError>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
- <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</TreatWarningAsError>
- </ClCompile>
<ClCompile Include="..\..\src\g711.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\..\libs\libtpl-1.5\src\tpl.h" />
<ClInclude Include="..\..\libs\miniupnpc\declspec.h" />
<ClInclude Include="..\..\src\include\g711.h" />
<ClInclude Include="..\..\src\include\SimpleGlob.h" />