summaryrefslogtreecommitdiff
path: root/Build/source/texk/lcdf-typetools/liblcdf
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2009-03-20 09:50:07 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2009-03-20 09:50:07 +0000
commit82150b6fc41b8a3446f2c6020ddf5625956dd708 (patch)
tree9234f85d00b9fd322b0986b62f09e355449190e6 /Build/source/texk/lcdf-typetools/liblcdf
parent6b3b122ab7e6994e0b4c8d1299eb2c3462388542 (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.am8
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/Makefile.in134
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/bezier.cc18
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/clp.c202
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/error.cc1580
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/filename.cc2
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/globmatch.cc4
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/md5.c4
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/permstr.cc8
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/slurper.cc22
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/straccum.cc191
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/string.cc630
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/transform.cc4
-rw-r--r--Build/source/texk/lcdf-typetools/liblcdf/vectorv.cc6
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> &parameters,
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;