diff options
Diffstat (limited to 'Build/source/utils/t1utils/t1utils-src')
25 files changed, 1043 insertions, 869 deletions
diff --git a/Build/source/utils/t1utils/t1utils-src/LICENSE b/Build/source/utils/t1utils/t1utils-src/LICENSE new file mode 100644 index 00000000000..82054edc397 --- /dev/null +++ b/Build/source/utils/t1utils/t1utils-src/LICENSE @@ -0,0 +1,30 @@ +Portions of this software are subject to the license below. The relevant +source files are clearly marked; they refer to this file using the phrase +"the Click LICENSE file". This license is an MIT license, plus a clause +(taken from the W3C license) requiring prior written permission to use our +names in publicity. + +=========================================================================== + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +The name and trademarks of copyright holders may NOT be used in advertising +or publicity pertaining to the Software without specific, written prior +permission. Title to copyright in this Software and any associated +documentation will at all times remain with copyright holders. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Build/source/utils/t1utils/t1utils-src/Makefile.am b/Build/source/utils/t1utils/t1utils-src/Makefile.am index bf0d339b582..b2c51eaf93b 100644 --- a/Build/source/utils/t1utils/t1utils-src/Makefile.am +++ b/Build/source/utils/t1utils/t1utils-src/Makefile.am @@ -1,5 +1,5 @@ ## Process this file with automake to produce Makefile.in -AUTOMAKE_OPTIONS = foreign check-news +AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = t1ascii t1binary t1asm t1disasm t1unmac t1mac man_MANS = t1ascii.1 t1binary.1 t1asm.1 t1disasm.1 t1unmac.1 t1mac.1 @@ -20,23 +20,9 @@ t1mac_SOURCES = include/lcdf/clp.h include/lcdf/inttypes.h \ AM_CPPFLAGS = -I$(top_srcdir)/include LDADD = @LIBOBJS@ -EXTRA_DIST = $(man_MANS) t1utils.spec +EXTRA_DIST = $(man_MANS) INSTALL LICENSE README.md NEWS.md versionize: perl -pi -e "s/^\\.ds V.*/.ds V $(VERSION)/;" t1ascii.1 t1binary.1 t1disasm.1 t1asm.1 t1unmac.1 t1mac.1 - perl -pi -e 's/^Version:(\s*).*/Version:$${1}$(VERSION)/; s/$(PACKAGE)-[\w.]+\.tar\.gz/$(PACKAGE)-$(VERSION).tar.gz/;' t1utils.spec - perl -pi -e 's/VERSION [\d.ab]+/VERSION $(VERSION)/;' README -rpm: dist - buildarch=`rpm --showrc | awk '/^build arch/ { print $$4; }'` ; \ - mkdir -p /tmp/rpm-t1u/SOURCES /tmp/rpm-t1u/RPMS/$$buildarch \ - /tmp/rpm-t1u/BUILD ; \ - echo 'include: /usr/lib/rpm/rpmrc' > /tmp/rpm-t1u/rc ; \ - echo 'macrofiles: /usr/lib/rpm/macros:/tmp/rpm-t1u/macros' >> /tmp/rpm-t1u/rc ; \ - echo '%_topdir /tmp/rpm-t1u' > /tmp/rpm-t1u/macros ; \ - cp $(PACKAGE)-$(VERSION).tar.gz /tmp/rpm-t1u/SOURCES ; \ - rpmbuild --rcfile /tmp/rpm-t1u/rc -bb t1utils.spec ; \ - cp /tmp/rpm-t1u/RPMS/$$buildarch/*.rpm . - rm -rf /tmp/rpm-t1u - -.PHONY: srclinks versionize rpm +.PHONY: srclinks versionize diff --git a/Build/source/utils/t1utils/t1utils-src/NEWS b/Build/source/utils/t1utils/t1utils-src/NEWS.md index f3ffbe0bbaf..458b6113182 100644 --- a/Build/source/utils/t1utils/t1utils-src/NEWS +++ b/Build/source/utils/t1utils/t1utils-src/NEWS.md @@ -1,146 +1,157 @@ T1utils NEWS - -Version 1.39 26.Feb.2015 +============ + +## Version 1.41 – 16.Aug.2017 + +* t1asm, t1disasm: More security fixes. + + +## Version 1.40 – 23.Jul.2017 + +* t1disasm: More security fixes reported by Jakub Wilk and Niels Thykier. + + +## Version 1.39 – 26.Feb.2015 * t1disasm: Security fixes for buffer overrun reported by Jakub Wilk and Niels Thykier. - -Version 1.38 29.Sep.2013 + +## Version 1.38 – 29.Sep.2013 * t1disasm: Fix an infinite loop on some fonts reported by Niels Thykier. - -Version 1.37 29.Jun.2011 + +## Version 1.37 – 29.Jun.2011 * t1asm: Use a dynamically allocated buffer to handle huge characters (reported by Werner Lemberg). - -Version 1.36 29.May.2010 + +## Version 1.36 – 29.May.2010 * Several minor cleanups. - -Version 1.35 22.Oct.2009 + +## Version 1.35 – 22.Oct.2009 * Don't use "getline" as a symbol (reported by Karl Berry and C.M. Connelly). - -Version 1.34 1.Mar.2008 -* Add '--enable-multiplatform' (requested by Karl Berry). +## Version 1.34 – 1.Mar.2008 + +* Add `--enable-multiplatform` (requested by Karl Berry). - -Version 1.33 8.Jan.2008 + +## Version 1.33 – 8.Jan.2008 * Several minor cleanups. - -Version 1.32 23.Feb.2004 -* t1disasm: Avoid memory corruption bug (strings passed to eexec_line are +## Version 1.32 – 23.Feb.2004 + +* t1disasm: Avoid memory corruption bug (strings passed to `eexec_line` are not null terminated). Reported by Werner Lemberg. - -Version 1.31 8.Feb.2004 + +## Version 1.31 – 8.Feb.2004 * All: Support fonts where the eexec-encrypted portion is binary, and the first ciphertext byte is 0. Reported by Werner Lemberg. - -Version 1.30 6.Jan.2004 + +## Version 1.30 – 6.Jan.2004 * All: Support fonts, such as those in PostScript files printed by - acroread, where "currentfile eexec" is not followed by a newline. + acroread, where `currentfile eexec` is not followed by a newline. + - -Version 1.29 6.Oct.2003 +## Version 1.29 – 6.Oct.2003 * t1disasm: Support odd fonts where a character is defined on the "/CharStrings" line. Reported by Werner Lemberg. - -Version 1.28 7.Aug.2003 + +## Version 1.28 – 7.Aug.2003 * Address build problems reported by Nelson H.F. Beebe. - -Version 1.27 26.Mar.2003 + +## Version 1.27 – 26.Mar.2003 * t1ascii: Add optional warning when output lines are longer than 255 characters. Requested by Werner Lemberg <wl@gnu.org>. - -Version 1.26 16.Apr.2002 + +## Version 1.26 – 16.Apr.2002 * t1mac: Fix buglet (C++ comment, and temporary file left behind). Reported by Vladimir Volovich <vvv@vsu.ru>. - -Version 1.25 3.Jan.2002 -* t1asm: Beware extra characters after `currentfile closefile'. Reported by +## Version 1.25 – 3.Jan.2002 + +* t1asm: Beware extra characters after `currentfile closefile`. Reported by Luc Devroye <luc@cs.mcgill.ca>. - -Version 1.24 6.Sep.2001 + +## Version 1.24 – 6.Sep.2001 * Fixed compilation bugs on various platforms reported by Nelson H. F. Beebe <beebe@math.utah.edu>. - -Version 1.23 18.Jun.2001 + +## Version 1.23 – 18.Jun.2001 * Fixed Macintosh file bugs: the MacBinary CRC was calculated incorrectly, and extended finder flags were set to random values in BinHex output. Reported, and patch provided, by Tom Kacvinsky <tjk@ams.org>. - -Version 1.22 6.Mar.2001 + +## Version 1.22 – 6.Mar.2001 * Fixed bug on processing PFA fonts with DOS line endings. The symptom was t1binary producing strange/unusable fonts. Problem: the all-zeros line, which signals the end of the font's binary section, was not being - recognized because of an extra '\r'. This has been a bug since version + recognized because of an extra `\r`. This has been a bug since version 1.13 -- chagrin! Problem reported by Han The Thanh <thanh@informatics.muni.cz>. - -Version 1.21 9.Feb.2001 + +## Version 1.21 – 9.Feb.2001 * t1ascii, t1asm, t1unmac: Raised minimum PFA line length to 8. The Adobe spec may imply that there cannot be whitespace within the first 8 bytes of an ASCII-encoded eexec section; it's somewhat ambiguous. Reported by Rainer Menzner <Rainer.Menzner@neuroinformatik.ruhr-uni-bochum.de>. - -Version 1.20 22.Jun.2000 -* t1asm: Fixed bug where `t1asm -a' would give a `warning: line length - raised to 4' error message. Reported by Tom Kacvinsky <tjk@ams.org>. +## Version 1.20 – 22.Jun.2000 + +* t1asm: Fixed bug where `t1asm -a` would give a “warning: line length + raised to 4” error message. Reported by Tom Kacvinsky <tjk@ams.org>. - -Version 1.19 3.May.2000 + +## Version 1.19 – 3.May.2000 * t1mac: Generated Macintosh fonts now use a custom-drawn icon set, rather than Adobe's default. They also have a t1utils-specific creator signature (T1UT), and their file information mentions t1utils. -* t1mac: Added the `--filename' option. +* t1mac: Added the `--filename` option. + - -Version 1.18 2.May.2000 +## Version 1.18 – 2.May.2000 * t1mac: Fixed bug where generated files appeared corrupted to Macintoshes. Reported by Marten Thavenius <marten.thavenius@bahnhof.se>. - -Version 1.17 27.Apr.2000 -* Added new program, `t1mac', which translates PFA or PFB fonts into +## Version 1.17 – 27.Apr.2000 + +* Added new program, `t1mac`, which translates PFA or PFB fonts into Macintosh-style fonts. T1mac can output in MacBinary, AppleSingle, AppleDouble, or BinHex format. Suggested by Marten Thavenius <marten.thavenius@bahnhof.se>. @@ -149,29 +160,29 @@ Version 1.17 27.Apr.2000 * t1unmac: Fixed bugs in manual page and program options. - -Version 1.16 25.Apr.2000 + +## Version 1.16 – 25.Apr.2000 * t1unmac: Supports AppleSingle and AppleDouble files with the - `--applesingle/double' option. Requested by Kent Boortz + `--applesingle/double` option. Requested by Kent Boortz <kent@erix.ericsson.se>. - -Version 1.15 4.Apr.2000 + +## Version 1.15 – 4.Apr.2000 * t1ascii, t1binary, and t1disasm: Fixed bad error message. * t1unmac: Generates PFB fonts by default. - -Version 1.14 25.Aug.1999 + +## Version 1.14 – 25.Aug.1999 * t1asm: Version 1.13 produced complete crap output. My test cases were too limited to catch this. Found by Rainer Menzner <Rainer.Menzner@neuroinformatik.ruhr-uni-bochum.de>. - -Version 1.13 2.Aug.1999 + +## Version 1.13 – 2.Aug.1999 * t1disasm: Complete rewrite. It now uses t1lib.c functions; the goal is to handle PFA and PFB fonts consistently. This has been extensively tested, @@ -185,22 +196,22 @@ Version 1.13 2.Aug.1999 * t1ascii, t1binary, t1disasm: Changes in t1lib.c to support reading binary PFA fonts. Requested by Tom Kacvinsky <tjk@ams.org>. - -Version 1.12 1.Aug.1999 + +## Version 1.12 – 1.Aug.1999 * t1ascii, t1binary, t1asm, t1disasm: Support fonts with whitespace - following the "currentfile eexec" line. Embedded fonts in PostScript + following the `currentfile eexec` line. Embedded fonts in PostScript generated by Acrobat Reader have this property. Reported by Tom Kacvinsky <tjk@ams.org>. * t1ascii, t1asm, t1unmac: Use lowercase hex digits instead of uppercase. -* t1unmac: Added `--line-length' option for PFA output. +* t1unmac: Added `--line-length` option for PFA output. + - -Version 1.11 29.May.1999 +## Version 1.11 – 29.May.1999 -* Bug fix in t1asm/t1disasm: if a `readhexstring' procedure was defined, we +* Bug fix in t1asm/t1disasm: if a `readhexstring` procedure was defined, we got confused. Reported by Luc Devroye <luc@CS.McGill.CA>. * t1binary now has a maximum block length of 2^32 - 1. "Feature" requested @@ -208,40 +219,39 @@ Version 1.11 29.May.1999 * t1ascii and t1binary each accept both PFA and PFB fonts. If you pass an ASCII font (PFA) to t1ascii, it will output it mostly unchanged, and - similarly for PFB fonts and t1binary. The `-l' options will still take - effect, so you can use `t1ascii -l 60' to shorten the encrypted line + similarly for PFB fonts and t1binary. The `-l` options will still take + effect, so you can use `t1ascii -l 60` to shorten the encrypted line lengths of a PFA font. t1ascii also does some newline translation (changes carriage returns to newlines). - -Version 1.10.1 12.Apr.1999 -* t1asm: Fixed bug when `-l' option wasn't provided. Caught by Giuseppe - Ghib <ghibo@caesar.polito.it>. +## Version 1.10.1 – 12.Apr.1999 - -Version 1.10 11.Apr.1999 +* t1asm: Fixed bug when `-l` option wasn't provided. Caught by Giuseppe + Ghibò <ghibo@caesar.polito.it>. + + +## Version 1.10 – 11.Apr.1999 * t1asm/t1disasm: Provide support for Type1C (Compact Font Format) font files. These fonts have unencrypted character strings, signalled by a negative lenIV value. Suggestion and patch thanks to Tom Kacvinsky <tjk@ams.org>. -* t1ascii/t1asm: Added `-l/--line-length' option to control maximum - encrypted line length. Suggestion thanks to Giuseppe Ghib - <ghibo@caesar.polito.it>. +* t1ascii/t1asm: Added `-l/--line-length` option to control maximum encrypted + line length. Suggestion thanks to Giuseppe Ghibò <ghibo@caesar.polito.it>. + - -Version 1.9 14.Feb.1999 +## Version 1.9 – 14.Feb.1999 * t1asm/t1disasm: Be more robust on fonts that don't end in `mark - currentfile closefile'. John Vromans <JVromans@squirrel.nl> provided a - font that ended with `mark' on one line and `currentfile closefile' on + currentfile closefile`. John Vromans <JVromans@squirrel.nl> provided a + font that ended with `mark` on one line and `currentfile closefile` on another; t1asm and t1disasm did not recognize the encrypted section of the font had ended, and generated some garbage. - -Version 1.8 2.Jan.1999 + +## Version 1.8 – 2.Jan.1999 * Added some more Type 2 commands (flex, flex1, hflex, hflex1) from a revision of the Type 2 spec. (I wouldn't have known about this except for @@ -252,20 +262,20 @@ Version 1.8 2.Jan.1999 * t1asm: Fixed one Type 2 command's translation (cntrmask was incorrectly mapped to 18, not 20). - -Version 1.7.2 11.Dec.1998 + +## Version 1.7.2 – 11.Dec.1998 * Integrated patches from Jan-Jaap van der Heijden <J.J.vanderHeijden@student.utwente.nl> to support building t1utils under 32-bit Windows. - -Version 1.7.1 5.Dec.1998 + +## Version 1.7.1 – 5.Dec.1998 * The t1utils package now uses automake. - -Version 1.7 27.Nov.1998 + +## Version 1.7 – 27.Nov.1998 * t1asm: Should now work with fonts that have no /Subrs sections. Previously, assembling such a font would silently fail; all the character definitions @@ -277,43 +287,43 @@ Version 1.7 27.Nov.1998 * Changed fgetc/fputc into getc/putc. - -Version 1.6 27.Sep.1998 -* `--help' now prints to stdout, following the GNU Coding Standards. +## Version 1.6 – 27.Sep.1998 + +* `--help` now prints to stdout, following the GNU Coding Standards. -* Makefiles: Added `make uninstall' target, enabled `./configure's +* Makefiles: Added `make uninstall` target, enabled `./configure`'s program name transformations, made VPATH builds possible. - -Version 1.5.2 6.Aug.1998 + +## Version 1.5.2 – 6.Aug.1998 * t1asm/t1disasm: Changed unknown charstring commands at the request of Werner Lemberg and LEE Chun-Yu. An unknown escape in the charstring, like 12 X, is translated to "escape_X" rather than "UNKNOWN_12_X". - -Version 1.5.1 31.May.1998 -* t1unmac did not actually understand the -r and -b options. Fixed. +## Version 1.5.1 – 31.May.1998 + +* t1unmac did not actually understand the `-r` and `-b` options. Fixed. * t1unmac: Added better diagnostics to help you diagnose seeking problems. - -Version 1.5 5.Mar.1998 + +## Version 1.5 – 5.Mar.1998 * Initial release with Eddie Kohler as maintainer. -* All: Updated to the GNU program behavior standards (long options, --help, - --version). Banners removed. Added more error messages. +* All: Updated to the GNU program behavior standards (long options, `--help`, + `--version`). Banners removed. Added more error messages. * t1binary: Removed fixed limit on line length. -* t1binary: Supports Macintosh files, whose lines end in `\r'. +* t1binary: Supports Macintosh files, whose lines end in `\r`. * t1binary: Supports an odd number of hex digits in a line. -* t1asm/t1disasm: Added support for Type 2 commands like `blend' and `add', +* t1asm/t1disasm: Added support for Type 2 commands like `blend` and `add`, which also appear in some multiple master fonts like Adobe Jenson. * t1asm/t1disasm: Added support for unknown charstring commands. t1disasm @@ -321,4 +331,4 @@ Version 1.5 5.Mar.1998 * t1asm/t1unmac: Changed default output to PFB. -* t1unmac: Used to be called `unpost'. `t1unmac' is a much better name. +* t1unmac: Used to be called `unpost`. `t1unmac` is a much better name. diff --git a/Build/source/utils/t1utils/t1utils-src/README b/Build/source/utils/t1utils/t1utils-src/README deleted file mode 100644 index 803b1ac7ee7..00000000000 --- a/Build/source/utils/t1utils/t1utils-src/README +++ /dev/null @@ -1,69 +0,0 @@ -T1UTILS -======= - - t1utils is a collection of simple type-1 font manipulation -programs. Together, they allow you to convert between PFA (ASCII) and -PFB (binary) formats, disassemble PFA or PFB files into human-readable -form, reassemble them into PFA or PFB format. Additionally you can -extract font resources from a Macintosh font file or create a -Macintosh Type 1 font file from a PFA or PFB font. - -There are currently six programs: - -t1ascii converts PFB files to PFA format. - -t1binary converts PFA files to PFB format. - -t1disasm disassembles a type-1 font (PFA or PFB format) into a - raw, human-readable text form for subsequent hand - editing, tweaking, hint fixing, etc... - -t1asm assembles type-1 font into PFA or PFB format from - human-readable form produced by t1disasm. - -t1unmac extracts POST resources from a Macintosh type-1 file - (ATM/Laserwriter) into PFA or PFB format for use outside - the Macintosh environment. The Macintosh file should be - stored in MacBinary, AppleSingle, AppleDouble, or BinHex - format, or as a raw resource fork. Note that t1unmac does - not have to run on a Macintosh, but makes Macintosh type-1 - fonts available to Unix machines and PCs. - -t1mac creates a Macintosh Type 1 file from a PFA or PFB-format - Type 1 font. Writes the Macintosh file in MacBinary, - AppleSingle, AppleDouble, or BinHex format, or as a raw - resource fork. WARNING: This will not suffice to use the - new font on a Macintosh, as Macintoshes cannot read raw - Type 1 fonts. You will need to create a font suitcase - containing bitmap fonts if you do not have such a suitcase - for the font already. T1utils cannot help you do this. - -Installation ------------- - - You need an ANSI C compiler, such as gcc. - - Just type `./configure', then `make'. `make install' will build and -install the utilities and their manual pages. - - `./configure' accepts the usual options. See `INSTALL' for more -details. The most commonly used option is `--prefix', which can be used -to install the utilities in a place other than /usr/local. - -Copyright and license ---------------------- - - The original t1utils were (c) 1992 I. Lee Hetherington. Changes -since version 1.2 are (c) 1998-2013 Eddie Kohler. Distribution is -under the Click LICENSE, a BSD-like license described in the LICENSE -file in this directory. - - Note that these tools should not be used to illegally copy type-1 -font programs. Typeface design is an intricate art that should be -rewarded. - -Eddie Kohler -ekohler@gmail.com - -I. Lee Hetherington -ilh@lcs.mit.edu diff --git a/Build/source/utils/t1utils/t1utils-src/README.md b/Build/source/utils/t1utils/t1utils-src/README.md new file mode 100644 index 00000000000..4e8715c72bb --- /dev/null +++ b/Build/source/utils/t1utils/t1utils-src/README.md @@ -0,0 +1,61 @@ +T1utils +======= + +T1utils is a collection of simple programs for manipulating PostScript Type 1 +fonts. Together, they allow you to convert between PFA (ASCII) and PFB +(binary) formats, disassemble PFA or PFB files into human-readable form, and +reassemble them into PFA or PFB format. Additionally you can extract font +resources from a Macintosh font file or create a Macintosh Type 1 font file +from a PFA or PFB font. + +There are currently six programs: + +* **t1ascii**: Converts PFB files to PFA format. + +* **t1binary**: Converts PFA files to PFB format. + +* **t1disasm**: Disassembles a Type 1 font (PFA or PFB format) into a + raw, human-readable text form for subsequent hand editing, tweaking, hint + fixing, and so forth. + +* **t1asm**: Assembles the human-readable t1disasm text form into a Type 1 + font in PFA or PFB format. + +* **t1unmac**: Extracts POST resources from a Macintosh Type 1 font file into + PFA or PFB format for use outside the Macintosh environment. The Macintosh + file should be stored in MacBinary, AppleSingle, AppleDouble, or BinHex + format, or as a raw resource fork. Note that t1unmac does not have to run on + a Macintosh. + +* **t1mac**: Creates a Macintosh Type 1 file from a PFA or PFB-format Type 1 + font. Writes the Macintosh file in MacBinary, AppleSingle, AppleDouble, or + BinHex format, or as a raw resource fork. WARNING: This will not suffice to + use the new font on a Macintosh, as Macintoshes cannot read raw Type 1 + fonts. You will need to create a font suitcase containing bitmap fonts if + you do not have such a suitcase for the font already. T1utils cannot help + you do this. + +Installation +------------ + +You need an ANSI C compiler, such as gcc. + +Just type `./configure`, then `make`. `make install` will build and install +the utilities and their manual pages. + +`./configure` accepts the usual options. See `INSTALL` for more details. The +most commonly used option is `--prefix`, which can be used to install the +utilities in a place other than /usr/local. + +Copyright and license +--------------------- + +The original t1utils were (c) 1992 I. Lee Hetherington, <ilh@lcs.mit.edu>. +Changes since version 1.2 are (c) 1998-2017 Eddie Kohler. Distribution is +under the Click LICENSE, a BSD-like license described in the LICENSE file in +this directory. + +Note that these tools should not be used to illegally copy Type 1 font +programs. Typeface design is an intricate art that should be rewarded. + +Eddie Kohler, ekohler@gmail.com diff --git a/Build/source/utils/t1utils/t1utils-src/clp.c b/Build/source/utils/t1utils/t1utils-src/clp.c index 3dff115733b..baf8dc5702e 100644 --- a/Build/source/utils/t1utils/t1utils-src/clp.c +++ b/Build/source/utils/t1utils/t1utils-src/clp.c @@ -2,18 +2,22 @@ /* clp.c - Complete source code for CLP. * This file is part of CLP, the command line parser package. * - * Copyright (c) 1997-2012 Eddie Kohler, ekohler@gmail.com + * Copyright (c) 1997-2014 Eddie Kohler, ekohler@gmail.com + * + * CLP is free software. It is distributed under the GNU General Public + * License, Version 2, or, alternatively and at your discretion, under the + * more permissive (BSD-like) Click LICENSE file as described below. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, subject to the conditions - * listed in the Click LICENSE file, which is available in full at - * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you - * must preserve this copyright notice, and you cannot mention the copyright - * holders in advertising related to the Software without their permission. - * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This - * notice is a summary of the Click LICENSE file; the license in that file is - * legally binding. */ + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, subject to the + * conditions listed in the Click LICENSE file, which is available in full at + * http://github.com/kohler/click/blob/master/LICENSE. The conditions + * include: you must preserve this copyright notice, and you cannot mention + * the copyright holders in advertising related to the Software without + * their permission. The Software is provided WITHOUT ANY WARRANTY, EXPRESS + * OR IMPLIED. This notice is a summary of the Click LICENSE file; the + * license in that file is binding. */ #ifdef HAVE_CONFIG_H # include <config.h> @@ -25,11 +29,20 @@ #include <assert.h> #include <stdarg.h> #include <ctype.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#if HAVE_INTTYPES_H || !defined(HAVE_CONFIG_H) +# include <inttypes.h> +#endif -/* By default, assume we have strtoul. */ -#if !defined(HAVE_STRTOUL) && !defined(HAVE_CONFIG_H) +/* By default, assume we have inttypes.h, strtoul, and uintptr_t. */ +#if !HAVE_STRTOUL && !defined(HAVE_CONFIG_H) # define HAVE_STRTOUL 1 #endif +#if !HAVE_UINTPTR_T && !HAVE_INTTYPES_H && defined(HAVE_CONFIG_H) +typedef unsigned long uintptr_t; +#endif #ifdef __cplusplus extern "C" { @@ -39,7 +52,7 @@ extern "C" { /** @file clp.h * @brief Functions for parsing command line options. * - * The CLP functions are used to parse command line arugments into options. + * The CLP functions are used to parse command line arguments into options. * It automatically handles value parsing, error messages, long options with * minimum prefix matching, short options, and negated options. * @@ -222,17 +235,24 @@ struct Clp_ParserState { typedef struct Clp_StringList { - Clp_Option *items; Clp_InternOption *iopt; int nitems; - int allow_int; + unsigned char allow_int; + unsigned char val_long; int nitems_invalid_report; - } Clp_StringList; +static const Clp_Option clp_option_sentinel[] = { + {"", 0, Clp_NotOption, 0, 0}, + {"", 0, Clp_Done, 0, 0}, + {"", 0, Clp_BadOption, 0, 0}, + {"", 0, Clp_Error, 0, 0} +}; + + static int parse_string(Clp_Parser *, const char *, int, void *); static int parse_int(Clp_Parser *, const char *, int, void *); static int parse_bool(Clp_Parser *, const char *, int, void *); @@ -430,6 +450,18 @@ compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1, } } +static void +calculate_lmm(Clp_Parser *clp, const Clp_Option *opt, Clp_InternOption *iopt, int nopt) +{ + int i, j; + for (i = 0; i < nopt; ++i) { + iopt[i].lmmpos = iopt[i].lmmneg = 1; + iopt[i].lmmpos_short = iopt[i].lmmneg_short = 0; + for (j = 0; j < nopt; ++j) + compare_options(clp, &opt[i], &iopt[i], &opt[j], &iopt[j]); + } +} + /** @param argc number of arguments * @param argv argument array * @param nopt number of option definitions @@ -451,7 +483,8 @@ compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1, * one of the substrings "UTF-8", "UTF8", or "utf8". Override this with * Clp_SetUTF8().</li> * <li>The Clp_ValString, Clp_ValStringNotOption, Clp_ValInt, Clp_ValUnsigned, - * Clp_ValBool, and Clp_ValDouble types are installed.</li> + * Clp_ValLong, Clp_ValUnsignedLong, Clp_ValBool, and Clp_ValDouble types are + * installed.</li> * <li>Errors are reported to standard error.</li> * </ul> * @@ -476,7 +509,7 @@ Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *op if (!clp || !cli || !iopt || !cli->valtype) goto failed; - clp->opt = -1; + clp->option = &clp_option_sentinel[-Clp_Done]; clp->negated = 0; clp->have_val = 0; clp->vstr = 0; @@ -514,8 +547,10 @@ Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *op 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_ValInt, 0, parse_int, (void*) (uintptr_t) 0); + Clp_AddType(clp, Clp_ValUnsigned, 0, parse_int, (void*) (uintptr_t) 1); + Clp_AddType(clp, Clp_ValLong, 0, parse_int, (void*) (uintptr_t) 2); + Clp_AddType(clp, Clp_ValUnsignedLong, 0, parse_int, (void*) (uintptr_t) 3); Clp_AddType(clp, Clp_ValBool, 0, parse_bool, 0); Clp_AddType(clp, Clp_ValDouble, 0, parse_double, 0); @@ -599,15 +634,9 @@ int Clp_SetUTF8(Clp_Parser *clp, int utf8) { Clp_Internal *cli = clp->internal; - int i, j, old_utf8 = cli->utf8; + int old_utf8 = cli->utf8; cli->utf8 = utf8; - for (i = 0; i < cli->nopt; ++i) { - cli->iopt[i].lmmpos = cli->iopt[i].lmmneg = 1; - cli->iopt[i].lmmpos_short = cli->iopt[i].lmmneg_short = 0; - for (j = 0; j < cli->nopt; ++j) - compare_options(clp, &cli->opt[i], &cli->iopt[i], - &cli->opt[j], &cli->iopt[j]); - } + calculate_lmm(clp, cli->opt, cli->iopt, cli->nopt); return old_utf8; } @@ -679,7 +708,7 @@ Clp_OptionChar(Clp_Parser *clp, int c) int Clp_SetOptionChar(Clp_Parser *clp, int c, int type) { - int i, j, long1pos, long1neg; + int i, long1pos, long1neg; int old = Clp_OptionChar(clp, c); Clp_Internal *cli = clp->internal; @@ -718,13 +747,7 @@ Clp_SetOptionChar(Clp_Parser *clp, int c, int type) /* Must recheck option set */ cli->long1pos = long1pos; cli->long1neg = long1neg; - for (i = 0; i < cli->nopt; ++i) { - cli->iopt[i].lmmpos = cli->iopt[i].lmmneg = 1; - cli->iopt[i].lmmpos_short = cli->iopt[i].lmmneg_short = 0; - for (j = 0; j < cli->nopt; ++j) - compare_options(clp, &cli->opt[i], &cli->iopt[i], - &cli->opt[j], &cli->iopt[j]); - } + calculate_lmm(clp, cli->opt, cli->iopt, cli->nopt); } return old; @@ -762,7 +785,7 @@ Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt) { Clp_Internal *cli = clp->internal; Clp_InternOption *iopt; - int i, j; + int i; static unsigned opt_generation = 0; if (nopt > cli->nopt) { @@ -780,7 +803,9 @@ Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt) cli->current_option = -1; /* Massage the options to make them usable */ - for (i = 0; i < nopt; i++) { + for (i = 0; i < nopt; ++i) { + memset(&iopt[i], 0, sizeof(iopt[i])); + /* Ignore negative option_ids, which are internal to CLP */ if (opt[i].option_id < 0) { Clp_OptionError(clp, "CLP internal error: option %d has negative option_id", i); @@ -819,12 +844,7 @@ Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt) } /* Check option set */ - for (i = 0; i < nopt; ++i) { - iopt[i].lmmpos = iopt[i].lmmneg = 1; - iopt[i].lmmpos_short = iopt[i].lmmneg_short = 0; - for (j = 0; j < nopt; ++j) - compare_options(clp, &opt[i], &iopt[i], &opt[j], &iopt[j]); - } + calculate_lmm(clp, opt, iopt, nopt); return 0; } @@ -1072,39 +1092,44 @@ parse_string(Clp_Parser *clp, const char *arg, int complain, void *user_data) } static int -parse_int(Clp_Parser *clp, const char *arg, int complain, void *user_data) +parse_int(Clp_Parser* clp, const char* arg, int complain, void* user_data) { const char *val; char *temp; + uintptr_t type = (uintptr_t) user_data; if (*arg == 0 || isspace((unsigned char) *arg) - || (user_data != 0 && *arg == '-')) + || ((type & 1) && *arg == '-')) val = arg; - else if (user_data != 0) { /* unsigned */ + else if (type & 1) { /* unsigned */ #if HAVE_STRTOUL - clp->val.u = strtoul(arg, &temp, 0); + clp->val.ul = strtoul(arg, &temp, 0); val = temp; #else /* don't bother really trying to do it right */ if (arg[0] == '-') val = arg; else { - clp->val.u = strtol(arg, &temp, 0); + clp->val.l = strtol(arg, &temp, 0); val = temp; } #endif } else { - clp->val.i = strtol(arg, &temp, 0); + clp->val.l = strtol(arg, &temp, 0); val = temp; } + if (type <= 1) + clp->val.u = (unsigned) clp->val.ul; if (*arg != 0 && *val == 0) return 1; - else if (complain) { - const char *message = user_data != 0 - ? "%<%O%> expects a nonnegative integer, not %<%s%>" - : "%<%O%> expects an integer, not %<%s%>"; - return Clp_OptionError(clp, message, arg); - } else - return 0; + else { + if (complain) { + const char *message = type & 1 + ? "%<%O%> expects a nonnegative integer, not %<%s%>" + : "%<%O%> expects an integer, not %<%s%>"; + Clp_OptionError(clp, message, arg); + } + return 0; + } } static int @@ -1121,10 +1146,11 @@ parse_double(Clp_Parser *clp, const char *arg, int complain, void *user_data) } if (*arg != 0 && *val == 0) return 1; - else if (complain) - return Clp_OptionError(clp, "%<%O%> expects a real number, not %<%s%>", arg); - else + else { + if (complain) + Clp_OptionError(clp, "%<%O%> expects a real number, not %<%s%>", arg); return 0; + } } static int @@ -1176,27 +1202,26 @@ parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_dat &ambiguous, ambiguous_values); if (idx >= 0) { clp->val.i = sl->items[idx].option_id; - return 1; + if (sl->val_long) + clp->val.l = clp->val.i; + return 1; } if (sl->allow_int) { - if (parse_int(clp, arg, 0, 0)) + if (parse_int(clp, arg, 0, (void*) (uintptr_t) (sl->val_long ? 2 : 0))) return 1; } if (complain) { - const char *complaint; - if (ambiguous) - complaint = "ambiguous value %<%s%> for option %<%O%>"; - else { - complaint = "unknown value %<%s%> for option %<%O%>"; + const char *complaint = (ambiguous ? "ambiguous" : "invalid"); + if (!ambiguous) { ambiguous = sl->nitems_invalid_report; for (idx = 0; idx < ambiguous; idx++) ambiguous_values[idx] = idx; } return ambiguity_error (clp, ambiguous, ambiguous_values, sl->items, sl->iopt, - "", complaint, arg); + "", "option %<%V%> is %s", complaint); } else return 0; } @@ -1206,7 +1231,7 @@ static int finish_string_list(Clp_Parser *clp, int val_type, int flags, Clp_Option *items, int nitems, int itemscap) { - int i, j; + int i; Clp_StringList *clsl = (Clp_StringList *)malloc(sizeof(Clp_StringList)); Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nitems); if (!clsl || !iopt) @@ -1216,6 +1241,7 @@ finish_string_list(Clp_Parser *clp, int val_type, int flags, clsl->iopt = iopt; clsl->nitems = nitems; clsl->allow_int = (flags & Clp_AllowNumbers) != 0; + clsl->val_long = (flags & Clp_StringListLong) != 0; if (nitems < MAX_AMBIGUOUS_VALUES && nitems < itemscap && clsl->allow_int) { items[nitems].long_name = "any integer"; @@ -1228,12 +1254,8 @@ finish_string_list(Clp_Parser *clp, int val_type, int flags, for (i = 0; i < nitems; i++) { iopt[i].ilong = iopt[i].ipos = 1; iopt[i].ishort = iopt[i].ineg = iopt[i].ilongoff = iopt[i].iprefmatch = 0; - iopt[i].lmmpos = 1; - iopt[i].lmmpos_short = 0; } - for (i = 0; i < nitems; i++) - for (j = 0; j < nitems; j++) - compare_options(clp, &items[i], &iopt[i], &items[j], &iopt[j]); + calculate_lmm(clp, items, iopt, nitems); if (Clp_AddType(clp, val_type, 0, parse_string_list, clsl) >= 0) return 0; @@ -1290,7 +1312,12 @@ Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) char *name = va_arg(val, char *); if (!name) break; - value = va_arg(val, int); + if (flags & Clp_StringListLong) { + long lvalue = va_arg(val, long); + value = (int) lvalue; + assert(value == lvalue); + } else + value = va_arg(val, int); if (nitems >= itemscap) { Clp_Option *new_items; @@ -1768,8 +1795,10 @@ find_short(Clp_Parser *clp, const 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)) + && (!clp->negated || iopt[i].ineg)) { + clp->negated = clp->negated || !iopt[i].ipos; return i; + } return -1; } @@ -1815,7 +1844,7 @@ find_short(Clp_Parser *clp, const char *text) * </dl> * * The parsed argument is shifted off the argument list, so that sequential - * calls to Clp_Next() step through the arugment list. + * calls to Clp_Next() step through the argument list. */ int Clp_Next(Clp_Parser *clp) @@ -1833,8 +1862,9 @@ Clp_Next(Clp_Parser *clp) /* Get the next argument or option */ if (!next_argument(clp, cli->option_processing ? 0 : 2)) { clp->val.s = clp->vstr; - clp->opt = clp->have_val ? Clp_NotOption : Clp_Done; - return clp->opt; + optno = clp->have_val ? Clp_NotOption : Clp_Done; + clp->option = &clp_option_sentinel[-optno]; + return optno; } clp->negated = cli->whole_negated; @@ -1872,7 +1902,8 @@ Clp_Next(Clp_Parser *clp) Clp_OptionError(clp, "unrecognized option %<%s%s%>", cli->option_chars, cli->xtext); - return (clp->opt = Clp_BadOption); + clp->option = &clp_option_sentinel[-Clp_BadOption]; + return Clp_BadOption; } /* Set the current option */ @@ -1885,20 +1916,27 @@ Clp_Next(Clp_Parser *clp) || (!cli->iopt[optno].imandatory && !cli->iopt[optno].ioptional)) { if (clp->have_val) { Clp_OptionError(clp, "%<%O%> can%,t take an argument"); - clp->opt = Clp_BadOption; - } else - clp->opt = cli->opt[optno].option_id; - return clp->opt; + clp->option = &clp_option_sentinel[-Clp_BadOption]; + return Clp_BadOption; + } else { + clp->option = &cli->opt[optno]; + 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]; - if (opt->val_type <= 0) - return (clp->opt = Clp_Error); + if (opt->val_type <= 0) { + clp->option = &clp_option_sentinel[-Clp_Error]; + return Clp_Error; + } vtpos = val_type_binsearch(cli, opt->val_type); - if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != opt->val_type) - return (clp->opt = Clp_Error); + if (vtpos == cli->nvaltype + || cli->valtype[vtpos].val_type != opt->val_type) { + clp->option = &clp_option_sentinel[-Clp_Error]; + return Clp_Error; + } /* complain == 1 only if the argument was explicitly given, or it is mandatory. */ @@ -1918,31 +1956,34 @@ Clp_Next(Clp_Parser *clp) Clp_OptionError(clp, "%<%O%> requires a non-option argument"); else Clp_OptionError(clp, "%<%O%> requires an argument"); - return (clp->opt = Clp_BadOption); + clp->option = &clp_option_sentinel[-Clp_BadOption]; + return Clp_BadOption; } } else if (cli->is_short && !clp->have_val - && cli->xtext[clp_utf8_charlen(cli, cli->xtext)]) { + && cli->xtext[clp_utf8_charlen(cli, cli->xtext)]) /* The -[option]argument case: Assume that the rest of the current string is the argument. */ next_argument(clp, 1); - complain = 1; - } /* Parse the argument */ + clp->option = opt; if (clp->have_val) { Clp_ValType *atr = &cli->valtype[vtpos]; if (atr->func(clp, clp->vstr, complain, atr->user_data) <= 0) { /* parser failed */ clp->have_val = 0; - if (complain) - return (clp->opt = Clp_BadOption); - else + if (complain) { + clp->option = &clp_option_sentinel[-Clp_BadOption]; + return Clp_BadOption; + } else { Clp_RestoreParser(clp, &clpsave); + clp->option = opt; + } } } - return (clp->opt = opt->option_id); + return opt->option_id; } @@ -1972,59 +2013,51 @@ Clp_Shift(Clp_Parser *clp, int allow_options) **/ typedef struct Clp_BuildString { - char *text; - char *pos; - int capacity; - int bad; + char* data; + char* pos; + char* end_data; + char buf[256]; } Clp_BuildString; -static Clp_BuildString * -new_build_string(void) -{ - Clp_BuildString *bs = (Clp_BuildString *)malloc(sizeof(Clp_BuildString)); - if (!bs) goto bad; - bs->text = (char *)malloc(256); - if (!bs->text) goto bad; - bs->pos = bs->text; - bs->capacity = 256; - bs->bad = 0; - return bs; - - bad: - if (bs) free(bs); - return 0; +static void build_string_program_prefix(Clp_BuildString* bs, + const Clp_Parser* clp); + +static void build_string_init(Clp_BuildString* bs, Clp_Parser* clp) { + bs->data = bs->pos = bs->buf; + bs->end_data = &bs->buf[sizeof(bs->buf)]; + if (clp) + build_string_program_prefix(bs, clp); } -static void -free_build_string(Clp_BuildString *bs) -{ - if (bs) free(bs->text); - free(bs); +static void build_string_cleanup(Clp_BuildString* bs) { + if (bs->data != bs->buf) + free(bs->data); } -static int -grow_build_string(Clp_BuildString *bs, int want) -{ - char *new_text; - int ipos = bs->pos - bs->text; - int new_capacity = bs->capacity; - while (want >= new_capacity) - new_capacity *= 2; - new_text = (char *)realloc(bs->text, new_capacity); - if (!new_text) { - bs->bad = 1; - return 0; +static int build_string_grow(Clp_BuildString* bs, size_t want) { + size_t ipos = bs->pos - bs->data, ncap; + if (!bs->pos) + return 0; + for (ncap = (bs->end_data - bs->data) << 1; ncap < want; ncap *= 2) + /* nada */; + if (bs->data == bs->buf) { + if ((bs->data = (char*) malloc(ncap))) + memcpy(bs->data, bs->buf, bs->pos - bs->buf); + } else + bs->data = (char*) realloc(bs->data, ncap); + if (!bs->data) { + bs->pos = bs->end_data = bs->data; + return 0; } else { - bs->text = new_text; - bs->pos = bs->text + ipos; - bs->capacity = new_capacity; - return 1; + bs->pos = bs->data + ipos; + bs->end_data = bs->data + ncap; + return 1; } } -#define ENSURE_BUILD_STRING(bs, space) \ - ((((bs)->pos - (bs)->text) + (space) >= (bs)->capacity) \ - || grow_build_string((bs), ((bs)->pos - (bs)->text) + (space))) +#define ENSURE_BUILD_STRING(bs, space) \ + ((((bs)->end_data - (bs)->pos) >= (space)) \ + || build_string_grow((bs), (bs)->pos - (bs)->data + (space))) static void append_build_string(Clp_BuildString *bs, const char *s, int l) @@ -2037,23 +2070,24 @@ append_build_string(Clp_BuildString *bs, const char *s, int l) } } - -static Clp_BuildString * -Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, - const char *fmt, va_list val) +static void +build_string_program_prefix(Clp_BuildString* bs, const Clp_Parser* clp) { - Clp_Internal *cli = clp->internal; - const char *percent; - int c; - - if (!bs) - bs = new_build_string(); - if (!bs) - return 0; + const Clp_Internal* cli = clp->internal; if (cli->program_name && cli->program_name[0]) { append_build_string(bs, cli->program_name, -1); append_build_string(bs, ": ", 2); } +} + + +static void +Clp_vbsprintf(Clp_Parser *clp, Clp_BuildString *bs, + const char *fmt, va_list val) +{ + Clp_Internal *cli = clp->internal; + const char *percent; + int c; for (percent = strchr(fmt, '%'); percent; percent = strchr(fmt, '%')) { append_build_string(bs, fmt, percent - fmt); @@ -2061,10 +2095,7 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, case 's': { const char *s = va_arg(val, const char *); - if (s) - append_build_string(bs, s, -1); - else - append_build_string(bs, "(null)", 6); + append_build_string(bs, s ? s : "(null)", -1); break; } @@ -2109,29 +2140,37 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, break; } - case 'O': { - int optno = cli->current_option; - const Clp_Option *opt = &cli->opt[optno]; - if (optno < 0) - append_build_string(bs, "(no current option!)", -1); - else if (cli->current_short) { - append_build_string(bs, cli->option_chars, -1); - if (ENSURE_BUILD_STRING(bs, 5)) { - if (cli->utf8) - bs->pos = encode_utf8(bs->pos, 5, opt->short_name); - else - *bs->pos++ = opt->short_name; - } - } else if (cli->negated_by_no) { - append_build_string(bs, cli->option_chars, -1); - append_build_string(bs, "no-", 3); - append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1); - } else { - append_build_string(bs, cli->option_chars, -1); - append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1); - } - break; - } + case 'O': + case 'V': { + int optno = cli->current_option; + const Clp_Option *opt = &cli->opt[optno]; + if (optno < 0) + append_build_string(bs, "(no current option!)", -1); + else if (cli->current_short) { + append_build_string(bs, cli->option_chars, -1); + if (ENSURE_BUILD_STRING(bs, 5)) { + if (cli->utf8) + bs->pos = encode_utf8(bs->pos, 5, opt->short_name); + else + *bs->pos++ = opt->short_name; + } + } else if (cli->negated_by_no) { + append_build_string(bs, cli->option_chars, -1); + append_build_string(bs, "no-", 3); + append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1); + } else { + append_build_string(bs, cli->option_chars, -1); + append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1); + } + if (optno >= 0 && clp->have_val && *percent == 'V') { + if (cli->current_short && !cli->iopt[optno].ioptional) + append_build_string(bs, " ", 1); + else if (!cli->current_short) + append_build_string(bs, "=", 1); + append_build_string(bs, clp->vstr, -1); + } + break; + } case '%': if (ENSURE_BUILD_STRING(bs, 1)) @@ -2149,6 +2188,10 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1); break; + case 0: + append_build_string(bs, "%", 1); + goto done; + default: if (ENSURE_BUILD_STRING(bs, 2)) { *bs->pos++ = '%'; @@ -2160,22 +2203,24 @@ Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, fmt = ++percent; } + done: append_build_string(bs, fmt, -1); - append_build_string(bs, "\n", 1); +} - return bs; +static const char* build_string_text(Clp_BuildString* bs, int report_oom) { + if (bs->pos) { + *bs->pos = 0; + return bs->data; + } else if (report_oom) + return "out of memory\n"; + else + return NULL; } static void do_error(Clp_Parser *clp, Clp_BuildString *bs) { - const char *text; - if (bs && !bs->bad) { - *bs->pos = 0; - text = bs->text; - } else - text = "out of memory\n"; - + const char *text = build_string_text(bs, 1); if (clp->internal->error_handler != 0) (*clp->internal->error_handler)(clp, text); else @@ -2185,9 +2230,10 @@ do_error(Clp_Parser *clp, Clp_BuildString *bs) /** @param clp the parser * @param format error format * - * Format an error message from @a format and any additional arguments in the - * ellipsis. The resulting error string by printing it to standard error or - * passing it to Clp_SetErrorHandler. + * Format an error message from @a format and any additional arguments in + * the ellipsis. The resulting error string is then printed to standard + * error (or passed to the error handler specified by Clp_SetErrorHandler). + * Returns the number of characters printed. * * The following format characters are accepted: * @@ -2208,6 +2254,9 @@ do_error(Clp_Parser *clp, Clp_BuildString *bs) * <dt><tt>%</tt><tt>O</tt></dt> * <dd>The current option. No values are read from the argument list; the * current option is defined in the Clp_Parser object itself.</dd> + * <dt><tt>%</tt><tt>V</tt></dt> + * <dd>Like <tt>%</tt><tt>O</tt>, but also includes the current value, + * if any.</dd> * <dt><tt>%%</tt></dt> * <dd>Prints a percent character.</dd> * <dt><tt>%</tt><tt><</tt></dt> @@ -2229,14 +2278,94 @@ do_error(Clp_Parser *clp, Clp_BuildString *bs) int Clp_OptionError(Clp_Parser *clp, const char *format, ...) { - Clp_BuildString *bs; + Clp_BuildString bs; va_list val; va_start(val, format); - bs = Clp_VaOptionError(clp, 0, format, val); + build_string_init(&bs, clp); + Clp_vbsprintf(clp, &bs, format, val); + append_build_string(&bs, "\n", 1); va_end(val); - do_error(clp, bs); - free_build_string(bs); - return 0; + do_error(clp, &bs); + build_string_cleanup(&bs); + return bs.pos - bs.data; +} + +/** @param clp the parser + * @param f output file + * @param format error format + * + * Format an error message using @a format and additional arguments in the + * ellipsis, according to the Clp_OptionError formatting conventions. The + * resulting message is written to @a f. + * + * @sa Clp_OptionError */ +int +Clp_fprintf(Clp_Parser* clp, FILE* f, const char* format, ...) +{ + Clp_BuildString bs; + va_list val; + va_start(val, format); + build_string_init(&bs, NULL); + Clp_vbsprintf(clp, &bs, format, val); + va_end(val); + if (bs.pos != bs.data) + fwrite(bs.data, 1, bs.pos - bs.data, f); + build_string_cleanup(&bs); + return bs.pos - bs.data; +} + +/** @param clp the parser + * @param f output file + * @param format error format + * @param val arguments + * + * Format an error message using @a format and @a val, according to the + * Clp_OptionError formatting conventions. The resulting message is written + * to @a f. + * + * @sa Clp_OptionError */ +int +Clp_vfprintf(Clp_Parser* clp, FILE* f, const char* format, va_list val) +{ + Clp_BuildString bs; + build_string_init(&bs, NULL); + Clp_vbsprintf(clp, &bs, format, val); + if (bs.pos != bs.data) + fwrite(bs.data, 1, bs.pos - bs.data, f); + build_string_cleanup(&bs); + return bs.pos - bs.data; +} + +/** @param clp the parser + * @param str output string + * @param size size of output string + * @param format error format + * + * Format an error message from @a format and any additional arguments in + * the ellipsis, according to the Clp_OptionError formatting conventions. + * The resulting string is written to @a str. At most @a size characters are + * written to @a str, including a terminating null byte. The return value is + * the number of characters that would have been written (excluding the + * terminating null byte) if @a size were large enough to contain the entire + * string. + * + * @sa Clp_OptionError */ +int +Clp_vsnprintf(Clp_Parser* clp, char* str, size_t size, + const char* format, va_list val) +{ + Clp_BuildString bs; + build_string_init(&bs, NULL); + Clp_vbsprintf(clp, &bs, format, val); + if ((size_t) (bs.pos - bs.data) < size) { + memcpy(str, bs.data, bs.pos - bs.data); + str[bs.pos - bs.data] = 0; + } else { + memcpy(str, bs.data, size - 1); + str[size - 1] = 0; + } + build_string_cleanup(&bs); + return bs.pos - bs.data; } static int @@ -2245,18 +2374,17 @@ ambiguity_error(Clp_Parser *clp, int ambiguous, int *ambiguous_values, const char *prefix, const char *fmt, ...) { Clp_Internal *cli = clp->internal; - Clp_BuildString *bs; + Clp_BuildString bs; int i; va_list val; + va_start(val, fmt); - bs = Clp_VaOptionError(clp, 0, fmt, val); - if (!bs) goto done; + build_string_init(&bs, clp); + Clp_vbsprintf(clp, &bs, fmt, val); + append_build_string(&bs, "\n", 1); - if (clp->internal->program_name && clp->internal->program_name[0]) { - append_build_string(bs, clp->internal->program_name, -1); - append_build_string(bs, ": ", 2); - } - append_build_string(bs, "(Possibilities are", -1); + build_string_program_prefix(&bs, clp); + append_build_string(&bs, "(Possibilities are", -1); for (i = 0; i < ambiguous && i < MAX_AMBIGUOUS_VALUES; i++) { int value = ambiguous_values[i]; @@ -2264,26 +2392,25 @@ ambiguity_error(Clp_Parser *clp, int ambiguous, int *ambiguous_values, if (value < 0) value = -(value + 1), no_dash = "no-"; if (i == 0) - append_build_string(bs, " ", 1); + append_build_string(&bs, " ", 1); else if (i == ambiguous - 1) - append_build_string(bs, (i == 1 ? " and " : ", and "), -1); + append_build_string(&bs, (i == 1 ? " and " : ", and "), -1); else - append_build_string(bs, ", ", 2); - append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1); - append_build_string(bs, prefix, -1); - append_build_string(bs, no_dash, -1); - append_build_string(bs, opt[value].long_name + iopt[value].ilongoff, -1); - append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1); + append_build_string(&bs, ", ", 2); + append_build_string(&bs, (cli->utf8 ? "\342\200\230" : "'"), -1); + append_build_string(&bs, prefix, -1); + append_build_string(&bs, no_dash, -1); + append_build_string(&bs, opt[value].long_name + iopt[value].ilongoff, -1); + append_build_string(&bs, (cli->utf8 ? "\342\200\231" : "'"), -1); } if (ambiguous > MAX_AMBIGUOUS_VALUES) - append_build_string(bs, ", and others", -1); - append_build_string(bs, ".)\n", -1); + append_build_string(&bs, ", and others", -1); + append_build_string(&bs, ".)\n", -1); va_end(val); - done: - do_error(clp, bs); - free_build_string(bs); + do_error(clp, &bs); + build_string_cleanup(&bs); return 0; } @@ -2355,6 +2482,22 @@ Clp_CurOptionName(Clp_Parser *clp) return buf; } +int +Clp_IsLong(Clp_Parser *clp, const char *long_name) +{ + Clp_Internal *cli = clp->internal; + int optno = cli->current_option; + return optno >= 0 && strcmp(cli->opt[optno].long_name, long_name) == 0; +} + +int +Clp_IsShort(Clp_Parser *clp, int short_name) +{ + Clp_Internal *cli = clp->internal; + int optno = cli->current_option; + return optno >= 0 && cli->opt[optno].short_name == short_name; +} + #ifdef __cplusplus } #endif diff --git a/Build/source/utils/t1utils/t1utils-src/config.h.in b/Build/source/utils/t1utils/t1utils-src/config.h.in index 76389dfbfe6..718cae85698 100644 --- a/Build/source/utils/t1utils/t1utils-src/config.h.in +++ b/Build/source/utils/t1utils/t1utils-src/config.h.in @@ -9,6 +9,9 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the `memmem' function. */ +#undef HAVE_MEMMEM + /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H @@ -89,7 +92,13 @@ extern "C" { /* Prototype strerror if we don't have it. */ #if !HAVE_STRERROR -char *strerror(int errno); +char* strerror(int errno); +#endif + +/* Prototype memmem if we don't have it. */ +#if !HAVE_MEMMEM +void* memmem(const void* haystack, size_t haystack_len, + const void* needle, size_t needle_len); #endif #ifdef __cplusplus diff --git a/Build/source/utils/t1utils/t1utils-src/configure.ac b/Build/source/utils/t1utils/t1utils-src/configure.ac index 96b13a35206..5b4e3ffc22a 100644 --- a/Build/source/utils/t1utils/t1utils-src/configure.ac +++ b/Build/source/utils/t1utils/t1utils-src/configure.ac @@ -1,9 +1,8 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([t1utils], [1.39]) +AC_INIT([t1utils], [1.41]) AC_CONFIG_SRCDIR([t1ascii.c]) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS([config.h]) -AM_MAINTAINER_MODE AC_PROG_CC AC_C_CONST @@ -19,7 +18,7 @@ dnl dnl strerror()? dnl -AC_REPLACE_FUNCS([strerror]) +AC_REPLACE_FUNCS([strerror memmem]) dnl @@ -85,7 +84,13 @@ extern "C" { /* Prototype strerror if we don't have it. */ #if !HAVE_STRERROR -char *strerror(int errno); +char* strerror(int errno); +#endif + +/* Prototype memmem if we don't have it. */ +#if !HAVE_MEMMEM +void* memmem(const void* haystack, size_t haystack_len, + const void* needle, size_t needle_len); #endif #ifdef __cplusplus diff --git a/Build/source/utils/t1utils/t1utils-src/include/lcdf/clp.h b/Build/source/utils/t1utils/t1utils-src/include/lcdf/clp.h index 1b658a17190..37b75194ac0 100644 --- a/Build/source/utils/t1utils/t1utils-src/include/lcdf/clp.h +++ b/Build/source/utils/t1utils/t1utils-src/include/lcdf/clp.h @@ -8,18 +8,25 @@ extern "C" { /* clp.h - Public interface to CLP. * This file is part of CLP, the command line parser package. * - * Copyright (c) 1997-2012 Eddie Kohler, ekohler@gmail.com + * Copyright (c) 1997-2014 Eddie Kohler, ekohler@gmail.com + * + * CLP is free software. It is distributed under the GNU General Public + * License, Version 2, or, alternatively and at your discretion, under the + * more permissive (BSD-like) Click LICENSE file as described below. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, subject to the conditions - * listed in the Click LICENSE file, which is available in full at - * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you - * must preserve this copyright notice, and you cannot mention the copyright - * holders in advertising related to the Software without their permission. - * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This - * notice is a summary of the Click LICENSE file; the license in that file is - * legally binding. */ + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, subject to the + * conditions listed in the Click LICENSE file, which is available in full at + * http://github.com/kohler/click/blob/master/LICENSE. The conditions + * include: you must preserve this copyright notice, and you cannot mention + * the copyright holders in advertising related to the Software without + * their permission. The Software is provided WITHOUT ANY WARRANTY, EXPRESS + * OR IMPLIED. This notice is a summary of the Click LICENSE file; the + * license in that file is binding. */ + +#include <stdio.h> +#include <stdarg.h> typedef struct Clp_Option Clp_Option; typedef struct Clp_Parser Clp_Parser; @@ -65,16 +72,20 @@ struct Clp_Option { Accepts an optional "+" or "-" sign, followed by one or more digits. The digits may be include a "0x" or "0X" prefix, for - a hexidecimal number, or a "0" prefix, for an octal number; + a hexadecimal number, or a "0" prefix, for an octal number; otherwise it is decimal. */ #define Clp_ValUnsigned 5 /**< @brief Option value is an unsigned int. Accepts an optional "+" sign, followed by one or more digits. The digits may be include a "0x" or "0X" prefix, for - a hexidecimal number, or a "0" prefix, for an octal number; + a hexadecimal number, or a "0" prefix, for an octal number; otherwise it is decimal. */ -#define Clp_ValDouble 6 /**< @brief Option value is a +#define Clp_ValLong 6 /**< @brief Option value is a + signed long. */ +#define Clp_ValUnsignedLong 7 /**< @brief Option value is an + unsigned long. */ +#define Clp_ValDouble 8 /**< @brief Option value is a double. Accepts a real number as defined by strtod(). */ #define Clp_ValFirstUser 10 /**< @brief Value types >= @@ -165,7 +176,7 @@ typedef void (*Clp_ErrorHandler)(Clp_Parser *clp, const char *message); * value types, and current arguments. * @sa Clp_NewParser, Clp_SetOptions, Clp_SetArguments */ struct Clp_Parser { - int opt; /**< The last option. */ + const Clp_Option *option; /**< The last option. */ int negated; /**< Whether the last option was negated. */ @@ -176,6 +187,8 @@ struct Clp_Parser { union { int i; unsigned u; + long l; + unsigned long ul; double d; const char *s; void *pv; @@ -253,9 +266,11 @@ int Clp_AddType(Clp_Parser *clp, int val_type, int flags, #define Clp_AllowNumbers (1<<0) /**< @brief String list flag: allow - explicit numbers. + explicit numbers. See Clp_AddStringListType() and Clp_AddStringListTypeVec(). */ +#define Clp_StringListLong (1<<1) /**< @brief String list flag: values + have long type. */ /** @brief Define a new string list value type for @a clp. */ int Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags, @@ -290,12 +305,28 @@ void Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state); /** @brief Report a parser error. */ int Clp_OptionError(Clp_Parser *clp, const char *format, ...); +/** @brief Format a message. */ +int Clp_vsnprintf(Clp_Parser* clp, char* str, size_t size, + const char* format, va_list val); + +/** @brief Print a message. */ +int Clp_fprintf(Clp_Parser* clp, FILE* f, const char* format, ...); + +/** @brief Print a message. */ +int Clp_vfprintf(Clp_Parser* clp, FILE* f, const char* format, va_list val); + /** @brief Extract the current option as a string. */ int Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len); /** @brief Extract the current option as a string. */ const char *Clp_CurOptionName(Clp_Parser *clp); +/** @brief Test if the current option had long name @a name. */ +int Clp_IsLong(Clp_Parser *clp, const char *long_name); + +/** @brief Test if the current option had short name @a name. */ +int Clp_IsShort(Clp_Parser *clp, int short_name); + #undef CLP_SENTINEL #ifdef __cplusplus } diff --git a/Build/source/utils/t1utils/t1utils-src/include/lcdf/inttypes.h b/Build/source/utils/t1utils/t1utils-src/include/lcdf/inttypes.h index b88e9e9faf0..b8bcedd120e 100644 --- a/Build/source/utils/t1utils/t1utils-src/include/lcdf/inttypes.h +++ b/Build/source/utils/t1utils/t1utils-src/include/lcdf/inttypes.h @@ -2,6 +2,8 @@ #define LCDF_INTTYPES_H /* Define known-width integer types. */ +#include <stddef.h> + #ifdef HAVE_INTTYPES_H # include <inttypes.h> #elif defined(HAVE_SYS_TYPES_H) diff --git a/Build/source/utils/t1utils/t1utils-src/t1ascii.1 b/Build/source/utils/t1utils/t1utils-src/t1ascii.1 index 5d883f99129..8fc7e884cf5 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1ascii.1 +++ b/Build/source/utils/t1utils/t1utils-src/t1ascii.1 @@ -1,4 +1,4 @@ -.ds V 1.39 +.ds V 1.41 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/utils/t1utils/t1utils-src/t1ascii.c b/Build/source/utils/t1utils/t1utils-src/t1ascii.c index 757ae2225a8..3e7d2abeb10 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1ascii.c +++ b/Build/source/utils/t1utils/t1utils-src/t1ascii.c @@ -4,7 +4,7 @@ * converts it to ASCII (PFA) format. * * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -240,7 +240,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1ascii (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\ + printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff --git a/Build/source/utils/t1utils/t1utils-src/t1asm.1 b/Build/source/utils/t1utils/t1utils-src/t1asm.1 index 0621a0e2585..cdf5e59c198 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1asm.1 +++ b/Build/source/utils/t1utils/t1utils-src/t1asm.1 @@ -1,4 +1,4 @@ -.ds V 1.39 +.ds V 1.41 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/utils/t1utils/t1utils-src/t1asm.c b/Build/source/utils/t1utils/t1utils-src/t1asm.c index 0021bf016e9..898c0c516a0 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1asm.c +++ b/Build/source/utils/t1utils/t1utils-src/t1asm.c @@ -1,4 +1,4 @@ -/* t1asm -*- c-basic-offset: 2 -*- +/* t1asm -*- c-basic-offset: 2 -*- * * This program `assembles' Adobe Type-1 font programs in pseudo-PostScript * form into either PFB or PFA format. The human readable/editable input is @@ -8,7 +8,7 @@ * file. * * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -97,76 +97,77 @@ static int charstring_bufsiz; /* decryption stuff */ static uint16_t er, cr; -static uint16_t c1 = 52845, c2 = 22719; +static const uint32_t c1 = 52845; +static const uint32_t c2 = 22719; /* table of charstring commands */ static struct command { const char *name; int one, two; } command_table[] = { - { "abs", 12, 9 }, /* Type 2 */ - { "add", 12, 10 }, /* Type 2 */ - { "and", 12, 3 }, /* Type 2 */ - { "blend", 16, -1 }, /* Type 2 */ - { "callgsubr", 29, -1 }, /* Type 2 */ - { "callother", 12, 16 }, /* Type 1 ONLY */ - { "callothersubr", 12, 16 }, /* Type 1 ONLY */ + { "abs", 12, 9 }, /* Type 2 */ + { "add", 12, 10 }, /* Type 2 */ + { "and", 12, 3 }, /* Type 2 */ + { "blend", 16, -1 }, /* Type 2 */ + { "callgsubr", 29, -1 }, /* Type 2 */ + { "callother", 12, 16 }, /* Type 1 ONLY */ + { "callothersubr", 12, 16 }, /* Type 1 ONLY */ { "callsubr", 10, -1 }, - { "closepath", 9, -1 }, /* Type 1 ONLY */ - { "cntrmask", 20, -1 }, /* Type 2 */ + { "closepath", 9, -1 }, /* Type 1 ONLY */ + { "cntrmask", 20, -1 }, /* Type 2 */ { "div", 12, 12 }, - { "dotsection", 12, 0 }, /* Type 1 ONLY */ - { "drop", 12, 18 }, /* Type 2 */ - { "dup", 12, 27 }, /* Type 2 */ + { "dotsection", 12, 0 }, /* Type 1 ONLY */ + { "drop", 12, 18 }, /* Type 2 */ + { "dup", 12, 27 }, /* Type 2 */ { "endchar", 14, -1 }, - { "eq", 12, 15 }, /* Type 2 */ - { "error", 0, -1 }, /* special */ - { "escape", 12, -1 }, /* special */ - { "exch", 12, 28 }, /* Type 2 */ - { "flex", 12, 35 }, /* Type 2 */ - { "flex1", 12, 37 }, /* Type 2 */ - { "get", 12, 21 }, /* Type 2 */ - { "hflex", 12, 34 }, /* Type 2 */ - { "hflex1", 12, 36 }, /* Type 2 */ - { "hhcurveto", 27, -1 }, /* Type 2 */ - { "hintmask", 19, -1 }, /* Type 2 */ + { "eq", 12, 15 }, /* Type 2 */ + { "error", 0, -1 }, /* special */ + { "escape", 12, -1 }, /* special */ + { "exch", 12, 28 }, /* Type 2 */ + { "flex", 12, 35 }, /* Type 2 */ + { "flex1", 12, 37 }, /* Type 2 */ + { "get", 12, 21 }, /* Type 2 */ + { "hflex", 12, 34 }, /* Type 2 */ + { "hflex1", 12, 36 }, /* Type 2 */ + { "hhcurveto", 27, -1 }, /* Type 2 */ + { "hintmask", 19, -1 }, /* Type 2 */ { "hlineto", 6, -1 }, { "hmoveto", 22, -1 }, - { "hsbw", 13, -1 }, /* Type 1 ONLY */ + { "hsbw", 13, -1 }, /* Type 1 ONLY */ { "hstem", 1, -1 }, - { "hstem3", 12, 2 }, /* Type 1 ONLY */ - { "hstemhm", 18, -1 }, /* Type 2 */ + { "hstem3", 12, 2 }, /* Type 1 ONLY */ + { "hstemhm", 18, -1 }, /* Type 2 */ { "hvcurveto", 31, -1 }, - { "ifelse", 12, 22 }, /* Type 2 */ - { "index", 12, 29 }, /* Type 2 */ - { "load", 12, 13 }, /* Type 2 */ - { "mul", 12, 24 }, /* Type 2 */ - { "neg", 12, 14 }, /* Type 2 */ - { "not", 12, 5 }, /* Type 2 */ - { "or", 12, 4 }, /* Type 2 */ - { "pop", 12, 17 }, /* Type 1 ONLY */ - { "put", 12, 20 }, /* Type 2 */ - { "random", 12, 23 }, /* Type 2 */ - { "rcurveline", 24, -1 }, /* Type 2 */ + { "ifelse", 12, 22 }, /* Type 2 */ + { "index", 12, 29 }, /* Type 2 */ + { "load", 12, 13 }, /* Type 2 */ + { "mul", 12, 24 }, /* Type 2 */ + { "neg", 12, 14 }, /* Type 2 */ + { "not", 12, 5 }, /* Type 2 */ + { "or", 12, 4 }, /* Type 2 */ + { "pop", 12, 17 }, /* Type 1 ONLY */ + { "put", 12, 20 }, /* Type 2 */ + { "random", 12, 23 }, /* Type 2 */ + { "rcurveline", 24, -1 }, /* Type 2 */ { "return", 11, -1 }, - { "rlinecurve", 25, -1 }, /* Type 2 */ + { "rlinecurve", 25, -1 }, /* Type 2 */ { "rlineto", 5, -1 }, { "rmoveto", 21, -1 }, - { "roll", 12, 30 }, /* Type 2 */ + { "roll", 12, 30 }, /* Type 2 */ { "rrcurveto", 8, -1 }, - { "sbw", 12, 7 }, /* Type 1 ONLY */ - { "seac", 12, 6 }, /* Type 1 ONLY */ + { "sbw", 12, 7 }, /* Type 1 ONLY */ + { "seac", 12, 6 }, /* Type 1 ONLY */ { "setcurrentpoint", 12, 33 }, /* Type 1 ONLY */ - { "sqrt", 12, 26 }, /* Type 2 */ - { "store", 12, 8 }, /* Type 2 */ - { "sub", 12, 11 }, /* Type 2 */ + { "sqrt", 12, 26 }, /* Type 2 */ + { "store", 12, 8 }, /* Type 2 */ + { "sub", 12, 11 }, /* Type 2 */ { "vhcurveto", 30, -1 }, { "vlineto", 7, -1 }, { "vmoveto", 4, -1 }, { "vstem", 3, -1 }, - { "vstem3", 12, 1 }, /* Type 1 ONLY */ - { "vstemhm", 23, -1 }, /* Type 2 */ - { "vvcurveto", 26, -1 }, /* Type 2 */ + { "vstem3", 12, 1 }, /* Type 1 ONLY */ + { "vstemhm", 23, -1 }, /* Type 2 */ + { "vvcurveto", 26, -1 }, /* Type 2 */ }; /* alphabetical */ /* Two separate encryption functions because eexec and charstring encryption @@ -211,8 +212,8 @@ static void output_byte(byte b) if (in_eexec) { /* trim hexadecimal lines to `blocklen' columns */ if (hexcol >= blocklen) { - putc('\n', ofp); - hexcol = 0; + putc('\n', ofp); + hexcol = 0; } putc(hexchar[(b >> 4) & 0xf], ofp); putc(hexchar[b & 0xf], ofp); @@ -298,10 +299,10 @@ static void t1utils_getline(void) else if (active && !comment && c == '{') { /* 25.Aug.1999 -- new check for whether we should stop be active */ if (check_line_charstring()) { - start_charstring = 1; - break; + start_charstring = 1; + break; } else - active = 0; + active = 0; } *p++ = (char) c; @@ -310,7 +311,7 @@ static void t1utils_getline(void) if (c == '\r') { c = getc(ifp); if (c != '\n') - ungetc(c, ifp); + ungetc(c, ifp); p[-1] = '\n'; break; } else if (c == '\n') @@ -465,8 +466,8 @@ static void get_charstring_token(void) *p++ = c; c = getc(ifp); if (c == EOF || isspace(c) || c == '%' || c == '}') { - ungetc(c, ifp); - break; + ungetc(c, ifp); + break; } } *p = 0; @@ -494,45 +495,45 @@ static void parse_charstring(void) int ok = 0; cp = (struct command *) - bsearch((void *) line, (void *) command_table, - sizeof(command_table) / sizeof(struct command), - sizeof(struct command), - command_compare); + bsearch((void *) line, (void *) command_table, + sizeof(command_table) / sizeof(struct command), + sizeof(struct command), + command_compare); if (cp) { - one = cp->one; - two = cp->two; - ok = 1; + one = cp->one; + two = cp->two; + ok = 1; } else if (strncmp(line, "escape_", 7) == 0) { - /* Parse the `escape' keyword requested by Lee Chun-Yu and Werner + /* Parse the `escape' keyword requested by Lee Chun-Yu and Werner Lemberg */ - one = 12; - if (sscanf(line + 7, "%d", &two) == 1) - ok = 1; + one = 12; + if (sscanf(line + 7, "%d", &two) == 1) + ok = 1; } else if (strncmp(line, "UNKNOWN_", 8) == 0) { - /* Allow unanticipated UNKNOWN commands. */ - one = 12; - if (sscanf(line + 8, "12_%d", &two) == 1) - ok = 1; - else if (sscanf(line + 8, "%d", &one) == 1) { - two = -1; - ok = 1; - } + /* Allow unanticipated UNKNOWN commands. */ + one = 12; + if (sscanf(line + 8, "12_%d", &two) == 1) + ok = 1; + else if (sscanf(line + 8, "%d", &one) == 1) { + two = -1; + ok = 1; + } } if (!ok) - error("unknown charstring command `%s'", line); + error("unknown charstring command `%s'", line); else if (one < 0 || one > 255) - error("bad charstring command number `%d'", one); + error("bad charstring command number `%d'", one); else if (two > 255) - error("bad charstring command number `%d'", two); + error("bad charstring command number `%d'", two); else if (two < 0) - charstring_byte(one); + charstring_byte(one); else { - charstring_byte(one); - charstring_byte(two); + charstring_byte(one); + charstring_byte(two); } } } @@ -544,12 +545,12 @@ static void parse_charstring(void) * Command line **/ -#define BLOCK_LEN_OPT 300 -#define OUTPUT_OPT 301 -#define VERSION_OPT 302 -#define HELP_OPT 303 -#define PFB_OPT 304 -#define PFA_OPT 305 +#define BLOCK_LEN_OPT 300 +#define OUTPUT_OPT 301 +#define VERSION_OPT 302 +#define HELP_OPT 303 +#define PFB_OPT 304 +#define PFA_OPT 305 static Clp_Option options[] = { { "block-length", 'l', BLOCK_LEN_OPT, Clp_ValInt, 0 }, @@ -590,7 +591,7 @@ short_usage(void) { fprintf(stderr, "Usage: %s [OPTION]... [INPUT [OUTPUT]]\n\ Try `%s --help' for more information.\n", - program_name, program_name); + program_name, program_name); } static void @@ -641,11 +642,11 @@ int main(int argc, char *argv[]) output_file: case OUTPUT_OPT: if (ofp) - fatal_error("output file already specified"); + fatal_error("output file already specified"); if (strcmp(clp->vstr, "-") == 0) - ofp = stdout; + ofp = stdout; else if (!(ofp = fopen(clp->vstr, "w"))) - fatal_error("%s: %s", clp->vstr, strerror(errno)); + fatal_error("%s: %s", clp->vstr, strerror(errno)); break; case PFB_OPT: @@ -663,7 +664,7 @@ int main(int argc, char *argv[]) case VERSION_OPT: printf("t1asm (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\ + printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -672,13 +673,13 @@ particular purpose.\n"); case Clp_NotOption: if (ifp && ofp) - fatal_error("too many arguments"); + fatal_error("too many arguments"); else if (ifp) - goto output_file; + goto output_file; if (strcmp(clp->vstr, "-") == 0) - ifp = stdin; + ifp = stdin; else if (!(ifp = fopen(clp->vstr, "r"))) - fatal_error("%s: %s", clp->vstr, strerror(errno)); + fatal_error("%s: %s", clp->vstr, strerror(errno)); break; case Clp_Done: @@ -738,41 +739,41 @@ particular purpose.\n"); if (!ever_active) { if (strncmp(line, "currentfile eexec", 17) == 0 && isspace((unsigned char) line[17])) { - /* Allow arbitrary whitespace after "currentfile eexec". - Thanks to Tom Kacvinsky <tjk@ams.org> for reporting this. - Note: strlen("currentfile eexec") == 17. */ - for (p = line + 18; isspace((unsigned char) *p); p++) - ; - eexec_start(p); - continue; + /* Allow arbitrary whitespace after "currentfile eexec". + Thanks to Tom Kacvinsky <tjk@ams.org> for reporting this. + Note: strlen("currentfile eexec") == 17. */ + for (p = line + 18; isspace((unsigned char) *p); p++) + ; + eexec_start(p); + continue; } else if (strncmp(line, "/lenIV", 6) == 0) { - set_lenIV(line); + set_lenIV(line, strlen(line)); } else if ((p = strstr(line, "string currentfile"))) { - set_cs_start(line); + set_cs_start(line, strlen(line)); } } if (!active) { if ((p = strstr(line, "/Subrs")) && isdigit((unsigned char) p[7])) - ever_active = active = 1; + ever_active = active = 1; else if ((p = strstr(line, "/CharStrings")) && isdigit((unsigned char) p[13])) - ever_active = active = 1; + ever_active = active = 1; } if ((p = strstr(line, "currentfile closefile"))) { /* 2/14/99 -- happy Valentine's day! -- don't look for `mark - currentfile closefile'; the `mark' might be on a different line */ + currentfile closefile'; the `mark' might be on a different line */ /* 1/3/2002 -- happy new year! -- Luc Devroye reports a failure with some printers when `currentfile closefile' is followed by space */ p += sizeof("currentfile closefile") - 1; for (q = p; isspace((unsigned char) *q) && *q != '\n'; q++) - /* nada */; + /* nada */; if (q == p && !*q) - error("warning: `currentfile closefile' line too long"); + error("warning: `currentfile closefile' line too long"); else if (q != p) { - if (*q != '\n') - error("text after `currentfile closefile' ignored"); - *p++ = '\n'; - *p++ = '\0'; + if (*q != '\n') + error("text after `currentfile closefile' ignored"); + *p++ = '\n'; + *p++ = '\0'; } eexec_string(line); break; @@ -783,7 +784,7 @@ particular purpose.\n"); /* output line data */ if (start_charstring) { if (!cs_start[0]) - fatal_error("couldn't find charstring start command"); + fatal_error("couldn't find charstring start command"); parse_charstring(); } } diff --git a/Build/source/utils/t1utils/t1utils-src/t1asmhelp.h b/Build/source/utils/t1utils/t1utils-src/t1asmhelp.h index 6c4b333c88e..fb7217464a8 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1asmhelp.h +++ b/Build/source/utils/t1utils/t1utils-src/t1asmhelp.h @@ -8,27 +8,35 @@ static int lenIV = 4; of each charstring. */ static void -set_lenIV(const char* line) +set_lenIV(const char* line, size_t line_len) { - char *p = strstr(line, "/lenIV "); + char* p = memmem(line, line_len, "/lenIV ", 7); /* Allow lenIV to be negative. Thanks to Tom Kacvinsky <tjk@ams.org> */ - if (p && (isdigit((unsigned char) p[7]) || p[7] == '+' || p[7] == '-')) { - lenIV = atoi(p + 7); + if (p && p + 7 < line + line_len) { + const char* x = p + 7 + (p[7] == '+' || p[7] == '-'); + if (x < line + line_len && isdigit((unsigned char) *x)) { + lenIV = (unsigned char) *x - '0'; + for (++x; x < line + line_len && isdigit((unsigned char) *x); ++x) + lenIV = 10 * lenIV + (unsigned char) *x - '0'; + if (p[7] == '-') + lenIV = -lenIV; + } } } + static char cs_start_init[] = ""; static char *cs_start = cs_start_init; static void -set_cs_start(const char* line) +set_cs_start(const char* line, size_t line_len) { static int cs_start_set = 0; char *p, *q, *r; - if ((p = strstr(line, "string currentfile")) - && strstr(line, "readstring")) { + if ((p = memmem(line, line_len, "string currentfile", 18)) + && memmem(line, line_len, "readstring", 10)) { /* locate the name of the charstring start command */ for (q = p; q != line && q[-1] != '/'; --q) /* nada */; diff --git a/Build/source/utils/t1utils/t1utils-src/t1binary.1 b/Build/source/utils/t1utils/t1utils-src/t1binary.1 index 19d04b5b161..9574b394989 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1binary.1 +++ b/Build/source/utils/t1utils/t1utils-src/t1binary.1 @@ -1,4 +1,4 @@ -.ds V 1.39 +.ds V 1.41 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/utils/t1utils/t1utils-src/t1binary.c b/Build/source/utils/t1utils/t1utils-src/t1binary.c index a8ca6f74fc6..240617ada0b 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1binary.c +++ b/Build/source/utils/t1utils/t1utils-src/t1binary.c @@ -4,7 +4,7 @@ * converts it to binary (PFB) format. * * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -215,7 +215,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1binary (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\ + printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff --git a/Build/source/utils/t1utils/t1utils-src/t1disasm.1 b/Build/source/utils/t1utils/t1utils-src/t1disasm.1 index 308241c91bc..f9ff3b54281 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1disasm.1 +++ b/Build/source/utils/t1utils/t1utils-src/t1disasm.1 @@ -1,4 +1,4 @@ -.ds V 1.39 +.ds V 1.41 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/utils/t1utils/t1utils-src/t1disasm.c b/Build/source/utils/t1utils/t1utils-src/t1disasm.c index 92901719e28..4382f6839b7 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1disasm.c +++ b/Build/source/utils/t1utils/t1utils-src/t1disasm.c @@ -8,7 +8,7 @@ * PFA format. * * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -82,7 +82,8 @@ static FILE *ofp; static int unknown = 0; /* decryption stuff */ -static uint16_t c1 = 52845, c2 = 22719; +static const uint32_t c1 = 52845; +static const uint32_t c2 = 22719; static uint16_t cr_default = 4330; static uint16_t er_default = 55665; @@ -106,11 +107,11 @@ output_token(const char *token) { static int start = 1; if (strcmp(token, "\n") == 0) { - fprintf(ofp, "\n"); - start = 1; + fprintf(ofp, "\n"); + start = 1; } else { - fprintf(ofp, "%s%s", start ? "\t" : " ", token); - start = 0; + fprintf(ofp, "%s%s", start ? "\t" : " ", token); + start = 0; } } @@ -147,31 +148,33 @@ decrypt_charstring(unsigned char *line, int len) if (b >= 32) { if (b >= 32 && b <= 246) - val = b - 139; + val = b - 139; else if (b >= 247 && b <= 250) { - i++; - val = (b - 247)*256 + 108 + line[i]; + i++; + val = (b - 247)*256 + 108 + line[i]; } else if (b >= 251 && b <= 254) { - i++; - val = -(b - 251)*256 - 108 - line[i]; + i++; + val = -(b - 251)*256 - 108 - line[i]; } else { - val = (line[i+1] & 0xff) << 24; - val |= (line[i+2] & 0xff) << 16; - val |= (line[i+3] & 0xff) << 8; - val |= (line[i+4] & 0xff) << 0; - /* in case an int32 is larger than four bytes---sign extend */ + uint32_t uval; + uval = (uint32_t) line[i+1] << 24; + uval |= (uint32_t) line[i+2] << 16; + uval |= (uint32_t) line[i+3] << 8; + uval |= (uint32_t) line[i+4] << 0; + /* in case an int32 is larger than four bytes---sign extend */ #if INT_MAX > 0x7FFFFFFFUL - if (val & 0x80000000) - val |= ~0x7FFFFFFF; + if (uval & 0x80000000U) + uval |= ~0x7FFFFFFFU; #endif - i += 4; + val = (int32_t) uval; + i += 4; } sprintf(buf, "%d", val); output_token(buf); } else { switch (b) { - case 0: output_token("error"); break; /* special */ + case 0: output_token("error"); break; /* special */ case 1: output_token("hstem"); break; case 3: output_token("vstem"); break; case 4: output_token("vmoveto"); break; @@ -179,80 +182,80 @@ decrypt_charstring(unsigned char *line, int len) case 6: output_token("hlineto"); break; case 7: output_token("vlineto"); break; case 8: output_token("rrcurveto"); break; - case 9: output_token("closepath"); break; /* Type 1 ONLY */ + case 9: output_token("closepath"); break; /* Type 1 ONLY */ case 10: output_token("callsubr"); break; case 11: output_token("return"); break; - case 13: output_token("hsbw"); break; /* Type 1 ONLY */ + case 13: output_token("hsbw"); break; /* Type 1 ONLY */ case 14: output_token("endchar"); break; - case 16: output_token("blend"); break; /* Type 2 */ - case 18: output_token("hstemhm"); break; /* Type 2 */ - case 19: output_token("hintmask"); break; /* Type 2 */ - case 20: output_token("cntrmask"); break; /* Type 2 */ + case 16: output_token("blend"); break; /* Type 2 */ + case 18: output_token("hstemhm"); break; /* Type 2 */ + case 19: output_token("hintmask"); break; /* Type 2 */ + case 20: output_token("cntrmask"); break; /* Type 2 */ case 21: output_token("rmoveto"); break; case 22: output_token("hmoveto"); break; - case 23: output_token("vstemhm"); break; /* Type 2 */ - case 24: output_token("rcurveline"); break; /* Type 2 */ - case 25: output_token("rlinecurve"); break; /* Type 2 */ - case 26: output_token("vvcurveto"); break; /* Type 2 */ - case 27: output_token("hhcurveto"); break; /* Type 2 */ - case 28: { /* Type 2 */ - /* short integer */ - val = (line[i+1] & 0xff) << 8; - val |= (line[i+2] & 0xff); - i += 2; - if (val & 0x8000) - val |= ~0x7FFF; - sprintf(buf, "%d", val); - output_token(buf); + case 23: output_token("vstemhm"); break; /* Type 2 */ + case 24: output_token("rcurveline"); break; /* Type 2 */ + case 25: output_token("rlinecurve"); break; /* Type 2 */ + case 26: output_token("vvcurveto"); break; /* Type 2 */ + case 27: output_token("hhcurveto"); break; /* Type 2 */ + case 28: { /* Type 2 */ + /* short integer */ + val = (line[i+1] & 0xff) << 8; + val |= (line[i+2] & 0xff); + i += 2; + if (val & 0x8000) + val |= ~0x7FFF; + sprintf(buf, "%d", val); + output_token(buf); } - case 29: output_token("callgsubr"); break; /* Type 2 */ + case 29: output_token("callgsubr"); break; /* Type 2 */ case 30: output_token("vhcurveto"); break; case 31: output_token("hvcurveto"); break; case 12: - i++; - b = line[i]; - switch (b) { - case 0: output_token("dotsection"); break; /* Type 1 ONLY */ - case 1: output_token("vstem3"); break; /* Type 1 ONLY */ - case 2: output_token("hstem3"); break; /* Type 1 ONLY */ - case 3: output_token("and"); break; /* Type 2 */ - case 4: output_token("or"); break; /* Type 2 */ - case 5: output_token("not"); break; /* Type 2 */ - case 6: output_token("seac"); break; /* Type 1 ONLY */ - case 7: output_token("sbw"); break; /* Type 1 ONLY */ - case 8: output_token("store"); break; /* Type 2 */ - case 9: output_token("abs"); break; /* Type 2 */ - case 10: output_token("add"); break; /* Type 2 */ - case 11: output_token("sub"); break; /* Type 2 */ - case 12: output_token("div"); break; - case 13: output_token("load"); break; /* Type 2 */ - case 14: output_token("neg"); break; /* Type 2 */ - case 15: output_token("eq"); break; /* Type 2 */ - case 16: output_token("callothersubr"); break; /* Type 1 ONLY */ - case 17: output_token("pop"); break; /* Type 1 ONLY */ - case 18: output_token("drop"); break; /* Type 2 */ - case 20: output_token("put"); break; /* Type 2 */ - case 21: output_token("get"); break; /* Type 2 */ - case 22: output_token("ifelse"); break; /* Type 2 */ - case 23: output_token("random"); break; /* Type 2 */ - case 24: output_token("mul"); break; /* Type 2 */ - case 26: output_token("sqrt"); break; /* Type 2 */ - case 27: output_token("dup"); break; /* Type 2 */ - case 28: output_token("exch"); break; /* Type 2 */ - case 29: output_token("index"); break; /* Type 2 */ - case 30: output_token("roll"); break; /* Type 2 */ - case 33: output_token("setcurrentpoint"); break;/* Type 1 ONLY */ - case 34: output_token("hflex"); break; /* Type 2 */ - case 35: output_token("flex"); break; /* Type 2 */ - case 36: output_token("hflex1"); break; /* Type 2 */ - case 37: output_token("flex1"); break; /* Type 2 */ - default: - sprintf(buf, "escape_%d", b); - unknown++; - output_token(buf); - break; - } - break; + i++; + b = line[i]; + switch (b) { + case 0: output_token("dotsection"); break; /* Type 1 ONLY */ + case 1: output_token("vstem3"); break; /* Type 1 ONLY */ + case 2: output_token("hstem3"); break; /* Type 1 ONLY */ + case 3: output_token("and"); break; /* Type 2 */ + case 4: output_token("or"); break; /* Type 2 */ + case 5: output_token("not"); break; /* Type 2 */ + case 6: output_token("seac"); break; /* Type 1 ONLY */ + case 7: output_token("sbw"); break; /* Type 1 ONLY */ + case 8: output_token("store"); break; /* Type 2 */ + case 9: output_token("abs"); break; /* Type 2 */ + case 10: output_token("add"); break; /* Type 2 */ + case 11: output_token("sub"); break; /* Type 2 */ + case 12: output_token("div"); break; + case 13: output_token("load"); break; /* Type 2 */ + case 14: output_token("neg"); break; /* Type 2 */ + case 15: output_token("eq"); break; /* Type 2 */ + case 16: output_token("callothersubr"); break; /* Type 1 ONLY */ + case 17: output_token("pop"); break; /* Type 1 ONLY */ + case 18: output_token("drop"); break; /* Type 2 */ + case 20: output_token("put"); break; /* Type 2 */ + case 21: output_token("get"); break; /* Type 2 */ + case 22: output_token("ifelse"); break; /* Type 2 */ + case 23: output_token("random"); break; /* Type 2 */ + case 24: output_token("mul"); break; /* Type 2 */ + case 26: output_token("sqrt"); break; /* Type 2 */ + case 27: output_token("dup"); break; /* Type 2 */ + case 28: output_token("exch"); break; /* Type 2 */ + case 29: output_token("index"); break; /* Type 2 */ + case 30: output_token("roll"); break; /* Type 2 */ + case 33: output_token("setcurrentpoint"); break;/* Type 1 ONLY */ + case 34: output_token("hflex"); break; /* Type 2 */ + case 35: output_token("flex"); break; /* Type 2 */ + case 36: output_token("hflex1"); break; /* Type 2 */ + case 37: output_token("flex1"); break; /* Type 2 */ + default: + sprintf(buf, "escape_%d", b); + unknown++; + output_token(buf); + break; + } + break; default: sprintf(buf, "UNKNOWN_%d", b); unknown++; @@ -299,24 +302,36 @@ append_save(const unsigned char *line, int len) save_len += len; } -/* 23.Feb.2004 - use 'memstr', not strstr, because the strings input to - eexec_line aren't null terminated! Reported by Werner Lemberg. */ -static unsigned char * -oog_memstr(unsigned char *line, int line_len, const char *pattern, int pattern_len) +static unsigned char* +check_eexec_charstrings_begin(unsigned char* line, int line_len) { - unsigned char *try; - unsigned char *last = line + line_len - pattern_len + 1; - while (line < last - && (try = memchr(line, (unsigned char)*pattern, last - line))) { - if (memcmp(try, pattern, pattern_len) == 0) - return try; - else - line = try + 1; - } - return 0; + unsigned char* line_end = line + line_len; + line = memmem(line, line_len, "/CharStrings ", 13); + if (!line) + return 0; + line += 13; + while (line < line_end && isspace(*line)) + ++line; + if (line == line_end || !isdigit(*line)) + return 0; + while (line < line_end && isdigit(*line)) + ++line; + if (line == line_end || !isspace(*line)) + return 0; + while (line < line_end && isspace(*line)) + ++line; + if (line_end - line < 14 || memcmp(line, "dict dup begin", 14) != 0) + return 0; + line += 14; + while (line < line_end && isspace(*line)) + ++line; + if (line == line_end || *line != '/') + return 0; + return line; } + /* returns 1 if next \n should be deleted */ static int @@ -330,69 +345,69 @@ eexec_line(unsigned char *line, int line_len) /* append this data to the end of `save' if necessary */ if (save_len) { - append_save(line, line_len); - line = save; - line_len = save_len; + append_save(line, line_len); + line = save; + line_len = save_len; save_len = 0; } if (!line_len) - return 0; + return 0; /* Look for charstring start */ /* skip first word */ for (pos = 0; pos < line_len && isspace(line[pos]); pos++) - ; + ; while (pos < line_len && !isspace(line[pos])) - pos++; + pos++; if (pos >= line_len) - goto not_charstring; + goto not_charstring; /* skip spaces */ first_space = pos; while (pos < line_len && isspace(line[pos])) - pos++; + pos++; if (pos >= line_len || !isdigit(line[pos])) - goto not_charstring; + goto not_charstring; /* skip number */ digits = pos; while (pos < line_len && isdigit(line[pos])) - pos++; + pos++; /* check for subr (another number) */ if (pos < line_len - 1 && isspace(line[pos]) && isdigit(line[pos+1])) { - first_space = pos; - digits = pos + 1; - for (pos = digits; pos < line_len && isdigit(line[pos]); pos++) - ; + first_space = pos; + digits = pos + 1; + for (pos = digits; pos < line_len && isdigit(line[pos]); pos++) + ; } /* check for charstring start */ if (pos + 2 + cs_start_len < line_len - && pos > digits - && line[pos] == ' ' - && strncmp((const char *)(line + pos + 1), cs_start, cs_start_len) == 0 - && line[pos + 1 + cs_start_len] == ' ') { - /* check if charstring is long enough */ - int cs_len = atoi((const char *)(line + digits)); - if (pos + 2 + cs_start_len + cs_len < line_len) { - /* long enough! */ - if (line[line_len - 1] == '\r') { - line[line_len - 1] = '\n'; - cut_newline = 1; - } - fprintf(ofp, "%.*s {\n", first_space, line); - decrypt_charstring(line + pos + 2 + cs_start_len, cs_len); - pos += 2 + cs_start_len + cs_len; - fprintf(ofp, "\t}%.*s", line_len - pos, line + pos); - return cut_newline; - } else { - /* not long enough! */ + && pos > digits + && line[pos] == ' ' + && strncmp((const char *)(line + pos + 1), cs_start, cs_start_len) == 0 + && line[pos + 1 + cs_start_len] == ' ') { + /* check if charstring is long enough */ + int cs_len = atoi((const char *)(line + digits)); + if (pos + 2 + cs_start_len + cs_len < line_len) { + /* long enough! */ + if (line[line_len - 1] == '\r') { + line[line_len - 1] = '\n'; + cut_newline = 1; + } + fprintf(ofp, "%.*s {\n", first_space, line); + decrypt_charstring(line + pos + 2 + cs_start_len, cs_len); + pos += 2 + cs_start_len + cs_len; + fprintf(ofp, "\t}%.*s", line_len - pos, line + pos); + return cut_newline; + } else { + /* not long enough! */ append_save(line, line_len); - return 0; - } + return 0; + } } /* otherwise, just output the line */ @@ -401,30 +416,25 @@ eexec_line(unsigned char *line, int line_len) badly: a charstring definition follows "/Charstrings ... begin", ON THE SAME LINE. */ { - char *CharStrings = (char *) - oog_memstr(line, line_len, "/CharStrings ", 13); - int crap, n; - char should_be_slash = 0; - if (CharStrings - && sscanf(CharStrings + 12, " %d dict dup begin %c%n", &crap, &should_be_slash, &n) >= 2 - && should_be_slash == '/') { - int len = (CharStrings + 12 + n - 1) - (char *) line; - fprintf(ofp, "%.*s\n", len, line); - return eexec_line((unsigned char *) (CharStrings + 12 + n - 1), line_len - len); - } + unsigned char* csbegin = check_eexec_charstrings_begin(line, line_len); + if (csbegin) { + int len = csbegin - line; + fprintf(ofp, "%.*s\n", len, line); + return eexec_line(csbegin, line_len - len); + } } if (line[line_len - 1] == '\r') { - line[line_len - 1] = '\n'; - cut_newline = 1; + line[line_len - 1] = '\n'; + cut_newline = 1; } - set_lenIV((char *)line); - set_cs_start((char *)line); + set_lenIV((char*) line, line_len); + set_cs_start((char*) line, line_len); fprintf(ofp, "%.*s", line_len, line); /* look for `currentfile closefile' to see if we should stop decrypting */ - if (oog_memstr(line, line_len, "currentfile closefile", 21) != 0) - in_eexec = -1; + if (memmem(line, line_len, "currentfile closefile", 21) != 0) + in_eexec = -1; return cut_newline; } @@ -433,9 +443,9 @@ static int all_zeroes(const char *string) { if (*string != '0') - return 0; + return 0; while (*string == '0') - string++; + string++; return *string == '\0' || *string == '\n'; } @@ -443,53 +453,53 @@ static void disasm_output_ascii(char *line, int len) { int was_in_eexec = in_eexec; - (void) len; /* avoid warning */ + (void) len; /* avoid warning */ in_eexec = 0; /* if we came from a binary section, we need to process that too */ if (was_in_eexec > 0) { - unsigned char zero = 0; - eexec_line(&zero, 0); + unsigned char zero = 0; + eexec_line(&zero, 0); } /* if we just came from the "ASCII part" of an eexec section, we need to process the saved lines */ if (was_in_eexec < 0) { - int i = 0; - int save_char = 0; /* note: save[] is unsigned char * */ - - while (i < save_len) { - /* grab a line */ - int start = i; - while (i < save_len && save[i] != '\r' && save[i] != '\n') - i++; - if (i < save_len) { - if (i < save_len - 1 && save[i] == '\r' && save[i+1] == '\n') - save_char = -1; - else - save_char = save[i+1]; - save[i] = '\n'; - save[i+1] = 0; - } else - save[i] = 0; - - /* output it */ - disasm_output_ascii((char *)(save + start), -1); - - /* repair damage */ - if (i < save_len) { - if (save_char >= 0) { - save[i+1] = save_char; - i++; - } else - i += 2; - } - } - save_len = 0; + int i = 0; + int save_char = 0; /* note: save[] is unsigned char * */ + + while (i < save_len) { + /* grab a line */ + int start = i; + while (i < save_len && save[i] != '\r' && save[i] != '\n') + i++; + if (i < save_len) { + if (i < save_len - 1 && save[i] == '\r' && save[i+1] == '\n') + save_char = -1; + else + save_char = save[i+1]; + save[i] = '\n'; + save[i+1] = 0; + } else + save[i] = 0; + + /* output it */ + disasm_output_ascii((char *)(save + start), -1); + + /* repair damage */ + if (i < save_len) { + if (save_char >= 0) { + save[i+1] = save_char; + i++; + } else + i += 2; + } + } + save_len = 0; } if (!all_zeroes(line)) - output(line); + output(line); } /* collect until '\n' or end of binary section */ @@ -505,61 +515,61 @@ disasm_output_binary(unsigned char *data, int len) /* in the ASCII portion of a binary section, just save this data */ if (in_eexec < 0) { - append_save(data, len); - return; + append_save(data, len); + return; } /* eexec initialization */ if (in_eexec == 0) { - er = er_default; - ignore_newline = 0; - in_eexec = 0; + er = er_default; + ignore_newline = 0; + in_eexec = 0; } if (in_eexec < 4) { - for (i = 0; i < len && in_eexec < 4; i++, in_eexec++) { - byte cipher = data[i]; - plain = (byte)(cipher ^ (er >> 8)); - er = (uint16_t)((cipher + er) * c1 + c2); - data[i] = plain; - } - data += i; - len -= i; + for (i = 0; i < len && in_eexec < 4; i++, in_eexec++) { + byte cipher = data[i]; + plain = (byte)(cipher ^ (er >> 8)); + er = (uint16_t)((cipher + er) * c1 + c2); + data[i] = plain; + } + data += i; + len -= i; } /* now make lines: collect until '\n' or '\r' and pass them off to eexec_line. */ i = 0; while (in_eexec > 0) { - int start = i; - - for (; i < len; i++) { - byte cipher = data[i]; - plain = (byte)(cipher ^ (er >> 8)); - er = (uint16_t)((cipher + er) * c1 + c2); - data[i] = plain; - if (plain == '\r' || plain == '\n') - break; - } - - if (ignore_newline && start < i && data[start] == '\n') { - ignore_newline = 0; - continue; - } - - if (i >= len) { - if (start < len) - append_save(data + start, i - start); - break; - } - - i++; - ignore_newline = eexec_line(data + start, i - start); + int start = i; + + for (; i < len; i++) { + byte cipher = data[i]; + plain = (byte)(cipher ^ (er >> 8)); + er = (uint16_t)((cipher + er) * c1 + c2); + data[i] = plain; + if (plain == '\r' || plain == '\n') + break; + } + + if (ignore_newline && start < i && data[start] == '\n') { + ignore_newline = 0; + continue; + } + + if (i >= len) { + if (start < len) + append_save(data + start, i - start); + break; + } + + i++; + ignore_newline = eexec_line(data + start, i - start); } /* if in_eexec < 0, we have some plaintext lines sitting around in a binary section of the PFB. save them for later */ if (in_eexec < 0 && i < len) - append_save(data + i, len - i); + append_save(data + i, len - i); } static void @@ -575,9 +585,9 @@ disasm_output_end(void) * Command line **/ -#define OUTPUT_OPT 301 -#define VERSION_OPT 302 -#define HELP_OPT 303 +#define OUTPUT_OPT 301 +#define VERSION_OPT 302 +#define HELP_OPT 303 static Clp_Option options[] = { { "help", 0, HELP_OPT, 0, 0 }, @@ -615,7 +625,7 @@ short_usage(void) { fprintf(stderr, "Usage: %s [INPUT [OUTPUT]]\n\ Try `%s --help' for more information.\n", - program_name, program_name); + program_name, program_name); } static void @@ -661,12 +671,12 @@ main(int argc, char *argv[]) output_file: case OUTPUT_OPT: if (ofp) - fatal_error("output file already specified"); + fatal_error("output file already specified"); if (strcmp(clp->vstr, "-") == 0) - ofp = stdout; + ofp = stdout; else { - ofp = fopen(clp->vstr, "w"); - if (!ofp) fatal_error("%s: %s", clp->vstr, strerror(errno)); + ofp = fopen(clp->vstr, "w"); + if (!ofp) fatal_error("%s: %s", clp->vstr, strerror(errno)); } break; @@ -677,7 +687,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1disasm (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\ + printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -686,15 +696,15 @@ particular purpose.\n"); case Clp_NotOption: if (ifp && ofp) - fatal_error("too many arguments"); + fatal_error("too many arguments"); else if (ifp) - goto output_file; + goto output_file; if (strcmp(clp->vstr, "-") == 0) - ifp = stdin; + ifp = stdin; else { - ifp_filename = clp->vstr; - ifp = fopen(clp->vstr, "rb"); - if (!ifp) fatal_error("%s: %s", clp->vstr, strerror(errno)); + ifp_filename = clp->vstr; + ifp = fopen(clp->vstr, "rb"); + if (!ifp) fatal_error("%s: %s", clp->vstr, strerror(errno)); } break; @@ -742,9 +752,9 @@ particular purpose.\n"); if (unknown) error((unknown > 1 - ? "encountered %d unknown charstring commands" - : "encountered %d unknown charstring command"), - unknown); + ? "encountered %d unknown charstring commands" + : "encountered %d unknown charstring command"), + unknown); return (error_count ? 1 : 0); } diff --git a/Build/source/utils/t1utils/t1utils-src/t1lib.c b/Build/source/utils/t1utils/t1utils-src/t1lib.c index 28df311b0ab..80af787dc06 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1lib.c +++ b/Build/source/utils/t1utils/t1utils-src/t1lib.c @@ -2,7 +2,7 @@ * * This file contains functions for reading PFA and PFB files. * - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the diff --git a/Build/source/utils/t1utils/t1utils-src/t1mac.1 b/Build/source/utils/t1utils/t1utils-src/t1mac.1 index a65fdc801c5..e48af31dbe3 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1mac.1 +++ b/Build/source/utils/t1utils/t1utils-src/t1mac.1 @@ -1,4 +1,4 @@ -.ds V 1.39 +.ds V 1.41 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/utils/t1utils/t1utils-src/t1mac.c b/Build/source/utils/t1utils/t1utils-src/t1mac.c index 617ad0189cb..3b5657e1075 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1mac.c +++ b/Build/source/utils/t1utils/t1utils-src/t1mac.c @@ -4,7 +4,7 @@ * 1 fonts stored in MacBinary (I or II), AppleSingle, AppleDouble, BinHex, or * raw resource fork format. * - * Copyright (c) 2000-2013 Eddie Kohler + * Copyright (c) 2000-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -899,7 +899,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1mac (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 2000-2010 Eddie Kohler et al.\n\ + printf("Copyright (C) 2000-2017 Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -949,7 +949,7 @@ particular purpose.\n"); /* prepare resource fork file */ rfork_f = tmpfile(); if (!rfork_f) - fatal_error("cannot open temorary file: %s", strerror(errno)); + fatal_error("cannot open temporary file: %s", strerror(errno)); for (i = 0; i < RFORK_HEADERLEN; i++) putc(0, rfork_f); init_current_post(); diff --git a/Build/source/utils/t1utils/t1utils-src/t1unmac.1 b/Build/source/utils/t1utils/t1utils-src/t1unmac.1 index 372bb74ccd8..a86c9ea15af 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1unmac.1 +++ b/Build/source/utils/t1utils/t1utils-src/t1unmac.1 @@ -1,4 +1,4 @@ -.ds V 1.39 +.ds V 1.41 .de M .BR "\\$1" "(\\$2)\\$3" .. diff --git a/Build/source/utils/t1utils/t1utils-src/t1unmac.c b/Build/source/utils/t1utils/t1utils-src/t1unmac.c index feadbfac65e..b4ffed3921b 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1unmac.c +++ b/Build/source/utils/t1utils/t1utils-src/t1unmac.c @@ -5,7 +5,7 @@ * PFB formats. * * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -615,7 +615,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1unmac (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\ + printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); diff --git a/Build/source/utils/t1utils/t1utils-src/t1utils.spec b/Build/source/utils/t1utils/t1utils-src/t1utils.spec deleted file mode 100644 index 3013d8b4041..00000000000 --- a/Build/source/utils/t1utils/t1utils-src/t1utils.spec +++ /dev/null @@ -1,53 +0,0 @@ -Summary: Programs for manipulating PostScript Type 1 fonts - -Name: t1utils -Version: 1.39 -Release: 1 -Source: http://www.lcdf.org/type/t1utils-1.39.tar.gz - -URL: http://www.lcdf.org/type/ - -Group: Utilities/Printing -Vendor: Little Cambridgeport Design Factory -Packager: Eddie Kohler <ekohler@gmail.com> -License: freely modifiable and distributable - -BuildRoot: /tmp/t1utils-build - -%description -The t1utils package is a set of programs for -manipulating PostScript Type 1 fonts. It contains -programs to change between binary PFB format (for -storage), ASCII PFA format (for printing), a -human-readable and -editable ASCII format, and -Macintosh resource forks. - -%prep -%setup - -%build -%configure -make - -%install -[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT install - -%clean -[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT - -%files -%attr(-,root,root) %doc NEWS README -%attr(0755,root,root) %{_bindir}/t1ascii -%attr(0755,root,root) %{_bindir}/t1binary -%attr(0755,root,root) %{_bindir}/t1asm -%attr(0755,root,root) %{_bindir}/t1disasm -%attr(0755,root,root) %{_bindir}/t1unmac -%attr(0755,root,root) %{_bindir}/t1mac -%attr(0644,root,root) %{_mandir}/man1/t1ascii.1* -%attr(0644,root,root) %{_mandir}/man1/t1binary.1* -%attr(0644,root,root) %{_mandir}/man1/t1asm.1* -%attr(0644,root,root) %{_mandir}/man1/t1disasm.1* -%attr(0644,root,root) %{_mandir}/man1/t1unmac.1* -%attr(0644,root,root) %{_mandir}/man1/t1mac.1* |