diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2009-03-20 09:50:07 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2009-03-20 09:50:07 +0000 |
commit | 82150b6fc41b8a3446f2c6020ddf5625956dd708 (patch) | |
tree | 9234f85d00b9fd322b0986b62f09e355449190e6 /Build/source/texk/lcdf-typetools/liblcdf | |
parent | 6b3b122ab7e6994e0b4c8d1299eb2c3462388542 (diff) |
new build system
git-svn-id: svn://tug.org/texlive/trunk@12456 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/lcdf-typetools/liblcdf')
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/Makefile.am | 8 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/Makefile.in | 134 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/bezier.cc | 18 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/clp.c | 202 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/error.cc | 1580 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/filename.cc | 2 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/globmatch.cc | 4 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/md5.c | 4 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/permstr.cc | 8 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/slurper.cc | 22 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/straccum.cc | 191 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/string.cc | 630 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/transform.cc | 4 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/liblcdf/vectorv.cc | 6 |
14 files changed, 1673 insertions, 1140 deletions
diff --git a/Build/source/texk/lcdf-typetools/liblcdf/Makefile.am b/Build/source/texk/lcdf-typetools/liblcdf/Makefile.am index 6531d5186e5..4059860d0cc 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/Makefile.am +++ b/Build/source/texk/lcdf-typetools/liblcdf/Makefile.am @@ -1,12 +1,11 @@ ## 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 \ + fixlibc.c \ globmatch.cc \ landmark.cc \ md5.c \ @@ -19,14 +18,11 @@ liblcdf_a_SOURCES = bezier.cc \ transform.cc \ vectorv.cc -liblcdf_a_DEPENDENCIES = @FIXLIBC_O@ -liblcdf_a_LIBADD = @FIXLIBC_O@ @TEMPLATE_OBJS@ +liblcdf_a_LIBADD = @TEMPLATE_OBJS@ CLEANFILES = @TEMPLATE_OBJS@ INCLUDES = -I$(top_srcdir)/include -EXTRA_DIST = fixlibc.c - srclinks: test -d $(top_srcdir)/include || mkdir $(top_srcdir)/include test -d $(top_srcdir)/include/lcdf || mkdir $(top_srcdir)/include/lcdf diff --git a/Build/source/texk/lcdf-typetools/liblcdf/Makefile.in b/Build/source/texk/lcdf-typetools/liblcdf/Makefile.in index 9acdcfd9c47..e0fe8d0f541 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/Makefile.in +++ b/Build/source/texk/lcdf-typetools/liblcdf/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -30,37 +30,55 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ subdir = liblcdf DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_cxx_template_objs.m4 \ + $(top_srcdir)/m4/kpse-common.m4 \ + $(top_srcdir)/m4/kpse-kpathsea-flags.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)/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)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) -AR = ar ARFLAGS = cru liblcdf_a_AR = $(AR) $(ARFLAGS) +liblcdf_a_DEPENDENCIES = 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) + filename.$(OBJEXT) fixlibc.$(OBJEXT) globmatch.$(OBJEXT) \ + landmark.$(OBJEXT) md5.$(OBJEXT) permstr.$(OBJEXT) \ + point.$(OBJEXT) slurper.$(OBJEXT) straccum.$(OBJEXT) \ + string.$(OBJEXT) strtonum.$(OBJEXT) transform.$(OBJEXT) \ + vectorv.$(OBJEXT) liblcdf_a_OBJECTS = $(am_liblcdf_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) -CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ - -o $@ +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ SOURCES = $(liblcdf_a_SOURCES) DIST_SOURCES = $(liblcdf_a_SOURCES) ETAGS = etags @@ -68,6 +86,7 @@ CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -84,29 +103,40 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -FIXLIBC_O = @FIXLIBC_O@ +FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KPSEINTERFACE_O = @KPSEINTERFACE_O@ +KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ +KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ +KPATHSEA_LIBS = @KPATHSEA_LIBS@ +LD = @LD@ LDFLAGS = @LDFLAGS@ -LIBKPATHSEA = @LIBKPATHSEA@ -LIBKPATHSEA_DEP = @LIBKPATHSEA_DEP@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -115,6 +145,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SED = @SED@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -127,20 +158,29 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ exec_prefix = @exec_prefix@ +host = @host@ host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ @@ -149,6 +189,7 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -164,12 +205,12 @@ 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 \ + fixlibc.c \ globmatch.cc \ landmark.cc \ md5.c \ @@ -182,21 +223,19 @@ liblcdf_a_SOURCES = bezier.cc \ transform.cc \ vectorv.cc -liblcdf_a_DEPENDENCIES = @FIXLIBC_O@ -liblcdf_a_LIBADD = @FIXLIBC_O@ @TEMPLATE_OBJS@ +liblcdf_a_LIBADD = @TEMPLATE_OBJS@ CLEANFILES = @TEMPLATE_OBJS@ INCLUDES = -I$(top_srcdir)/include -EXTRA_DIST = fixlibc.c all: all-am .SUFFIXES: -.SUFFIXES: .c .cc .o .obj +.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 \ - && exit 0; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ @@ -238,6 +277,7 @@ distclean-compile: @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@ @@ -264,6 +304,13 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + .cc.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @@ -278,12 +325,25 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +.cc.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -382,7 +442,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -425,7 +486,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf: pdf-am @@ -440,17 +502,17 @@ uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-noinstLIBRARIES ctags distclean distclean-compile \ - distclean-generic 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 pdf pdf-am ps ps-am tags uninstall \ - uninstall-am + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am srclinks: diff --git a/Build/source/texk/lcdf-typetools/liblcdf/bezier.cc b/Build/source/texk/lcdf-typetools/liblcdf/bezier.cc index 54402c90276..4d874695052 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/bezier.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/bezier.cc @@ -235,23 +235,23 @@ generate_bezier(const Point *d, int nd, const Vector<double> ¶meters, 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]; @@ -277,7 +277,7 @@ 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; @@ -334,12 +334,12 @@ fit0(const Point *d, int nd, Point left_tangent, Point 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); @@ -347,7 +347,7 @@ fit0(const Point *d, int nd, Point left_tangent, Point right_tangent, 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++) { @@ -359,7 +359,7 @@ fit0(const Point *d, int nd, Point left_tangent, Point right_tangent, 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); diff --git a/Build/source/texk/lcdf-typetools/liblcdf/clp.c b/Build/source/texk/lcdf-typetools/liblcdf/clp.c index 83321e01c29..11ca85e16da 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/clp.c +++ b/Build/source/texk/lcdf-typetools/liblcdf/clp.c @@ -170,10 +170,10 @@ typedef struct Clp_Internal { Clp_InternOption *iopt; int nopt; unsigned opt_generation; - + Clp_ValType *valtype; int nvaltype; - + const char * const *argv; int argc; @@ -182,22 +182,22 @@ typedef struct Clp_Internal { 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; @@ -206,7 +206,7 @@ typedef struct Clp_Internal { struct Clp_ParserState { const char * const *argv; int argc; - + char option_chars[Clp_OptionCharsSize]; const char *xtext; @@ -226,10 +226,10 @@ typedef struct Clp_StringList { Clp_Option *items; Clp_InternOption *iopt; int nitems; - + int allow_int; int nitems_invalid_report; - + } Clp_StringList; @@ -379,13 +379,13 @@ compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1, { 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); @@ -479,13 +479,13 @@ Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *op 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], '/'); @@ -512,19 +512,19 @@ Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *op if (!cli->valtype) goto failed; 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); @@ -547,9 +547,9 @@ Clp_DeleteParser(Clp_Parser *clp) 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) { @@ -558,7 +558,7 @@ Clp_DeleteParser(Clp_Parser *clp) free(clsl->iopt); free(clsl); } - + free(cli->valtype); free(cli->iopt); free(cli); @@ -720,7 +720,7 @@ Clp_SetOptionChar(Clp_Parser *clp, int c, int type) &cli->opt[j], &cli->iopt[j]); } } - + return old; } @@ -772,7 +772,7 @@ Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt) 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 */ @@ -792,7 +792,7 @@ Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt) 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; @@ -844,7 +844,7 @@ 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; @@ -886,7 +886,7 @@ argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes) 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 @@ -898,7 +898,7 @@ argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes) const char *refstart = ref; const char *argstart = arg; assert(min_match > 0); - + compare: while (*ref && *arg && *arg != '=' && *ref == *arg) ref++, arg++; @@ -908,7 +908,7 @@ argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes) ref++; goto compare; } - + if (*arg && *arg != '=') return 0; else if (ref - refstart < min_match) @@ -936,7 +936,7 @@ find_prefix_opt(Clp_Parser *clp, const char *arg, 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)) @@ -956,7 +956,7 @@ find_prefix_opt(Clp_Parser *clp, const char *arg, fewer_dashes = 1; goto retry; } - + return -1; } @@ -1018,12 +1018,12 @@ Clp_AddType(Clp_Parser *clp, int val_type, int flags, { 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 = @@ -1120,11 +1120,11 @@ parse_bool(Clp_Parser *clp, const char *arg, int complain, void *user_data) (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) { @@ -1136,7 +1136,7 @@ parse_bool(Clp_Parser *clp, const char *arg, int complain, void *user_data) clp->val.i = 0; return 1; } - + error: if (complain) Clp_OptionError(clp, "%`%O%' expects a true-or-false value, not %`%s%'", arg); @@ -1154,7 +1154,7 @@ parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_dat 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, @@ -1163,12 +1163,12 @@ parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_dat 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 = (ambiguous ? "ambiguous" : "invalid"); if (!ambiguous) { @@ -1193,7 +1193,7 @@ finish_string_list(Clp_Parser *clp, int val_type, int flags, Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nitems); if (!clsl || !iopt) goto error; - + clsl->items = items; clsl->iopt = iopt; clsl->nitems = nitems; @@ -1206,7 +1206,7 @@ finish_string_list(Clp_Parser *clp, int val_type, int flags, 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; @@ -1216,7 +1216,7 @@ finish_string_list(Clp_Parser *clp, int val_type, int flags, 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; @@ -1259,13 +1259,13 @@ 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; @@ -1273,7 +1273,7 @@ Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) if (!name) break; value = va_arg(val, int); - + if (nitems >= itemscap) { Clp_Option *new_items; itemscap *= 2; @@ -1282,7 +1282,7 @@ Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) goto error; items = new_items; } - + items[nitems].long_name = name; items[nitems].option_id = value; items[nitems].flags = 0; @@ -1292,7 +1292,7 @@ Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) va_end(val); if (finish_string_list(clp, val_type, flags, items, nitems, itemscap) >= 0) return 0; - + error: va_end(val); if (items) @@ -1350,14 +1350,14 @@ Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags, 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 { @@ -1537,7 +1537,7 @@ next_argument(Clp_Parser *clp, int want_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? @@ -1554,7 +1554,7 @@ next_argument(Clp_Parser *clp, int want_argument) 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); @@ -1571,31 +1571,31 @@ next_argument(Clp_Parser *clp, int want_argument) 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. */ @@ -1605,25 +1605,25 @@ next_argument(Clp_Parser *clp, int want_argument) 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. */ @@ -1631,7 +1631,7 @@ next_argument(Clp_Parser *clp, int want_argument) 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 */ @@ -1639,23 +1639,23 @@ next_argument(Clp_Parser *clp, int want_argument) goto not_option; set_option_text(cli, text, 0); break; - + case Clp_DoubledLong: set_option_text(cli, text, ocharskip); break; - - not_option: + + 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; } @@ -1685,14 +1685,14 @@ find_long(Clp_Parser *clp, const char *arg) 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. :) */ @@ -1706,7 +1706,7 @@ find_long(Clp_Parser *clp, const char *arg) if (optno >= 0) goto worked; } - + /* No valid option was found; return 0. Mark the ambiguous values found through '--no' by making them negative. */ { @@ -1716,7 +1716,7 @@ find_long(Clp_Parser *clp, const char *arg) cli->ambiguous_values[i] = -cli->ambiguous_values[i] - 1; } return -1; - + worked: iopt = &cli->iopt[optno]; lmm = (clp->negated ? iopt->lmmneg : iopt->lmmpos); @@ -1747,12 +1747,12 @@ find_short(Clp_Parser *clp, const char *text) 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; } @@ -1807,23 +1807,23 @@ Clp_Next(Clp_Parser *clp) 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; return clp->have_val ? Clp_NotOption : Clp_Done; } - + 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) { @@ -1855,12 +1855,12 @@ Clp_Next(Clp_Parser *clp) return 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)) { @@ -1870,7 +1870,7 @@ Clp_Next(Clp_Parser *clp) } else return cli->opt[optno].option_id; } - + /* Get an argument if we need one, or if it's optional */ /* Sanity-check the argument type. */ opt = &cli->opt[optno]; @@ -1879,12 +1879,12 @@ Clp_Next(Clp_Parser *clp) vtpos = val_type_binsearch(cli, opt->val_type); if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != opt->val_type) return 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 @@ -1900,13 +1900,13 @@ Clp_Next(Clp_Parser *clp) Clp_OptionError(clp, "%`%O%' requires an argument"); return 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); - + /* Parse the argument */ if (clp->have_val) { Clp_ValType *atr = &cli->valtype[vtpos]; @@ -1919,7 +1919,7 @@ Clp_Next(Clp_Parser *clp) Clp_RestoreParser(clp, &clpsave); } } - + return opt->option_id; } @@ -2023,7 +2023,7 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, Clp_Internal *cli = clp->internal; const char *percent; int c; - + if (!bs) bs = new_build_string(); if (!bs) @@ -2032,11 +2032,11 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, 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) @@ -2077,7 +2077,7 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, } } break; - + case 'd': { int d = va_arg(val, int); if (ENSURE_BUILD_STRING(bs, 32)) { @@ -2086,7 +2086,7 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, } break; } - + case 'O': { int optno = cli->current_option; const Clp_Option *opt = &cli->opt[optno]; @@ -2110,7 +2110,7 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, } break; } - + case '%': if (ENSURE_BUILD_STRING(bs, 1)) *bs->pos++ = '%'; @@ -2119,25 +2119,25 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, case '`': append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1); break; - + 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; } diff --git a/Build/source/texk/lcdf-typetools/liblcdf/error.cc b/Build/source/texk/lcdf-typetools/liblcdf/error.cc index 2602f460bca..dea40b63fd6 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/error.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/error.cc @@ -1,10 +1,11 @@ -// -*- c-basic-offset: 2; related-file-name: "../include/lcdf/error.hh" -*- +// -*- 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-2006 Eddie Kohler + * Copyright (c) 2001-2008 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"), @@ -28,738 +29,1030 @@ #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; - ConversionHook hook; - Conversion *next; + String name; + ConversionFunction hook; + Conversion *next; }; static ErrorHandler::Conversion *error_items; -const int ErrorHandler::OK_RESULT = 0; -const int ErrorHandler::ERROR_RESULT = -EINVAL; +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>"; -int -ErrorHandler::min_verbosity() const -{ - return 0; -} +const int ErrorHandler::ok_result = 0; +const int ErrorHandler::error_result = -EINVAL; -void -ErrorHandler::debug(const char *format, ...) -{ - va_list val; - va_start(val, format); - verror(ERR_DEBUG, String(), format, val); - va_end(val); -} +ErrorHandler *ErrorHandler::the_default_handler = 0; +ErrorHandler *ErrorHandler::the_silent_handler = 0; -void -ErrorHandler::message(const char *format, ...) -{ - va_list val; - va_start(val, format); - verror(ERR_MESSAGE, String(), format, val); - va_end(val); -} -int -ErrorHandler::warning(const char *format, ...) -{ - va_list val; - va_start(val, format); - verror(ERR_WARNING, String(), format, val); - va_end(val); - return ERROR_RESULT; -} +// ANNOTATION MANAGEMENT -int -ErrorHandler::error(const char *format, ...) +static const char * +parse_level(const char *begin, const char *end, int *result) { - va_list val; - va_start(val, format); - verror(ERR_ERROR, String(), format, val); - va_end(val); - return ERROR_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; } -int -ErrorHandler::fatal(const char *format, ...) +String +ErrorHandler::make_anno(const char *name, const String &value) { - va_list val; - va_start(val, format); - verror(ERR_FATAL, String(), format, val); - va_end(val); - return ERROR_RESULT; -} + 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(); + } -int -ErrorHandler::fatal(int exit_status, const char *format, ...) -{ - assert(exit_status >= 0 && exit_status < 0x1000); - va_list val; - va_start(val, format); - verror((Seriousness) (ERR_MIN_FATAL + (exit_status << ERRVERBOSITY_SHIFT)), String(), format, val); - va_end(val); - return ERROR_RESULT; + 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(); } -void -ErrorHandler::ldebug(const String &where, const char *format, ...) +const char * +ErrorHandler::skip_anno(const String &str, const char *begin, const char *end, + String *name_result, String *value_result, bool raw) { - va_list val; - va_start(val, format); - verror(ERR_DEBUG, where, format, val); - va_end(val); -} + 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; + } + } + } -void -ErrorHandler::lmessage(const String &where, const char *format, ...) -{ - va_list val; - va_start(val, format); - verror(ERR_MESSAGE, where, format, val); - va_end(val); + if (name_result) + *name_result = name; + if (value_result) + *value_result = value; + return begin; } -int -ErrorHandler::lwarning(const String &where, const char *format, ...) +const char * +ErrorHandler::parse_anno(const String &str, const char *begin, const char *end, + ...) { - va_list val; - va_start(val, format); - verror(ERR_WARNING, where, format, val); - va_end(val); - return ERROR_RESULT; -} + 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; + } -int -ErrorHandler::lerror(const String &where, const char *format, ...) -{ - va_list val; - va_start(val, format); - verror(ERR_ERROR, where, format, val); - va_end(val); - return ERROR_RESULT; -} + 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; + } + } -int -ErrorHandler::lfatal(const String &where, const char *format, ...) -{ - va_list val; - va_start(val, format); - verror(ERR_FATAL, where, format, val); - va_end(val); - return ERROR_RESULT; + return begin; } -int -ErrorHandler::lfatal(int exit_status, const String &where, const char *format, ...) +String +ErrorHandler::combine_anno(const String &text, const String &anno) { - assert(exit_status >= 0 && exit_status < 0x1000); - va_list val; - va_start(val, format); - verror((Seriousness) (ERR_MIN_FATAL + (exit_status << ERRVERBOSITY_SHIFT)), where, format, val); - va_end(val); - return ERROR_RESULT; + 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::make_text(Seriousness seriousness, const char *format, ...) +ErrorHandler::clean_landmark(const String &landmark, bool with_colon) { - va_list val; - va_start(val, format); - String s = make_text(seriousness, format, val); - va_end(val); - return s; + 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::UPPERCASE) ? "0123456789ABCDEF" : "0123456789abcdef"); - char *pos = after_last; - while (num) { - *--pos = digits[num % base]; - num /= base; - } - if (pos == after_last) - *--pos = '0'; - return pos; + 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 ALTERNATE_FORM for zero results in base 16 - if ((flags & ErrH::ALTERNATE_FORM) && base == 16 && *pos == '0') - flags &= ~ErrH::ALTERNATE_FORM; - - // account for zero padding - if (precision >= 0) - while (after_last - pos < precision) - *--pos = '0'; - else if (flags & ErrH::ZERO_PAD) { - if ((flags & ErrH::ALTERNATE_FORM) && base == 16) - field_width -= 2; - if ((flags & ErrH::NEGATIVE) - || (flags & (ErrH::PLUS_POSITIVE | ErrH::SPACE_POSITIVE))) - field_width--; - while (after_last - pos < field_width) - *--pos = '0'; - } - - // alternate forms - if ((flags & ErrH::ALTERNATE_FORM) && base == 8 && pos[1] != '0') - *--pos = '0'; - else if ((flags & ErrH::ALTERNATE_FORM) && base == 16) { - *--pos = ((flags & ErrH::UPPERCASE) ? 'X' : 'x'); - *--pos = '0'; - } - - // sign - if (flags & ErrH::NEGATIVE) - *--pos = '-'; - else if (flags & ErrH::PLUS_POSITIVE) - *--pos = '+'; - else if (flags & ErrH::SPACE_POSITIVE) - *--pos = ' '; - - return pos; + // 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::make_text(Seriousness seriousness, const char *s, va_list val) -{ - StringAccum msg; - - char numbuf[NUMBUF_SIZE]; // for numerics - numbuf[NUMBUF_SIZE-1] = 0; - - String placeholder; // to ensure temporaries aren't destroyed - - // prepend 'warning: ' to every line if appropriate - String begin_lines; - if (seriousness >= ERR_MIN_WARNING && seriousness < ERR_MIN_ERROR) { - begin_lines = String::stable_string("warning: ", 9); - msg << begin_lines; - } - - // 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, '%'); - - // handle begin_lines - const char *nl; - while (begin_lines && (nl = strchr(s, '\n')) && (!pct || nl < pct)) { - msg.append(s, nl + 1 - s); - if (nl[1]) - msg.append(begin_lines.data(), begin_lines.length()); - s = nl + 1; - } - - if (!pct) { - if (*s) - msg << s; - break; - } - if (pct != s) { - msg.append(s, pct - s); - s = pct; - } - - // parse flags - flags = 0; - flags: - switch (*++s) { - case '#': flags |= ALTERNATE_FORM; goto flags; - case '0': flags |= ZERO_PAD; goto flags; - case '-': flags |= LEFT_JUST; goto flags; - case ' ': flags |= SPACE_POSITIVE; goto flags; - case '+': flags |= PLUS_POSITIVE; 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 |= 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': - width_flag = 'h'; s++; goto width_flags; - case 'l': - width_flag = (width_flag == 'l' ? 'q' : 'l'); s++; goto width_flags; - case 'L': case 'q': - width_flag = 'q'; s++; goto width_flags; - } - - // 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)"; - if (flags & ALTERNATE_FORM) { - placeholder = String(s1).printable(); - s1 = placeholder.c_str(); - } - for (s2 = s1; *s2 && precision != 0; s2++) - if (precision > 0) - precision--; - 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 'd': - case 'i': - flags |= 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; -#ifdef HAVE_INT64_TYPES - if (width_flag == 'q') { - uint64_t qnum = va_arg(val, uint64_t); - if ((flags & SIGNED) && (int64_t)qnum < 0) - qnum = -(int64_t)qnum, flags |= NEGATIVE; - String q = cp_unparse_unsigned64(qnum, base, flags & UPPERCASE); - s1 = s2 - q.length(); - memcpy((char *)s1, q.data(), q.length()); - goto got_number; - } +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)"; + + // transform string, fetch length + int len; + if (flags & cf_alternate_form) { + strstore = String(s1).printable(); + len = strstore.length(); + } else + len = strlen(s1); + + // adjust length for precision + if (precision >= 0 && precision < len) + len = precision; + + // 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::uint_large_t>(qnum), base, (flags & cf_uppercase)); + s1 = s2 - sa.length(); + memcpy(const_cast<char*>(s1), sa.data(), s2 - s1); + goto got_number; + } #endif - if (width_flag == 'h') { - num = (unsigned short)va_arg(val, int); - if ((flags & SIGNED) && (short)num < 0) - num = -(short)num, flags |= NEGATIVE; - } else if (width_flag == 'l') { - num = va_arg(val, unsigned long); - if ((flags & SIGNED) && (long)num < 0) - num = -(long)num, flags |= NEGATIVE; - } else { - num = va_arg(val, unsigned int); - if ((flags & SIGNED) && (int)num < 0) - num = -(int)num, flags |= NEGATIVE; - } - s1 = do_number(num, (char *)s2, base, flags); - -#ifdef HAVE_INT64_TYPES - got_number: + 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 |= UPPERCASE; - case 'x': - base = 16; - goto number; - - case 'p': { - 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 | ALTERNATE_FORM, - precision, field_width); - break; - } + 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': { + 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 & 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 & ~ALTERNATE_FORM, -1, field_width); - break; - } + 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 '{': { - const char *rbrace = strchr(s, '}'); - if (!rbrace || rbrace == s) - assert(0 /* Bad %{ in error */); - String name(s, rbrace - s); - s = rbrace + 1; - for (Conversion *item = error_items; item; item = item->next) - if (item->name == name) { - placeholder = item->hook(flags, VA_LIST_REF(val)); - s1 = placeholder.data(); - s2 = s1 + placeholder.length(); - goto got_result; - } - assert(0 /* Bad %{ in error */); - break; - } - - 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 & LEFT_JUST) { - memcpy(dest, s1, slen); - memset(dest + slen, ' ', field_width - slen); - } else { - memcpy(dest + field_width - slen, s1, slen); - memset(dest, (flags & ZERO_PAD ? '0' : ' '), field_width - slen); + case '{': { + const char *rbrace = strchr(s, '}'); + if (!rbrace || rbrace == s) + assert(0 /* Bad %{ in error */); + String name(s, rbrace - s); + s = rbrace + 1; + for (Conversion *item = error_items; item; item = item->next) + if (item->name == name) { + 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(); + return msg.take_string(); } String -ErrorHandler::decorate_text(Seriousness, const String &landmark, const String &text) -{ - String new_text = text; - - // handle landmark - if (landmark - && !(landmark.length() > 2 && landmark[0] == '\\' - && landmark.back() == '\\')) { - // ignore special-purpose landmarks (begin and end with a backslash `\') - // fix landmark: skip trailing spaces and trailing colon - int i, len = landmark.length(); - for (i = len - 1; i >= 0; i--) - if (!isspace((unsigned char) landmark[i])) - break; - if (i >= 0 && landmark[i] == ':') - i--; - - // prepend landmark, unless all spaces - if (i >= 0) - new_text = prepend_lines(landmark.substring(0, i+1) + ": ", new_text); - } - - return new_text; +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; } -int -ErrorHandler::verror(Seriousness seriousness, const String &where, - const char *s, va_list val) +String +ErrorHandler::xformat(const char *fmt, ...) { - String text = make_text(seriousness, s, val); - text = decorate_text(seriousness, where, text); - handle_text(seriousness, text); - return count_error(seriousness, text); + va_list val; + va_start(val, fmt); + String s = vxformat(0, fmt, val); + va_end(val); + return s; } -int -ErrorHandler::verror_text(Seriousness seriousness, const String &where, - const String &text) +String +ErrorHandler::format(const char *fmt, ...) { - // text is already made - String dec_text = decorate_text(seriousness, where, text); - handle_text(seriousness, dec_text); - return count_error(seriousness, dec_text); + va_list val; + va_start(val, fmt); + String s = vformat(fmt, val); + va_end(val); + return s; } + +// ERROR MESSAGE SHORTHAND + void -ErrorHandler::set_error_code(int) +ErrorHandler::debug(const char *fmt, ...) { + va_list val; + va_start(val, fmt); + vxmessage(String::make_stable(e_debug, 3), fmt, val); + va_end(val); } -String -ErrorHandler::prepend_lines(const String &prepend, const String &text) -{ - if (!prepend) - return text; - - StringAccum sa; - const char *begin = text.begin(); - const char *end = text.end(); - while (begin < end) { - const char *nl = std::find(begin, end, '\n'); - if (nl < end) - nl++; - sa << prepend << text.substring(begin, nl); - begin = nl; - } - - return sa.take_string(); +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); } - -// -// BASE ERROR HANDLER -// - int -BaseErrorHandler::count_error(Seriousness seriousness, const String &) +ErrorHandler::warning(const char *fmt, ...) { - if (seriousness < ERR_MIN_WARNING) - /* do nothing */; - else if (seriousness < ERR_MIN_ERROR) - _nwarnings++; - else - _nerrors++; - return (seriousness < ERR_MIN_WARNING ? OK_RESULT : ERROR_RESULT); + 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; +} -#ifndef __KERNEL__ -// -// FILE ERROR HANDLER -// - -FileErrorHandler::FileErrorHandler(FILE *f, const String &context) - : _f(f), _context(context) +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 -FileErrorHandler::handle_text(Seriousness seriousness, const String &message) -{ - String text = prepend_lines(_context, message); - if (text && text.back() != '\n') - text += '\n'; - fwrite(text.data(), 1, text.length(), _f); - - if (seriousness >= ERR_MIN_FATAL) { - int exit_status = (seriousness - ERR_MIN_FATAL) >> ERRVERBOSITY_SHIFT; - exit(exit_status); - } +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); } -#endif - - -// -// SILENT ERROR HANDLER -// void -SilentErrorHandler::handle_text(Seriousness, const String &) +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; +} -// -// STATIC ERROR HANDLERS -// - -static ErrorHandler *the_default_handler = 0; -static ErrorHandler *the_ignore_handler = 0; +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; +} -ErrorHandler::Conversion * -ErrorHandler::add_conversion(const String &name, ConversionHook hook) -{ - if (Conversion *c = new Conversion) { - c->name = name; - c->hook = hook; - c->next = error_items; - error_items = c; - return c; - } else - return 0; +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::remove_conversion(ErrorHandler::Conversion *conv) +ErrorHandler::xmessage(const String &str) { - 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; + 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); } - return -1; + + account(min_level); + + return (min_level <= el_warning ? error_result : ok_result); } -ErrorHandler * -ErrorHandler::static_initialize(ErrorHandler *default_handler) +String +ErrorHandler::vformat(const char *fmt, va_list val) { - the_default_handler = default_handler; - return the_default_handler; + return vxformat(0, fmt, val); } -void -ErrorHandler::static_cleanup() +String +ErrorHandler::decorate(const String &str) { - delete the_default_handler; - delete the_ignore_handler; - the_default_handler = the_ignore_handler = 0; - while (error_items) { - Conversion *next = error_items->next; - delete error_items; - error_items = next; - } + return str; } -bool -ErrorHandler::has_default_handler() +void * +ErrorHandler::emit(const String &, void *user_data, bool) { - return the_default_handler ? true : false; + return user_data; } -ErrorHandler * -ErrorHandler::default_handler() + +#ifndef __KERNEL__ +// +// FILE ERROR HANDLER +// + +FileErrorHandler::FileErrorHandler(FILE *f, const String &context) + : _f(f), _context(context), _default_flags(0) { - assert(the_default_handler != 0); - return the_default_handler; +# 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 } -ErrorHandler * -ErrorHandler::ignore_handler() +String +FileErrorHandler::vformat(const char *fmt, va_list val) { - if (!the_ignore_handler) - the_ignore_handler = new SilentErrorHandler; - return the_ignore_handler; + 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'; + (void) fwrite(sa.begin(), 1, sa.length(), _f); + return 0; } void -ErrorHandler::set_default_handler(ErrorHandler *errh) +FileErrorHandler::account(int level) { - the_default_handler = errh; + ErrorHandler::account(level); + if (level <= el_abort) + abort(); + else if (level <= el_fatal) + exit(-level); } +#endif + // -// ERROR VENEER +// STATIC ERROR HANDLERS // -int -ErrorVeneer::nwarnings() const +ErrorHandler::Conversion * +ErrorHandler::add_conversion(const String &name, ConversionFunction function) { - return _errh->nwarnings(); + if (Conversion *c = new Conversion) { + c->name = name; + c->hook = function; + c->next = error_items; + error_items = c; + return c; + } else + return 0; } int -ErrorVeneer::nerrors() const +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() { - return _errh->nerrors(); + 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 -ErrorVeneer::reset_counts() +ErrorHandler::set_default_handler(ErrorHandler *errh) { - _errh->reset_counts(); + the_default_handler = errh; } + +// +// ERROR VENEER +// + String -ErrorVeneer::make_text(Seriousness seriousness, const char *s, va_list val) +ErrorVeneer::vformat(const char *fmt, va_list val) { - return _errh->make_text(seriousness, s, val); + if (_errh) + return _errh->vformat(fmt, val); + else + return ErrorHandler::vformat(fmt, val); } String -ErrorVeneer::decorate_text(Seriousness seriousness, const String &landmark, const String &text) +ErrorVeneer::decorate(const String &str) { - return _errh->decorate_text(seriousness, landmark, text); + if (_errh) + return _errh->decorate(str); + else + return ErrorHandler::decorate(str); } -void -ErrorVeneer::handle_text(Seriousness seriousness, const String &text) +void * +ErrorVeneer::emit(const String &str, void *user_data, bool more) { - _errh->handle_text(seriousness, text); + if (_errh) + return _errh->emit(str, user_data, more); + else + return ErrorHandler::emit(str, user_data, more); } -int -ErrorVeneer::count_error(Seriousness seriousness, const String &text) +void +ErrorVeneer::account(int level) { - return _errh->count_error(seriousness, text); + ErrorHandler::account(level); + if (_errh) + _errh->account(level); } @@ -767,32 +1060,44 @@ ErrorVeneer::count_error(Seriousness seriousness, const String &text) // CONTEXT ERROR HANDLER // -ContextErrorHandler::ContextErrorHandler(ErrorHandler *errh, - const String &context, - const String &indent, - const String &context_landmark) - : ErrorVeneer(errh), _context(context), _indent(indent), - _context_landmark(context_landmark) +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_text(Seriousness seriousness, const String &landmark, const String &text) -{ - String context_lines; - if (_context) { - // do not print context or indent if underlying ErrorHandler doesn't want - // context - if (_errh->min_verbosity() > ERRVERBOSITY_CONTEXT) - _context = _indent = String(); - else { - context_lines = _errh->decorate_text(ERR_MESSAGE, (_context_landmark ? _context_landmark : landmark), _context); - if (context_lines && context_lines.back() != '\n') - context_lines += '\n'; - _context = String(); - } - } - return context_lines + _errh->decorate_text(seriousness, (landmark ? landmark : _context_landmark), prepend_lines(_indent, text)); +ContextErrorHandler::decorate(const String &str) +{ + String cstr = ErrorVeneer::decorate(str), context_anno; + const char *cstr_endanno = parse_anno(cstr, cstr.begin(), cstr.end(), + "context", &context_anno, + (const char *) 0); + if (context_anno.equals("no", 2)) + return cstr; + + String icstr; + if (context_anno.equals("noindent", 8)) + icstr = combine_anno(cstr, _context_landmark); + else + icstr = combine_anno(cstr, _context_landmark + _indent); + + if (!_context_printed && !context_anno.equals("nocontext", 9)) { + String astr = combine_anno(combine_anno(_context, _context_landmark), + cstr.substring(cstr.begin(), cstr_endanno)); + if (astr && astr.back() != '\n') + astr += '\n'; + _context_printed = true; + return ErrorVeneer::decorate(astr) + icstr; + } else + return icstr; } @@ -802,14 +1107,14 @@ ContextErrorHandler::decorate_text(Seriousness seriousness, const String &landma PrefixErrorHandler::PrefixErrorHandler(ErrorHandler *errh, const String &prefix) - : ErrorVeneer(errh), _prefix(prefix) + : ErrorVeneer(errh), _prefix(prefix) { } String -PrefixErrorHandler::decorate_text(Seriousness seriousness, const String &landmark, const String &text) +PrefixErrorHandler::decorate(const String &str) { - return _errh->decorate_text(seriousness, landmark, prepend_lines(_prefix, text)); + return ErrorVeneer::decorate(combine_anno(str, _prefix)); } @@ -818,41 +1123,14 @@ PrefixErrorHandler::decorate_text(Seriousness seriousness, const String &landmar // LandmarkErrorHandler::LandmarkErrorHandler(ErrorHandler *errh, const String &landmark) - : ErrorVeneer(errh), _landmark(landmark) + : ErrorVeneer(errh), _landmark(make_landmark_anno(landmark)) { } String -LandmarkErrorHandler::decorate_text(Seriousness seriousness, const String &lm, const String &text) -{ - if (lm) - return _errh->decorate_text(seriousness, lm, text); - else - return _errh->decorate_text(seriousness, _landmark, text); -} - - -// -// VERBOSE FILTER ERROR HANDLER -// - -VerboseFilterErrorHandler::VerboseFilterErrorHandler(ErrorHandler *errh, int min_verbosity) - : ErrorVeneer(errh), _min_verbosity(min_verbosity) -{ -} - -int -VerboseFilterErrorHandler::min_verbosity() const -{ - int m = _errh->min_verbosity(); - return (m >= _min_verbosity ? m : _min_verbosity); -} - -void -VerboseFilterErrorHandler::handle_text(Seriousness s, const String &text) +LandmarkErrorHandler::decorate(const String &str) { - if ((s & ERRVERBOSITY_MASK) >= _min_verbosity) - _errh->handle_text(s, text); + return ErrorVeneer::decorate(combine_anno(str, _landmark)); } @@ -862,17 +1140,17 @@ VerboseFilterErrorHandler::handle_text(Seriousness s, const String &text) #ifndef __KERNEL__ -BailErrorHandler::BailErrorHandler(ErrorHandler *errh, Seriousness s) - : ErrorVeneer(errh), _exit_seriousness(s) +BailErrorHandler::BailErrorHandler(ErrorHandler *errh, int l) + : ErrorVeneer(errh), _level(l) { } void -BailErrorHandler::handle_text(Seriousness s, const String &text) +BailErrorHandler::account(int level) { - _errh->handle_text(s, text); - if (s >= _exit_seriousness) - exit(1); + ErrorVeneer::account(level); + if (level <= _level) + exit(1); } #endif diff --git a/Build/source/texk/lcdf-typetools/liblcdf/filename.cc b/Build/source/texk/lcdf-typetools/liblcdf/filename.cc index fcd8e89029a..dd603088b05 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/filename.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/filename.cc @@ -69,7 +69,7 @@ Filename::Filename(const String &dir, const String &name) _dir += name.substring(0, slash + 1); _name = name.substring(slash + 1); } - + _path = _dir + _name; } diff --git a/Build/source/texk/lcdf-typetools/liblcdf/globmatch.cc b/Build/source/texk/lcdf-typetools/liblcdf/globmatch.cc index 023a8f2a4ca..33b59521ecf 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/globmatch.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/globmatch.cc @@ -67,7 +67,7 @@ glob_match(const String& str, const String& pattern) 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++) { @@ -95,7 +95,7 @@ glob_match(const String& str, const String& pattern) spos++; ppos++; break; - + } done: diff --git a/Build/source/texk/lcdf-typetools/liblcdf/md5.c b/Build/source/texk/lcdf-typetools/liblcdf/md5.c index ecacfadd3bc..d2373dc6120 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/md5.c +++ b/Build/source/texk/lcdf-typetools/liblcdf/md5.c @@ -118,7 +118,7 @@ transform(MD5_CONTEXT *ctx, const unsigned char *data) #define OP(a, b, c, d, s, T) \ do { \ - a += FF (b, c, d) + (*cwp++) + T; \ + a += FF (b, c, d) + (*cwp++) + T; \ a = rol(a, s); \ a += b; \ } while (0) @@ -152,7 +152,7 @@ transform(MD5_CONTEXT *ctx, const unsigned char *data) do { \ a += f (b, c, d) + correct_words[k] + T; \ a = rol(a, s); \ - a += b; \ + a += b; \ } while (0) /* Round 2. */ diff --git a/Build/source/texk/lcdf-typetools/liblcdf/permstr.cc b/Build/source/texk/lcdf-typetools/liblcdf/permstr.cc index 4d6744215c3..b7c1eb52d97 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/permstr.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/permstr.cc @@ -115,7 +115,7 @@ PermString::initialize(const char* s, int length) if (length < 0) length = (s ? strlen(s) : 0); - + if (length == 0) { _rep = zero_char_doodad.data; return; @@ -144,7 +144,7 @@ PermString::initialize(const char* s, int length) buck->length = length; memcpy(buck->data, s, length); buck->data[length] = 0; - + _rep = buck->data; } @@ -287,11 +287,11 @@ vpermprintf(const char *s, va_list val) goto pctdone; } - + pctdone: s++; } - + return PermString(psc, pspos); } diff --git a/Build/source/texk/lcdf-typetools/liblcdf/slurper.cc b/Build/source/texk/lcdf-typetools/liblcdf/slurper.cc index 54905b8bdbd..ec09e76a147 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/slurper.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/slurper.cc @@ -58,7 +58,7 @@ Slurper::grow_buffer() _len -= _pos; _pos = 0; } - + // Grow the buffer if necessary. if (_len >= _cap) { unsigned char *new_data = new unsigned char[ 2 * _cap ]; @@ -75,7 +75,7 @@ inline int Slurper::more_data() { grow_buffer(); - + // Read new data into the buffer. int amount = fread(_data + _len, 1, _cap - _len, _f); _len += amount; @@ -89,7 +89,7 @@ Slurper::get_line_at(unsigned pos) 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; @@ -100,12 +100,12 @@ Slurper::get_line_at(unsigned pos) 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; @@ -118,10 +118,10 @@ Slurper::get_line_at(unsigned pos) 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 @@ -138,12 +138,12 @@ Slurper::get_line_at(unsigned pos) else next_pos = pos + 1; } - + _line = _data + _pos; _line_len = pos - _pos; _data[pos] = 0; _pos = next_pos; - _lineno++; + _lineno++; return (char *)_line; } @@ -180,7 +180,7 @@ Slurper::append_next_line() _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/liblcdf/straccum.cc b/Build/source/texk/lcdf-typetools/liblcdf/straccum.cc index 9c9217358b5..78f8d217493 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/straccum.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/straccum.cc @@ -4,7 +4,7 @@ * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology - * Copyright (c) 2001-2006 Eddie Kohler + * Copyright (c) 2001-2008 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,63 +26,75 @@ #include <stdio.h> #include <ctype.h> -StringAccum::StringAccum(const char *s) - : _s(0), _len(0), _cap(0) -{ - *this << s; -} +/** @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" string. + * Out-of-memory strings are contagious: the result of any concatenation + * operation involving an out-of-memory string is another out-of-memory + * string. Calling take_string() on an out-of-memory StringAccum returns an + * out-of-memory String. + * + * Out-of-memory StringAccum objects nominally have zero characters. + */ -StringAccum::StringAccum(const String &s) - : _s(0), _len(0), _cap(0) +void +StringAccum::assign_out_of_memory() { - *this << s; + assert(_cap >= 0); + delete[] _s; + _s = reinterpret_cast<unsigned char *>(const_cast<char *>(String::out_of_memory_data())); + _cap = -1; + _len = 0; } -#ifdef HAVE_PERMSTRING -StringAccum::StringAccum(PermString s) - : _s(0), _len(0), _cap(0) +bool +StringAccum::grow(int want) { - *this << s; -} -#endif + // can't append to out-of-memory strings + if (_cap < 0) + return false; -void -StringAccum::make_out_of_memory() -{ - assert(_cap >= 0); - delete[] _s; - _s = reinterpret_cast<unsigned char *>(const_cast<char *>(String::out_of_memory_data())); - _cap = -1; - _len = 0; + int ncap = (_cap ? _cap * 2 : 128); + while (ncap <= want) + ncap *= 2; + + unsigned char *n = new unsigned char[ncap]; + if (!n) { + assign_out_of_memory(); + return false; + } + + if (_s) + memcpy(n, _s, _cap); + delete[] _s; + _s = n; + _cap = ncap; + return true; } -bool -StringAccum::grow(int want) +void +StringAccum::append_fill(int c, int len) { - // can't append to out-of-memory strings - if (_cap < 0) - return false; - - int ncap = (_cap ? _cap * 2 : 128); - while (ncap <= want) - ncap *= 2; - - unsigned char *n = new unsigned char[ncap]; - if (!n) { - make_out_of_memory(); - return false; - } - - if (_s) - memcpy(n, _s, _cap); - delete[] _s; - _s = n; - _cap = ncap; - return true; + if (char *s = extend(len)) + memset(s, c, len); } void -StringAccum::append_utf8_hard(uint32_t ch) +StringAccum::append_utf8_hard(unsigned ch) { if (ch < 0x80) append((unsigned char) ch); @@ -110,65 +122,96 @@ StringAccum::c_str() return reinterpret_cast<char *>(_s); } +void +StringAccum::append_unsafe_data(const char *s, int len) +{ + char *copy = new char[len]; + memcpy(copy, s, len); + append_safe_data(copy, len); + delete[] copy; +} + String StringAccum::take_string() { int len = length(); - if (len) { - int capacity = _cap; - return String::claim_string(reinterpret_cast<char *>(take_bytes()), len, capacity); - } else if (out_of_memory()) - return String::out_of_memory_string(); - else + 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.forward(len); + 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.forward(len); - } - return sa; + 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.forward(len); - } - return sa; + 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)) { -#ifdef HAVE_VSNPRINTF - int len = vsnprintf(x, n + 1, format, val); + 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); + int len = vsprintf(x, format, val); + assert(len <= n); #endif - forward(len); - } - va_end(val); - return *this; + adjust_length(len); + } + va_end(val); + return *this; } void diff --git a/Build/source/texk/lcdf-typetools/liblcdf/string.cc b/Build/source/texk/lcdf-typetools/liblcdf/string.cc index 9f3c27e07c6..6ba05536f25 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/string.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/string.cc @@ -4,7 +4,8 @@ * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology - * Copyright (c) 2001-2006 Eddie Kohler + * Copyright (c) 2001-2008 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"), @@ -27,102 +28,158 @@ #include <ctype.h> #include <lcdf/inttypes.h> -static String::Initializer initializer; -String::Memo *String::null_memo = 0; -String::Memo *String::permanent_memo = 0; -String::Memo *String::oom_memo = 0; -String *String::null_string_p = 0; -String *String::oom_string_p = 0; -const char String::oom_string_data = 0; - -inline -String::Memo::Memo() - : _refcount(0), _capacity(0), _dirty(0), _real_data("") -{ -} +/** @file string.hh + * @brief The LCDF String class. + */ -inline -String::Memo::Memo(char *data, int dirty, int capacity) - : _refcount(0), _capacity(capacity), _dirty(dirty), - _real_data(data) -{ -} +/** @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>Initialization</h3> + * + * The String implementation must be explicitly initialized before use; see + * static_initialize(). Explicit initialization is used because static + * constructors and other automatic initialization tricks don't work in the + * kernel. However, at user level, you can declare a String::Initializer + * object to initialize the library. + * + * <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. + */ -String::Memo::Memo(int dirty, int capacity) - : _refcount(1), _capacity(capacity), _dirty(dirty), - _real_data(new char[capacity]) -{ - assert(_capacity >= _dirty); +const char String::null_string_data = 0; +const char String::oom_string_data = 0; +const char String::bool_data[] = "true\0false"; + +String::memo_t String::null_memo = { + 2, 0, 0, const_cast<char *>(&null_string_data) +}; +String::memo_t String::permanent_memo = { + 1, 0, 0, const_cast<char *>(&null_string_data) +}; +String::memo_t String::oom_memo = { + 2, 0, 0, const_cast<char *>(&oom_string_data) +}; + +const String::rep_t String::null_string_rep = { + &null_string_data, 0, &null_memo +}; +const String::rep_t String::oom_string_rep = { + &oom_string_data, 0, &oom_memo +}; + +/** @cond never */ +String::memo_t * +String::create_memo(char *data, int dirty, int capacity) +{ + assert(capacity >= dirty); + memo_t *memo = new memo_t; + if (memo) { + if (data) + memo->real_data = data; + else if (!(memo->real_data = new char[capacity])) { + delete memo; + return 0; + } + memo->capacity = capacity; + memo->dirty = dirty; + memo->refcount = (data ? 0 : 1); + } + return memo; } -String::Memo::~Memo() +void +String::delete_memo(memo_t *memo) { - if (_capacity) { - assert(_capacity >= _dirty); - delete[] _real_data; + if (memo->capacity) { + assert(memo->capacity >= memo->dirty); + delete[] memo->real_data; } + delete memo; } +/** @endcond never */ String::String(int i) { char buf[128]; sprintf(buf, "%d", i); - assign(buf, -1); + assign(buf, -1, false); } String::String(unsigned u) { char buf[128]; sprintf(buf, "%u", u); - assign(buf, -1); + assign(buf, -1, false); } -String::String(long d) +String::String(long i) { char buf[128]; - sprintf(buf, "%ld", d); - assign(buf, -1); + sprintf(buf, "%ld", i); + assign(buf, -1, false); } String::String(unsigned long u) { char buf[128]; sprintf(buf, "%lu", u); - assign(buf, -1); + assign(buf, -1, false); } String::String(double d) { char buf[128]; - sprintf(buf, "%.12g", d); - assign(buf, -1); + int len = sprintf(buf, "%.12g", d); + assign(buf, len, false); } String -String::claim_string(char *str, int len, int capacity) +String::make_claim(char *str, int len, int capacity) { assert(str && len > 0 && capacity >= len); - Memo *new_memo = new Memo(str, len, capacity); - if (new_memo) + if (memo_t *new_memo = create_memo(str, len, capacity)) return String(str, len, new_memo); else - return String(oom_memo->_real_data, 0, oom_memo); + return String(&oom_string_data, 0, &oom_memo); } String -String::stable_string(const char *str, int len) +String::make_stable(const char *s, int len) { if (len < 0) - len = (str ? strlen(str) : 0); + len = (s ? strlen(s) : 0); if (len == 0) return String(); else - return String(str, len, permanent_memo); + return String(s, len, &permanent_memo); } String -String::garbage_string(int len) +String::make_garbage(int len) { String s; s.append_garbage(len); @@ -130,7 +187,7 @@ String::garbage_string(int len) } String -String::fill_string(int c, int len) +String::make_fill(int c, int len) { String s; s.append_fill(c, len); @@ -138,111 +195,134 @@ String::fill_string(int c, int len) } void -String::make_out_of_memory() +String::assign_out_of_memory() { - if (_memo) + if (_r.memo) deref(); - _memo = oom_memo; - _memo->_refcount++; - _data = _memo->_real_data; - _length = 0; + _r.memo = &oom_memo; + _r.data = _r.memo->real_data; + _r.length = 0; + ++_r.memo->refcount; } void -String::assign(const char *str, int len) +String::assign(const char *str, int len, bool need_deref) { if (!str) { assert(len <= 0); len = 0; } else if (len < 0) len = strlen(str); - + + // need to start with dereference + if (need_deref) { + if (str >= _r.memo->real_data + && str + len <= _r.memo->real_data + _r.memo->capacity) { + // Be careful about "String s = ...; s = s.c_str();" + _r.data = str; + _r.length = len; + return; + } else + deref(); + } + if (len == 0) { - _memo = (str == oom_memo->_real_data ? oom_memo : null_memo); - _memo->_refcount++; - + _r.memo = (str == &oom_string_data ? &oom_memo : &null_memo); + ++_r.memo->refcount; + } else { - // Make 'capacity' a multiple of 16 characters at least as big as - // 'len'. + // Make 'capacity' a multiple of 16 characters and bigger than 'len'. int capacity = (len + 16) & ~15; - _memo = new Memo(len, capacity); - if (!_memo || !_memo->_real_data) { - make_out_of_memory(); + _r.memo = create_memo(0, len, capacity); + if (!_r.memo) { + assign_out_of_memory(); return; } - memcpy(_memo->_real_data, str, len); + memcpy(_r.memo->real_data, str, len); } - - _data = _memo->_real_data; - _length = len; + + _r.data = _r.memo->real_data; + _r.length = len; } char * -String::append_garbage(int suffix_len) +String::append_garbage(int len) { // Appending anything to "out of memory" leaves it as "out of memory" - if (suffix_len <= 0 || _memo == oom_memo) + if (len <= 0 || _r.memo == &oom_memo) return 0; - + // If we can, append into unused space. First, we check that there's - // enough unused space for `suffix_len' characters to fit; then, we check - // that the unused space immediately follows the data in `*this'. - if (_memo->_capacity > _memo->_dirty + suffix_len) { - char *real_dirty = _memo->_real_data + _memo->_dirty; - if (real_dirty == _data + _length) { - _length += suffix_len; - _memo->_dirty += suffix_len; - assert(_memo->_dirty < _memo->_capacity); + // enough unused space for 'len' characters to fit; then, we check + // that the unused space immediately follows the data in '*this'. + uint32_t dirty = _r.memo->dirty; + if (_r.memo->capacity > dirty + len) { + char *real_dirty = _r.memo->real_data + dirty; + if (real_dirty == _r.data + _r.length) { + _r.length += len; + _r.memo->dirty = dirty + len; + assert(_r.memo->dirty < _r.memo->capacity); return real_dirty; } } - + // Now we have to make new space. Make sure the new capacity is a - // multiple of 16 characters and that it is at least 16. - int new_capacity = (_length + 16) & ~15; - while (new_capacity < _length + suffix_len) + // multiple of 16 characters 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 new_capacity = (_r.length + len < 1024 ? (_r.length + 16) & ~15 : 1024); + while (new_capacity < _r.length + len) new_capacity *= 2; - Memo *new_memo = new Memo(_length + suffix_len, new_capacity); - if (!new_memo || !new_memo->_real_data) { - delete new_memo; - make_out_of_memory(); + + memo_t *new_memo = create_memo(0, _r.length + len, new_capacity); + if (!new_memo) { + assign_out_of_memory(); return 0; } - char *new_data = new_memo->_real_data; - memcpy(new_data, _data, _length); - + char *new_data = new_memo->real_data; + memcpy(new_data, _r.data, _r.length); + deref(); - _data = new_data; - new_data += _length; // now new_data points to the garbage - _length += suffix_len; - _memo = new_memo; + _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 *suffix, int suffix_len) +String::append(const char *s, int len) { - if (!suffix) { - assert(suffix_len <= 0); - suffix_len = 0; - } else if (suffix_len < 0) - suffix_len = strlen(suffix); + if (!s) { + assert(len <= 0); + len = 0; + } else if (len < 0) + len = strlen(s); - if (char *space = append_garbage(suffix_len)) - memcpy(space, suffix, suffix_len); - else if (suffix == oom_memo->_real_data) + if (s == &oom_string_data) // Appending "out of memory" to a regular string makes it "out of // memory" - make_out_of_memory(); + assign_out_of_memory(); + else if (len == 0) + /* do nothing */; + else if (!(s >= _r.memo->real_data + && s + len <= _r.memo->real_data + _r.memo->capacity)) { + if (char *space = append_garbage(len)) + memcpy(space, s, len); + } else { + String preserve_s(*this); + if (char *space = append_garbage(len)) + memcpy(space, s, len); + } } void -String::append_fill(int c, int suffix_len) +String::append_fill(int c, int len) { - assert(suffix_len >= 0); - if (char *space = append_garbage(suffix_len)) - memset(space, c, suffix_len); + assert(len >= 0); + if (char *space = append_garbage(len)) + memset(space, c, len); } char * @@ -250,15 +330,15 @@ 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 (_memo->_capacity && _memo->_refcount == 1) - return const_cast<char *>(_data); - + if (_r.memo->capacity && _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(!_memo->_capacity || _memo->_refcount > 1); + assert(!_r.memo->capacity || _r.memo->refcount > 1); deref(); - assign(_data, _length); - return const_cast<char *>(_data); + assign(_r.data, _r.length, false); + return const_cast<char *>(_r.data); } char * @@ -266,7 +346,7 @@ String::mutable_c_str() { (void) mutable_data(); (void) c_str(); - return const_cast<char *>(_data); + return const_cast<char *>(_r.data); } const char * @@ -276,94 +356,107 @@ String::c_str() const // or PermString). We are guaranteed, in these strings, that // _data[_length] exists. We can return _data immediately if we have a // '\0' in the right place. - if (!_memo->_capacity && _data[_length] == '\0') - return _data; - + if (!_r.memo->capacity && _r.data[_r.length] == '\0') + return _r.data; + // Otherwise, this invariant must hold (there's more real data in _memo // than in our substring). - assert(!_memo->_capacity - || _memo->_real_data + _memo->_dirty >= _data + _length); - + assert(!_r.memo->capacity + || _r.memo->real_data + _r.memo->dirty >= _r.data + _r.length); + // Has the character after our substring been set? - if (_memo->_real_data + _memo->_dirty == _data + _length) { - // Character after our substring has not been set. May be able to - // change it to '\0'. This case will never occur on special strings. - if (_memo->_dirty < _memo->_capacity) - goto add_final_nul; - + uint32_t dirty = _r.memo->dirty; + if (_r.memo->real_data + dirty == _r.data + _r.length) { + if (_r.memo->capacity > dirty) { + _r.memo->dirty = dirty + 1; + // Character after our substring has not been set. Change it to + // '\0'. This case will never occur on special strings. + char *real_data = const_cast<char *>(_r.data); + real_data[_r.length] = '\0'; + return _r.data; + } + } else { // Character after our substring has been set. OK to return _data if // it is already '\0'. - if (_data[_length] == '\0') - return _data; + if (_r.data[_r.length] == '\0') + return _r.data; } - + // If we get here, we must make a copy of our portion of the string. { - String s(_data, _length); + String s(_r.data, _r.length); deref(); assign(s); } - - add_final_nul: - char *real_data = const_cast<char *>(_data); - real_data[_length] = '\0'; - _memo->_dirty++; // include '\0' in used portion of _memo - return _data; + + char *real_data = const_cast<char *>(_r.data); + real_data[_r.length] = '\0'; + ++_r.memo->dirty; // include '\0' in used portion of _memo + return _r.data; } String -String::substring(int left, int len) const +String::substring(int pos, int len) const { - if (left < 0) - left += _length; + if (pos < 0) + pos += _r.length; + + int pos2; if (len < 0) - len = _length - left + len; - if (left + len > _length) - len = _length - left; - - if (left < 0 || 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(_data + left, len, _memo); + return String(_r.data + pos, pos2 - pos, _r.memo); } int -String::find_left(int c, int start) const +String::find_left(char c, int start) const { - if (start < 0) - start = 0; - for (int i = start; i < _length; i++) - if ((unsigned char)_data[i] == c) - return i; - return -1; + 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 &s, int start) const +String::find_left(const String &str, int start) const { if (start < 0) start = 0; if (start >= length()) return -1; - if (!s.length()) + if (!str.length()) return 0; - int first_c = (unsigned char)s[0]; - int pos = start, max_pos = length() - s.length(); + int first_c = (unsigned char)str[0]; + int pos = start, max_pos = length() - str.length(); for (pos = find_left(first_c, pos); pos >= 0 && pos <= max_pos; pos = find_left(first_c, pos + 1)) - if (!memcmp(_data + pos, s._data, s.length())) + if (!memcmp(_r.data + pos, str._r.data, str.length())) return pos; return -1; } int -String::find_right(int c, int start) const +String::find_right(char c, int start) const { - if (start >= _length) - start = _length - 1; + if (start >= _r.length) + start = _r.length - 1; for (int i = start; i >= 0; i--) - if ((unsigned char)_data[i] == c) + if (_r.data[i] == c) return i; return -1; } @@ -383,8 +476,8 @@ String String::lower() const { // avoid copies - for (int i = 0; i < _length; i++) - if (_data[i] >= 'A' && _data[i] <= 'Z') + for (int i = 0; i < _r.length; i++) + if (_r.data[i] >= 'A' && _r.data[i] <= 'Z') return hard_lower(*this, i); return *this; } @@ -404,8 +497,8 @@ String String::upper() const { // avoid copies - for (int i = 0; i < _length; i++) - if (_data[i] >= 'a' && _data[i] <= 'z') + for (int i = 0; i < _r.length; i++) + if (_r.data[i] >= 'a' && _r.data[i] <= 'z') return hard_upper(*this, i); return *this; } @@ -432,43 +525,143 @@ String String::printable() const { // avoid copies - for (int i = 0; i < _length; i++) - if (_data[i] < 32 || _data[i] > 126) + for (int i = 0; i < _r.length; i++) + if (_r.data[i] < 32 || _r.data[i] > 126) return hard_printable(*this, i); return *this; } -unsigned -hashcode(const String &s) +uint32_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 !__i386__ +# define get16(p) (((unsigned char) (p)[0] << 8) + (unsigned char) (p)[1]) +# else +# define get16(p) ((unsigned char) (p)[0] + ((unsigned char) (p)[1] << 8)) +# 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. +size_t +String::hashcode() const { - int length = s.length(); - const char *data = s.data(); - if (!length) + int l = length(); + const char *d = data(); + if (!l) return 0; - else if (length == 1) - return data[0] | (data[0] << 8); - else if (length < 4) - return data[0] + (data[1] << 3) + (length << 12); + else if (l == 1) + return d[0] | (d[0] << 8); + else if (l < 4) + return d[0] + (d[1] << 3) + (l << 12); else - return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24) - + (length << 12) + (data[length-1] << 10); + 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 { - // I would like to make "out-of-memory" strings compare unequal to - // anything, even themseleves, but this would be a bad idea for Strings + // 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 (_length != len) + if (_r.length != len) return false; + else if (_r.data == s) + return true; else if (len == 0) - return (_data == s || (s != oom_memo->_real_data && _memo != oom_memo)); + return (s != &oom_string_data && _r.memo != &oom_memo); else - return (_data == s || memcmp(_data, s, len) == 0); + 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_string_data && _r.memo != &oom_memo); + else + return memcmp(_r.data, s, len) == 0; } int @@ -476,15 +669,19 @@ String::compare(const char *s, int len) const { if (len < 0) len = strlen(s); - if (_data == s && _length == len) - return 0; - if (_length == len) - return memcmp(_data, s, len); - else if (_length < len) { - int v = memcmp(_data, s, _length); + if (_r.data == s) + return _r.length - len; + else if (_r.memo == &oom_memo) + return 1; + else if (s == &oom_string_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(_data, s, len); + int v = memcmp(_r.data, s, len); return (v ? v : 1); } } @@ -492,57 +689,14 @@ String::compare(const char *s, int len) const void String::align(int n) { - int offset = reinterpret_cast<uintptr_t>(_data) % n; + int offset = reinterpret_cast<uintptr_t>(_r.data) % n; if (offset) { String s; - s.append_garbage(_length + n + 1); - offset = reinterpret_cast<uintptr_t>(s._data) % n; - memcpy((char *)s._data + n - offset, _data, _length); - s._data += n - offset; - s._length = _length; + s.append_garbage(_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; } } - - -String::Initializer::Initializer() -{ - String::static_initialize(); -} - -void -String::static_initialize() -{ - // function called to initialize static globals - if (!null_memo) { - null_memo = new Memo; - null_memo->_refcount++; - permanent_memo = new Memo; - permanent_memo->_refcount++; - // use a separate string for oom_memo's data, so we can distinguish - // the pointer - oom_memo = new Memo; - oom_memo->_refcount++; - oom_memo->_real_data = const_cast<char*>(&oom_string_data); - null_string_p = new String; - oom_string_p = new String(oom_memo->_real_data, 0, oom_memo); - } -} - -void -String::static_cleanup() -{ - if (null_string_p) { - delete null_string_p; - null_string_p = 0; - delete oom_string_p; - oom_string_p = 0; - if (--null_memo->_refcount == 0) - delete null_memo; - if (--permanent_memo->_refcount == 0) - delete permanent_memo; - if (--oom_memo->_refcount == 0) - delete oom_memo; - null_memo = permanent_memo = oom_memo = 0; - } -} diff --git a/Build/source/texk/lcdf-typetools/liblcdf/transform.cc b/Build/source/texk/lcdf-typetools/liblcdf/transform.cc index b59da9de99a..d8b58a02d08 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/transform.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/transform.cc @@ -76,11 +76,11 @@ 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; diff --git a/Build/source/texk/lcdf-typetools/liblcdf/vectorv.cc b/Build/source/texk/lcdf-typetools/liblcdf/vectorv.cc index 26dc1a05a66..f5f12b52c90 100644 --- a/Build/source/texk/lcdf-typetools/liblcdf/vectorv.cc +++ b/Build/source/texk/lcdf-typetools/liblcdf/vectorv.cc @@ -60,14 +60,14 @@ Vector<void*>::reserve(int want) 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; |