• R/O
  • SSH
  • HTTPS

tsukurimashou: Commit


Commit MetaInfo

Revision247 (tree)
Time2012-03-29 13:17:06
Authormskala

Log Message

bundle t1asm

Change Summary

Incremental Difference

--- trunk/m4/ax_create_stdint_h.m4 (nonexistent)
+++ trunk/m4/ax_create_stdint_h.m4 (revision 247)
@@ -0,0 +1,727 @@
1+# ===========================================================================
2+# http://www.gnu.org/software/autoconf-archive/ax_create_stdint_h.html
3+# ===========================================================================
4+#
5+# SYNOPSIS
6+#
7+# AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])]
8+#
9+# DESCRIPTION
10+#
11+# the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
12+# existence of an include file <stdint.h> that defines a set of typedefs,
13+# especially uint8_t,int32_t,uintptr_t. Many older installations will not
14+# provide this file, but some will have the very same definitions in
15+# <inttypes.h>. In other enviroments we can use the inet-types in
16+# <sys/types.h> which would define the typedefs int8_t and u_int8_t
17+# respectivly.
18+#
19+# This macros will create a local "_stdint.h" or the headerfile given as
20+# an argument. In many cases that file will just "#include <stdint.h>" or
21+# "#include <inttypes.h>", while in other environments it will provide the
22+# set of basic 'stdint's definitions/typedefs:
23+#
24+# int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
25+# int_least32_t.. int_fast32_t.. intmax_t
26+#
27+# which may or may not rely on the definitions of other files, or using
28+# the AC_CHECK_SIZEOF macro to determine the actual sizeof each type.
29+#
30+# if your header files require the stdint-types you will want to create an
31+# installable file mylib-int.h that all your other installable header may
32+# include. So if you have a library package named "mylib", just use
33+#
34+# AX_CREATE_STDINT_H(mylib-int.h)
35+#
36+# in configure.ac and go to install that very header file in Makefile.am
37+# along with the other headers (mylib.h) - and the mylib-specific headers
38+# can simply use "#include <mylib-int.h>" to obtain the stdint-types.
39+#
40+# Remember, if the system already had a valid <stdint.h>, the generated
41+# file will include it directly. No need for fuzzy HAVE_STDINT_H things...
42+# (oops, GCC 4.2.x has deliberatly disabled its stdint.h for non-c99
43+# compilation and the c99-mode is not the default. Therefore this macro
44+# will not use the compiler's stdint.h - please complain to the GCC
45+# developers).
46+#
47+# LICENSE
48+#
49+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
50+#
51+# This program is free software; you can redistribute it and/or modify it
52+# under the terms of the GNU General Public License as published by the
53+# Free Software Foundation; either version 3 of the License, or (at your
54+# option) any later version.
55+#
56+# This program is distributed in the hope that it will be useful, but
57+# WITHOUT ANY WARRANTY; without even the implied warranty of
58+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
59+# Public License for more details.
60+#
61+# You should have received a copy of the GNU General Public License along
62+# with this program. If not, see <http://www.gnu.org/licenses/>.
63+#
64+# As a special exception, the respective Autoconf Macro's copyright owner
65+# gives unlimited permission to copy, distribute and modify the configure
66+# scripts that are the output of Autoconf when processing the Macro. You
67+# need not follow the terms of the GNU General Public License when using
68+# or distributing such scripts, even though portions of the text of the
69+# Macro appear in them. The GNU General Public License (GPL) does govern
70+# all other use of the material that constitutes the Autoconf Macro.
71+#
72+# This special exception to the GPL applies to versions of the Autoconf
73+# Macro released by the Autoconf Archive. When you make and distribute a
74+# modified version of the Autoconf Macro, you may extend this special
75+# exception to the GPL to apply to your modified version as well.
76+
77+#serial 10
78+
79+AC_DEFUN([AX_CHECK_DATA_MODEL],[
80+ AC_CHECK_SIZEOF(char)
81+ AC_CHECK_SIZEOF(short)
82+ AC_CHECK_SIZEOF(int)
83+ AC_CHECK_SIZEOF(long)
84+ AC_CHECK_SIZEOF(void*)
85+ ac_cv_char_data_model=""
86+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char"
87+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short"
88+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int"
89+ ac_cv_long_data_model=""
90+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int"
91+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long"
92+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp"
93+ AC_MSG_CHECKING([data model])
94+ case "$ac_cv_char_data_model/$ac_cv_long_data_model" in
95+ 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;;
96+ 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;;
97+ 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;;
98+ 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;;
99+ 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;;
100+ 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;;
101+ 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;;
102+ 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;;
103+ 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;;
104+ 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;;
105+ 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;;
106+ 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;;
107+ 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;;
108+ 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;;
109+ 222/*|333/*|444/*|666/*|888/*) :
110+ ac_cv_data_model="iDSP" ; n="unusual dsptype" ;;
111+ *) ac_cv_data_model="none" ; n="very unusual model" ;;
112+ esac
113+ AC_MSG_RESULT([$ac_cv_data_model ($ac_cv_long_data_model, $n)])
114+])
115+
116+dnl AX_CHECK_HEADER_STDINT_X([HEADERLIST][,ACTION-IF])
117+AC_DEFUN([AX_CHECK_HEADER_STDINT_X],[
118+AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[
119+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
120+ AC_MSG_RESULT([(..)])
121+ for i in m4_ifval([$1],[$1],[stdint.h inttypes.h sys/inttypes.h sys/types.h])
122+ do
123+ unset ac_cv_type_uintptr_t
124+ unset ac_cv_type_uint64_t
125+ AC_CHECK_TYPE(uintptr_t,[ac_cv_header_stdint_x=$i],continue,[#include <$i>])
126+ AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
127+ m4_ifvaln([$2],[$2]) break
128+ done
129+ AC_MSG_CHECKING([for stdint uintptr_t])
130+ ])
131+])
132+
133+AC_DEFUN([AX_CHECK_HEADER_STDINT_O],[
134+AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[
135+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
136+ AC_MSG_RESULT([(..)])
137+ for i in m4_ifval([$1],[$1],[inttypes.h sys/inttypes.h sys/types.h stdint.h])
138+ do
139+ unset ac_cv_type_uint32_t
140+ unset ac_cv_type_uint64_t
141+ AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],continue,[#include <$i>])
142+ AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
143+ m4_ifvaln([$2],[$2]) break
144+ break;
145+ done
146+ AC_MSG_CHECKING([for stdint uint32_t])
147+ ])
148+])
149+
150+AC_DEFUN([AX_CHECK_HEADER_STDINT_U],[
151+AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[
152+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
153+ AC_MSG_RESULT([(..)])
154+ for i in m4_ifval([$1],[$1],[sys/types.h inttypes.h sys/inttypes.h]) ; do
155+ unset ac_cv_type_u_int32_t
156+ unset ac_cv_type_u_int64_t
157+ AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],continue,[#include <$i>])
158+ AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>])
159+ m4_ifvaln([$2],[$2]) break
160+ break;
161+ done
162+ AC_MSG_CHECKING([for stdint u_int32_t])
163+ ])
164+])
165+
166+AC_DEFUN([AX_CREATE_STDINT_H],
167+[# ------ AX CREATE STDINT H -------------------------------------
168+AC_MSG_CHECKING([for stdint types])
169+ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
170+# try to shortcircuit - if the default include path of the compiler
171+# can find a "stdint.h" header then we assume that all compilers can.
172+AC_CACHE_VAL([ac_cv_header_stdint_t],[
173+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
174+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
175+old_CFLAGS="$CFLAGS" ; CFLAGS=""
176+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
177+[ac_cv_stdint_result="(assuming C99 compatible system)"
178+ ac_cv_header_stdint_t="stdint.h"; ],
179+[ac_cv_header_stdint_t=""])
180+if test "$GCC" = "yes" && test ".$ac_cv_header_stdint_t" = "."; then
181+CFLAGS="-std=c99"
182+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
183+[AC_MSG_WARN(your GCC compiler has a defunct stdint.h for its default-mode)])
184+fi
185+CXXFLAGS="$old_CXXFLAGS"
186+CPPFLAGS="$old_CPPFLAGS"
187+CFLAGS="$old_CFLAGS" ])
188+
189+v="... $ac_cv_header_stdint_h"
190+if test "$ac_stdint_h" = "stdint.h" ; then
191+ AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)])
192+elif test "$ac_stdint_h" = "inttypes.h" ; then
193+ AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)])
194+elif test "_$ac_cv_header_stdint_t" = "_" ; then
195+ AC_MSG_RESULT([(putting them into $ac_stdint_h)$v])
196+else
197+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
198+ AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)])
199+fi
200+
201+if test "_$ac_cv_header_stdint_t" = "_" ; then # cannot shortcircuit..
202+
203+dnl .....intro message done, now do a few system checks.....
204+dnl btw, all old CHECK_TYPE macros do automatically "DEFINE" a type,
205+dnl therefore we use the autoconf implementation detail CHECK_TYPE_NEW
206+dnl instead that is triggered with 3 or more arguments (see types.m4)
207+
208+inttype_headers=`echo $2 | sed -e 's/,/ /g'`
209+
210+ac_cv_stdint_result="(no helpful system typedefs seen)"
211+AX_CHECK_HEADER_STDINT_X(dnl
212+ stdint.h inttypes.h sys/inttypes.h $inttype_headers,
213+ ac_cv_stdint_result="(seen uintptr_t$and64 in $i)")
214+
215+if test "_$ac_cv_header_stdint_x" = "_" ; then
216+AX_CHECK_HEADER_STDINT_O(dnl,
217+ inttypes.h sys/inttypes.h stdint.h $inttype_headers,
218+ ac_cv_stdint_result="(seen uint32_t$and64 in $i)")
219+fi
220+
221+if test "_$ac_cv_header_stdint_x" = "_" ; then
222+if test "_$ac_cv_header_stdint_o" = "_" ; then
223+AX_CHECK_HEADER_STDINT_U(dnl,
224+ sys/types.h inttypes.h sys/inttypes.h $inttype_headers,
225+ ac_cv_stdint_result="(seen u_int32_t$and64 in $i)")
226+fi fi
227+
228+dnl if there was no good C99 header file, do some typedef checks...
229+if test "_$ac_cv_header_stdint_x" = "_" ; then
230+ AC_MSG_CHECKING([for stdint datatype model])
231+ AC_MSG_RESULT([(..)])
232+ AX_CHECK_DATA_MODEL
233+fi
234+
235+if test "_$ac_cv_header_stdint_x" != "_" ; then
236+ ac_cv_header_stdint="$ac_cv_header_stdint_x"
237+elif test "_$ac_cv_header_stdint_o" != "_" ; then
238+ ac_cv_header_stdint="$ac_cv_header_stdint_o"
239+elif test "_$ac_cv_header_stdint_u" != "_" ; then
240+ ac_cv_header_stdint="$ac_cv_header_stdint_u"
241+else
242+ ac_cv_header_stdint="stddef.h"
243+fi
244+
245+AC_MSG_CHECKING([for extra inttypes in chosen header])
246+AC_MSG_RESULT([($ac_cv_header_stdint)])
247+dnl see if int_least and int_fast types are present in _this_ header.
248+unset ac_cv_type_int_least32_t
249+unset ac_cv_type_int_fast32_t
250+AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
251+AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
252+AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>])
253+
254+fi # shortcircut to system "stdint.h"
255+# ------------------ PREPARE VARIABLES ------------------------------
256+if test "$GCC" = "yes" ; then
257+ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
258+else
259+ac_cv_stdint_message="using $CC"
260+fi
261+
262+AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl
263+$ac_cv_stdint_result])
264+
265+dnl -----------------------------------------------------------------
266+# ----------------- DONE inttypes.h checks START header -------------
267+AC_CONFIG_COMMANDS([$ac_stdint_h],[
268+AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h)
269+ac_stdint=$tmp/_stdint.h
270+
271+echo "#ifndef" $_ac_stdint_h >$ac_stdint
272+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
273+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
274+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
275+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
276+if test "_$ac_cv_header_stdint_t" != "_" ; then
277+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
278+echo "#include <stdint.h>" >>$ac_stdint
279+echo "#endif" >>$ac_stdint
280+echo "#endif" >>$ac_stdint
281+else
282+
283+cat >>$ac_stdint <<STDINT_EOF
284+
285+/* ................... shortcircuit part ........................... */
286+
287+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
288+#include <stdint.h>
289+#else
290+#include <stddef.h>
291+
292+/* .................... configured part ............................ */
293+
294+STDINT_EOF
295+
296+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
297+if test "_$ac_cv_header_stdint_x" != "_" ; then
298+ ac_header="$ac_cv_header_stdint_x"
299+ echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
300+else
301+ echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
302+fi
303+
304+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
305+if test "_$ac_cv_header_stdint_o" != "_" ; then
306+ ac_header="$ac_cv_header_stdint_o"
307+ echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
308+else
309+ echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
310+fi
311+
312+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
313+if test "_$ac_cv_header_stdint_u" != "_" ; then
314+ ac_header="$ac_cv_header_stdint_u"
315+ echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
316+else
317+ echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
318+fi
319+
320+echo "" >>$ac_stdint
321+
322+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
323+ echo "#include <$ac_header>" >>$ac_stdint
324+ echo "" >>$ac_stdint
325+fi fi
326+
327+echo "/* which 64bit typedef has been found */" >>$ac_stdint
328+if test "$ac_cv_type_uint64_t" = "yes" ; then
329+echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint
330+else
331+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
332+fi
333+if test "$ac_cv_type_u_int64_t" = "yes" ; then
334+echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint
335+else
336+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
337+fi
338+echo "" >>$ac_stdint
339+
340+echo "/* which type model has been detected */" >>$ac_stdint
341+if test "_$ac_cv_char_data_model" != "_" ; then
342+echo "#define _STDINT_CHAR_MODEL" "$ac_cv_char_data_model" >>$ac_stdint
343+echo "#define _STDINT_LONG_MODEL" "$ac_cv_long_data_model" >>$ac_stdint
344+else
345+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
346+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
347+fi
348+echo "" >>$ac_stdint
349+
350+echo "/* whether int_least types were detected */" >>$ac_stdint
351+if test "$ac_cv_type_int_least32_t" = "yes"; then
352+echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint
353+else
354+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
355+fi
356+echo "/* whether int_fast types were detected */" >>$ac_stdint
357+if test "$ac_cv_type_int_fast32_t" = "yes"; then
358+echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
359+else
360+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
361+fi
362+echo "/* whether intmax_t type was detected */" >>$ac_stdint
363+if test "$ac_cv_type_intmax_t" = "yes"; then
364+echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
365+else
366+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
367+fi
368+echo "" >>$ac_stdint
369+
370+ cat >>$ac_stdint <<STDINT_EOF
371+/* .................... detections part ............................ */
372+
373+/* whether we need to define bitspecific types from compiler base types */
374+#ifndef _STDINT_HEADER_INTPTR
375+#ifndef _STDINT_HEADER_UINT32
376+#ifndef _STDINT_HEADER_U_INT32
377+#define _STDINT_NEED_INT_MODEL_T
378+#else
379+#define _STDINT_HAVE_U_INT_TYPES
380+#endif
381+#endif
382+#endif
383+
384+#ifdef _STDINT_HAVE_U_INT_TYPES
385+#undef _STDINT_NEED_INT_MODEL_T
386+#endif
387+
388+#ifdef _STDINT_CHAR_MODEL
389+#if _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
390+#ifndef _STDINT_BYTE_MODEL
391+#define _STDINT_BYTE_MODEL 12
392+#endif
393+#endif
394+#endif
395+
396+#ifndef _STDINT_HAVE_INT_LEAST32_T
397+#define _STDINT_NEED_INT_LEAST_T
398+#endif
399+
400+#ifndef _STDINT_HAVE_INT_FAST32_T
401+#define _STDINT_NEED_INT_FAST_T
402+#endif
403+
404+#ifndef _STDINT_HEADER_INTPTR
405+#define _STDINT_NEED_INTPTR_T
406+#ifndef _STDINT_HAVE_INTMAX_T
407+#define _STDINT_NEED_INTMAX_T
408+#endif
409+#endif
410+
411+
412+/* .................... definition part ............................ */
413+
414+/* some system headers have good uint64_t */
415+#ifndef _HAVE_UINT64_T
416+#if defined _STDINT_HAVE_UINT64_T || defined HAVE_UINT64_T
417+#define _HAVE_UINT64_T
418+#elif defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
419+#define _HAVE_UINT64_T
420+typedef u_int64_t uint64_t;
421+#endif
422+#endif
423+
424+#ifndef _HAVE_UINT64_T
425+/* .. here are some common heuristics using compiler runtime specifics */
426+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
427+#define _HAVE_UINT64_T
428+#define _HAVE_LONGLONG_UINT64_T
429+typedef long long int64_t;
430+typedef unsigned long long uint64_t;
431+
432+#elif !defined __STRICT_ANSI__
433+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
434+#define _HAVE_UINT64_T
435+typedef __int64 int64_t;
436+typedef unsigned __int64 uint64_t;
437+
438+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
439+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
440+#if !defined _NO_LONGLONG
441+#define _HAVE_UINT64_T
442+#define _HAVE_LONGLONG_UINT64_T
443+typedef long long int64_t;
444+typedef unsigned long long uint64_t;
445+#endif
446+
447+#elif defined __alpha || (defined __mips && defined _ABIN32)
448+#if !defined _NO_LONGLONG
449+typedef long int64_t;
450+typedef unsigned long uint64_t;
451+#endif
452+ /* compiler/cpu type to define int64_t */
453+#endif
454+#endif
455+#endif
456+
457+#if defined _STDINT_HAVE_U_INT_TYPES
458+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
459+typedef u_int8_t uint8_t;
460+typedef u_int16_t uint16_t;
461+typedef u_int32_t uint32_t;
462+
463+/* glibc compatibility */
464+#ifndef __int8_t_defined
465+#define __int8_t_defined
466+#endif
467+#endif
468+
469+#ifdef _STDINT_NEED_INT_MODEL_T
470+/* we must guess all the basic types. Apart from byte-adressable system, */
471+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
472+/* (btw, those nibble-addressable systems are way off, or so we assume) */
473+
474+dnl /* have a look at "64bit and data size neutrality" at */
475+dnl /* http://unix.org/version2/whatsnew/login_64bit.html */
476+dnl /* (the shorthand "ILP" types always have a "P" part) */
477+
478+#if defined _STDINT_BYTE_MODEL
479+#if _STDINT_LONG_MODEL+0 == 242
480+/* 2:4:2 = IP16 = a normal 16-bit system */
481+typedef unsigned char uint8_t;
482+typedef unsigned short uint16_t;
483+typedef unsigned long uint32_t;
484+#ifndef __int8_t_defined
485+#define __int8_t_defined
486+typedef char int8_t;
487+typedef short int16_t;
488+typedef long int32_t;
489+#endif
490+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
491+/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */
492+/* 4:4:4 = ILP32 = a normal 32-bit system */
493+typedef unsigned char uint8_t;
494+typedef unsigned short uint16_t;
495+typedef unsigned int uint32_t;
496+#ifndef __int8_t_defined
497+#define __int8_t_defined
498+typedef char int8_t;
499+typedef short int16_t;
500+typedef int int32_t;
501+#endif
502+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
503+/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */
504+/* 4:8:8 = LP64 = a normal 64-bit system */
505+typedef unsigned char uint8_t;
506+typedef unsigned short uint16_t;
507+typedef unsigned int uint32_t;
508+#ifndef __int8_t_defined
509+#define __int8_t_defined
510+typedef char int8_t;
511+typedef short int16_t;
512+typedef int int32_t;
513+#endif
514+/* this system has a "long" of 64bit */
515+#ifndef _HAVE_UINT64_T
516+#define _HAVE_UINT64_T
517+typedef unsigned long uint64_t;
518+typedef long int64_t;
519+#endif
520+#elif _STDINT_LONG_MODEL+0 == 448
521+/* LLP64 a 64-bit system derived from a 32-bit system */
522+typedef unsigned char uint8_t;
523+typedef unsigned short uint16_t;
524+typedef unsigned int uint32_t;
525+#ifndef __int8_t_defined
526+#define __int8_t_defined
527+typedef char int8_t;
528+typedef short int16_t;
529+typedef int int32_t;
530+#endif
531+/* assuming the system has a "long long" */
532+#ifndef _HAVE_UINT64_T
533+#define _HAVE_UINT64_T
534+#define _HAVE_LONGLONG_UINT64_T
535+typedef unsigned long long uint64_t;
536+typedef long long int64_t;
537+#endif
538+#else
539+#define _STDINT_NO_INT32_T
540+#endif
541+#else
542+#define _STDINT_NO_INT8_T
543+#define _STDINT_NO_INT32_T
544+#endif
545+#endif
546+
547+/*
548+ * quote from SunOS-5.8 sys/inttypes.h:
549+ * Use at your own risk. As of February 1996, the committee is squarely
550+ * behind the fixed sized types; the "least" and "fast" types are still being
551+ * discussed. The probability that the "fast" types may be removed before
552+ * the standard is finalized is high enough that they are not currently
553+ * implemented.
554+ */
555+
556+#if defined _STDINT_NEED_INT_LEAST_T
557+typedef int8_t int_least8_t;
558+typedef int16_t int_least16_t;
559+typedef int32_t int_least32_t;
560+#ifdef _HAVE_UINT64_T
561+typedef int64_t int_least64_t;
562+#endif
563+
564+typedef uint8_t uint_least8_t;
565+typedef uint16_t uint_least16_t;
566+typedef uint32_t uint_least32_t;
567+#ifdef _HAVE_UINT64_T
568+typedef uint64_t uint_least64_t;
569+#endif
570+ /* least types */
571+#endif
572+
573+#if defined _STDINT_NEED_INT_FAST_T
574+typedef int8_t int_fast8_t;
575+typedef int int_fast16_t;
576+typedef int32_t int_fast32_t;
577+#ifdef _HAVE_UINT64_T
578+typedef int64_t int_fast64_t;
579+#endif
580+
581+typedef uint8_t uint_fast8_t;
582+typedef unsigned uint_fast16_t;
583+typedef uint32_t uint_fast32_t;
584+#ifdef _HAVE_UINT64_T
585+typedef uint64_t uint_fast64_t;
586+#endif
587+ /* fast types */
588+#endif
589+
590+#ifdef _STDINT_NEED_INTMAX_T
591+#ifdef _HAVE_UINT64_T
592+typedef int64_t intmax_t;
593+typedef uint64_t uintmax_t;
594+#else
595+typedef long intmax_t;
596+typedef unsigned long uintmax_t;
597+#endif
598+#endif
599+
600+#ifdef _STDINT_NEED_INTPTR_T
601+#ifndef __intptr_t_defined
602+#define __intptr_t_defined
603+/* we encourage using "long" to store pointer values, never use "int" ! */
604+#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
605+typedef unsigned int uintptr_t;
606+typedef int intptr_t;
607+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
608+typedef unsigned long uintptr_t;
609+typedef long intptr_t;
610+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
611+typedef uint64_t uintptr_t;
612+typedef int64_t intptr_t;
613+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
614+typedef unsigned long uintptr_t;
615+typedef long intptr_t;
616+#endif
617+#endif
618+#endif
619+
620+/* The ISO C99 standard specifies that in C++ implementations these
621+ should only be defined if explicitly requested. */
622+#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS
623+#ifndef UINT32_C
624+
625+/* Signed. */
626+# define INT8_C(c) c
627+# define INT16_C(c) c
628+# define INT32_C(c) c
629+# ifdef _HAVE_LONGLONG_UINT64_T
630+# define INT64_C(c) c ## L
631+# else
632+# define INT64_C(c) c ## LL
633+# endif
634+
635+/* Unsigned. */
636+# define UINT8_C(c) c ## U
637+# define UINT16_C(c) c ## U
638+# define UINT32_C(c) c ## U
639+# ifdef _HAVE_LONGLONG_UINT64_T
640+# define UINT64_C(c) c ## UL
641+# else
642+# define UINT64_C(c) c ## ULL
643+# endif
644+
645+/* Maximal type. */
646+# ifdef _HAVE_LONGLONG_UINT64_T
647+# define INTMAX_C(c) c ## L
648+# define UINTMAX_C(c) c ## UL
649+# else
650+# define INTMAX_C(c) c ## LL
651+# define UINTMAX_C(c) c ## ULL
652+# endif
653+
654+ /* literalnumbers */
655+#endif
656+#endif
657+
658+/* These limits are merily those of a two complement byte-oriented system */
659+
660+/* Minimum of signed integral types. */
661+# define INT8_MIN (-128)
662+# define INT16_MIN (-32767-1)
663+# define INT32_MIN (-2147483647-1)
664+# define INT64_MIN (-__INT64_C(9223372036854775807)-1)
665+/* Maximum of signed integral types. */
666+# define INT8_MAX (127)
667+# define INT16_MAX (32767)
668+# define INT32_MAX (2147483647)
669+# define INT64_MAX (__INT64_C(9223372036854775807))
670+
671+/* Maximum of unsigned integral types. */
672+# define UINT8_MAX (255)
673+# define UINT16_MAX (65535)
674+# define UINT32_MAX (4294967295U)
675+# define UINT64_MAX (__UINT64_C(18446744073709551615))
676+
677+/* Minimum of signed integral types having a minimum size. */
678+# define INT_LEAST8_MIN INT8_MIN
679+# define INT_LEAST16_MIN INT16_MIN
680+# define INT_LEAST32_MIN INT32_MIN
681+# define INT_LEAST64_MIN INT64_MIN
682+/* Maximum of signed integral types having a minimum size. */
683+# define INT_LEAST8_MAX INT8_MAX
684+# define INT_LEAST16_MAX INT16_MAX
685+# define INT_LEAST32_MAX INT32_MAX
686+# define INT_LEAST64_MAX INT64_MAX
687+
688+/* Maximum of unsigned integral types having a minimum size. */
689+# define UINT_LEAST8_MAX UINT8_MAX
690+# define UINT_LEAST16_MAX UINT16_MAX
691+# define UINT_LEAST32_MAX UINT32_MAX
692+# define UINT_LEAST64_MAX UINT64_MAX
693+
694+ /* shortcircuit*/
695+#endif
696+ /* once */
697+#endif
698+#endif
699+STDINT_EOF
700+fi
701+ if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
702+ AC_MSG_NOTICE([$ac_stdint_h is unchanged])
703+ else
704+ ac_dir=`AS_DIRNAME(["$ac_stdint_h"])`
705+ AS_MKDIR_P(["$ac_dir"])
706+ rm -f $ac_stdint_h
707+ mv $ac_stdint $ac_stdint_h
708+ fi
709+],[# variables for create stdint.h replacement
710+PACKAGE="$PACKAGE"
711+VERSION="$VERSION"
712+ac_stdint_h="$ac_stdint_h"
713+_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h)
714+ac_cv_stdint_message="$ac_cv_stdint_message"
715+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
716+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
717+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
718+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
719+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
720+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
721+ac_cv_char_data_model="$ac_cv_char_data_model"
722+ac_cv_long_data_model="$ac_cv_long_data_model"
723+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
724+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
725+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
726+])
727+])
--- trunk/t1asm/clp.c (nonexistent)
+++ trunk/t1asm/clp.c (revision 247)
@@ -0,0 +1,2381 @@
1+/* -*- related-file-name: "../include/lcdf/clp.h" -*- */
2+/* clp.c - Complete source code for CLP.
3+ * This file is part of CLP, the command line parser package.
4+ *
5+ * Copyright (c) 1997-2011 Eddie Kohler, ekohler@gmail.com
6+ *
7+ * Permission is hereby granted, free of charge, to any person obtaining a
8+ * copy of this software and associated documentation files (the "Software"),
9+ * to deal in the Software without restriction, subject to the conditions
10+ * listed in the Click LICENSE file, which is available in full at
11+ * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you
12+ * must preserve this copyright notice, and you cannot mention the copyright
13+ * holders in advertising related to the Software without their permission.
14+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
15+ * notice is a summary of the Click LICENSE file; the license in that file is
16+ * legally binding. */
17+
18+/* Note added by Matthew Skala: as of this writing (March 28, 2012) the
19+ * above license URL doesn't work. But digging around on the Web site it
20+ * redirects to yields the link http://www.read.cs.ucla.edu/click/license ,
21+ * which contains the following notice. Since the one above says that the
22+ * one on the Web is binding, and the one on the Web says that it "shall"
23+ * be included in all copies - a Web pointer not being enough precisely
24+ * because of this kind of confusion when URLs change - I'm going to
25+ * include the license notice in its entirety below. */
26+
27+/********************************************************************
28+ * The Click License
29+ *
30+ * Permission is hereby granted, free of charge, to any person
31+ * obtaining a copy of this software and associated documentation files
32+ * (the "Software"), to deal in the Software without restriction,
33+ * including without limitation the rights to use, copy, modify, merge,
34+ * publish, distribute, sublicense, and/or sell copies of the Software,
35+ * and to permit persons to whom the Software is furnished to do so,
36+ * subject to the following conditions:
37+ *
38+ * The above copyright notice and this permission notice shall be
39+ * included in all copies or substantial portions of the Software.
40+ *
41+ * The name and trademarks of copyright holders may NOT be used in
42+ * advertising or publicity pertaining to the Software without specific,
43+ * written prior permission. Title to copyright in this Software and
44+ * any associated documentation will at all times remain with copyright
45+ * holders.
46+ *
47+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
48+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
51+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
52+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
53+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54+ **********************************************************************/
55+
56+#ifdef HAVE_CONFIG_H
57+# include <config.h>
58+#endif
59+#include "clp.h"
60+#include <stdlib.h>
61+#include <string.h>
62+#include <stdio.h>
63+#include <assert.h>
64+#include <stdarg.h>
65+#include <ctype.h>
66+
67+/* By default, assume we have strtoul. */
68+#if !defined(HAVE_STRTOUL) && !defined(HAVE_CONFIG_H)
69+# define HAVE_STRTOUL 1
70+#endif
71+
72+#ifdef __cplusplus
73+extern "C" {
74+#endif
75+
76+
77+/** @file clp.h
78+ * @brief Functions for parsing command line options.
79+ *
80+ * The CLP functions are used to parse command line arugments into options.
81+ * It automatically handles value parsing, error messages, long options with
82+ * minimum prefix matching, short options, and negated options.
83+ *
84+ * The CLP model works like this.
85+ *
86+ * <ol>
87+ * <li>The user declares an array of Clp_Option structures that define the
88+ * options their program accepts.</li>
89+ * <li>The user creates a Clp_Parser object using Clp_NewParser(), passing in
90+ * the command line arguments to parse and the Clp_Option structures.</li>
91+ * <li>A loop repeatedly calls Clp_Next() to parse the arguments.</li>
92+ * </ol>
93+ *
94+ * Unlike many command line parsing libraries, CLP steps through all arguments
95+ * one at a time, rather than slurping up all options at once. This makes it
96+ * meaningful to give an option more than once.
97+ *
98+ * Here's an example.
99+ *
100+ * @code
101+ * #define ANIMAL_OPT 1
102+ * #define VEGETABLE_OPT 2
103+ * #define MINERALS_OPT 3
104+ * #define USAGE_OPT 4
105+ *
106+ * static const Clp_Option options[] = {
107+ * { "animal", 'a', ANIMAL_OPT, Clp_ValString, 0 },
108+ * { "vegetable", 'v', VEGETABLE_OPT, Clp_ValString, Clp_Negate | Clp_Optional },
109+ * { "minerals", 'm', MINERALS_OPT, Clp_ValInt, 0 },
110+ * { "usage", 0, USAGE_OPT, 0, 0 }
111+ * };
112+ *
113+ * int main(int argc, char *argv[]) {
114+ * Clp_Parser *clp = Clp_NewParser(argc, argv,
115+ * sizeof(options) / sizeof(options[0]), options);
116+ * int opt;
117+ * while ((opt = Clp_Next(clp)) != Clp_Done)
118+ * switch (opt) {
119+ * case ANIMAL_OPT:
120+ * fprintf(stderr, "animal is %s\n", clp->val.s);
121+ * break;
122+ * case VEGETABLE_OPT:
123+ * if (clp->negated)
124+ * fprintf(stderr, "no vegetables!\n");
125+ * else if (clp->have_val)
126+ * fprintf(stderr, "vegetable is %s\n", clp->val.s);
127+ * else
128+ * fprintf(stderr, "vegetables OK\n");
129+ * break;
130+ * case MINERALS_OPT:
131+ * fprintf(stderr, "%d minerals\n", clp->val.i);
132+ * break;
133+ * case USAGE_OPT:
134+ * fprintf(stderr, "Usage: 20q [--animal=ANIMAL] [--vegetable[=VEGETABLE]] [--minerals=N]\n");
135+ * break;
136+ * case Clp_NotOption:
137+ * fprintf(stderr, "non-option %s\n", clp->vstr);
138+ * break;
139+ * }
140+ * }
141+ * }
142+ * @endcode
143+ *
144+ * Here are a couple of executions.
145+ *
146+ * <pre>
147+ * % ./20q --animal=cat
148+ * animal is cat
149+ * % ./20q --animal=cat -a dog -afish --animal bird --an=snake
150+ * animal is cat
151+ * animal is dog
152+ * animal is fish
153+ * animal is bird
154+ * animal is snake
155+ * % ./20q --no-vegetables
156+ * no vegetables!
157+ * % ./20q -v
158+ * vegetables OK
159+ * % ./20q -vkale
160+ * vegetable is kale
161+ * % ./20q -m10
162+ * 10 minerals
163+ * % ./20q -m foo
164+ * '-m' expects an integer, not 'foo'
165+ * </pre>
166+ */
167+
168+
169+/* Option types for Clp_SetOptionChar */
170+#define Clp_DoubledLong (Clp_LongImplicit * 2)
171+
172+#define Clp_InitialValType 8
173+#define MAX_AMBIGUOUS_VALUES 4
174+
175+typedef struct {
176+ int val_type;
177+ Clp_ValParseFunc func;
178+ int flags;
179+ void *user_data;
180+} Clp_ValType;
181+
182+typedef struct {
183+ unsigned ilong : 1;
184+ unsigned ishort : 1;
185+ unsigned imandatory : 1;
186+ unsigned ioptional : 1;
187+ unsigned ipos : 1;
188+ unsigned ineg : 1;
189+ unsigned iprefmatch : 1;
190+ unsigned lmmpos_short : 1;
191+ unsigned lmmneg_short : 1;
192+ unsigned char ilongoff;
193+ int lmmpos;
194+ int lmmneg;
195+} Clp_InternOption;
196+
197+
198+#define Clp_OptionCharsSize 5
199+
200+typedef struct {
201+ int c;
202+ int type;
203+} Clp_Oclass;
204+#define Clp_OclassSize 10
205+
206+typedef struct Clp_Internal {
207+ const Clp_Option *opt;
208+ Clp_InternOption *iopt;
209+ int nopt;
210+ unsigned opt_generation;
211+
212+ Clp_ValType *valtype;
213+ int nvaltype;
214+
215+ const char * const *argv;
216+ int argc;
217+
218+ Clp_Oclass oclass[Clp_OclassSize];
219+ int noclass;
220+ int long1pos;
221+ int long1neg;
222+ int utf8;
223+
224+ char option_chars[Clp_OptionCharsSize];
225+ const char *xtext;
226+
227+ const char *program_name;
228+ void (*error_handler)(Clp_Parser *, const char *);
229+
230+ int option_processing;
231+ int current_option;
232+
233+ unsigned char is_short;
234+ unsigned char whole_negated; /* true if negated by an option character */
235+ unsigned char could_be_short;
236+ unsigned char current_short;
237+ unsigned char negated_by_no;
238+
239+ int ambiguous;
240+ int ambiguous_values[MAX_AMBIGUOUS_VALUES];
241+} Clp_Internal;
242+
243+
244+struct Clp_ParserState {
245+ const char * const *argv;
246+ int argc;
247+
248+ char option_chars[Clp_OptionCharsSize];
249+ const char *xtext;
250+
251+ int option_processing;
252+
253+ unsigned opt_generation;
254+ int current_option;
255+ unsigned char is_short;
256+ unsigned char whole_negated;
257+ unsigned char current_short;
258+ unsigned char negated_by_no;
259+};
260+
261+
262+typedef struct Clp_StringList {
263+
264+ Clp_Option *items;
265+ Clp_InternOption *iopt;
266+ int nitems;
267+
268+ int allow_int;
269+ int nitems_invalid_report;
270+
271+} Clp_StringList;
272+
273+
274+static int parse_string(Clp_Parser *, const char *, int, void *);
275+static int parse_int(Clp_Parser *, const char *, int, void *);
276+static int parse_bool(Clp_Parser *, const char *, int, void *);
277+static int parse_double(Clp_Parser *, const char *, int, void *);
278+static int parse_string_list(Clp_Parser *, const char *, int, void *);
279+
280+static int ambiguity_error(Clp_Parser *, int, int *, const Clp_Option *,
281+ const Clp_InternOption *, const char *, const char *,
282+ ...);
283+
284+
285+/*******
286+ * utf8
287+ **/
288+
289+#define U_REPLACEMENT 0xFFFD
290+
291+static char *
292+encode_utf8(char *s, int n, int c)
293+{
294+ if (c < 0 || c >= 0x110000 || (c >= 0xD800 && c <= 0xDFFF))
295+ c = U_REPLACEMENT;
296+ if (c <= 0x7F && n >= 1)
297+ *s++ = c;
298+ else if (c <= 0x7FF && n >= 2) {
299+ *s++ = 0xC0 | (c >> 6);
300+ goto char1;
301+ } else if (c <= 0xFFFF && n >= 3) {
302+ *s++ = 0xE0 | (c >> 12);
303+ goto char2;
304+ } else if (n >= 4) {
305+ *s++ = 0xF0 | (c >> 18);
306+ *s++ = 0x80 | ((c >> 12) & 0x3F);
307+ char2:
308+ *s++ = 0x80 | ((c >> 6) & 0x3F);
309+ char1:
310+ *s++ = 0x80 | (c & 0x3F);
311+ }
312+ return s;
313+}
314+
315+static int
316+decode_utf8(const char *s, const char **cp)
317+{
318+ int c;
319+ if ((unsigned char) *s <= 0x7F) /* 1 byte: 0x000000-0x00007F */
320+ c = *s++;
321+ else if ((unsigned char) *s <= 0xC1) /* bad/overlong encoding */
322+ goto replacement;
323+ else if ((unsigned char) *s <= 0xDF) { /* 2 bytes: 0x000080-0x0007FF */
324+ if ((s[1] & 0xC0) != 0x80) /* bad encoding */
325+ goto replacement;
326+ c = (*s++ & 0x1F) << 6;
327+ goto char1;
328+ } else if ((unsigned char) *s <= 0xEF) { /* 3 bytes: 0x000800-0x00FFFF */
329+ if ((s[1] & 0xC0) != 0x80 /* bad encoding */
330+ || (s[2] & 0xC0) != 0x80 /* bad encoding */
331+ || ((unsigned char) *s == 0xE0 /* overlong encoding */
332+ && (s[1] & 0xE0) == 0x80)
333+ || ((unsigned char) *s == 0xED /* encoded surrogate */
334+ && (s[1] & 0xE0) == 0xA0))
335+ goto replacement;
336+ c = (*s++ & 0x0F) << 12;
337+ goto char2;
338+ } else if ((unsigned char) *s <= 0xF4) { /* 4 bytes: 0x010000-0x10FFFF */
339+ if ((s[1] & 0xC0) != 0x80 /* bad encoding */
340+ || (s[2] & 0xC0) != 0x80 /* bad encoding */
341+ || (s[3] & 0xC0) != 0x80 /* bad encoding */
342+ || ((unsigned char) *s == 0xF0 /* overlong encoding */
343+ && (s[1] & 0xF0) == 0x80)
344+ || ((unsigned char) *s == 0xF4 /* encoded value > 0x10FFFF */
345+ && (unsigned char) s[1] >= 0x90))
346+ goto replacement;
347+ c = (*s++ & 0x07) << 18;
348+ c += (*s++ & 0x3F) << 12;
349+ char2:
350+ c += (*s++ & 0x3F) << 6;
351+ char1:
352+ c += (*s++ & 0x3F);
353+ } else {
354+ replacement:
355+ c = U_REPLACEMENT;
356+ for (s++; (*s & 0xC0) == 0x80; s++)
357+ /* nothing */;
358+ }
359+ if (cp)
360+ *cp = s;
361+ return c;
362+}
363+
364+static int
365+utf8_charlen(const char *s)
366+{
367+ const char *sout;
368+ (void) decode_utf8(s, &sout);
369+ return sout - s;
370+}
371+
372+static int
373+clp_utf8_charlen(const Clp_Internal *cli, const char *s)
374+{
375+ return (cli->utf8 ? utf8_charlen(s) : 1);
376+}
377+
378+
379+/*******
380+ * Clp_NewParser, etc.
381+ **/
382+
383+static int
384+min_different_chars(const char *s, const char *t)
385+ /* Returns the minimum number of bytes required to distinguish
386+ s from t.
387+ If s is shorter than t, returns strlen(s). */
388+{
389+ const char *sfirst = s;
390+ while (*s && *t && *s == *t)
391+ s++, t++;
392+ if (!*s)
393+ return s - sfirst;
394+ else
395+ return s - sfirst + 1;
396+}
397+
398+static int
399+long_as_short(const Clp_Internal *cli, const Clp_Option *o,
400+ Clp_InternOption *io, int failure)
401+{
402+ if ((cli->long1pos || cli->long1neg) && io->ilong) {
403+ const char *name = o->long_name + io->ilongoff;
404+ if (cli->utf8) {
405+ int c = decode_utf8(name, &name);
406+ if (!*name && c && c != U_REPLACEMENT)
407+ return c;
408+ } else if (name[0] && !name[1])
409+ return (unsigned char) name[0];
410+ }
411+ return failure;
412+}
413+
414+static void
415+compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1,
416+ const Clp_Option *o2, Clp_InternOption *io2)
417+{
418+ Clp_Internal *cli = clp->internal;
419+ int short1, shortx1;
420+
421+ /* ignore meaningless combinations */
422+ if ((!io1->ishort && !io1->ilong) || (!io2->ishort && !io2->ilong)
423+ || !((io1->ipos && io2->ipos) || (io1->ineg && io2->ineg))
424+ || o1->option_id == o2->option_id)
425+ return;
426+
427+ /* look for duplication of short options */
428+ short1 = (io1->ishort ? o1->short_name : -1);
429+ shortx1 = long_as_short(cli, o1, io1, -2);
430+ if (short1 >= 0 || shortx1 >= 0) {
431+ int short2 = (io2->ishort ? o2->short_name : -3);
432+ int shortx2 = long_as_short(cli, o2, io2, -4);
433+ if (short1 == short2)
434+ Clp_OptionError(clp, "CLP internal error: more than 1 option has short name %<%c%>", short1);
435+ else if ((short1 == shortx2 || shortx1 == short2 || shortx1 == shortx2)
436+ && ((io1->ipos && io2->ipos && cli->long1pos)
437+ || (io1->ineg && io2->ineg && cli->long1neg)))
438+ Clp_OptionError(clp, "CLP internal error: 1-char long name conflicts with short name %<%c%>", (short1 == shortx2 ? shortx2 : shortx1));
439+ }
440+
441+ /* analyze longest minimum match */
442+ if (io1->ilong) {
443+ const char *name1 = o1->long_name + io1->ilongoff;
444+
445+ /* long name's first character matches short name */
446+ if (io2->ishort && !io1->iprefmatch) {
447+ int name1char = (cli->utf8 ? decode_utf8(name1, 0) : (unsigned char) *name1);
448+ if (name1char == o2->short_name) {
449+ if (io1->ipos && io2->ipos)
450+ io1->lmmpos_short = 1;
451+ if (io1->ineg && io2->ineg)
452+ io1->lmmneg_short = 1;
453+ }
454+ }
455+
456+ /* match long name to long name */
457+ if (io2->ilong) {
458+ const char *name2 = o2->long_name + io2->ilongoff;
459+ if (strcmp(name1, name2) == 0)
460+ Clp_OptionError(clp, "CLP internal error: duplicate long name %<%s%>", name1);
461+ if (io1->ipos && io2->ipos && !strncmp(name1, name2, io1->lmmpos)
462+ && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1))))
463+ io1->lmmpos = min_different_chars(name1, name2);
464+ if (io1->ineg && io2->ineg && !strncmp(name1, name2, io1->lmmneg)
465+ && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1))))
466+ io1->lmmneg = min_different_chars(name1, name2);
467+ }
468+ }
469+}
470+
471+/** @param argc number of arguments
472+ * @param argv argument array
473+ * @param nopt number of option definitions
474+ * @param opt option definition array
475+ * @return the parser
476+ *
477+ * The new Clp_Parser that will parse the arguments in @a argv according to
478+ * the option definitions in @a opt.
479+ *
480+ * The Clp_Parser is created with the following characteristics:
481+ *
482+ * <ul>
483+ * <li>The "-" character introduces short options (<tt>Clp_SetOptionChar(clp,
484+ * '-', Clp_Short)</tt>).</li>
485+ * <li>Clp_ProgramName is set from the first argument in @a argv, if any. The
486+ * first argument returned by Clp_Next() will be the second argument in @a
487+ * argv. Note that this behavior differs from Clp_SetArguments.</li>
488+ * <li>UTF-8 support is on iff the <tt>LANG</tt> environment variable contains
489+ * one of the substrings "UTF-8", "UTF8", or "utf8". Override this with
490+ * Clp_SetUTF8().</li>
491+ * <li>The Clp_ValString, Clp_ValStringNotOption, Clp_ValInt, Clp_ValUnsigned,
492+ * Clp_ValBool, and Clp_ValDouble types are installed.</li>
493+ * <li>Errors are reported to standard error.</li>
494+ * </ul>
495+ *
496+ * You may also create a Clp_Parser with no arguments or options
497+ * (<tt>Clp_NewParser(0, 0, 0, 0)</tt>) and set the arguments and options
498+ * later.
499+ *
500+ * Returns NULL if there isn't enough memory to construct the parser.
501+ *
502+ * @note The CLP library will not modify the contents of @a argv or @a opt.
503+ * The calling program must not modify @a opt. It may modify @a argv in
504+ * limited cases.
505+ */
506+Clp_Parser *
507+Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *opt)
508+{
509+ Clp_Parser *clp = (Clp_Parser *)malloc(sizeof(Clp_Parser));
510+ Clp_Internal *cli = (Clp_Internal *)malloc(sizeof(Clp_Internal));
511+ Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt);
512+ if (cli)
513+ cli->valtype = (Clp_ValType *)malloc(sizeof(Clp_ValType) * Clp_InitialValType);
514+ if (!clp || !cli || !iopt || !cli->valtype)
515+ goto failed;
516+
517+ clp->negated = 0;
518+ clp->have_val = 0;
519+ clp->vstr = 0;
520+ clp->user_data = 0;
521+ clp->internal = cli;
522+
523+ cli->opt = opt;
524+ cli->nopt = nopt;
525+ cli->iopt = iopt;
526+ cli->opt_generation = 0;
527+ cli->error_handler = 0;
528+
529+ /* Assign program name (now so we can call Clp_OptionError) */
530+ if (argc > 0) {
531+ const char *slash = strrchr(argv[0], '/');
532+ cli->program_name = slash ? slash + 1 : argv[0];
533+ } else
534+ cli->program_name = 0;
535+
536+ /* Assign arguments, skipping program name */
537+ Clp_SetArguments(clp, argc - 1, argv + 1);
538+
539+ /* Initialize UTF-8 status and option classes */
540+ {
541+ char *s = getenv("LANG");
542+ cli->utf8 = (s && (strstr(s, "UTF-8") != 0 || strstr(s, "UTF8") != 0
543+ || strstr(s, "utf8") != 0));
544+ }
545+ cli->oclass[0].c = '-';
546+ cli->oclass[0].type = Clp_Short;
547+ cli->noclass = 1;
548+ cli->long1pos = cli->long1neg = 0;
549+
550+ /* Add default type parsers */
551+ cli->nvaltype = 0;
552+ Clp_AddType(clp, Clp_ValString, 0, parse_string, 0);
553+ Clp_AddType(clp, Clp_ValStringNotOption, Clp_DisallowOptions, parse_string, 0);
554+ Clp_AddType(clp, Clp_ValInt, 0, parse_int, 0);
555+ Clp_AddType(clp, Clp_ValUnsigned, 0, parse_int, (void *)cli);
556+ Clp_AddType(clp, Clp_ValBool, 0, parse_bool, 0);
557+ Clp_AddType(clp, Clp_ValDouble, 0, parse_double, 0);
558+
559+ /* Set options */
560+ Clp_SetOptions(clp, nopt, opt);
561+
562+ return clp;
563+
564+ failed:
565+ if (cli && cli->valtype)
566+ free(cli->valtype);
567+ if (cli)
568+ free(cli);
569+ if (clp)
570+ free(clp);
571+ if (iopt)
572+ free(iopt);
573+ return 0;
574+}
575+
576+/** @param clp the parser
577+ *
578+ * All memory associated with @a clp is freed. */
579+void
580+Clp_DeleteParser(Clp_Parser *clp)
581+{
582+ int i;
583+ Clp_Internal *cli;
584+ if (!clp)
585+ return;
586+
587+ cli = clp->internal;
588+
589+ /* get rid of any string list types */
590+ for (i = 0; i < cli->nvaltype; i++)
591+ if (cli->valtype[i].func == parse_string_list) {
592+ Clp_StringList *clsl = (Clp_StringList *)cli->valtype[i].user_data;
593+ free(clsl->items);
594+ free(clsl->iopt);
595+ free(clsl);
596+ }
597+
598+ free(cli->valtype);
599+ free(cli->iopt);
600+ free(cli);
601+ free(clp);
602+}
603+
604+
605+/** @param clp the parser
606+ * @param errh error handler function
607+ * @return previous error handler function
608+ *
609+ * The error handler function is called when CLP encounters an error while
610+ * parsing the command line. It is called with the arguments "<tt>(*errh)(@a
611+ * clp, s)</tt>", where <tt>s</tt> is a description of the error terminated by
612+ * a newline. The <tt>s</tt> descriptions produced by CLP itself are prefixed
613+ * by the program name, if any. */
614+Clp_ErrorHandler
615+Clp_SetErrorHandler(Clp_Parser *clp, void (*errh)(Clp_Parser *, const char *))
616+{
617+ Clp_Internal *cli = clp->internal;
618+ Clp_ErrorHandler old = cli->error_handler;
619+ cli->error_handler = errh;
620+ return old;
621+}
622+
623+/** @param clp the parser
624+ * @param utf8 does the parser support UTF-8?
625+ * @return previous UTF-8 mode
626+ *
627+ * In UTF-8 mode, all input strings (arguments and long names for options) are
628+ * assumed to be encoded via UTF-8, and all character names
629+ * (Clp_SetOptionChar() and short names for options) may cover the whole
630+ * Unicode range. Out of UTF-8 mode, all input strings are treated as binary,
631+ * and all character names must be unsigned char values.
632+ *
633+ * Furthermore, error messages in UTF-8 mode may contain Unicode quote
634+ * characters. */
635+int
636+Clp_SetUTF8(Clp_Parser *clp, int utf8)
637+{
638+ Clp_Internal *cli = clp->internal;
639+ int i, j, old_utf8 = cli->utf8;
640+ cli->utf8 = utf8;
641+ for (i = 0; i < cli->nopt; ++i) {
642+ cli->iopt[i].lmmpos = cli->iopt[i].lmmneg = 1;
643+ cli->iopt[i].lmmpos_short = cli->iopt[i].lmmneg_short = 0;
644+ for (j = 0; j < cli->nopt; ++j)
645+ compare_options(clp, &cli->opt[i], &cli->iopt[i],
646+ &cli->opt[j], &cli->iopt[j]);
647+ }
648+ return old_utf8;
649+}
650+
651+/** @param clp the parser
652+ * @param c character
653+ * @return option character treatment
654+ *
655+ * Returns an integer specifying how CLP treats arguments that begin
656+ * with character @a c. See Clp_SetOptionChar for possibilities.
657+ */
658+int
659+Clp_OptionChar(Clp_Parser *clp, int c)
660+{
661+ Clp_Internal *cli = clp->internal;
662+ int i, oclass = 0;
663+ if (cli->noclass > 0 && cli->oclass[0].c == 0)
664+ oclass = cli->oclass[0].type;
665+ for (i = 0; i < cli->noclass; ++i)
666+ if (cli->oclass[i].c == c)
667+ oclass = cli->oclass[i].type;
668+ return oclass;
669+}
670+
671+/** @param clp the parser
672+ * @param c character
673+ * @param type option character treatment
674+ * @return previous option character treatment, or -1 on error
675+ *
676+ * @a type specifies how CLP treats arguments that begin with character @a c.
677+ * Possibilities are:
678+ *
679+ * <dl>
680+ * <dt>Clp_NotOption (or 0)</dt>
681+ * <dd>The argument cannot be an option.</dd>
682+ * <dt>Clp_Long</dt>
683+ * <dd>The argument is a long option.</dd>
684+ * <dt>Clp_Short</dt>
685+ * <dd>The argument is a set of short options.</dd>
686+ * <dt>Clp_Short|Clp_Long</dt>
687+ * <dd>The argument is either a long option or, if no matching long option is
688+ * found, a set of short options.</dd>
689+ * <dt>Clp_LongNegated</dt>
690+ * <dd>The argument is a negated long option. For example, after
691+ * Clp_SetOptionChar(@a clp, '^', Clp_LongNegated), the argument "^foo" is
692+ * equivalent to "--no-foo".</dd>
693+ * <dt>Clp_ShortNegated</dt>
694+ * <dd>The argument is a set of negated short options.</dd>
695+ * <dt>Clp_ShortNegated|Clp_LongNegated</dt>
696+ * <dd>The argument is either a negated long option or, if no matching long
697+ * option is found, a set of negated short options.</dd>
698+ * <dt>Clp_LongImplicit</dt>
699+ * <dd>The argument may be a long option, where the character @a c is actually
700+ * part of the long option name. For example, after Clp_SetOptionChar(@a clp,
701+ * 'f', Clp_LongImplicit), the argument "foo" may be equivalent to
702+ * "--foo".</dd>
703+ * </dl>
704+ *
705+ * In UTF-8 mode, @a c may be any Unicode character. Otherwise, @a c must be
706+ * an unsigned char value. The special character 0 assigns @a type to @em
707+ * every character.
708+ *
709+ * It is an error if @a c is out of range, @a type is illegal, or there are
710+ * too many character definitions stored in @a clp already. The function
711+ * returns -1 on error.
712+ *
713+ * A double hyphen "--" always introduces a long option. This behavior cannot
714+ * currently be changed with Clp_SetOptionChar().
715+ */
716+int
717+Clp_SetOptionChar(Clp_Parser *clp, int c, int type)
718+{
719+ int i, j, long1pos, long1neg;
720+ int old = Clp_OptionChar(clp, c);
721+ Clp_Internal *cli = clp->internal;
722+
723+ if (type != Clp_NotOption && type != Clp_Short && type != Clp_Long
724+ && type != Clp_ShortNegated && type != Clp_LongNegated
725+ && type != Clp_LongImplicit && type != (Clp_Short | Clp_Long)
726+ && type != (Clp_ShortNegated | Clp_LongNegated))
727+ return -1;
728+ if (c < 0 || c >= (cli->utf8 ? 0x110000 : 256))
729+ return -1;
730+
731+ if (c == 0)
732+ cli->noclass = 0;
733+ for (i = 0; i < cli->noclass; ++i)
734+ if (cli->oclass[i].c == c)
735+ break;
736+ if (i == Clp_OclassSize)
737+ return -1;
738+
739+ cli->oclass[i].c = c;
740+ cli->oclass[i].type = type;
741+ if (cli->noclass == i)
742+ cli->noclass = i + 1;
743+
744+ long1pos = long1neg = 0;
745+ for (i = 0; i < cli->noclass; ++i) {
746+ if ((cli->oclass[i].type & Clp_Short)
747+ && (cli->oclass[i].type & Clp_Long))
748+ long1pos = 1;
749+ if ((cli->oclass[i].type & Clp_ShortNegated)
750+ && (cli->oclass[i].type & Clp_LongNegated))
751+ long1neg = 1;
752+ }
753+
754+ if (long1pos != cli->long1pos || long1neg != cli->long1neg) {
755+ /* Must recheck option set */
756+ cli->long1pos = long1pos;
757+ cli->long1neg = long1neg;
758+ for (i = 0; i < cli->nopt; ++i) {
759+ cli->iopt[i].lmmpos = cli->iopt[i].lmmneg = 1;
760+ cli->iopt[i].lmmpos_short = cli->iopt[i].lmmneg_short = 0;
761+ for (j = 0; j < cli->nopt; ++j)
762+ compare_options(clp, &cli->opt[i], &cli->iopt[i],
763+ &cli->opt[j], &cli->iopt[j]);
764+ }
765+ }
766+
767+ return old;
768+}
769+
770+/** @param clp the parser
771+ * @param nopt number of option definitions
772+ * @param opt option definition array
773+ * @return 0 on success, -1 on failure
774+ *
775+ * Installs the option definitions in @a opt. Future option parsing will
776+ * use @a opt to search for options.
777+ *
778+ * Also checks @a opt's option definitions for validity. "CLP internal
779+ * errors" are reported via Clp_OptionError() if:
780+ *
781+ * <ul>
782+ * <li>An option has a negative ID.</li>
783+ * <li>Two different short options have the same name.</li>
784+ * <li>Two different long options have the same name.</li>
785+ * <li>A short and a long option are ambiguous, in that some option character
786+ * might introduce either a short or a long option (e.g., Clp_SetOptionChar(@a
787+ * clp, '-', Clp_Long|Clp_Short)), and a short name equals a long name.</li>
788+ * </ul>
789+ *
790+ * If necessary memory cannot be allocated, this function returns -1 without
791+ * modifying the parser.
792+ *
793+ * @note The CLP library will not modify the contents of @a argv or @a opt.
794+ * The calling program must not modify @a opt either until another call to
795+ * Clp_SetOptions() or the parser is destroyed.
796+ */
797+int
798+Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt)
799+{
800+ Clp_Internal *cli = clp->internal;
801+ Clp_InternOption *iopt;
802+ int i, j;
803+ static unsigned opt_generation = 0;
804+
805+ if (nopt > cli->nopt) {
806+ iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt);
807+ if (!iopt)
808+ return -1;
809+ free(cli->iopt);
810+ cli->iopt = iopt;
811+ }
812+
813+ cli->opt = opt;
814+ cli->nopt = nopt;
815+ cli->opt_generation = ++opt_generation;
816+ iopt = cli->iopt;
817+ cli->current_option = -1;
818+
819+ /* Massage the options to make them usable */
820+ for (i = 0; i < nopt; i++) {
821+ /* Ignore negative option_ids, which are internal to CLP */
822+ if (opt[i].option_id < 0) {
823+ Clp_OptionError(clp, "CLP internal error: option %d has negative option_id", i);
824+ iopt[i].ilong = iopt[i].ishort = iopt[i].ipos = iopt[i].ineg = 0;
825+ continue;
826+ }
827+
828+ /* Set flags based on input flags */
829+ iopt[i].ilong = (opt[i].long_name != 0 && opt[i].long_name[0] != 0);
830+ iopt[i].ishort = (opt[i].short_name > 0
831+ && opt[i].short_name < (cli->utf8 ? 0x110000 : 256));
832+ iopt[i].ipos = 1;
833+ iopt[i].ineg = (opt[i].flags & Clp_Negate) != 0;
834+ iopt[i].imandatory = (opt[i].flags & Clp_Mandatory) != 0;
835+ iopt[i].ioptional = (opt[i].flags & Clp_Optional) != 0;
836+ iopt[i].iprefmatch = (opt[i].flags & Clp_PreferredMatch) != 0;
837+ iopt[i].ilongoff = 0;
838+
839+ /* Enforce invariants */
840+ if (opt[i].val_type <= 0)
841+ iopt[i].imandatory = iopt[i].ioptional = 0;
842+ if (opt[i].val_type > 0 && !iopt[i].ioptional)
843+ iopt[i].imandatory = 1;
844+
845+ /* Options that start with 'no-' should be changed to OnlyNegated */
846+ if (iopt[i].ilong && strncmp(opt[i].long_name, "no-", 3) == 0) {
847+ iopt[i].ipos = 0;
848+ iopt[i].ineg = 1;
849+ iopt[i].ilongoff = 3;
850+ if (strncmp(opt[i].long_name + 3, "no-", 3) == 0)
851+ Clp_OptionError(clp, "CLP internal error: option %d begins with \"no-no-\"", i);
852+ } else if (opt[i].flags & Clp_OnlyNegated) {
853+ iopt[i].ipos = 0;
854+ iopt[i].ineg = 1;
855+ }
856+ }
857+
858+ /* Check option set */
859+ for (i = 0; i < nopt; ++i) {
860+ iopt[i].lmmpos = iopt[i].lmmneg = 1;
861+ iopt[i].lmmpos_short = iopt[i].lmmneg_short = 0;
862+ for (j = 0; j < nopt; ++j)
863+ compare_options(clp, &opt[i], &iopt[i], &opt[j], &iopt[j]);
864+ }
865+
866+ return 0;
867+}
868+
869+/** @param clp the parser
870+ * @param argc number of arguments
871+ * @param argv argument array
872+ *
873+ * Installs the arguments in @a argv for parsing. Future option parsing will
874+ * analyze @a argv.
875+ *
876+ * Unlike Clp_NewParser(), this function does not treat @a argv[0] specially.
877+ * The first subsequent call to Clp_Next() will analyze @a argv[0].
878+ *
879+ * This function also sets option processing to on, as by
880+ * Clp_SetOptionProcessing(@a clp, 1).
881+ *
882+ * @note The CLP library will not modify the contents of @a argv. The calling
883+ * program should not generally modify the element of @a argv that CLP is
884+ * currently analyzing.
885+ */
886+void
887+Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv)
888+{
889+ Clp_Internal *cli = clp->internal;
890+
891+ cli->argc = argc + 1;
892+ cli->argv = argv - 1;
893+
894+ cli->is_short = 0;
895+ cli->whole_negated = 0;
896+ cli->option_processing = 1;
897+ cli->current_option = -1;
898+}
899+
900+
901+/** @param clp the parser
902+ * @param on whether to search for options
903+ * @return previous option processing setting
904+ *
905+ * When option processing is off, every call to Clp_Next() returns
906+ * Clp_NotOption. By default the option <tt>"--"</tt> turns off option
907+ * processing and is otherwise ignored.
908+ */
909+int
910+Clp_SetOptionProcessing(Clp_Parser *clp, int on)
911+{
912+ Clp_Internal *cli = clp->internal;
913+ int old = cli->option_processing;
914+ cli->option_processing = on;
915+ return old;
916+}
917+
918+
919+/*******
920+ * functions for Clp_Option lists
921+ **/
922+
923+/* the ever-glorious argcmp */
924+
925+static int
926+argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes)
927+ /* Returns 0 if ref and arg don't match.
928+ Returns -1 if ref and arg match, but fewer than min_match characters.
929+ Returns len if ref and arg match min_match or more characters;
930+ len is the number of characters that matched in arg.
931+ Allows arg to contain fewer dashes than ref iff fewer_dashes != 0.
932+
933+ Examples:
934+ argcmp("x", "y", 1, 0) --> 0 / just plain wrong
935+ argcmp("a", "ax", 1, 0) --> 0 / ...even though min_match == 1
936+ and the 1st chars match
937+ argcmp("box", "bo", 3, 0) --> -1 / ambiguous
938+ argcmp("cat", "c=3", 1, 0) --> 1 / handles = arguments
939+ */
940+{
941+ const char *refstart = ref;
942+ const char *argstart = arg;
943+ assert(min_match > 0);
944+
945+ compare:
946+ while (*ref && *arg && *arg != '=' && *ref == *arg)
947+ ref++, arg++;
948+
949+ /* Allow arg to contain fewer dashes than ref */
950+ if (fewer_dashes && *ref == '-' && ref[1] && ref[1] == *arg) {
951+ ref++;
952+ goto compare;
953+ }
954+
955+ if (*arg && *arg != '=')
956+ return 0;
957+ else if (ref - refstart < min_match)
958+ return -1;
959+ else
960+ return arg - argstart;
961+}
962+
963+static int
964+find_prefix_opt(Clp_Parser *clp, const char *arg,
965+ int nopt, const Clp_Option *opt,
966+ const Clp_InternOption *iopt,
967+ int *ambiguous, int *ambiguous_values)
968+ /* Looks for an unambiguous match of 'arg' against one of the long
969+ options in 'opt'. Returns positive if it finds one; otherwise, returns
970+ -1 and possibly changes 'ambiguous' and 'ambiguous_values' to keep
971+ track of at most MAX_AMBIGUOUS_VALUES possibilities. */
972+{
973+ int i, fewer_dashes = 0, first_ambiguous = *ambiguous;
974+ int negated = clp && clp->negated;
975+ int first_charlen = (clp ? clp_utf8_charlen(clp->internal, arg) : 1);
976+
977+ retry:
978+ for (i = 0; i < nopt; i++) {
979+ int len, lmm;
980+ if (!iopt[i].ilong || (negated ? !iopt[i].ineg : !iopt[i].ipos))
981+ continue;
982+
983+ lmm = (negated ? iopt[i].lmmneg : iopt[i].lmmpos);
984+ if (clp && clp->internal->could_be_short
985+ && (negated ? iopt[i].lmmneg_short : iopt[i].lmmpos_short))
986+ lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm);
987+ len = argcmp(opt[i].long_name + iopt[i].ilongoff, arg, lmm, fewer_dashes);
988+ if (len > 0)
989+ return i;
990+ else if (len < 0) {
991+ if (*ambiguous < MAX_AMBIGUOUS_VALUES)
992+ ambiguous_values[*ambiguous] = i;
993+ (*ambiguous)++;
994+ }
995+ }
996+
997+ /* If there were no partial matches, try again with fewer_dashes true */
998+ if (*ambiguous == first_ambiguous && !fewer_dashes) {
999+ fewer_dashes = 1;
1000+ goto retry;
1001+ }
1002+
1003+ return -1;
1004+}
1005+
1006+
1007+/*****
1008+ * Argument parsing
1009+ **/
1010+
1011+static int
1012+val_type_binsearch(Clp_Internal *cli, int val_type)
1013+{
1014+ unsigned l = 0, r = cli->nvaltype;
1015+ while (l < r) {
1016+ unsigned m = l + (r - l) / 2;
1017+ if (cli->valtype[m].val_type == val_type)
1018+ return m;
1019+ else if (cli->valtype[m].val_type < val_type)
1020+ l = m + 1;
1021+ else
1022+ r = m;
1023+ }
1024+ return l;
1025+}
1026+
1027+/** @param clp the parser
1028+ * @param val_type value type ID
1029+ * @param flags value type flags
1030+ * @param parser parser function
1031+ * @param user_data user data for @a parser function
1032+ * @return 0 on success, -1 on failure
1033+ *
1034+ * Defines argument type @a val_type in parser @a clp. The parsing function
1035+ * @a parser will be passed argument values for type @a val_type. It should
1036+ * parse the argument into values (usually in @a clp->val, but sometimes
1037+ * elsewhere), report errors if necessary, and return whether the parse was
1038+ * successful.
1039+ *
1040+ * Any prior argument parser match @a val_type is removed. @a val_type must
1041+ * be greater than zero.
1042+ *
1043+ * @a flags specifies additional parsing flags. At the moment the only
1044+ * relevant flag is Clp_DisallowOptions, which means that separated values
1045+ * must not look like options. For example, assume argument
1046+ * <tt>--a</tt>/<tt>-a</tt> has mandatory value type Clp_ValStringNotOption
1047+ * (which has Clp_DisallowOptions). Then:
1048+ *
1049+ * <ul>
1050+ * <li><tt>--a=--b</tt> will parse with value <tt>--b</tt>.</li>
1051+ * <li><tt>-a--b</tt> will parse with value <tt>--b</tt>.</li>
1052+ * <li><tt>--a --b</tt> will not parse, since the mandatory value looks like
1053+ * an option.</li>
1054+ * <li><tt>-a --b</tt> will not parse, since the mandatory value looks like
1055+ * an option.</li>
1056+ * </ul>
1057+ */
1058+int
1059+Clp_AddType(Clp_Parser *clp, int val_type, int flags,
1060+ Clp_ValParseFunc parser, void *user_data)
1061+{
1062+ Clp_Internal *cli = clp->internal;
1063+ int vtpos;
1064+
1065+ if (val_type <= 0 || !parser)
1066+ return -1;
1067+
1068+ vtpos = val_type_binsearch(cli, val_type);
1069+
1070+ if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != val_type) {
1071+ if (cli->nvaltype != 0 && (cli->nvaltype % Clp_InitialValType) == 0) {
1072+ Clp_ValType *new_valtype =
1073+ (Clp_ValType *) realloc(cli->valtype, sizeof(Clp_ValType) * (cli->nvaltype + Clp_InitialValType));
1074+ if (!new_valtype)
1075+ return -1;
1076+ cli->valtype = new_valtype;
1077+ }
1078+ memmove(&cli->valtype[vtpos + 1], &cli->valtype[vtpos],
1079+ sizeof(Clp_ValType) * (cli->nvaltype - vtpos));
1080+ cli->nvaltype++;
1081+ cli->valtype[vtpos].func = 0;
1082+ }
1083+
1084+ if (cli->valtype[vtpos].func == parse_string_list) {
1085+ Clp_StringList *clsl = (Clp_StringList *) cli->valtype[vtpos].user_data;
1086+ free(clsl->items);
1087+ free(clsl->iopt);
1088+ free(clsl);
1089+ }
1090+
1091+ cli->valtype[vtpos].val_type = val_type;
1092+ cli->valtype[vtpos].func = parser;
1093+ cli->valtype[vtpos].flags = flags;
1094+ cli->valtype[vtpos].user_data = user_data;
1095+ return 0;
1096+}
1097+
1098+
1099+/*******
1100+ * Default argument parsers
1101+ **/
1102+
1103+static int
1104+parse_string(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1105+{
1106+ (void)complain, (void)user_data;
1107+ clp->val.s = arg;
1108+ return 1;
1109+}
1110+
1111+static int
1112+parse_int(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1113+{
1114+ const char *val;
1115+ if (*arg == 0 || isspace((unsigned char) *arg)
1116+ || (user_data != 0 && *arg == '-'))
1117+ val = arg;
1118+ else if (user_data != 0) { /* unsigned */
1119+#if HAVE_STRTOUL
1120+ clp->val.u = strtoul(arg, (char **) &val, 0);
1121+#else
1122+ /* don't bother really trying to do it right */
1123+ if (arg[0] == '-')
1124+ val = arg;
1125+ else
1126+ clp->val.u = strtol(arg, (char **) &val, 0);
1127+#endif
1128+ } else
1129+ clp->val.i = strtol(arg, (char **) &val, 0);
1130+ if (*arg != 0 && *val == 0)
1131+ return 1;
1132+ else if (complain) {
1133+ const char *message = user_data != 0
1134+ ? "%<%O%> expects a nonnegative integer, not %<%s%>"
1135+ : "%<%O%> expects an integer, not %<%s%>";
1136+ return Clp_OptionError(clp, message, arg);
1137+ } else
1138+ return 0;
1139+}
1140+
1141+static int
1142+parse_double(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1143+{
1144+ const char *val;
1145+ (void)user_data;
1146+ if (*arg == 0 || isspace((unsigned char) *arg))
1147+ val = arg;
1148+ else
1149+ clp->val.d = strtod(arg, (char **) &val);
1150+ if (*arg != 0 && *val == 0)
1151+ return 1;
1152+ else if (complain)
1153+ return Clp_OptionError(clp, "%<%O%> expects a real number, not %<%s%>", arg);
1154+ else
1155+ return 0;
1156+}
1157+
1158+static int
1159+parse_bool(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1160+{
1161+ int i;
1162+ char lcarg[6];
1163+ (void)user_data;
1164+ if (strlen(arg) > 5 || strchr(arg, '=') != 0)
1165+ goto error;
1166+
1167+ for (i = 0; arg[i] != 0; i++)
1168+ lcarg[i] = tolower((unsigned char) arg[i]);
1169+ lcarg[i] = 0;
1170+
1171+ if (argcmp("yes", lcarg, 1, 0) > 0
1172+ || argcmp("true", lcarg, 1, 0) > 0
1173+ || argcmp("1", lcarg, 1, 0) > 0) {
1174+ clp->val.i = 1;
1175+ return 1;
1176+ } else if (argcmp("no", lcarg, 1, 0) > 0
1177+ || argcmp("false", lcarg, 1, 0) > 0
1178+ || argcmp("1", lcarg, 1, 0) > 0) {
1179+ clp->val.i = 0;
1180+ return 1;
1181+ }
1182+
1183+ error:
1184+ if (complain)
1185+ Clp_OptionError(clp, "%<%O%> expects a true-or-false value, not %<%s%>", arg);
1186+ return 0;
1187+}
1188+
1189+
1190+/*****
1191+ * Clp_AddStringListType
1192+ **/
1193+
1194+static int
1195+parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1196+{
1197+ Clp_StringList *sl = (Clp_StringList *)user_data;
1198+ int idx, ambiguous = 0;
1199+ int ambiguous_values[MAX_AMBIGUOUS_VALUES + 1];
1200+
1201+ /* actually look for a string value */
1202+ idx = find_prefix_opt
1203+ (0, arg, sl->nitems, sl->items, sl->iopt,
1204+ &ambiguous, ambiguous_values);
1205+ if (idx >= 0) {
1206+ clp->val.i = sl->items[idx].option_id;
1207+ return 1;
1208+ }
1209+
1210+ if (sl->allow_int) {
1211+ if (parse_int(clp, arg, 0, 0))
1212+ return 1;
1213+ }
1214+
1215+ if (complain) {
1216+ const char *complaint = (ambiguous ? "ambiguous" : "invalid");
1217+ if (!ambiguous) {
1218+ ambiguous = sl->nitems_invalid_report;
1219+ for (idx = 0; idx < ambiguous; idx++)
1220+ ambiguous_values[idx] = idx;
1221+ }
1222+ return ambiguity_error
1223+ (clp, ambiguous, ambiguous_values, sl->items, sl->iopt,
1224+ "", "option %<%O%> value %<%s%> is %s", arg, complaint);
1225+ } else
1226+ return 0;
1227+}
1228+
1229+
1230+static int
1231+finish_string_list(Clp_Parser *clp, int val_type, int flags,
1232+ Clp_Option *items, int nitems, int itemscap)
1233+{
1234+ int i, j;
1235+ Clp_StringList *clsl = (Clp_StringList *)malloc(sizeof(Clp_StringList));
1236+ Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nitems);
1237+ if (!clsl || !iopt)
1238+ goto error;
1239+
1240+ clsl->items = items;
1241+ clsl->iopt = iopt;
1242+ clsl->nitems = nitems;
1243+ clsl->allow_int = (flags & Clp_AllowNumbers) != 0;
1244+
1245+ if (nitems < MAX_AMBIGUOUS_VALUES && nitems < itemscap && clsl->allow_int) {
1246+ items[nitems].long_name = "any integer";
1247+ clsl->nitems_invalid_report = nitems + 1;
1248+ } else if (nitems > MAX_AMBIGUOUS_VALUES + 1)
1249+ clsl->nitems_invalid_report = MAX_AMBIGUOUS_VALUES + 1;
1250+ else
1251+ clsl->nitems_invalid_report = nitems;
1252+
1253+ for (i = 0; i < nitems; i++) {
1254+ iopt[i].ilong = iopt[i].ipos = 1;
1255+ iopt[i].ishort = iopt[i].ineg = iopt[i].ilongoff = iopt[i].iprefmatch = 0;
1256+ iopt[i].lmmpos = 1;
1257+ iopt[i].lmmpos_short = 0;
1258+ }
1259+ for (i = 0; i < nitems; i++)
1260+ for (j = 0; j < nitems; j++)
1261+ compare_options(clp, &items[i], &iopt[i], &items[j], &iopt[j]);
1262+
1263+ if (Clp_AddType(clp, val_type, 0, parse_string_list, clsl) >= 0)
1264+ return 0;
1265+
1266+ error:
1267+ if (clsl)
1268+ free(clsl);
1269+ if (iopt)
1270+ free(iopt);
1271+ return -1;
1272+}
1273+
1274+/** @param clp the parser
1275+ * @param val_type value type ID
1276+ * @param flags string list flags
1277+ * @return 0 on success, -1 on failure
1278+ *
1279+ * Defines argument type @a val_type in parser @a clp. The parsing function
1280+ * sets @a clp->val.i to an integer. The value string is matched against
1281+ * strings provided in the ellipsis arguments. For example, the
1282+ * Clp_AddStringListType() call below has the same effect as the
1283+ * Clp_AddStringListTypeVec() call:
1284+ *
1285+ * For example:
1286+ * @code
1287+ * Clp_AddStringListType(clp, 100, Clp_AllowNumbers, "cat", 1,
1288+ * "cattle", 2, "dog", 3, (const char *) NULL);
1289+ *
1290+ * const char * const strs[] = { "cat", "cattle", "dog" };
1291+ * const int vals[] = { 1, 2, 3 };
1292+ * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals);
1293+ * @endcode
1294+ *
1295+ * @note The CLP library will not modify any of the passed-in strings. The
1296+ * calling program must not modify or free them either until the parser is
1297+ * destroyed.
1298+ */
1299+int
1300+Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...)
1301+{
1302+ int nitems = 0;
1303+ int itemscap = 5;
1304+ Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
1305+
1306+ va_list val;
1307+ va_start(val, flags);
1308+
1309+ if (!items)
1310+ goto error;
1311+
1312+ /* slurp up the arguments */
1313+ while (1) {
1314+ int value;
1315+ char *name = va_arg(val, char *);
1316+ if (!name)
1317+ break;
1318+ value = va_arg(val, int);
1319+
1320+ if (nitems >= itemscap) {
1321+ Clp_Option *new_items;
1322+ itemscap *= 2;
1323+ new_items = (Clp_Option *)realloc(items, sizeof(Clp_Option) * itemscap);
1324+ if (!new_items)
1325+ goto error;
1326+ items = new_items;
1327+ }
1328+
1329+ items[nitems].long_name = name;
1330+ items[nitems].option_id = value;
1331+ items[nitems].flags = 0;
1332+ nitems++;
1333+ }
1334+
1335+ va_end(val);
1336+ if (finish_string_list(clp, val_type, flags, items, nitems, itemscap) >= 0)
1337+ return 0;
1338+
1339+ error:
1340+ va_end(val);
1341+ if (items)
1342+ free(items);
1343+ return -1;
1344+}
1345+
1346+/** @param clp the parser
1347+ * @param val_type value type ID
1348+ * @param flags string list flags
1349+ * @param nstrs number of strings in list
1350+ * @param strs array of strings
1351+ * @param vals array of values
1352+ * @return 0 on success, -1 on failure
1353+ *
1354+ * Defines argument type @a val_type in parser @a clp. The parsing function
1355+ * sets @a clp->val.i to an integer. The value string is matched against the
1356+ * @a strs. If there's a unique match, the corresponding entry from @a vals
1357+ * is returned. Unique prefix matches also work. Finally, if @a flags
1358+ * contains the Clp_AllowNumbers flag, then integers are also accepted.
1359+ *
1360+ * For example:
1361+ * @code
1362+ * const char * const strs[] = { "cat", "cattle", "dog" };
1363+ * const int vals[] = { 1, 2, 3 };
1364+ * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals);
1365+ * @endcode
1366+ *
1367+ * Say that option <tt>--animal</tt> takes value type 100. Then:
1368+ *
1369+ * <ul>
1370+ * <li><tt>--animal=cat</tt> will succeed and set @a clp->val.i = 1.</li>
1371+ * <li><tt>--animal=cattle</tt> will succeed and set @a clp->val.i = 2.</li>
1372+ * <li><tt>--animal=dog</tt> will succeed and set @a clp->val.i = 3.</li>
1373+ * <li><tt>--animal=d</tt> will succeed and set @a clp->val.i = 3.</li>
1374+ * <li><tt>--animal=c</tt> will fail, since <tt>c</tt> is ambiguous.</li>
1375+ * <li><tt>--animal=4</tt> will succeed and set @a clp->val.i = 4.</li>
1376+ * </ul>
1377+ *
1378+ * @note The CLP library will not modify the contents of @a strs or @a vals.
1379+ * The calling program can modify the @a strs array, but the actual strings
1380+ * (for instance, @a strs[0] and @a strs[1]) must not be modified or freed
1381+ * until the parser is destroyed.
1382+ */
1383+int
1384+Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags,
1385+ int nstrs, const char * const *strs,
1386+ const int *vals)
1387+ /* An alternate way to make a string list type. See Clp_AddStringListType
1388+ for the basics; this coalesces the strings and values into two arrays,
1389+ rather than spreading them out into a variable argument list. */
1390+{
1391+ int i;
1392+ int itemscap = (nstrs < 5 ? 5 : nstrs);
1393+ Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
1394+ if (!items)
1395+ return -1;
1396+
1397+ /* copy over items */
1398+ for (i = 0; i < nstrs; i++) {
1399+ items[i].long_name = strs[i];
1400+ items[i].option_id = vals[i];
1401+ items[i].flags = 0;
1402+ }
1403+
1404+ if (finish_string_list(clp, val_type, flags, items, nstrs, itemscap) >= 0)
1405+ return 0;
1406+ else {
1407+ free(items);
1408+ return -1;
1409+ }
1410+}
1411+
1412+
1413+/*******
1414+ * Returning information
1415+ **/
1416+
1417+const char *
1418+Clp_ProgramName(Clp_Parser *clp)
1419+{
1420+ return clp->internal->program_name;
1421+}
1422+
1423+/** @param clp the parser
1424+ * @param name new program name
1425+ * @return previous program name
1426+ *
1427+ * The calling program should not modify or free @a name until @a clp itself
1428+ * is destroyed. */
1429+const char *
1430+Clp_SetProgramName(Clp_Parser *clp, const char *name)
1431+{
1432+ const char *old = clp->internal->program_name;
1433+ clp->internal->program_name = name;
1434+ return old;
1435+}
1436+
1437+
1438+/******
1439+ * Clp_ParserStates
1440+ **/
1441+
1442+/** @return the parser state
1443+ *
1444+ * A Clp_ParserState object can store a parsing state of a Clp_Parser object.
1445+ * This state specifies exactly how far the Clp_Parser has gotten in parsing
1446+ * an argument list. The Clp_SaveParser() and Clp_RestoreParser() functions
1447+ * can be used to save this state and then restore it later, allowing a
1448+ * Clp_Parser to switch among argument lists.
1449+ *
1450+ * The initial state is empty, in that after Clp_RestoreParser(clp, state),
1451+ * Clp_Next(clp) would return Clp_Done.
1452+ *
1453+ * Parser states can be saved and restored among different parser objects.
1454+ *
1455+ * @sa Clp_DeleteParserState, Clp_SaveParser, Clp_RestoreParser
1456+ */
1457+Clp_ParserState *
1458+Clp_NewParserState(void)
1459+{
1460+ Clp_ParserState *state = (Clp_ParserState *)malloc(sizeof(Clp_ParserState));
1461+ if (state) {
1462+ state->argv = 0;
1463+ state->argc = 0;
1464+ state->option_chars[0] = 0;
1465+ state->xtext = 0;
1466+ state->option_processing = 0;
1467+ state->opt_generation = 0;
1468+ state->current_option = -1;
1469+ state->is_short = 0;
1470+ state->whole_negated = 0;
1471+ state->current_short = 0;
1472+ state->negated_by_no = 0;
1473+ }
1474+ return state;
1475+}
1476+
1477+/** @param state parser state
1478+ *
1479+ * The memory associated with @a state is freed.
1480+ */
1481+void
1482+Clp_DeleteParserState(Clp_ParserState *state)
1483+{
1484+ free(state);
1485+}
1486+
1487+/** @param clp the parser
1488+ * @param state parser state
1489+ * @sa Clp_NewParserState, Clp_RestoreParser
1490+ */
1491+void
1492+Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state)
1493+{
1494+ Clp_Internal *cli = clp->internal;
1495+ state->argv = cli->argv;
1496+ state->argc = cli->argc;
1497+ memcpy(state->option_chars, cli->option_chars, Clp_OptionCharsSize);
1498+ state->xtext = cli->xtext;
1499+
1500+ state->option_processing = cli->option_processing;
1501+ state->opt_generation = cli->opt_generation;
1502+ state->current_option = cli->current_option;
1503+ state->is_short = cli->is_short;
1504+ state->whole_negated = cli->whole_negated;
1505+ state->current_short = cli->current_short;
1506+ state->negated_by_no = cli->negated_by_no;
1507+}
1508+
1509+
1510+/** @param clp the parser
1511+ * @param state parser state
1512+ *
1513+ * The parser state in @a state is restored into @a clp. The next call to
1514+ * Clp_Next() will return the same result as it would have at the time @a
1515+ * state was saved (probably by Clp_SaveParser(@a clp, @a state)).
1516+ *
1517+ * A parser state contains information about arguments (argc and argv; see
1518+ * Clp_SetArguments()) and option processing (Clp_SetOptionProcessing()), but
1519+ * not about options (Clp_SetOptions()). Changes to options and value types
1520+ * are preserved across Clp_RestoreParser().
1521+ *
1522+ * @sa Clp_NewParserState, Clp_SaveParser
1523+ */
1524+void
1525+Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state)
1526+{
1527+ Clp_Internal *cli = clp->internal;
1528+ cli->argv = state->argv;
1529+ cli->argc = state->argc;
1530+ memcpy(cli->option_chars, state->option_chars, Clp_OptionCharsSize);
1531+ cli->xtext = state->xtext;
1532+ cli->option_processing = state->option_processing;
1533+ cli->is_short = state->is_short;
1534+ cli->whole_negated = state->whole_negated;
1535+ cli->current_short = state->current_short;
1536+ cli->negated_by_no = state->negated_by_no;
1537+ if (cli->opt_generation == state->opt_generation)
1538+ cli->current_option = state->current_option;
1539+ else
1540+ cli->current_option = -1;
1541+}
1542+
1543+
1544+/*******
1545+ * Clp_Next and its helpers
1546+ **/
1547+
1548+static void
1549+set_option_text(Clp_Internal *cli, const char *text, int n_option_chars)
1550+{
1551+ assert(n_option_chars < Clp_OptionCharsSize);
1552+ memcpy(cli->option_chars, text, n_option_chars);
1553+ cli->option_chars[n_option_chars] = 0;
1554+ cli->xtext = text + n_option_chars;
1555+}
1556+
1557+static int
1558+get_oclass(Clp_Parser *clp, const char *text, int *ocharskip)
1559+{
1560+ int c;
1561+ if (clp->internal->utf8) {
1562+ const char *s;
1563+ c = decode_utf8(text, &s);
1564+ *ocharskip = s - text;
1565+ } else {
1566+ c = (unsigned char) text[0];
1567+ *ocharskip = 1;
1568+ }
1569+ return Clp_OptionChar(clp, c);
1570+}
1571+
1572+static int
1573+next_argument(Clp_Parser *clp, int want_argument)
1574+ /* Moves clp to the next argument.
1575+ Returns 1 if it finds another option.
1576+ Returns 0 if there aren't any more arguments.
1577+ Returns 0, sets clp->have_val = 1, and sets clp->vstr to the argument
1578+ if the next argument isn't an option.
1579+ If want_argument > 0, it'll look for an argument.
1580+ want_argument == 1: Accept arguments that start with Clp_NotOption
1581+ or Clp_LongImplicit.
1582+ want_argument == 2: Accept ALL arguments.
1583+
1584+ Where is the option stored when this returns?
1585+ Well, cli->argv[0] holds the whole of the next command line argument.
1586+ cli->option_chars holds a string: what characters began the option?
1587+ It is generally "-" or "--".
1588+ cli->text holds the text of the option:
1589+ for short options, cli->text[0] is the relevant character;
1590+ for long options, cli->text holds the rest of the option. */
1591+{
1592+ Clp_Internal *cli = clp->internal;
1593+ const char *text;
1594+ int oclass, ocharskip;
1595+
1596+ /* clear relevant flags */
1597+ clp->have_val = 0;
1598+ clp->vstr = 0;
1599+ cli->could_be_short = 0;
1600+
1601+ /* if we're in a string of short options, move up one char in the string */
1602+ if (cli->is_short) {
1603+ cli->xtext += clp_utf8_charlen(cli, cli->xtext);
1604+ if (cli->xtext[0] == 0)
1605+ cli->is_short = 0;
1606+ else if (want_argument > 0) {
1607+ /* handle -O[=]argument case */
1608+ clp->have_val = 1;
1609+ if (cli->xtext[0] == '=')
1610+ clp->vstr = cli->xtext + 1;
1611+ else
1612+ clp->vstr = cli->xtext;
1613+ cli->is_short = 0;
1614+ return 0;
1615+ }
1616+ }
1617+
1618+ /* if in short options, we're all set */
1619+ if (cli->is_short)
1620+ return 1;
1621+
1622+ /** if not in short options, move to the next argument **/
1623+ cli->whole_negated = 0;
1624+ cli->xtext = 0;
1625+
1626+ if (cli->argc <= 1)
1627+ return 0;
1628+
1629+ cli->argc--;
1630+ cli->argv++;
1631+ text = cli->argv[0];
1632+
1633+ if (want_argument > 1)
1634+ goto not_option;
1635+
1636+ if (text[0] == '-' && text[1] == '-') {
1637+ oclass = Clp_DoubledLong;
1638+ ocharskip = 2;
1639+ } else
1640+ oclass = get_oclass(clp, text, &ocharskip);
1641+
1642+ /* If this character could introduce either a short or a long option,
1643+ try a long option first, but remember that short's a possibility for
1644+ later. */
1645+ if ((oclass & (Clp_Short | Clp_ShortNegated))
1646+ && (oclass & (Clp_Long | Clp_LongNegated))) {
1647+ oclass &= ~(Clp_Short | Clp_ShortNegated);
1648+ if (text[ocharskip])
1649+ cli->could_be_short = 1;
1650+ }
1651+
1652+ switch (oclass) {
1653+
1654+ case Clp_Short:
1655+ cli->is_short = 1;
1656+ goto check_singleton;
1657+
1658+ case Clp_ShortNegated:
1659+ cli->is_short = 1;
1660+ cli->whole_negated = 1;
1661+ goto check_singleton;
1662+
1663+ case Clp_Long:
1664+ goto check_singleton;
1665+
1666+ case Clp_LongNegated:
1667+ cli->whole_negated = 1;
1668+ goto check_singleton;
1669+
1670+ check_singleton:
1671+ /* For options introduced with one character, option-char,
1672+ '[option-char]' alone is NOT an option. */
1673+ if (!text[ocharskip])
1674+ goto not_option;
1675+ set_option_text(cli, text, ocharskip);
1676+ break;
1677+
1678+ case Clp_LongImplicit:
1679+ /* LongImplict: option_chars == "" (since all chars are part of the
1680+ option); restore head -> text of option */
1681+ if (want_argument > 0)
1682+ goto not_option;
1683+ set_option_text(cli, text, 0);
1684+ break;
1685+
1686+ case Clp_DoubledLong:
1687+ set_option_text(cli, text, ocharskip);
1688+ break;
1689+
1690+ not_option:
1691+ case Clp_NotOption:
1692+ cli->is_short = 0;
1693+ clp->have_val = 1;
1694+ clp->vstr = text;
1695+ return 0;
1696+
1697+ default:
1698+ assert(0 /* CLP misconfiguration: bad option type */);
1699+
1700+ }
1701+
1702+ return 1;
1703+}
1704+
1705+
1706+static void
1707+switch_to_short_argument(Clp_Parser *clp)
1708+{
1709+ Clp_Internal *cli = clp->internal;
1710+ const char *text = cli->argv[0];
1711+ int ocharskip, oclass = get_oclass(clp, text, &ocharskip);
1712+ assert(cli->could_be_short);
1713+ cli->is_short = 1;
1714+ cli->whole_negated = (oclass & Clp_ShortNegated ? 1 : 0);
1715+ set_option_text(cli, cli->argv[0], ocharskip);
1716+}
1717+
1718+
1719+static int
1720+find_long(Clp_Parser *clp, const char *arg)
1721+ /* If arg corresponds to one of clp's options, finds that option &
1722+ returns it. If any argument is given after an = sign in arg, sets
1723+ clp->have_val = 1 and clp->vstr to that argument. Sets cli->ambiguous
1724+ to 1 iff there was no match because the argument was ambiguous. */
1725+{
1726+ Clp_Internal *cli = clp->internal;
1727+ int optno, len, lmm;
1728+ const Clp_Option *opt = cli->opt;
1729+ const Clp_InternOption *iopt;
1730+ int first_negative_ambiguous;
1731+
1732+ /* Look for a normal option. */
1733+ optno = find_prefix_opt
1734+ (clp, arg, cli->nopt, opt, cli->iopt,
1735+ &cli->ambiguous, cli->ambiguous_values);
1736+ if (optno >= 0)
1737+ goto worked;
1738+
1739+ /* If we can't find it, look for a negated option. */
1740+ /* I know this is silly, but it makes me happy to accept
1741+ --no-no-option as a double negative synonym for --option. :) */
1742+ first_negative_ambiguous = cli->ambiguous;
1743+ while (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') {
1744+ arg += 3;
1745+ clp->negated = !clp->negated;
1746+ optno = find_prefix_opt
1747+ (clp, arg, cli->nopt, opt, cli->iopt,
1748+ &cli->ambiguous, cli->ambiguous_values);
1749+ if (optno >= 0)
1750+ goto worked;
1751+ }
1752+
1753+ /* No valid option was found; return 0. Mark the ambiguous values found
1754+ through '--no' by making them negative. */
1755+ {
1756+ int i, max = cli->ambiguous;
1757+ if (max > MAX_AMBIGUOUS_VALUES) max = MAX_AMBIGUOUS_VALUES;
1758+ for (i = first_negative_ambiguous; i < max; i++)
1759+ cli->ambiguous_values[i] = -cli->ambiguous_values[i] - 1;
1760+ }
1761+ return -1;
1762+
1763+ worked:
1764+ iopt = &cli->iopt[optno];
1765+ lmm = (clp->negated ? iopt->lmmneg : iopt->lmmpos);
1766+ if (cli->could_be_short
1767+ && (clp->negated ? iopt->lmmneg_short : iopt->lmmpos_short)) {
1768+ int first_charlen = clp_utf8_charlen(cli, arg);
1769+ lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm);
1770+ }
1771+ len = argcmp(opt[optno].long_name + iopt->ilongoff, arg, lmm, 1);
1772+ assert(len > 0);
1773+ if (arg[len] == '=') {
1774+ clp->have_val = 1;
1775+ clp->vstr = arg + len + 1;
1776+ }
1777+ return optno;
1778+}
1779+
1780+
1781+static int
1782+find_short(Clp_Parser *clp, const char *text)
1783+ /* If short_name corresponds to one of clp's options, returns it. */
1784+{
1785+ Clp_Internal *cli = clp->internal;
1786+ const Clp_Option *opt = cli->opt;
1787+ const Clp_InternOption *iopt = cli->iopt;
1788+ int i, c;
1789+ if (clp->internal->utf8)
1790+ c = decode_utf8(text, 0);
1791+ else
1792+ c = (unsigned char) *text;
1793+
1794+ for (i = 0; i < cli->nopt; i++)
1795+ if (iopt[i].ishort && opt[i].short_name == c
1796+ && (clp->negated ? iopt[i].ineg : iopt[i].ipos))
1797+ return i;
1798+
1799+ return -1;
1800+}
1801+
1802+
1803+/** @param clp the parser
1804+ * @return option ID of next option
1805+ *
1806+ * Parse the next argument from the argument list, store information about
1807+ * that argument in the fields of @a clp, and return the option's ID.
1808+ *
1809+ * If an argument was successfully parsed, that option's ID is returned.
1810+ * Other possible return values are:
1811+ *
1812+ * <dl>
1813+ * <dt>Clp_Done</dt>
1814+ * <dd>There are no more arguments.</dd>
1815+ * <dt>Clp_NotOption</dt>
1816+ * <dd>The next argument was not an option. The argument's text is @a
1817+ * clp->vstr (and @a clp->val.s).</dd>
1818+ * <dt>Clp_BadOption</dt>
1819+ * <dd>The next argument was a bad option: either an option that wasn't
1820+ * understood, or an option lacking a required value, or an option whose value
1821+ * couldn't be parsed. The option has been skipped.</dd>
1822+ * <dt>Clp_Error</dt>
1823+ * <dd>There was an internal error. This should never occur unless a user
1824+ * messes with, for example, a Clp_Option array.</dd>
1825+ * </dl>
1826+ *
1827+ * The fields of @a clp are set as follows.
1828+ *
1829+ * <dl>
1830+ * <dt><tt>negated</tt></dt>
1831+ * <dd>1 if the option was negated, 0 if it wasn't.</dd>
1832+ * <dt><tt>have_val</tt></dt>
1833+ * <dd>1 if the option had a value, 0 if it didn't. Note that negated options
1834+ * are not allowed to have values.</dd>
1835+ * <dt><tt>vstr</tt></dt>
1836+ * <dd>The value string, if any. NULL if there was no value.</dd>
1837+ * <dt><tt>val</tt></dt>
1838+ * <dd>An option's value type will parse the value string into this
1839+ * union.</dd>
1840+ * </dl>
1841+ *
1842+ * The parsed argument is shifted off the argument list, so that sequential
1843+ * calls to Clp_Next() step through the arugment list.
1844+ */
1845+int
1846+Clp_Next(Clp_Parser *clp)
1847+{
1848+ Clp_Internal *cli = clp->internal;
1849+ int optno;
1850+ const Clp_Option *opt;
1851+ Clp_ParserState clpsave;
1852+ int vtpos, complain;
1853+
1854+ /* Set up clp */
1855+ cli->current_option = -1;
1856+ cli->ambiguous = 0;
1857+
1858+ /* Get the next argument or option */
1859+ if (!next_argument(clp, cli->option_processing ? 0 : 2)) {
1860+ clp->val.s = clp->vstr;
1861+ return clp->have_val ? Clp_NotOption : Clp_Done;
1862+ }
1863+
1864+ clp->negated = cli->whole_negated;
1865+ if (cli->is_short)
1866+ optno = find_short(clp, cli->xtext);
1867+ else
1868+ optno = find_long(clp, cli->xtext);
1869+
1870+ /* If there's ambiguity between long & short options, and we couldn't
1871+ find a long option, look for a short option */
1872+ if (optno < 0 && cli->could_be_short) {
1873+ switch_to_short_argument(clp);
1874+ optno = find_short(clp, cli->xtext);
1875+ }
1876+
1877+ /* If we didn't find an option... */
1878+ if (optno < 0 || (clp->negated && !cli->iopt[optno].ineg)) {
1879+ /* default processing for the "--" option: turn off option processing
1880+ and return the next argument */
1881+ if (strcmp(cli->argv[0], "--") == 0) {
1882+ Clp_SetOptionProcessing(clp, 0);
1883+ return Clp_Next(clp);
1884+ }
1885+
1886+ /* otherwise, report some error or other */
1887+ if (cli->ambiguous)
1888+ ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values,
1889+ cli->opt, cli->iopt, cli->option_chars,
1890+ "option %<%s%s%> is ambiguous",
1891+ cli->option_chars, cli->xtext);
1892+ else if (cli->is_short && !cli->could_be_short)
1893+ Clp_OptionError(clp, "unrecognized option %<%s%C%>",
1894+ cli->option_chars, cli->xtext);
1895+ else
1896+ Clp_OptionError(clp, "unrecognized option %<%s%s%>",
1897+ cli->option_chars, cli->xtext);
1898+
1899+ return Clp_BadOption;
1900+ }
1901+
1902+ /* Set the current option */
1903+ cli->current_option = optno;
1904+ cli->current_short = cli->is_short;
1905+ cli->negated_by_no = clp->negated && !cli->whole_negated;
1906+
1907+ /* The no-argument (or should-have-no-argument) case */
1908+ if (clp->negated
1909+ || (!cli->iopt[optno].imandatory && !cli->iopt[optno].ioptional)) {
1910+ if (clp->have_val) {
1911+ Clp_OptionError(clp, "%<%O%> can%,t take an argument");
1912+ return Clp_BadOption;
1913+ } else
1914+ return cli->opt[optno].option_id;
1915+ }
1916+
1917+ /* Get an argument if we need one, or if it's optional */
1918+ /* Sanity-check the argument type. */
1919+ opt = &cli->opt[optno];
1920+ if (opt->val_type <= 0)
1921+ return Clp_Error;
1922+ vtpos = val_type_binsearch(cli, opt->val_type);
1923+ if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != opt->val_type)
1924+ return Clp_Error;
1925+
1926+ /* complain == 1 only if the argument was explicitly given,
1927+ or it is mandatory. */
1928+ complain = (clp->have_val != 0) || cli->iopt[optno].imandatory;
1929+ Clp_SaveParser(clp, &clpsave);
1930+
1931+ if (cli->iopt[optno].imandatory && !clp->have_val) {
1932+ /* Mandatory argument case */
1933+ /* Allow arguments to options to start with a dash, but only if the
1934+ argument type allows it by not setting Clp_DisallowOptions */
1935+ int disallow = (cli->valtype[vtpos].flags & Clp_DisallowOptions) != 0;
1936+ next_argument(clp, disallow ? 1 : 2);
1937+ if (!clp->have_val) {
1938+ int got_option = cli->xtext != 0;
1939+ Clp_RestoreParser(clp, &clpsave);
1940+ if (got_option)
1941+ Clp_OptionError(clp, "%<%O%> requires a non-option argument");
1942+ else
1943+ Clp_OptionError(clp, "%<%O%> requires an argument");
1944+ return Clp_BadOption;
1945+ }
1946+
1947+ } else if (cli->is_short && !clp->have_val
1948+ && cli->xtext[clp_utf8_charlen(cli, cli->xtext)])
1949+ /* The -[option]argument case:
1950+ Assume that the rest of the current string is the argument. */
1951+ next_argument(clp, 1);
1952+
1953+ /* Parse the argument */
1954+ if (clp->have_val) {
1955+ Clp_ValType *atr = &cli->valtype[vtpos];
1956+ if (atr->func(clp, clp->vstr, complain, atr->user_data) <= 0) {
1957+ /* parser failed */
1958+ clp->have_val = 0;
1959+ if (cli->iopt[optno].imandatory)
1960+ return Clp_BadOption;
1961+ else
1962+ Clp_RestoreParser(clp, &clpsave);
1963+ }
1964+ }
1965+
1966+ return opt->option_id;
1967+}
1968+
1969+
1970+/** @param clp the parser
1971+ * @param allow_options whether options will be allowed
1972+ *
1973+ * Remove and return the next argument from @a clp's argument array. If there
1974+ * are no arguments left, or if the next argument is an option and @a
1975+ * allow_options != 0, then returns null.
1976+ */
1977+const char *
1978+Clp_Shift(Clp_Parser *clp, int allow_options)
1979+ /* Returns the next argument from the argument list without parsing it.
1980+ If there are no more arguments, returns 0. */
1981+{
1982+ Clp_ParserState clpsave;
1983+ Clp_SaveParser(clp, &clpsave);
1984+ next_argument(clp, allow_options ? 2 : 1);
1985+ if (!clp->have_val)
1986+ Clp_RestoreParser(clp, &clpsave);
1987+ return clp->vstr;
1988+}
1989+
1990+
1991+/*******
1992+ * Clp_OptionError
1993+ **/
1994+
1995+typedef struct Clp_BuildString {
1996+ char *text;
1997+ char *pos;
1998+ int capacity;
1999+ int bad;
2000+} Clp_BuildString;
2001+
2002+static Clp_BuildString *
2003+new_build_string(void)
2004+{
2005+ Clp_BuildString *bs = (Clp_BuildString *)malloc(sizeof(Clp_BuildString));
2006+ if (!bs) goto bad;
2007+ bs->text = (char *)malloc(256);
2008+ if (!bs->text) goto bad;
2009+ bs->pos = bs->text;
2010+ bs->capacity = 256;
2011+ bs->bad = 0;
2012+ return bs;
2013+
2014+ bad:
2015+ if (bs) free(bs);
2016+ return 0;
2017+}
2018+
2019+static void
2020+free_build_string(Clp_BuildString *bs)
2021+{
2022+ if (bs) free(bs->text);
2023+ free(bs);
2024+}
2025+
2026+static int
2027+grow_build_string(Clp_BuildString *bs, int want)
2028+{
2029+ char *new_text;
2030+ int ipos = bs->pos - bs->text;
2031+ int new_capacity = bs->capacity;
2032+ while (want >= new_capacity)
2033+ new_capacity *= 2;
2034+ new_text = (char *)realloc(bs->text, new_capacity);
2035+ if (!new_text) {
2036+ bs->bad = 1;
2037+ return 0;
2038+ } else {
2039+ bs->text = new_text;
2040+ bs->pos = bs->text + ipos;
2041+ bs->capacity = new_capacity;
2042+ return 1;
2043+ }
2044+}
2045+
2046+#define ENSURE_BUILD_STRING(bs, space) \
2047+ ((((bs)->pos - (bs)->text) + (space) >= (bs)->capacity) \
2048+ || grow_build_string((bs), ((bs)->pos - (bs)->text) + (space)))
2049+
2050+static void
2051+append_build_string(Clp_BuildString *bs, const char *s, int l)
2052+{
2053+ if (l < 0)
2054+ l = strlen(s);
2055+ if (ENSURE_BUILD_STRING(bs, l)) {
2056+ memcpy(bs->pos, s, l);
2057+ bs->pos += l;
2058+ }
2059+}
2060+
2061+
2062+static Clp_BuildString *
2063+Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs,
2064+ const char *fmt, va_list val)
2065+{
2066+ Clp_Internal *cli = clp->internal;
2067+ const char *percent;
2068+ int c;
2069+
2070+ if (!bs)
2071+ bs = new_build_string();
2072+ if (!bs)
2073+ return 0;
2074+ if (cli->program_name && cli->program_name[0]) {
2075+ append_build_string(bs, cli->program_name, -1);
2076+ append_build_string(bs, ": ", 2);
2077+ }
2078+
2079+ for (percent = strchr(fmt, '%'); percent; percent = strchr(fmt, '%')) {
2080+ append_build_string(bs, fmt, percent - fmt);
2081+ switch (*++percent) {
2082+
2083+ case 's': {
2084+ const char *s = va_arg(val, const char *);
2085+ if (s)
2086+ append_build_string(bs, s, -1);
2087+ else
2088+ append_build_string(bs, "(null)", 6);
2089+ break;
2090+ }
2091+
2092+ case 'C': {
2093+ const char *s = va_arg(val, const char *);
2094+ if (cli->utf8)
2095+ c = decode_utf8(s, 0);
2096+ else
2097+ c = (unsigned char) *s;
2098+ goto char_c;
2099+ }
2100+
2101+ case 'c':
2102+ c = va_arg(val, int);
2103+ goto char_c;
2104+
2105+ char_c:
2106+ if (ENSURE_BUILD_STRING(bs, 4)) {
2107+ if (c >= 32 && c <= 126)
2108+ *bs->pos++ = c;
2109+ else if (c < 32) {
2110+ *bs->pos++ = '^';
2111+ *bs->pos++ = c + 64;
2112+ } else if (cli->utf8 && c >= 127 && c < 0x110000) {
2113+ bs->pos = encode_utf8(bs->pos, 4, c);
2114+ } else if (c >= 127 && c <= 255) {
2115+ sprintf(bs->pos, "\\%03o", c & 0xFF);
2116+ bs->pos += 4;
2117+ } else {
2118+ *bs->pos++ = '\\';
2119+ *bs->pos++ = '?';
2120+ }
2121+ }
2122+ break;
2123+
2124+ case 'd': {
2125+ int d = va_arg(val, int);
2126+ if (ENSURE_BUILD_STRING(bs, 32)) {
2127+ sprintf(bs->pos, "%d", d);
2128+ bs->pos = strchr(bs->pos, 0);
2129+ }
2130+ break;
2131+ }
2132+
2133+ case 'O': {
2134+ int optno = cli->current_option;
2135+ const Clp_Option *opt = &cli->opt[optno];
2136+ if (optno < 0)
2137+ append_build_string(bs, "(no current option!)", -1);
2138+ else if (cli->current_short) {
2139+ append_build_string(bs, cli->option_chars, -1);
2140+ if (ENSURE_BUILD_STRING(bs, 5)) {
2141+ if (cli->utf8)
2142+ bs->pos = encode_utf8(bs->pos, 5, opt->short_name);
2143+ else
2144+ *bs->pos++ = opt->short_name;
2145+ }
2146+ } else if (cli->negated_by_no) {
2147+ append_build_string(bs, cli->option_chars, -1);
2148+ append_build_string(bs, "no-", 3);
2149+ append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1);
2150+ } else {
2151+ append_build_string(bs, cli->option_chars, -1);
2152+ append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1);
2153+ }
2154+ break;
2155+ }
2156+
2157+ case '%':
2158+ if (ENSURE_BUILD_STRING(bs, 1))
2159+ *bs->pos++ = '%';
2160+ break;
2161+
2162+ case '`': /* backwards compatibility */
2163+ case '<':
2164+ append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1);
2165+ break;
2166+
2167+ case '\'': /* backwards compatibility */
2168+ case ',':
2169+ case '>':
2170+ append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1);
2171+ break;
2172+
2173+ default:
2174+ if (ENSURE_BUILD_STRING(bs, 2)) {
2175+ *bs->pos++ = '%';
2176+ *bs->pos++ = *percent;
2177+ }
2178+ break;
2179+
2180+ }
2181+ fmt = ++percent;
2182+ }
2183+
2184+ append_build_string(bs, fmt, -1);
2185+ append_build_string(bs, "\n", 1);
2186+
2187+ return bs;
2188+}
2189+
2190+static void
2191+do_error(Clp_Parser *clp, Clp_BuildString *bs)
2192+{
2193+ const char *text;
2194+ if (bs && !bs->bad) {
2195+ *bs->pos = 0;
2196+ text = bs->text;
2197+ } else
2198+ text = "out of memory\n";
2199+
2200+ if (clp->internal->error_handler != 0)
2201+ (*clp->internal->error_handler)(clp, text);
2202+ else
2203+ fputs(text, stderr);
2204+}
2205+
2206+/** @param clp the parser
2207+ * @param format error format
2208+ *
2209+ * Format an error message from @a format and any additional arguments in the
2210+ * ellipsis. The resulting error string by printing it to standard error or
2211+ * passing it to Clp_SetErrorHandler.
2212+ *
2213+ * The following format characters are accepted:
2214+ *
2215+ * <dl>
2216+ * <dt><tt>%</tt><tt>c</tt></dt>
2217+ * <dd>A character (type <tt>int</tt>). Control characters are printed in
2218+ * caret notation. If the parser is in UTF-8 mode, the character is formatted
2219+ * in UTF-8. Otherwise, special characters are printed with backslashes and
2220+ * octal notation.</dd>
2221+ * <dt><tt>%</tt><tt>s</tt></dt>
2222+ * <dd>A string (type <tt>const char *</tt>).</dd>
2223+ * <dt><tt>%</tt><tt>C</tt></dt>
2224+ * <dd>The argument is a string (type <tt>const char *</tt>). The first
2225+ * character in this string is printed. If the parser is in UTF-8 mode, this
2226+ * may involve multiple bytes.</dd>
2227+ * <dt><tt>%</tt><tt>d</tt></dt>
2228+ * <dd>An integer (type <tt>int</tt>). Printed in decimal.</dd>
2229+ * <dt><tt>%</tt><tt>O</tt></dt>
2230+ * <dd>The current option. No values are read from the argument list; the
2231+ * current option is defined in the Clp_Parser object itself.</dd>
2232+ * <dt><tt>%%</tt></dt>
2233+ * <dd>Prints a percent character.</dd>
2234+ * <dt><tt>%</tt><tt>&lt;</tt></dt>
2235+ * <dd>Prints an open quote string. In UTF-8 mode, prints a left single
2236+ * quote. Otherwise prints a single quote.</dd>
2237+ * <dt><tt>%</tt><tt>&gt;</tt></dt>
2238+ * <dd>Prints a closing quote string. In UTF-8 mode, prints a right single
2239+ * quote. Otherwise prints a single quote.</dd>
2240+ * <dt><tt>%</tt><tt>,</tt></dt>
2241+ * <dd>Prints an apostrophe. In UTF-8 mode, prints a right single quote.
2242+ * Otherwise prints a single quote.</dd>
2243+ * </dl>
2244+ *
2245+ * Note that no flag characters, precision, or field width characters are
2246+ * currently supported.
2247+ *
2248+ * @sa Clp_SetErrorHandler
2249+ */
2250+int
2251+Clp_OptionError(Clp_Parser *clp, const char *format, ...)
2252+{
2253+ Clp_BuildString *bs;
2254+ va_list val;
2255+ va_start(val, format);
2256+ bs = Clp_VaOptionError(clp, 0, format, val);
2257+ va_end(val);
2258+ do_error(clp, bs);
2259+ free_build_string(bs);
2260+ return 0;
2261+}
2262+
2263+static int
2264+ambiguity_error(Clp_Parser *clp, int ambiguous, int *ambiguous_values,
2265+ const Clp_Option *opt, const Clp_InternOption *iopt,
2266+ const char *prefix, const char *fmt, ...)
2267+{
2268+ Clp_Internal *cli = clp->internal;
2269+ Clp_BuildString *bs;
2270+ int i;
2271+ va_list val;
2272+ va_start(val, fmt);
2273+ bs = Clp_VaOptionError(clp, 0, fmt, val);
2274+ if (!bs) goto done;
2275+
2276+ if (clp->internal->program_name && clp->internal->program_name[0]) {
2277+ append_build_string(bs, clp->internal->program_name, -1);
2278+ append_build_string(bs, ": ", 2);
2279+ }
2280+ append_build_string(bs, "(Possibilities are", -1);
2281+
2282+ for (i = 0; i < ambiguous && i < MAX_AMBIGUOUS_VALUES; i++) {
2283+ int value = ambiguous_values[i];
2284+ const char *no_dash = "";
2285+ if (value < 0)
2286+ value = -(value + 1), no_dash = "no-";
2287+ if (i == 0)
2288+ append_build_string(bs, " ", 1);
2289+ else if (i == ambiguous - 1)
2290+ append_build_string(bs, (i == 1 ? " and " : ", and "), -1);
2291+ else
2292+ append_build_string(bs, ", ", 2);
2293+ append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1);
2294+ append_build_string(bs, prefix, -1);
2295+ append_build_string(bs, no_dash, -1);
2296+ append_build_string(bs, opt[value].long_name + iopt[value].ilongoff, -1);
2297+ append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1);
2298+ }
2299+
2300+ if (ambiguous > MAX_AMBIGUOUS_VALUES)
2301+ append_build_string(bs, ", and others", -1);
2302+ append_build_string(bs, ".)\n", -1);
2303+ va_end(val);
2304+
2305+ done:
2306+ do_error(clp, bs);
2307+ free_build_string(bs);
2308+ return 0;
2309+}
2310+
2311+static int
2312+copy_string(char *buf, int buflen, int bufpos, const char *what)
2313+{
2314+ int l = strlen(what);
2315+ if (l > buflen - bufpos - 1)
2316+ l = buflen - bufpos - 1;
2317+ memcpy(buf + bufpos, what, l);
2318+ return l;
2319+}
2320+
2321+/** @param clp the parser
2322+ * @param buf output buffer
2323+ * @param len length of output buffer
2324+ * @return number of characters written to the buffer, not including the terminating NUL
2325+ *
2326+ * A string that looks like the last option parsed by @a clp is extracted into
2327+ * @a buf. The correct option characters are put into the string first,
2328+ * followed by the option text. The output buffer is null-terminated unless
2329+ * @a len == 0.
2330+ *
2331+ * @sa Clp_CurOptionName
2332+ */
2333+int
2334+Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len)
2335+{
2336+ Clp_Internal *cli = clp->internal;
2337+ int optno = cli->current_option;
2338+ int pos = 0;
2339+ if (optno < 0)
2340+ pos += copy_string(buf, len, pos, "(no current option!)");
2341+ else if (cli->current_short) {
2342+ pos += copy_string(buf, len, pos, cli->option_chars);
2343+ if (cli->utf8)
2344+ pos = (encode_utf8(buf + pos, len - pos - 1, cli->opt[optno].short_name) - buf);
2345+ else if (pos < len - 1)
2346+ buf[pos++] = cli->opt[optno].short_name;
2347+ } else if (cli->negated_by_no) {
2348+ pos += copy_string(buf, len, pos, cli->option_chars);
2349+ pos += copy_string(buf, len, pos, "no-");
2350+ pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff);
2351+ } else {
2352+ pos += copy_string(buf, len, pos, cli->option_chars);
2353+ pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff);
2354+ }
2355+ if (pos < len)
2356+ buf[pos] = 0;
2357+ return pos;
2358+}
2359+
2360+/** @param clp the parser
2361+ * @return string describing the current option
2362+ *
2363+ * This function acts like Clp_CurOptionNameBuf(), but returns a pointer into
2364+ * a static buffer that will be rewritten on the next call to
2365+ * Clp_CurOptionName().
2366+ *
2367+ * @note This function is not thread safe.
2368+ *
2369+ * @sa Clp_CurOptionName
2370+ */
2371+const char *
2372+Clp_CurOptionName(Clp_Parser *clp)
2373+{
2374+ static char buf[256];
2375+ Clp_CurOptionNameBuf(clp, buf, 256);
2376+ return buf;
2377+}
2378+
2379+#ifdef __cplusplus
2380+}
2381+#endif
--- trunk/t1asm/t1lib.h (nonexistent)
+++ trunk/t1asm/t1lib.h (revision 247)
@@ -0,0 +1,56 @@
1+#ifndef T1LIB_H
2+#define T1LIB_H
3+#ifdef __cplusplus
4+extern "C" {
5+#endif
6+
7+#ifdef WIN32
8+# pragma warning (disable: 4007 4096)
9+# define CDECL __cdecl
10+#else
11+# define CDECL
12+#endif
13+
14+#define PFB_MARKER 128
15+#define PFB_ASCII 1
16+#define PFB_BINARY 2
17+#define PFB_DONE 3
18+
19+struct font_reader {
20+ void (*output_ascii)(char *, int);
21+ void (*output_binary)(unsigned char *, int);
22+ void (*output_end)();
23+};
24+
25+void process_pfa(FILE *, const char *filename, struct font_reader *);
26+void process_pfb(FILE *, const char *filename, struct font_reader *);
27+
28+struct pfb_writer {
29+ unsigned char *buf;
30+ unsigned len;
31+ unsigned max_len;
32+ unsigned pos;
33+ int blocktyp;
34+ int binary_blocks_written;
35+ FILE *f;
36+};
37+
38+void init_pfb_writer(struct pfb_writer *, int, FILE *);
39+void pfb_writer_output_block(struct pfb_writer *);
40+void pfb_writer_grow_buf(struct pfb_writer *);
41+void pfb_writer_end(struct pfb_writer *);
42+#define PFB_OUTPUT_BYTE(w, b) do { \
43+ if ((w)->pos >= (w)->len) pfb_writer_grow_buf(w); \
44+ (w)->buf[(w)->pos++] = (b); \
45+ } while (0)
46+
47+int crcbuf(int crc, unsigned int len, const char *buf);
48+
49+/* whoever uses this code must provide a definition for these functions */
50+extern void error(const char *, ...);
51+extern void fatal_error(const char *, ...);
52+
53+#ifdef __cplusplus
54+}
55+#endif
56+#endif
--- trunk/t1asm/clp.h (nonexistent)
+++ trunk/t1asm/clp.h (revision 247)
@@ -0,0 +1,339 @@
1+/* -*- related-file-name: "../../liblcdf/clp.c" -*- */
2+#ifndef CLP_H
3+#define CLP_H
4+#ifdef __cplusplus
5+extern "C" {
6+#endif
7+
8+/* clp.h - Public interface to CLP.
9+ * This file is part of CLP, the command line parser package.
10+ *
11+ * Copyright (c) 1997-2011 Eddie Kohler, ekohler@gmail.com
12+ *
13+ * Permission is hereby granted, free of charge, to any person obtaining a
14+ * copy of this software and associated documentation files (the "Software"),
15+ * to deal in the Software without restriction, subject to the conditions
16+ * listed in the Click LICENSE file, which is available in full at
17+ * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you
18+ * must preserve this copyright notice, and you cannot mention the copyright
19+ * holders in advertising related to the Software without their permission.
20+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
21+ * notice is a summary of the Click LICENSE file; the license in that file is
22+ * legally binding. */
23+
24+/* Note added by Matthew Skala: as of this writing (March 28, 2012) the
25+ * above license URL doesn't work. But digging around on the Web site it
26+ * redirects to yields the link http://www.read.cs.ucla.edu/click/license ,
27+ * which contains the following notice. Since the one above says that the
28+ * one on the Web is binding, and the one on the Web says that it "shall"
29+ * be included in all copies - a Web pointer not being enough precisely
30+ * because of this kind of confusion when URLs change - I'm going to
31+ * include the license notice in its entirety below. */
32+
33+/********************************************************************
34+ * The Click License
35+ *
36+ * Permission is hereby granted, free of charge, to any person
37+ * obtaining a copy of this software and associated documentation files
38+ * (the "Software"), to deal in the Software without restriction,
39+ * including without limitation the rights to use, copy, modify, merge,
40+ * publish, distribute, sublicense, and/or sell copies of the Software,
41+ * and to permit persons to whom the Software is furnished to do so,
42+ * subject to the following conditions:
43+ *
44+ * The above copyright notice and this permission notice shall be
45+ * included in all copies or substantial portions of the Software.
46+ *
47+ * The name and trademarks of copyright holders may NOT be used in
48+ * advertising or publicity pertaining to the Software without specific,
49+ * written prior permission. Title to copyright in this Software and
50+ * any associated documentation will at all times remain with copyright
51+ * holders.
52+ *
53+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
54+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
57+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
58+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
59+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
60+ **********************************************************************/
61+
62+typedef struct Clp_Option Clp_Option;
63+typedef struct Clp_Parser Clp_Parser;
64+typedef struct Clp_ParserState Clp_ParserState;
65+
66+
67+/** @brief Option description.
68+ *
69+ * CLP users declare arrays of Clp_Option structures to specify what options
70+ * should be parsed.
71+ * @sa Clp_NewParser, Clp_SetOptions */
72+struct Clp_Option {
73+ const char *long_name; /**< Name of long option, or NULL if the option
74+ has no long name. */
75+ int short_name; /**< Character defining short option, or 0 if
76+ the option has no short name. */
77+ int option_id; /**< User-specified ID defining option,
78+ returned by Clp_Next. */
79+ int val_type; /**< ID of option's value type, or 0 if option
80+ takes no value. */
81+ int flags; /**< Option parsing flags. */
82+};
83+
84+/** @name Value types
85+ * These values describe the type of an option's argument and are used in
86+ * the Clp_Option val_type field. For example, if an option took integers, its
87+ * Clp_Option structure would have val_type set to Clp_ValInt. */
88+/**@{*/
89+#define Clp_NoVal 0 /**< @brief Option takes no value. */
90+#define Clp_ValString 1 /**< @brief Option value is an
91+ arbitrary string. */
92+#define Clp_ValStringNotOption 2 /**< @brief Option value is a
93+ non-option string.
94+
95+ See Clp_DisallowOptions. */
96+#define Clp_ValBool 3 /**< @brief Option value is a
97+ boolean.
98+
99+ Accepts "true", "false", "yes", "no", "1", and "0", or any
100+ prefixes thereof. The match is case-insensitive. */
101+#define Clp_ValInt 4 /**< @brief Option value is a
102+ signed int.
103+
104+ Accepts an optional "+" or "-" sign, followed by one or more
105+ digits. The digits may be include a "0x" or "0X" prefix, for
106+ a hexidecimal number, or a "0" prefix, for an octal number;
107+ otherwise it is decimal. */
108+#define Clp_ValUnsigned 5 /**< @brief Option value is an
109+ unsigned int.
110+
111+ Accepts an optional "+" sign, followed by one or more
112+ digits. The digits may be include a "0x" or "0X" prefix, for
113+ a hexidecimal number, or a "0" prefix, for an octal number;
114+ otherwise it is decimal. */
115+#define Clp_ValDouble 6 /**< @brief Option value is a
116+ double.
117+ Accepts a real number as defined by strtod(). */
118+#define Clp_ValFirstUser 10 /**< @brief Value types >=
119+ Clp_ValFirstUser are available
120+ for user types. */
121+/**@}*/
122+
123+/** @name Option flags
124+ * These flags are used in the Clp_Option flags field. */
125+/**@{*/
126+#define Clp_Mandatory (1<<0) /**< @brief Option flag: value
127+ is mandatory.
128+
129+ It is an error if the option has no value. This is the
130+ default if an option has arg_type != 0 and the Clp_Optional
131+ flag is not provided. */
132+#define Clp_Optional (1<<1) /**< @brief Option flag: value
133+ is optional. */
134+#define Clp_Negate (1<<2) /**< @brief Option flag: option
135+ may be negated.
136+
137+ --no-[long_name] will be accepted in argument lists. */
138+#define Clp_OnlyNegated (1<<3) /**< @brief Option flag: option
139+ <em>must</em> be negated.
140+
141+ --no-[long_name] will be accepted in argument lists, but
142+ --[long_name] will not. This is the default if long_name
143+ begins with "no-". */
144+#define Clp_PreferredMatch (1<<4) /**< @brief Option flag: prefer this
145+ option when matching.
146+
147+ Prefixes of --[long_name] should map to this option, even if
148+ other options begin with --[long_name]. */
149+/**@}*/
150+
151+/** @name Option character types
152+ * These flags are used in to define character types in Clp_SetOptionChar(). */
153+/**@{*/
154+/* Clp_NotOption 0 */
155+#define Clp_Short (1<<0) /**< @brief Option character begins
156+ a set of short options. */
157+#define Clp_Long (1<<1) /**< @brief Option character begins
158+ a long option. */
159+#define Clp_ShortNegated (1<<2) /**< @brief Option character begins
160+ a set of negated short options. */
161+#define Clp_LongNegated (1<<3) /**< @brief Option character begins
162+ a negated long option. */
163+#define Clp_LongImplicit (1<<4) /**< @brief Option character can begin
164+ a long option, and is part of that
165+ long option. */
166+/**@}*/
167+
168+#define Clp_NotOption 0 /**< @brief Clp_Next value: argument
169+ was not an option. */
170+#define Clp_Done -1 /**< @brief Clp_Next value: there are
171+ no more arguments. */
172+#define Clp_BadOption -2 /**< @brief Clp_Next value: argument
173+ was an erroneous option. */
174+#define Clp_Error -3 /**< @brief Clp_Next value: internal
175+ CLP error. */
176+
177+#define Clp_ValSize 40 /**< @brief Minimum size of the
178+ Clp_Parser val.cs field. */
179+#define Clp_ValIntSize 10 /**< @brief Minimum size of the
180+ Clp_Parser val.is field. */
181+
182+
183+/** @brief A value parsing function.
184+ * @param clp the parser
185+ * @param vstr the value to be parsed
186+ * @param complain if nonzero, report error messages via Clp_OptionError
187+ * @param user_data user data passed to Clp_AddType()
188+ * @return 1 if parsing succeeded, 0 otherwise
189+ */
190+typedef int (*Clp_ValParseFunc)(Clp_Parser *clp, const char *vstr,
191+ int complain, void *user_data);
192+
193+/** @brief A function for reporting option errors.
194+ * @param clp the parser
195+ * @param message error message
196+ */
197+typedef void (*Clp_ErrorHandler)(Clp_Parser *clp, const char *message);
198+
199+
200+/** @brief Command line parser.
201+ *
202+ * A Clp_Parser object defines an instance of CLP, including allowed options,
203+ * value types, and current arguments.
204+ * @sa Clp_NewParser, Clp_SetOptions, Clp_SetArguments */
205+struct Clp_Parser {
206+ int negated; /**< Whether the last option was negated. */
207+
208+ int have_val; /**< Whether the last option had a value. */
209+ const char *vstr; /**< The string value provided with the last
210+ option. */
211+
212+ union {
213+ int i;
214+ unsigned u;
215+ double d;
216+ const char *s;
217+ void *pv;
218+#ifdef HAVE_INT64_TYPES
219+ int64_t i64;
220+ uint64_t u64;
221+#endif
222+ char cs[Clp_ValSize];
223+ unsigned char ucs[Clp_ValSize];
224+ int is[Clp_ValIntSize];
225+ unsigned us[Clp_ValIntSize];
226+ } val; /**< The parsed value provided with the last
227+ option. */
228+
229+ void *user_data; /**< Uninterpreted by CLP; users can set
230+ arbitrarily. */
231+
232+ struct Clp_Internal *internal;
233+};
234+
235+/** @cond never */
236+#if __GNUC__ >= 4
237+# define CLP_SENTINEL __attribute__((sentinel))
238+#else
239+# define CLP_SENTINEL /* nothing */
240+#endif
241+/** @endcond never */
242+
243+
244+/** @brief Create a new Clp_Parser. */
245+Clp_Parser *Clp_NewParser(int argc, const char * const *argv,
246+ int nopt, const Clp_Option *opt);
247+
248+/** @brief Destroy a Clp_Parser object. */
249+void Clp_DeleteParser(Clp_Parser *clp);
250+
251+
252+/** @brief Return @a clp's program name. */
253+const char *Clp_ProgramName(Clp_Parser *clp);
254+
255+/** @brief Set @a clp's program name. */
256+const char *Clp_SetProgramName(Clp_Parser *clp, const char *name);
257+
258+
259+/** @brief Set @a clp's error handler function. */
260+Clp_ErrorHandler Clp_SetErrorHandler(Clp_Parser *clp, Clp_ErrorHandler errh);
261+
262+/** @brief Set @a clp's UTF-8 mode. */
263+int Clp_SetUTF8(Clp_Parser *clp, int utf8);
264+
265+/** @brief Return @a clp's treatment of character @a c. */
266+int Clp_OptionChar(Clp_Parser *clp, int c);
267+
268+/** @brief Set @a clp's treatment of character @a c. */
269+int Clp_SetOptionChar(Clp_Parser *clp, int c, int type);
270+
271+/** @brief Set @a clp's option definitions. */
272+int Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt);
273+
274+/** @brief Set @a clp's arguments. */
275+void Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv);
276+
277+/** @brief Set whether @a clp is searching for options. */
278+int Clp_SetOptionProcessing(Clp_Parser *clp, int on);
279+
280+
281+#define Clp_DisallowOptions (1<<0) /**< @brief Value type flag: value
282+ can't be an option string.
283+
284+ See Clp_AddType(). */
285+
286+/** @brief Define a new value type for @a clp. */
287+int Clp_AddType(Clp_Parser *clp, int val_type, int flags,
288+ Clp_ValParseFunc parser, void *user_data);
289+
290+
291+#define Clp_AllowNumbers (1<<0) /**< @brief String list flag: allow
292+ explicit numbers.
293+
294+ See Clp_AddStringListType() and Clp_AddStringListTypeVec(). */
295+
296+/** @brief Define a new string list value type for @a clp. */
297+int Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags,
298+ int nstrs, const char * const *strs,
299+ const int *vals);
300+
301+/** @brief Define a new string list value type for @a clp. */
302+int Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...)
303+ CLP_SENTINEL;
304+
305+
306+/** @brief Parse and return the next argument from @a clp. */
307+int Clp_Next(Clp_Parser *clp);
308+
309+/** @brief Return the next argument from @a clp without option parsing. */
310+const char *Clp_Shift(Clp_Parser *clp, int allow_options);
311+
312+
313+/** @brief Create a new Clp_ParserState. */
314+Clp_ParserState *Clp_NewParserState(void);
315+
316+/** @brief Destroy a Clp_ParserState object. */
317+void Clp_DeleteParserState(Clp_ParserState *state);
318+
319+/** @brief Save @a clp's current state in @a state. */
320+void Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state);
321+
322+/** @brief Restore parser state from @a state into @a clp. */
323+void Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state);
324+
325+
326+/** @brief Report a parser error. */
327+int Clp_OptionError(Clp_Parser *clp, const char *format, ...);
328+
329+/** @brief Extract the current option as a string. */
330+int Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len);
331+
332+/** @brief Extract the current option as a string. */
333+const char *Clp_CurOptionName(Clp_Parser *clp);
334+
335+#undef CLP_SENTINEL
336+#ifdef __cplusplus
337+}
338+#endif
339+#endif
--- trunk/t1asm/t1asm.c (nonexistent)
+++ trunk/t1asm/t1asm.c (revision 247)
@@ -0,0 +1,820 @@
1+/* t1asm -*- c-basic-offset: 2 -*-
2+ *
3+ * This program `assembles' Adobe Type-1 font programs in pseudo-PostScript
4+ * form into either PFB or PFA format. The human readable/editable input is
5+ * charstring- and eexec-encrypted as specified in the `Adobe Type 1 Font
6+ * Format' version 1.1 (the `black book'). There is a companion program,
7+ * t1disasm, which `disassembles' PFB and PFA files into a pseudo-PostScript
8+ * file.
9+ *
10+ * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
11+ *
12+ * Permission is hereby granted to use, modify, and distribute this program
13+ * for any purpose provided this copyright notice and the one below remain
14+ * intact.
15+ *
16+ * I. Lee Hetherington (ilh@lcs.mit.edu)
17+ *
18+ * 1.5 and later versions contain changes by, and are maintained by,
19+ * Eddie Kohler <ekohler@gmail.com>.
20+ *
21+ * New change log in `NEWS'. Old change log:
22+ *
23+ * Revision 1.4 92/07/10 10:53:09 ilh
24+ * Added support for additional PostScript after the closefile command
25+ * (ie., some fonts have {restore}if after the cleartomark).
26+ *
27+ * Revision 1.3 92/06/23 10:58:25 ilh
28+ * MSDOS porting by Kai-Uwe Herbing (herbing@netmbx.netmbx.de)
29+ * incoporated.
30+ *
31+ * Revision 1.2 92/05/22 11:54:45 ilh
32+ * Fixed bug where integers larger than 32000 could not be encoded in
33+ * charstrings. Now integer range is correct for four-byte
34+ * twos-complement integers: -(1<<31) <= i <= (1<<31)-1. Bug detected by
35+ * Piet Tutelaers (rcpt@urc.tue.nl).
36+ *
37+ * Revision 1.1 92/05/22 11:48:46 ilh
38+ * initial version
39+ *
40+ * Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
41+ * Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
42+ * specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
43+ * ... #endif, where _MSDOS is an identifier, which is automatically
44+ * defined, if you compile with the Microsoft C/C++ Compiler.
45+ *
46+ */
47+
48+/* Note: this is ANSI C. */
49+
50+#ifdef HAVE_CONFIG_H
51+# include <config.h>
52+#endif
53+#if defined(_MSDOS) || defined(_WIN32)
54+# include <fcntl.h>
55+# include <io.h>
56+#endif
57+#include <stdio.h>
58+#include <stdlib.h>
59+#include <string.h>
60+#include <ctype.h>
61+#include <limits.h>
62+#include <stdarg.h>
63+#include <errno.h>
64+#include "../_stdint.h"
65+#include "clp.h"
66+#include "t1lib.h"
67+
68+#define LINESIZE 512
69+
70+#ifdef __cplusplus
71+extern "C" {
72+#endif
73+
74+typedef unsigned char byte;
75+
76+static FILE *ifp;
77+static FILE *ofp;
78+static struct pfb_writer w;
79+static int blocklen = -1;
80+
81+/* flags */
82+static int pfb = 1;
83+static int active = 0;
84+static int ever_active = 0;
85+static int start_charstring = 0;
86+static int in_eexec = 0;
87+
88+/* need to add 1 as space for \0 */
89+static char line[LINESIZE + 1];
90+
91+/* lenIV and charstring start command */
92+static int lenIV = 4;
93+static char cs_start[10];
94+
95+/* for charstring buffering */
96+static byte *charstring_buf, *charstring_bp;
97+static int charstring_bufsiz;
98+
99+/* decryption stuff */
100+static uint16_t er, cr;
101+static uint16_t c1 = 52845, c2 = 22719;
102+
103+/* table of charstring commands */
104+static struct command {
105+ const char *name;
106+ int one, two;
107+} command_table[] = {
108+ { "abs", 12, 9 }, /* Type 2 */
109+ { "add", 12, 10 }, /* Type 2 */
110+ { "and", 12, 3 }, /* Type 2 */
111+ { "blend", 16, -1 }, /* Type 2 */
112+ { "callgsubr", 29, -1 }, /* Type 2 */
113+ { "callother", 12, 16 }, /* Type 1 ONLY */
114+ { "callothersubr", 12, 16 }, /* Type 1 ONLY */
115+ { "callsubr", 10, -1 },
116+ { "closepath", 9, -1 }, /* Type 1 ONLY */
117+ { "cntrmask", 20, -1 }, /* Type 2 */
118+ { "div", 12, 12 },
119+ { "dotsection", 12, 0 }, /* Type 1 ONLY */
120+ { "drop", 12, 18 }, /* Type 2 */
121+ { "dup", 12, 27 }, /* Type 2 */
122+ { "endchar", 14, -1 },
123+ { "eq", 12, 15 }, /* Type 2 */
124+ { "error", 0, -1 }, /* special */
125+ { "escape", 12, -1 }, /* special */
126+ { "exch", 12, 28 }, /* Type 2 */
127+ { "flex", 12, 35 }, /* Type 2 */
128+ { "flex1", 12, 37 }, /* Type 2 */
129+ { "get", 12, 21 }, /* Type 2 */
130+ { "hflex", 12, 34 }, /* Type 2 */
131+ { "hflex1", 12, 36 }, /* Type 2 */
132+ { "hhcurveto", 27, -1 }, /* Type 2 */
133+ { "hintmask", 19, -1 }, /* Type 2 */
134+ { "hlineto", 6, -1 },
135+ { "hmoveto", 22, -1 },
136+ { "hsbw", 13, -1 }, /* Type 1 ONLY */
137+ { "hstem", 1, -1 },
138+ { "hstem3", 12, 2 }, /* Type 1 ONLY */
139+ { "hstemhm", 18, -1 }, /* Type 2 */
140+ { "hvcurveto", 31, -1 },
141+ { "ifelse", 12, 22 }, /* Type 2 */
142+ { "index", 12, 29 }, /* Type 2 */
143+ { "load", 12, 13 }, /* Type 2 */
144+ { "mul", 12, 24 }, /* Type 2 */
145+ { "neg", 12, 14 }, /* Type 2 */
146+ { "not", 12, 5 }, /* Type 2 */
147+ { "or", 12, 4 }, /* Type 2 */
148+ { "pop", 12, 17 }, /* Type 1 ONLY */
149+ { "put", 12, 20 }, /* Type 2 */
150+ { "random", 12, 23 }, /* Type 2 */
151+ { "rcurveline", 24, -1 }, /* Type 2 */
152+ { "return", 11, -1 },
153+ { "rlinecurve", 25, -1 }, /* Type 2 */
154+ { "rlineto", 5, -1 },
155+ { "rmoveto", 21, -1 },
156+ { "roll", 12, 30 }, /* Type 2 */
157+ { "rrcurveto", 8, -1 },
158+ { "sbw", 12, 7 }, /* Type 1 ONLY */
159+ { "seac", 12, 6 }, /* Type 1 ONLY */
160+ { "setcurrentpoint", 12, 33 }, /* Type 1 ONLY */
161+ { "sqrt", 12, 26 }, /* Type 2 */
162+ { "store", 12, 8 }, /* Type 2 */
163+ { "sub", 12, 11 }, /* Type 2 */
164+ { "vhcurveto", 30, -1 },
165+ { "vlineto", 7, -1 },
166+ { "vmoveto", 4, -1 },
167+ { "vstem", 3, -1 },
168+ { "vstem3", 12, 1 }, /* Type 1 ONLY */
169+ { "vstemhm", 23, -1 }, /* Type 2 */
170+ { "vvcurveto", 26, -1 }, /* Type 2 */
171+}; /* alphabetical */
172+
173+/* Two separate encryption functions because eexec and charstring encryption
174+ must proceed in parallel. */
175+
176+static byte eencrypt(byte plain)
177+{
178+ byte cipher;
179+
180+ cipher = (byte)(plain ^ (er >> 8));
181+ er = (uint16_t)((cipher + er) * c1 + c2);
182+ return cipher;
183+}
184+
185+static byte cencrypt(byte plain)
186+{
187+ byte cipher;
188+
189+ /* Thanks to Tom Kacvinsky <tjk@ams.org> who reported that lenIV == -1 means
190+ unencrypted charstrings. */
191+ if (lenIV < 0) return plain;
192+
193+ cipher = (byte)(plain ^ (cr >> 8));
194+ cr = (uint16_t)((cipher + cr) * c1 + c2);
195+ return cipher;
196+}
197+
198+/* This function outputs a single byte. If output is in PFB format then output
199+ is buffered through blockbuf[]. If output is in PFA format, then output
200+ will be hexadecimal if in_eexec is set, ASCII otherwise. */
201+
202+static void output_byte(byte b)
203+{
204+ static const char *hexchar = "0123456789abcdef";
205+ static int hexcol = 0;
206+
207+ if (pfb) {
208+ /* PFB */
209+ PFB_OUTPUT_BYTE(&w, b);
210+ } else {
211+ /* PFA */
212+ if (in_eexec) {
213+ /* trim hexadecimal lines to `blocklen' columns */
214+ if (hexcol >= blocklen) {
215+ putc('\n', ofp);
216+ hexcol = 0;
217+ }
218+ putc(hexchar[(b >> 4) & 0xf], ofp);
219+ putc(hexchar[b & 0xf], ofp);
220+ hexcol += 2;
221+ } else {
222+ putc(b, ofp);
223+ }
224+ }
225+}
226+
227+/* This function outputs a byte through possible eexec encryption. */
228+
229+static void eexec_byte(byte b)
230+{
231+ if (in_eexec)
232+ output_byte(eencrypt(b));
233+ else
234+ output_byte(b);
235+}
236+
237+/* This function outputs a null-terminated string through possible eexec
238+ encryption. */
239+
240+static void eexec_string(const char *string)
241+{
242+ while (*string)
243+ eexec_byte(*string++);
244+}
245+
246+/* This function gets ready for the eexec-encrypted data. If output is in
247+ PFB format then flush current ASCII block and get ready for binary block.
248+ We start encryption with four random (zero) bytes. */
249+
250+static void eexec_start(char *string)
251+{
252+ eexec_string("currentfile eexec\n");
253+ if (pfb && w.blocktyp != PFB_BINARY) {
254+ pfb_writer_output_block(&w);
255+ w.blocktyp = PFB_BINARY;
256+ }
257+
258+ in_eexec = 1;
259+ er = 55665;
260+ eexec_byte(0);
261+ eexec_byte(0);
262+ eexec_byte(0);
263+ eexec_byte(0);
264+ eexec_string(string);
265+}
266+
267+/* 25.Aug.1999 -- Return 1 if this line actually looks like the start of a
268+ charstring. We use the heuristic that it should start with `/' (a name) or
269+ `dup' (a subroutine). Previous heuristic caused killa bad output. */
270+
271+static int check_line_charstring(void)
272+{
273+ char *p = line;
274+ while (isspace(*p))
275+ p++;
276+ return (*p == '/' || (p[0] == 'd' && p[1] == 'u' && p[2] == 'p'));
277+}
278+
279+/* This function returns an input line of characters. A line is terminated by
280+ length (including terminating null) greater than LINESIZE, \r, \n, \r\n, or
281+ when active (looking for charstrings) by '{'. When terminated by a newline
282+ the newline is put into line[]. When terminated by '{', the '{' is not put
283+ into line[], and the flag start_charstring is set to 1. */
284+
285+static void t1utils_getline(void)
286+{
287+ int c;
288+ char *p = line;
289+ int comment = 0;
290+ start_charstring = 0;
291+
292+ while (p < line + LINESIZE) {
293+ c = getc(ifp);
294+
295+ if (c == EOF)
296+ break;
297+ else if (c == '%')
298+ comment = 1;
299+ else if (active && !comment && c == '{') {
300+ /* 25.Aug.1999 -- new check for whether we should stop be active */
301+ if (check_line_charstring()) {
302+ start_charstring = 1;
303+ break;
304+ } else
305+ active = 0;
306+ }
307+
308+ *p++ = (char) c;
309+
310+ /* end of line processing: change CR or CRLF into LF, and exit */
311+ if (c == '\r') {
312+ c = getc(ifp);
313+ if (c != '\n')
314+ ungetc(c, ifp);
315+ p[-1] = '\n';
316+ break;
317+ } else if (c == '\n')
318+ break;
319+ }
320+
321+ *p = '\0';
322+}
323+
324+/* This function wraps-up the eexec-encrypted data and writes ASCII trailer.
325+ If output is in PFB format then this entails flushing binary block and
326+ starting an ASCII block. */
327+
328+static void eexec_end(void)
329+{
330+ int i, j;
331+
332+ if (!pfb)
333+ putc('\n', ofp);
334+ else if (w.blocktyp != PFB_ASCII) {
335+ pfb_writer_output_block(&w);
336+ w.blocktyp = PFB_ASCII;
337+ }
338+
339+ in_eexec = active = 0;
340+
341+ for (i = 0; i < 8; i++) {
342+ for (j = 0; j < 64; j++)
343+ eexec_byte('0');
344+ eexec_byte('\n');
345+ }
346+}
347+
348+/* This function is used by the binary search, bsearch(), for command names in
349+ the command table. */
350+
351+static int CDECL command_compare(const void *key, const void *item)
352+{
353+ return strcmp((const char *) key, ((const struct command *) item)->name);
354+}
355+
356+/* This function returns 1 if the string is an integer and 0 otherwise. */
357+
358+static int is_integer(char *string)
359+{
360+ if (isdigit(string[0]) || string[0] == '-' || string[0] == '+') {
361+ while (*++string && isdigit(*string))
362+ ; /* deliberately empty */
363+ if (!*string)
364+ return 1;
365+ }
366+ return 0;
367+}
368+
369+/* This function initializes charstring encryption. Note that this is called
370+ at the beginning of every charstring. */
371+
372+static void charstring_start(void)
373+{
374+ int i;
375+
376+ if (!charstring_buf) {
377+ charstring_bufsiz = 65536;
378+ if (!(charstring_buf = (byte *) malloc(charstring_bufsiz)))
379+ fatal_error("out of memory");
380+ }
381+
382+ charstring_bp = charstring_buf;
383+ cr = 4330;
384+ for (i = 0; i < lenIV; i++)
385+ *charstring_bp++ = cencrypt((byte) 0);
386+}
387+
388+/* This function encrypts and buffers a single byte of charstring data. */
389+
390+static void charstring_byte(int v)
391+{
392+ byte b = (byte)(v & 0xff);
393+ if (charstring_bp - charstring_buf == charstring_bufsiz) {
394+ charstring_bufsiz *= 2;
395+ if (!(charstring_buf = (byte *) realloc(charstring_buf, charstring_bufsiz)))
396+ fatal_error("out of memory");
397+ charstring_bp = charstring_buf + charstring_bufsiz / 2;
398+ }
399+ *charstring_bp++ = cencrypt(b);
400+}
401+
402+/* This function outputs buffered, encrypted charstring data through possible
403+ eexec encryption. */
404+
405+static void charstring_end(void)
406+{
407+ byte *bp;
408+
409+ sprintf(line, "%d ", (int) (charstring_bp - charstring_buf));
410+ eexec_string(line);
411+ sprintf(line, "%s ", cs_start);
412+ eexec_string(line);
413+ for (bp = charstring_buf; bp < charstring_bp; bp++)
414+ eexec_byte(*bp);
415+}
416+
417+/* This function generates the charstring representation of an integer. */
418+
419+static void charstring_int(int num)
420+{
421+ int x;
422+
423+ if (num >= -107 && num <= 107) {
424+ charstring_byte(num + 139);
425+ } else if (num >= 108 && num <= 1131) {
426+ x = num - 108;
427+ charstring_byte(x / 256 + 247);
428+ charstring_byte(x % 256);
429+ } else if (num >= -1131 && num <= -108) {
430+ x = abs(num) - 108;
431+ charstring_byte(x / 256 + 251);
432+ charstring_byte(x % 256);
433+ } else if (num >= (-2147483647-1) && num <= 2147483647) {
434+ charstring_byte(255);
435+ charstring_byte(num >> 24);
436+ charstring_byte(num >> 16);
437+ charstring_byte(num >> 8);
438+ charstring_byte(num);
439+ } else {
440+ error("can't format huge number `%d'", num);
441+ /* output 0 instead */
442+ charstring_byte(139);
443+ }
444+}
445+
446+/* This function returns one charstring token. It ignores comments. */
447+
448+static void get_charstring_token(void)
449+{
450+ int c = getc(ifp);
451+ while (isspace(c))
452+ c = getc(ifp);
453+
454+ if (c == '%') {
455+ while (c != EOF && c != '\r' && c != '\n')
456+ c = getc(ifp);
457+ get_charstring_token();
458+
459+ } else if (c == '}') {
460+ line[0] = '}';
461+ line[1] = 0;
462+
463+ } else {
464+ char *p = line;
465+ while (p < line + LINESIZE) {
466+ *p++ = c;
467+ c = getc(ifp);
468+ if (c == EOF || isspace(c) || c == '%' || c == '}') {
469+ ungetc(c, ifp);
470+ break;
471+ }
472+ }
473+ *p = 0;
474+ }
475+}
476+
477+
478+/* This function parses an entire charstring into integers and commands,
479+ outputting bytes through the charstring buffer. */
480+
481+static void parse_charstring(void)
482+{
483+ struct command *cp;
484+
485+ charstring_start();
486+ while (!feof(ifp)) {
487+ get_charstring_token();
488+ if (line[0] == '}')
489+ break;
490+ if (is_integer(line)) {
491+ charstring_int(atoi(line));
492+ } else {
493+ int one;
494+ int two;
495+ int ok = 0;
496+
497+ cp = (struct command *)
498+ bsearch((void *) line, (void *) command_table,
499+ sizeof(command_table) / sizeof(struct command),
500+ sizeof(struct command),
501+ command_compare);
502+
503+ if (cp) {
504+ one = cp->one;
505+ two = cp->two;
506+ ok = 1;
507+
508+ } else if (strncmp(line, "escape_", 7) == 0) {
509+ /* Parse the `escape' keyword requested by Lee Chun-Yu and Werner
510+ Lemberg */
511+ one = 12;
512+ if (sscanf(line + 7, "%d", &two) == 1)
513+ ok = 1;
514+
515+ } else if (strncmp(line, "UNKNOWN_", 8) == 0) {
516+ /* Allow unanticipated UNKNOWN commands. */
517+ one = 12;
518+ if (sscanf(line + 8, "12_%d", &two) == 1)
519+ ok = 1;
520+ else if (sscanf(line + 8, "%d", &one) == 1) {
521+ two = -1;
522+ ok = 1;
523+ }
524+ }
525+
526+ if (!ok)
527+ error("unknown charstring command `%s'", line);
528+ else if (one < 0 || one > 255)
529+ error("bad charstring command number `%d'", one);
530+ else if (two > 255)
531+ error("bad charstring command number `%d'", two);
532+ else if (two < 0)
533+ charstring_byte(one);
534+ else {
535+ charstring_byte(one);
536+ charstring_byte(two);
537+ }
538+ }
539+ }
540+ charstring_end();
541+}
542+
543+
544+/*****
545+ * Command line
546+ **/
547+
548+#define BLOCK_LEN_OPT 300
549+#define OUTPUT_OPT 301
550+#define VERSION_OPT 302
551+#define HELP_OPT 303
552+#define PFB_OPT 304
553+#define PFA_OPT 305
554+
555+static Clp_Option options[] = {
556+ { "block-length", 'l', BLOCK_LEN_OPT, Clp_ValInt, 0 },
557+ { "help", 0, HELP_OPT, 0, 0 },
558+ { "line-length", 0, BLOCK_LEN_OPT, Clp_ValInt, 0 },
559+ { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 },
560+ { "pfa", 'a', PFA_OPT, 0, 0 },
561+ { "pfb", 'b', PFB_OPT, 0, 0 },
562+ { "version", 0, VERSION_OPT, 0, 0 },
563+};
564+static const char *program_name;
565+
566+void
567+fatal_error(const char *message, ...)
568+{
569+ va_list val;
570+ va_start(val, message);
571+ fprintf(stderr, "%s: ", program_name);
572+ vfprintf(stderr, message, val);
573+ putc('\n', stderr);
574+ exit(1);
575+}
576+
577+void
578+error(const char *message, ...)
579+{
580+ va_list val;
581+ va_start(val, message);
582+ fprintf(stderr, "%s: ", program_name);
583+ vfprintf(stderr, message, val);
584+ putc('\n', stderr);
585+}
586+
587+static void
588+short_usage(void)
589+{
590+ fprintf(stderr, "Usage: %s [OPTION]... [INPUT [OUTPUT]]\n\
591+Try `%s --help' for more information.\n",
592+ program_name, program_name);
593+}
594+
595+static void
596+usage(void)
597+{
598+ printf("\
599+`T1asm' translates a human-readable version of a PostScript Type 1 font into\n\
600+standard PFB or PFA format. The result is written to the standard output\n\
601+unless an OUTPUT file is given.\n\
602+\n\
603+Usage: %s [OPTION]... [INPUT [OUTPUT]]\n\
604+\n\
605+Options:\n\
606+ -a, --pfa Output font in ASCII (PFA) format.\n\
607+ -b, --pfb Output font in binary (PFB) format. This is\n\
608+ the default.\n\
609+ -l, --block-length NUM Set max block length for PFB output.\n\
610+ -l, --line-length NUM Set max encrypted line length for PFA output.\n\
611+ -o, --output=FILE Write output to FILE.\n\
612+ -h, --help Print this message and exit.\n\
613+ --version Print version number and warranty and exit.\n\
614+\n\
615+Report bugs to <ekohler@gmail.com>.\n", program_name);
616+}
617+
618+#ifdef __cplusplus
619+}
620+#endif
621+
622+
623+int main(int argc, char *argv[])
624+{
625+ char *p, *q, *r;
626+
627+ Clp_Parser *clp =
628+ Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options);
629+ program_name = Clp_ProgramName(clp);
630+
631+ /* interpret command line arguments using CLP */
632+ while (1) {
633+ int opt = Clp_Next(clp);
634+ switch (opt) {
635+
636+ case BLOCK_LEN_OPT:
637+ blocklen = clp->val.i;
638+ break;
639+
640+ output_file:
641+ case OUTPUT_OPT:
642+ if (ofp)
643+ fatal_error("output file already specified");
644+ if (strcmp(clp->vstr, "-") == 0)
645+ ofp = stdout;
646+ else if (!(ofp = fopen(clp->vstr, "w")))
647+ fatal_error("%s: %s", clp->vstr, strerror(errno));
648+ break;
649+
650+ case PFB_OPT:
651+ pfb = 1;
652+ break;
653+
654+ case PFA_OPT:
655+ pfb = 0;
656+ break;
657+
658+ case HELP_OPT:
659+ usage();
660+ exit(0);
661+ break;
662+
663+ case VERSION_OPT:
664+ printf("t1asm (LCDF t1utils) %s\n", VERSION);
665+ printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\
666+This is free software; see the source for copying conditions.\n\
667+There is NO warranty, not even for merchantability or fitness for a\n\
668+particular purpose.\n");
669+ exit(0);
670+ break;
671+
672+ case Clp_NotOption:
673+ if (ifp && ofp)
674+ fatal_error("too many arguments");
675+ else if (ifp)
676+ goto output_file;
677+ if (strcmp(clp->vstr, "-") == 0)
678+ ifp = stdin;
679+ else if (!(ifp = fopen(clp->vstr, "r")))
680+ fatal_error("%s: %s", clp->vstr, strerror(errno));
681+ break;
682+
683+ case Clp_Done:
684+ goto done;
685+
686+ case Clp_BadOption:
687+ short_usage();
688+ exit(1);
689+ break;
690+
691+ }
692+ }
693+
694+ done:
695+ if (!pfb) {
696+ if (blocklen == -1)
697+ blocklen = 64;
698+ else if (blocklen < 8) {
699+ blocklen = 8;
700+ error("warning: line length raised to %d", blocklen);
701+ } else if (blocklen > 1024) {
702+ blocklen = 1024;
703+ error("warning: line length lowered to %d", blocklen);
704+ }
705+ }
706+
707+ if (!ifp) ifp = stdin;
708+ if (!ofp) ofp = stdout;
709+
710+ if (pfb)
711+ init_pfb_writer(&w, blocklen, ofp);
712+
713+#if defined(_MSDOS) || defined(_WIN32)
714+ /* If we are processing a PFB (binary) output */
715+ /* file, we must set its file mode to binary. */
716+ if (pfb)
717+ _setmode(_fileno(ofp), _O_BINARY);
718+#endif
719+
720+ /* Finally, we loop until no more input. Some special things to look for are
721+ the `currentfile eexec' line, the beginning of the `/Subrs' or
722+ `/CharStrings' definition, the definition of `/lenIV', and the definition
723+ of the charstring start command which has `...string currentfile...' in
724+ it.
725+
726+ Being careful: Check with `/Subrs' and `/CharStrings' to see that a
727+ number follows the token -- otherwise, the token is probably nested in a
728+ subroutine a la Adobe Jenson, and we shouldn't pay attention to it.
729+
730+ Bugs: Occurrence of `/Subrs 9' in a comment will fool t1asm.
731+
732+ Thanks to Tom Kacvinsky <tjk@ams.org> who reported that some fonts come
733+ without /Subrs sections and provided a patch. */
734+
735+ while (!feof(ifp) && !ferror(ifp)) {
736+ t1utils_getline();
737+
738+ if (!ever_active) {
739+ if (strncmp(line, "currentfile eexec", 17) == 0 && isspace(line[17])) {
740+ /* Allow arbitrary whitespace after "currentfile eexec".
741+ Thanks to Tom Kacvinsky <tjk@ams.org> for reporting this.
742+ Note: strlen("currentfile eexec") == 17. */
743+ for (p = line + 18; isspace(*p); p++)
744+ ;
745+ eexec_start(p);
746+ continue;
747+ } else if (strncmp(line, "/lenIV", 6) == 0) {
748+ lenIV = atoi(line + 6);
749+ } else if ((p = strstr(line, "string currentfile"))
750+ && strstr(line, "readstring")) { /* enforce `readstring' */
751+ /* locate the name of the charstring start command */
752+ *p = '\0'; /* damage line[] */
753+ q = strrchr(line, '/');
754+ if (q) {
755+ r = cs_start;
756+ ++q;
757+ while (!isspace(*q) && *q != '{')
758+ *r++ = *q++;
759+ *r = '\0';
760+ }
761+ *p = 's'; /* repair line[] */
762+ }
763+ }
764+
765+ if (!active) {
766+ if ((p = strstr(line, "/Subrs")) && isdigit(p[7]))
767+ ever_active = active = 1;
768+ else if ((p = strstr(line, "/CharStrings")) && isdigit(p[13]))
769+ ever_active = active = 1;
770+ }
771+ if ((p = strstr(line, "currentfile closefile"))) {
772+ /* 2/14/99 -- happy Valentine's day! -- don't look for `mark
773+ currentfile closefile'; the `mark' might be on a different line */
774+ /* 1/3/2002 -- happy new year! -- Luc Devroye reports a failure with
775+ some printers when `currentfile closefile' is followed by space */
776+ p += sizeof("currentfile closefile") - 1;
777+ for (q = p; isspace(*q) && *q != '\n'; q++)
778+ /* nada */;
779+ if (q == p && !*q)
780+ error("warning: `currentfile closefile' line too long");
781+ else if (q != p) {
782+ if (*q != '\n')
783+ error("text after `currentfile closefile' ignored");
784+ *p++ = '\n';
785+ *p++ = '\0';
786+ }
787+ eexec_string(line);
788+ break;
789+ }
790+
791+ eexec_string(line);
792+
793+ /* output line data */
794+ if (start_charstring) {
795+ if (!cs_start[0])
796+ fatal_error("couldn't find charstring start command");
797+ parse_charstring();
798+ }
799+ }
800+
801+ /* Handle remaining PostScript after the eexec section */
802+ if (in_eexec)
803+ eexec_end();
804+
805+ /* There may be additional code. */
806+ while (!feof(ifp) && !ferror(ifp)) {
807+ t1utils_getline();
808+ eexec_string(line);
809+ }
810+
811+ if (pfb)
812+ pfb_writer_end(&w);
813+
814+ /* the end! */
815+ if (!ever_active)
816+ error("warning: no charstrings found in input file");
817+ fclose(ifp);
818+ fclose(ofp);
819+ return 0;
820+}
--- trunk/t1asm/t1lib.c (nonexistent)
+++ trunk/t1asm/t1lib.c (revision 247)
@@ -0,0 +1,441 @@
1+/* t1lib
2+ *
3+ * This file contains functions for reading PFA and PFB files.
4+ *
5+ * (C) 1999-2008 Eddie Kohler <ekohler@gmail.com>, after code by
6+ * I. Lee Hetherington <ilh@lcs.mit.edu>. All rights reserved.
7+ *
8+ * Permission is hereby granted to use, modify, and distribute this program
9+ * for any purpose provided this copyright notice remains intact.
10+ *
11+ */
12+
13+#ifdef HAVE_CONFIG_H
14+# include <config.h>
15+#endif
16+#include <stdio.h>
17+#include <stdlib.h>
18+#include <ctype.h>
19+#include <string.h>
20+#include "t1lib.h"
21+#ifdef __cplusplus
22+extern "C" {
23+#endif
24+
25+#define PFA_ASCII 1
26+#define PFA_EEXEC_TEST 2
27+#define PFA_HEX 3
28+#define PFA_BINARY 4
29+
30+/* This function returns the value (0-15) of a single hex digit. It returns
31+ 0 for an invalid hex digit. */
32+
33+static int
34+hexval(char c)
35+{
36+ if (c >= 'A' && c <= 'F')
37+ return c - 'A' + 10;
38+ else if (c >= 'a' && c <= 'f')
39+ return c - 'a' + 10;
40+ else if (c >= '0' && c <= '9')
41+ return c - '0';
42+ else
43+ return 0;
44+}
45+
46+/* This function translates a string of hexadecimal digits into binary data.
47+ We allow an odd number of digits. Returns length of binary data. */
48+
49+static int
50+translate_hex_string(char *s, char *saved_orphan)
51+{
52+ int c1 = *saved_orphan;
53+ char *start = s;
54+ char *t = s;
55+ for (; *s; s++) {
56+ if (isspace(*s))
57+ continue;
58+ if (c1) {
59+ *t++ = (hexval(c1) << 4) + hexval(*s);
60+ c1 = 0;
61+ } else
62+ c1 = *s;
63+ }
64+ *saved_orphan = c1;
65+ return t - start;
66+}
67+
68+/* This function returns 1 if the string contains all '0's. */
69+
70+static int
71+all_zeroes(char *s)
72+{
73+ if (*s == '\0' || *s == '\n')
74+ return 0;
75+ while (*s == '0')
76+ s++;
77+ return *s == '\0' || *s == '\n';
78+}
79+
80+/* This function handles the entire file. */
81+
82+#define LINESIZE 1024
83+
84+void
85+process_pfa(FILE *ifp, const char *ifp_filename, struct font_reader *fr)
86+{
87+ /* Loop until no more input. We need to look for `currentfile eexec' to
88+ start eexec section (hex to binary conversion) and line of all zeros to
89+ switch back to ASCII. */
90+
91+ /* Don't use fgets() in case line-endings are indicated by bare \r's, as
92+ occurs in Macintosh fonts. */
93+
94+ /* 2.Aug.1999 - At the behest of Tom Kacvinsky <tjk@ams.org>, support
95+ binary PFA fonts. */
96+
97+ char buffer[LINESIZE];
98+ int c = 0;
99+ int blocktyp = PFA_ASCII;
100+ char saved_orphan = 0;
101+ (void)ifp_filename;
102+
103+ while (c != EOF) {
104+ char *line = buffer, *last = buffer;
105+ int crlf = 0;
106+ c = getc(ifp);
107+ while (c != EOF && c != '\r' && c != '\n' && last < buffer + LINESIZE - 1) {
108+ *last++ = c;
109+ c = getc(ifp);
110+ }
111+
112+ /* handle the end of the line */
113+ if (last == buffer + LINESIZE - 1)
114+ /* buffer overrun: don't append newline even if we have it */
115+ ungetc(c, ifp);
116+ else if (c == '\r' && blocktyp != PFA_BINARY) {
117+ /* change CR or CR/LF into LF, unless reading binary data! (This
118+ condition was wrong before, caused Thanh problems -
119+ 6.Mar.2001) */
120+ c = getc(ifp);
121+ if (c != '\n')
122+ ungetc(c, ifp), crlf = 1;
123+ else
124+ crlf = 2;
125+ *last++ = '\n';
126+ } else if (c != EOF)
127+ *last++ = c;
128+
129+ *last = 0;
130+
131+ /* now that we have the line, handle it */
132+ if (blocktyp == PFA_ASCII) {
133+ if (strncmp(line, "currentfile eexec", 17) == 0 && isspace(line[17])) {
134+ char saved_p;
135+ /* assert(line == buffer); */
136+ for (line += 18; isspace(*line); line++)
137+ /* nada */;
138+ saved_p = *line;
139+ *line = 0;
140+ fr->output_ascii(buffer, line - buffer);
141+ *line = saved_p;
142+ blocktyp = PFA_EEXEC_TEST;
143+ if (!*line)
144+ continue;
145+ } else {
146+ fr->output_ascii(line, last - line);
147+ continue;
148+ }
149+ }
150+
151+ /* check immediately after "currentfile eexec" for ASCII or binary */
152+ if (blocktyp == PFA_EEXEC_TEST) {
153+ /* 8.Feb.2004: fix bug if first character in a binary eexec block
154+ is 0, reported by Werner Lemberg */
155+ for (; line < last && isspace(*line); line++)
156+ /* nada */;
157+ if (line == last)
158+ continue;
159+ else if (last >= line + 4 && isxdigit(line[0]) && isxdigit(line[1])
160+ && isxdigit(line[2]) && isxdigit(line[3]))
161+ blocktyp = PFA_HEX;
162+ else
163+ blocktyp = PFA_BINARY;
164+ memmove(buffer, line, last - line + 1);
165+ last = buffer + (last - line);
166+ line = buffer;
167+ /* patch up crlf fix */
168+ if (blocktyp == PFA_BINARY && crlf) {
169+ last[-1] = '\r';
170+ if (crlf == 2)
171+ *last++ = '\n';
172+ }
173+ }
174+
175+ /* blocktyp == PFA_HEX || blocktyp == PFA_BINARY */
176+ if (all_zeroes(line)) { /* XXX not safe */
177+ fr->output_ascii(line, last - line);
178+ blocktyp = PFA_ASCII;
179+ } else if (blocktyp == PFA_HEX) {
180+ int len = translate_hex_string(line, &saved_orphan);
181+ if (len)
182+ fr->output_binary((unsigned char *)line, len);
183+ } else
184+ fr->output_binary((unsigned char *)line, last - line);
185+ }
186+
187+ fr->output_end();
188+}
189+
190+/* Process a PFB file. */
191+
192+/* XXX Doesn't handle "currentfile eexec" as intelligently as process_pfa
193+ does. */
194+
195+static int
196+handle_pfb_ascii(struct font_reader *fr, char *line, int len)
197+{
198+ /* Divide PFB_ASCII blocks into lines */
199+ int start = 0;
200+
201+ while (1) {
202+ int pos = start;
203+
204+ while (pos < len && line[pos] != '\n' && line[pos] != '\r')
205+ pos++;
206+
207+ if (pos >= len) {
208+ if (pos == start)
209+ return 0;
210+ else if (start == 0 && pos == LINESIZE - 1) {
211+ line[pos] = 0;
212+ fr->output_ascii(line, pos);
213+ return 0;
214+ } else {
215+ memmove(line, line + start, pos - start);
216+ return pos - start;
217+ }
218+
219+ } else if (pos < len - 1 && line[pos] == '\r' && line[pos+1] == '\n') {
220+ line[pos] = '\n';
221+ line[pos+1] = 0;
222+ fr->output_ascii(line + start, pos + 1 - start);
223+ start = pos + 2;
224+
225+ } else {
226+ char save = line[pos+1];
227+ line[pos] = '\n';
228+ line[pos+1] = 0;
229+ fr->output_ascii(line + start, pos + 1 - start);
230+ line[pos+1] = save;
231+ start = pos + 1;
232+ }
233+ }
234+}
235+
236+
237+void
238+process_pfb(FILE *ifp, const char *ifp_filename, struct font_reader *fr)
239+{
240+ int blocktyp = 0;
241+ int block_len = 0;
242+ int c = 0;
243+ int filepos = 0;
244+ int linepos = 0;
245+ char line[LINESIZE];
246+
247+ while (1) {
248+ while (block_len == 0) {
249+ c = getc(ifp);
250+ blocktyp = getc(ifp);
251+ if (c != PFB_MARKER
252+ || (blocktyp != PFB_ASCII && blocktyp != PFB_BINARY
253+ && blocktyp != PFB_DONE)) {
254+ if (c == EOF || blocktyp == EOF)
255+ error("%s corrupted: no end-of-file marker", ifp_filename);
256+ else
257+ error("%s corrupted: bad block marker at position %d",
258+ ifp_filename, filepos);
259+ blocktyp = PFB_DONE;
260+ }
261+ if (blocktyp == PFB_DONE)
262+ goto done;
263+
264+ block_len = getc(ifp) & 0xFF;
265+ block_len |= (getc(ifp) & 0xFF) << 8;
266+ block_len |= (getc(ifp) & 0xFF) << 16;
267+ block_len |= (getc(ifp) & 0xFF) << 24;
268+ if (feof(ifp)) {
269+ error("%s corrupted: bad block length at position %d",
270+ ifp_filename, filepos);
271+ blocktyp = PFB_DONE;
272+ goto done;
273+ }
274+ filepos += 6;
275+ }
276+
277+ /* read the block in its entirety, in LINESIZE chunks */
278+ while (block_len > 0) {
279+ int rest = LINESIZE - 1 - linepos; /* leave space for '\0' */
280+ int n = (block_len > rest ? rest : block_len);
281+ int actual = fread(line + linepos, 1, n, ifp);
282+ if (actual != n) {
283+ error("%s corrupted: block short by %d bytes at position %d",
284+ ifp_filename, block_len - actual, filepos);
285+ block_len = actual;
286+ }
287+
288+ if (blocktyp == PFB_BINARY)
289+ fr->output_binary((unsigned char *)line, actual);
290+ else
291+ linepos = handle_pfb_ascii(fr, line, linepos + actual);
292+
293+ block_len -= actual;
294+ filepos += actual;
295+ }
296+
297+ /* handle any leftover line */
298+ if (linepos > 0) {
299+ line[linepos] = 0;
300+ fr->output_ascii(line, linepos);
301+ linepos = 0;
302+ }
303+ }
304+
305+ done:
306+ c = getc(ifp);
307+ if (c != EOF)
308+ error("%s corrupted: data after PFB end marker at position %d",
309+ ifp_filename, filepos - 2);
310+ fr->output_end();
311+}
312+
313+
314+#define DEFAULT_BLOCKLEN (1L<<12)
315+
316+void
317+init_pfb_writer(struct pfb_writer *w, int blocklen, FILE *f)
318+{
319+ w->len = DEFAULT_BLOCKLEN;
320+ w->buf = (unsigned char *)malloc(w->len);
321+ if (!w->buf)
322+ fatal_error("out of memory");
323+ w->max_len = (blocklen <= 0 ? 0xFFFFFFFFU : (unsigned)blocklen);
324+ w->pos = 0;
325+ w->blocktyp = PFB_ASCII;
326+ w->binary_blocks_written = 0;
327+ w->f = f;
328+}
329+
330+void
331+pfb_writer_output_block(struct pfb_writer *w)
332+{
333+ /* do nothing if nothing in block */
334+ if (w->pos == 0)
335+ return;
336+
337+ /* output four-byte block length */
338+ putc(PFB_MARKER, w->f);
339+ putc(w->blocktyp, w->f);
340+ putc((int)(w->pos & 0xff), w->f);
341+ putc((int)((w->pos >> 8) & 0xff), w->f);
342+ putc((int)((w->pos >> 16) & 0xff), w->f);
343+ putc((int)((w->pos >> 24) & 0xff), w->f);
344+
345+ /* output block data */
346+ fwrite(w->buf, 1, w->pos, w->f);
347+
348+ /* mark block buffer empty and uninitialized */
349+ w->pos = 0;
350+ if (w->blocktyp == PFB_BINARY)
351+ w->binary_blocks_written++;
352+}
353+
354+void
355+pfb_writer_grow_buf(struct pfb_writer *w)
356+{
357+ if (w->len < w->max_len) {
358+ /* grow w->buf */
359+ unsigned new_len = w->len * 2;
360+ unsigned char *new_buf;
361+ if (new_len > w->max_len)
362+ new_len = w->max_len;
363+ new_buf = (unsigned char *)malloc(new_len);
364+ if (!new_buf) {
365+ error("out of memory; continuing with a smaller block size");
366+ w->max_len = w->len;
367+ pfb_writer_output_block(w);
368+ } else {
369+ memcpy(new_buf, w->buf, w->len);
370+ free(w->buf);
371+ w->buf = new_buf;
372+ w->len = new_len;
373+ }
374+
375+ } else
376+ /* buf already the right size, just output the block */
377+ pfb_writer_output_block(w);
378+}
379+
380+void
381+pfb_writer_end(struct pfb_writer *w)
382+{
383+ if (w->pos)
384+ pfb_writer_output_block(w);
385+ putc(PFB_MARKER, w->f);
386+ putc(PFB_DONE, w->f);
387+}
388+
389+/* This CRC table and routine were borrowed from macutils-2.0b3 */
390+
391+static unsigned short crctab[256] = {
392+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
393+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
394+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
395+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
396+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
397+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
398+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
399+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
400+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
401+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
402+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
403+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
404+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
405+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
406+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
407+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
408+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
409+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
410+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
411+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
412+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
413+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
414+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
415+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
416+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
417+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
418+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
419+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
420+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
421+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
422+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
423+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
424+};
425+
426+/*
427+ * Update a CRC check on the given buffer.
428+ */
429+
430+int
431+crcbuf(int crc, unsigned int len, const char *buf)
432+{
433+ const unsigned char *ubuf = (const unsigned char *)buf;
434+ while (len--)
435+ crc = ((crc << 8) & 0xFF00) ^ crctab[((crc >> 8) & 0xFF) ^ *ubuf++];
436+ return crc;
437+}
438+
439+#ifdef __cplusplus
440+}
441+#endif
--- trunk/t1asm/README (nonexistent)
+++ trunk/t1asm/README (revision 247)
@@ -0,0 +1,17 @@
1+This directory contains a copy of the t1asm utility, originally by
2+I. Lee Hetherington, with further development by Eddie Kohler. This is
3+part of version 1.37 the t1utils package, which is available from:
4+ http://www.lcdf.org/~eddietwo/type/#t1utils
5+
6+For general use, I recommend getting and installing that package. This
7+bundled copy of t1asm is intended just for building Tsukurimashou, so that
8+there'll be one less dependency for Tsukurimashou builders to worry about.
9+Accordingly, it's integrated into the Tsukurimashou build system, and the
10+Tsukurimashou build will not install it when Tsukurimashou is installed.
11+
12+Files in this directory have their own copyrights separate from
13+Tsukurimashou's; see the individual files for more information on
14+licensing, and contact information for the authors.
15+
16+Matthew Skala
17+mskala@ansuz.sooke.bc.ca
--- trunk/configure.ac (revision 246)
+++ trunk/configure.ac (revision 247)
@@ -198,7 +198,7 @@
198198 AC_CONFIG_SRCDIR([hamlog/hamlog])
199199 AC_CONFIG_HEADERS([config.h])
200200 AC_CONFIG_MACRO_DIR([m4])
201-AC_REVISION([$Id: configure.ac 1293 2012-03-29 02:06:26Z mskala $])
201+AC_REVISION([$Id: configure.ac 1294 2012-03-29 04:08:55Z mskala $])
202202 AC_COPYRIGHT([Copyright (C) 2011, 2012 Matthew Skala])
203203 AC_SUBST([release_date],["February 25, 2012"])
204204 AM_SILENT_RULES
@@ -209,6 +209,7 @@
209209 #
210210 AC_PROG_CC
211211 AC_PROG_CC_C_O
212+AC_PROG_CPP
212213 AC_PROG_GREP
213214 AC_PROG_INSTALL
214215 AC_PROG_LN_S
@@ -230,7 +231,6 @@
230231 AC_ARG_VAR([PERL],[Perl])
231232 AC_PATH_PROG([PERL],[perl])
232233 AC_PATH_PROGS([PROLOG],[pl swipl eclipse gprolog],[])
233-AC_PATH_PROG([T1ASM],[t1asm])
234234 AC_ARG_VAR([XDVIPDFMX],[xdvipdfmx])
235235 AC_PATH_PROG([XDVIPDFMX],[xdvipdfmx])
236236 AC_ARG_VAR([XELATEX],[XeLaTeX])
@@ -246,21 +246,25 @@
246246 #
247247 # Checks for header files.
248248 #
249-AC_CHECK_HEADERS([limits.h stdlib.h string.h])
249+AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h])
250+AX_CREATE_STDINT_H
250251 #
251252 ############################################################################
252253 #
253254 # Checks for typedefs, structures, and compiler characteristics.
254255 #
256+AC_TYPE_INT64_T
255257 AC_FUNC_OBSTACK
258+AC_TYPE_UINT16_T
259+AC_TYPE_UINT64_T
256260 #
257261 ############################################################################
258262 #
259263 # Checks for library functions.
260264 #
265+AC_CHECK_FUNCS([memmove])
261266 AC_CHECK_FUNCS([pow])
262-AC_CHECK_FUNCS([strdup])
263-AC_CHECK_FUNCS([strstr])
267+AC_CHECK_FUNCS([strchr strdup strerror strrchr strstr strtol strtoul])
264268 #
265269 ############################################################################
266270 #
@@ -472,9 +476,6 @@
472476 AS_IF([test "x$PERL" = "x"],
473477 [missing_perl=yes
474478 can_core=no])
475-AS_IF([test "x$T1ASM" = "x"],
476- [missing_t1asm=yes
477- can_core=no])
478479 AS_IF([test "$tsu_prolog_style" = "unknown"],
479480 [missing_prolog=yes
480481 can_core=no])
@@ -681,8 +682,6 @@
681682 [AS_ECHO([" Perl http://www.perl.org/"])])
682683 AS_IF([test "$missing_prolog" = "yes"],
683684 [AS_ECHO([" logic programming (should be built-in, did you override?)"])])
684- AS_IF([test "$missing_t1asm" = "yes"],
685- [AS_ECHO([" T1 Utils http://www.lcdf.org/~eddietwo/type/#t1utils"])])
686685 AS_IF([test '!' "$ac_cv_sys_long_file_names" = "yes"],
687686 [AS_ECHO([" long filename support"])])
688687 AS_ECHO(["Without the above it is not possible to build Tsukurimashou at all."])
--- trunk/Makefile.am (revision 246)
+++ trunk/Makefile.am (revision 247)
@@ -214,7 +214,12 @@
214214 $(filter-out $(wildcard $(mvp)/mp/jieub-[a-d][0-9a-f].mp),\
215215 $(wildcard $(mvp)/mp/*.mp))
216216
217-noinst_PROGRAMS = kerner/kerner
217+noinst_PROGRAMS = kerner/kerner t1asm/t1asm
218+
219+kerner_kerner_SOURCES = kerner/kerner.c
220+t1asm_t1asm_SOURCES = \
221+ t1asm/t1asm.c t1asm/clp.c t1asm/clp.h t1asm/t1lib.c t1asm/t1lib.h
222+
218223 dist_noinst_SCRIPTS = \
219224 hamlog/hamlog \
220225 hamlog/select.hl hamlog/swi-ham.pl hamlog/ecl-ham.ecl hamlog/gp-ham.pl \
@@ -244,7 +249,7 @@
244249 # MAKE CLEAN
245250
246251 MOSTLYCLEANFILES = \
247- *~ doc/*~ fea/*~ kerner/*~ m4/*~ mp/*~ pe/*~ \
252+ *~ doc/*~ fea/*~ kerner/*~ m4/*~ mp/*~ pe/*~ t1asm/*~ \
248253 bdf/*.bdf \
249254 doc/*.aux doc/*.log doc/*.out doc/*-draft.tex doc/*.toc doc/*.xdv \
250255 doc/kanjichart.tex \
@@ -576,7 +581,7 @@
576581 ALLPRFS=$(foreach st,$(PROOF_STYLES),$(call PAGEFILES,prf/,$(st),.prf))
577582
578583 pfbtmp/%.pfb prf/%.prf: pfbtmp/.dirstamp prf/.dirstamp sum/.dirstamp \
579- tools/livecode tools/mp2pf
584+ tools/livecode tools/mp2pf t1asm/t1asm
580585 $(AM_V_at)CODESTAMP=`$(PERL) -CSD $(mvp)/tools/livecode \
581586 $(foreach fn,$(call PFBDEPS,pfbtmp/$*.pfb),$(mvp)/mp/$(fn)) \
582587 | $(CHECKSUM)` ; \
@@ -595,7 +600,7 @@
595600 (cd $*.tmp ; $(expect_start)$(MPOST) $*.mp$(expect_end) ) ; \
596601 $(TSU_V_NAPERL) \
597602 $(PERL) -CSD $(mvp)/tools/mp2pf $*.tmp/$* 2> /dev/null ; \
598- (cd $*.tmp ; $(T1ASM) -b $*.p $*.pfb ) ; \
603+ (cd $*.tmp ; ../t1asm/t1asm -b $*.p $*.pfb ) ; \
599604 if test -r $*.tmp/$*.pfb ; then \
600605 mv -f $*.tmp/$*.pfb pfbtmp/ ; \
601606 echo "$$CODESTAMP" > sum/$*.sum ; \
@@ -612,7 +617,6 @@
612617 fi ; \
613618 fi
614619
615-
616620 pfb/%.pfb: pfbtmp/%.pfb pfb/.dirstamp sum/.dirstamp pe/rmo.pe tools/livecode
617621 $(AM_V_at)CODESTAMP=`$(PERL) -CSD $(mvp)/tools/livecode \
618622 $(foreach fn,$(call PFBDEPS,pfbtmp/$*.pfb),$(mvp)/mp/$(fn)) \
Show on old repository browser