diff options
author | Karl Berry <karl@freefriends.org> | 2009-04-13 00:08:16 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-04-13 00:08:16 +0000 |
commit | e0bf193d67d722a044f7ab3efa98854757d619c4 (patch) | |
tree | effb1e008f9baf040415173587f7723dbbc5f325 /Build/source/texk/lcdf-typetools/t1lint | |
parent | c87c5680a97ea7d5458d6ae7c95bc83c60c912a0 (diff) |
lcdf-typetools 2.78
git-svn-id: svn://tug.org/texlive/trunk@12708 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/lcdf-typetools/t1lint')
-rw-r--r-- | Build/source/texk/lcdf-typetools/t1lint/Makefile.in | 10 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/t1lint/cscheck.cc | 140 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/t1lint/cscheck.hh | 84 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/t1lint/t1lint.1 | 2 | ||||
-rw-r--r-- | Build/source/texk/lcdf-typetools/t1lint/t1lint.cc | 28 |
5 files changed, 212 insertions, 52 deletions
diff --git a/Build/source/texk/lcdf-typetools/t1lint/Makefile.in b/Build/source/texk/lcdf-typetools/t1lint/Makefile.in index cfd04901fab..8e1a1cf297b 100644 --- a/Build/source/texk/lcdf-typetools/t1lint/Makefile.in +++ b/Build/source/texk/lcdf-typetools/t1lint/Makefile.in @@ -317,11 +317,11 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -install-man1: $(man_MANS) +install-man1: $(man1_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list=''; \ - l2='$(man_MANS)'; \ + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ @@ -343,8 +343,8 @@ install-man1: $(man_MANS) done uninstall-man1: @$(NORMAL_UNINSTALL) - @list=''; \ - l2='$(man_MANS)'; \ + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ diff --git a/Build/source/texk/lcdf-typetools/t1lint/cscheck.cc b/Build/source/texk/lcdf-typetools/t1lint/cscheck.cc index 78183a927a6..6413df5abfa 100644 --- a/Build/source/texk/lcdf-typetools/t1lint/cscheck.cc +++ b/Build/source/texk/lcdf-typetools/t1lint/cscheck.cc @@ -1,6 +1,6 @@ /* cscheck.{cc,hh} -- checking Type 1 charstrings for validity * - * Copyright (c) 1999-2006 Eddie Kohler + * Copyright (c) 1999-2009 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -21,8 +21,9 @@ using namespace Efont; -#define CHECK_STACK(numargs) do { if (size() < numargs) return error(errUnderflow, cmd); } while (0) -#define CHECK_STACK_CP(numargs) do { CHECK_STACK(numargs); if (!_cp_exists) return error(errCurrentPoint, cmd); } while (0) +#define CHECK_STACK_GE(numargs) do { if (size() < numargs) return error(errUnderflow, cmd); } while (0) +#define CHECK_STACK_EQ(numargs) do { CHECK_STACK_GE(numargs); if (size() > numargs) _errh->warning("too many arguments to %<%s%> (have %d, expected %d)", Charstring::command_name(cmd).c_str(), size(), numargs); } while (0) +#define CHECK_STACK_CPEQ(numargs) do { CHECK_STACK_EQ(numargs); if (!_cp_exists) return error(errCurrentPoint, cmd); } while (0) CharstringChecker::CharstringChecker() @@ -80,10 +81,10 @@ CharstringChecker::check_stem3(const char *cmd_name) i2 = 4; // check constraints. count "almost equal" as equal - double stemw1 = hints[i0+1] - hints[i0]; + double stemw0 = hints[i0+1] - hints[i0]; double stemw2 = hints[i2+1] - hints[i2]; - if ((int)(1024*(stemw1 - stemw2) + .5) != 0) - _errh->error("bad %<%s%>: extreme stem widths unequal (%g, %g)", cmd_name, stemw1, stemw2); + if ((int)(1024*(stemw0 - stemw2) + .5) != 0) + _errh->error("bad %<%s%>: extreme stem widths unequal (%g, %g)", cmd_name, stemw0, stemw2); double c0 = (hints[i0] + hints[i0+1])/2; double c1 = (hints[i1] + hints[i1+1])/2; @@ -154,9 +155,14 @@ CharstringChecker::callothersubr() _errh->error("wrong number of arguments to Flex"); goto unknown; } - if (!_flex || ps_size() != 16) { - _errh->error("bad Flex"); - return false; + if (!_flex) { + _errh->error("no Flex in progress"); + pop(3); + return false; + } else if (ps_size() != 16) { + _errh->error("Flex needs 16 arguments, have %d", ps_size()); + pop(3); + return false; } //_connect = _flex_connect; #if 0 @@ -240,16 +246,22 @@ CharstringChecker::callothersubr() bool CharstringChecker::type1_command(int cmd) { - if (cmd == Cs::cCallsubr) - return callsubr_command(); - else if (cmd == Cs::cCallothersubr) { - CHECK_STACK(2); - return callothersubr(); - } else if (cmd == Cs::cReturn) { - return false; - } else if (cmd == Cs::cPop || cmd == Cs::cDiv) { - return arith_command(cmd); - } + if (_subrno < 0) + ++_ncommand; + if (cmd == Cs::cCallsubr) { + int old_subrno = _subrno; + _subrno = (size() > 1 ? (int) top(0) : -300); + bool result = callsubr_command(); + _subrno = old_subrno; + return result; + } else if (cmd == Cs::cCallothersubr) { + CHECK_STACK_GE(2); + return callothersubr(); + } else if (cmd == Cs::cReturn) { + return false; + } else if (cmd == Cs::cPop || cmd == Cs::cDiv) { + return arith_command(cmd); + } if (cmd != Cs::cHsbw && cmd != Cs::cSbw) { if (!_started) @@ -263,13 +275,13 @@ CharstringChecker::type1_command(int cmd) switch (cmd) { case Cs::cHsbw: - CHECK_STACK(2); + CHECK_STACK_EQ(2); moveto(at(0), 0, false); clear(); break; case Cs::cSbw: - CHECK_STACK(4); + CHECK_STACK_EQ(4); moveto(at(0), at(1), false); clear(); break; @@ -280,61 +292,61 @@ CharstringChecker::type1_command(int cmd) break; case Cs::cHlineto: - CHECK_STACK_CP(1); + CHECK_STACK_CPEQ(1); rlineto(at(0), 0); clear(); break; case Cs::cHmoveto: - CHECK_STACK(1); + CHECK_STACK_EQ(1); rmoveto(at(0), 0); clear(); break; case Cs::cHvcurveto: - CHECK_STACK_CP(4); + CHECK_STACK_CPEQ(4); rrcurveto(at(0), 0, at(1), at(2), 0, at(3)); clear(); break; case Cs::cRlineto: - CHECK_STACK_CP(2); + CHECK_STACK_CPEQ(2); rlineto(at(0), at(1)); clear(); break; case Cs::cRmoveto: - CHECK_STACK(2); + CHECK_STACK_EQ(2); rmoveto(at(0), at(1)); clear(); break; case Cs::cRrcurveto: - CHECK_STACK_CP(6); + CHECK_STACK_CPEQ(6); rrcurveto(at(0), at(1), at(2), at(3), at(4), at(5)); clear(); break; case Cs::cVhcurveto: - CHECK_STACK_CP(4); + CHECK_STACK_CPEQ(4); rrcurveto(0, at(0), at(1), at(2), at(3), 0); clear(); break; case Cs::cVlineto: - CHECK_STACK_CP(1); + CHECK_STACK_CPEQ(1); rlineto(0, at(0)); clear(); break; case Cs::cVmoveto: - CHECK_STACK(1); + CHECK_STACK_EQ(1); rmoveto(0, at(0)); clear(); break; case Cs::cHstem: - CHECK_STACK(2); + CHECK_STACK_EQ(2); if (_hstem3 && !_hstem) _errh->error("charstring has both %<hstem%> and %<hstem3%>"); _hstem = true; @@ -343,7 +355,7 @@ CharstringChecker::type1_command(int cmd) break; case Cs::cVstem: - CHECK_STACK(2); + CHECK_STACK_EQ(2); if (_vstem3 && !_vstem) _errh->error("charstring has both %<vstem%> and %<vstem3%>"); _vstem = true; @@ -359,7 +371,7 @@ CharstringChecker::type1_command(int cmd) break; case Cs::cVstem3: - CHECK_STACK(6); + CHECK_STACK_EQ(6); if (_vstem && !_vstem3) _errh->error("charstring has both %<vstem%> and %<vstem3%>"); _vstem3 = true; @@ -372,7 +384,7 @@ CharstringChecker::type1_command(int cmd) break; case Cs::cHstem3: - CHECK_STACK(6); + CHECK_STACK_EQ(6); if (_hstem && !_hstem3) _errh->error("charstring has both %<hstem%> and %<hstem3%>"); _hstem3 = true; @@ -385,7 +397,7 @@ CharstringChecker::type1_command(int cmd) break; case Cs::cSeac: { - CHECK_STACK(5); + CHECK_STACK_EQ(5); #if 0 double asb = at(0); double adx = at(1); @@ -422,7 +434,7 @@ CharstringChecker::type1_command(int cmd) } case Cs::cSetcurrentpoint: - CHECK_STACK(2); + CHECK_STACK_EQ(2); _cp = Point(at(0), at(1)); _cp_exists = true; clear(); @@ -445,7 +457,8 @@ CharstringChecker::type1_command(int cmd) bool CharstringChecker::check(const CharstringContext &g, ErrorHandler *errh) { - _errh = errh; + CharstringCheckerErrorHandler<CharstringChecker> merrh(errh, this); + _errh = &merrh; int old_errors = errh->nerrors(); _started = false; @@ -455,8 +468,61 @@ CharstringChecker::check(const CharstringContext &g, ErrorHandler *errh) _h_vstem.clear(); _h_hstem3.clear(); _h_vstem3.clear(); + _ncommand = 0; + _subrno = -1; + + CharstringInterp::interpret(g); + + return errh->nerrors() == old_errors; +} + + + +CharstringSubrChecker::CharstringSubrChecker() + : CharstringInterp(), _errh(0) +{ + set_careful(true); +} + +CharstringSubrChecker::CharstringSubrChecker(const Vector<double> &weight) + : CharstringInterp(weight), _errh(0) +{ + set_careful(true); +} + +bool +CharstringSubrChecker::error(int error, int data) +{ + CharstringInterp::error(error, data); + _errh->error("%s", error_string().c_str()); + return false; +} + +bool +CharstringSubrChecker::type1_command(int cmd) +{ + switch (cmd) { + case Cs::cReturn: + _returned = true; + return false; + default: + clear(); + return true; + } +} + +bool +CharstringSubrChecker::check(const CharstringContext &g, ErrorHandler *errh) +{ + CharstringCheckerErrorHandler<CharstringSubrChecker> merrh(errh, this); + _errh = &merrh; + int old_errors = errh->nerrors(); + + _returned = false; CharstringInterp::interpret(g); + if (!_returned) + _errh->error("subroutine does not return"); return errh->nerrors() == old_errors; } diff --git a/Build/source/texk/lcdf-typetools/t1lint/cscheck.hh b/Build/source/texk/lcdf-typetools/t1lint/cscheck.hh index 9563e27fa62..9ba167b1588 100644 --- a/Build/source/texk/lcdf-typetools/t1lint/cscheck.hh +++ b/Build/source/texk/lcdf-typetools/t1lint/cscheck.hh @@ -3,7 +3,24 @@ #include <efont/t1interp.hh> #include <lcdf/point.hh> #include <lcdf/vector.hh> -class ErrorHandler; +#include <lcdf/error.hh> +#include <lcdf/straccum.hh> +#include <ctype.h> + +template <typename T> +class CharstringCheckerErrorHandler : public ErrorVeneer { public: + + CharstringCheckerErrorHandler(ErrorHandler *errh, T *checker) + : ErrorVeneer(errh), _checker(checker) { + } + + String decorate(const String &str); + + private: + + T *_checker; + +}; class CharstringChecker : public Efont::CharstringInterp { public: @@ -16,9 +33,18 @@ class CharstringChecker : public Efont::CharstringInterp { public: bool check(const Efont::CharstringContext &, ErrorHandler *); + int ncommand() const { + return _ncommand; + } + int subrno() const { + return _subrno; + } + private: ErrorHandler *_errh; + int _ncommand; + int _subrno; Point _cp; @@ -49,4 +75,60 @@ class CharstringChecker : public Efont::CharstringInterp { public: }; +class CharstringSubrChecker : public Efont::CharstringInterp { public: + + CharstringSubrChecker(); + CharstringSubrChecker(const Vector<double> &weight_vec); + + bool error(int, int); + bool type1_command(int); + + bool check(const Efont::CharstringContext &, ErrorHandler *); + + int ncommand() const { + return -1; + } + int subrno() const { + return -1; + } + + private: + + ErrorHandler *_errh; + + bool _returned; + +}; + + +template <typename T> String +CharstringCheckerErrorHandler<T>::decorate(const String &str) +{ + StringAccum sa; + const char *s = skip_anno(str.begin(), str.end()); + while (s < str.end() && isspace((unsigned char) *s)) + ++s; + sa.append(str.begin(), s); + if (_checker->subrno() >= 0) + sa << "called from "; + if (_checker->ncommand() >= 0) + sa << "command " << (_checker->ncommand() - 1) << ':'; + if (sa) + sa << ' '; + if (s + 11 < str.end() && memcmp(s, "charstring ", 11) == 0) { + bool quote_parity = 0; + const char *last = s + 11; + for (const char *x = last; x != str.end(); ++x) + if (*x == '\'') { + sa.append(last, x); + sa << format(quote_parity ? "%>" : "%<"); + quote_parity = !quote_parity; + last = x + 1; + } + sa.append(last, str.end()); + } else + sa.append(s, str.end()); + return ErrorVeneer::decorate(sa.take_string()); +} + #endif diff --git a/Build/source/texk/lcdf-typetools/t1lint/t1lint.1 b/Build/source/texk/lcdf-typetools/t1lint/t1lint.1 index 36bedc100f7..16aaf20f506 100644 --- a/Build/source/texk/lcdf-typetools/t1lint/t1lint.1 +++ b/Build/source/texk/lcdf-typetools/t1lint/t1lint.1 @@ -1,4 +1,4 @@ -.ds V 2.75 +.ds V 2.78 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/texk/lcdf-typetools/t1lint/t1lint.cc b/Build/source/texk/lcdf-typetools/t1lint/t1lint.cc index 336eda27457..a6448608135 100644 --- a/Build/source/texk/lcdf-typetools/t1lint/t1lint.cc +++ b/Build/source/texk/lcdf-typetools/t1lint/t1lint.cc @@ -293,7 +293,8 @@ check_stems(Type1Font *font, ErrorHandler *errh) // MAIN static void -do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) +do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh, + ErrorHandler *err_errh) { FILE *f; if (strcmp(filename, "-") == 0) { @@ -312,13 +313,13 @@ do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) } if (!f) - errh->fatal("%s: %s", filename, strerror(errno)); + err_errh->fatal("%s: %s", filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) - errh->fatal("%s: empty file", filename); + err_errh->fatal("%s: empty file", filename); if (c == 128) reader = new Type1PFBReader(f); else @@ -368,6 +369,15 @@ do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) (&cerrh, "While interpreting %<%s%>:", font->glyph_name(i).c_str()); cc.check(font->glyph_context(i), &derrh); } + + int ns = font->nsubrs(); + CharstringSubrChecker csc(weight_vector); + for (int i = 0; i < ns; ++i) + if (Type1Charstring *cs = font->subr(i)) { + ContextErrorHandler derrh(&cerrh, "While interpreting subr %d:", i); + CharstringContext cctx(font, cs); + csc.check(cctx, &derrh); + } } delete font; @@ -384,7 +394,9 @@ main(int argc, char *argv[]) Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); - ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); + ErrorHandler *err_errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); + ErrorHandler *out_errh = new FileErrorHandler(stdout); + ErrorHandler *errh = out_errh; int nfiles = 0; while (1) { @@ -393,7 +405,7 @@ main(int argc, char *argv[]) case QUIET_OPT: if (clp->negated) - errh = ErrorHandler::default_handler(); + errh = out_errh; else errh = new SilentErrorHandler; break; @@ -413,7 +425,7 @@ particular purpose.\n"); break; case Clp_NotOption: - do_file(clp->vstr, psres, errh); + do_file(clp->vstr, psres, errh, err_errh); nfiles++; break; @@ -421,7 +433,7 @@ particular purpose.\n"); goto done; case Clp_BadOption: - usage_error(errh, 0); + usage_error(err_errh, 0); break; default: @@ -432,7 +444,7 @@ particular purpose.\n"); done: if (nfiles == 0) - do_file("-", psres, errh); + do_file("-", psres, errh, err_errh); return (errh->nerrors() == 0 ? 0 : 1); } |