summaryrefslogtreecommitdiff
path: root/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf')
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.am31
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.in675
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/bezier.cc376
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/clp.c2351
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/error.cc1169
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/filename.cc130
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/fixlibc.c73
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/globmatch.cc116
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/landmark.cc36
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/md5.c357
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/permstr.cc319
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/point.cc57
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/slurper.cc187
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/straccum.cc304
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/string.cc786
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/strtonum.c31
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/transform.cc167
-rw-r--r--Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/vectorv.cc110
18 files changed, 7275 insertions, 0 deletions
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.am b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.am
new file mode 100644
index 00000000000..f096b1c41bf
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.am
@@ -0,0 +1,31 @@
+## Process this file with automake to produce Makefile.in
+AUTOMAKE_OPTIONS = foreign
+
+noinst_LIBRARIES = liblcdf.a
+
+liblcdf_a_SOURCES = bezier.cc \
+ clp.c \
+ error.cc \
+ filename.cc \
+ globmatch.cc \
+ landmark.cc \
+ md5.c \
+ permstr.cc \
+ point.cc \
+ slurper.cc \
+ straccum.cc \
+ string.cc \
+ strtonum.c \
+ transform.cc \
+ vectorv.cc
+
+if FIXLIBC
+liblcdf_a_SOURCES += fixlibc.c
+endif FIXLIBC
+
+liblcdf_a_LIBADD = @TEMPLATE_OBJS@
+CLEANFILES = @TEMPLATE_OBJS@
+
+AM_CPPFLAGS = -I$(srcdir)/../include
+
+EXTRA_DIST = fixlibc.c
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.in b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.in
new file mode 100644
index 00000000000..5c19bd59f17
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/Makefile.in
@@ -0,0 +1,675 @@
+# Makefile.in generated by automake 1.14 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@FIXLIBC_TRUE@am__append_1 = fixlibc.c
+subdir = lcdf-typetools-2.99/liblcdf
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/../../build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_cxx_template_objs.m4 \
+ $(top_srcdir)/../../m4/kpse-common.m4 \
+ $(top_srcdir)/../../m4/kpse-cxx-hack.m4 \
+ $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \
+ $(top_srcdir)/../../m4/kpse-warnings.m4 \
+ $(top_srcdir)/../../m4/kpse-win32.m4 \
+ $(top_srcdir)/../../m4/libtool.m4 \
+ $(top_srcdir)/../../m4/ltoptions.m4 \
+ $(top_srcdir)/../../m4/ltsugar.m4 \
+ $(top_srcdir)/../../m4/ltversion.m4 \
+ $(top_srcdir)/../../m4/lt~obsolete.m4 $(top_srcdir)/version.ac \
+ $(top_srcdir)/ac/lcdf-typetools.ac $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/autoconf.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_@AM_V@)
+am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
+am__v_AR_0 = @echo " AR " $@;
+am__v_AR_1 =
+liblcdf_a_AR = $(AR) $(ARFLAGS)
+liblcdf_a_DEPENDENCIES =
+am__liblcdf_a_SOURCES_DIST = bezier.cc clp.c error.cc filename.cc \
+ globmatch.cc landmark.cc md5.c permstr.cc point.cc slurper.cc \
+ straccum.cc string.cc strtonum.c transform.cc vectorv.cc \
+ fixlibc.c
+@FIXLIBC_TRUE@am__objects_1 = fixlibc.$(OBJEXT)
+am_liblcdf_a_OBJECTS = bezier.$(OBJEXT) clp.$(OBJEXT) error.$(OBJEXT) \
+ filename.$(OBJEXT) globmatch.$(OBJEXT) landmark.$(OBJEXT) \
+ md5.$(OBJEXT) permstr.$(OBJEXT) point.$(OBJEXT) \
+ slurper.$(OBJEXT) straccum.$(OBJEXT) string.$(OBJEXT) \
+ strtonum.$(OBJEXT) transform.$(OBJEXT) vectorv.$(OBJEXT) \
+ $(am__objects_1)
+liblcdf_a_OBJECTS = $(am_liblcdf_a_OBJECTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../../build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(liblcdf_a_SOURCES)
+DIST_SOURCES = $(am__liblcdf_a_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXLD = @CXXLD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+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@
+KPATHSEA_DEPEND = @KPATHSEA_DEPEND@
+KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@
+KPATHSEA_LIBS = @KPATHSEA_LIBS@
+LCDF_TYPETOOLS_TREE = @LCDF_TYPETOOLS_TREE@
+LCDF_TYPETOOLS_VERSION = @LCDF_TYPETOOLS_VERSION@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+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_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SELECTED_SUBDIRS = @SELECTED_SUBDIRS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TEMPLATE_OBJS = @TEMPLATE_OBJS@
+VERSION = @VERSION@
+WARNING_CFLAGS = @WARNING_CFLAGS@
+WARNING_CXXFLAGS = @WARNING_CXXFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+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@
+encdir = @encdir@
+exec_prefix = @exec_prefix@
+glyphlistdir = @glyphlistdir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+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@
+AUTOMAKE_OPTIONS = foreign
+noinst_LIBRARIES = liblcdf.a
+liblcdf_a_SOURCES = bezier.cc clp.c error.cc filename.cc globmatch.cc \
+ landmark.cc md5.c permstr.cc point.cc slurper.cc straccum.cc \
+ string.cc strtonum.c transform.cc vectorv.cc $(am__append_1)
+liblcdf_a_LIBADD = @TEMPLATE_OBJS@
+CLEANFILES = @TEMPLATE_OBJS@
+AM_CPPFLAGS = -I$(srcdir)/../include
+EXTRA_DIST = fixlibc.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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 lcdf-typetools-2.99/liblcdf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign lcdf-typetools-2.99/liblcdf/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: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+liblcdf.a: $(liblcdf_a_OBJECTS) $(liblcdf_a_DEPENDENCIES) $(EXTRA_liblcdf_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f liblcdf.a
+ $(AM_V_AR)$(liblcdf_a_AR) liblcdf.a $(liblcdf_a_OBJECTS) $(liblcdf_a_LIBADD)
+ $(AM_V_at)$(RANLIB) liblcdf.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bezier.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filename.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixlibc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globmatch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/landmark.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/permstr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/point.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slurper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/straccum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtonum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vectorv.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLIBRARIES cscopelist-am ctags \
+ ctags-am 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 tags-am 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:
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/bezier.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/bezier.cc
new file mode 100644
index 00000000000..95c8d8b9fb0
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/bezier.cc
@@ -0,0 +1,376 @@
+// -*- related-file-name: "../include/lcdf/bezier.hh" -*-
+
+/* bezier.{cc,hh} -- cubic Bezier curves
+ *
+ * Copyright (c) 1998-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/bezier.hh>
+
+//
+// bounding box
+//
+
+void
+Bezier::make_bb() const throw ()
+{
+ _bb = 0;
+ for (int i = 1; i < 4; i++) {
+ if (_p[i].x > bb_right_x())
+ _bb = (_bb & ~0x03) | (i << 0);
+ else if (_p[i].x < bb_left_x())
+ _bb = (_bb & ~0x0C) | (i << 2);
+ if (_p[i].y > bb_top_x())
+ _bb = (_bb & ~0x30) | (i << 4);
+ else if (_p[i].y < bb_bottom_x())
+ _bb = (_bb & ~0xC0) | (i << 6);
+ }
+}
+
+
+//
+// is_flat, eval
+//
+
+bool
+Bezier::is_flat(double t) const throw ()
+{
+ return (_p[2].on_segment(_p[0], _p[3], t)
+ && _p[1].on_segment(_p[0], _p[3], t));
+}
+
+static Point
+eval_bezier(Point *b_in, int degree, double u)
+{
+ assert(degree < 4);
+ Point b[4];
+ for (int i = 0; i <= degree; i++)
+ b[i] = b_in[i];
+
+ double m = 1.0 - u;
+ for (int i = 1; i <= degree; i++)
+ for (int j = 0; j <= degree - i; j++)
+ b[j] = b[j]*m + b[j+1]*u;
+ return b[0];
+}
+
+Point
+Bezier::eval(double u) const throw ()
+{
+ Bezier b = *this;
+ double m = 1.0 - u;
+ for (int i = 1; i < 4; i++)
+ for (int j = 0; j < 4 - i; j++)
+ b._p[j] = m * b._p[j] + u * b._p[j+1];
+ return b._p[0];
+}
+
+
+//
+// halve
+//
+
+void
+Bezier::halve(Bezier &l, Bezier &r) const throw ()
+{
+ Point half = Point::midpoint(_p[1], _p[2]);
+ l._p[0] = _p[0];
+ l._p[1] = Point::midpoint(_p[0], _p[1]);
+ l._p[2] = Point::midpoint(l._p[1], half);
+ r._p[3] = _p[3];
+ r._p[2] = Point::midpoint(_p[2], _p[3]);
+ r._p[1] = Point::midpoint(r._p[2], half);
+ r._p[0] = l._p[3] = Point::midpoint(l._p[2], r._p[1]);
+}
+
+
+//
+// hit testing
+//
+
+bool
+Bezier::in_bb(const Point &p, double tolerance) const throw ()
+{
+ ensure_bb();
+ if (bb_right() + tolerance < p.x
+ || bb_left() - tolerance > p.x
+ || bb_top() + tolerance < p.y
+ || bb_bottom() - tolerance > p.y)
+ return false;
+ else
+ return true;
+}
+
+double
+Bezier::hit_recurse(const Point &p, double tolerance, double leftd,
+ double rightd, double leftt, double rightt) const throw ()
+{
+ Bezier left, right;
+ double middled, resultt;
+
+ if (is_flat(tolerance)) {
+ if (p.on_segment(_p[0], _p[3], tolerance))
+ return (leftt + rightt) / 2;
+ else
+ return -1;
+ }
+
+ if (leftd < tolerance * tolerance)
+ return leftt;
+ if (rightd < tolerance * tolerance)
+ return rightt;
+
+ if (!in_bb(p, tolerance))
+ return -1;
+
+ halve(left, right);
+ middled = (right._p[0] - p).squared_length();
+ resultt = left.hit_recurse
+ (p, tolerance, leftd, middled, leftt, (leftt + rightt) / 2);
+ if (resultt >= 0)
+ return resultt;
+
+ return right.hit_recurse
+ (p, tolerance, middled, rightd, (leftt + rightt) / 2, rightt);
+}
+
+bool
+Bezier::hit(const Point &p, double tolerance) const throw ()
+{
+ double leftd = (_p[0] - p).squared_length();
+ double rightd = (_p[3] - p).squared_length();
+ double resultt = hit_recurse(p, tolerance, leftd, rightd, 0, 1);
+ return resultt >= 0;
+}
+
+
+//
+// segmentize to list of points
+//
+// uses recursive subdivision
+//
+
+void
+Bezier::segmentize(Vector<Point> &v, bool first) const
+{
+ if (is_flat(0.5)) {
+ if (first)
+ v.push_back(_p[0]);
+ v.push_back(_p[3]);
+ } else {
+ Bezier left, right;
+ halve(left, right);
+ left.segmentize(v, first);
+ right.segmentize(v, false);
+ }
+}
+
+
+//
+// curve fitting
+//
+// code after Philip J. Schneider's algorithm described, with code, in the
+// first Graphics Gems
+//
+
+static void
+chord_length_parameterize(const Point *d, int nd, Vector<double> &result)
+{
+ assert(result.size() == 0);
+ result.reserve(nd);
+ result.push_back(0);
+ for (int i = 1; i < nd; i++)
+ result.push_back(result.back() + Point::distance(d[i-1], d[i]));
+ double last_dist = result.back();
+ for (int i = 1; i < nd; i++)
+ result[i] /= last_dist;
+}
+
+static inline double
+B0(double u)
+{
+ double m = 1.0 - u;
+ return m*m*m;
+}
+
+static inline double
+B1(double u)
+{
+ double m = 1.0 - u;
+ return 3*m*m*u;
+}
+
+static inline double
+B2(double u)
+{
+ double m = 1.0 - u;
+ return 3*m*u*u;
+}
+
+static inline double
+B3(double u)
+{
+ return u*u*u;
+}
+
+static Bezier
+generate_bezier(const Point *d, int nd, const Vector<double> &parameters,
+ const Point &left_tangent, const Point &right_tangent)
+{
+ Point *a0 = new Point[nd];
+ Point *a1 = new Point[nd];
+
+ for (int i = 0; i < nd; i++) {
+ a0[i] = left_tangent * B1(parameters[i]);
+ a1[i] = right_tangent * B2(parameters[i]);
+ }
+
+ double c[2][2], x[2];
+ c[0][0] = c[0][1] = c[1][0] = c[1][1] = x[0] = x[1] = 0.0;
+
+ int last = nd - 1;
+ for (int i = 0; i < nd; i++) {
+ c[0][0] += Point::dot(a0[i], a0[i]);
+ c[0][1] += Point::dot(a0[i], a1[i]);
+ c[1][1] += Point::dot(a1[i], a1[i]);
+
+ Point tmp = d[i] - (d[0] * (B0(parameters[i]) + B1(parameters[i]))
+ + d[last] * (B2(parameters[i]) + B3(parameters[i])));
+ x[0] += Point::dot(a0[i], tmp);
+ x[1] += Point::dot(a1[i], tmp);
+ }
+ c[1][0] = c[0][1];
+
+ // compute determinants
+ double det_c0_c1 = c[0][0]*c[1][1] - c[1][0]*c[0][1];
+ double det_c0_x = c[0][0]*x[1] - c[0][1]*x[0];
+ double det_x_c1 = x[0]*c[1][1] - x[1]*c[0][1];
+
+ // finally, derive alpha values
+ if (det_c0_c1 == 0.0)
+ det_c0_c1 = c[0][0]*c[1][1] * 10e-12;
+ double alpha_l = det_x_c1 / det_c0_c1;
+ double alpha_r = det_c0_x / det_c0_c1;
+
+ // if alpha negative, use the Wu/Barsky heuristic
+ if (alpha_l < 0.0 || alpha_r < 0.0) {
+ double distance = Point::distance(d[0], d[last]) / 3;
+ return Bezier(d[0], d[0] + left_tangent*distance,
+ d[last] + right_tangent*distance, d[last]);
+ } else
+ return Bezier(d[0], d[0] + left_tangent*alpha_l,
+ d[last] + right_tangent*alpha_r, d[last]);
+}
+
+static double
+newton_raphson_root_find(const Bezier &b, const Point &p, double u)
+{
+ const Point *b_pts = b.points();
+
+ Point b_det[3];
+ for (int i = 0; i < 3; i++)
+ b_det[i] = (b_pts[i+1] - b_pts[i]) * 3;
+
+ Point b_det_det[2];
+ for (int i = 0; i < 2; i++)
+ b_det_det[i] = (b_det[i+1] - b_det[i]) * 2;
+
+ Point b_u = b.eval(u);
+ Point b_det_u = eval_bezier(b_det, 2, u);
+ Point b_det_det_u = eval_bezier(b_det_det, 1, u);
+
+ double numerator = Point::dot(b_u - p, b_det_u);
+ double denominator = Point::dot(b_det_u, b_det_u) +
+ Point::dot(b_u - p, b_det_det_u);
+
+ return u - numerator/denominator;
+}
+
+static void
+reparameterize(const Point *d, int nd, Vector<double> &parameters,
+ const Bezier &b)
+{
+ for (int i = 0; i < nd; i++)
+ parameters[i] = newton_raphson_root_find(b, d[i], parameters[i]);
+}
+
+static double
+compute_max_error(const Point *d, int nd, const Bezier &b,
+ const Vector<double> &parameters, int *split_point)
+{
+ *split_point = nd/2;
+ double max_dist = 0.0;
+ for (int i = 1; i < nd - 1; i++) {
+ double dist = (b.eval(parameters[i]) - d[i]).squared_length();
+ if (dist >= max_dist) {
+ max_dist = dist;
+ *split_point = i;
+ }
+ }
+ return max_dist;
+}
+
+static void
+fit0(const Point *d, int nd, Point left_tangent, Point right_tangent,
+ double error, Vector<Bezier> &result)
+{
+ // Use a heuristic for small regions (only two points)
+ if (nd == 2) {
+ double dist = Point::distance(d[0], d[1]) / 3;
+ result.push_back(Bezier(d[0],
+ d[0] + dist*left_tangent,
+ d[1] + dist*right_tangent,
+ d[1]));
+ return;
+ }
+
+ // Parameterize points and attempt to fit curve
+ Vector<double> parameters;
+ chord_length_parameterize(d, nd, parameters);
+ Bezier b = generate_bezier(d, nd, parameters, left_tangent, right_tangent);
+
+ // find max error
+ int split_point;
+ double max_error = compute_max_error(d, nd, b, parameters, &split_point);
+ if (max_error < error) {
+ result.push_back(b);
+ return;
+ }
+
+ // if error not too large, try iteration and reparameterization
+ if (max_error < error*error)
+ for (int i = 0; i < 4; i++) {
+ reparameterize(d, nd, parameters, b);
+ b = generate_bezier(d, nd, parameters, left_tangent, right_tangent);
+ max_error = compute_max_error(d, nd, b, parameters, &split_point);
+ if (max_error < error) {
+ result.push_back(b);
+ return;
+ }
+ }
+
+ // fitting failed -- split at max error point and fit again
+ Point center_tangent = ((d[split_point-1] - d[split_point+1])/2).normal();
+ fit0(d, split_point+1, left_tangent, center_tangent, error, result);
+ fit0(d+split_point, nd-split_point, -center_tangent, right_tangent, error, result);
+}
+
+void
+Bezier::fit(const Vector<Point> &points, double error, Vector<Bezier> &result)
+{
+ int npoints = points.size();
+ Point left_tangent = (points[1] - points[0]).normal();
+ Point right_tangent = (points[npoints-2] - points[npoints-1]).normal();
+ fit0(&points[0], npoints, left_tangent, right_tangent, error, result);
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/clp.c b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/clp.c
new file mode 100644
index 00000000000..b8aaafd2096
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/clp.c
@@ -0,0 +1,2351 @@
+/* -*- related-file-name: "../include/lcdf/clp.h" -*- */
+/* clp.c - Complete source code for CLP.
+ * This file is part of CLP, the command line parser package.
+ *
+ * Copyright (c) 1997-2012 Eddie Kohler, ekohler@gmail.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file, which is available in full at
+ * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you
+ * must preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/clp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+/* By default, assume we have strtoul. */
+#if !defined(HAVE_STRTOUL) && !defined(HAVE_CONFIG_H)
+# define HAVE_STRTOUL 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @file clp.h
+ * @brief Functions for parsing command line options.
+ *
+ * The CLP functions are used to parse command line arugments into options.
+ * It automatically handles value parsing, error messages, long options with
+ * minimum prefix matching, short options, and negated options.
+ *
+ * The CLP model works like this.
+ *
+ * <ol>
+ * <li>The user declares an array of Clp_Option structures that define the
+ * options their program accepts.</li>
+ * <li>The user creates a Clp_Parser object using Clp_NewParser(), passing in
+ * the command line arguments to parse and the Clp_Option structures.</li>
+ * <li>A loop repeatedly calls Clp_Next() to parse the arguments.</li>
+ * </ol>
+ *
+ * Unlike many command line parsing libraries, CLP steps through all arguments
+ * one at a time, rather than slurping up all options at once. This makes it
+ * meaningful to give an option more than once.
+ *
+ * Here's an example.
+ *
+ * @code
+ * #define ANIMAL_OPT 1
+ * #define VEGETABLE_OPT 2
+ * #define MINERALS_OPT 3
+ * #define USAGE_OPT 4
+ *
+ * static const Clp_Option options[] = {
+ * { "animal", 'a', ANIMAL_OPT, Clp_ValString, 0 },
+ * { "vegetable", 'v', VEGETABLE_OPT, Clp_ValString, Clp_Negate | Clp_Optional },
+ * { "minerals", 'm', MINERALS_OPT, Clp_ValInt, 0 },
+ * { "usage", 0, USAGE_OPT, 0, 0 }
+ * };
+ *
+ * int main(int argc, char *argv[]) {
+ * Clp_Parser *clp = Clp_NewParser(argc, argv,
+ * sizeof(options) / sizeof(options[0]), options);
+ * int opt;
+ * while ((opt = Clp_Next(clp)) != Clp_Done)
+ * switch (opt) {
+ * case ANIMAL_OPT:
+ * fprintf(stderr, "animal is %s\n", clp->val.s);
+ * break;
+ * case VEGETABLE_OPT:
+ * if (clp->negated)
+ * fprintf(stderr, "no vegetables!\n");
+ * else if (clp->have_val)
+ * fprintf(stderr, "vegetable is %s\n", clp->val.s);
+ * else
+ * fprintf(stderr, "vegetables OK\n");
+ * break;
+ * case MINERALS_OPT:
+ * fprintf(stderr, "%d minerals\n", clp->val.i);
+ * break;
+ * case USAGE_OPT:
+ * fprintf(stderr, "Usage: 20q [--animal=ANIMAL] [--vegetable[=VEGETABLE]] [--minerals=N]\n");
+ * break;
+ * case Clp_NotOption:
+ * fprintf(stderr, "non-option %s\n", clp->vstr);
+ * break;
+ * }
+ * }
+ * }
+ * @endcode
+ *
+ * Here are a couple of executions.
+ *
+ * <pre>
+ * % ./20q --animal=cat
+ * animal is cat
+ * % ./20q --animal=cat -a dog -afish --animal bird --an=snake
+ * animal is cat
+ * animal is dog
+ * animal is fish
+ * animal is bird
+ * animal is snake
+ * % ./20q --no-vegetables
+ * no vegetables!
+ * % ./20q -v
+ * vegetables OK
+ * % ./20q -vkale
+ * vegetable is kale
+ * % ./20q -m10
+ * 10 minerals
+ * % ./20q -m foo
+ * '-m' expects an integer, not 'foo'
+ * </pre>
+ */
+
+
+/* Option types for Clp_SetOptionChar */
+#define Clp_DoubledLong (Clp_LongImplicit * 2)
+
+#define Clp_InitialValType 8
+#define MAX_AMBIGUOUS_VALUES 4
+
+typedef struct {
+ int val_type;
+ Clp_ValParseFunc func;
+ int flags;
+ void *user_data;
+} Clp_ValType;
+
+typedef struct {
+ unsigned ilong : 1;
+ unsigned ishort : 1;
+ unsigned imandatory : 1;
+ unsigned ioptional : 1;
+ unsigned ipos : 1;
+ unsigned ineg : 1;
+ unsigned iprefmatch : 1;
+ unsigned lmmpos_short : 1;
+ unsigned lmmneg_short : 1;
+ unsigned char ilongoff;
+ int lmmpos;
+ int lmmneg;
+} Clp_InternOption;
+
+
+#define Clp_OptionCharsSize 5
+
+typedef struct {
+ int c;
+ int type;
+} Clp_Oclass;
+#define Clp_OclassSize 10
+
+typedef struct Clp_Internal {
+ const Clp_Option *opt;
+ Clp_InternOption *iopt;
+ int nopt;
+ unsigned opt_generation;
+
+ Clp_ValType *valtype;
+ int nvaltype;
+
+ const char * const *argv;
+ int argc;
+
+ Clp_Oclass oclass[Clp_OclassSize];
+ int noclass;
+ int long1pos;
+ int long1neg;
+ int utf8;
+
+ char option_chars[Clp_OptionCharsSize];
+ const char *xtext;
+
+ const char *program_name;
+ void (*error_handler)(Clp_Parser *, const char *);
+
+ int option_processing;
+ int current_option;
+
+ unsigned char is_short;
+ unsigned char whole_negated; /* true if negated by an option character */
+ unsigned char could_be_short;
+ unsigned char current_short;
+ unsigned char negated_by_no;
+
+ int ambiguous;
+ int ambiguous_values[MAX_AMBIGUOUS_VALUES];
+} Clp_Internal;
+
+
+struct Clp_ParserState {
+ const char * const *argv;
+ int argc;
+
+ char option_chars[Clp_OptionCharsSize];
+ const char *xtext;
+
+ int option_processing;
+
+ unsigned opt_generation;
+ int current_option;
+ unsigned char is_short;
+ unsigned char whole_negated;
+ unsigned char current_short;
+ unsigned char negated_by_no;
+};
+
+
+typedef struct Clp_StringList {
+
+ Clp_Option *items;
+ Clp_InternOption *iopt;
+ int nitems;
+
+ int allow_int;
+ int nitems_invalid_report;
+
+} Clp_StringList;
+
+
+static int parse_string(Clp_Parser *, const char *, int, void *);
+static int parse_int(Clp_Parser *, const char *, int, void *);
+static int parse_bool(Clp_Parser *, const char *, int, void *);
+static int parse_double(Clp_Parser *, const char *, int, void *);
+static int parse_string_list(Clp_Parser *, const char *, int, void *);
+
+static int ambiguity_error(Clp_Parser *, int, int *, const Clp_Option *,
+ const Clp_InternOption *, const char *, const char *,
+ ...);
+
+
+/*******
+ * utf8
+ **/
+
+#define U_REPLACEMENT 0xFFFD
+
+static char *
+encode_utf8(char *s, int n, int c)
+{
+ if (c < 0 || c >= 0x110000 || (c >= 0xD800 && c <= 0xDFFF))
+ c = U_REPLACEMENT;
+ if (c <= 0x7F && n >= 1)
+ *s++ = c;
+ else if (c <= 0x7FF && n >= 2) {
+ *s++ = 0xC0 | (c >> 6);
+ goto char1;
+ } else if (c <= 0xFFFF && n >= 3) {
+ *s++ = 0xE0 | (c >> 12);
+ goto char2;
+ } else if (n >= 4) {
+ *s++ = 0xF0 | (c >> 18);
+ *s++ = 0x80 | ((c >> 12) & 0x3F);
+ char2:
+ *s++ = 0x80 | ((c >> 6) & 0x3F);
+ char1:
+ *s++ = 0x80 | (c & 0x3F);
+ }
+ return s;
+}
+
+static int
+decode_utf8(const char *s, const char **cp)
+{
+ int c;
+ if ((unsigned char) *s <= 0x7F) /* 1 byte: 0x000000-0x00007F */
+ c = *s++;
+ else if ((unsigned char) *s <= 0xC1) /* bad/overlong encoding */
+ goto replacement;
+ else if ((unsigned char) *s <= 0xDF) { /* 2 bytes: 0x000080-0x0007FF */
+ if ((s[1] & 0xC0) != 0x80) /* bad encoding */
+ goto replacement;
+ c = (*s++ & 0x1F) << 6;
+ goto char1;
+ } else if ((unsigned char) *s <= 0xEF) { /* 3 bytes: 0x000800-0x00FFFF */
+ if ((s[1] & 0xC0) != 0x80 /* bad encoding */
+ || (s[2] & 0xC0) != 0x80 /* bad encoding */
+ || ((unsigned char) *s == 0xE0 /* overlong encoding */
+ && (s[1] & 0xE0) == 0x80)
+ || ((unsigned char) *s == 0xED /* encoded surrogate */
+ && (s[1] & 0xE0) == 0xA0))
+ goto replacement;
+ c = (*s++ & 0x0F) << 12;
+ goto char2;
+ } else if ((unsigned char) *s <= 0xF4) { /* 4 bytes: 0x010000-0x10FFFF */
+ if ((s[1] & 0xC0) != 0x80 /* bad encoding */
+ || (s[2] & 0xC0) != 0x80 /* bad encoding */
+ || (s[3] & 0xC0) != 0x80 /* bad encoding */
+ || ((unsigned char) *s == 0xF0 /* overlong encoding */
+ && (s[1] & 0xF0) == 0x80)
+ || ((unsigned char) *s == 0xF4 /* encoded value > 0x10FFFF */
+ && (unsigned char) s[1] >= 0x90))
+ goto replacement;
+ c = (*s++ & 0x07) << 18;
+ c += (*s++ & 0x3F) << 12;
+ char2:
+ c += (*s++ & 0x3F) << 6;
+ char1:
+ c += (*s++ & 0x3F);
+ } else {
+ replacement:
+ c = U_REPLACEMENT;
+ for (s++; (*s & 0xC0) == 0x80; s++)
+ /* nothing */;
+ }
+ if (cp)
+ *cp = s;
+ return c;
+}
+
+static int
+utf8_charlen(const char *s)
+{
+ const char *sout;
+ (void) decode_utf8(s, &sout);
+ return sout - s;
+}
+
+static int
+clp_utf8_charlen(const Clp_Internal *cli, const char *s)
+{
+ return (cli->utf8 ? utf8_charlen(s) : 1);
+}
+
+
+/*******
+ * Clp_NewParser, etc.
+ **/
+
+static int
+min_different_chars(const char *s, const char *t)
+ /* Returns the minimum number of bytes required to distinguish
+ s from t.
+ If s is shorter than t, returns strlen(s). */
+{
+ const char *sfirst = s;
+ while (*s && *t && *s == *t)
+ s++, t++;
+ if (!*s)
+ return s - sfirst;
+ else
+ return s - sfirst + 1;
+}
+
+static int
+long_as_short(const Clp_Internal *cli, const Clp_Option *o,
+ Clp_InternOption *io, int failure)
+{
+ if ((cli->long1pos || cli->long1neg) && io->ilong) {
+ const char *name = o->long_name + io->ilongoff;
+ if (cli->utf8) {
+ int c = decode_utf8(name, &name);
+ if (!*name && c && c != U_REPLACEMENT)
+ return c;
+ } else if (name[0] && !name[1])
+ return (unsigned char) name[0];
+ }
+ return failure;
+}
+
+static void
+compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1,
+ const Clp_Option *o2, Clp_InternOption *io2)
+{
+ Clp_Internal *cli = clp->internal;
+ int short1, shortx1;
+
+ /* ignore meaningless combinations */
+ if ((!io1->ishort && !io1->ilong) || (!io2->ishort && !io2->ilong)
+ || !((io1->ipos && io2->ipos) || (io1->ineg && io2->ineg))
+ || o1->option_id == o2->option_id)
+ return;
+
+ /* look for duplication of short options */
+ short1 = (io1->ishort ? o1->short_name : -1);
+ shortx1 = long_as_short(cli, o1, io1, -2);
+ if (short1 >= 0 || shortx1 >= 0) {
+ int short2 = (io2->ishort ? o2->short_name : -3);
+ int shortx2 = long_as_short(cli, o2, io2, -4);
+ if (short1 == short2)
+ Clp_OptionError(clp, "CLP internal error: more than 1 option has short name %<%c%>", short1);
+ else if ((short1 == shortx2 || shortx1 == short2 || shortx1 == shortx2)
+ && ((io1->ipos && io2->ipos && cli->long1pos)
+ || (io1->ineg && io2->ineg && cli->long1neg)))
+ Clp_OptionError(clp, "CLP internal error: 1-char long name conflicts with short name %<%c%>", (short1 == shortx2 ? shortx2 : shortx1));
+ }
+
+ /* analyze longest minimum match */
+ if (io1->ilong) {
+ const char *name1 = o1->long_name + io1->ilongoff;
+
+ /* long name's first character matches short name */
+ if (io2->ishort && !io1->iprefmatch) {
+ int name1char = (cli->utf8 ? decode_utf8(name1, 0) : (unsigned char) *name1);
+ if (name1char == o2->short_name) {
+ if (io1->ipos && io2->ipos)
+ io1->lmmpos_short = 1;
+ if (io1->ineg && io2->ineg)
+ io1->lmmneg_short = 1;
+ }
+ }
+
+ /* match long name to long name */
+ if (io2->ilong) {
+ const char *name2 = o2->long_name + io2->ilongoff;
+ if (strcmp(name1, name2) == 0)
+ Clp_OptionError(clp, "CLP internal error: duplicate long name %<%s%>", name1);
+ if (io1->ipos && io2->ipos && !strncmp(name1, name2, io1->lmmpos)
+ && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1))))
+ io1->lmmpos = min_different_chars(name1, name2);
+ if (io1->ineg && io2->ineg && !strncmp(name1, name2, io1->lmmneg)
+ && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1))))
+ io1->lmmneg = min_different_chars(name1, name2);
+ }
+ }
+}
+
+/** @param argc number of arguments
+ * @param argv argument array
+ * @param nopt number of option definitions
+ * @param opt option definition array
+ * @return the parser
+ *
+ * The new Clp_Parser that will parse the arguments in @a argv according to
+ * the option definitions in @a opt.
+ *
+ * The Clp_Parser is created with the following characteristics:
+ *
+ * <ul>
+ * <li>The "-" character introduces short options (<tt>Clp_SetOptionChar(clp,
+ * '-', Clp_Short)</tt>).</li>
+ * <li>Clp_ProgramName is set from the first argument in @a argv, if any. The
+ * first argument returned by Clp_Next() will be the second argument in @a
+ * argv. Note that this behavior differs from Clp_SetArguments.</li>
+ * <li>UTF-8 support is on iff the <tt>LANG</tt> environment variable contains
+ * one of the substrings "UTF-8", "UTF8", or "utf8". Override this with
+ * Clp_SetUTF8().</li>
+ * <li>The Clp_ValString, Clp_ValStringNotOption, Clp_ValInt, Clp_ValUnsigned,
+ * Clp_ValBool, and Clp_ValDouble types are installed.</li>
+ * <li>Errors are reported to standard error.</li>
+ * </ul>
+ *
+ * You may also create a Clp_Parser with no arguments or options
+ * (<tt>Clp_NewParser(0, 0, 0, 0)</tt>) and set the arguments and options
+ * later.
+ *
+ * Returns NULL if there isn't enough memory to construct the parser.
+ *
+ * @note The CLP library will not modify the contents of @a argv or @a opt.
+ * The calling program must not modify @a opt. It may modify @a argv in
+ * limited cases.
+ */
+Clp_Parser *
+Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *opt)
+{
+ Clp_Parser *clp = (Clp_Parser *)malloc(sizeof(Clp_Parser));
+ Clp_Internal *cli = (Clp_Internal *)malloc(sizeof(Clp_Internal));
+ Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt);
+ if (cli)
+ cli->valtype = (Clp_ValType *)malloc(sizeof(Clp_ValType) * Clp_InitialValType);
+ if (!clp || !cli || !iopt || !cli->valtype)
+ goto failed;
+
+ clp->opt = -1;
+ clp->negated = 0;
+ clp->have_val = 0;
+ clp->vstr = 0;
+ clp->user_data = 0;
+ clp->internal = cli;
+
+ cli->opt = opt;
+ cli->nopt = nopt;
+ cli->iopt = iopt;
+ cli->opt_generation = 0;
+ cli->error_handler = 0;
+
+ /* Assign program name (now so we can call Clp_OptionError) */
+ if (argc > 0) {
+ const char *slash = strrchr(argv[0], '/');
+ cli->program_name = slash ? slash + 1 : argv[0];
+ } else
+ cli->program_name = 0;
+
+ /* Assign arguments, skipping program name */
+ Clp_SetArguments(clp, argc - 1, argv + 1);
+
+ /* Initialize UTF-8 status and option classes */
+ {
+ char *s = getenv("LANG");
+ cli->utf8 = (s && (strstr(s, "UTF-8") != 0 || strstr(s, "UTF8") != 0
+ || strstr(s, "utf8") != 0));
+ }
+ cli->oclass[0].c = '-';
+ cli->oclass[0].type = Clp_Short;
+ cli->noclass = 1;
+ cli->long1pos = cli->long1neg = 0;
+
+ /* Add default type parsers */
+ cli->nvaltype = 0;
+ Clp_AddType(clp, Clp_ValString, 0, parse_string, 0);
+ Clp_AddType(clp, Clp_ValStringNotOption, Clp_DisallowOptions, parse_string, 0);
+ Clp_AddType(clp, Clp_ValInt, 0, parse_int, 0);
+ Clp_AddType(clp, Clp_ValUnsigned, 0, parse_int, (void *)cli);
+ Clp_AddType(clp, Clp_ValBool, 0, parse_bool, 0);
+ Clp_AddType(clp, Clp_ValDouble, 0, parse_double, 0);
+
+ /* Set options */
+ Clp_SetOptions(clp, nopt, opt);
+
+ return clp;
+
+ failed:
+ if (cli && cli->valtype)
+ free(cli->valtype);
+ if (cli)
+ free(cli);
+ if (clp)
+ free(clp);
+ if (iopt)
+ free(iopt);
+ return 0;
+}
+
+/** @param clp the parser
+ *
+ * All memory associated with @a clp is freed. */
+void
+Clp_DeleteParser(Clp_Parser *clp)
+{
+ int i;
+ Clp_Internal *cli;
+ if (!clp)
+ return;
+
+ cli = clp->internal;
+
+ /* get rid of any string list types */
+ for (i = 0; i < cli->nvaltype; i++)
+ if (cli->valtype[i].func == parse_string_list) {
+ Clp_StringList *clsl = (Clp_StringList *)cli->valtype[i].user_data;
+ free(clsl->items);
+ free(clsl->iopt);
+ free(clsl);
+ }
+
+ free(cli->valtype);
+ free(cli->iopt);
+ free(cli);
+ free(clp);
+}
+
+
+/** @param clp the parser
+ * @param errh error handler function
+ * @return previous error handler function
+ *
+ * The error handler function is called when CLP encounters an error while
+ * parsing the command line. It is called with the arguments "<tt>(*errh)(@a
+ * clp, s)</tt>", where <tt>s</tt> is a description of the error terminated by
+ * a newline. The <tt>s</tt> descriptions produced by CLP itself are prefixed
+ * by the program name, if any. */
+Clp_ErrorHandler
+Clp_SetErrorHandler(Clp_Parser *clp, void (*errh)(Clp_Parser *, const char *))
+{
+ Clp_Internal *cli = clp->internal;
+ Clp_ErrorHandler old = cli->error_handler;
+ cli->error_handler = errh;
+ return old;
+}
+
+/** @param clp the parser
+ * @param utf8 does the parser support UTF-8?
+ * @return previous UTF-8 mode
+ *
+ * In UTF-8 mode, all input strings (arguments and long names for options) are
+ * assumed to be encoded via UTF-8, and all character names
+ * (Clp_SetOptionChar() and short names for options) may cover the whole
+ * Unicode range. Out of UTF-8 mode, all input strings are treated as binary,
+ * and all character names must be unsigned char values.
+ *
+ * Furthermore, error messages in UTF-8 mode may contain Unicode quote
+ * characters. */
+int
+Clp_SetUTF8(Clp_Parser *clp, int utf8)
+{
+ Clp_Internal *cli = clp->internal;
+ int i, j, old_utf8 = cli->utf8;
+ cli->utf8 = utf8;
+ for (i = 0; i < cli->nopt; ++i) {
+ cli->iopt[i].lmmpos = cli->iopt[i].lmmneg = 1;
+ cli->iopt[i].lmmpos_short = cli->iopt[i].lmmneg_short = 0;
+ for (j = 0; j < cli->nopt; ++j)
+ compare_options(clp, &cli->opt[i], &cli->iopt[i],
+ &cli->opt[j], &cli->iopt[j]);
+ }
+ return old_utf8;
+}
+
+/** @param clp the parser
+ * @param c character
+ * @return option character treatment
+ *
+ * Returns an integer specifying how CLP treats arguments that begin
+ * with character @a c. See Clp_SetOptionChar for possibilities.
+ */
+int
+Clp_OptionChar(Clp_Parser *clp, int c)
+{
+ Clp_Internal *cli = clp->internal;
+ int i, oclass = 0;
+ if (cli->noclass > 0 && cli->oclass[0].c == 0)
+ oclass = cli->oclass[0].type;
+ for (i = 0; i < cli->noclass; ++i)
+ if (cli->oclass[i].c == c)
+ oclass = cli->oclass[i].type;
+ return oclass;
+}
+
+/** @param clp the parser
+ * @param c character
+ * @param type option character treatment
+ * @return previous option character treatment, or -1 on error
+ *
+ * @a type specifies how CLP treats arguments that begin with character @a c.
+ * Possibilities are:
+ *
+ * <dl>
+ * <dt>Clp_NotOption (or 0)</dt>
+ * <dd>The argument cannot be an option.</dd>
+ * <dt>Clp_Long</dt>
+ * <dd>The argument is a long option.</dd>
+ * <dt>Clp_Short</dt>
+ * <dd>The argument is a set of short options.</dd>
+ * <dt>Clp_Short|Clp_Long</dt>
+ * <dd>The argument is either a long option or, if no matching long option is
+ * found, a set of short options.</dd>
+ * <dt>Clp_LongNegated</dt>
+ * <dd>The argument is a negated long option. For example, after
+ * Clp_SetOptionChar(@a clp, '^', Clp_LongNegated), the argument "^foo" is
+ * equivalent to "--no-foo".</dd>
+ * <dt>Clp_ShortNegated</dt>
+ * <dd>The argument is a set of negated short options.</dd>
+ * <dt>Clp_ShortNegated|Clp_LongNegated</dt>
+ * <dd>The argument is either a negated long option or, if no matching long
+ * option is found, a set of negated short options.</dd>
+ * <dt>Clp_LongImplicit</dt>
+ * <dd>The argument may be a long option, where the character @a c is actually
+ * part of the long option name. For example, after Clp_SetOptionChar(@a clp,
+ * 'f', Clp_LongImplicit), the argument "foo" may be equivalent to
+ * "--foo".</dd>
+ * </dl>
+ *
+ * In UTF-8 mode, @a c may be any Unicode character. Otherwise, @a c must be
+ * an unsigned char value. The special character 0 assigns @a type to @em
+ * every character.
+ *
+ * It is an error if @a c is out of range, @a type is illegal, or there are
+ * too many character definitions stored in @a clp already. The function
+ * returns -1 on error.
+ *
+ * A double hyphen "--" always introduces a long option. This behavior cannot
+ * currently be changed with Clp_SetOptionChar().
+ */
+int
+Clp_SetOptionChar(Clp_Parser *clp, int c, int type)
+{
+ int i, j, long1pos, long1neg;
+ int old = Clp_OptionChar(clp, c);
+ Clp_Internal *cli = clp->internal;
+
+ if (type != Clp_NotOption && type != Clp_Short && type != Clp_Long
+ && type != Clp_ShortNegated && type != Clp_LongNegated
+ && type != Clp_LongImplicit && type != (Clp_Short | Clp_Long)
+ && type != (Clp_ShortNegated | Clp_LongNegated))
+ return -1;
+ if (c < 0 || c >= (cli->utf8 ? 0x110000 : 256))
+ return -1;
+
+ if (c == 0)
+ cli->noclass = 0;
+ for (i = 0; i < cli->noclass; ++i)
+ if (cli->oclass[i].c == c)
+ break;
+ if (i == Clp_OclassSize)
+ return -1;
+
+ cli->oclass[i].c = c;
+ cli->oclass[i].type = type;
+ if (cli->noclass == i)
+ cli->noclass = i + 1;
+
+ long1pos = long1neg = 0;
+ for (i = 0; i < cli->noclass; ++i) {
+ if ((cli->oclass[i].type & Clp_Short)
+ && (cli->oclass[i].type & Clp_Long))
+ long1pos = 1;
+ if ((cli->oclass[i].type & Clp_ShortNegated)
+ && (cli->oclass[i].type & Clp_LongNegated))
+ long1neg = 1;
+ }
+
+ if (long1pos != cli->long1pos || long1neg != cli->long1neg) {
+ /* Must recheck option set */
+ cli->long1pos = long1pos;
+ cli->long1neg = long1neg;
+ for (i = 0; i < cli->nopt; ++i) {
+ cli->iopt[i].lmmpos = cli->iopt[i].lmmneg = 1;
+ cli->iopt[i].lmmpos_short = cli->iopt[i].lmmneg_short = 0;
+ for (j = 0; j < cli->nopt; ++j)
+ compare_options(clp, &cli->opt[i], &cli->iopt[i],
+ &cli->opt[j], &cli->iopt[j]);
+ }
+ }
+
+ return old;
+}
+
+/** @param clp the parser
+ * @param nopt number of option definitions
+ * @param opt option definition array
+ * @return 0 on success, -1 on failure
+ *
+ * Installs the option definitions in @a opt. Future option parsing will
+ * use @a opt to search for options.
+ *
+ * Also checks @a opt's option definitions for validity. "CLP internal
+ * errors" are reported via Clp_OptionError() if:
+ *
+ * <ul>
+ * <li>An option has a negative ID.</li>
+ * <li>Two different short options have the same name.</li>
+ * <li>Two different long options have the same name.</li>
+ * <li>A short and a long option are ambiguous, in that some option character
+ * might introduce either a short or a long option (e.g., Clp_SetOptionChar(@a
+ * clp, '-', Clp_Long|Clp_Short)), and a short name equals a long name.</li>
+ * </ul>
+ *
+ * If necessary memory cannot be allocated, this function returns -1 without
+ * modifying the parser.
+ *
+ * @note The CLP library will not modify the contents of @a argv or @a opt.
+ * The calling program must not modify @a opt either until another call to
+ * Clp_SetOptions() or the parser is destroyed.
+ */
+int
+Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt)
+{
+ Clp_Internal *cli = clp->internal;
+ Clp_InternOption *iopt;
+ int i, j;
+ static unsigned opt_generation = 0;
+
+ if (nopt > cli->nopt) {
+ iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt);
+ if (!iopt)
+ return -1;
+ free(cli->iopt);
+ cli->iopt = iopt;
+ }
+
+ cli->opt = opt;
+ cli->nopt = nopt;
+ cli->opt_generation = ++opt_generation;
+ iopt = cli->iopt;
+ cli->current_option = -1;
+
+ /* Massage the options to make them usable */
+ for (i = 0; i < nopt; i++) {
+ /* Ignore negative option_ids, which are internal to CLP */
+ if (opt[i].option_id < 0) {
+ Clp_OptionError(clp, "CLP internal error: option %d has negative option_id", i);
+ iopt[i].ilong = iopt[i].ishort = iopt[i].ipos = iopt[i].ineg = 0;
+ continue;
+ }
+
+ /* Set flags based on input flags */
+ iopt[i].ilong = (opt[i].long_name != 0 && opt[i].long_name[0] != 0);
+ iopt[i].ishort = (opt[i].short_name > 0
+ && opt[i].short_name < (cli->utf8 ? 0x110000 : 256));
+ iopt[i].ipos = 1;
+ iopt[i].ineg = (opt[i].flags & Clp_Negate) != 0;
+ iopt[i].imandatory = (opt[i].flags & Clp_Mandatory) != 0;
+ iopt[i].ioptional = (opt[i].flags & Clp_Optional) != 0;
+ iopt[i].iprefmatch = (opt[i].flags & Clp_PreferredMatch) != 0;
+ iopt[i].ilongoff = 0;
+
+ /* Enforce invariants */
+ if (opt[i].val_type <= 0)
+ iopt[i].imandatory = iopt[i].ioptional = 0;
+ if (opt[i].val_type > 0 && !iopt[i].ioptional)
+ iopt[i].imandatory = 1;
+
+ /* Options that start with 'no-' should be changed to OnlyNegated */
+ if (iopt[i].ilong && strncmp(opt[i].long_name, "no-", 3) == 0) {
+ iopt[i].ipos = 0;
+ iopt[i].ineg = 1;
+ iopt[i].ilongoff = 3;
+ if (strncmp(opt[i].long_name + 3, "no-", 3) == 0)
+ Clp_OptionError(clp, "CLP internal error: option %d begins with \"no-no-\"", i);
+ } else if (opt[i].flags & Clp_OnlyNegated) {
+ iopt[i].ipos = 0;
+ iopt[i].ineg = 1;
+ }
+ }
+
+ /* Check option set */
+ for (i = 0; i < nopt; ++i) {
+ iopt[i].lmmpos = iopt[i].lmmneg = 1;
+ iopt[i].lmmpos_short = iopt[i].lmmneg_short = 0;
+ for (j = 0; j < nopt; ++j)
+ compare_options(clp, &opt[i], &iopt[i], &opt[j], &iopt[j]);
+ }
+
+ return 0;
+}
+
+/** @param clp the parser
+ * @param argc number of arguments
+ * @param argv argument array
+ *
+ * Installs the arguments in @a argv for parsing. Future option parsing will
+ * analyze @a argv.
+ *
+ * Unlike Clp_NewParser(), this function does not treat @a argv[0] specially.
+ * The first subsequent call to Clp_Next() will analyze @a argv[0].
+ *
+ * This function also sets option processing to on, as by
+ * Clp_SetOptionProcessing(@a clp, 1).
+ *
+ * @note The CLP library will not modify the contents of @a argv. The calling
+ * program should not generally modify the element of @a argv that CLP is
+ * currently analyzing.
+ */
+void
+Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv)
+{
+ Clp_Internal *cli = clp->internal;
+
+ cli->argc = argc + 1;
+ cli->argv = argv - 1;
+
+ cli->is_short = 0;
+ cli->whole_negated = 0;
+ cli->option_processing = 1;
+ cli->current_option = -1;
+}
+
+
+/** @param clp the parser
+ * @param on whether to search for options
+ * @return previous option processing setting
+ *
+ * When option processing is off, every call to Clp_Next() returns
+ * Clp_NotOption. By default the option <tt>"--"</tt> turns off option
+ * processing and is otherwise ignored.
+ */
+int
+Clp_SetOptionProcessing(Clp_Parser *clp, int on)
+{
+ Clp_Internal *cli = clp->internal;
+ int old = cli->option_processing;
+ cli->option_processing = on;
+ return old;
+}
+
+
+/*******
+ * functions for Clp_Option lists
+ **/
+
+/* the ever-glorious argcmp */
+
+static int
+argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes)
+ /* Returns 0 if ref and arg don't match.
+ Returns -1 if ref and arg match, but fewer than min_match characters.
+ Returns len if ref and arg match min_match or more characters;
+ len is the number of characters that matched in arg.
+ Allows arg to contain fewer dashes than ref iff fewer_dashes != 0.
+
+ Examples:
+ argcmp("x", "y", 1, 0) --> 0 / just plain wrong
+ argcmp("a", "ax", 1, 0) --> 0 / ...even though min_match == 1
+ and the 1st chars match
+ argcmp("box", "bo", 3, 0) --> -1 / ambiguous
+ argcmp("cat", "c=3", 1, 0) --> 1 / handles = arguments
+ */
+{
+ const char *refstart = ref;
+ const char *argstart = arg;
+ assert(min_match > 0);
+
+ compare:
+ while (*ref && *arg && *arg != '=' && *ref == *arg)
+ ref++, arg++;
+
+ /* Allow arg to contain fewer dashes than ref */
+ if (fewer_dashes && *ref == '-' && ref[1] && ref[1] == *arg) {
+ ref++;
+ goto compare;
+ }
+
+ if (*arg && *arg != '=')
+ return 0;
+ else if (ref - refstart < min_match)
+ return -1;
+ else
+ return arg - argstart;
+}
+
+static int
+find_prefix_opt(Clp_Parser *clp, const char *arg,
+ int nopt, const Clp_Option *opt,
+ const Clp_InternOption *iopt,
+ int *ambiguous, int *ambiguous_values)
+ /* Looks for an unambiguous match of 'arg' against one of the long
+ options in 'opt'. Returns positive if it finds one; otherwise, returns
+ -1 and possibly changes 'ambiguous' and 'ambiguous_values' to keep
+ track of at most MAX_AMBIGUOUS_VALUES possibilities. */
+{
+ int i, fewer_dashes = 0, first_ambiguous = *ambiguous;
+ int negated = clp && clp->negated;
+ int first_charlen = (clp ? clp_utf8_charlen(clp->internal, arg) : 1);
+
+ retry:
+ for (i = 0; i < nopt; i++) {
+ int len, lmm;
+ if (!iopt[i].ilong || (negated ? !iopt[i].ineg : !iopt[i].ipos))
+ continue;
+
+ lmm = (negated ? iopt[i].lmmneg : iopt[i].lmmpos);
+ if (clp && clp->internal->could_be_short
+ && (negated ? iopt[i].lmmneg_short : iopt[i].lmmpos_short))
+ lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm);
+ len = argcmp(opt[i].long_name + iopt[i].ilongoff, arg, lmm, fewer_dashes);
+ if (len > 0)
+ return i;
+ else if (len < 0) {
+ if (*ambiguous < MAX_AMBIGUOUS_VALUES)
+ ambiguous_values[*ambiguous] = i;
+ (*ambiguous)++;
+ }
+ }
+
+ /* If there were no partial matches, try again with fewer_dashes true */
+ if (*ambiguous == first_ambiguous && !fewer_dashes) {
+ fewer_dashes = 1;
+ goto retry;
+ }
+
+ return -1;
+}
+
+
+/*****
+ * Argument parsing
+ **/
+
+static int
+val_type_binsearch(Clp_Internal *cli, int val_type)
+{
+ unsigned l = 0, r = cli->nvaltype;
+ while (l < r) {
+ unsigned m = l + (r - l) / 2;
+ if (cli->valtype[m].val_type == val_type)
+ return m;
+ else if (cli->valtype[m].val_type < val_type)
+ l = m + 1;
+ else
+ r = m;
+ }
+ return l;
+}
+
+/** @param clp the parser
+ * @param val_type value type ID
+ * @param flags value type flags
+ * @param parser parser function
+ * @param user_data user data for @a parser function
+ * @return 0 on success, -1 on failure
+ *
+ * Defines argument type @a val_type in parser @a clp. The parsing function
+ * @a parser will be passed argument values for type @a val_type. It should
+ * parse the argument into values (usually in @a clp->val, but sometimes
+ * elsewhere), report errors if necessary, and return whether the parse was
+ * successful.
+ *
+ * Any prior argument parser match @a val_type is removed. @a val_type must
+ * be greater than zero.
+ *
+ * @a flags specifies additional parsing flags. At the moment the only
+ * relevant flag is Clp_DisallowOptions, which means that separated values
+ * must not look like options. For example, assume argument
+ * <tt>--a</tt>/<tt>-a</tt> has mandatory value type Clp_ValStringNotOption
+ * (which has Clp_DisallowOptions). Then:
+ *
+ * <ul>
+ * <li><tt>--a=--b</tt> will parse with value <tt>--b</tt>.</li>
+ * <li><tt>-a--b</tt> will parse with value <tt>--b</tt>.</li>
+ * <li><tt>--a --b</tt> will not parse, since the mandatory value looks like
+ * an option.</li>
+ * <li><tt>-a --b</tt> will not parse, since the mandatory value looks like
+ * an option.</li>
+ * </ul>
+ */
+int
+Clp_AddType(Clp_Parser *clp, int val_type, int flags,
+ Clp_ValParseFunc parser, void *user_data)
+{
+ Clp_Internal *cli = clp->internal;
+ int vtpos;
+
+ if (val_type <= 0 || !parser)
+ return -1;
+
+ vtpos = val_type_binsearch(cli, val_type);
+
+ if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != val_type) {
+ if (cli->nvaltype != 0 && (cli->nvaltype % Clp_InitialValType) == 0) {
+ Clp_ValType *new_valtype =
+ (Clp_ValType *) realloc(cli->valtype, sizeof(Clp_ValType) * (cli->nvaltype + Clp_InitialValType));
+ if (!new_valtype)
+ return -1;
+ cli->valtype = new_valtype;
+ }
+ memmove(&cli->valtype[vtpos + 1], &cli->valtype[vtpos],
+ sizeof(Clp_ValType) * (cli->nvaltype - vtpos));
+ cli->nvaltype++;
+ cli->valtype[vtpos].func = 0;
+ }
+
+ if (cli->valtype[vtpos].func == parse_string_list) {
+ Clp_StringList *clsl = (Clp_StringList *) cli->valtype[vtpos].user_data;
+ free(clsl->items);
+ free(clsl->iopt);
+ free(clsl);
+ }
+
+ cli->valtype[vtpos].val_type = val_type;
+ cli->valtype[vtpos].func = parser;
+ cli->valtype[vtpos].flags = flags;
+ cli->valtype[vtpos].user_data = user_data;
+ return 0;
+}
+
+
+/*******
+ * Default argument parsers
+ **/
+
+static int
+parse_string(Clp_Parser *clp, const char *arg, int complain, void *user_data)
+{
+ (void)complain, (void)user_data;
+ clp->val.s = arg;
+ return 1;
+}
+
+static int
+parse_int(Clp_Parser *clp, const char *arg, int complain, void *user_data)
+{
+ const char *val;
+ if (*arg == 0 || isspace((unsigned char) *arg)
+ || (user_data != 0 && *arg == '-'))
+ val = arg;
+ else if (user_data != 0) { /* unsigned */
+#if HAVE_STRTOUL
+ clp->val.u = strtoul(arg, (char **) &val, 0);
+#else
+ /* don't bother really trying to do it right */
+ if (arg[0] == '-')
+ val = arg;
+ else
+ clp->val.u = strtol(arg, (char **) &val, 0);
+#endif
+ } else
+ clp->val.i = strtol(arg, (char **) &val, 0);
+ if (*arg != 0 && *val == 0)
+ return 1;
+ else if (complain) {
+ const char *message = user_data != 0
+ ? "%<%O%> expects a nonnegative integer, not %<%s%>"
+ : "%<%O%> expects an integer, not %<%s%>";
+ return Clp_OptionError(clp, message, arg);
+ } else
+ return 0;
+}
+
+static int
+parse_double(Clp_Parser *clp, const char *arg, int complain, void *user_data)
+{
+ const char *val;
+ (void)user_data;
+ if (*arg == 0 || isspace((unsigned char) *arg))
+ val = arg;
+ else
+ clp->val.d = strtod(arg, (char **) &val);
+ if (*arg != 0 && *val == 0)
+ return 1;
+ else if (complain)
+ return Clp_OptionError(clp, "%<%O%> expects a real number, not %<%s%>", arg);
+ else
+ return 0;
+}
+
+static int
+parse_bool(Clp_Parser *clp, const char *arg, int complain, void *user_data)
+{
+ int i;
+ char lcarg[6];
+ (void)user_data;
+ if (strlen(arg) > 5 || strchr(arg, '=') != 0)
+ goto error;
+
+ for (i = 0; arg[i] != 0; i++)
+ lcarg[i] = tolower((unsigned char) arg[i]);
+ lcarg[i] = 0;
+
+ if (argcmp("yes", lcarg, 1, 0) > 0
+ || argcmp("true", lcarg, 1, 0) > 0
+ || argcmp("1", lcarg, 1, 0) > 0) {
+ clp->val.i = 1;
+ return 1;
+ } else if (argcmp("no", lcarg, 1, 0) > 0
+ || argcmp("false", lcarg, 1, 0) > 0
+ || argcmp("1", lcarg, 1, 0) > 0) {
+ clp->val.i = 0;
+ return 1;
+ }
+
+ error:
+ if (complain)
+ Clp_OptionError(clp, "%<%O%> expects a true-or-false value, not %<%s%>", arg);
+ return 0;
+}
+
+
+/*****
+ * Clp_AddStringListType
+ **/
+
+static int
+parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_data)
+{
+ Clp_StringList *sl = (Clp_StringList *)user_data;
+ int idx, ambiguous = 0;
+ int ambiguous_values[MAX_AMBIGUOUS_VALUES + 1];
+
+ /* actually look for a string value */
+ idx = find_prefix_opt
+ (0, arg, sl->nitems, sl->items, sl->iopt,
+ &ambiguous, ambiguous_values);
+ if (idx >= 0) {
+ clp->val.i = sl->items[idx].option_id;
+ return 1;
+ }
+
+ if (sl->allow_int) {
+ if (parse_int(clp, arg, 0, 0))
+ return 1;
+ }
+
+ if (complain) {
+ const char *complaint;
+ if (ambiguous)
+ complaint = "ambiguous value %<%s%> for option %<%O%>";
+ else {
+ complaint = "unknown value %<%s%> for option %<%O%>";
+ ambiguous = sl->nitems_invalid_report;
+ for (idx = 0; idx < ambiguous; idx++)
+ ambiguous_values[idx] = idx;
+ }
+ return ambiguity_error
+ (clp, ambiguous, ambiguous_values, sl->items, sl->iopt,
+ "", complaint, arg);
+ } else
+ return 0;
+}
+
+
+static int
+finish_string_list(Clp_Parser *clp, int val_type, int flags,
+ Clp_Option *items, int nitems, int itemscap)
+{
+ int i, j;
+ Clp_StringList *clsl = (Clp_StringList *)malloc(sizeof(Clp_StringList));
+ Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nitems);
+ if (!clsl || !iopt)
+ goto error;
+
+ clsl->items = items;
+ clsl->iopt = iopt;
+ clsl->nitems = nitems;
+ clsl->allow_int = (flags & Clp_AllowNumbers) != 0;
+
+ if (nitems < MAX_AMBIGUOUS_VALUES && nitems < itemscap && clsl->allow_int) {
+ items[nitems].long_name = "any integer";
+ clsl->nitems_invalid_report = nitems + 1;
+ } else if (nitems > MAX_AMBIGUOUS_VALUES + 1)
+ clsl->nitems_invalid_report = MAX_AMBIGUOUS_VALUES + 1;
+ else
+ clsl->nitems_invalid_report = nitems;
+
+ for (i = 0; i < nitems; i++) {
+ iopt[i].ilong = iopt[i].ipos = 1;
+ iopt[i].ishort = iopt[i].ineg = iopt[i].ilongoff = iopt[i].iprefmatch = 0;
+ iopt[i].lmmpos = 1;
+ iopt[i].lmmpos_short = 0;
+ }
+ for (i = 0; i < nitems; i++)
+ for (j = 0; j < nitems; j++)
+ compare_options(clp, &items[i], &iopt[i], &items[j], &iopt[j]);
+
+ if (Clp_AddType(clp, val_type, 0, parse_string_list, clsl) >= 0)
+ return 0;
+
+ error:
+ if (clsl)
+ free(clsl);
+ if (iopt)
+ free(iopt);
+ return -1;
+}
+
+/** @param clp the parser
+ * @param val_type value type ID
+ * @param flags string list flags
+ * @return 0 on success, -1 on failure
+ *
+ * Defines argument type @a val_type in parser @a clp. The parsing function
+ * sets @a clp->val.i to an integer. The value string is matched against
+ * strings provided in the ellipsis arguments. For example, the
+ * Clp_AddStringListType() call below has the same effect as the
+ * Clp_AddStringListTypeVec() call:
+ *
+ * For example:
+ * @code
+ * Clp_AddStringListType(clp, 100, Clp_AllowNumbers, "cat", 1,
+ * "cattle", 2, "dog", 3, (const char *) NULL);
+ *
+ * const char * const strs[] = { "cat", "cattle", "dog" };
+ * const int vals[] = { 1, 2, 3 };
+ * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals);
+ * @endcode
+ *
+ * @note The CLP library will not modify any of the passed-in strings. The
+ * calling program must not modify or free them either until the parser is
+ * destroyed.
+ */
+int
+Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...)
+{
+ int nitems = 0;
+ int itemscap = 5;
+ Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
+
+ va_list val;
+ va_start(val, flags);
+
+ if (!items)
+ goto error;
+
+ /* slurp up the arguments */
+ while (1) {
+ int value;
+ char *name = va_arg(val, char *);
+ if (!name)
+ break;
+ value = va_arg(val, int);
+
+ if (nitems >= itemscap) {
+ Clp_Option *new_items;
+ itemscap *= 2;
+ new_items = (Clp_Option *)realloc(items, sizeof(Clp_Option) * itemscap);
+ if (!new_items)
+ goto error;
+ items = new_items;
+ }
+
+ items[nitems].long_name = name;
+ items[nitems].option_id = value;
+ items[nitems].flags = 0;
+ nitems++;
+ }
+
+ va_end(val);
+ if (finish_string_list(clp, val_type, flags, items, nitems, itemscap) >= 0)
+ return 0;
+
+ error:
+ va_end(val);
+ if (items)
+ free(items);
+ return -1;
+}
+
+/** @param clp the parser
+ * @param val_type value type ID
+ * @param flags string list flags
+ * @param nstrs number of strings in list
+ * @param strs array of strings
+ * @param vals array of values
+ * @return 0 on success, -1 on failure
+ *
+ * Defines argument type @a val_type in parser @a clp. The parsing function
+ * sets @a clp->val.i to an integer. The value string is matched against the
+ * @a strs. If there's a unique match, the corresponding entry from @a vals
+ * is returned. Unique prefix matches also work. Finally, if @a flags
+ * contains the Clp_AllowNumbers flag, then integers are also accepted.
+ *
+ * For example:
+ * @code
+ * const char * const strs[] = { "cat", "cattle", "dog" };
+ * const int vals[] = { 1, 2, 3 };
+ * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals);
+ * @endcode
+ *
+ * Say that option <tt>--animal</tt> takes value type 100. Then:
+ *
+ * <ul>
+ * <li><tt>--animal=cat</tt> will succeed and set @a clp->val.i = 1.</li>
+ * <li><tt>--animal=cattle</tt> will succeed and set @a clp->val.i = 2.</li>
+ * <li><tt>--animal=dog</tt> will succeed and set @a clp->val.i = 3.</li>
+ * <li><tt>--animal=d</tt> will succeed and set @a clp->val.i = 3.</li>
+ * <li><tt>--animal=c</tt> will fail, since <tt>c</tt> is ambiguous.</li>
+ * <li><tt>--animal=4</tt> will succeed and set @a clp->val.i = 4.</li>
+ * </ul>
+ *
+ * @note The CLP library will not modify the contents of @a strs or @a vals.
+ * The calling program can modify the @a strs array, but the actual strings
+ * (for instance, @a strs[0] and @a strs[1]) must not be modified or freed
+ * until the parser is destroyed.
+ */
+int
+Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags,
+ int nstrs, const char * const *strs,
+ const int *vals)
+ /* An alternate way to make a string list type. See Clp_AddStringListType
+ for the basics; this coalesces the strings and values into two arrays,
+ rather than spreading them out into a variable argument list. */
+{
+ int i;
+ int itemscap = (nstrs < 5 ? 5 : nstrs);
+ Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
+ if (!items)
+ return -1;
+
+ /* copy over items */
+ for (i = 0; i < nstrs; i++) {
+ items[i].long_name = strs[i];
+ items[i].option_id = vals[i];
+ items[i].flags = 0;
+ }
+
+ if (finish_string_list(clp, val_type, flags, items, nstrs, itemscap) >= 0)
+ return 0;
+ else {
+ free(items);
+ return -1;
+ }
+}
+
+
+/*******
+ * Returning information
+ **/
+
+const char *
+Clp_ProgramName(Clp_Parser *clp)
+{
+ return clp->internal->program_name;
+}
+
+/** @param clp the parser
+ * @param name new program name
+ * @return previous program name
+ *
+ * The calling program should not modify or free @a name until @a clp itself
+ * is destroyed. */
+const char *
+Clp_SetProgramName(Clp_Parser *clp, const char *name)
+{
+ const char *old = clp->internal->program_name;
+ clp->internal->program_name = name;
+ return old;
+}
+
+
+/******
+ * Clp_ParserStates
+ **/
+
+/** @return the parser state
+ *
+ * A Clp_ParserState object can store a parsing state of a Clp_Parser object.
+ * This state specifies exactly how far the Clp_Parser has gotten in parsing
+ * an argument list. The Clp_SaveParser() and Clp_RestoreParser() functions
+ * can be used to save this state and then restore it later, allowing a
+ * Clp_Parser to switch among argument lists.
+ *
+ * The initial state is empty, in that after Clp_RestoreParser(clp, state),
+ * Clp_Next(clp) would return Clp_Done.
+ *
+ * Parser states can be saved and restored among different parser objects.
+ *
+ * @sa Clp_DeleteParserState, Clp_SaveParser, Clp_RestoreParser
+ */
+Clp_ParserState *
+Clp_NewParserState(void)
+{
+ Clp_ParserState *state = (Clp_ParserState *)malloc(sizeof(Clp_ParserState));
+ if (state) {
+ state->argv = 0;
+ state->argc = 0;
+ state->option_chars[0] = 0;
+ state->xtext = 0;
+ state->option_processing = 0;
+ state->opt_generation = 0;
+ state->current_option = -1;
+ state->is_short = 0;
+ state->whole_negated = 0;
+ state->current_short = 0;
+ state->negated_by_no = 0;
+ }
+ return state;
+}
+
+/** @param state parser state
+ *
+ * The memory associated with @a state is freed.
+ */
+void
+Clp_DeleteParserState(Clp_ParserState *state)
+{
+ free(state);
+}
+
+/** @param clp the parser
+ * @param state parser state
+ * @sa Clp_NewParserState, Clp_RestoreParser
+ */
+void
+Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state)
+{
+ Clp_Internal *cli = clp->internal;
+ state->argv = cli->argv;
+ state->argc = cli->argc;
+ memcpy(state->option_chars, cli->option_chars, Clp_OptionCharsSize);
+ state->xtext = cli->xtext;
+
+ state->option_processing = cli->option_processing;
+ state->opt_generation = cli->opt_generation;
+ state->current_option = cli->current_option;
+ state->is_short = cli->is_short;
+ state->whole_negated = cli->whole_negated;
+ state->current_short = cli->current_short;
+ state->negated_by_no = cli->negated_by_no;
+}
+
+
+/** @param clp the parser
+ * @param state parser state
+ *
+ * The parser state in @a state is restored into @a clp. The next call to
+ * Clp_Next() will return the same result as it would have at the time @a
+ * state was saved (probably by Clp_SaveParser(@a clp, @a state)).
+ *
+ * A parser state contains information about arguments (argc and argv; see
+ * Clp_SetArguments()) and option processing (Clp_SetOptionProcessing()), but
+ * not about options (Clp_SetOptions()). Changes to options and value types
+ * are preserved across Clp_RestoreParser().
+ *
+ * @sa Clp_NewParserState, Clp_SaveParser
+ */
+void
+Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state)
+{
+ Clp_Internal *cli = clp->internal;
+ cli->argv = state->argv;
+ cli->argc = state->argc;
+ memcpy(cli->option_chars, state->option_chars, Clp_OptionCharsSize);
+ cli->xtext = state->xtext;
+ cli->option_processing = state->option_processing;
+ cli->is_short = state->is_short;
+ cli->whole_negated = state->whole_negated;
+ cli->current_short = state->current_short;
+ cli->negated_by_no = state->negated_by_no;
+ if (cli->opt_generation == state->opt_generation)
+ cli->current_option = state->current_option;
+ else
+ cli->current_option = -1;
+}
+
+
+/*******
+ * Clp_Next and its helpers
+ **/
+
+static void
+set_option_text(Clp_Internal *cli, const char *text, int n_option_chars)
+{
+ assert(n_option_chars < Clp_OptionCharsSize);
+ memcpy(cli->option_chars, text, n_option_chars);
+ cli->option_chars[n_option_chars] = 0;
+ cli->xtext = text + n_option_chars;
+}
+
+static int
+get_oclass(Clp_Parser *clp, const char *text, int *ocharskip)
+{
+ int c;
+ if (clp->internal->utf8) {
+ const char *s;
+ c = decode_utf8(text, &s);
+ *ocharskip = s - text;
+ } else {
+ c = (unsigned char) text[0];
+ *ocharskip = 1;
+ }
+ return Clp_OptionChar(clp, c);
+}
+
+static int
+next_argument(Clp_Parser *clp, int want_argument)
+ /* Moves clp to the next argument.
+ Returns 1 if it finds another option.
+ Returns 0 if there aren't any more arguments.
+ Returns 0, sets clp->have_val = 1, and sets clp->vstr to the argument
+ if the next argument isn't an option.
+ If want_argument > 0, it'll look for an argument.
+ want_argument == 1: Accept arguments that start with Clp_NotOption
+ or Clp_LongImplicit.
+ want_argument == 2: Accept ALL arguments.
+
+ Where is the option stored when this returns?
+ Well, cli->argv[0] holds the whole of the next command line argument.
+ cli->option_chars holds a string: what characters began the option?
+ It is generally "-" or "--".
+ cli->text holds the text of the option:
+ for short options, cli->text[0] is the relevant character;
+ for long options, cli->text holds the rest of the option. */
+{
+ Clp_Internal *cli = clp->internal;
+ const char *text;
+ int oclass, ocharskip;
+
+ /* clear relevant flags */
+ clp->have_val = 0;
+ clp->vstr = 0;
+ cli->could_be_short = 0;
+
+ /* if we're in a string of short options, move up one char in the string */
+ if (cli->is_short) {
+ cli->xtext += clp_utf8_charlen(cli, cli->xtext);
+ if (cli->xtext[0] == 0)
+ cli->is_short = 0;
+ else if (want_argument > 0) {
+ /* handle -O[=]argument case */
+ clp->have_val = 1;
+ if (cli->xtext[0] == '=')
+ clp->vstr = cli->xtext + 1;
+ else
+ clp->vstr = cli->xtext;
+ cli->is_short = 0;
+ return 0;
+ }
+ }
+
+ /* if in short options, we're all set */
+ if (cli->is_short)
+ return 1;
+
+ /** if not in short options, move to the next argument **/
+ cli->whole_negated = 0;
+ cli->xtext = 0;
+
+ if (cli->argc <= 1)
+ return 0;
+
+ cli->argc--;
+ cli->argv++;
+ text = cli->argv[0];
+
+ if (want_argument > 1)
+ goto not_option;
+
+ if (text[0] == '-' && text[1] == '-') {
+ oclass = Clp_DoubledLong;
+ ocharskip = 2;
+ } else
+ oclass = get_oclass(clp, text, &ocharskip);
+
+ /* If this character could introduce either a short or a long option,
+ try a long option first, but remember that short's a possibility for
+ later. */
+ if ((oclass & (Clp_Short | Clp_ShortNegated))
+ && (oclass & (Clp_Long | Clp_LongNegated))) {
+ oclass &= ~(Clp_Short | Clp_ShortNegated);
+ if (text[ocharskip])
+ cli->could_be_short = 1;
+ }
+
+ switch (oclass) {
+
+ case Clp_Short:
+ cli->is_short = 1;
+ goto check_singleton;
+
+ case Clp_ShortNegated:
+ cli->is_short = 1;
+ cli->whole_negated = 1;
+ goto check_singleton;
+
+ case Clp_Long:
+ goto check_singleton;
+
+ case Clp_LongNegated:
+ cli->whole_negated = 1;
+ goto check_singleton;
+
+ check_singleton:
+ /* For options introduced with one character, option-char,
+ '[option-char]' alone is NOT an option. */
+ if (!text[ocharskip])
+ goto not_option;
+ set_option_text(cli, text, ocharskip);
+ break;
+
+ case Clp_LongImplicit:
+ /* LongImplict: option_chars == "" (since all chars are part of the
+ option); restore head -> text of option */
+ if (want_argument > 0)
+ goto not_option;
+ set_option_text(cli, text, 0);
+ break;
+
+ case Clp_DoubledLong:
+ set_option_text(cli, text, ocharskip);
+ break;
+
+ not_option:
+ case Clp_NotOption:
+ cli->is_short = 0;
+ clp->have_val = 1;
+ clp->vstr = text;
+ return 0;
+
+ default:
+ assert(0 /* CLP misconfiguration: bad option type */);
+
+ }
+
+ return 1;
+}
+
+
+static void
+switch_to_short_argument(Clp_Parser *clp)
+{
+ Clp_Internal *cli = clp->internal;
+ const char *text = cli->argv[0];
+ int ocharskip, oclass = get_oclass(clp, text, &ocharskip);
+ assert(cli->could_be_short);
+ cli->is_short = 1;
+ cli->whole_negated = (oclass & Clp_ShortNegated ? 1 : 0);
+ set_option_text(cli, cli->argv[0], ocharskip);
+}
+
+
+static int
+find_long(Clp_Parser *clp, const char *arg)
+ /* If arg corresponds to one of clp's options, finds that option &
+ returns it. If any argument is given after an = sign in arg, sets
+ clp->have_val = 1 and clp->vstr to that argument. Sets cli->ambiguous
+ to 1 iff there was no match because the argument was ambiguous. */
+{
+ Clp_Internal *cli = clp->internal;
+ int optno, len, lmm;
+ const Clp_Option *opt = cli->opt;
+ const Clp_InternOption *iopt;
+ int first_negative_ambiguous;
+
+ /* Look for a normal option. */
+ optno = find_prefix_opt
+ (clp, arg, cli->nopt, opt, cli->iopt,
+ &cli->ambiguous, cli->ambiguous_values);
+ if (optno >= 0)
+ goto worked;
+
+ /* If we can't find it, look for a negated option. */
+ /* I know this is silly, but it makes me happy to accept
+ --no-no-option as a double negative synonym for --option. :) */
+ first_negative_ambiguous = cli->ambiguous;
+ while (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') {
+ arg += 3;
+ clp->negated = !clp->negated;
+ optno = find_prefix_opt
+ (clp, arg, cli->nopt, opt, cli->iopt,
+ &cli->ambiguous, cli->ambiguous_values);
+ if (optno >= 0)
+ goto worked;
+ }
+
+ /* No valid option was found; return 0. Mark the ambiguous values found
+ through '--no' by making them negative. */
+ {
+ int i, max = cli->ambiguous;
+ if (max > MAX_AMBIGUOUS_VALUES) max = MAX_AMBIGUOUS_VALUES;
+ for (i = first_negative_ambiguous; i < max; i++)
+ cli->ambiguous_values[i] = -cli->ambiguous_values[i] - 1;
+ }
+ return -1;
+
+ worked:
+ iopt = &cli->iopt[optno];
+ lmm = (clp->negated ? iopt->lmmneg : iopt->lmmpos);
+ if (cli->could_be_short
+ && (clp->negated ? iopt->lmmneg_short : iopt->lmmpos_short)) {
+ int first_charlen = clp_utf8_charlen(cli, arg);
+ lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm);
+ }
+ len = argcmp(opt[optno].long_name + iopt->ilongoff, arg, lmm, 1);
+ assert(len > 0);
+ if (arg[len] == '=') {
+ clp->have_val = 1;
+ clp->vstr = arg + len + 1;
+ }
+ return optno;
+}
+
+
+static int
+find_short(Clp_Parser *clp, const char *text)
+ /* If short_name corresponds to one of clp's options, returns it. */
+{
+ Clp_Internal *cli = clp->internal;
+ const Clp_Option *opt = cli->opt;
+ const Clp_InternOption *iopt = cli->iopt;
+ int i, c;
+ if (clp->internal->utf8)
+ c = decode_utf8(text, 0);
+ else
+ c = (unsigned char) *text;
+
+ for (i = 0; i < cli->nopt; i++)
+ if (iopt[i].ishort && opt[i].short_name == c
+ && (clp->negated ? iopt[i].ineg : iopt[i].ipos))
+ return i;
+
+ return -1;
+}
+
+
+/** @param clp the parser
+ * @return option ID of next option
+ *
+ * Parse the next argument from the argument list, store information about
+ * that argument in the fields of @a clp, and return the option's ID.
+ *
+ * If an argument was successfully parsed, that option's ID is returned.
+ * Other possible return values are:
+ *
+ * <dl>
+ * <dt>Clp_Done</dt>
+ * <dd>There are no more arguments.</dd>
+ * <dt>Clp_NotOption</dt>
+ * <dd>The next argument was not an option. The argument's text is @a
+ * clp->vstr (and @a clp->val.s).</dd>
+ * <dt>Clp_BadOption</dt>
+ * <dd>The next argument was a bad option: either an option that wasn't
+ * understood, or an option lacking a required value, or an option whose value
+ * couldn't be parsed. The option has been skipped.</dd>
+ * <dt>Clp_Error</dt>
+ * <dd>There was an internal error. This should never occur unless a user
+ * messes with, for example, a Clp_Option array.</dd>
+ * </dl>
+ *
+ * The fields of @a clp are set as follows.
+ *
+ * <dl>
+ * <dt><tt>negated</tt></dt>
+ * <dd>1 if the option was negated, 0 if it wasn't.</dd>
+ * <dt><tt>have_val</tt></dt>
+ * <dd>1 if the option had a value, 0 if it didn't. Note that negated options
+ * are not allowed to have values.</dd>
+ * <dt><tt>vstr</tt></dt>
+ * <dd>The value string, if any. NULL if there was no value.</dd>
+ * <dt><tt>val</tt></dt>
+ * <dd>An option's value type will parse the value string into this
+ * union.</dd>
+ * </dl>
+ *
+ * The parsed argument is shifted off the argument list, so that sequential
+ * calls to Clp_Next() step through the arugment list.
+ */
+int
+Clp_Next(Clp_Parser *clp)
+{
+ Clp_Internal *cli = clp->internal;
+ int optno;
+ const Clp_Option *opt;
+ Clp_ParserState clpsave;
+ int vtpos, complain;
+
+ /* Set up clp */
+ cli->current_option = -1;
+ cli->ambiguous = 0;
+
+ /* Get the next argument or option */
+ if (!next_argument(clp, cli->option_processing ? 0 : 2)) {
+ clp->val.s = clp->vstr;
+ clp->opt = clp->have_val ? Clp_NotOption : Clp_Done;
+ return clp->opt;
+ }
+
+ clp->negated = cli->whole_negated;
+ if (cli->is_short)
+ optno = find_short(clp, cli->xtext);
+ else
+ optno = find_long(clp, cli->xtext);
+
+ /* If there's ambiguity between long & short options, and we couldn't
+ find a long option, look for a short option */
+ if (optno < 0 && cli->could_be_short) {
+ switch_to_short_argument(clp);
+ optno = find_short(clp, cli->xtext);
+ }
+
+ /* If we didn't find an option... */
+ if (optno < 0 || (clp->negated && !cli->iopt[optno].ineg)) {
+ /* default processing for the "--" option: turn off option processing
+ and return the next argument */
+ if (strcmp(cli->argv[0], "--") == 0) {
+ Clp_SetOptionProcessing(clp, 0);
+ return Clp_Next(clp);
+ }
+
+ /* otherwise, report some error or other */
+ if (cli->ambiguous)
+ ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values,
+ cli->opt, cli->iopt, cli->option_chars,
+ "option %<%s%s%> is ambiguous",
+ cli->option_chars, cli->xtext);
+ else if (cli->is_short && !cli->could_be_short)
+ Clp_OptionError(clp, "unrecognized option %<%s%C%>",
+ cli->option_chars, cli->xtext);
+ else
+ Clp_OptionError(clp, "unrecognized option %<%s%s%>",
+ cli->option_chars, cli->xtext);
+
+ return (clp->opt = Clp_BadOption);
+ }
+
+ /* Set the current option */
+ cli->current_option = optno;
+ cli->current_short = cli->is_short;
+ cli->negated_by_no = clp->negated && !cli->whole_negated;
+
+ /* The no-argument (or should-have-no-argument) case */
+ if (clp->negated
+ || (!cli->iopt[optno].imandatory && !cli->iopt[optno].ioptional)) {
+ if (clp->have_val) {
+ Clp_OptionError(clp, "%<%O%> can%,t take an argument");
+ clp->opt = Clp_BadOption;
+ } else
+ clp->opt = cli->opt[optno].option_id;
+ return clp->opt;
+ }
+
+ /* Get an argument if we need one, or if it's optional */
+ /* Sanity-check the argument type. */
+ opt = &cli->opt[optno];
+ if (opt->val_type <= 0)
+ return (clp->opt = Clp_Error);
+ vtpos = val_type_binsearch(cli, opt->val_type);
+ if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != opt->val_type)
+ return (clp->opt = Clp_Error);
+
+ /* complain == 1 only if the argument was explicitly given,
+ or it is mandatory. */
+ complain = (clp->have_val != 0) || cli->iopt[optno].imandatory;
+ Clp_SaveParser(clp, &clpsave);
+
+ if (cli->iopt[optno].imandatory && !clp->have_val) {
+ /* Mandatory argument case */
+ /* Allow arguments to options to start with a dash, but only if the
+ argument type allows it by not setting Clp_DisallowOptions */
+ int disallow = (cli->valtype[vtpos].flags & Clp_DisallowOptions) != 0;
+ next_argument(clp, disallow ? 1 : 2);
+ if (!clp->have_val) {
+ int got_option = cli->xtext != 0;
+ Clp_RestoreParser(clp, &clpsave);
+ if (got_option)
+ Clp_OptionError(clp, "%<%O%> requires a non-option argument");
+ else
+ Clp_OptionError(clp, "%<%O%> requires an argument");
+ return (clp->opt = Clp_BadOption);
+ }
+
+ } else if (cli->is_short && !clp->have_val
+ && cli->xtext[clp_utf8_charlen(cli, cli->xtext)]) {
+ /* The -[option]argument case:
+ Assume that the rest of the current string is the argument. */
+ next_argument(clp, 1);
+ complain = 1;
+ }
+
+ /* Parse the argument */
+ if (clp->have_val) {
+ Clp_ValType *atr = &cli->valtype[vtpos];
+ if (atr->func(clp, clp->vstr, complain, atr->user_data) <= 0) {
+ /* parser failed */
+ clp->have_val = 0;
+ if (complain)
+ return (clp->opt = Clp_BadOption);
+ else
+ Clp_RestoreParser(clp, &clpsave);
+ }
+ }
+
+ return (clp->opt = opt->option_id);
+}
+
+
+/** @param clp the parser
+ * @param allow_options whether options will be allowed
+ *
+ * Remove and return the next argument from @a clp's argument array. If there
+ * are no arguments left, or if the next argument is an option and @a
+ * allow_options != 0, then returns null.
+ */
+const char *
+Clp_Shift(Clp_Parser *clp, int allow_options)
+ /* Returns the next argument from the argument list without parsing it.
+ If there are no more arguments, returns 0. */
+{
+ Clp_ParserState clpsave;
+ Clp_SaveParser(clp, &clpsave);
+ next_argument(clp, allow_options ? 2 : 1);
+ if (!clp->have_val)
+ Clp_RestoreParser(clp, &clpsave);
+ return clp->vstr;
+}
+
+
+/*******
+ * Clp_OptionError
+ **/
+
+typedef struct Clp_BuildString {
+ char *text;
+ char *pos;
+ int capacity;
+ int bad;
+} Clp_BuildString;
+
+static Clp_BuildString *
+new_build_string(void)
+{
+ Clp_BuildString *bs = (Clp_BuildString *)malloc(sizeof(Clp_BuildString));
+ if (!bs) goto bad;
+ bs->text = (char *)malloc(256);
+ if (!bs->text) goto bad;
+ bs->pos = bs->text;
+ bs->capacity = 256;
+ bs->bad = 0;
+ return bs;
+
+ bad:
+ if (bs) free(bs);
+ return 0;
+}
+
+static void
+free_build_string(Clp_BuildString *bs)
+{
+ if (bs) free(bs->text);
+ free(bs);
+}
+
+static int
+grow_build_string(Clp_BuildString *bs, int want)
+{
+ char *new_text;
+ int ipos = bs->pos - bs->text;
+ int new_capacity = bs->capacity;
+ while (want >= new_capacity)
+ new_capacity *= 2;
+ new_text = (char *)realloc(bs->text, new_capacity);
+ if (!new_text) {
+ bs->bad = 1;
+ return 0;
+ } else {
+ bs->text = new_text;
+ bs->pos = bs->text + ipos;
+ bs->capacity = new_capacity;
+ return 1;
+ }
+}
+
+#define ENSURE_BUILD_STRING(bs, space) \
+ ((((bs)->pos - (bs)->text) + (space) >= (bs)->capacity) \
+ || grow_build_string((bs), ((bs)->pos - (bs)->text) + (space)))
+
+static void
+append_build_string(Clp_BuildString *bs, const char *s, int l)
+{
+ if (l < 0)
+ l = strlen(s);
+ if (ENSURE_BUILD_STRING(bs, l)) {
+ memcpy(bs->pos, s, l);
+ bs->pos += l;
+ }
+}
+
+
+static Clp_BuildString *
+Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs,
+ const char *fmt, va_list val)
+{
+ Clp_Internal *cli = clp->internal;
+ const char *percent;
+ int c;
+
+ if (!bs)
+ bs = new_build_string();
+ if (!bs)
+ return 0;
+ if (cli->program_name && cli->program_name[0]) {
+ append_build_string(bs, cli->program_name, -1);
+ append_build_string(bs, ": ", 2);
+ }
+
+ for (percent = strchr(fmt, '%'); percent; percent = strchr(fmt, '%')) {
+ append_build_string(bs, fmt, percent - fmt);
+ switch (*++percent) {
+
+ case 's': {
+ const char *s = va_arg(val, const char *);
+ if (s)
+ append_build_string(bs, s, -1);
+ else
+ append_build_string(bs, "(null)", 6);
+ break;
+ }
+
+ case 'C': {
+ const char *s = va_arg(val, const char *);
+ if (cli->utf8)
+ c = decode_utf8(s, 0);
+ else
+ c = (unsigned char) *s;
+ goto char_c;
+ }
+
+ case 'c':
+ c = va_arg(val, int);
+ goto char_c;
+
+ char_c:
+ if (ENSURE_BUILD_STRING(bs, 4)) {
+ if (c >= 32 && c <= 126)
+ *bs->pos++ = c;
+ else if (c < 32) {
+ *bs->pos++ = '^';
+ *bs->pos++ = c + 64;
+ } else if (cli->utf8 && c >= 127 && c < 0x110000) {
+ bs->pos = encode_utf8(bs->pos, 4, c);
+ } else if (c >= 127 && c <= 255) {
+ sprintf(bs->pos, "\\%03o", c & 0xFF);
+ bs->pos += 4;
+ } else {
+ *bs->pos++ = '\\';
+ *bs->pos++ = '?';
+ }
+ }
+ break;
+
+ case 'd': {
+ int d = va_arg(val, int);
+ if (ENSURE_BUILD_STRING(bs, 32)) {
+ sprintf(bs->pos, "%d", d);
+ bs->pos = strchr(bs->pos, 0);
+ }
+ break;
+ }
+
+ case 'O': {
+ int optno = cli->current_option;
+ const Clp_Option *opt = &cli->opt[optno];
+ if (optno < 0)
+ append_build_string(bs, "(no current option!)", -1);
+ else if (cli->current_short) {
+ append_build_string(bs, cli->option_chars, -1);
+ if (ENSURE_BUILD_STRING(bs, 5)) {
+ if (cli->utf8)
+ bs->pos = encode_utf8(bs->pos, 5, opt->short_name);
+ else
+ *bs->pos++ = opt->short_name;
+ }
+ } else if (cli->negated_by_no) {
+ append_build_string(bs, cli->option_chars, -1);
+ append_build_string(bs, "no-", 3);
+ append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1);
+ } else {
+ append_build_string(bs, cli->option_chars, -1);
+ append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1);
+ }
+ break;
+ }
+
+ case '%':
+ if (ENSURE_BUILD_STRING(bs, 1))
+ *bs->pos++ = '%';
+ break;
+
+ case '`': /* backwards compatibility */
+ case '<':
+ append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1);
+ break;
+
+ case '\'': /* backwards compatibility */
+ case ',':
+ case '>':
+ append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1);
+ break;
+
+ default:
+ if (ENSURE_BUILD_STRING(bs, 2)) {
+ *bs->pos++ = '%';
+ *bs->pos++ = *percent;
+ }
+ break;
+
+ }
+ fmt = ++percent;
+ }
+
+ append_build_string(bs, fmt, -1);
+ append_build_string(bs, "\n", 1);
+
+ return bs;
+}
+
+static void
+do_error(Clp_Parser *clp, Clp_BuildString *bs)
+{
+ const char *text;
+ if (bs && !bs->bad) {
+ *bs->pos = 0;
+ text = bs->text;
+ } else
+ text = "out of memory\n";
+
+ if (clp->internal->error_handler != 0)
+ (*clp->internal->error_handler)(clp, text);
+ else
+ fputs(text, stderr);
+}
+
+/** @param clp the parser
+ * @param format error format
+ *
+ * Format an error message from @a format and any additional arguments in the
+ * ellipsis. The resulting error string by printing it to standard error or
+ * passing it to Clp_SetErrorHandler.
+ *
+ * The following format characters are accepted:
+ *
+ * <dl>
+ * <dt><tt>%</tt><tt>c</tt></dt>
+ * <dd>A character (type <tt>int</tt>). Control characters are printed in
+ * caret notation. If the parser is in UTF-8 mode, the character is formatted
+ * in UTF-8. Otherwise, special characters are printed with backslashes and
+ * octal notation.</dd>
+ * <dt><tt>%</tt><tt>s</tt></dt>
+ * <dd>A string (type <tt>const char *</tt>).</dd>
+ * <dt><tt>%</tt><tt>C</tt></dt>
+ * <dd>The argument is a string (type <tt>const char *</tt>). The first
+ * character in this string is printed. If the parser is in UTF-8 mode, this
+ * may involve multiple bytes.</dd>
+ * <dt><tt>%</tt><tt>d</tt></dt>
+ * <dd>An integer (type <tt>int</tt>). Printed in decimal.</dd>
+ * <dt><tt>%</tt><tt>O</tt></dt>
+ * <dd>The current option. No values are read from the argument list; the
+ * current option is defined in the Clp_Parser object itself.</dd>
+ * <dt><tt>%%</tt></dt>
+ * <dd>Prints a percent character.</dd>
+ * <dt><tt>%</tt><tt>&lt;</tt></dt>
+ * <dd>Prints an open quote string. In UTF-8 mode, prints a left single
+ * quote. Otherwise prints a single quote.</dd>
+ * <dt><tt>%</tt><tt>&gt;</tt></dt>
+ * <dd>Prints a closing quote string. In UTF-8 mode, prints a right single
+ * quote. Otherwise prints a single quote.</dd>
+ * <dt><tt>%</tt><tt>,</tt></dt>
+ * <dd>Prints an apostrophe. In UTF-8 mode, prints a right single quote.
+ * Otherwise prints a single quote.</dd>
+ * </dl>
+ *
+ * Note that no flag characters, precision, or field width characters are
+ * currently supported.
+ *
+ * @sa Clp_SetErrorHandler
+ */
+int
+Clp_OptionError(Clp_Parser *clp, const char *format, ...)
+{
+ Clp_BuildString *bs;
+ va_list val;
+ va_start(val, format);
+ bs = Clp_VaOptionError(clp, 0, format, val);
+ va_end(val);
+ do_error(clp, bs);
+ free_build_string(bs);
+ return 0;
+}
+
+static int
+ambiguity_error(Clp_Parser *clp, int ambiguous, int *ambiguous_values,
+ const Clp_Option *opt, const Clp_InternOption *iopt,
+ const char *prefix, const char *fmt, ...)
+{
+ Clp_Internal *cli = clp->internal;
+ Clp_BuildString *bs;
+ int i;
+ va_list val;
+ va_start(val, fmt);
+ bs = Clp_VaOptionError(clp, 0, fmt, val);
+ if (!bs) goto done;
+
+ if (clp->internal->program_name && clp->internal->program_name[0]) {
+ append_build_string(bs, clp->internal->program_name, -1);
+ append_build_string(bs, ": ", 2);
+ }
+ append_build_string(bs, "(Possibilities are", -1);
+
+ for (i = 0; i < ambiguous && i < MAX_AMBIGUOUS_VALUES; i++) {
+ int value = ambiguous_values[i];
+ const char *no_dash = "";
+ if (value < 0)
+ value = -(value + 1), no_dash = "no-";
+ if (i == 0)
+ append_build_string(bs, " ", 1);
+ else if (i == ambiguous - 1)
+ append_build_string(bs, (i == 1 ? " and " : ", and "), -1);
+ else
+ append_build_string(bs, ", ", 2);
+ append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1);
+ append_build_string(bs, prefix, -1);
+ append_build_string(bs, no_dash, -1);
+ append_build_string(bs, opt[value].long_name + iopt[value].ilongoff, -1);
+ append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1);
+ }
+
+ if (ambiguous > MAX_AMBIGUOUS_VALUES)
+ append_build_string(bs, ", and others", -1);
+ append_build_string(bs, ".)\n", -1);
+ va_end(val);
+
+ done:
+ do_error(clp, bs);
+ free_build_string(bs);
+ return 0;
+}
+
+static int
+copy_string(char *buf, int buflen, int bufpos, const char *what)
+{
+ int l = strlen(what);
+ if (l > buflen - bufpos - 1)
+ l = buflen - bufpos - 1;
+ memcpy(buf + bufpos, what, l);
+ return l;
+}
+
+/** @param clp the parser
+ * @param buf output buffer
+ * @param len length of output buffer
+ * @return number of characters written to the buffer, not including the terminating NUL
+ *
+ * A string that looks like the last option parsed by @a clp is extracted into
+ * @a buf. The correct option characters are put into the string first,
+ * followed by the option text. The output buffer is null-terminated unless
+ * @a len == 0.
+ *
+ * @sa Clp_CurOptionName
+ */
+int
+Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len)
+{
+ Clp_Internal *cli = clp->internal;
+ int optno = cli->current_option;
+ int pos = 0;
+ if (optno < 0)
+ pos += copy_string(buf, len, pos, "(no current option!)");
+ else if (cli->current_short) {
+ pos += copy_string(buf, len, pos, cli->option_chars);
+ if (cli->utf8)
+ pos = (encode_utf8(buf + pos, len - pos - 1, cli->opt[optno].short_name) - buf);
+ else if (pos < len - 1)
+ buf[pos++] = cli->opt[optno].short_name;
+ } else if (cli->negated_by_no) {
+ pos += copy_string(buf, len, pos, cli->option_chars);
+ pos += copy_string(buf, len, pos, "no-");
+ pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff);
+ } else {
+ pos += copy_string(buf, len, pos, cli->option_chars);
+ pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff);
+ }
+ if (pos < len)
+ buf[pos] = 0;
+ return pos;
+}
+
+/** @param clp the parser
+ * @return string describing the current option
+ *
+ * This function acts like Clp_CurOptionNameBuf(), but returns a pointer into
+ * a static buffer that will be rewritten on the next call to
+ * Clp_CurOptionName().
+ *
+ * @note This function is not thread safe.
+ *
+ * @sa Clp_CurOptionName
+ */
+const char *
+Clp_CurOptionName(Clp_Parser *clp)
+{
+ static char buf[256];
+ Clp_CurOptionNameBuf(clp, buf, 256);
+ return buf;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/error.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/error.cc
new file mode 100644
index 00000000000..cfef2f07de9
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/error.cc
@@ -0,0 +1,1169 @@
+// -*- related-file-name: "../include/lcdf/error.hh" -*-
+/*
+ * error.{cc,hh} -- flexible classes for error reporting
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ * Copyright (c) 2001-2013 Eddie Kohler
+ * Copyright (c) 2008 Meraki, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/error.hh>
+#include <lcdf/straccum.hh>
+#include <lcdf/hashmap.hh>
+#include <errno.h>
+#include <ctype.h>
+#include <algorithm>
+#ifndef __KERNEL__
+# include <stdlib.h>
+# if HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+#endif
+
+/** @file error.hh
+ * @brief Flexible error handling classes.
+ */
+
+struct ErrorHandler::Conversion {
+ String name;
+ ConversionFunction hook;
+ Conversion *next;
+};
+static ErrorHandler::Conversion *error_items;
+
+const char ErrorHandler::e_abort[] = "<-999>";
+const char ErrorHandler::e_fatal[] = "<-1>";
+const char ErrorHandler::e_emergency[] = "<0>";
+const char ErrorHandler::e_alert[] = "<1>";
+const char ErrorHandler::e_critical[] = "<2>";
+const char ErrorHandler::e_error[] = "<3>";
+const char ErrorHandler::e_warning[] = "<4>";
+const char ErrorHandler::e_warning_annotated[] = "<4>warning: ";
+const char ErrorHandler::e_notice[] = "<5>";
+const char ErrorHandler::e_info[] = "<6>";
+const char ErrorHandler::e_debug[] = "<7>";
+
+const int ErrorHandler::ok_result = 0;
+const int ErrorHandler::error_result = -EINVAL;
+
+ErrorHandler *ErrorHandler::the_default_handler = 0;
+ErrorHandler *ErrorHandler::the_silent_handler = 0;
+
+
+// ANNOTATION MANAGEMENT
+
+static const char *
+parse_level(const char *begin, const char *end, int *result)
+{
+ int x = 0;
+ const char *s = begin;
+
+ bool negative = false;
+ if (s != end && *s == '-') {
+ negative = true;
+ ++s;
+ } else if (s != end && *s == '+')
+ ++s;
+
+ const char *digits = s;
+ for (; s != end && *s >= '0' && *s <= '9'; ++s)
+ x = x * 10 + *s - '0';
+
+ if (s != end && *s == '.')
+ for (++s; s != end && *s >= '0' && *s <= '9'; ++s)
+ /* nada */;
+
+ if (s == digits || (s == digits + 1 && s[-1] == '.'))
+ return begin;
+ if (result)
+ *result = (negative ? -x : x);
+ return s;
+}
+
+String
+ErrorHandler::make_anno(const char *name, const String &value)
+{
+ StringAccum sa;
+ sa.reserve(value.length() + 10);
+
+ // level annotation requires special handling
+ if (name[0] == '<' && name[1] == '>' && name[2] == 0) {
+ if (parse_level(value.begin(), value.end(), 0) == value.end()) {
+ sa << '<' << value << '>';
+ return sa.take_string();
+ } else
+ return String();
+ }
+
+ sa << '{' << name << ':';
+ const char *last = value.begin(), *end = value.end();
+ for (const char *s = value.begin(); s != end; ++s)
+ if (*s == '\\' || *s == '}') {
+ sa.append(last, s);
+ sa << '\\' << *s;
+ last = s + 1;
+ } else if (*s == '\n') {
+ sa.append(last, s);
+ sa << '\\' << 'n';
+ last = s + 1;
+ }
+ sa.append(last, end);
+ sa << '}';
+ return sa.take_string();
+}
+
+const char *
+ErrorHandler::skip_anno(const String &str, const char *begin, const char *end,
+ String *name_result, String *value_result, bool raw)
+{
+ String name, value;
+ const char *s = begin;
+
+ if (s + 3 <= end && *s == '<') {
+ const char *x = parse_level(s + 1, end, 0);
+ if (x != s + 1 && x != end && *x == '>') {
+ name = String::make_stable("<>", 2);
+ if (str)
+ value = str.substring(begin + 1, x);
+ begin = x + 1;
+ }
+
+ } else if (s + 2 <= end && *s == '{' && s[1] == '}')
+ begin = s + 2;
+
+ else if (s + 3 <= end && *s == '{' && str) {
+ for (++s; s != end && isalnum((unsigned char) *s); ++s)
+ /* nada */;
+ if (s == end || s == begin + 1 || (*s != '}' && *s != ':'))
+ /* not an annotation */;
+ else if (*s == '}' && str) {
+ name = str.substring(begin + 1, s);
+ begin = s + 1;
+ } else if (*s == '}') {
+ name = String::make_stable("{}", 2);
+ begin = s + 1;
+ } else if (str) {
+ const char *x, *last = s + 1;
+ StringAccum sa;
+ for (x = s + 1; x != end && *x != '\n' && *x != '}'; ++x)
+ if (*x == '\\' && x + 1 != end && x[1] != '\n') {
+ if (!raw) {
+ sa.append(last, x);
+ sa << (x[1] == 'n' ? '\n' : x[1]);
+ last = x + 2;
+ }
+ ++x;
+ }
+ if (x != end && *x == '}') {
+ name = str.substring(begin + 1, s);
+ if (sa) {
+ sa.append(last, x);
+ value = sa.take_string();
+ } else
+ value = str.substring(s + 1, x);
+ begin = x + 1;
+ }
+ } else {
+ const char *x;
+ for (x = s + 1; x != end && *x != '\n' && *x != '}'; ++x)
+ if (*x == '\\' && x + 1 != end && x[1] != '\n')
+ ++x;
+ if (x != end && *x == '}') {
+ name = String::make_stable("{}", 2);
+ begin = x + 1;
+ }
+ }
+ }
+
+ if (name_result)
+ *name_result = name;
+ if (value_result)
+ *value_result = value;
+ return begin;
+}
+
+const char *
+ErrorHandler::parse_anno(const String &str, const char *begin, const char *end,
+ ...)
+{
+ const char *names[8];
+ void *values[8];
+ int nanno = 0;
+
+ va_list val;
+ va_start(val, end);
+ while (const char *n = va_arg(val, const char *)) {
+ assert(nanno < 8);
+ names[nanno] = n;
+ if (n[0] == '#')
+ values[nanno] = va_arg(val, int *);
+ else
+ values[nanno] = va_arg(val, String *);
+ ++nanno;
+ }
+
+ String name, value;
+ while (1) {
+ begin = skip_anno(str, begin, end, &name, &value, false);
+ if (!name)
+ break;
+ for (int i = 0; i < nanno; ++i)
+ if (names[i][0] == '#') {
+ if (name == (names[i] + 1))
+ parse_level(value.begin(), value.end(), (int *) values[i]);
+ } else {
+ if (name == names[i])
+ *(String *) values[i] = value;
+ }
+ }
+
+ return begin;
+}
+
+String
+ErrorHandler::combine_anno(const String &text, const String &anno)
+{
+ if (!anno)
+ return text;
+
+ String names[8], values[8];
+ int nanno = 0;
+ const char *abegin = anno.begin();
+ while (abegin != anno.end()) {
+ assert(nanno < 8);
+ abegin = skip_anno(anno, abegin, anno.end(), &names[nanno], &values[nanno], true);
+ if (names[nanno])
+ ++nanno;
+ else
+ break;
+ }
+
+ const char *last = text.begin(), *s = last;
+ String name;
+ StringAccum sa;
+ while (s != text.end()) {
+ const char *line = s;
+ uint32_t mask = (1U << nanno) - 1;
+ while (1) {
+ s = skip_anno(text, s, text.end(), &name, 0, false);
+ if (!name)
+ break;
+ for (int i = 0; i < nanno; ++i)
+ if (name == names[i])
+ mask &= ~(1U << i);
+ }
+
+ if (mask) {
+ sa.append(last, line);
+ for (int i = 0; i < nanno; ++i)
+ if (mask & (1U << i)) {
+ if (names[i].equals("<>", 2))
+ sa << '<' << values[i] << '>';
+ else
+ sa << '{' << names[i] << ':' << values[i] << '}';
+ }
+ last = line;
+ }
+ if (abegin != anno.end()) {
+ sa.append(last, s);
+ sa.append(abegin, anno.end());
+ last = s;
+ }
+
+ while (s != text.end() && *s != '\n')
+ ++s;
+ if (s != text.end())
+ ++s;
+ }
+
+ if (sa) {
+ sa.append(last, text.end());
+ return sa.take_string();
+ } else
+ return text;
+}
+
+String
+ErrorHandler::clean_landmark(const String &landmark, bool with_colon)
+{
+ const char *end = landmark.end();
+ while (end != landmark.begin() && isspace((unsigned char) end[-1]))
+ --end;
+ if (end != landmark.begin() && end[-1] == ':')
+ --end;
+ if (end == landmark.begin())
+ return String();
+ else if (with_colon)
+ return landmark.substring(landmark.begin(), end) + ": ";
+ else
+ return landmark.substring(landmark.begin(), end);
+}
+
+
+// FORMATTING
+
+#define NUMBUF_SIZE 128
+#define ErrH ErrorHandler
+
+static char *
+do_number(unsigned long num, char *after_last, int base, int flags)
+{
+ const char *digits =
+ ((flags & ErrH::cf_uppercase) ? "0123456789ABCDEF" : "0123456789abcdef");
+ char *pos = after_last;
+ while (num) {
+ *--pos = digits[num % base];
+ num /= base;
+ }
+ if (pos == after_last)
+ *--pos = '0';
+ return pos;
+}
+
+static char *
+do_number_flags(char *pos, char *after_last, int base, int flags,
+ int precision, int field_width)
+{
+ // remove cf_alternate_form for zero results in base 16
+ if ((flags & ErrH::cf_alternate_form) && base == 16 && *pos == '0')
+ flags &= ~ErrH::cf_alternate_form;
+
+ // account for zero padding
+ if (precision >= 0)
+ while (after_last - pos < precision)
+ *--pos = '0';
+ else if (flags & ErrH::cf_zero_pad) {
+ if ((flags & ErrH::cf_alternate_form) && base == 16)
+ field_width -= 2;
+ if ((flags & ErrH::cf_negative)
+ || (flags & (ErrH::cf_plus_positive | ErrH::cf_space_positive)))
+ field_width--;
+ while (after_last - pos < field_width)
+ *--pos = '0';
+ }
+
+ // alternate forms
+ if ((flags & ErrH::cf_alternate_form) && base == 8 && pos[1] != '0')
+ *--pos = '0';
+ else if ((flags & ErrH::cf_alternate_form) && base == 16) {
+ *--pos = ((flags & ErrH::cf_uppercase) ? 'X' : 'x');
+ *--pos = '0';
+ }
+
+ // sign
+ if (flags & ErrH::cf_negative)
+ *--pos = '-';
+ else if (flags & ErrH::cf_plus_positive)
+ *--pos = '+';
+ else if (flags & ErrH::cf_space_positive)
+ *--pos = ' ';
+
+ return pos;
+}
+
+String
+ErrorHandler::vxformat(int default_flags, const char *s, va_list val)
+{
+ StringAccum msg;
+
+ char numbuf[NUMBUF_SIZE]; // for numerics
+ numbuf[NUMBUF_SIZE-1] = 0;
+
+ String strstore; // to ensure temporaries aren't destroyed
+
+ // declare and initialize these here to make gcc shut up about possible
+ // use before initialization
+ int flags = 0;
+ int field_width = -1;
+ int precision = -1;
+ int width_flag = 0;
+ int base = 10;
+ while (1) {
+
+ const char *pct = strchr(s, '%');
+ if (!pct) {
+ if (*s)
+ msg << s;
+ break;
+ }
+ if (pct != s) {
+ msg.append(s, pct - s);
+ s = pct;
+ }
+
+ // parse flags
+ flags = default_flags;
+ flags:
+ switch (*++s) {
+ case '#': flags |= cf_alternate_form; goto flags;
+ case '0': flags |= cf_zero_pad; goto flags;
+ case '-': flags |= cf_left_just; goto flags;
+ case ' ': flags |= cf_space_positive; goto flags;
+ case '+': flags |= cf_plus_positive; goto flags;
+ case '\'': flags |= cf_singlequote; goto flags;
+ case '_': flags &= ~cf_utf8; goto flags;
+ }
+
+ // parse field width
+ field_width = -1;
+ if (*s == '*') {
+ field_width = va_arg(val, int);
+ if (field_width < 0) {
+ field_width = -field_width;
+ flags |= cf_left_just;
+ }
+ s++;
+ } else if (*s >= '0' && *s <= '9')
+ for (field_width = 0; *s >= '0' && *s <= '9'; s++)
+ field_width = 10*field_width + *s - '0';
+
+ // parse precision
+ precision = -1;
+ if (*s == '.') {
+ s++;
+ precision = 0;
+ if (*s == '*') {
+ precision = va_arg(val, int);
+ s++;
+ } else if (*s >= '0' && *s <= '9')
+ for (; *s >= '0' && *s <= '9'; s++)
+ precision = 10*precision + *s - '0';
+ }
+
+ // parse width flags
+ width_flag = 0;
+ width_flags:
+ switch (*s) {
+ case 'h': case 'l':
+ if (width_flag == *s)
+ width_flag = *s + 'A' - 'a';
+ else if (width_flag)
+ break;
+ else
+ width_flag = *s;
+ s++;
+ goto width_flags;
+ case 'z':
+ if (width_flag)
+ break;
+ width_flag = *s++;
+ break;
+ case '^':
+ if (!isdigit((unsigned char) s[1]) || width_flag)
+ break;
+ for (s++; isdigit((unsigned char) *s); s++)
+ width_flag = width_flag * 10 + *s - '0';
+ width_flag = -width_flag;
+ break;
+ }
+
+ // conversion character
+ // after switch, data lies between `s1' and `s2'
+ const char *s1 = 0, *s2 = 0;
+ base = 10;
+ switch (*s++) {
+
+ case 's': {
+ s1 = va_arg(val, const char *);
+ if (!s1)
+ s1 = "(null)";
+
+ // fetch length
+ int len;
+ if (precision < 0)
+ len = strlen(s1);
+ else
+ len = strnlen(s1, precision);
+
+ // transform string if alternate form
+ if (flags & cf_alternate_form) {
+ strstore = String(s1, len).printable();
+ if (precision < 0 || strstore.length() < precision)
+ len = strstore.length();
+ }
+
+ // quote characters that look like annotations, readjusting length
+ if (flags & (cf_singlequote | cf_alternate_form)) {
+ if (!(flags & cf_alternate_form))
+ strstore = String(s1, len);
+
+ // check first line, considering trailing part of 'msg'
+ const char *mbegin = msg.end();
+ while (mbegin != msg.begin() && mbegin[-1] != '\n')
+ --mbegin;
+ if (skip_anno(strstore.begin(), strstore.end()) != strstore.begin()
+ && skip_anno(mbegin, msg.end()) == msg.end()) {
+ strstore = String::make_stable("{}", 2) + strstore;
+ len += 2;
+ }
+
+ // check subsequent lines
+ const char *s = std::find(strstore.begin(), strstore.end(), '\n');
+ while (s != strstore.end() && s + 1 != strstore.end()) {
+ size_t nextpos = (s + 1) - strstore.begin();
+ if (skip_anno(s + 1, strstore.end()) != s + 1) {
+ strstore = strstore.substring(strstore.begin(), s + 1)
+ + String::make_stable("{}", 2)
+ + strstore.substring(s + 1, strstore.end());
+ len += 2;
+ }
+ s = std::find(strstore.begin() + nextpos, strstore.end(), '\n');
+ }
+ }
+
+ // obtain begin and end pointers
+ if (flags & (cf_singlequote | cf_alternate_form))
+ s1 = strstore.begin();
+ s2 = s1 + len;
+ break;
+ }
+
+ case 'c': {
+ int c = va_arg(val, int);
+ // check for extension of 'signed char' to 'int'
+ if (c < 0)
+ c += 256;
+ // assume ASCII
+ if (c == '\n')
+ strcpy(numbuf, "\\n");
+ else if (c == '\t')
+ strcpy(numbuf, "\\t");
+ else if (c == '\r')
+ strcpy(numbuf, "\\r");
+ else if (c == '\0')
+ strcpy(numbuf, "\\0");
+ else if (c < 0 || c >= 256)
+ strcpy(numbuf, "(bad char)");
+ else if (c < 32 || c >= 0177)
+ sprintf(numbuf, "\\%03o", c);
+ else
+ sprintf(numbuf, "%c", c);
+ s1 = numbuf;
+ s2 = strchr(numbuf, 0);
+ break;
+ }
+
+ case '%': {
+ numbuf[0] = '%';
+ s1 = numbuf;
+ s2 = s1 + 1;
+ break;
+ }
+
+ case '<':
+ s1 = (flags & cf_utf8 ? "\342\200\230" : "\'");
+ s2 = s1 + strlen(s1);
+ break;
+
+ case '>':
+ case ',':
+ s1 = (flags & cf_utf8 ? "\342\200\231" : "\'");
+ s2 = s1 + strlen(s1);
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= cf_signed;
+ case 'u':
+ number: {
+ // protect numbuf from overflow
+ if (field_width > NUMBUF_SIZE)
+ field_width = NUMBUF_SIZE;
+ if (precision > NUMBUF_SIZE - 4)
+ precision = NUMBUF_SIZE - 4;
+
+ s2 = numbuf + NUMBUF_SIZE;
+
+ unsigned long num;
+ switch (width_flag) {
+ case 'H':
+ case -8:
+ num = (unsigned char) va_arg(val, int);
+ if ((flags & cf_signed) && (signed char) num < 0)
+ num = -(signed char) num, flags |= cf_negative;
+ break;
+ case 'h':
+ case -16:
+ num = (unsigned short) va_arg(val, int);
+ if ((flags & cf_signed) && (short) num < 0)
+ num = -(short) num, flags |= cf_negative;
+ break;
+ case 0:
+ case -32:
+#if SIZEOF_LONG == 4
+ case 'l':
+#endif
+#if SIZEOF_SIZE_T == 4
+ case 'z':
+#endif
+ num = va_arg(val, unsigned);
+ if ((flags & cf_signed) && (int) num < 0)
+ num = -(int) num, flags |= cf_negative;
+ break;
+#if HAVE_INT64_TYPES
+# if SIZEOF_LONG == 8
+ case 'l':
+# endif
+# if SIZEOF_LONG_LONG == 8
+ case 'L':
+# endif
+# if SIZEOF_SIZE_T == 8
+ case 'z':
+# endif
+ case -64: {
+ uint64_t qnum = va_arg(val, uint64_t);
+ if ((flags & cf_signed) && (int64_t)qnum < 0)
+ qnum = -(int64_t) qnum, flags |= cf_negative;
+ StringAccum sa;
+ sa.append_numeric(static_cast<String::uintmax_t>(qnum), base, (flags & cf_uppercase));
+ s1 = s2 - sa.length();
+ memcpy(const_cast<char*>(s1), sa.data(), s2 - s1);
+ goto got_number;
+ }
+#endif
+ default:
+ goto error;
+ }
+ s1 = do_number(num, (char *)s2, base, flags);
+
+#if HAVE_INT64_TYPES
+ got_number:
+#endif
+ s1 = do_number_flags((char *)s1, (char *)s2, base, flags,
+ precision, field_width);
+ break;
+ }
+
+ case 'o':
+ base = 8;
+ goto number;
+
+ case 'X':
+ flags |= cf_uppercase;
+ case 'x':
+ base = 16;
+ goto number;
+
+ case 'p': {
+ if (*s == '{') {
+ s1 = s2 = s + 1;
+ while (*s2 && *s2 != '}' && !isspace((unsigned char) *s2))
+ ++s2;
+ if (*s2 == '}')
+ goto braces;
+ }
+ void *v = va_arg(val, void *);
+ s2 = numbuf + NUMBUF_SIZE;
+ s1 = do_number((unsigned long)v, (char *)s2, 16, flags);
+ s1 = do_number_flags((char *)s1, (char *)s2, 16, flags | cf_alternate_form,
+ precision, field_width);
+ break;
+ }
+
+#ifndef __KERNEL__
+ case 'e': case 'f': case 'g':
+ case 'E': case 'F': case 'G': {
+ char format[80], *f = format, new_numbuf[NUMBUF_SIZE];
+ *f++ = '%';
+ if (flags & cf_alternate_form)
+ *f++ = '#';
+ if (precision >= 0)
+ f += sprintf(f, ".%d", precision);
+ *f++ = s[-1];
+ *f++ = 0;
+
+ int len = sprintf(new_numbuf, format, va_arg(val, double));
+
+ s2 = numbuf + NUMBUF_SIZE;
+ s1 = s2 - len;
+ memcpy((char *)s1, new_numbuf, len); // note: no terminating \0
+ s1 = do_number_flags((char *)s1, (char *)s2, 10, flags & ~cf_alternate_form, -1, field_width);
+ break;
+ }
+#endif
+
+ case '{':
+ s1 = s2 = s;
+ while (*s2 && *s2 != '}' && !isspace((unsigned char) *s2))
+ ++s2;
+ if (*s2 != '}')
+ goto error;
+ goto braces;
+
+ braces:
+ s = s2 + 1;
+ for (Conversion *item = error_items; item; item = item->next)
+ if (item->name.equals(s1, s2 - s1)) {
+ strstore = item->hook(flags, VA_LIST_REF(val));
+ s1 = strstore.begin();
+ s2 = strstore.end();
+ goto got_result;
+ }
+ goto error;
+
+ error:
+ default:
+ assert(0 /* Bad % in error */);
+ break;
+
+ }
+
+ // add result of conversion
+ got_result:
+ int slen = s2 - s1;
+ if (slen > field_width)
+ field_width = slen;
+ char *dest = msg.extend(field_width);
+ if (flags & cf_left_just) {
+ memcpy(dest, s1, slen);
+ memset(dest + slen, ' ', field_width - slen);
+ } else {
+ memcpy(dest + field_width - slen, s1, slen);
+ memset(dest, (flags & cf_zero_pad ? '0' : ' '), field_width - slen);
+ }
+ }
+
+ return msg.take_string();
+}
+
+String
+ErrorHandler::xformat(int default_flags, const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String s = vxformat(default_flags, fmt, val);
+ va_end(val);
+ return s;
+}
+
+String
+ErrorHandler::xformat(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String s = vxformat(0, fmt, val);
+ va_end(val);
+ return s;
+}
+
+String
+ErrorHandler::format(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String s = vformat(fmt, val);
+ va_end(val);
+ return s;
+}
+
+
+// ERROR MESSAGE SHORTHAND
+
+void
+ErrorHandler::debug(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ vxmessage(String::make_stable(e_debug, 3), fmt, val);
+ va_end(val);
+}
+
+void
+ErrorHandler::message(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ vxmessage(String::make_stable(e_info, 3), fmt, val);
+ va_end(val);
+}
+
+int
+ErrorHandler::warning(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ int r = vxmessage(String::make_stable(e_warning_annotated, 12), fmt, val);
+ va_end(val);
+ return r;
+}
+
+int
+ErrorHandler::error(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ int r = vxmessage(String::make_stable(e_error, 3), fmt, val);
+ va_end(val);
+ return r;
+}
+
+int
+ErrorHandler::fatal(const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ int r = vxmessage(String::make_stable(e_fatal, 4), fmt, val);
+ va_end(val);
+ return r;
+}
+
+void
+ErrorHandler::ldebug(const String &landmark, const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String l = make_landmark_anno(landmark);
+ vxmessage(String::make_stable(e_debug, 3) + l, fmt, val);
+ va_end(val);
+}
+
+void
+ErrorHandler::lmessage(const String &landmark, const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String l = make_landmark_anno(landmark);
+ vxmessage(String::make_stable(e_info, 3) + l, fmt, val);
+ va_end(val);
+}
+
+int
+ErrorHandler::lwarning(const String &landmark, const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String l = make_landmark_anno(landmark);
+ int r = vxmessage(l + String::make_stable(e_warning_annotated, 12), fmt, val);
+ va_end(val);
+ return r;
+}
+
+int
+ErrorHandler::lerror(const String &landmark, const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String l = make_landmark_anno(landmark);
+ int r = vxmessage(String::make_stable(e_error, 3) + l, fmt, val);
+ va_end(val);
+ return r;
+}
+
+int
+ErrorHandler::lfatal(const String &landmark, const char *fmt, ...)
+{
+ va_list val;
+ va_start(val, fmt);
+ String l = make_landmark_anno(landmark);
+ int r = vxmessage(String::make_stable(e_fatal, 4) + l, fmt, val);
+ va_end(val);
+ return r;
+}
+
+int
+ErrorHandler::xmessage(const String &str)
+{
+ String xstr = decorate(str);
+
+ int min_level = 1000, xlevel = 1000;
+ const char *s = xstr.begin(), *end = xstr.end();
+ void *user_data = 0;
+ while (s != end) {
+ const char *l = parse_anno(xstr, s, end, "#<>", &xlevel,
+ (const char *) 0);
+ const char *nl = std::find(l, end, '\n');
+ String line = xstr.substring(s, nl);
+ s = nl + (nl != end);
+ user_data = emit(line, user_data, s != end);
+ min_level = (xlevel < min_level ? xlevel : min_level);
+ }
+
+ account(min_level);
+
+ return (min_level <= el_warning ? error_result : ok_result);
+}
+
+String
+ErrorHandler::vformat(const char *fmt, va_list val)
+{
+ return vxformat(0, fmt, val);
+}
+
+String
+ErrorHandler::decorate(const String &str)
+{
+ return str;
+}
+
+void *
+ErrorHandler::emit(const String &, void *user_data, bool)
+{
+ return user_data;
+}
+
+
+#ifndef __KERNEL__
+//
+// FILE ERROR HANDLER
+//
+
+FileErrorHandler::FileErrorHandler(FILE *f, const String &context)
+ : _f(f), _context(context), _default_flags(0)
+{
+# if HAVE_UNISTD_H
+ if (isatty(fileno(_f))) {
+# endif
+ char *s = getenv("LANG");
+ if (s && (strstr(s, "UTF-8") != 0 || strstr(s, "UTF8") != 0
+ || strstr(s, "utf8") != 0))
+ _default_flags |= cf_utf8;
+# if HAVE_UNISTD_H
+ }
+# endif
+}
+
+String
+FileErrorHandler::vformat(const char *fmt, va_list val)
+{
+ return vxformat(_default_flags, fmt, val);
+}
+
+void *
+FileErrorHandler::emit(const String &str, void *, bool)
+{
+ String landmark;
+ const char *s = parse_anno(str, str.begin(), str.end(),
+ "l", &landmark, (const char *) 0);
+ StringAccum sa;
+ sa << _context << clean_landmark(landmark, true)
+ << str.substring(s, str.end()) << '\n';
+ ssize_t result = fwrite(sa.begin(), 1, sa.length(), _f);
+ (void) result;
+ return 0;
+}
+
+void
+FileErrorHandler::account(int level)
+{
+ ErrorHandler::account(level);
+ if (level <= el_abort)
+ abort();
+ else if (level <= el_fatal)
+ exit(-level);
+}
+
+#endif
+
+
+//
+// STATIC ERROR HANDLERS
+//
+
+ErrorHandler::Conversion *
+ErrorHandler::add_conversion(const String &name, ConversionFunction function)
+{
+ if (Conversion *c = new Conversion) {
+ c->name = name;
+ c->hook = function;
+ c->next = error_items;
+ error_items = c;
+ return c;
+ } else
+ return 0;
+}
+
+int
+ErrorHandler::remove_conversion(ErrorHandler::Conversion *conv)
+{
+ Conversion **pprev = &error_items;
+ for (Conversion *c = error_items; c; pprev = &c->next, c = *pprev)
+ if (c == conv) {
+ *pprev = c->next;
+ delete c;
+ return 0;
+ }
+ return -1;
+}
+
+ErrorHandler *
+ErrorHandler::static_initialize(ErrorHandler *default_handler)
+{
+ if (!the_silent_handler) {
+ the_default_handler = default_handler;
+ the_silent_handler = new SilentErrorHandler;
+ }
+ return default_handler;
+}
+
+void
+ErrorHandler::static_cleanup()
+{
+ delete the_default_handler;
+ delete the_silent_handler;
+ the_default_handler = the_silent_handler = 0;
+ while (error_items) {
+ Conversion *next = error_items->next;
+ delete error_items;
+ error_items = next;
+ }
+}
+
+void
+ErrorHandler::set_default_handler(ErrorHandler *errh)
+{
+ the_default_handler = errh;
+}
+
+
+//
+// ERROR VENEER
+//
+
+String
+ErrorVeneer::vformat(const char *fmt, va_list val)
+{
+ if (_errh)
+ return _errh->vformat(fmt, val);
+ else
+ return ErrorHandler::vformat(fmt, val);
+}
+
+String
+ErrorVeneer::decorate(const String &str)
+{
+ if (_errh)
+ return _errh->decorate(str);
+ else
+ return ErrorHandler::decorate(str);
+}
+
+void *
+ErrorVeneer::emit(const String &str, void *user_data, bool more)
+{
+ if (_errh)
+ return _errh->emit(str, user_data, more);
+ else
+ return ErrorHandler::emit(str, user_data, more);
+}
+
+void
+ErrorVeneer::account(int level)
+{
+ ErrorHandler::account(level);
+ if (_errh)
+ _errh->account(level);
+}
+
+
+//
+// CONTEXT ERROR HANDLER
+//
+
+ContextErrorHandler::ContextErrorHandler(ErrorHandler *errh, const char *fmt,
+ ...)
+ : ErrorVeneer(errh), _indent(String::make_stable(" ", 2)),
+ _context_printed(false)
+{
+ va_list val;
+ va_start(val, fmt);
+ _context = ErrorVeneer::vformat(fmt, val);
+ va_end(val);
+ if (_context)
+ _context = combine_anno(_context, String::make_stable("{context:context}", 17));
+}
+
+String
+ContextErrorHandler::decorate(const String &str)
+{
+ String context_anno;
+ const char *str_endanno = parse_anno(str, str.begin(), str.end(),
+ "context", &context_anno,
+ (const char *) 0);
+ if (context_anno.equals("no", 2))
+ return ErrorVeneer::decorate(str);
+
+ String istr;
+ if (context_anno.equals("noindent", 8))
+ istr = combine_anno(str, _context_landmark);
+ else
+ istr = combine_anno(str, _context_landmark + _indent);
+
+ if (!_context_printed && !context_anno.equals("nocontext", 9)) {
+ String astr = combine_anno(combine_anno(_context, _context_landmark),
+ str.substring(str.begin(), str_endanno));
+ if (astr && astr.back() != '\n')
+ astr += '\n';
+ _context_printed = true;
+ return ErrorVeneer::decorate(astr + istr);
+ } else
+ return ErrorVeneer::decorate(istr);
+}
+
+
+//
+// PREFIX ERROR HANDLER
+//
+
+PrefixErrorHandler::PrefixErrorHandler(ErrorHandler *errh,
+ const String &prefix)
+ : ErrorVeneer(errh), _prefix(prefix)
+{
+}
+
+String
+PrefixErrorHandler::decorate(const String &str)
+{
+ return ErrorVeneer::decorate(combine_anno(str, _prefix));
+}
+
+
+//
+// LANDMARK ERROR HANDLER
+//
+
+LandmarkErrorHandler::LandmarkErrorHandler(ErrorHandler *errh, const String &landmark)
+ : ErrorVeneer(errh), _landmark(make_landmark_anno(landmark))
+{
+}
+
+String
+LandmarkErrorHandler::decorate(const String &str)
+{
+ return ErrorVeneer::decorate(combine_anno(str, _landmark));
+}
+
+
+//
+// BAIL ERROR HANDLER
+//
+
+#ifndef __KERNEL__
+
+BailErrorHandler::BailErrorHandler(ErrorHandler *errh, int l)
+ : ErrorVeneer(errh), _level(l)
+{
+}
+
+void
+BailErrorHandler::account(int level)
+{
+ ErrorVeneer::account(level);
+ if (level <= _level)
+ exit(1);
+}
+
+#endif
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/filename.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/filename.cc
new file mode 100644
index 00000000000..396e81cd3c5
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/filename.cc
@@ -0,0 +1,130 @@
+// -*- related-file-name: "../include/lcdf/filename.hh" -*-
+
+/* filename.{cc,hh} -- filenames
+ *
+ * Copyright (c) 1999-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/filename.hh>
+#include <lcdf/landmark.hh>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifndef PATHNAME_SEPARATOR
+# define PATHNAME_SEPARATOR '/'
+#endif
+#ifndef CURRENT_DIRECTORY
+# define CURRENT_DIRECTORY "./"
+#endif
+
+
+Filename::Filename(const String &fn)
+ : _path(fn), _actual(0)
+{
+ if (!fn)
+ return;
+
+ int last_slash = fn.find_right(PATHNAME_SEPARATOR);
+ if (last_slash >= 0) {
+ _dir = _path.substring(0, last_slash + 1);
+ _name = _path.substring(last_slash + 1);
+ } else {
+ _dir = CURRENT_DIRECTORY;
+ _name = fn;
+ }
+
+ assert(_dir.back() == PATHNAME_SEPARATOR);
+}
+
+Filename::Filename(const String &dir, const String &name)
+ : _name(name), _actual(0)
+{
+ if (!name)
+ return;
+
+ if (_name[0] == PATHNAME_SEPARATOR)
+ _dir = "";
+ else if (dir) {
+ _dir = dir;
+ if (dir.back() != PATHNAME_SEPARATOR)
+ _dir += PATHNAME_SEPARATOR;
+ } else
+ _dir = CURRENT_DIRECTORY;
+
+ int slash = name.find_right(PATHNAME_SEPARATOR);
+ if (slash >= 0) {
+ _dir += name.substring(0, slash + 1);
+ _name = name.substring(slash + 1);
+ }
+
+ _path = _dir + _name;
+}
+
+Filename::Filename(FILE *actual, const String &name)
+ : _name(name), _path(name), _actual(actual)
+{
+}
+
+
+String
+Filename::extension() const
+{
+ int dot = _name.find_right('.');
+ while (dot > 0 && _name[dot - 1] == '.')
+ dot--;
+ if (dot > 0)
+ return _name.substring(dot + 1);
+ else
+ return String();
+}
+
+String
+Filename::base() const
+{
+ if (String ex = extension())
+ return _name.substring(0, _name.length() - ex.length() - 1);
+ else
+ return _name;
+}
+
+
+FILE *
+Filename::open_read(bool binary) const
+{
+ if (_actual || !_path)
+ return _actual;
+ else
+ return fopen(_path.c_str(), binary ? "rb" : "r");
+}
+
+bool
+Filename::readable() const
+{
+ struct stat s;
+ if (!_path)
+ return false;
+ return _actual || (_path && (stat(_path.c_str(), &s) >= 0));
+}
+
+
+FILE *
+Filename::open_write(bool binary) const
+{
+ if (_actual || !_path)
+ return _actual;
+ else
+ return fopen(_path.c_str(), "wb");
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/fixlibc.c b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/fixlibc.c
new file mode 100644
index 00000000000..d41238daf85
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/fixlibc.c
@@ -0,0 +1,73 @@
+/* Provide definitions for missing or incorrect libc functions. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !HAVE_STRDUP
+char *
+strdup(const char *s)
+{
+ char *t;
+ int l;
+ if (!s)
+ return 0;
+ l = strlen(s) + 1;
+ t = (char *)malloc(l);
+ if (!t)
+ return 0;
+ memcpy(t, s, l);
+ return t;
+}
+#endif
+
+#if !HAVE_STRERROR
+/* David Mazieres <dm@lcs.mit.edu> assures me that this definition works. */
+char *
+strerror(int errno)
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ if (errno < 0 || errno >= sys_nerr)
+ return (char *)"bad error number";
+ else
+ return sys_errlist[errno];
+}
+#endif
+
+#if HAVE_BROKEN_STRTOD
+/* On NeXTSTEP, Melissa O'Neill <oneill@cs.sfu.ca> reports that strtod
+ consumes whitespace after its argument, which makes mminstance (among other
+ programs) not work. This wrapper gets rid of that whitespace again.
+ (Originally, we suspected strtol too, but it seems to work, at least in
+ NeXTSTEP 3.3 patch 2.) */
+
+double
+good_strtod(const char *nptr, char **endptr)
+{
+ double d = strtod(nptr, endptr);
+ if (endptr)
+ while (*endptr > nptr && isspace((unsigned char) (*endptr)[-1]))
+ (*endptr)--;
+ return d;
+}
+#endif
+
+#if !HAVE_STRNLEN || HAVE_BROKEN_STRNLEN
+size_t
+strnlen(const char *s, size_t maxlen)
+{
+ const char *p = (const char *) memchr(s, 0, maxlen);
+ return p ? p - s : maxlen;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/globmatch.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/globmatch.cc
new file mode 100644
index 00000000000..dcd7afc135c
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/globmatch.cc
@@ -0,0 +1,116 @@
+// -*- related-file-name: "../include/lcdf/globmatch.hh" -*-
+
+/* globmatch.{cc,hh} -- glob_match() function for shell globbing
+ *
+ * Copyright (c) 2000-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/globmatch.hh>
+#include <lcdf/string.hh>
+#include <lcdf/vector.hh>
+
+bool
+glob_match(const String& str, const String& pattern)
+{
+ const char* sdata = str.data();
+ const char* pdata = pattern.data();
+ int slen = str.length();
+ int plen = pattern.length();
+ int spos = 0, ppos = 0;
+ Vector<int> glob_ppos, glob_spos1, glob_spos2;
+
+ while (1) {
+ while (ppos < plen)
+ switch (pdata[ppos]) {
+
+ case '?':
+ if (spos >= slen)
+ goto done;
+ spos++;
+ ppos++;
+ break;
+
+ case '*':
+ glob_ppos.push_back(ppos + 1);
+ glob_spos1.push_back(spos);
+ glob_spos2.push_back(slen);
+ spos = slen;
+ ppos++;
+ break;
+
+ case '[': {
+ if (spos >= slen)
+ goto done;
+
+ // find end of character class
+ int p = ppos + 1;
+ bool negated = false;
+ if (p < plen && pdata[p] == '^') {
+ negated = true;
+ p++;
+ }
+ int first = p;
+ if (p < plen && pdata[p] == ']')
+ p++;
+ while (p < plen && pdata[p] != ']')
+ p++;
+ if (p >= plen) // not a character class at all
+ goto ordinary;
+
+ // parse character class
+ bool in = false;
+ for (int i = first; i < p && !in; i++) {
+ int c1 = pdata[i];
+ int c2 = c1;
+ if (i < p - 2 && pdata[i+1] == '-') {
+ c2 = pdata[i+2];
+ i += 2;
+ }
+ if (sdata[spos] >= c1 && sdata[spos] <= c2)
+ in = true;
+ }
+
+ if ((negated && in) || (!negated && !in))
+ goto done;
+ ppos = p + 1;
+ spos++;
+ break;
+ }
+
+ default:
+ ordinary:
+ if (spos >= slen || sdata[spos] != pdata[ppos])
+ goto done;
+ spos++;
+ ppos++;
+ break;
+
+ }
+
+ done:
+ if (spos == slen && ppos == plen)
+ return true;
+ while (glob_ppos.size() && glob_spos1.back() == glob_spos2.back()) {
+ glob_ppos.pop_back();
+ glob_spos1.pop_back();
+ glob_spos2.pop_back();
+ }
+ if (glob_ppos.size()) {
+ glob_spos2.back()--;
+ spos = glob_spos2.back();
+ ppos = glob_ppos.back();
+ } else
+ return false;
+ }
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/landmark.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/landmark.cc
new file mode 100644
index 00000000000..68511055ddc
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/landmark.cc
@@ -0,0 +1,36 @@
+// -*- related-file-name: "../include/lcdf/landmark.hh" -*-
+
+/* landmark.{cc,hh} -- FILE:LINE type landmarks
+ *
+ * Copyright (c) 1998-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/landmark.hh>
+
+Landmark
+operator+(const Landmark &landmark, int offset)
+{
+ if (landmark.has_line())
+ return Landmark(landmark.file(), landmark.line() + offset);
+ else
+ return landmark;
+}
+
+Landmark::operator String() const
+{
+ if (_file && has_line())
+ return _file + ":" + String(_line);
+ else
+ return _file;
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/md5.c b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/md5.c
new file mode 100644
index 00000000000..557a39bef95
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/md5.c
@@ -0,0 +1,357 @@
+/* -*- mode: c; c-basic-offset: 8; related-file-name: "../include/lcdf/md5.h" -*- */
+/* md5.c - MD5 Message-Digest Algorithm
+ * Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
+ *
+ * according to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
+/* heavily modified for GnuPG by <werner.koch@guug.de> */
+/* modified again for Sylpheed by <wk@gnupg.org> 2001-02-11 */
+/* modified again for LCDF by Eddie Kohler <kohler@icir.org> */
+
+
+/* Test values:
+ * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
+ * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
+ * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
+ * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <lcdf/inttypes.h>
+#include <lcdf/md5.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/****************
+ * Rotate a 32 bit integer by n bits
+ */
+#if defined(__GNUC__) && defined(__i386__)
+static inline uint32_t
+rol( uint32_t x, int n)
+{
+ __asm__("roll %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+
+void
+md5_init(MD5_CONTEXT *ctx)
+{
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+ ctx->finalized = 0;
+}
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+
+/****************
+ * transform n*64 bytes
+ */
+static void
+transform(MD5_CONTEXT *ctx, const unsigned char *data)
+{
+ uint32_t correct_words[16];
+ uint32_t A = ctx->A;
+ uint32_t B = ctx->B;
+ uint32_t C = ctx->C;
+ uint32_t D = ctx->D;
+ uint32_t *cwp = correct_words;
+
+#if WORDS_BIGENDIAN
+ {
+ int i;
+ unsigned char *p2, *p1;
+
+ for (i = 0, p1 = data, p2 = (unsigned char*)correct_words;
+ i < 16; i++, p2 += 4) {
+ p2[3] = *p1++;
+ p2[2] = *p1++;
+ p2[1] = *p1++;
+ p2[0] = *p1++;
+ }
+ }
+#elif WORDS_LITTLEENDIAN
+ memcpy(correct_words, data, 64);
+#else
+# error "Neither WORDS_BIGENDIAN nor WORDS_LITTLEENDIAN is defined!"
+#endif
+
+
+#define OP(a, b, c, d, s, T) \
+ do { \
+ a += FF (b, c, d) + (*cwp++) + T; \
+ a = rol(a, s); \
+ a += b; \
+ } while (0)
+
+ /* Before we start, one word about the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do { \
+ a += f (b, c, d) + correct_words[k] + T; \
+ a = rol(a, s); \
+ a += b; \
+ } while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+void
+md5_update(MD5_CONTEXT *hd, const unsigned char *inbuf, size_t inlen)
+{
+ if (hd->count == 64) { /* flush the buffer */
+ transform( hd, hd->buf );
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return;
+ if (hd->count) {
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ md5_update(hd, NULL, 0);
+ if (!inlen)
+ return;
+ }
+
+ while (inlen >= 64) {
+ transform(hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+do_final(MD5_CONTEXT *hd)
+{
+ uint32_t t, msb, lsb;
+ unsigned char *p;
+
+ md5_update(hd, NULL, 0); /* flush */
+
+ msb = 0;
+ t = hd->nblocks;
+ if ((lsb = t << 6) < t) /* multiply by 64 to make a byte count */
+ msb++;
+ msb += t >> 26;
+ t = lsb;
+ if ((lsb = t + hd->count) < t) /* add the count */
+ msb++;
+ t = lsb;
+ if ((lsb = t << 3) < t) /* multiply by 8 to make a bit count */
+ msb++;
+ msb += t >> 29;
+
+ if (hd->count < 56) { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while(hd->count < 56)
+ hd->buf[hd->count++] = 0; /* pad */
+ } else { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64)
+ hd->buf[hd->count++] = 0;
+ md5_update(hd, NULL, 0); /* flush */
+ memset(hd->buf, 0, 56); /* fill next block with zeroes */
+ }
+
+ /* append the 64 bit count */
+ hd->buf[56] = lsb ;
+ hd->buf[57] = lsb >> 8;
+ hd->buf[58] = lsb >> 16;
+ hd->buf[59] = lsb >> 24;
+ hd->buf[60] = msb ;
+ hd->buf[61] = msb >> 8;
+ hd->buf[62] = msb >> 16;
+ hd->buf[63] = msb >> 24;
+ transform(hd, hd->buf);
+
+ p = hd->buf;
+#if WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
+ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
+#elif WORDS_LITTLEENDIAN
+ /*#define X(a) do { *(uint32_t*)p = hd->##a ; p += 4; } while(0)*/
+ /* Unixware's cpp doesn't like the above construct so we do it his way:
+ * (reported by Allan Clark) */
+#define X(a) do { *(uint32_t*)p = (*hd).a ; p += 4; } while(0)
+#else
+# error "Neither WORDS_BIGENDIAN nor WORDS_LITTLEENDIAN is defined!"
+#endif
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+ hd->finalized = 1;
+}
+
+void
+md5_final(unsigned char *digest, MD5_CONTEXT *ctx)
+{
+ if (!ctx->finalized)
+ do_final(ctx);
+ memcpy(digest, ctx->buf, 16);
+}
+
+void
+md5_final_text(char *buf, MD5_CONTEXT *ctx)
+{
+ static const char *chars = "abcdefghijklmnopqrstuvwxyz234567";
+ int bit;
+ if (!ctx->finalized)
+ do_final(ctx);
+ for (bit = 0; bit < 16*8; bit += 5) {
+ int first_char = bit / 8;
+ int val = ctx->buf[first_char] >> (bit % 8);
+ if (bit + 8 > (first_char + 1) * 8 && first_char < 15)
+ val += ctx->buf[first_char + 1] << (8 - (bit % 8));
+ *buf++ = chars[val & 0x1F];
+ }
+ *buf++ = 0;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/permstr.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/permstr.cc
new file mode 100644
index 00000000000..c6aebab31e7
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/permstr.cc
@@ -0,0 +1,319 @@
+// -*- related-file-name: "../include/lcdf/permstr.hh" -*-
+
+/* permstr.{cc,hh} -- permanent strings
+ *
+ * Copyright (c) 1998-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/permstr.hh>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static PermString::Initializer initializer;
+
+PermString::Doodad PermString::zero_char_doodad = {
+ 0, 0, { 0, 0 }
+};
+PermString::Doodad PermString::one_char_doodad[256];
+PermString::Doodad* PermString::buckets[NHASH];
+
+PermString::Initializer::Initializer()
+{
+ static int initialized = 0;
+ if (!initialized) {
+ PermString::static_initialize();
+ initialized = 1;
+ }
+}
+
+void
+PermString::static_initialize()
+{
+ for (int i = 0; i < 256; i++) {
+ one_char_doodad[i].next = 0;
+ one_char_doodad[i].length = 1;
+ one_char_doodad[i].data[0] = i;
+ one_char_doodad[i].data[1] = 0;
+ }
+}
+
+
+// This scatter array, and the ideas behind it, are stolen from lcc.
+static int scatter[] = { /* map characters to random values */
+ 2078917053, 143302914, 1027100827, 1953210302, 755253631,
+ 2002600785, 1405390230, 45248011, 1099951567, 433832350,
+ 2018585307, 438263339, 813528929, 1703199216, 618906479,
+ 573714703, 766270699, 275680090, 1510320440, 1583583926,
+ 1723401032, 1965443329, 1098183682, 1636505764, 980071615,
+ 1011597961, 643279273, 1315461275, 157584038, 1069844923,
+ 471560540, 89017443, 1213147837, 1498661368, 2042227746,
+ 1968401469, 1353778505, 1300134328, 2013649480, 306246424,
+ 1733966678, 1884751139, 744509763, 400011959, 1440466707,
+ 1363416242, 973726663, 59253759, 1639096332, 336563455,
+ 1642837685, 1215013716, 154523136, 593537720, 704035832,
+ 1134594751, 1605135681, 1347315106, 302572379, 1762719719,
+ 269676381, 774132919, 1851737163, 1482824219, 125310639,
+ 1746481261, 1303742040, 1479089144, 899131941, 1169907872,
+ 1785335569, 485614972, 907175364, 382361684, 885626931,
+ 200158423, 1745777927, 1859353594, 259412182, 1237390611,
+ 48433401, 1902249868, 304920680, 202956538, 348303940,
+ 1008956512, 1337551289, 1953439621, 208787970, 1640123668,
+ 1568675693, 478464352, 266772940, 1272929208, 1961288571,
+ 392083579, 871926821, 1117546963, 1871172724, 1771058762,
+ 139971187, 1509024645, 109190086, 1047146551, 1891386329,
+ 994817018, 1247304975, 1489680608, 706686964, 1506717157,
+ 579587572, 755120366, 1261483377, 884508252, 958076904,
+ 1609787317, 1893464764, 148144545, 1415743291, 2102252735,
+ 1788268214, 836935336, 433233439, 2055041154, 2109864544,
+ 247038362, 299641085, 834307717, 1364585325, 23330161,
+ 457882831, 1504556512, 1532354806, 567072918, 404219416,
+ 1276257488, 1561889936, 1651524391, 618454448, 121093252,
+ 1010757900, 1198042020, 876213618, 124757630, 2082550272,
+ 1834290522, 1734544947, 1828531389, 1982435068, 1002804590,
+ 1783300476, 1623219634, 1839739926, 69050267, 1530777140,
+ 1802120822, 316088629, 1830418225, 488944891, 1680673954,
+ 1853748387, 946827723, 1037746818, 1238619545, 1513900641,
+ 1441966234, 367393385, 928306929, 946006977, 985847834,
+ 1049400181, 1956764878, 36406206, 1925613800, 2081522508,
+ 2118956479, 1612420674, 1668583807, 1800004220, 1447372094,
+ 523904750, 1435821048, 923108080, 216161028, 1504871315,
+ 306401572, 2018281851, 1820959944, 2136819798, 359743094,
+ 1354150250, 1843084537, 1306570817, 244413420, 934220434,
+ 672987810, 1686379655, 1301613820, 1601294739, 484902984,
+ 139978006, 503211273, 294184214, 176384212, 281341425,
+ 228223074, 147857043, 1893762099, 1896806882, 1947861263,
+ 1193650546, 273227984, 1236198663, 2116758626, 489389012,
+ 593586330, 275676551, 360187215, 267062626, 265012701,
+ 719930310, 1621212876, 2108097238, 2026501127, 1865626297,
+ 894834024, 552005290, 1404522304, 48964196, 5816381,
+ 1889425288, 188942202, 509027654, 36125855, 365326415,
+ 790369079, 264348929, 513183458, 536647531, 13672163,
+ 313561074, 1730298077, 286900147, 1549759737, 1699573055,
+ 776289160, 2143346068, 1975249606, 1136476375, 262925046,
+ 92778659, 1856406685, 1884137923, 53392249, 1735424165,
+ 1602280572
+};
+
+
+void
+PermString::initialize(const char* s, int length)
+{
+ const unsigned char* m = reinterpret_cast<const unsigned char*>(s);
+ const unsigned char* mm;
+
+ if (length < 0)
+ length = (s ? strlen(s) : 0);
+
+ if (length == 0) {
+ _rep = zero_char_doodad.data;
+ return;
+ } else if (length == 1) {
+ _rep = one_char_doodad[m[0]].data;
+ return;
+ }
+
+ unsigned hash;
+ int l;
+ for (hash = 0, l = length, mm = m; l; mm++, l--)
+ hash = (hash << 1) + scatter[*mm];
+ hash &= (NHASH - 1);
+
+ Doodad *buck;
+ for (buck = buckets[hash]; buck; buck = buck->next)
+ if (length == buck->length && memcmp(s, buck->data, length) == 0) {
+ _rep = buck->data;
+ return;
+ }
+
+ // CANNOT USE new because the structure has variable size.
+ buck = (Doodad *)malloc(sizeof(Doodad) + length - 1);
+ buck->next = buckets[hash];
+ buckets[hash] = buck;
+ buck->length = length;
+ memcpy(buck->data, s, length);
+ buck->data[length] = 0;
+
+ _rep = buck->data;
+}
+
+static int pspos;
+static int pscap = 64;
+static char *psc = (char *)malloc(pscap);
+
+static void
+append(const char *s, int len)
+{
+ if (pspos + len >= pscap) {
+ pscap *= 2;
+ psc = (char *)realloc(psc, pscap);
+ }
+ memcpy(psc + pspos, s, len);
+ pspos += len;
+}
+
+inline static void
+extend(int len)
+{
+ while (pspos + len >= pscap) {
+ pscap *= 2;
+ psc = (char *)realloc(psc, pscap);
+ }
+}
+
+PermString
+vpermprintf(const char *s, va_list val)
+{
+ pspos = 0;
+ while (1) {
+
+ const char *pct = strchr(s, '%');
+ if (!pct) {
+ if (*s)
+ append(s, strlen(s));
+ break;
+ }
+ if (pct != s) {
+ append(s, pct - s);
+ s = pct;
+ }
+
+ int iflag = -1;
+ while (1)
+ switch (*++s) {
+
+ case '0':
+ /* zeroflag = 1; */
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ assert(iflag == -1 /* Too many decimal flags in permprintf */);
+ iflag = 0;
+ while (*s >= '0' && *s <= '9') {
+ iflag = iflag * 10 + *s - '0';
+ s++;
+ }
+ break;
+
+ case '*':
+ assert(iflag == -1 /* iflag given */);
+ iflag = va_arg(val, int);
+ break;
+
+ case 's': {
+ const char *x = va_arg(val, const char *);
+ if (x) {
+ if (iflag < 0)
+ append(x, strlen(x));
+ else
+ append(x, iflag);
+ }
+ goto pctdone;
+ }
+
+ case 'c': {
+ char c = (char)(va_arg(val, int) & 0xFF);
+ append(&c, 1);
+ goto pctdone;
+ }
+
+ case 'p': {
+ PermString::Capsule x = va_arg(val, PermString::Capsule);
+ PermString px;
+ if (x)
+ px = PermString::decapsule(x);
+ if (iflag < 0 || iflag > px.length())
+ append(px.c_str(), px.length());
+ else
+ append(px.c_str(), iflag);
+ goto pctdone;
+ }
+
+ case 'd': {
+ // FIXME FIXME rewrite for sense
+ int x = va_arg(val, int);
+ if (pspos == pscap)
+ extend(1);
+
+ // FIXME -2^31
+ unsigned int ux = x;
+ if (x < 0) {
+ psc[pspos++] = '-';
+ ux = -x;
+ }
+
+ int numdigits = 0;
+ for (unsigned digcountx = ux; digcountx > 9; digcountx /= 10)
+ numdigits++;
+
+ extend(numdigits + 1);
+ int digit = numdigits;
+ do {
+ psc[pspos + digit] = (ux % 10) + '0';
+ ux /= 10;
+ digit--;
+ } while (ux);
+ pspos += numdigits + 1;
+
+ goto pctdone;
+ }
+
+ case 'g': {
+ // FIXME FIXME rewrite for sense
+ double x = va_arg(val, double);
+ char buffer[1000];
+ int len;
+ sprintf(buffer, "%.10g%n", x, &len);
+ extend(len);
+ strcpy(psc + pspos, buffer);
+ pspos += len;
+ goto pctdone;
+ }
+
+ default:
+ assert(0 /* Bad % in permprintf */);
+ goto pctdone;
+
+ }
+
+ pctdone:
+ s++;
+ }
+
+ return PermString(psc, pspos);
+}
+
+PermString permprintf(const char *s, ...)
+{
+ va_list val;
+ va_start(val, s);
+ PermString p = vpermprintf(s, val);
+ va_end(val);
+ return p;
+}
+
+PermString permcat(PermString a, PermString b)
+{
+ if (!a || !b)
+ return a ? a : b;
+ unsigned al = a.length();
+ unsigned bl = b.length();
+ char *s = new char[al + bl];
+ memcpy(s, a.c_str(), al);
+ memcpy(s + al, b.c_str(), bl);
+ PermString p(s, al + bl);
+ delete[] s;
+ return p;
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/point.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/point.cc
new file mode 100644
index 00000000000..8b23fdcb571
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/point.cc
@@ -0,0 +1,57 @@
+// -*- related-file-name: "../include/lcdf/point.hh" -*-
+
+/* point.{cc,hh} -- 2D points
+ *
+ * Copyright (c) 1998-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/point.hh>
+
+Point
+Point::rotated(double rotation) const throw ()
+{
+ double r = length();
+ double theta = angle() + rotation;
+ return Point(r * cos(theta), r * sin(theta));
+}
+
+Point
+Point::midpoint(const Point &a, const Point &b) throw ()
+{
+ return Point((a.x + b.x)/2, (a.y + b.y)/2);
+}
+
+bool
+Point::on_line(const Point &a, const Point &b, double tolerance) const throw ()
+{
+ Point c = b - a;
+ double d = c.x * (y - a.y) - c.y * (x - a.x);
+ return (d * d <= tolerance * tolerance * c.squared_length());
+}
+
+bool
+Point::on_segment(const Point &a, const Point &b, double t) const throw ()
+{
+ double tt;
+ Point c = b - a;
+ if (fabs(c.x) > fabs(c.y))
+ tt = (x - a.x) / c.x;
+ else if (c.y)
+ tt = (y - a.y) / c.y;
+ else
+ tt = 0;
+ if (tt < 0 || tt > 1)
+ return 0;
+ return on_line(a, b, t);
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/slurper.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/slurper.cc
new file mode 100644
index 00000000000..e089617705d
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/slurper.cc
@@ -0,0 +1,187 @@
+// -*- related-file-name: "../include/lcdf/slurper.hh" -*-
+
+/* slurper.{cc,hh} -- reading from files a line at a time
+ *
+ * Copyright (c) 1998-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/slurper.hh>
+#include <string.h>
+
+static const int DefChunkCap = 2048;
+static const int WorthMoving = 256;
+
+
+Slurper::Slurper(const Filename &filename, FILE *f)
+ : _filename(filename), _lineno(0),
+ _data(new unsigned char[DefChunkCap]), _cap(DefChunkCap),
+ _pos(0), _len(0), _line(0), _line_len(0),
+ _saved_line(false), _at_eof(false)
+{
+ if (f) {
+ _f = f;
+ _own_f = false;
+ } else {
+ _f = _filename.open_read();
+ _own_f = true;
+ }
+}
+
+Slurper::~Slurper()
+{
+ delete[] _data;
+ if (_f && _own_f) fclose(_f);
+}
+
+
+void
+Slurper::grow_buffer()
+{
+ // If we need to keep the upper part of the buffer, shift it down (moving
+ // any data we care about).
+ if (_pos >= _cap - WorthMoving) {
+ // I used to move it myself, with a comment that SunOS didn't have a
+ // correct implementation of memmove. This should be detected by
+ // configure, if it's really a problem.
+ memmove(_data, _data + _pos, _len - _pos);
+ _len -= _pos;
+ _pos = 0;
+ }
+
+ // Grow the buffer if necessary.
+ if (_len >= _cap) {
+ unsigned char *new_data = new unsigned char[ 2 * _cap ];
+ // I can't believe I didn't have the line below!!
+ memcpy(new_data, _data, _len);
+ delete[] _data;
+ _data = new_data;
+ _cap = 2 * _cap;
+ }
+}
+
+
+inline int
+Slurper::more_data()
+{
+ grow_buffer();
+
+ // Read new data into the buffer.
+ int amount = fread(_data + _len, 1, _cap - _len, _f);
+ _len += amount;
+ return amount;
+}
+
+char *
+Slurper::get_line_at(unsigned pos)
+{
+ while (1) {
+ for (; pos < _len; pos++)
+ if (_data[pos] == '\n' || _data[pos] == '\r')
+ goto line_ends_at_pos;
+
+ // no line end? look for more data. save and reset `pos', since _pos
+ // may change.
+ int offset = pos - _pos;
+ bool got_more_data = more_data() != 0;
+ pos = _pos + offset;
+ if (!got_more_data) {
+ _at_eof = true;
+ goto line_ends_at_pos;
+ }
+ }
+
+ line_ends_at_pos:
+
+ // PRECONDITION: the line starts at _pos and ends at pos.
+ unsigned next_pos;
+
+ // Find beginning of next line. 3 cases:
+ // 1. line ends in \r\n -> _pos = pos + 2;
+ // 2. line ends in \r OR \n -> _pos = pos + 1;
+ // 3. neither -> must be last line in file; _pos = pos,
+ // since pos == _len
+ if (pos == _len) {
+ // last line in file didn't end in `\n': must have no data left
+ // ensure we have enough space for terminating nul
+ if (pos == _cap) grow_buffer();
+ next_pos = pos;
+ // if already at EOF, don't increment the line number
+ if (pos == _pos) _lineno--;
+
+ } else if (_data[pos] == '\n')
+ next_pos = pos + 1;
+
+ else {
+ assert(_data[pos] == '\r');
+ // If `\r' is last char in buffer, `\n' might be next char. Must read more
+ // data to check for it, or we'd report an empty line that didn't really
+ // exist.
+ if (pos == _len - 1) {
+ // be careful about the possible shift of _pos and _len!
+ int offset = pos - _pos;
+ more_data();
+ pos = _pos + offset;
+ }
+ if (pos < _len - 1 && _data[pos + 1] == '\n')
+ next_pos = pos + 2;
+ else
+ next_pos = pos + 1;
+ }
+
+ _line = _data + _pos;
+ _line_len = pos - _pos;
+ _data[pos] = 0;
+ _pos = next_pos;
+ _lineno++;
+ return (char *)_line;
+}
+
+char *
+Slurper::next_line()
+{
+ if (_saved_line) {
+ _saved_line = false;
+ return (char *)_line;
+ }
+ get_line_at(_pos);
+ if (_line_len == 0 && _at_eof)
+ _line = 0;
+ return (char *)_line;
+}
+
+char *
+Slurper::peek_line()
+{
+ next_line();
+ _saved_line = true;
+ return (char *)_line;
+}
+
+char *
+Slurper::append_next_line()
+{
+ unsigned delta = (_data + _pos) - (_line + _line_len);
+ if (_len - _pos > _line_len) {
+ memmove(_line + delta, _line, _line_len);
+ _line += delta;
+ } else {
+ memmove(_data + _pos - delta, _data + _pos, _len - _pos);
+ _pos -= delta;
+ _len -= delta;
+ }
+
+ unsigned append_at = _pos;
+ _pos = _line - _data;
+ return get_line_at(append_at);
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/straccum.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/straccum.cc
new file mode 100644
index 00000000000..f31b9e216fc
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/straccum.cc
@@ -0,0 +1,304 @@
+// -*- related-file-name: "../include/lcdf/straccum.hh" -*-
+/*
+ * straccum.{cc,hh} -- build up strings with operator<<
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ * Copyright (c) 2001-2012 Eddie Kohler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/straccum.hh>
+#include <lcdf/vector.hh>
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+/** @class StringAccum
+ * @brief Efficiently build up Strings from pieces.
+ *
+ * Like the String class, StringAccum represents a string of characters.
+ * However, unlike a String, a StringAccum is inherently mutable, and
+ * efficiently supports building up a large string from many smaller pieces.
+ *
+ * StringAccum objects support operator<<() operations for most fundamental
+ * data types. A StringAccum is generally built up by operator<<(), and then
+ * turned into a String by the take_string() method. Extracting the String
+ * from a StringAccum does no memory allocation or copying; the StringAccum's
+ * memory is donated to the String.
+ *
+ * <h3>Out-of-memory StringAccums</h3>
+ *
+ * When there is not enough memory to add requested characters to a
+ * StringAccum object, the object becomes a special "out-of-memory"
+ * StringAccum. Out-of-memory objects are contagious: the result of any
+ * concatenation operation involving an out-of-memory StringAccum is another
+ * out-of-memory StringAccum. Appending an out-of-memory String with "sa <<
+ * s" makes "sa" out-of-memory. (However, other usually-equivalent calls,
+ * such as "sa.append(s.begin(), s.end())", <em>do not</em> make "sa"
+ * out-of-memory.) Calling take_string() on an out-of-memory StringAccum
+ * returns an out-of-memory String.
+ *
+ * Out-of-memory StringAccum objects have length zero.
+ */
+
+
+void
+StringAccum::assign_out_of_memory()
+{
+ assert(_cap >= 0);
+ if (_cap > 0)
+ delete[] (_s - MEMO_SPACE);
+ _s = reinterpret_cast<unsigned char *>(const_cast<char *>(String::out_of_memory_data()));
+ _cap = -1;
+ _len = 0;
+}
+
+char *
+StringAccum::grow(int want)
+{
+ // can't append to out-of-memory strings
+ if (_cap < 0) {
+ errno = ENOMEM;
+ return 0;
+ }
+
+ int ncap = (_cap ? (_cap + MEMO_SPACE) * 2 : 128) - MEMO_SPACE;
+ while (ncap <= want)
+ ncap = (ncap + MEMO_SPACE) * 2 - MEMO_SPACE;
+
+ unsigned char *n = new unsigned char[ncap + MEMO_SPACE];
+ if (!n) {
+ assign_out_of_memory();
+ errno = ENOMEM;
+ return 0;
+ }
+ n += MEMO_SPACE;
+
+ if (_s) {
+ memcpy(n, _s, _len);
+ delete[] (_s - MEMO_SPACE);
+ }
+ _s = n;
+ _cap = ncap;
+ return reinterpret_cast<char *>(_s + _len);
+}
+
+int
+StringAccum::resize(int len)
+{
+ assert(len >= 0);
+ if (len > _cap && !grow(len))
+ return -ENOMEM;
+ else {
+ _len = len;
+ return 0;
+ }
+}
+
+char *
+StringAccum::hard_extend(int nadjust, int nreserve)
+{
+ char *x = grow(_len + nadjust + nreserve);
+ if (x)
+ _len += nadjust;
+ return x;
+}
+
+const char *
+StringAccum::c_str()
+{
+ if (_len < _cap || grow(_len))
+ _s[_len] = '\0';
+ return reinterpret_cast<char *>(_s);
+}
+
+void
+StringAccum::append_fill(int c, int len)
+{
+ if (char *s = extend(len))
+ memset(s, c, len);
+}
+
+void
+StringAccum::append_utf8_hard(unsigned ch)
+{
+ if (ch < 0x80)
+ append((unsigned char) ch);
+ else if (ch < 0x800) {
+ append((unsigned char) (0xC0 + ((ch >> 6) & 0x1F)));
+ append((unsigned char) (0x80 + (ch & 0x3F)));
+ } else if (ch < 0x10000) {
+ append((unsigned char) (0xE0 + ((ch >> 12) & 0x0F)));
+ append((unsigned char) (0x80 + ((ch >> 6) & 0x3F)));
+ append((unsigned char) (0x80 + (ch & 0x3F)));
+ } else if (ch < 0x110000) {
+ append((unsigned char) (0xF0 + ((ch >> 18) & 0x07)));
+ append((unsigned char) (0x80 + ((ch >> 12) & 0x3F)));
+ append((unsigned char) (0x80 + ((ch >> 6) & 0x3F)));
+ append((unsigned char) (0x80 + (ch & 0x3F)));
+ } else
+ append((unsigned char) '?');
+}
+
+void
+StringAccum::hard_append(const char *s, int len)
+{
+ // We must be careful about calls like "sa.append(sa.begin(), sa.end())";
+ // a naive implementation might use sa's data after freeing it.
+ const char *my_s = reinterpret_cast<char *>(_s);
+
+ if (_len + len <= _cap) {
+ success:
+ memcpy(_s + _len, s, len);
+ _len += len;
+ } else if (s < my_s || s >= my_s + _cap) {
+ if (grow(_len + len))
+ goto success;
+ } else {
+ unsigned char *old_s = _s;
+ int old_len = _len;
+
+ _s = 0;
+ _len = 0;
+ _cap = 0;
+
+ if (char *new_s = extend(old_len + len)) {
+ memcpy(new_s, old_s, old_len);
+ memcpy(new_s + old_len, s, len);
+ }
+
+ delete[] (old_s - MEMO_SPACE);
+ }
+}
+
+void
+StringAccum::append(const char *s)
+{
+ hard_append(s, strlen(s));
+}
+
+String
+StringAccum::take_string()
+{
+ int len = length();
+ int cap = _cap;
+ char *str = reinterpret_cast<char *>(_s);
+ if (len > 0) {
+ _s = 0;
+ _len = _cap = 0;
+ return String::make_claim(str, len, cap);
+ } else if (!out_of_memory())
+ return String();
+ else {
+ clear();
+ return String::make_out_of_memory();
+ }
+}
+
+void
+StringAccum::swap(StringAccum &o)
+{
+ unsigned char *os = o._s;
+ int olen = o._len, ocap = o._cap;
+ o._s = _s;
+ o._len = _len, o._cap = _cap;
+ _s = os;
+ _len = olen, _cap = ocap;
+}
+
+/** @relates StringAccum
+ @brief Append decimal representation of @a i to @a sa.
+ @return @a sa */
+StringAccum &
+operator<<(StringAccum &sa, long i)
+{
+ if (char *x = sa.reserve(24)) {
+ int len = sprintf(x, "%ld", i);
+ sa.adjust_length(len);
+ }
+ return sa;
+}
+
+/** @relates StringAccum
+ @brief Append decimal representation of @a u to @a sa.
+ @return @a sa */
+StringAccum &
+operator<<(StringAccum &sa, unsigned long u)
+{
+ if (char *x = sa.reserve(24)) {
+ int len = sprintf(x, "%lu", u);
+ sa.adjust_length(len);
+ }
+ return sa;
+}
+
+StringAccum &
+operator<<(StringAccum &sa, double d)
+{
+ if (char *x = sa.reserve(256)) {
+ int len = sprintf(x, "%.12g", d);
+ sa.adjust_length(len);
+ }
+ return sa;
+}
+
+StringAccum &
+StringAccum::snprintf(int n, const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ if (char *x = reserve(n + 1)) {
+#if HAVE_VSNPRINTF
+ int len = vsnprintf(x, n + 1, format, val);
+#else
+ int len = vsprintf(x, format, val);
+ assert(len <= n);
+#endif
+ adjust_length(len);
+ }
+ va_end(val);
+ return *this;
+}
+
+void
+StringAccum::append_break_lines(const String& text, int linelen, const String &leftmargin)
+{
+ if (text.length() == 0)
+ return;
+ const char* line = text.begin();
+ const char* ends = text.end();
+ linelen -= leftmargin.length();
+ for (const char* s = line; s < ends; s++) {
+ const char* start = s;
+ while (s < ends && isspace((unsigned char) *s))
+ s++;
+ const char* word = s;
+ while (s < ends && !isspace((unsigned char) *s))
+ s++;
+ if (s - line > linelen && start > line) {
+ *this << leftmargin;
+ append(line, start - line);
+ *this << '\n';
+ line = word;
+ }
+ }
+ if (line < text.end()) {
+ *this << leftmargin;
+ append(line, text.end() - line);
+ *this << '\n';
+ }
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/string.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/string.cc
new file mode 100644
index 00000000000..ec14c378f20
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/string.cc
@@ -0,0 +1,786 @@
+// -*- related-file-name: "../include/lcdf/string.hh" -*-
+/*
+ * string.{cc,hh} -- a String class with shared substrings
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ * Copyright (c) 2001-2012 Eddie Kohler
+ * Copyright (c) 2008-2009 Meraki, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/string.hh>
+#include <lcdf/straccum.hh>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <lcdf/inttypes.h>
+
+#ifndef likely
+#define likely(x) (x)
+#endif
+#ifndef unlikely
+#define unlikely(x) (x)
+#endif
+
+/** @file string.hh
+ * @brief The LCDF String class.
+ */
+
+/** @class String
+ * @brief A string of characters.
+ *
+ * The String class represents a string of characters. Strings may be
+ * constructed from C strings, characters, numbers, and so forth. They may
+ * also be added together. The underlying character arrays are dynamically
+ * allocated; String operations allocate and free memory as needed. A String
+ * and its substrings generally share memory. Accessing a character by index
+ * takes O(1) time; so does creating a substring.
+ *
+ * <h3>Out-of-memory strings</h3>
+ *
+ * When there is not enough memory to create a particular string, a special
+ * "out-of-memory" string is returned instead. Out-of-memory strings are
+ * contagious: the result of any concatenation operation involving an
+ * out-of-memory string is another out-of-memory string. Thus, the final
+ * result of a series of String operations will be an out-of-memory string,
+ * even if the out-of-memory condition occurs in the middle.
+ *
+ * Out-of-memory strings have zero characters, but they aren't equal to other
+ * empty strings. If @a s is a normal String (even an empty string), and @a
+ * oom is an out-of-memory string, then @a s @< @a oom.
+ *
+ * All out-of-memory strings are equal and share the same data(), which is
+ * different from the data() of any other string. See
+ * String::out_of_memory_data(). The String::make_out_of_memory() function
+ * returns an out-of-memory string.
+ */
+
+const char String::null_data = '\0';
+const char String::oom_data = '\0';
+const char String::bool_data[] = "true\0false";
+const char String::int_data[] = "0\0001\0002\0003\0004\0005\0006\0007\0008\0009";
+
+#if HAVE_STRING_PROFILING > 1
+# define MEMO_INITIALIZER_TAIL , 0, 0
+#else
+# define MEMO_INITIALIZER_TAIL
+#endif
+
+const String::rep_t String::null_string_rep = {
+ &null_data, 0, 0
+};
+const String::rep_t String::oom_string_rep = {
+ &oom_data, 0, 0
+};
+
+#if HAVE_STRING_PROFILING
+uint64_t String::live_memo_count;
+uint64_t String::memo_sizes[55];
+uint64_t String::live_memo_sizes[55];
+uint64_t String::live_memo_bytes[55];
+# if HAVE_STRING_PROFILING > 1
+String::memo_t *String::live_memos[55];
+# endif
+#endif
+
+/** @cond never */
+String::memo_t *
+String::create_memo(char *space, int dirty, int capacity)
+{
+ assert(capacity > 0 && capacity >= dirty);
+ memo_t *memo;
+ if (space)
+ memo = reinterpret_cast<memo_t *>(space);
+ else
+ memo = reinterpret_cast<memo_t *>(new char[MEMO_SPACE + capacity]);
+ if (memo) {
+ memo->capacity = capacity;
+ memo->dirty = dirty;
+ memo->refcount = (space ? 0 : 1);
+#if HAVE_STRING_PROFILING
+ int bucket = profile_memo_size_bucket(dirty, capacity);
+ ++memo_sizes[bucket];
+ ++live_memo_sizes[bucket];
+ live_memo_bytes[bucket] += capacity;
+ ++live_memo_count;
+# if HAVE_STRING_PROFILING > 1
+ memo->pprev = &live_memos[bucket];
+ if ((memo->next = *memo->pprev))
+ memo->next->pprev = &memo->next;
+ *memo->pprev = memo;
+# endif
+#endif
+ }
+ return memo;
+}
+
+void
+String::delete_memo(memo_t *memo)
+{
+ assert(memo->capacity > 0);
+ assert(memo->capacity >= memo->dirty);
+#if HAVE_STRING_PROFILING
+ int bucket = profile_memo_size_bucket(memo->dirty, memo->capacity);
+ --live_memo_sizes[bucket];
+ live_memo_bytes[bucket] -= memo->capacity;
+ --live_memo_count;
+# if HAVE_STRING_PROFILING > 1
+ if ((*memo->pprev = memo->next))
+ memo->next->pprev = memo->pprev;
+# endif
+#endif
+ delete[] reinterpret_cast<char *>(memo);
+}
+
+
+#if HAVE_STRING_PROFILING
+void
+String::one_profile_report(StringAccum &sa, int i, int examples)
+{
+ if (i <= 16)
+ sa << "memo_dirty_" << i;
+ else if (i < 25) {
+ uint32_t s = (i - 17) * 2 + 17;
+ sa << "memo_cap_" << s << '_' << (s + 1);
+ } else if (i < 29) {
+ uint32_t s = (i - 25) * 8 + 33;
+ sa << "memo_cap_" << s << '_' << (s + 7);
+ } else {
+ uint32_t s1 = (1U << (i - 23)) + 1;
+ uint32_t s2 = (s1 - 1) << 1;
+ sa << "memo_cap_" << s1 << '_' << s2;
+ }
+ sa << '\t' << live_memo_sizes[i] << '\t' << memo_sizes[i] << '\t' << live_memo_bytes[i] << '\n';
+ if (examples) {
+# if HAVE_STRING_PROFILING > 1
+ for (memo_t *m = live_memos[i]; m; m = m->next) {
+ sa << " [" << m->dirty << "] ";
+ uint32_t dirty = m->dirty;
+ if (dirty > 0 && m->real_data[dirty - 1] == '\0')
+ --dirty;
+ sa.append(m->real_data, dirty > 128 ? 128 : dirty);
+ sa << '\n';
+ }
+# endif
+ }
+}
+
+void
+String::profile_report(StringAccum &sa, int examples)
+{
+ uint64_t all_live_sizes = 0, all_sizes = 0, all_live_bytes = 0;
+ for (int i = 0; i < 55; ++i) {
+ if (memo_sizes[i])
+ one_profile_report(sa, i, examples);
+ all_live_sizes += live_memo_sizes[i];
+ all_sizes += memo_sizes[i];
+ all_live_bytes += live_memo_bytes[i];
+ }
+ sa << "memo_total\t" << all_live_sizes << '\t' << all_sizes << '\t' << all_live_bytes << '\n';
+}
+#endif
+
+/** @endcond never */
+
+
+/** @brief Construct a base-10 string representation of @a x. */
+String::String(int x)
+{
+ if (x >= 0 && x < 10)
+ assign_memo(int_data + 2 * x, 1, 0);
+ else {
+ char buf[128];
+ sprintf(buf, "%d", x);
+ assign(buf, -1, false);
+ }
+}
+
+/** @overload */
+String::String(unsigned x)
+{
+ if (x < 10)
+ assign_memo(int_data + 2 * x, 1, 0);
+ else {
+ char buf[128];
+ sprintf(buf, "%u", x);
+ assign(buf, -1, false);
+ }
+}
+
+/** @overload */
+String::String(long x)
+{
+ if (x >= 0 && x < 10)
+ assign_memo(int_data + 2 * x, 1, 0);
+ else {
+ char buf[128];
+ sprintf(buf, "%ld", x);
+ assign(buf, -1, false);
+ }
+}
+
+/** @overload */
+String::String(unsigned long x)
+{
+ if (x < 10)
+ assign_memo(int_data + 2 * x, 1, 0);
+ else {
+ char buf[128];
+ sprintf(buf, "%lu", x);
+ assign(buf, -1, false);
+ }
+}
+
+String::String(double x)
+{
+ char buf[128];
+ int len = sprintf(buf, "%.12g", x);
+ assign(buf, len, false);
+}
+
+String
+String::make_claim(char *str, int len, int capacity)
+{
+ assert(str && len > 0 && capacity >= len);
+ memo_t *new_memo = create_memo(str - MEMO_SPACE, len, capacity);
+ return String(str, len, new_memo);
+}
+
+String
+String::make_stable(const char *s, int len)
+{
+ if (len < 0)
+ len = (s ? strlen(s) : 0);
+ return String(s, len, 0);
+}
+
+String
+String::make_fill(int c, int len)
+{
+ String s;
+ s.append_fill(c, len);
+ return s;
+}
+
+void
+String::assign_out_of_memory()
+{
+ if (_r.memo)
+ deref();
+ _r.memo = 0;
+ _r.data = &oom_data;
+ _r.length = 0;
+}
+
+void
+String::assign(const char *s, int len, bool need_deref)
+{
+ if (!s) {
+ assert(len <= 0);
+ len = 0;
+ } else if (len < 0)
+ len = strlen(s);
+
+ // need to start with dereference
+ if (need_deref) {
+ if (unlikely(_r.memo
+ && s >= _r.memo->real_data
+ && s + len <= _r.memo->real_data + _r.memo->capacity)) {
+ // Be careful about "String s = ...; s = s.c_str();"
+ _r.data = s;
+ _r.length = len;
+ return;
+ } else
+ deref();
+ }
+
+ if (len == 0) {
+ _r.memo = 0;
+ _r.data = (s == &oom_data ? s : &null_data);
+
+ } else {
+ // Make the memo a multiple of 16 characters and bigger than 'len'.
+ int memo_capacity = (len + 15 + MEMO_SPACE) & ~15;
+ _r.memo = create_memo(0, len, memo_capacity - MEMO_SPACE);
+ if (!_r.memo) {
+ assign_out_of_memory();
+ return;
+ }
+ memcpy(_r.memo->real_data, s, len);
+ _r.data = _r.memo->real_data;
+ }
+
+ _r.length = len;
+}
+
+/** @brief Append @a len unknown characters to this string.
+ * @return Modifiable pointer to the appended characters.
+ *
+ * The caller may safely modify the returned memory. Null is returned if
+ * the string becomes out-of-memory. */
+char *
+String::append_uninitialized(int len)
+{
+ // Appending anything to "out of memory" leaves it as "out of memory"
+ if (unlikely(len <= 0) || out_of_memory())
+ return 0;
+
+ // If we can, append into unused space. First, we check that there's
+ // enough unused space for 'len' characters to fit; then, we check
+ // that the unused space immediately follows the data in '*this'.
+ uint32_t dirty;
+ if (_r.memo
+ && ((dirty = _r.memo->dirty), _r.memo->capacity > dirty + len)) {
+ char *real_dirty = _r.memo->real_data + dirty;
+ if (real_dirty == _r.data + _r.length) {
+ _r.memo->dirty = dirty + len;
+ _r.length += len;
+ assert(_r.memo->dirty < _r.memo->capacity);
+#if HAVE_STRING_PROFILING
+ profile_update_memo_dirty(_r.memo, dirty, dirty + len, _r.memo->capacity);
+#endif
+ return real_dirty;
+ }
+ }
+
+ // Now we have to make new space. Make sure the memo is a multiple of 16
+ // bytes and that it is at least 16. But for large strings, allocate a
+ // power of 2, since power-of-2 sizes minimize waste in frequently-used
+ // allocators, like Linux kmalloc.
+ int want_memo_len = _r.length + len + MEMO_SPACE;
+ int memo_capacity;
+ if (want_memo_len <= 1024)
+ memo_capacity = (want_memo_len + 15) & ~15;
+ else
+ for (memo_capacity = 2048; memo_capacity < want_memo_len; )
+ memo_capacity *= 2;
+
+ memo_t *new_memo = create_memo(0, _r.length + len, memo_capacity - MEMO_SPACE);
+ if (!new_memo) {
+ assign_out_of_memory();
+ return 0;
+ }
+
+ char *new_data = new_memo->real_data;
+ memcpy(new_data, _r.data, _r.length);
+
+ deref();
+ _r.data = new_data;
+ new_data += _r.length; // now new_data points to the garbage
+ _r.length += len;
+ _r.memo = new_memo;
+ return new_data;
+}
+
+void
+String::append(const char *s, int len, memo_t *memo)
+{
+ if (!s) {
+ assert(len <= 0);
+ len = 0;
+ } else if (len < 0)
+ len = strlen(s);
+
+ if (s == &oom_data)
+ // Appending "out of memory" to a regular string makes it "out of
+ // memory"
+ assign_out_of_memory();
+ else if (len == 0)
+ /* do nothing */;
+ else if (_r.length == 0 && memo && !out_of_memory()) {
+ deref();
+ assign_memo(s, len, memo);
+ } else if (likely(!(_r.memo
+ && s >= _r.memo->real_data
+ && s + len <= _r.memo->real_data + _r.memo->capacity))) {
+ if (char *space = append_uninitialized(len))
+ memcpy(space, s, len);
+ } else {
+ String preserve_s(*this);
+ if (char *space = append_uninitialized(len))
+ memcpy(space, s, len);
+ }
+}
+
+/** @brief Append @a len copies of character @a c to this string. */
+void
+String::append_fill(int c, int len)
+{
+ assert(len >= 0);
+ if (char *space = append_uninitialized(len))
+ memset(space, c, len);
+}
+
+/** @brief Ensure the string's data is unshared and return a mutable
+ pointer to it. */
+char *
+String::mutable_data()
+{
+ // If _memo has a capacity (it's not one of the special strings) and it's
+ // uniquely referenced, return _data right away.
+ if (_r.memo && _r.memo->refcount == 1)
+ return const_cast<char *>(_r.data);
+
+ // Otherwise, make a copy of it. Rely on: deref() doesn't change _data or
+ // _length; and if _capacity == 0, then deref() doesn't free _real_data.
+ assert(!_r.memo || _r.memo->refcount > 1);
+ // But in multithreaded situations we must hold a local copy of memo!
+ String do_not_delete_underlying_memo(*this);
+ deref();
+ assign(_r.data, _r.length, false);
+ return const_cast<char *>(_r.data);
+}
+
+char *
+String::mutable_c_str()
+{
+ (void) mutable_data();
+ (void) c_str();
+ return const_cast<char *>(_r.data);
+}
+
+/** @brief Return a substring of this string, consisting of the @a len
+ characters starting at index @a pos.
+ @param pos substring's first position relative to the string
+ @param len length of substring
+
+ If @a pos is negative, starts that far from the end of the string. If @a
+ len is negative, leaves that many characters off the end of the string.
+ If @a pos and @a len specify a substring that is partly outside the
+ string, only the part within the string is returned. If the substring is
+ beyond either end of the string, returns an empty string (but this
+ should be considered a programming error; a future version may generate
+ a warning for this case).
+
+ @note String::substring() is intended to behave like Perl's substr(). */
+String
+String::substring(int pos, int len) const
+{
+ if (pos < 0)
+ pos += _r.length;
+
+ int pos2;
+ if (len < 0)
+ pos2 = _r.length + len;
+ else if (pos >= 0 && len >= _r.length) // avoid integer overflow
+ pos2 = _r.length;
+ else
+ pos2 = pos + len;
+
+ if (pos < 0)
+ pos = 0;
+ if (pos2 > _r.length)
+ pos2 = _r.length;
+
+ if (pos >= pos2)
+ return String();
+ else
+ return String(_r.data + pos, pos2 - pos, _r.memo);
+}
+
+int
+String::find_left(char c, int start) const
+{
+ if (start < 0)
+ start = 0;
+ for (int i = start; i < _r.length; i++)
+ if (_r.data[i] == c)
+ return i;
+ return -1;
+}
+
+int
+String::find_left(const String &str, int start) const
+{
+ if (start < 0)
+ start = 0;
+ int max_pos = length() - str.length();
+ for (int i = start; i <= max_pos; ++i)
+ if (memcmp(_r.data + i, str.data(), str.length()) == 0)
+ return i;
+ return -1;
+}
+
+int
+String::find_right(char c, int start) const
+{
+ if (start >= _r.length)
+ start = _r.length - 1;
+ for (int i = start; i >= 0; i--)
+ if (_r.data[i] == c)
+ return i;
+ return -1;
+}
+
+static String
+hard_lower(const String &s, int pos)
+{
+ String new_s(s.data(), s.length());
+ char *x = const_cast<char *>(new_s.data()); // know it's mutable
+ int len = s.length();
+ for (; pos < len; pos++)
+ x[pos] = tolower((unsigned char) x[pos]);
+ return new_s;
+}
+
+/** @brief Return a lowercased version of this string.
+
+ Translates the ASCII characters 'A' through 'Z' into their lowercase
+ equivalents. */
+String
+String::lower() const
+{
+ // avoid copies
+ if (!out_of_memory())
+ for (int i = 0; i < _r.length; i++)
+ if (_r.data[i] >= 'A' && _r.data[i] <= 'Z')
+ return hard_lower(*this, i);
+ return *this;
+}
+
+static String
+hard_upper(const String &s, int pos)
+{
+ String new_s(s.data(), s.length());
+ char *x = const_cast<char *>(new_s.data()); // know it's mutable
+ int len = s.length();
+ for (; pos < len; pos++)
+ x[pos] = toupper((unsigned char) x[pos]);
+ return new_s;
+}
+
+/** @brief Return an uppercased version of this string.
+
+ Translates the ASCII characters 'a' through 'z' into their uppercase
+ equivalents. */
+String
+String::upper() const
+{
+ // avoid copies
+ for (int i = 0; i < _r.length; i++)
+ if (_r.data[i] >= 'a' && _r.data[i] <= 'z')
+ return hard_upper(*this, i);
+ return *this;
+}
+
+static String
+hard_printable(const String &s, int pos, int type)
+{
+ StringAccum sa(s.length() * 2);
+ sa.append(s.data(), pos);
+ const unsigned char *x = reinterpret_cast<const unsigned char *>(s.data());
+ int len = s.length();
+ for (; pos < len; pos++) {
+ if (x[pos] >= 32 && x[pos] < 127)
+ sa << x[pos];
+ else if (x[pos] < 32 && type != 1)
+ sa << '^' << (unsigned char)(x[pos] + 64);
+ else if (char *buf = sa.extend(4, 1))
+ sprintf(buf, "\\%03o", x[pos]);
+ }
+ return sa.take_string();
+}
+
+/** @brief Return a "printable" version of this string.
+ @param type quoting type
+
+ The default quoting type (0) translates control characters 0-31 into
+ "control" sequences, such as "^@" for the null character, and characters
+ 127-255 into octal escape sequences, such as "\377" for 255. Quoting
+ type 1 translates all characters outside of 32-126 into octal escape
+ sequences. */
+String
+String::printable(int type) const
+{
+ // avoid copies
+ if (!out_of_memory())
+ for (int i = 0; i < _r.length; i++)
+ if (_r.data[i] < 32 || _r.data[i] > 126)
+ return hard_printable(*this, i, type);
+ return *this;
+}
+
+hashcode_t
+String::hashcode(const char *begin, const char *end)
+{
+ if (end <= begin)
+ return 0;
+
+ uint32_t hash = end - begin;
+ int rem = hash & 3;
+ end -= rem;
+ uint32_t last16;
+
+#if !HAVE_INDIFFERENT_ALIGNMENT
+ if (!(reinterpret_cast<uintptr_t>(begin) & 1)) {
+#endif
+#define get16(p) (*reinterpret_cast<const uint16_t *>((p)))
+ for (; begin != end; begin += 4) {
+ hash += get16(begin);
+ uint32_t tmp = (get16(begin + 2) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ hash += hash >> 11;
+ }
+ if (rem >= 2) {
+ last16 = get16(begin);
+ goto rem2;
+ }
+#undef get16
+#if !HAVE_INDIFFERENT_ALIGNMENT
+ } else {
+# if WORDS_BIGENDIAN
+# define get16(p) (((unsigned char) (p)[0] << 8) + (unsigned char) (p)[1])
+# elif WORDS_LITTLEENDIAN
+# define get16(p) ((unsigned char) (p)[0] + ((unsigned char) (p)[1] << 8))
+# else
+# error "unknown byte order"
+# endif
+ // should be exactly the same as the code above
+ for (; begin != end; begin += 4) {
+ hash += get16(begin);
+ uint32_t tmp = (get16(begin + 2) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ hash += hash >> 11;
+ }
+ if (rem >= 2) {
+ last16 = get16(begin);
+ goto rem2;
+ }
+# undef get16
+ }
+#endif
+
+ /* Handle end cases */
+ if (0) { // weird organization avoids uninitialized
+ rem2: // variable warnings
+ if (rem == 3) {
+ hash += last16;
+ hash ^= hash << 16;
+ hash ^= ((unsigned char) begin[2]) << 18;
+ hash += hash >> 11;
+ } else {
+ hash += last16;
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ }
+ } else if (rem == 1) {
+ hash += (unsigned char) *begin;
+ hash ^= hash << 10;
+ hash += hash >> 1;
+ }
+
+ /* Force "avalanching" of final 127 bits */
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+
+ return hash;
+}
+
+#if 0
+// 11.Apr.2008 -- This old hash function was swapped out in favor of
+// SuperFastHash, above.
+hashcode_t
+String::hashcode() const
+{
+ int l = length();
+ const char *d = data();
+ if (!l)
+ return 0;
+ else if (l == 1)
+ return d[0] | (d[0] << 8);
+ else if (l < 4)
+ return d[0] + (d[1] << 3) + (l << 12);
+ else
+ return d[0] + (d[1] << 8) + (d[2] << 16) + (d[3] << 24)
+ + (l << 12) + (d[l-1] << 10);
+}
+#endif
+
+bool
+String::equals(const char *s, int len) const
+{
+ // It'd be nice to make "out-of-memory" strings compare unequal to
+ // anything, even themselves, but this would be a bad idea for Strings
+ // used as (for example) keys in hashtables. Instead, "out-of-memory"
+ // strings compare unequal to other null strings, but equal to each other.
+ if (len < 0)
+ len = strlen(s);
+ if (_r.length != len)
+ return false;
+ else if (_r.data == s)
+ return true;
+ else if (len == 0)
+ return (s != &oom_data && _r.data != &oom_data);
+ else
+ return memcmp(_r.data, s, len) == 0;
+}
+
+bool
+String::starts_with(const char *s, int len) const
+{
+ // See note on equals() re: "out-of-memory" strings.
+ if (len < 0)
+ len = strlen(s);
+ if (_r.length < len)
+ return false;
+ else if (_r.data == s)
+ return true;
+ else if (len == 0)
+ return (s != &oom_data && _r.data != &oom_data);
+ else
+ return memcmp(_r.data, s, len) == 0;
+}
+
+int
+String::compare(const char *s, int len) const
+{
+ if (len < 0)
+ len = strlen(s);
+ if (_r.data == s)
+ return _r.length - len;
+ else if (_r.data == &oom_data)
+ return 1;
+ else if (s == &oom_data)
+ return -1;
+ else if (_r.length == len)
+ return memcmp(_r.data, s, len);
+ else if (_r.length < len) {
+ int v = memcmp(_r.data, s, _r.length);
+ return (v ? v : -1);
+ } else {
+ int v = memcmp(_r.data, s, len);
+ return (v ? v : 1);
+ }
+}
+
+void
+String::align(int n)
+{
+ int offset = reinterpret_cast<uintptr_t>(_r.data) % n;
+ if (offset) {
+ String s;
+ s.append_uninitialized(_r.length + n + 1);
+ offset = reinterpret_cast<uintptr_t>(s._r.data) % n;
+ memcpy((char *)s._r.data + n - offset, _r.data, _r.length);
+ s._r.data += n - offset;
+ s._r.length = _r.length;
+ *this = s;
+ }
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/strtonum.c b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/strtonum.c
new file mode 100644
index 00000000000..36898c5a7ad
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/strtonum.c
@@ -0,0 +1,31 @@
+/* -*- related-file-name: "../include/lcdf/strtonum.h" -*- */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/strtonum.h>
+#include <stdlib.h>
+#if HAVE_BROKEN_STRTOD
+# define strtod good_strtod
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* A faster strtod which only calls the real strtod if the string has a
+ fractional part. */
+
+double
+strtonumber(const char *f, char **endf)
+{
+ long v = strtol((char *)f, endf, 10);
+
+ /* handle any possible decimal part */
+ if (**endf == '.' || **endf == 'E' || **endf == 'e')
+ return strtod((char *)f, endf);
+ else
+ return v;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/transform.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/transform.cc
new file mode 100644
index 00000000000..5eb0ff58728
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/transform.cc
@@ -0,0 +1,167 @@
+// -*- related-file-name: "../include/lcdf/transform.hh" -*-
+
+/* transform.{cc,hh} -- planar affine transformations
+ *
+ * Copyright (c) 2000-2012 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/transform.hh>
+#include <lcdf/straccum.hh>
+#include <math.h>
+
+Transform::Transform()
+{
+ _m[0] = _m[3] = 1;
+ _m[1] = _m[2] = _m[4] = _m[5] = 0;
+ _null = true;
+}
+
+Transform::Transform(const double m[6])
+{
+ _m[0] = m[0];
+ _m[1] = m[1];
+ _m[2] = m[2];
+ _m[3] = m[3];
+ _m[4] = m[4];
+ _m[5] = m[5];
+ check_null(0);
+}
+
+Transform::Transform(double m0, double m1, double m2,
+ double m3, double m4, double m5)
+{
+ _m[0] = m0;
+ _m[1] = m1;
+ _m[2] = m2;
+ _m[3] = m3;
+ _m[4] = m4;
+ _m[5] = m5;
+ check_null(0);
+}
+
+void
+Transform::check_null(double tolerance)
+{
+ _null = (fabs(_m[0] - 1) < tolerance && fabs(_m[1]) < tolerance
+ && fabs(_m[2]) < tolerance && fabs(_m[3] - 1) < tolerance
+ && fabs(_m[4]) < tolerance && fabs(_m[5]) < tolerance);
+}
+
+
+void
+Transform::scale(double x, double y)
+{
+ _m[0] *= x;
+ _m[1] *= x;
+ _m[2] *= y;
+ _m[3] *= y;
+
+ if (x != 1 || y != 1)
+ _null = false;
+}
+
+void
+Transform::rotate(double r)
+{
+ double c = cos(r);
+ double s = sin(r);
+
+ double a = _m[0], b = _m[2];
+ _m[0] = a*c + b*s;
+ _m[2] = b*c - a*s;
+
+ a = _m[1], b = _m[3];
+ _m[1] = a*c + b*s;
+ _m[3] = b*c - a*s;
+
+ if (r != 0)
+ _null = false;
+}
+
+void
+Transform::translate(double x, double y)
+{
+ _m[4] += _m[0]*x + _m[2]*y;
+ _m[5] += _m[1]*x + _m[3]*y;
+
+ if (x != 0 || y != 0)
+ _null = false;
+}
+
+void
+Transform::shear(double s)
+{
+ *this *= Transform(1, 0, s, 1, 0, 0);
+}
+
+Transform
+Transform::transformed(const Transform &t) const
+{
+ return Transform(_m[0] * t._m[0] + _m[2] * t._m[1],
+ _m[1] * t._m[0] + _m[3] * t._m[1],
+ _m[0] * t._m[2] + _m[2] * t._m[3],
+ _m[1] * t._m[2] + _m[3] * t._m[3],
+ _m[0] * t._m[4] + _m[2] * t._m[5] + _m[4],
+ _m[1] * t._m[4] + _m[3] * t._m[5] + _m[5]);
+}
+
+
+void
+Transform::real_apply_to(Point &p) const
+{
+ double x = p.x;
+ p.x = x*_m[0] + p.y*_m[2] + _m[4];
+ p.y = x*_m[1] + p.y*_m[3] + _m[5];
+}
+
+Point
+Transform::real_apply(const Point &p) const
+{
+ return Point(p.x*_m[0] + p.y*_m[2] + _m[4],
+ p.x*_m[1] + p.y*_m[3] + _m[5]);
+}
+
+Bezier &
+operator*=(Bezier &b, const Transform &t)
+{
+ if (!t.null()) {
+ b.mpoint(0) *= t;
+ b.mpoint(1) *= t;
+ b.mpoint(2) *= t;
+ b.mpoint(3) *= t;
+ }
+ return b;
+}
+
+Bezier
+operator*(const Bezier &b, const Transform &t)
+{
+ return (t.null()
+ ? b
+ : Bezier(b.point(0) * t, b.point(1) * t, b.point(2) * t, b.point(3) * t));
+}
+
+String
+Transform::unparse() const
+{
+ StringAccum sa;
+ sa << '[';
+ for (int i = 0; i < 6; i++) {
+ if (i)
+ sa << ',' << ' ';
+ sa << _m[i];
+ }
+ sa << ']';
+ return sa.take_string();
+}
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/vectorv.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/vectorv.cc
new file mode 100644
index 00000000000..f5f12b52c90
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/lcdf-typetools-2.99/liblcdf/vectorv.cc
@@ -0,0 +1,110 @@
+/*
+ * vectorv.cc -- template specialization for Vector<void*>
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2006 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <lcdf/vector.hh>
+#include <string.h>
+
+Vector<void*>::Vector(const Vector<void*> &o)
+ : _l(0), _n(0), _capacity(0)
+{
+ *this = o;
+}
+
+Vector<void*>::~Vector()
+{
+ delete[] _l;
+}
+
+Vector<void*> &
+Vector<void*>::operator=(const Vector<void*> &o)
+{
+ if (&o != this) {
+ _n = 0;
+ if (reserve(o._n)) {
+ _n = o._n;
+ memcpy(_l, o._l, sizeof(void *) * _n);
+ }
+ }
+ return *this;
+}
+
+Vector<void*> &
+Vector<void*>::assign(int n, void *e)
+{
+ _n = 0;
+ resize(n, e);
+ return *this;
+}
+
+bool
+Vector<void*>::reserve(int want)
+{
+ if (want < 0)
+ want = (_capacity > 0 ? _capacity * 2 : 4);
+ if (want <= _capacity)
+ return true;
+
+ void **new_l = new void*[want];
+ if (!new_l)
+ return false;
+
+ memcpy(new_l, _l, sizeof(void*) * _n);
+ delete[] _l;
+
+ _l = new_l;
+ _capacity = want;
+ return true;
+}
+
+Vector<void*>::iterator
+Vector<void*>::erase(iterator a, iterator b)
+{
+ if (b > a) {
+ assert(a >= begin() && b <= end());
+ memmove(a, b, (end() - b) * sizeof(void*));
+ _n -= b - a;
+ return a;
+ } else
+ return b;
+}
+
+void
+Vector<void*>::resize(int nn, void *e)
+{
+ if (nn <= _capacity || reserve(nn)) {
+ for (int i = _n; i < nn; i++)
+ _l[i] = e;
+ _n = nn;
+ }
+}
+
+void
+Vector<void*>::swap(Vector<void*>& o)
+{
+ void **l = _l;
+ int n = _n;
+ int cap = _capacity;
+ _l = o._l;
+ _n = o._n;
+ _capacity = o._capacity;
+ o._l = l;
+ o._n = n;
+ o._capacity = cap;
+}