summaryrefslogtreecommitdiff
path: root/support/word2x
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/word2x
Initial commit
Diffstat (limited to 'support/word2x')
-rw-r--r--support/word2x/INTERNALS171
-rw-r--r--support/word2x/Makefile.in116
-rw-r--r--support/word2x/Makefile.linux68
-rw-r--r--support/word2x/README189
-rw-r--r--support/word2x/alloca.c466
-rw-r--r--support/word2x/col-align.cc109
-rw-r--r--support/word2x/compat.c79
-rwxr-xr-xsupport/word2x/config.guess973
-rw-r--r--support/word2x/config.h.bot7
-rw-r--r--support/word2x/config.h.in80
-rw-r--r--support/word2x/config.h.top2
-rwxr-xr-xsupport/word2x/config.sub956
-rwxr-xr-xsupport/word2x/configure2214
-rw-r--r--support/word2x/configure.in77
-rw-r--r--support/word2x/deHTMLdate.cc40
-rw-r--r--support/word2x/deL1date.cc38
-rw-r--r--support/word2x/dedate.cc39
-rwxr-xr-xsupport/word2x/fake_link6
-rw-r--r--support/word2x/fifo.h265
-rw-r--r--support/word2x/fmt-html.h48
-rw-r--r--support/word2x/fmt-latex.h45
-rw-r--r--support/word2x/getopt.c752
-rw-r--r--support/word2x/getopt.h132
-rw-r--r--support/word2x/getopt1.c184
-rw-r--r--support/word2x/html-embed.cc381
-rw-r--r--support/word2x/html-fmt.cc487
-rw-r--r--support/word2x/html-table.cc297
-rw-r--r--support/word2x/html-table.h27
-rwxr-xr-xsupport/word2x/install-sh238
-rw-r--r--support/word2x/interface.h60
-rw-r--r--support/word2x/latex-embed.cc555
-rw-r--r--support/word2x/latex-fmt.cc537
-rw-r--r--support/word2x/latex-table.cc302
-rw-r--r--support/word2x/latex-table.h27
-rw-r--r--support/word2x/lib.h116
-rw-r--r--support/word2x/liboutfmt.abin0 -> 154364 bytes
-rw-r--r--support/word2x/map_chars.cc57
-rw-r--r--support/word2x/nullproc.cc12
-rw-r--r--support/word2x/num_unit_probe.c67
-rw-r--r--support/word2x/part_num_probe.c45
-rw-r--r--support/word2x/reader.cc1246
-rw-r--r--support/word2x/reader.h278
-rwxr-xr-xsupport/word2x/rtest2bin0 -> 131357 bytes
-rw-r--r--support/word2x/rtest2.cc113
-rw-r--r--support/word2x/scan_num.cc76
-rw-r--r--support/word2x/shrink_width.cc35
-rw-r--r--support/word2x/strip.cc527
-rw-r--r--support/word2x/strip.cc.orig522
-rw-r--r--support/word2x/strip.h135
-rw-r--r--support/word2x/tblock.cc242
-rw-r--r--support/word2x/tblock.h46
-rw-r--r--support/word2x/tblock.h.orig48
-rw-r--r--support/word2x/text-fmt.cc287
-rw-r--r--support/word2x/text-table.cc337
-rw-r--r--support/word2x/text-table.h25
-rw-r--r--support/word2x/transcript83
-rw-r--r--support/word2x/tune.h30
-rw-r--r--support/word2x/ukdate.cc61
-rw-r--r--support/word2x/usdate.cc65
-rw-r--r--support/word2x/use_getopt.h8
-rwxr-xr-xsupport/word2x/word2xbin0 -> 323122 bytes
-rw-r--r--support/word2x/word2x.1103
-rw-r--r--support/word2x/word2x.cc395
-rw-r--r--support/word2x/word6.h37
-rw-r--r--support/word2x/wordwrap.cc74
65 files changed, 15037 insertions, 0 deletions
diff --git a/support/word2x/INTERNALS b/support/word2x/INTERNALS
new file mode 100644
index 0000000000..ef89a8e95f
--- /dev/null
+++ b/support/word2x/INTERNALS
@@ -0,0 +1,171 @@
+$Id: INTERNALS,v 1.3 1997/04/10 19:53:54 dps Exp $
+
+Here is how the program works.
+
+
+reader.cc (1.10)
+
+read_character reads characters from a word document suitably
+translated, including dsitingishing between multiple and single ^Gs,
+etc.
+
+The output is fetched by chunk_reader::read_chunk_raw that assembles
+it into bits ignoring inclusions. chunk_Reader::read_chunk gets these
+chunks are parcels them out with inclusion seperated out.
+
+tok_seq::rd_token adds start and end tags for rows, fields, paragraphs
+and all the rest storing the tokens in a table on a seperate queue
+before transfering them all onto the main queue. tok_seq::rd_token also
+keeps track of the size and detects the probable end of the table.
+
+tok_seq::feed_token takes a token off the queue and requests a refill at the
+appropiate time. At the end of the document it tests a flag and if the flag
+is not set then adds a document end entry (and then feeds it to the caller).
+
+OK, so far? Now the fun begins!
+
+If you look at the outptut now you see horrofic stuff like
+<PARAGRAPH>550 *<SPEC>eq \F(foom bar)</SPEC><PARGRAPH>= 42</PARAGRAPH>
+so the input is further processed by tok_seq::math_collect().
+math_collect() uses saved_tok as a one byte push back mechamism and
+will use this token before asking feed_token() for one. Non-paragraphs and non-equations go straight thorugh.
+
+When math_collect sees a paragaph is pears at the next item. If this
+is not an equation it just forwards the token and stashes the item it
+got in saved_token (saved_token is definately free: either it was used
+or feed_token supplied something). If it sees an euqation it calls
+math_reverse_scan to work out whether there is any equation in the
+string (guesswork but works quite nicely). If math_reverse_scan
+decides it is all real text the token is just forwarded (with the
+extra token still stashed in saved_tok).
+
+Assuming math_reverse_scan found something to move that material is
+moved into the equation and ntok and the current token
+modified. saved_token still pointds to ntok so we use the same
+structure but new strings. The reduced paragraoh token is returned.
+
+-----
+
+When the code sees an equation special (quite possibly saved_tok from
+the paragraph process above) it ask feed_token() for the next two
+tokens. The next token is the end token for the special and the one
+after that interesting, and will be called T (the token itself is
+*ntok in the code).
+
+If T is an equation the end spec token is junked and the two equations
+joined. One of the equations is then junked. The end special is
+pushed onto the start of the outpiut for feed_token to find there;
+saved_tok is pointed to the expanded equations. The code then returns
+to the original read a token state so further aggregation can take
+place.
+
+If T is a paragraph then the code uses math_forward_scan to see how
+much of that is consumed as part of the equation. If none then the end
+special and paragraph tokens are pushed onto the front of the output
+queue and saved_tok invalided. The code is then returns the current
+(equation special) token. The end special passes straight through and
+then the accumulaion can begin again.
+
+If T (a paragraph) is partial consumed the current equation and it is
+adjusted and the same processing as if the paragraph had no formula contents.
+
+If T (a paragraph) entirely consumed its contents are added onto to
+the text, the paragraph junked, the end spec pushed pack. saved_tok is
+pointed to the current, expanded equations. The code then returns
+to the original read a token state so further aggregation can take
+place.
+
+The output now contians nice stuff like
+
+<PARAGRAPH><SPEC> 550 * \F(foo,bar) = 29</SPEC></PARAGRAPH> and even
+horrors that word veiwer renders as displayed equations like
+<PARAGRAPH><SPEC> 550 * \F(foo,bar) = 29</SPEC><PARAGRAPH>.</PARAGRAPH>
+
+
+
+
+This output is requested by tok_seq::eqn_rd_token() which is an
+internal method. It is not devoid of tricks however. Anything other
+than the start of a paragragh passes straight through.
+
+
+When it sees a paragraph it pushes it onto a seperate queue and
+acculumates totals of characters and specials in it sees. The loop
+exits when any of the following applies:
+
+ The paragaraph character total exceeds then (small, currently 3)
+ treshold.
+
+ The end of the paragraph is spotted.
+
+ A non-special, non-pargraph, non-other character is seen (if this
+ happens we add the treshold to the count to be sure of being >= to it.
+
+
+On exit from the loop if the total is less than the critical value the
+queue is reveresed and inserted at the front of the output queue minus
+the paragraph items. Since the tokens are inserted as the first
+character of the ouput they appear in reverse order of insertion (hence
+the reverse makes the elements appear it the original order on the output
+queue). This deletes that extraneous and wrong full stop, for example.
+
+Otherwise the queue is the elements are transfered to the front of the
+output queue in the existing order (this actually just sets a couple
+of pointers).
+
+Either way the temporary queue is now empty and is deleted. The first
+item dequeued is returned. (This is what rtest2 shows you).
+
+
+-----
+
+The output of eqn_rd_token is fed to the listhandling guesswork. A
+list is started by A pargraph starting with a number 1 (enumerate) or
+a bullet character (itemize). If a paragraph does not fit then it is
+checked for a list start---if so it is assumed to be a sublist. The
+end of the list is signalled by MAX_ITEM_SEP_PARS which can not be
+part of a list (default value is 5). Only the last paragraph with the
+appropiate lead in text is included. Since this involves delaying
+tokens and looking ahead the easiest place to do this is in the
+reader.
+
+Only the bottom level list is actually ended by enough non-list
+paragraphs; the list is closed and the output is fed back in, giving
+them the chance to kill the list the next level up.
+
+
+The lists queues are completely seperate from anything eqn_rd_token
+uses: each list builds the tokens in items. Note that the first item
+includes the list start to make it easy to recover the original text
+if required. When a level of list is popped these tokens are pointed
+to by recycled, which is initially NULL.
+
+If the list only has one item the list is transformed back into its
+(listless) tokens, as recieved from eqn_rd_token. The first token is
+appended to the list bellow the one popped or the output queue if there
+is not such list.
+
+The main loop of read_token grabs values from recycled if it is not
+null, setting it to NULL if it becomes empty. If recycled is NULL then
+the code asks eqn_rd_token for a token. As with eqn_rd_token the loop
+waits for its own output queue (outqueue) to have something in it and
+returns the first item in this queue.
+
+
+The overall effect of the layered intelligence described above is that
+the code in reader.cc is too complicated for comfort. The overall
+performance is nice though...
+
+
+----------------------------------------------------------------------
+
+OH, yes and the *TeX output format also uses context cues. There is a
+minimal amount of context cue usage in the ascii format. Overall this
+program tends towards my idea of a complex AI program using context
+cues to do the right stuff with what word throws at it!!
+
+I hope this is now 100% clear.
+
+
+
+
diff --git a/support/word2x/Makefile.in b/support/word2x/Makefile.in
new file mode 100644
index 0000000000..935da6688e
--- /dev/null
+++ b/support/word2x/Makefile.in
@@ -0,0 +1,116 @@
+# $Id: Makefile.in,v 1.18 1997/04/13 09:11:40 dps Exp dps $
+#
+# My test system is Linux 2.1.30, gcc 2.7.2, libc 5.4.27
+
+CC=@CC@
+CPP=@CXX@
+
+#seek_set_hdr is a hack for Sun OS (and others? I hope not)
+CPPFLAGS=-g -Wall @DEFS@ @seek_set_hdr@
+LD=@ld@
+
+CCFLAGS=-O3 @DEFS@
+LIBOBJS=wordwrap.o nullproc.o tblock.o scan_num.o map_chars.o col-align.o \
+ compat.o num_unit_probe.o part_num_probe.o
+AR=ar
+RANLIB=@RANLIB@
+MYLIBS=liboutfmt.a
+READER=reader.o strip.o
+FMTS=fmt-text.o fmt-latex.o fmt-html.o
+DATEFMTS=dedate.o deL1date.o deHTMLdate.o ukdate.o usdate.o
+#Set to gopt.o if you lack getopt_long
+GETOPT=@getopt@
+ALLOCA=@ALLOCA@
+PROGOBJS=$(READER) word2x.o $(FMTS) $(DATEFMTS) $(GETOPT) $(ALLOCA) $(MYLIBS)
+TARGETS=word2x rtest2
+MANP=word2x.1
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+%.o: %.cc
+ $(CPP) $(CPPFLAGS) -c -o $@ $<
+
+%.o: $.c $(CC) $(CCFLAGS) -c -o $@ $<
+
+all: config.h $(TARGETS)
+
+config.h: configure.in Makefile.in config.h.in
+ ./configure
+
+configure: configure.in
+ autoconf
+
+Makefile: Makefile.in configure
+ ./configure
+
+clean:
+ rm -f *.o
+ rm -f $(MYLIBS)
+
+clobber: clean
+ rm -f $(TARGETS)
+ rm -f config.h Makefile
+ rm -f config.cache config.status config.log *~
+ rm -f cfg-script make-script
+
+word2x.tar.gz: clobber configure config.h.in configure.in Makefile.in transcript
+ chmod a-w configure
+ tar -C .. -czf word2x.tar.gz word2x \
+ --exclude word2x/RCS --exclude word2x/word2x.tar.gz \
+ --exclude word2x/samples --exclude word2x/config.cache \
+ --exclude word2x/config.status --exclude word2x/config.log \
+ --exclude word2x/catdoc.c --exclude word2x/catdoc.msg \
+ --exclude word2x/config.h --exclude word2x/Makefile \
+ --exclude word2x/config.cache --exclude word2x/config.status \
+ --exclude word2x/config.log
+ chmod 755 configure
+
+transcript: cfg-script make-script
+ @echo "word2x build transcript" >transcript
+ @echo "Note: the prompts are simulated. All the rest is real." >>transcript
+ @echo "Simulation> ./configure" >>transcript
+ @cat cfg-script >>transcript
+ @echo "Simulation> make all" >>transcript
+ @cat make-script >>transcript
+ rm -f cfg-script make-script
+
+cfg-script:
+ @rm -f config.cache config.h
+ ./configure 2>&1 | tee cfg-script
+
+make-script: config.h
+ make all 2>&1 | tee make-script
+
+liboutfmt.a: $(LIBOBJS)
+ $(AR) rc $@ $(LIBOBJS)
+ $(RANLIB) $@
+
+rtest2: rtest2.o $(READER) tblock.o
+ g++ -o rtest2 rtest2.o $(READER) tblock.o
+
+fmt-text.o: text-fmt.o text-table.o
+ $(LD) -r -o $@ text-fmt.o text-table.o
+
+fmt-latex.o: latex-fmt.o latex-table.o latex-embed.o
+ $(LD) -r -o $@ latex-fmt.o latex-table.o latex-embed.o
+
+fmt-html.o: html-fmt.o html-table.o html-embed.o
+ $(LD) -r -o $@ html-fmt.o html-table.o html-embed.o
+
+getopt.o: getopt.c
+ $(CC) $(CFLAGS) -D_LIBC=1 -c -o $@ $<
+
+getopt1.o: getopt1.c
+ $(CC) $(CFLAGS) -D_LIBC=1 -c -o $@ $<
+
+gopt.o: getopt.o getopt1.o
+ $(LD) -r -o gopt.o getopt.o getopt1.o
+
+word2x: $(PROGOBJS)
+ $(CPP) -o $@ $(PROGOBJS)
+
+install: $(TARGETS) $(MANP)
+ @INSTALL@ $(MANP) -m 644 @mandir@/man1
+ for I in $(TARGETS); do \
+ @INSTALL@ $${I} -m 755 @bindir@; \
+ done
diff --git a/support/word2x/Makefile.linux b/support/word2x/Makefile.linux
new file mode 100644
index 0000000000..471743bcd2
--- /dev/null
+++ b/support/word2x/Makefile.linux
@@ -0,0 +1,68 @@
+# $Id: Makefile,v 1.12 1997/04/09 04:57:12 dps Exp $
+#
+#Makefile for word2x
+#Test system is Linux 2.1.30, gcc 2.7.2, libc 5.4.27
+
+#if you are compiling on SUNOS, use the following
+#CPPFLAGS=-g -Wall -DSUNOS=1
+#LD=./sunos_link
+
+#For normal systems try this instead
+CPPFLAGS=-g -Wall
+LD=ld
+
+CCFLAGS=-O3
+LIBOBJS=wordwrap.o nullproc.o tblock.o scan_num.o map_chars.o col-align.o \
+ ukdate.o usdate.o
+AR=ar
+RANLIB=ranlib
+MYLIBS=liboutfmt.a
+READER=reader.o
+FMTS=fmt-text.o fmt-latex.o
+CPP=g++
+#Set to gopt.o if you lack getopt_long
+GETOPT=
+PROGOBJS=$(READER) word2x.o $(FMTS) $(GETOPT) $(MYLIBS)
+TARGETS=word2x rtest2
+
+all: $(TARGETS)
+
+clean:
+ rm -f *.o
+ rm -f $(MYLIBS)
+
+clobber: clean
+ rm -f $(TARGETS)
+
+word2x.tar.gz:
+ tar -C .. -czf word2x.tar.gz word2x \
+ --exclude word2x/RCS --exclude word2x/word2x.tar.gz
+
+
+liboutfmt.a: $(LIBOBJS)
+ $(AR) rc $@ $(LIBOBJS)
+ $(RANLIB) $@
+
+rtest2: rtest2.o reader.o tblock.o
+ g++ -o rtest2 rtest2.o reader.o tblock.o
+
+fmt-text.o: text-fmt.o text-table.o
+ $(LD) -r -o $@ text-fmt.o text-table.o
+
+fmt-latex.o: latex-fmt.o latex-table.o latex-embed.o
+ $(LD) -r -o $@ latex-fmt.o latex-table.o latex-embed.o
+
+getopt.o: getopt.c
+ $(CC) $(CFLAGS) -D_LIBC=1 -c -o $@ $<
+
+getopt1.o: getopt1.c
+ $(CC) $(CFLAGS) -D_LIBC=1 -c -o $@ $<
+
+gopt.o: getopt.o getopt1.o
+ $(LD) -r -o gopt.o getopt.o getopt1.o
+
+word2x: $(PROGOBJS)
+ $(CPP) -o $@ $(PROGOBJS)
+
+%.o: %.cc
+ $(CPP) $(CPPFLAGS) -c -o $@ $<
diff --git a/support/word2x/README b/support/word2x/README
new file mode 100644
index 0000000000..5750d9c584
--- /dev/null
+++ b/support/word2x/README
@@ -0,0 +1,189 @@
+$Id: README,v 1.7 1997/04/13 02:59:59 dps Exp $
+
+What is new in version 0.005 of word2x
+
+Update version to 0.005
+Fix version number bug
+Update config.guess an config.sub
+Re-generate configure.in with newer autoconf
+Fix various ANSI violations that g++ 2.95 disliked
+
+
+What is new in version 0.004 of word2x
+
+Stupid bug in word2x_junk_filter::filter_junk bug which ignored the last
+character read squashed.
+
+Added german support from word2x port EX2.
+
+
+What it was new in version 0.003 of word2x
+
+word2x-0.003 is version word2x-0.002 with a major bug in strip.cc
+eliminated. word2x-0.002 was 0.001 retro-fitted with some quite new
+junk filtering code with lots of tunable parameters (i.e. all of
+tune.h). This code is extracted from the envolving, and currently
+incomplete, source tree of the next major release. (When this happens I
+will stop supporting or maintaing any 0.00x versions).
+
+The major change is much better junk filtering, losing less text and
+throwing out more junk; unicode documents should now
+work. Increasing numbers of problem document which have OLE junk in
+places that break the code are appearing. Splitting the document with
+lls (from the LAOLA package) and attacking the WordDocument stream
+works---sometime I will have a useable library that can do this
+automagically. (In word2x-0.002 you have a very good chance of
+tickling the strip.cc bug and its (buggy) bug trap).
+
+Documents that do cause problems after the suggested work-around to
+word2x@duncan.telstar.net please. The immediate fix is to try one of
+the other two programs. (Free software people are prepared to
+co-operate with the "competition"). There are links to all the
+"competition" I know of on the word2x home page at
+http://word2x.alcom.co.uk (hosted by the alcom.co.uk free of charge,
+despite the fact charges normally apply).
+
+
+Installing word2x
+
+You need a C++ compiler and a version of make that does understands
+how to make .o files from .cc files, for example GNU make. Ideally you
+have getopt_long already in your C library but you might not. If this
+applies set GETOPT to gopt.o in the Makefile. getopt_long is the
+version supplied by the free software foundation in glibc-1.09
+
+If your make does not know then add a rule. for GNU make the rule is
+
+%.o: %.cc
+ $(CPP) $(CPPFLAGS) -c -o $@ $<
+
+Please note that a warning about a contravariance violation is normal.
+
+As this is program only recently escaped, YMMV. The main reason for
+its escape was incessant irration that comp.os.linux.misc posters
+manage about word .doc files (IMHO this is justified). I had wrote
+this program for myself and my word problem; I let it run wild in the
+hope that is it useful for others. [I now know is it is helping some
+people]
+
+Further information on other converters is avialable in the list of
+converters avialble via <http://www.kfa-juelich.de/isr/1/texconv.html>
+(word2x seems to have a monopoly on converters from word to latex not
+requiring word and avialable on non-MS platforms).
+
+The program has been compiled on (the first two by me personally):
+
+Linux 2.1.30 (Unix)
+SunOS (Unix)
+DEC Alpha AXP under OSF/1 (Unix)
+IBM SP/2 (RS6000) under AIX (Unix) [SP/2s are heavy computing power...]
+
+It is known not compile with
+
+Borland C++ 3.1 (PC version).
+
+If any manages to compile on a PC version, please tell
+Duncan Simpson <dps@duncan.telstar.net> and
+W.Hennings <W.Hennings@kfa-juelich.de>
+
+Limited flat (linear) memory might be lethal, esp. if your system
+lacks alloca. If have not learned to steal what is free then you can
+send money (prefably UK funds), postcards, etc to the author at
+
+Frax House, Kingston Bagpuize, OXON OX13 5AW
+
+or for the next couple of years
+
+Flat 6, 93 Westridge Road, Southampton
+
+I neither suggest that you do donate nor that you do not donate.
+
+
+SunOS
+
+Can be problematic. Setting LD to ./sunos_link and defining add
+produced a binary that worked for me with one warning about
+strncasecmp. I guess SUN's ld is incompatible with g++ or something;
+using ar and ranlib, aka the sunos_link shell script, works. The
+configuration script hopefuk does this stuff for you.
+
+
+Reported bugs
+
+On some platforms it misses the first 3/4 of a page. If you are
+afflicted get out your copy of hexdump and adjust the start offset in
+word2x to the correct value. This should be fixed now.
+
+Copyright
+
+This program is(c) D.P.Simson 1997. The program is licenced under the
+GPL version 2, or any later version (at your option). This means DOS
+people must distribute source as per the GPL.
+
+The stuff I did not write is:
+
+config.guess and config.sub come from GNU autoconf and are thus
+(c) The Free Software Foundation.
+
+getopt.c, getopt1.c and getopt.h are (c) The Free Software Foundation.
+I am fairly sure the LGPL requires these files to be distributed as
+well.
+
+alloca.c is almost certaintly also (c) The Free Sofwtware Foundation.
+
+install-sh is probably (c) The X consortium
+
+
+Introductory proganda
+
+Despite the fact that open formats like rtf are good and widely
+avialable far too many idiots seem to insist on using word .doc
+format. This program is an attempt to limit the damage this causes
+users of non-microsoft systems and text processing systems, for
+example LaTeX.
+
+It is designed to be retargetable and avoid some of the travesties of
+proper typsetting comitted by word, which is hobbled by the lack of
+litagures in TrueType fonts (and the lack of different design sizes to
+some extent). There is quite a large amount of guesswork from context
+to reduce the impact of my lack of understanding a document the way
+word does. One even sees interesting things like
+<Paragraph mode> 550* <eqn> \F(foo, bar) <end eqn> * 42 * (pixels per em)
+<End paragraph>
+which is not too good! There may be multiple bits of alternating roman
+and equation, multiple items of text in brackets, etc.
+etc. Fortunately the reader converts these, in two stages, to a single
+maths insert. Maths inserts with embedded newlines get rendered as
+eqnarray* in LaTeX mode. All maths is just deleted in text mode (would
+someone like to add this support?).
+
+LaTeX mode sees the equation example above as <eqn insert> 550
+* \F(foo, bar * baz) * 42 * (pixels per em) <end eqn insert> and
+renders it as
+% Some comments omited for brevity
+$$550 \times {\text{foo} \over \text{bar} \times \text{baz} } \times 42
+\times \text{(pixels per em)}$$
+which looks a lot better than word's own version, which uses awful
+stars instead of proper times signs.
+
+Text mode implements tables with real columns, unlike catdoc. Long
+entries are folded automatically and there is some semi-intelligent
+width reduction. Hypenation is not supported so if someone instists
+on using supercalifragilistic... then an overlong line might result
+(anyone care to fix this? I thought it was just overkill to implement
+the hypenation algorithm along with all the rest).
+
+Apart from the pictures and a little trailing junk the code does a
+good job on the TrueType documents. The readme generates some error
+messages about extra ^Us amoung other things due to a lack of
+understanding of some of the inserts used in some documents. Anyone
+who can decode more types of insert, please tell me about it and
+preferably send a patch so I can avoid extra programming (got too much
+real work to be doing).
+
+If someone wishes to contribute *roff output I would include it. Extra
+understanding of equations also gratefully recieved as the examples in
+the TrueType docs are rather limited. Bibliography and any other you
+can tell me about also grateful listened to.
+
+Duncan (-:
diff --git a/support/word2x/alloca.c b/support/word2x/alloca.c
new file mode 100644
index 0000000000..91d64bb526
--- /dev/null
+++ b/support/word2x/alloca.c
@@ -0,0 +1,466 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* If compiling with GCC, this file's not needed. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+#ifdef emacs
+#define free xfree
+#endif
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#ifdef CRAY
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#define NULL 0
+
+extern pointer (*_mp_allocate_func) ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = (*_mp_allocate_func) (sizeof (header) + size);
+ /* Address of header. */
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#ifdef CRAY
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
diff --git a/support/word2x/col-align.cc b/support/word2x/col-align.cc
new file mode 100644
index 0000000000..b205c83faa
--- /dev/null
+++ b/support/word2x/col-align.cc
@@ -0,0 +1,109 @@
+/* $Id: col-align.cc,v 1.3 1997/03/22 20:20:17 dps Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+/* Calculate the widths and guess the alignment a column wants */
+struct wd_info find_width(int rows, const char *const *cdata)
+{
+ int max_wd[3], i, not_num, is_num;
+ int lt_sp, rt_sp, align_set;
+ wd_info res;
+ const char *cdp, *sc;
+ num_info nd;
+
+ max_wd[0]=0;
+ max_wd[1]=0;
+ max_wd[2]=0;
+ is_num=not_num=align_set=0;
+ res.align=ALIGN_LEFT;
+ res.has_sign=0;
+
+ for (i=0; i<rows; i++)
+ {
+ cdp=cdata[i];
+ if (cdp==NULL)
+ continue; // Handle blank entries
+
+ nd=scan_num(cdp);
+ if (nd.dot_pos==-1)
+ not_num++;
+ else
+ {
+ is_num++;
+ res.has_sign |= nd.has_sign;
+ if (nd.wd[0]>max_wd[0])
+ max_wd[0]=nd.wd[0];
+ if (nd.wd[1]>max_wd[1])
+ max_wd[1]=nd.wd[1];
+ }
+ if (strlen(cdp)>(unsigned) max_wd[2])
+ max_wd[2]=strlen(cdp);
+ for (lt_sp=0, sc=cdp; isspace(*sc); sc++, lt_sp++)
+ {
+ if (*sc==CH_SUSPECT)
+ align_set=1;
+ }
+ if (*sc=='\0')
+ continue; // Blank entry gives no information
+
+ while (*sc!='\0')
+ {
+ if (*sc==CH_SUSPECT)
+ align_set=1;
+ if (isspace(*sc))
+ rt_sp++;
+ else
+ rt_sp=0;
+ sc++;
+ }
+
+ if (align_set)
+ continue;
+
+ if (lt_sp==0 && rt_sp<=1)
+ continue;
+ if (lt_sp-rt_sp<-1)
+ {
+ res.align=ALIGN_LEFT;
+ continue;
+ }
+ if (lt_sp-rt_sp>1)
+ {
+ res.align=ALIGN_RIGHT;
+ continue;
+ }
+ res.align=ALIGN_CENTER;
+ }
+
+ if (is_num>not_num)
+ {
+ /*
+ * Decimal alignment, set dp_col and leave the alignment
+ * alone to handle non-number entries nicely.
+ */
+ res.width=max_wd[0]+(max_wd[1]>0) ? 0 : 1;
+ res.dp_col=max_wd[0]+1;
+ }
+ else
+ {
+ res.width=0;
+ res.dp_col=-1;
+ }
+
+ if (res.width<max_wd[2])
+ res.width=max_wd[2]; // dp_col irrelant
+
+ return res;
+}
diff --git a/support/word2x/compat.c b/support/word2x/compat.c
new file mode 100644
index 0000000000..fbd1a55db8
--- /dev/null
+++ b/support/word2x/compat.c
@@ -0,0 +1,79 @@
+/* $Id: compat.c,v 1.2 1997/04/13 05:51:35 dps Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HAVE_STRCASECMP
+int strcasecmp(const char *s, const char *t)
+{
+ register unsigned char a,b;
+
+ while (*s && *t)
+ {
+ a=tolower(*s);
+ b=tolower(*t);
+ if (a<b)
+ return -1;
+ if (a>b)
+ return 1;
+ s++;
+ t++;
+ }
+ if (*s!='\0')
+ return -1;
+ if (*t!='\0')
+ return 1;
+ return 0;
+}
+#endif
+
+#ifndef HAVE_STRNCASECMP
+int strncasecmp(const char *s, const char *t, int n)
+{
+ register unsigned char a,b;
+
+ while (*s && *t)
+ {
+ if (n--==0)
+ return 0;
+
+ a=tolower(*s);
+ b=tolower(*t);
+ if (a<b)
+ return -1;
+ if (a>b)
+ return 1;
+ s++;
+ t++;
+ }
+ if (*s!='\0')
+ return -1;
+ if (*t!='\0')
+ return 1;
+ return 0;
+}
+#endif
+
+#ifndef HAVE_STRDUP
+char *strdup(const char *s)
+{
+ char *t;
+ t=malloc(strlen(s)+1);
+ strcpy(t,s);
+
+ return t;
+}
+#endif /* HAVE_STRDUP */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/support/word2x/config.guess b/support/word2x/config.guess
new file mode 100755
index 0000000000..4e5345fac2
--- /dev/null
+++ b/support/word2x/config.guess
@@ -0,0 +1,973 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:NetBSD:*:*)
+ echo powerpc-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
+ sed 's/^ //' << EOF >$dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (${CC-cc} $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ rm -f $dummy.c $dummy
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ ${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo t3e-cray-unicosmk${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us.
+ ld_help_string=`ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >$dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >$dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i?86:UnixWare:*:*)
+ if /bin/uname -X 2>/dev/null >/dev/null ; then
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ fi
+ echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION}
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/support/word2x/config.h.bot b/support/word2x/config.h.bot
new file mode 100644
index 0000000000..ca8bc9dfa0
--- /dev/null
+++ b/support/word2x/config.h.bot
@@ -0,0 +1,7 @@
+
+/* Bad stuff fixed in the next release */
+#ifndef NUNITS
+#define NUNITS 4
+#endif /* NUNITS */
+
+#endif /* __CONFIG_H__ */
diff --git a/support/word2x/config.h.in b/support/word2x/config.h.in
new file mode 100644
index 0000000000..bc41cd22fa
--- /dev/null
+++ b/support/word2x/config.h.in
@@ -0,0 +1,80 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+#ifndef __CONFIG_H__
+#define __CONFIG_H__ 1
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm. */
+#undef TM_IN_SYS_TIME
+
+/* Define if you have the fstat function. */
+#undef HAVE_FSTAT
+
+/* Define if you have the localtime function. */
+#undef HAVE_LOCALTIME
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strncasecmp function. */
+#undef HAVE_STRNCASECMP
+
+/* Define if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the sun library (-lsun). */
+#undef HAVE_LIBSUN
+
+/* Bad stuff fixed in the next release */
+#ifndef NUNITS
+#define NUNITS 4
+#endif /* NUNITS */
+
+#endif /* __CONFIG_H__ */
diff --git a/support/word2x/config.h.top b/support/word2x/config.h.top
new file mode 100644
index 0000000000..10bd207677
--- /dev/null
+++ b/support/word2x/config.h.top
@@ -0,0 +1,2 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__ 1
diff --git a/support/word2x/config.sub b/support/word2x/config.sub
new file mode 100755
index 0000000000..da8b7ae65c
--- /dev/null
+++ b/support/word2x/config.sub
@@ -0,0 +1,956 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \
+ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+ | mipstx39 | mipstx39el \
+ | sparc | sparclet | sparclite | sparc64 | v850)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \
+ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | k6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | k6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -rhapsody* \
+ | -openstep*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/support/word2x/configure b/support/word2x/configure
new file mode 100755
index 0000000000..99cdc6d70d
--- /dev/null
+++ b/support/word2x/configure
@@ -0,0 +1,2214 @@
+#! /bin/sh
+
+# From configure.in Id: configure.in# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=word2x.cc
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:529: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:559: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:610: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:642: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 653 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:684: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:689: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:717: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:753: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CXX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+ echo "$ac_t""$CXX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:785: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 796 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cxx_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cxx_cross=no
+ else
+ ac_cv_prog_cxx_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+ { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:827: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:832: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.C <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:841: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:860: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ ac_cv_prog_cxx_g=yes
+else
+ ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:894: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:952: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking for getopt_long""... $ac_c" 1>&6
+echo "configure:1006: checking for getopt_long" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getopt_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1011 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getopt_long(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getopt_long();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getopt_long) || defined (__stub___getopt_long)
+choke me
+#else
+getopt_long();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getopt_long=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getopt_long=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getopt_long`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ getopt=""
+else
+ echo "$ac_t""no" 1>&6
+getopt=gopt.o
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1056: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1071 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1077: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1088 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1094: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1105 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1111: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1138: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1143 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1171: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1176 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:1236: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1241 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1266: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1271 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:1321: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1329 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:1348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1370: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1375 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1384: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:1405: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1410 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:1418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+
+echo $ac_n "checking header file for SEEK_SET""... $ac_c" 1>&6
+echo "configure:1441: checking header file for SEEK_SET" >&5
+if eval "test \"`echo '$''{'ac_cv_hdrfile_SEEK_SET'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_hdrfile_SEEK_SET=""
+for xhdr in stdio.h unistd.h; do
+if test -z "${ac_cv_hdrfile_SEEK_SET}"; then
+cat > conftest.$ac_ext <<EOF
+#line 1449 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include<${xhdr}>
+int main() {
+ if (SEEK_SET==SEEK_SET) printf("ok");
+; return 0; }
+EOF
+if { (eval echo configure:1457: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_hdrfile_SEEK_SET=${xhdr}
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+fi
+done
+if test -z "${ac_cv_hdrfile_SEEK_SET}"; then
+echo "$ac_t"""not found"" 1>&6
+{ echo "configure: error: Could not locate SEEK_SET" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""<${ac_cv_hdrfile_SEEK_SET}>" 1>&6
+seek_hdr="${ac_cv_hdrfile_SEEK_SET}"
+
+if test "${seek_hdr}" = "stdio.h"; then
+ seek_set_hdr=""
+else
+ seek_set_hdr="--include /usr/include/${seek_hdr}"
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1483: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1488 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1496: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1513 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1531 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1552 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1563: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in ctype.h string.h strings.h time.h sys/time.h sys/stat.h unistd.h alloca.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1590: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1595 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1600: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strncasecmp strcasecmp strdup localtime fstat
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1629: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1634 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1657: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for in -lsun""... $ac_c" 1>&6
+echo "configure:1682: checking for in -lsun" >&5
+ac_lib_var=`echo sun'_' | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsun $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1690 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char ();
+
+int main() {
+()
+; return 0; }
+EOF
+if { (eval echo configure:1701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo sun | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lsun $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo "checking if I know ld and ${ac_cv_prog_CXX} might not work together" 1>&6
+echo "configure:1730: checking if I know ld and ${ac_cv_prog_CXX} might not work together" >&5
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1759: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:1780: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1798: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+case "$target" in
+*-*-hpux*) ld=ld
+ echo "$ac_t""Using ld, as on ${target} I know ld and ${ac_cv_prog_CXX} mix" 1>&6
+ ;;
+*-*-linux*) ld=ld
+ echo "$ac_t""Using ld, as on ${target} I know ld and ${ac_cv_prog_CXX} mix" 1>&6
+ ;;
+
+*SPARC*-*-SUN*) ld=./fake_link
+ echo "$ac_t""Using my ar and ranlib shell script since ${ac_cv_prog_CXX} and ld do not mix" 1>&6
+ ;;
+
+*) ld=./fake_link
+ echo "$ac_t""Using my ar and ranlib shell script lest ${ac_cv_prog_CXX} and ld do not mix" 1>&6
+ ;;
+esac
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@CXX@%$CXX%g
+s%@RANLIB@%$RANLIB%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@getopt@%$getopt%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@seek_set_hdr@%$seek_set_hdr%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@ld@%$ld%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/support/word2x/configure.in b/support/word2x/configure.in
new file mode 100644
index 0000000000..f1d2493930
--- /dev/null
+++ b/support/word2x/configure.in
@@ -0,0 +1,77 @@
+AC_REVISION($Id: configure.in,v 1.15 1997/04/17 15:59:03 dps Exp $)dnl
+AC_INIT(word2x.cc)
+AC_CONFIG_HEADER(config.h)
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+
+dnl check for built in getopt_long, alloca and strftime
+AC_FUNC_CHECK(getopt_long, getopt="", getopt=gopt.o)
+AC_SUBST(getopt)
+AC_FUNC_ALLOCA
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl locate some symbols I want (why does SUN have to do this to me?)
+dnl At least these is some hack value in this stuff.
+AC_DEFUN(ac_FIND_HDR,
+[AC_MSG_CHECKING([header file for $1])
+AC_CACHE_VAL(ac_cv_hdrfile_$1,
+[ac_cv_hdrfile_$1=""
+for xhdr in $2; do
+if test -z "${ac_cv_hdrfile_$1}"; then
+AC_TRY_COMPILE([#include <stdio.h>
+#include<${xhdr}>],[ if ($1==$1) printf("ok");],
+[ac_cv_hdrfile_$1=${xhdr}])
+fi
+done
+if test -z "${ac_cv_hdrfile_$1}"; then
+AC_MSG_RESULT("not found")
+AC_ERROR([Could not locate $1])
+fi])
+AC_MSG_RESULT(<${ac_cv_hdrfile_$1}>)
+$3="${ac_cv_hdrfile_$1}"])dnl
+
+dnl Quite why Sun OS puts SEEK_SET in unistd.h (and not in stdio.h)
+dnl is a mystery!!
+ac_FIND_HDR(SEEK_SET, stdio.h unistd.h, seek_hdr)
+
+if test "${seek_hdr}" = "stdio.h"; then
+ seek_set_hdr=""
+else
+ seek_set_hdr="--include /usr/include/${seek_hdr}"
+fi
+AC_SUBST(seek_set_hdr)
+AC_STDC_HEADERS
+AC_CHECK_HEADERS(ctype.h string.h strings.h time.h sys/time.h sys/stat.h unistd.h alloca.h)
+AC_CHECK_FUNCS(strncasecmp strcasecmp strdup localtime fstat)
+AC_CHECK_LIB(sun)
+
+dnl on some systems ld and g++ are not compatible, so we have to kludge it
+dnl using the sunos_link shell script instead
+AC_CHECKING([if I know ld and ${ac_cv_prog_CXX} might not work together])
+AC_CANONICAL_SYSTEM
+case "$target" in
+*-*-hpux*) ld=ld
+ AC_MSG_RESULT(
+[Using ld, as on ${target} I know ld and ${ac_cv_prog_CXX} mix])
+ ;;
+*-*-linux*) ld=ld
+ AC_MSG_RESULT(
+[Using ld, as on ${target} I know ld and ${ac_cv_prog_CXX} mix])
+ ;;
+
+*SPARC*-*-SUN*) ld=./fake_link
+ AC_MSG_RESULT(
+[Using my ar and ranlib shell script since ${ac_cv_prog_CXX} and ld do not mix])
+ ;;
+
+*) ld=./fake_link
+ AC_MSG_RESULT(
+[Using my ar and ranlib shell script lest ${ac_cv_prog_CXX} and ld do not mix])
+ ;;
+esac
+AC_SUBST(ld)
+
+AC_OUTPUT(Makefile)
diff --git a/support/word2x/deHTMLdate.cc b/support/word2x/deHTMLdate.cc
new file mode 100644
index 0000000000..638b98650e
--- /dev/null
+++ b/support/word2x/deHTMLdate.cc
@@ -0,0 +1,40 @@
+// Date formatter for German dates (in German)
+// With correct a-umlaut in HTML encoding
+// Note: Using escape sequences in the <title> tag is not *really*
+// defined. You may want to use deL1 for your HTML stuff
+// 8/1998 jk
+#include "config.h"
+
+#ifdef TM_IN_SYS_TIME
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else /* do not have sting.h */
+#include <strings.h>
+#endif /* HAVE_STRING_H */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+char *deHTML_date(time_t when)
+{
+ static const char *months[]=
+ {
+ "Januar", "Februar", "M&auml;rz", "April",
+ "Mai", "Juni", "Juli", "August",
+ "September", "Oktober", "November", "Dezember",
+ };
+
+ struct tm *tim;
+ char date_buf[200];
+
+ tim=localtime(&when);
+
+ sprintf(date_buf, "%d. %s %d", tim->tm_mday,
+ months[tim->tm_mon], 1900+tim->tm_year);
+
+ return strdup(date_buf);
+}
diff --git a/support/word2x/deL1date.cc b/support/word2x/deL1date.cc
new file mode 100644
index 0000000000..43e0051f7f
--- /dev/null
+++ b/support/word2x/deL1date.cc
@@ -0,0 +1,38 @@
+// Date formatter for German dates (in German)
+// With correct a-umlaut in ISO-8859-1 (Latin-1) charset
+// 8/1998 jk
+#include "config.h"
+
+#ifdef TM_IN_SYS_TIME
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else /* do not have sting.h */
+#include <strings.h>
+#endif /* HAVE_STRING_H */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+char *deL1_date(time_t when)
+{
+ static const char *months[]=
+ {
+ "Januar", "Februar", "März", "April",
+ "Mai", "Juni", "Juli", "August",
+ "September", "Oktober", "November", "Dezember",
+ };
+
+ struct tm *tim;
+ char date_buf[200];
+
+ tim=localtime(&when);
+
+ sprintf(date_buf, "%d. %s %d", tim->tm_mday,
+ months[tim->tm_mon], 1900+tim->tm_year);
+
+ return strdup(date_buf);
+}
diff --git a/support/word2x/dedate.cc b/support/word2x/dedate.cc
new file mode 100644
index 0000000000..27f2e4250e
--- /dev/null
+++ b/support/word2x/dedate.cc
@@ -0,0 +1,39 @@
+// Date formatter for German dates (in German)
+// a-umlaut in Maerz is written as "ae" for compatibility reasons
+// use date format deL1 or deHTML for correct umlaut
+// 8/1998 jk
+#include "config.h"
+
+#ifdef TM_IN_SYS_TIME
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else /* do not have sting.h */
+#include <strings.h>
+#endif /* HAVE_STRING_H */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+char *de_date(time_t when)
+{
+ static const char *months[]=
+ {
+ "Januar", "Februar", "Maerz", "April",
+ "Mai", "Juni", "Juli", "August",
+ "September", "Oktober", "November", "Dezember",
+ };
+
+ struct tm *tim;
+ char date_buf[200];
+
+ tim=localtime(&when);
+
+ sprintf(date_buf, "%d. %s %d", tim->tm_mday,
+ months[tim->tm_mon], 1900+tim->tm_year);
+
+ return strdup(date_buf);
+}
diff --git a/support/word2x/fake_link b/support/word2x/fake_link
new file mode 100755
index 0000000000..c7eb40c855
--- /dev/null
+++ b/support/word2x/fake_link
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: sunos_link,v 1.2 1997/04/07 18:21:43 dps Exp $
+shift
+shift
+ar rc $@
+ranlib $1
diff --git a/support/word2x/fifo.h b/support/word2x/fifo.h
new file mode 100644
index 0000000000..2011c0ef64
--- /dev/null
+++ b/support/word2x/fifo.h
@@ -0,0 +1,265 @@
+/* $Id: fifo.h,v 1.17 1998/04/19 15:44:31 dps Exp $ */
+/* Generalised fifo */
+
+#ifndef __FIFO_H__
+#define __FIFO_H__
+
+#include <iostream.h>
+#include <stddef.h>
+#ifndef NULL
+#define NULL (void *) 0
+#endif /* NULL */
+
+template<class T>
+class fifo
+{
+private:
+ typedef struct queue
+ {
+ const T *data;
+ struct queue *next;
+ } queue;
+ struct queue *start;
+ struct queue **end;
+ int length;
+
+public:
+ inline fifo(void)
+ {
+ start=NULL;
+ end=&start;
+ length=0;
+ }
+ inline int is_empty(void)
+ {
+#ifdef CONSIST_CHECK
+ if (end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+ return (length==0) ? 1 : 0;
+ }
+ inline int qlen(void)
+ {
+ return length;
+ }
+ ~fifo(void);
+ void enqueue(const T *d); /* Add to end of queue */
+ void insert(const T *d); /* Add to start of queue */
+ void ins_trans(fifo *f); /* Insert fifo */
+ void rev(void); /* Reverse */
+ void clear(void); /* Wipe list to empty */
+ void transfer(fifo *f);
+ const T *dequeue(void);
+ ostream &__print_fifo(ostream &) const; /* Print */
+};
+
+#ifndef __NO_FIFO_FUNCTIONS__
+
+template<class T>
+void fifo<T>::clear(void)
+{
+ struct queue *ptr, *next;
+
+ ptr=start;
+ while (ptr!=NULL)
+ {
+ next=ptr->next;
+ delete(ptr->data);
+ delete(ptr);
+ ptr=next;
+ }
+ start=NULL;
+ end=&start;
+ length=0;
+}
+
+template<class T>
+fifo<T>::~fifo(void)
+{
+ struct queue *ptr, *next;
+
+ ptr=start;
+ while (ptr!=NULL)
+ {
+ next=ptr->next;
+ delete(ptr->data);
+ delete(ptr);
+ ptr=next;
+ }
+}
+
+template<class T>
+void fifo<T>::enqueue(const T *d)
+{
+ struct queue *q;
+
+#ifdef DEBUG_FIFO
+ cerr<<"Queue "<<(void *) d<<"\n";
+#endif
+ q=new(struct queue);
+ q->next=NULL;
+ q->data=d;
+ *end=q;
+ end=&(q->next);
+ length++;
+}
+
+template<class T>
+void fifo<T>::insert(const T *d)
+{
+ struct queue *q;
+#ifdef CONSIST_CHECK
+ if (end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+
+ q=new(struct queue);
+ q->next=start;
+ q->data=d;
+ start=q;
+ if (q->next==NULL)
+ end=&(q->next);
+ length++;
+}
+
+template<class T>
+const T *fifo<T>::dequeue(void)
+{
+ const T *d;
+ struct queue *q;
+#ifdef CONSIST_CHECK
+ if (end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+
+ if (length==0)
+ return NULL;
+
+ q=start;
+ d=q->data;
+#ifdef DEBUG_FIFO
+ cerr<<"Dequeue "<<(void *) d<<"\n";
+#endif
+ start=start->next;
+ if (--length==0)
+ end=&start;
+ delete(q);
+ return d;
+}
+
+template <class T>
+void fifo<T>::transfer(fifo<T> *d)
+{
+#ifdef CONSIST_CHECK
+ if (end==NULL || d->end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+
+ if (d==NULL || d->length==0)
+ return;
+
+ *end=d->start;
+ end=d->end;
+ length+=d->length;
+ d->start=NULL;
+ d->end=&(d->start);
+ d->length=0;
+}
+
+template<class T>
+void fifo<T>::ins_trans(fifo<T> *d)
+{
+#ifdef CONSIST_CHECK
+ if (end==NULL || d->end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+
+ if (d==NULL || d->length==0)
+ return;
+
+ *(d->end)=start;
+ start=d->start;
+ if (*(d->end)==NULL)
+ end=d->end;
+ length+=d->length;
+
+ d->length=0;
+ d->start=NULL;
+ d->end=&(d->start);
+}
+
+template<class T>
+void fifo<T>::rev(void)
+{
+ struct queue *p, *n, *hdr, **ep;
+#ifdef CONSIST_CHECK
+ if (end==NULL || d->end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+
+ if (length==0)
+ return;
+
+ ep=&(start->next);
+ for (hdr=NULL, p=start; p!=NULL; )
+ {
+ n=p->next;
+ p->next=hdr;
+ hdr=p;
+ p=n;
+ }
+ start=hdr;
+ end=ep;
+}
+
+
+template<class T>
+ostream &fifo<T>::__print_fifo(ostream &os) const
+{
+ const struct fifo<T>::queue *q;
+
+#ifdef CONSIST_CHECK
+ if (end==NULL || this->end==NULL)
+ {
+ cerr<<"Oops! end of list is NULL\n";
+ exit(1);
+ }
+#endif
+
+ q=this->start;
+ while (q!=NULL)
+ {
+ os<<(q->data)<<',';
+ q=q->next;
+ }
+ return os;
+}
+
+template<class T>
+inline ostream &operator << (ostream &os, const fifo<T> *d)
+{
+ d->__print_fifo(os);
+ return os;
+}
+
+
+#endif /* not __NO_FIFO_FUNCTIONS__ */
+#endif /* __FIFO_H__ */
diff --git a/support/word2x/fmt-html.h b/support/word2x/fmt-html.h
new file mode 100644
index 0000000000..37e6a70fd1
--- /dev/null
+++ b/support/word2x/fmt-html.h
@@ -0,0 +1,48 @@
+/* $Id: fmt-html.h,v 1.3 1997/03/31 21:59:42 dps Exp $ */
+/* Shared stuff for the *TeX output format */
+
+#ifndef __fmt_html_h__
+#define __fmt_html_h__
+#include "tblock.h"
+#include "interface.h"
+#include "html-table.h"
+
+/* Anything shorter than this is not a real paragraph */
+#define PAR_TRESHOLD_LEN 70
+/* Less than this is not a heading */
+#define HEADING_TRESHOLD_LEN 10
+/* Maximum section number */
+#define MAX_START_NUM 100
+
+/* Type */
+struct embed
+{
+ const char *key;
+ int key_len;
+ void (*handle)(const char *txt, const docfmt *fmt, FILE *out,
+ void *d);
+};
+
+
+/* Local data */
+struct html_data
+{
+ html_table *tabl;
+ int col;
+ int row;
+ const char *last_tc;
+ struct unit_info unit_d;
+ int par_flg;
+ int list_flg;
+ const char *unit_html;
+};
+
+/* latex-fmt.cc */
+extern tblock *__html_do_map(const char *s);
+
+/* latex-embed.cc */
+extern void html_embed(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d);
+
+#endif /* __fmt_html_h__ */
+
diff --git a/support/word2x/fmt-latex.h b/support/word2x/fmt-latex.h
new file mode 100644
index 0000000000..96977c1d14
--- /dev/null
+++ b/support/word2x/fmt-latex.h
@@ -0,0 +1,45 @@
+/* $Id: fmt-latex.h,v 1.8 1997/04/22 20:09:49 dps Exp $ */
+/* Shared stuff for the *TeX output format */
+
+#ifndef __fmt_latex_h__
+#define __fmt_latex_h__
+#include "tblock.h"
+#include "interface.h"
+#include "latex-table.h"
+
+/* Anything shorter than this is not a real paragraph */
+#define PAR_TRESHOLD_LEN 70
+/* Less than this is not a heading */
+#define HEADING_TRESHOLD_LEN 10
+
+/* Type */
+struct embed
+{
+ const char *key;
+ int key_len;
+ void (*handle)(const char *txt, const docfmt *fmt, FILE *out,
+ void *d);
+};
+
+
+/* Local data */
+struct latex_data
+{
+ latex_table *tabl;
+ int col;
+ int row;
+ const char *last_tc;
+ struct unit_info unit_d;
+ int par_flg;
+ int list_flg;
+};
+
+/* latex-fmt.cc */
+extern tblock *__latex_do_map(const char *s);
+
+/* latex-embed.cc */
+extern void ltx_embed(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d);
+
+#endif /* __fmt_latex_h__ */
+
diff --git a/support/word2x/getopt.c b/support/word2x/getopt.c
new file mode 100644
index 0000000000..23ce0648b7
--- /dev/null
+++ b/support/word2x/getopt.c
@@ -0,0 +1,752 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+ before changing it!
+
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
+ Free Software Foundation, Inc.
+
+This file is part of the GNU C Library. Its master source is NOT part of
+the C library, however. The master source lives in /gd/gnu/lib.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+#include <stdlib.h>
+#endif /* GNU C library. */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* XXX 1003.2 says this must be 1 before any call. */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return EOF with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+#include <string.h>
+#define my_index strchr
+#else
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+#if !defined (__STDC__) || !__STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+static const char *
+_getopt_initialize (optstring)
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind = 1;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns `EOF'.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ optarg = NULL;
+
+ if (optind == 0)
+ optstring = _getopt_initialize (optstring);
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc
+ && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return EOF;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
+ {
+ if (ordering == REQUIRE_ORDER)
+ return EOF;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if (nameend - nextchar == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, "%s: option `%s' is ambiguous\n",
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ "%s: option `--%s' doesn't allow an argument\n",
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ "%s: option `%c%s' doesn't allow an argument\n",
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr, "%s: option `%s' requires an argument\n",
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (opterr)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, "%s: unrecognized option `--%s'\n",
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+ else
+ fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, "%s: option requires an argument -- %c\n",
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == EOF)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/support/word2x/getopt.h b/support/word2x/getopt.h
new file mode 100644
index 0000000000..51ae8a734f
--- /dev/null
+++ b/support/word2x/getopt.h
@@ -0,0 +1,132 @@
+/* Declarations for getopt.
+ Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+#if __STDC__
+ const char *name;
+#else
+ char *name;
+#endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt (int, char *const *, const char *);
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/support/word2x/getopt1.c b/support/word2x/getopt1.c
new file mode 100644
index 0000000000..de8e2ad567
--- /dev/null
+++ b/support/word2x/getopt1.c
@@ -0,0 +1,184 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
+ Free Software Foundation, Inc.
+
+This file is part of the GNU C Library. Its master source is NOT part of
+the C library, however. The master source lives in /gd/gnu/lib.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#else
+char *getenv ();
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == EOF)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/support/word2x/html-embed.cc b/support/word2x/html-embed.cc
new file mode 100644
index 0000000000..55bc9ec720
--- /dev/null
+++ b/support/word2x/html-embed.cc
@@ -0,0 +1,381 @@
+/* $Id: html-embed.cc,v 1.8 1997/03/25 23:23:04 dps Exp $ */
+/* Embed handling for *TeX output */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include "interface.h"
+#include "tblock.h"
+#include "fmt-html.h"
+
+
+/* Skip a term */
+const char *html_skip_to_next(const char *ptr)
+{
+ int blevel;
+ int ign_nxt;
+
+ ign_nxt=0;
+ blevel=0;
+ while(1)
+ {
+ switch(*ptr)
+ {
+ case '\\':
+ ign_nxt=1;
+ break;
+
+ case '(':
+ if (!ign_nxt)
+ blevel++;
+ break;
+
+ case ')':
+ if (!ign_nxt)
+ blevel--;
+ if (blevel<0)
+ return ptr;
+ break;
+
+ case ',':
+ if (!ign_nxt && blevel==0)
+ return ptr;
+ break;
+
+ case '\0':
+ return ptr;
+
+ default:
+ break;
+ }
+ ptr++;
+ }
+}
+
+
+
+/* For detial of this see The TeXbook p. 141) */
+typedef enum {Disp=0, DispP, Text, TextP,
+ Script, ScriptP,
+ SScript, SScriptP } style;
+
+enum TypeIndex { Op_Sup=0, Op_Sub, Op_FTop, Op_FBot };
+/* Style navigation map */
+static const style style_map[][4]=
+{
+ { Script, ScriptP, Text, TextP }, // style D
+ { ScriptP, ScriptP, TextP, TextP }, // style D'
+ { Script, ScriptP, Script, ScriptP }, // Style T
+ { ScriptP, ScriptP, ScriptP, ScriptP }, // Style T'
+ { SScript, SScriptP, SScript, SScriptP }, // Style S
+ { SScriptP, SScriptP, SScriptP, SScriptP }, // Style S'
+ { SScript, SScriptP, SScript, SScriptP }, // Style SS
+ { SScriptP, SScriptP, SScriptP, SScriptP } // Style SS'
+};
+
+/* The actual work is in this recursive procedure */
+static tblock *cvt_eqn(const char *inp, const char *stop,
+ const int mline, const style sty)
+{
+ tblock *res, *r1, *r2;
+ const char *mid, *end;
+
+
+ res=new(tblock);
+ while (inp<stop)
+ {
+ if (isspace(*inp) && *inp!='\n')
+ {
+ inp++;
+ continue;
+ }
+
+ switch (*inp)
+ {
+ case '\0':
+ return res;
+
+ case '\n':
+ if (mline)
+ res->add(" \\\\\n");
+ break;
+
+ case '<':
+ case '>':
+ case '=':
+ if (mline)
+ {
+ res->add(" & ");
+ res->add(*inp);
+ res->add(" & ");
+ }
+ else
+ res->add(*inp);
+ break;
+
+ case '\\':
+ inp++;
+ switch(*inp)
+ {
+ case '\0':
+ cerr<<"Bug: cvt_eqn as \\0\n";
+ return res; // Safety.
+
+ case '(': // Guesswork FIXME
+ res->add(" (");
+ break;
+
+ case ')': // Guesswork FIXME
+ res->add(" )");
+ break;
+
+ case 'F': // Fraction
+ if (*(++inp)=='(' &&
+ *(mid=html_skip_to_next(++inp))!='\0' &&
+ *(end=html_skip_to_next(mid+1))!='\0')
+ {
+ r1=cvt_eqn(inp, mid, mline, style_map[sty][Op_FTop]);
+ r2=cvt_eqn(mid+1, end, mline, style_map[sty][Op_FBot]);
+ res->add(' ');
+ res->add(*r1);
+ res->add(" / "); // TeX syntax
+ res->add(*r2);
+ res->add(' ');
+ delete(r1); delete(r2);
+ }
+ inp=end;
+ break;
+ default:
+ end=html_skip_to_next(inp+1);
+ r1=cvt_eqn(inp+1, end, mline, sty);
+ res->add("<TT> \\backslash "); res->add(*inp);
+ res->add("</TT> "); res->add(*r1); res->add("<TT> ");
+ delete(r1);
+ inp=end;
+ break;
+ }
+ break;
+ case '+':
+ case '-':
+ res->add(*inp);
+ break;
+ case '*':
+ res->add(" * ");
+ break;
+
+ case ' ':
+ res->add(" ");
+ break;
+
+ case '_':
+ res->add("_");
+ break;
+
+ default:
+ int flg=0;
+ const char *scn;
+
+ /*
+ * This section is meant to catch 72 dpi and render it as
+ * \hbox{72 dpi} but not catch 12 * 18 (which should become
+ * 12\times 18).
+ */
+ if (isdigit(*inp) || *inp=='-' || *inp=='+')
+ {
+
+ /* Scan forward to see what comes text */
+ scn=inp;
+ if (*scn=='-' || *scn=='+')
+ scn++; // Skip sign
+ while (scn<stop && isdigit(*scn))
+ scn++; // Skip number
+ if (*scn=='.')
+ {
+ scn++;
+ while (scn<stop && isdigit(*scn))
+ scn++; // Hanlde decimals number
+ }
+
+ /* Now start looking at what comes next */
+ while (scn<stop)
+ {
+ if (isspace(*scn))
+ {
+ scn++;
+ continue;
+ }
+ if (isupper(*scn) || islower(*scn))
+ flg=1;
+ else
+ flg=0;
+ break;
+ }
+ }
+
+ /*
+ * This section is meant to catch strings and render them nicely
+ * in a mbox.
+ */
+ if (islower(*inp) || isupper(*inp) || flg)
+ {
+ res->add("\\text{");
+ if (flg) // If flag set then add everything up to scn
+ {
+ while (inp<scn)
+ {
+ res->add(*inp);
+ inp++;
+ }
+ }
+
+ flg=0; // Re-use flg
+ while (inp<stop && (islower(*inp) || isupper(*inp)
+ || isspace(*inp)
+ || *inp=='_'
+ || *inp=='^'))
+ {
+ if (isspace(*inp))
+ {
+ flg=1;
+ inp++;
+ continue; // If space, just set the flag
+ }
+ if (flg)
+ res->add(' '); // If skiped a space, add one
+ flg=0; // Clear flag
+ if (*inp=='_' || *inp=='^')
+ res->add('\\');
+ res->add(*inp);
+ inp++;
+ }
+ res->add("} ");
+ inp--;
+ break;
+ }
+ res->add(*inp);
+ break;
+ }
+ inp++;
+ }
+ return res;
+}
+
+/* Equations --- need more examples here */
+static void equation(const char *txt, const docfmt *fmt, FILE *out,
+ void *d)
+{
+
+ static const cmap comment_map[]={ { '\n', "\n% (contd) % " } };
+ struct html_data *dp;
+ tblock *cvt, eqn, *op;
+ const char *s;
+ int mline;
+
+ dp=(struct html_data *) d;
+ cvt=map_string(txt, comment_map);
+ fprintf(out, "%%\n%% EMBED %s\n", (const char *) (*cvt));
+ delete(cvt);
+
+ for (mline=0, s=txt; *s!='\0'; s++)
+ {
+ if (*s=='\n')
+ {
+ mline=1;
+ break;
+ }
+ }
+ if (!mline)
+ eqn.add((dp->par_flg) ? "$" : "$$");
+ else
+ eqn.add("\\begin{eqnarray*}\n");
+ cvt=cvt_eqn(txt+3, txt+strlen(txt), mline, (dp->par_flg) ? Disp : Text);
+ eqn.add(*cvt);
+ delete(cvt);
+
+ if (!mline)
+ eqn.add((dp->par_flg) ? "$" : "$$%");
+ else
+ eqn.add("\n\\end{eqnarray*}\n");
+
+ op=word_wrap(eqn, "\n", "\n", fmt->maxline);
+ fputs((const char *) (*op), out);
+ fputc('\n', out);
+ delete(op);
+}
+
+
+
+/* Table of contents entries, used as a cue for stuff like sections */
+/* This code jus stashes it away for the paragraph code */
+static void add_contents(const char *txt, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ const char *open, *close;
+ tblock entry;
+ struct html_data *dp;
+
+ fmt=fmt;
+ out=out;
+ dp=(struct html_data *) d;
+ for (open=txt; *open!='"'; open++)
+ {
+ if (*open=='\0')
+ {
+ cerr<<"Found tc entry but no openning quote\n";
+ return;
+ }
+ }
+
+ for (close=open+1; *close!='"'; close++)
+ {
+ if (*close=='\0')
+ {
+ cerr<<"Found tc entry but no closing quote\n";
+ return;
+ }
+ }
+
+ if (close-open==1)
+ {
+ cerr<<"Ignoring empty table of contents entry\n";
+ return;
+ }
+
+ while (++open<close)
+ entry.add(*open);
+ if (dp->last_tc!=NULL)
+ free((void *) dp->last_tc);
+ dp->last_tc=strdup(entry);
+
+}
+
+static struct embed emb[]=
+{
+ { "tc ", 3, add_contents }, // Table of contents line
+ { "eq ", 3, equation }, // Equations
+};
+
+void html_embed(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ int i;
+
+ for (i=0; (unsigned) i<N(emb); i++)
+ {
+ if (strncmp(t->data.d, emb[i].key, emb[i].key_len)==0)
+ {
+ (emb[i].handle)(t->data.d, fmt, out, d);
+ return;
+ }
+ }
+ fprintf(out, "%%\n%% %s\n", t->data.d);
+}
diff --git a/support/word2x/html-fmt.cc b/support/word2x/html-fmt.cc
new file mode 100644
index 0000000000..11344d6530
--- /dev/null
+++ b/support/word2x/html-fmt.cc
@@ -0,0 +1,487 @@
+/* $Id: html-fmt.cc,v 1.1 1997/04/23 00:45:06 dps Exp dps $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+#include "interface.h"
+#include "lib.h"
+#include "html-table.h"
+#include "fmt-html.h"
+
+static const cmap html_map[]=
+{
+ { '\n', "<BR>\n" }, // Newline
+ { 0x1E, "-" }, // Unbreakable join
+ { 0x1F, "\\-" }, // Soft hypen
+ { '<', "&lt;" }, // #
+ { '>', "&gt;" }, // $
+ { '&', "&amp;" }, // &
+ { 0x85, "..." }, // Dots
+ { 0x91, "`" }, // 91 = left quote (15th element)
+ { 0x92, "'" }, // 92 = right quote
+ { 0x93, "``" }, // 93 = opening double quote
+ { 0x94, "''" }, // 94 = closing double quote
+ { 0x96, "--" }, // em-dash
+ { 0x97, "---" }, // en-dash (20th element)
+ { 0x99, "(TM)" }, // Trademark
+ { 0xA0, " " }, // Unbreakable space
+ { 0xA3, "&lt;=" }, // <= came out as A3, also pounds
+ { 0xA9, "(C)" }, // Copyright
+ { 0xAB, "&lt;&lt;" }, // Openning << quotes (25th element)
+ { 0xAE, "(R)" }, // reserved sign
+ { 0xB3, "&gt;=" }, // Greater than or = came out as B3
+ { 0xBB, "&gt;&gt;" }, // Closing >> quotes (28th element)
+ { 0xDF, "&szlig;" }, // beta
+ { 0xE4, "&auml;" }, // a with umlualt
+ { 0xE9, "&egrave;" }, // e grave??
+ { 0xF1, "&ntidle" }, // n bar
+ { 0xF6, "&ouml;" }, // o with umlualt
+ { 0xFA, "\\.u" }, // u with dot?
+ { 0xFC, "&uuml;" }, // u with umlualt.
+};
+
+tblock *__html_do_map(const char *s)
+{
+ tblock *out;
+
+ out = map_string(s, html_map);
+ return out;
+}
+
+/* Preamble */
+static void h_preamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ time_t now;
+ struct stat st;
+ char *tnow, *tdoc;
+
+ t=t;
+ d=d;
+
+ now=time(NULL);
+ tnow=(fmt->date)(now);
+
+ if (fstat(fileno(out), &st)==-1)
+ st.st_mtime=now;
+ tdoc=fmt->date(st.st_mtime);
+
+ fprintf(out,
+ "<!-- Generated by word2x on %s-->\n"
+ "\n"
+ "<HTML>\n"
+ "<HEAD>\n"
+ " <TITLE>Word document from %s</TITLE>"
+ "</HEAD>\n"
+ "<BODY>\n",
+ tnow, tdoc);
+ free(tnow);
+ free(tdoc);
+}
+
+/* Postamble */
+static void h_postamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *dp;
+ fmt=fmt;
+ t=t;
+ dp=(struct html_data *) d;
+
+ fputs("</BODY></HTML>\n", out);
+}
+
+/* Allocate local data */
+static void *allocate_html(void)
+{
+ struct html_data *tdata;
+ int i;
+
+ tdata = new(struct html_data);
+ tdata->tabl = NULL;
+ tdata->last_tc = NULL;
+ tdata->unit_d.unit_type = 1;
+ tdata->list_flg = 0;
+ for (i=0; i<4; i++)
+ tdata->unit_d.unit_number[i]=-1;
+
+ return tdata;
+}
+
+/* Free local data */
+static void free_html(void *d)
+{
+ struct html_data *tdata;
+
+ tdata=(struct html_data *) d;
+ if (tdata->tabl!=NULL)
+ delete(tdata->tabl);
+}
+
+
+static void html_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ d=d;
+ switch(*(t->data.d))
+ {
+ case CH_PAGE:
+ if (fmt->flags.new_pages)
+ fputs("\n<HR>\n", out);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+struct list_info
+{
+ const char *ltype; // List type from reader
+ const char *start; // Start tag
+ const char *end; // End tag
+};
+
+static const struct list_info *ltype_info(const char *type)
+{
+ static const struct list_info list_inf[]=
+ {
+ { "listAlpha", "<OL TYPE=\"A\">", "</OL>" }, // Netscape extension
+ { "listalpha", "<OL TYPE=\"a\">", "</OL>" }, // Netscape extension
+ { "enumerate", "<OL>", "</OL>" }, // Standard
+ { "itemize", "<UL>", "</UL>" }, // Standard
+ };
+
+ unsigned i;
+
+ for (i=0; i<N(list_inf); i++)
+ {
+ if (strcmp(type, list_inf[i].ltype)==0)
+ return (list_inf+i);
+ }
+ return NULL;
+}
+
+/* item */
+static void html_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *dp;
+ fmt=fmt;
+ t=t;
+ out=out;
+ dp=(struct html_data *) d;
+
+ dp->list_flg=1;
+}
+
+
+/* start list, have to convert from *TeX types... */
+static void html_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ const struct list_info *linf;
+ const char *s;
+
+ fmt=fmt;
+ d=d;
+ linf=ltype_info(t->data.d);
+ if (linf==NULL)
+ {
+ cerr<<"Unknown list type "<<t->data.d<<" treated as bulleted list\n";
+ s="<UL>";
+ }
+ else
+ {
+ s=linf->start;
+ }
+ fprintf(out, "\n%s\n", s);
+}
+
+/* end list, have to convert from *TeX types... */
+static void html_end_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ const struct list_info *linf;
+ const char *s;
+
+ fmt=fmt;
+ d=d;
+ fmt=fmt;
+ d=d;
+ linf=ltype_info(t->data.d);
+ if (linf==NULL)
+ {
+ cerr<<"Unknown list type "<<t->data.d<<" treated as bulleted list\n";
+ s="</UL>";
+ }
+ else
+ s=linf->end;
+ fprintf(out, "\n%s\n", s);
+}
+
+/*
+ * Paragraphs are easy, but get complicated due to need to work out
+ * which things are actually chapter headings, etc
+ */
+static void fold_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ tblock *b, *ts, op;
+ const char *s, *t, *pt, *unit_html="P";
+ struct html_data *dp;
+ int has_num, i, j;
+ struct unit_number u_num;
+
+ static const char *const sects[]=
+ {
+ "H1", "H2", "H3", "H4"
+ };
+ static const char *const sects_english[]=
+ {
+ "chapter", "section", "subsection", "subsubsection"
+ };
+
+ dp = (struct html_data *) d;
+
+ /* Even this much is under 100%!! */
+ pt=(tok->data.d);
+
+ if (*pt=='\0' && dp->list_flg==1)
+ return;
+
+ if (dp->last_tc != NULL)
+ {
+ if (strcmp(dp->last_tc, pt)==0)
+ {
+ unit_html=sects[dp->unit_d.unit_type];
+ }
+
+ else
+ {
+ s=dp->last_tc+strlen(dp->last_tc)-strlen(pt);
+ if (strcmp(s, pt)==0)
+ {
+ /* Find type */
+ for (i=0; i<(int) N(sects_english); i++)
+ {
+ if (strncasecmp(dp->last_tc, sects_english[i],
+ strlen(sects_english[i]))==0)
+ break;
+ }
+ t = dp->last_tc+strlen(sects_english[i]);
+ has_num = get_part_num(t,s);
+ unit_html=sects[i]; // Set the section type
+
+ /* Update the control data */
+ if (dp->unit_d.unit_number[i]==-1)
+ {
+ dp->unit_d.unit_number[i]=(has_num==-1) ? 1 : has_num;
+ for (j=i+1; j<(int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ if (i<(int) N(sects)-1)
+ dp->unit_d.unit_type=i+1;
+ else
+ dp->unit_d.unit_type=i;
+ }
+ }
+ free((void *) dp->last_tc);
+ dp->last_tc=NULL;
+ }
+ else
+ {
+ if (dp->list_flg)
+ {
+ op.add("<Li>");
+ }
+ else
+ {
+ if (strlen(pt)>0 && strlen(pt)<PAR_TRESHOLD_LEN)
+ {
+ if (strcasecmp(pt,"Appendix")==0)
+ {
+ dp->unit_d.unit_type=
+ (dp->unit_d.unit_number[0]==-1) ? 1 : 0;
+
+ /* Output the heading level */
+ unit_html=sects[dp->unit_d.unit_type];
+ for (j=dp->unit_d.unit_type+1; j<(int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ else if (strcasecmp(pt,"Bibliography")==0)
+ {
+ dp->unit_d.unit_type=
+ (dp->unit_d.unit_number[0]==-1) ? 1 : 0;
+ for (j=dp->unit_d.unit_type+1; j<(int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ else
+ {
+ u_num=n_unit_probe(pt, &(dp->unit_d));
+
+ if (u_num.unit_num!=-1)
+ {
+ i=u_num.offset;
+ unit_html=sects[u_num.unit_num];
+ }
+ }
+ }
+ }
+ dp->list_flg=0;
+ }
+ /* Record the unit type started */
+ dp->unit_html=unit_html;
+ /* Insert the start tag and eneter paragraoh if not in one */
+ if (!dp->par_flg)
+ {
+ dp->par_flg = 1;
+ op.add("<");
+ op.add(unit_html);
+ op.add('>');
+ }
+ /* Add the text */
+ ts = map_string(pt, html_map);
+ op.add(*ts);
+ delete(ts);
+ /* fold the line */
+ b = word_wrap(op, "\n", "\n", fmt->maxline, 0);
+ fputs((*b), out);
+ delete(b);
+}
+
+/* End of paragraph, outputs the end tag */
+static void end_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *dp;
+
+ tok=tok;
+ fmt=fmt;
+ dp=(struct html_data *) d;
+ dp->par_flg=0;
+
+ fputs("</",out);
+ fputs(dp->unit_html, out);
+ fputs(">\n\n", out);
+}
+
+/* Start a table === allocate table and initialise */
+static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ tdata=(struct html_data *) d;
+ tdata->col=0;
+ tdata->row=0;
+ tdata->tabl=new(html_table)(t->data.table.cols, t->data.table.rows);
+ tdata->par_flg=0;
+}
+
+
+/* End of a table==print the table */
+static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *tdata;
+
+ t=t;
+ tdata=(struct html_data *) d;
+ tdata->tabl->print_table(fmt->maxline, out); // Print table
+ delete(tdata->tabl);
+ tdata->tabl=NULL;
+}
+
+/* start row==set column to 0 */
+static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct html_data *) d;
+ tdata->col=0;
+}
+
+/* end row==add one to row */
+static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *tdata;
+
+ fmt=fmt;
+ t=t;
+ out=out;
+ tdata=(struct html_data *) d;
+ tdata->row++;
+}
+
+
+/* Start field === set field */
+static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *tdata;
+
+ tdata=(struct html_data *) d;
+ out=out;
+ fmt=fmt;
+ tdata->tabl->set(tdata->col, tdata->row, t->data.d);
+}
+
+/* end field==add one to col */
+static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct html_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct html_data *) d;
+ tdata->col++;
+}
+
+
+
+/* pointers to the functions that do the work */
+docfmt htmlfmt=
+{
+ { 1 }, // Keep page breaks
+ 76, // Width
+ "\n", // Use \n as line ends
+ allocate_html, // Allocate space
+ free_html, // Free text
+ {
+ { h_preamble, h_postamble }, // End and start of document
+ { fold_para, end_para }, // Paragraph
+ { alloc_tbl, format_tbl }, // Start/end table
+ { set_field, inc_col }, // Start/end field
+ { start_row, inc_row }, // Start/end row
+ { html_embed, null_proc }, // Throw away embed messages
+ { html_list, html_end_list }, // Start/end list
+ { html_item, null_proc }, // Start/end item
+ { html_code, null_proc }, // Code ends do not occur
+ { null_proc, null_proc } // Do not understanding anything else
+ }
+} ;
+
+
+
diff --git a/support/word2x/html-table.cc b/support/word2x/html-table.cc
new file mode 100644
index 0000000000..6609aacaff
--- /dev/null
+++ b/support/word2x/html-table.cc
@@ -0,0 +1,297 @@
+/* $Id: html-table.cc,v 1.4 1997/04/01 01:02:28 dps Exp $ */
+/* Html table layout */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include "tblock.h"
+#include "html-table.h"
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+#ifndef HAVE_ALLOCA_H
+extern "C" char *alloca(int);
+#else
+#include <alloca.h>
+#endif /* HAVE_ALLOCA_H */
+
+struct rdata
+{
+ struct wd_info w;
+ const char *data;
+};
+
+
+
+/* Print row after folding of columns has been done */
+static void basic_print_row(int ncols, const struct rdata *cols,
+ int maxw, FILE *out)
+{
+ const char *s;
+ int i, nsp, nz;
+ align_t al;
+ num_info n;
+ tblock output, *outp;
+
+ /* Print the content */
+ output.add("<TR>");
+ for (i=0; i<ncols; i++)
+ {
+ output.add("<TD>");
+
+ s=cols[i].data;
+ al=cols[i].w.align;
+ if (cols[i].w.dp_col>=0)
+ {
+ n=scan_num(s);
+ if (n.dot_pos!=-1)
+ {
+ nz=cols[i].w.dp_col-n.dot_pos;
+ if ((!n.has_sign) && (cols[i].w.has_sign))
+ {
+ /*
+ output.add("\\phantom{$-$");
+ if (nz>0)
+ {
+ while (nz--)
+ output.add('0');
+ }
+ output.add("}");
+ */
+ }
+ else
+ {
+ if (n.has_sign)
+ nz++; // - does not count as a digit.
+ if (nz>0)
+ {
+ /*
+ output.add("\\phantom{");
+ while (nz--)
+ output.add('0');
+ output.add("}");
+ */
+ }
+ }
+ if (n.has_sign)
+ {
+ /* Typeset the sign in math mode */
+ output.add(*s);
+ s++;
+ }
+ output.add(s);
+ if (nsp-cols[i].w.dp_col+n.dot_pos>0
+ && cols[i].w.align!=ALIGN_LEFT)
+ output.add(""); /* was hfill */
+ al=ALIGN_DP;
+ }
+ }
+
+ switch(al)
+ {
+ case ALIGN_DP:
+ break;
+
+ case ALIGN_LEFT:
+ case ALIGN_CENTER:
+ case ALIGN_RIGHT:
+ output.add(s);
+ break;
+
+ default:
+ fprintf(stderr,"basic_print_row: Invalid alignment\n");
+ break;
+ }
+
+ output.add(" </TD> "); // Seperate columns
+ }
+ output.add(" \n"); // converted to \\ \n by word_wrap.
+ outp=word_wrap((const char *) output, "\n", "</TR>\n", maxw, 0);
+ fputs((const char *) (*outp), out);
+ delete(outp);
+}
+
+extern tblock *__html_do_map(const char *);
+/* Split the elements of a row */
+static void print_row(int ncols, const struct rdata *dp, int maxw, FILE *out)
+{
+ static const char null_string[]={'\0'};
+ struct rdata *rd;
+ tblock *d;
+ int i;
+
+ /* Allocate structures */
+ if ((rd=(struct rdata *) alloca(ncols*sizeof(rdata)))==NULL)
+ {
+ fprintf(stderr, "print_row: fatal alloca failure\n");
+ exit(1);
+ }
+
+ /* Convert data to *TeX */
+ for (i=0; i<ncols; i++)
+ {
+ rd[i].w=dp[i].w;
+ if (dp[i].data==NULL)
+ {
+ rd[i].data=null_string; // Avoid complication of null in
+ // basic_print_row
+ continue; // Move on to next item
+ }
+
+ d=__html_do_map(dp[i].data);
+ if ((rd[i].data=strdup(*d))==NULL)
+ {
+ fprintf(stderr, "html_table::print_row: fatal alloca failure\n");
+ exit(1);
+ }
+ delete(d);
+ }
+ basic_print_row(ncols, rd, maxw, out); // Printing the rows is actually
+ // quite complex.
+ for (i=0; i<ncols; i++)
+ {
+ if (rd[i].data!=null_string)
+ free((void *) rd[i].data); // Free data
+ }
+}
+
+
+
+/* Returns NULL or text message */
+const char *html_table::print_table(int wd, FILE *out, const int ruled)
+{
+ int i,j;
+ struct rdata *d;
+ const struct col_info *col;
+
+ if ((d=(struct rdata *) alloca(cols*sizeof(struct rdata)))==NULL)
+ {
+ cerr<<"html_table::print_table alloca failute (fatal)\n";
+ return "[Table omitted due to lack of memory]";
+ }
+ if (cols==0 || rows==0)
+ {
+ fputs("[empty tabel ignored]\n", out);
+ return "[Ignored empty table]";
+ }
+
+ for (i=0, col=cdata; col!=NULL; i++, col=col->next)
+ d[i].w=find_width(rows, col->data);
+
+ if (ruled)
+ fputs("<TABLE BORDER=1>", out);
+ else
+ fputs("<TABLE>", out);
+
+ for (i=0; i<cols; i++)
+ {
+ switch(d[i].w.align)
+ {
+ default:
+ cerr<<"Alignment "<<d[i].w.align<<" unsupported\n";
+ /* Fall through */
+
+ case ALIGN_LEFT:
+ /* fputc('l', out); */
+ break;
+
+ case ALIGN_CENTER:
+ /* fputc('c', out); */
+ break;
+
+ case ALIGN_RIGHT:
+ /* fputc('r', out); */
+ break;
+ }
+ }
+ fprintf(out, "\n");
+
+ for (i=0; i<rows; i++)
+ {
+ for (j=0, col=cdata; col!=NULL; j++, col=col->next)
+ d[j].data=(col->data)[i];
+ print_row(cols, d, wd, out);
+ if (i==0)
+ fputs("\\hline\n", out);
+ }
+
+ fprintf(out, "</TABLE>\n");
+ return NULL;
+}
+
+/* Set */
+int html_table::set(int c, int r, const char *s)
+{
+ struct col_info *col;
+ int i;
+
+ if (c<0 || c>=cols || r<0 || r>=rows)
+ {
+ cerr<<"Invalid request to set "<<c<<','<<r<<" in "
+ <<cols<<'x'<<rows<<" table (value "<<s<<")\n";
+ return 0;
+ }
+
+ for (col=cdata, i=0; i<c && col!=NULL; i++, col=col->next) ;
+ if (col!=NULL)
+ {
+ if (col->data[r]!=NULL)
+ free((void *) col->data[r]);
+ col->data[r]=strdup(s);
+ }
+ return 1;
+}
+
+
+/* Constructor */
+html_table::html_table(int c, int r)
+{
+ int i, j;
+ struct col_info *col, **nptr;
+
+ cols=c;
+ rows=r;
+ cdata=NULL; // Hardenning against cols=0
+ for (nptr=&cdata, i=0; i<cols; i++)
+ {
+ col=new(struct col_info);
+ *nptr=col;
+ col->next=NULL;
+ nptr=&(col->next);
+ if ((col->data=
+ (const char **) malloc(rows*(sizeof(const char *))))==NULL)
+ {
+ cerr<<"html_table::constructor: malloc failure (fatal)\n";
+ exit(1);
+ }
+ for (j=0; j<rows; j++)
+ (col->data)[j]=NULL;
+ }
+}
+
+/* Destructor */
+html_table::~html_table()
+{
+ int i;
+ struct col_info *col, *nxt;
+
+ for (col=cdata; col!=NULL;)
+ {
+ for (i=0; i<rows; i++)
+ if (col->data[i]==NULL)
+ free((void *) col->data[i]);
+ nxt=col->next;
+ free(col);
+ col=nxt;
+ }
+}
+
+
+
diff --git a/support/word2x/html-table.h b/support/word2x/html-table.h
new file mode 100644
index 0000000000..ebdd2adf69
--- /dev/null
+++ b/support/word2x/html-table.h
@@ -0,0 +1,27 @@
+/* $Id: html-table.h,v 1.1 1997/04/29 06:46:08 dps Exp $ */
+
+#ifndef __html_table__
+#define __html_table__
+#include <stdio.h>
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+class html_table
+{
+private:
+ struct col_info
+ {
+ const char **data;
+ struct col_info *next;
+ };
+ int cols;
+ int rows;
+ struct col_info *cdata;
+
+public:
+ const char *print_table(int, FILE *, const int =1);
+ int set(int, int, const char *);
+ html_table(int, int);
+ ~html_table(void);
+};
+#endif /* __html_table__ */
diff --git a/support/word2x/install-sh b/support/word2x/install-sh
new file mode 100755
index 0000000000..89fc9b098b
--- /dev/null
+++ b/support/word2x/install-sh
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/support/word2x/interface.h b/support/word2x/interface.h
new file mode 100644
index 0000000000..d549bf9bd3
--- /dev/null
+++ b/support/word2x/interface.h
@@ -0,0 +1,60 @@
+/* $Id: interface.h,v 1.10 1997/04/09 12:14:24 dps Exp $ */
+/* Interface for output code */
+
+#ifndef __w6cvt_iface_h__
+#define __w6cvt_iface_h__
+#include <stdio.h>
+#include <time.h>
+
+typedef enum
+{
+ T_DOC=0, /* Document */
+ T_PARAGRAPH, /* Paragraph */
+ T_TABLE, T_FIELD, T_ROW, /* Tables */
+ T_SPEC, /* Embed messages */
+ T_LIST, T_ITEM, /* Lists */
+ T_CODE, /* One off codes, e.g. page breaks */
+ T_OTHER, /* Unknown stuff */
+ NFUNCS
+} token;
+
+typedef struct
+{
+ unsigned char win;
+ const char *ascii;
+} cmap;
+
+#include "reader.h" /* Need token for this file.... */
+
+#ifndef __EXCLUDE_READER_CLASSES
+typedef struct
+{
+ void (*start)(const tok_seq::tok *, const struct docfmt *, FILE *, void *);
+ void (*end)(const tok_seq::tok *, const struct docfmt *, FILE *, void *);
+} funcs;
+
+typedef struct docfmt
+{
+ struct
+ {
+ unsigned new_pages :1;
+ } flags; /* Flags */
+ int maxline; /* Maximum line length */
+ const char *foldchar; /* Newline for folding line */
+ void *(*new_state)(void); /* Make new state */
+ void (*free_state)(void *); /* Free state */
+ funcs f[NFUNCS]; /* Document output fucntions */
+ char *(*date)(time_t); /* Set by front end */
+} docfmt;
+
+#endif /* __EXLCUDE_READER_CLASSES */
+
+#ifndef N
+#define N(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+#endif /* __w6cvt_iface_h__ */
+
+
+
+
diff --git a/support/word2x/latex-embed.cc b/support/word2x/latex-embed.cc
new file mode 100644
index 0000000000..810e3a17ad
--- /dev/null
+++ b/support/word2x/latex-embed.cc
@@ -0,0 +1,555 @@
+/* $Id: latex-embed.cc,v 1.12 1997/04/17 20:03:19 dps Exp $ */
+/* Embed handling for *TeX output */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include "interface.h"
+#include "tblock.h"
+#include "fmt-latex.h"
+
+
+/* For detial of this see The TeXbook p. 141) */
+typedef enum {Disp=0, DispP, Text, TextP,
+ Script, ScriptP,
+ SScript, SScriptP } style;
+
+enum TypeIndex { Op_Sup=0, Op_Sub, Op_FTop, Op_FBot, Op_Cramp };
+/* Style navigation map */
+static const style style_map[][5]=
+{
+ { Script, ScriptP, Text, TextP, DispP }, // style D
+ { ScriptP, ScriptP, TextP, TextP, DispP }, // style D'
+ { Script, ScriptP, Script, ScriptP, TextP }, // Style T
+ { ScriptP, ScriptP, ScriptP, ScriptP, TextP }, // Style T'
+ { SScript, SScriptP, SScript, SScriptP, ScriptP }, // Style S
+ { SScriptP, SScriptP, SScriptP, SScriptP, ScriptP }, // Style S'
+ { SScript, SScriptP, SScript, SScriptP, SScriptP }, // Style SS
+ { SScriptP, SScriptP, SScriptP, SScriptP, SScriptP } // Style SS'
+};
+
+static tblock *cvt_eqn(const char *, const char *, const int, const style);
+
+
+/* Skip a term */
+const char *skip_to_next(const char *ptr)
+{
+ int blevel;
+ int ign_nxt;
+
+ ign_nxt=0;
+ blevel=0;
+ while(1)
+ {
+ switch(*ptr)
+ {
+ case '\\':
+ ign_nxt=1;
+ break;
+
+ case '(':
+ if (!ign_nxt)
+ blevel++;
+ break;
+
+ case ')':
+ if (!ign_nxt)
+ blevel--;
+ if (blevel<0)
+ return ptr;
+ break;
+
+ case ',':
+ if (!ign_nxt && blevel==0)
+ return ptr;
+ break;
+
+ case '\0':
+ return ptr;
+
+ default:
+ break;
+ }
+ ptr++;
+ }
+}
+
+
+/* Equation sub-bits */
+
+/* \b bracket */
+static const char *eqn_backet(tblock *res, const char *inp,
+ const int mline, const style sty)
+{
+ const char *end;
+ tblock *r1;
+
+ end=skip_to_next(inp);
+ if (*inp!=')')
+ return NULL;
+ {
+ r1=cvt_eqn(inp, end, mline, sty);
+ res->add("\\left(");
+ res->add(*r1);
+ res->add("\\right)");
+ delete(r1);
+ }
+ return end;
+}
+
+/* \l group */
+static const char *eqn_list(tblock *res, const char *inp,
+ const int mline, const style sty)
+{
+ tblock *r1;
+ const char *end;
+
+ end=skip_to_next(inp);
+ if (*inp!=')')
+ return NULL;
+ {
+ r1=cvt_eqn(inp, end, mline, sty);
+ res->add("{");
+ res->add(*r1);
+ res->add("}");
+ delete(r1);
+ }
+ return end;
+}
+
+/* \o overlay */
+static const char *eqn_overlay(tblock *res, const char *inp,
+ const int mline, const style sty)
+{
+ const char *end;
+ tblock *r1;
+
+ end=skip_to_next(inp);
+ if (*inp!=')')
+ return NULL;
+ {
+ r1=cvt_eqn(inp, end, mline, sty);
+ res->add("\\smash{");
+ res->add(*r1);
+ res->add("}");
+ delete(r1);
+ }
+ return end;
+}
+
+/* \r root */
+static const char *eqn_root(tblock *res, const char *inp,
+ const int mline, const style sty)
+
+{
+ tblock *r1, *r2;
+ const char *mid, *end;
+
+ mid=skip_to_next(inp);
+ switch (*mid)
+ {
+ case ',':
+ end=skip_to_next(mid+1);
+ if (*end!=')')
+ return NULL;
+
+ r1=cvt_eqn(inp, mid, mline, style_map[sty][Op_Cramp]);
+ r2=cvt_eqn(mid+1, end, mline, style_map[sty][Op_Cramp]);
+ res->add("\\sqrt["); res->add(*r1);
+ res->add("]{"); // TeX syntax
+ res->add(*r2);
+ res->add('}');
+ delete(r1);
+ delete(r2);
+ break;
+
+ case ')':
+ r1=cvt_eqn(inp, mid, mline, style_map[sty][Op_Cramp]);
+ res->add("\\sqrt{");
+ res->add(*r1);
+ res->add(*r1);
+ res->add('}');
+ delete(r1);
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/* \f fraction */
+static const char *eqn_fract(tblock *res, const char *inp,
+ const int mline, const style sty)
+{
+ tblock *r1, *r2;
+ const char *mid, *end;
+
+ mid=skip_to_next(inp);
+ if (*mid!=',')
+ return NULL;
+
+ end=skip_to_next(mid+1);
+ if (*end!=')')
+ return NULL;
+
+ r1=cvt_eqn(inp, mid, mline, style_map[sty][Op_FTop]);
+ r2=cvt_eqn(mid+1, end, mline, style_map[sty][Op_FBot]);
+ res->add('{');
+ res->add(*r1);
+ res->add(" \\over "); // TeX syntax
+ res->add(*r2);
+ res->add('}');
+ delete(r1);
+ delete(r2);
+
+ return end;
+}
+
+
+/* Anything I do not understand */
+const char *eqn_default(tblock *res, const char *inp, const char *end,
+ const int mline, const style sty)
+{
+ tblock *r1;
+
+ res->add("{\\text{\tt \\backslash ");
+ res->add(inp, end-inp+1);
+ inp=end+1;
+ do
+ {
+ end=skip_to_next(inp);
+ r1=cvt_eqn(inp, end, mline, sty);
+ res->add(*r1);
+ if (*end!='\0')
+ res->add(*end);
+ else
+ res->add("{\\it EOF}");
+ delete(r1);
+ inp=end+1;
+ } while (*end!='\0' && *end!=')');
+ res->add("}} ");
+
+ return end;
+}
+
+/* The actual work is in this recursive procedure */
+static tblock *cvt_eqn(const char *inp, const char *stop,
+ const int mline, const style sty)
+{
+ tblock *res;
+ const char *mid, *end;
+ int l, i;
+
+ typedef const char *(*eqn_proc)(tblock *, const char *, const int,
+ const style);
+ static const struct { const char *name; eqn_proc func; } eqp[]=
+ {
+ { "b", eqn_backet },
+ { "l", eqn_list },
+ { "o", eqn_overlay },
+ { "r", eqn_root },
+ { "f", eqn_fract },
+ { NULL, NULL },
+ };
+
+ res=new(tblock);
+ while (inp<stop)
+ {
+ if (isspace(*inp) && *inp!='\n')
+ {
+ inp++;
+ continue;
+ }
+
+ switch (*inp)
+ {
+ case '\0':
+ return res;
+
+ case '\n':
+ if (mline)
+ res->add(" \\\\\n");
+ break;
+
+ case '<':
+ case '>':
+ case '=':
+ if (mline)
+ {
+ res->add(" & ");
+ res->add(*inp);
+ res->add(" & ");
+ }
+ else
+ res->add(*inp);
+ break;
+
+ case '\\':
+ inp++;
+ switch(*inp)
+ {
+ case '\0':
+ cerr<<"cvt_eqn saw \\\\0\n";
+ return res; // Safety.
+
+ case '{':
+ res->add(" \\{"); // More guesswork
+ break;
+
+ case '}':
+ res->add(" \\}"); // More guesswork
+ break;
+
+ default:
+ mid=inp;
+ for (mid=inp; !isspace(*mid) && *mid!='('; mid++) ;
+ for (end=mid; *end!='('; end++)
+ {
+ if (*end=='\0')
+ break;
+ }
+ for (i=0; (unsigned) i<N(eqp); i++)
+ {
+ if (eqp[i].name==NULL)
+ {
+ inp=eqn_default(res, inp, end, mline, sty);
+ break;
+ }
+ l=strlen(eqp[i].name);
+ if (l!=mid-inp)
+ continue;
+ if (strncasecmp(eqp[i].name, inp, l)==0)
+ {
+ if ((inp=(*(eqp[i].func))(res, end+1,
+ mline, sty))!=NULL)
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ case '+':
+ case '-':
+ res->add(*inp);
+ break;
+ case '*':
+ res->add("\\times ");
+ break;
+
+ case ' ':
+ res->add("\\ ");
+ break;
+
+ case '_':
+ res->add("\\hbox{\\_}");
+ break;
+
+ default:
+ int flg=0;
+ const char *scn;
+
+ /*
+ * This section is meant to catch 72 dpi and render it as
+ * \hbox{72 dpi} but not catch 12 * 18 (which should become
+ * 12\times 18).
+ */
+ if (isdigit(*inp) || *inp=='-' || *inp=='+')
+ {
+
+ /* Scan forward to see what comes text */
+ scn=inp;
+ if (*scn=='-' || *scn=='+')
+ scn++; // Skip sign
+ while (scn<stop && isdigit(*scn))
+ scn++; // Skip number
+ if (*scn=='.')
+ {
+ scn++;
+ while (scn<stop && isdigit(*scn))
+ scn++; // Hanlde decimals number
+ }
+
+ /* Now start looking at what comes next */
+ while (scn<stop)
+ {
+ if (isspace(*scn))
+ {
+ scn++;
+ continue;
+ }
+ if (isupper(*scn) || islower(*scn))
+ flg=1;
+ else
+ flg=0;
+ break;
+ }
+ }
+
+ /*
+ * This section is meant to catch strings and render them nicely
+ * in a mbox.
+ */
+ if (islower(*inp) || isupper(*inp) || flg)
+ {
+ res->add("\\text{");
+ if (flg) // If flag set then add everything up to scn
+ {
+ while (inp<scn)
+ {
+ res->add(*inp);
+ inp++;
+ }
+ }
+
+ flg=0; // Re-use flg
+ while (inp<stop && (islower(*inp) || isupper(*inp)
+ || isspace(*inp)
+ || *inp=='_'
+ || *inp=='^'))
+ {
+ if (isspace(*inp))
+ {
+ flg=1;
+ inp++;
+ continue; // If space, just set the flag
+ }
+ if (flg)
+ res->add(' '); // If skiped a space, add one
+ flg=0; // Clear flag
+ if (*inp=='_' || *inp=='^')
+ res->add('\\');
+ res->add(*inp);
+ inp++;
+ }
+ res->add("} ");
+ inp--;
+ break;
+ }
+ res->add(*inp);
+ break;
+ }
+ inp++;
+ }
+ return res;
+}
+
+/* Equations --- need more examples here */
+static void equation(const char *txt, const docfmt *fmt, FILE *out,
+ void *d)
+{
+
+ static const cmap comment_map[]={ { '\n', "\n% (contd) % " } };
+ struct latex_data *dp;
+ tblock *cvt, eqn, *op;
+ const char *s;
+ int mline;
+
+ dp=(struct latex_data *) d;
+ cvt=map_string(txt, comment_map);
+ fprintf(out, "%%\n%% EMBED %s\n", (const char *) (*cvt));
+ delete(cvt);
+
+ for (mline=0, s=txt; *s!='\0'; s++)
+ {
+ if (*s=='\n')
+ {
+ mline=1;
+ break;
+ }
+ }
+ if (!mline)
+ eqn.add((dp->par_flg) ? "$" : "$$");
+ else
+ eqn.add("\\begin{eqnarray*}\n");
+ cvt=cvt_eqn(txt+3, txt+strlen(txt), mline, (dp->par_flg) ? Disp : Text);
+ eqn.add(*cvt);
+ delete(cvt);
+
+ if (!mline)
+ eqn.add((dp->par_flg) ? "$" : "$$%");
+ else
+ eqn.add("\n\\end{eqnarray*}\n");
+
+ op=word_wrap(eqn, "\n", "\n", fmt->maxline);
+ fputs((const char *) (*op), out);
+ fputc('\n', out);
+ delete(op);
+}
+
+
+
+/* Table of contents entries, used as a cue for stuff like sections */
+/* This code jus stashes it away for the paragraph code */
+static void add_contents(const char *txt, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ const char *open, *close;
+ tblock entry;
+ struct latex_data *dp;
+
+ fmt=fmt;
+ out=out;
+ dp=(struct latex_data *) d;
+ for (open=txt; *open!='"'; open++)
+ {
+ if (*open=='\0')
+ {
+ cerr<<"Found tc entry but no openning quote\n";
+ return;
+ }
+ }
+
+ for (close=open+1; *close!='"'; close++)
+ {
+ if (*close=='\0')
+ {
+ cerr<<"Found tc entry but no closing quote\n";
+ return;
+ }
+ }
+
+ if (close-open==1)
+ {
+ cerr<<"Ignoring empty table of contents entry\n";
+ return;
+ }
+
+ while (++open<close)
+ entry.add(*open);
+ if (dp->last_tc!=NULL)
+ free((void *) dp->last_tc);
+ dp->last_tc=strdup(entry);
+
+}
+
+static struct embed emb[]=
+{
+ { "tc ", 3, add_contents }, // Table of contents line
+ { "eq ", 3, equation }, // Equations
+};
+
+void ltx_embed(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ int i;
+
+ for (i=0; (unsigned) i<N(emb); i++)
+ {
+ if (strncmp(t->data.d, emb[i].key, emb[i].key_len)==0)
+ {
+ (emb[i].handle)(t->data.d, fmt, out, d);
+ return;
+ }
+ }
+ fprintf(out, "%%\n%% %s\n", t->data.d);
+}
diff --git a/support/word2x/latex-fmt.cc b/support/word2x/latex-fmt.cc
new file mode 100644
index 0000000000..1caf7fb4e2
--- /dev/null
+++ b/support/word2x/latex-fmt.cc
@@ -0,0 +1,537 @@
+/* $Id: latex-fmt.cc,v 1.15 1997/04/13 13:26:38 dps Exp dps $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+#include "interface.h"
+#include "lib.h"
+#include "latex-table.h"
+#include "fmt-latex.h"
+
+static const cmap tex_map[]=
+{
+ { '\n', "\\\\\n" }, // Newline
+ { 0x1E, "-" }, // Unbreakable join
+ { 0x1F, "\\-" }, // Soft hypen
+ { '#', "{\\#}" }, // #
+ { '$', "{\\$}" }, // $
+ { '%', "{\\%}" }, // % (5th element)
+ { '&', "{\\&}" }, // &
+ { '@', "{\\@}" }, // @
+ { '\\', "$\\backslash$" }, // backslash
+ { '^', "{\\^}" }, // ^
+ { '_', "{\\_}" }, // _ (10th element)
+ { '{', "{\\{}" }, // {
+ { '}', "{\\}}" }, // }
+ { '~', "{\\~}" }, // ~
+ { CH_SUSPECT, "" }, // Delete suspect data markers
+ { 0x85, "\\unskip\\ldots" }, // Dots
+ { 0x91, "{`}" }, // 91 = left quote (15th element)
+ { 0x92, "{'}" }, // 92 = right quote
+ { 0x93, "``" }, // 93 = opening double quote
+ { 0x94, "''" }, // 94 = closing double quote
+ { 0x96, "--" }, // em-dash
+ { 0x97, "---" }, // en-dash (20th element)
+ { 0x99, "${}^{\\rm TM}$" }, // Trademark
+ { 0xA0, "~" }, // Unbreakable space
+ { 0xA3, "$\\leq$" }, // <= came out as A3, also pounds
+ { 0xA9, "{\\copyright}" }, // Copyright
+ { 0xAB, "$<\\!\\!<$" }, // Openning << quotes (25th element)
+ { 0xAE, "{\\reg}" }, // reserved sign
+ { 0xB3, "$\\geq$" }, // Greater than or = came out as B3
+ { 0xBB, "$>\\!\\!>$" }, // Closing >> quotes (28th element)
+ { 0xDF, "{\\ss}" }, // beta
+ { 0xE4, "\\\"a" }, // a with umlualt
+ { 0xE9, "\\'e" }, // e grave??
+ { 0xF1, "\\=n" }, // n bar
+ { 0xF6, "\\\"o" }, // o with umlualt
+ { 0xFA, "\\.u" }, // u with dot?
+ { 0xFC, "\\\"u" }, // u with umlualt.
+
+};
+
+tblock *__latex_do_map(const char *s)
+{
+ tblock *out;
+
+ out=map_string(s, tex_map);
+ return out;
+}
+
+/* Preamble */
+static void preamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ time_t now;
+#ifdef HAVE_FSTAT
+ struct stat st;
+#endif
+ char *tnow, *tdoc;
+
+ t=t;
+ d=d;
+
+ now=time(NULL);
+ tnow=(fmt->date)(now);
+
+#ifdef HAVE_FSTAT
+ if (fstat(fileno(out), &st)==-1)
+ {
+ fprintf(stderr, "Warning: fstat failed\n");
+ st.st_mtime=now;
+ }
+ tdoc=fmt->date(st.st_mtime);
+#else
+ tdoc="date not known";
+#endif
+
+ fprintf(out,
+ "%% Generated by word2x on %s\n"
+ "%%\n"
+ "\\date{%s}\n"
+ "\\documentclass{article}\n"
+ "\\usepackage{amstext}\n"
+ "\\def\\reg{\\setbox0\\hbox{$\\mathchar\"20D$}%%\n"
+ "\\hbox to 0pt{\\hbox to \\wd0{\\hfill\\,\\rm R\\hfill}\\hss}%%\n"
+ "$\\mathchar\"20D$}\n"
+ "\\usepackage[latin1]{inputenc}\n"
+ "\\begin{document}\n",
+ tnow, tdoc);
+ free(tnow);
+ free(tdoc);
+}
+
+/* Postamble */
+static void postamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *dp;
+ fmt=fmt;
+ t=t;
+ dp=(struct latex_data *) d;
+
+ fputs("\\end{document}\n", out);
+}
+
+/* Allocate local data */
+static void *allocate_latex(void)
+{
+ struct latex_data *tdata;
+ int i;
+
+ tdata=new(struct latex_data);
+ tdata->tabl=NULL;
+ tdata->last_tc=NULL;
+ tdata->unit_d.unit_type=1;
+ tdata->list_flg=0;
+ for (i=0; i<4; i++)
+ tdata->unit_d.unit_number[i]=-1;
+ return tdata;
+}
+
+/* Free local data */
+static void free_latex(void *d)
+{
+ struct latex_data *tdata;
+
+ tdata=(struct latex_data *) d;
+ if (tdata->tabl!=NULL)
+ delete(tdata->tabl);
+
+}
+
+static void ltx_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ d=d;
+ switch(*(t->data.d))
+ {
+ case CH_PAGE:
+ if (fmt->flags.new_pages)
+ fputs("%\n\\newpage%\n", out);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* item */
+static void ltx_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *dp;
+ fmt=fmt;
+ t=t;
+ out=out;
+ dp=(struct latex_data *) d;
+
+ dp->list_flg=1;
+}
+
+
+/* start list */
+static void ltx_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ fmt=fmt;
+ d=d;
+
+ fprintf(out, "\n\\begin{%s}\n", t->data.d); // Prior argement with reader
+}
+
+/* end list */
+static void ltx_end_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ fmt=fmt;
+ d=d;
+
+ fprintf(out, "\n\\end{%s}\n", t->data.d); // Prior argement with reader
+}
+
+
+/* Find part number and return it or -1 if no number */
+int get_part_num(const char *st, const char *fence)
+{
+ int n;
+
+ while (st<fence)
+ {
+ if (isspace(*st))
+ {
+ st++;
+ continue;
+ }
+ if (isdigit(*st))
+ {
+ n=0;
+ while (st<fence && isdigit(*st))
+ {
+ n=n*10+(*st)-'0';
+ st++;
+ }
+ if (!isspace(*st))
+ return -1;
+ else
+ return n;
+
+ }
+ if (isupper(*st) && isspace(*(st+1)))
+ return (*st)-'A'+1;
+
+ /* Nothing else understood at this time */
+ return -1;
+ }
+ return -1;
+}
+
+
+
+
+
+/*
+ * Paragraphs are easy, but get complicated due to need to work out
+ * which things are actually chapter headings, etc
+ */
+static void fold_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ tblock *b, *ts, op;
+ const char *s, *t, *pt;
+ struct latex_data *dp;
+ int do_add, has_num, i, j;
+
+ static const char *const sects[]=
+ {
+ "chapter", "section", "subsection", "subsubsection"
+ };
+
+ dp=(struct latex_data *) d;
+ do_add=0;
+ dp->par_flg=1;
+
+ /* Even this much is under 100%!! */
+ pt=(tok->data.d);
+
+ if (*pt=='\0')
+ return;
+
+ if (dp->last_tc!=NULL)
+ {
+ if (strcmp(dp->last_tc, pt)==0)
+ {
+ op.add("\\addcontentsline{toc}{");
+ op.add(sects[dp->unit_d.unit_type]); op.add("}{");
+ op.add(dp->last_tc); op.add("}\n\\");
+ op.add(sects[dp->unit_d.unit_type]);
+ op.add("*{");
+ do_add=1;
+ }
+
+ else
+ {
+ s=dp->last_tc+strlen(dp->last_tc)-strlen(pt);
+ if (strcmp(s, pt)==0)
+ {
+ /* Find type */
+ for (i=0; i< (int) N(sects)-1; i++)
+ {
+ if (strncasecmp(dp->last_tc, sects[i],
+ strlen(sects[i]))==0)
+ break;
+ }
+ t=dp->last_tc+strlen(sects[i]);
+ has_num=get_part_num(t,s);
+ if (has_num==-1)
+ {
+ op.add("\\addcontentsline{toc}{");
+ op.add(sects[i]); op.add("}{");
+ op.add(dp->last_tc);
+ op.add("}\n");
+ }
+ op.add('\\');
+ op.add(sects[i]);
+ op.add((has_num!=-1) ? "{" : "*{");
+ if (dp->unit_d.unit_number[i]==-1)
+ {
+ dp->unit_d.unit_number[i]=(has_num==-1) ? 1 : has_num;
+ for (j=i+1; j< (int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ if (i< (int) N(sects)-1)
+ dp->unit_d.unit_type=i+1;
+ else
+ dp->unit_d.unit_type=i;
+ do_add=1;
+ }
+ }
+ free((void *) dp->last_tc);
+ dp->last_tc=NULL;
+ }
+ else
+ {
+ if (dp->list_flg)
+ {
+ op.add("\\item ");
+ }
+ else
+ {
+ if (strlen(pt)>0 && strlen(pt)<PAR_TRESHOLD_LEN)
+ {
+ if (strcasecmp(pt,"Appendix")==0)
+ {
+ op.add("\\appendix\n\\");
+ dp->unit_d.unit_type=(dp->unit_d.unit_number[0]==-1) ? 1:0;
+ op.add(sects[dp->unit_d.unit_type]);
+ op.add("{");
+ do_add=1;
+ for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ else if (strcasecmp(pt,"Bibliography")==0)
+ {
+ dp->unit_d.unit_type= (dp->unit_d.unit_number[0]==-1) ? 1:0;
+ op.add('\\');
+ op.add(sects[dp->unit_d.unit_type]);
+ op.add("*{");
+ do_add=1;
+ for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ else
+ {
+ int i,n,c,l, unit;
+
+ unit=dp->unit_d.unit_type-1;
+ l=strlen(pt);
+ i=0;
+ while(1)
+ {
+ n=0;
+ for (c=0; i<l && isdigit(pt[i]); i++, c++)
+ n=n*10+pt[i]-'0';
+ if (c==0)
+ break;
+ unit++;
+ if (unit>= (int) N(sects))
+ {
+ unit=N(sects)-1;
+ break;
+ }
+ if (dp->unit_d.unit_number[unit]==-1)
+ {
+ if (n>MAX_START_NUM)
+ goto out_normal;
+
+ dp->unit_d.unit_number[unit]=n;
+ for (j=unit+1; j< (int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ else if (dp->unit_d.unit_number[unit]+1==n)
+ {
+ dp->unit_d.unit_number[unit]++;
+ for (j=unit+1; j< (int) N(sects); j++)
+ dp->unit_d.unit_number[j]=0;
+ }
+ else if (dp->unit_d.unit_number[unit]!=n)
+ goto out_normal;
+
+ if (pt[i]!='.')
+ break;
+ i++;
+ }
+
+ if (unit==dp->unit_d.unit_type-1)
+ goto out_normal;
+ op.add('\\');
+ op.add(sects[unit]);
+ op.add((i>0) ? "{" : "*{");
+ while(isspace(pt[i])) i++;
+ pt+=i;
+ do_add=1;
+ }
+ }
+ out_normal: ;
+ }
+ dp->list_flg=0;
+ }
+
+ ts=map_string(pt, tex_map);
+ op.add(*ts);
+ if (do_add)
+ op.add('}');
+ delete(ts);
+
+ b=word_wrap(op, "\n", "\n", fmt->maxline, 0);
+ fputs((*b), out);
+ delete(b);
+}
+
+/* End of paragraph */
+static void end_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *dp;
+
+ tok=tok;
+ fmt=fmt;
+ dp=(struct latex_data *) d;
+ dp->par_flg=0;
+
+ fputs("\n\n", out);
+}
+
+/* Start a table === allocate table and initialise */
+static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ tdata=(struct latex_data *) d;
+ tdata->col=0;
+ tdata->row=0;
+ tdata->tabl=new(latex_table)(t->data.table.cols, t->data.table.rows);
+ tdata->par_flg=0;
+}
+
+
+/* End of a table==print the table */
+static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *tdata;
+
+ t=t;
+ tdata=(struct latex_data *) d;
+ tdata->tabl->print_table(fmt->maxline, out); // Print table
+ delete(tdata->tabl);
+ tdata->tabl=NULL;
+}
+
+/* start row==set column to 0 */
+static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct latex_data *) d;
+ tdata->col=0;
+}
+
+/* end row==add one to row */
+static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *tdata;
+
+ fmt=fmt;
+ t=t;
+ out=out;
+ tdata=(struct latex_data *) d;
+ tdata->row++;
+}
+
+
+/* Start field === set field */
+static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *tdata;
+
+ tdata=(struct latex_data *) d;
+ out=out;
+ fmt=fmt;
+ tdata->tabl->set(tdata->col, tdata->row, t->data.d);
+}
+
+/* end field==add one to col */
+static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct latex_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct latex_data *) d;
+ tdata->col++;
+}
+
+/* pointers to the functions that do the work */
+docfmt latexfmt=
+{
+ { 0 }, // Ignore page breaks
+ 76, // Width
+ "\n", // Use \n as line ends
+ allocate_latex, // Allocate space
+ free_latex, // Free text
+ {
+ { preamble, postamble }, // End and start of document---do nothing
+ { fold_para, end_para }, // Paragraph
+ { alloc_tbl, format_tbl }, // Start/end table
+ { set_field, inc_col }, // Start/end field
+ { start_row, inc_row }, // Start/end row
+ { ltx_embed, null_proc }, // Throw away embed messages
+ { ltx_list, ltx_end_list }, // Start/end list
+ { ltx_item, null_proc }, // Start/end item
+ { ltx_code, null_proc }, // Codes end do not happen
+ { null_proc, null_proc } // Do not understanding anything else
+ }
+};
diff --git a/support/word2x/latex-table.cc b/support/word2x/latex-table.cc
new file mode 100644
index 0000000000..486bd361ca
--- /dev/null
+++ b/support/word2x/latex-table.cc
@@ -0,0 +1,302 @@
+/* $Id: latex-table.cc,v 1.8 1997/04/13 13:27:29 dps Exp $ */
+/* Latex table layout */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* Do not have alloca.h */
+#ifdef _AIX
+ #pragma alloca
+#else /* not _AIX */
+extern "C" char *alloca(int);
+#endif /* _AIX */
+#endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include "tblock.h"
+#include "latex-table.h"
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+struct rdata
+{
+ struct wd_info w;
+ const char *data;
+};
+
+
+
+/* Print row after folding of columns has been done */
+static void basic_print_row(int ncols, const struct rdata *cols,
+ int maxw, FILE *out)
+{
+ const char *s;
+ int i, nsp, nz;
+ align_t al;
+ num_info n;
+ tblock output, *outp;
+
+ /* Print the content */
+ for (i=0; i<ncols; i++)
+ {
+
+ s=cols[i].data;
+ al=cols[i].w.align;
+ if (cols[i].w.dp_col>=0)
+ {
+ n=scan_num(s);
+ if (n.dot_pos!=-1)
+ {
+ nz=cols[i].w.dp_col-n.dot_pos;
+ if ((!n.has_sign) && (cols[i].w.has_sign))
+ {
+ output.add("\\phantom{$-$");
+ if (nz>0)
+ {
+ while (nz--)
+ output.add('0');
+ }
+ output.add("}");
+ }
+ else
+ {
+ if (n.has_sign)
+ nz++; // - does not count as a digit.
+ if (nz>0)
+ {
+ output.add("\\phantom{");
+ while (nz--)
+ output.add('0');
+ output.add("}");
+ }
+ }
+ if (n.has_sign)
+ {
+ /* Typeset the sign in math mode */
+ output.add('$');
+ output.add(*s);
+ output.add('$');
+ s++;
+ }
+ output.add(s);
+ if (nsp-cols[i].w.dp_col+n.dot_pos>0
+ && cols[i].w.align!=ALIGN_LEFT)
+ output.add("\\hfill");
+ al=ALIGN_DP;
+ }
+ }
+
+ switch(al)
+ {
+ case ALIGN_DP:
+ break;
+
+ case ALIGN_LEFT:
+ case ALIGN_CENTER:
+ case ALIGN_RIGHT:
+ output.add(s);
+ break;
+
+ default:
+ fprintf(stderr,"basic_print_row: Invalid alignment\n");
+ break;
+ }
+
+ if (i<ncols-1)
+ output.add(" & ", 3); // Seperate columns
+ }
+ output.add(" \n"); // converted to \\ \n by word_wrap.
+ outp=word_wrap((const char *) output, "\n", "\n", maxw, 0);
+ fputs((const char *) (*outp), out);
+ delete(outp);
+}
+
+extern tblock *__latex_do_map(const char *);
+/* Split the elements of a row */
+static void print_row(int ncols, const struct rdata *dp, int maxw, FILE *out)
+{
+ static const char null_string[]={'\0'};
+ struct rdata *rd;
+ tblock *d;
+ int i;
+
+ /* Allocate structures */
+ if ((rd=(struct rdata *) alloca(ncols*sizeof(rdata)))==NULL)
+ {
+ fprintf(stderr, "print_row: fatal alloca failure\n");
+ exit(1);
+ }
+
+ /* Convert data to *TeX */
+ for (i=0; i<ncols; i++)
+ {
+ rd[i].w=dp[i].w;
+ if (dp[i].data==NULL)
+ {
+ rd[i].data=null_string; // Avoid complication of null in
+ // basic_print_row
+ continue; // Move on to next item
+ }
+
+ d=__latex_do_map(dp[i].data);
+ if ((rd[i].data=strdup(*d))==NULL)
+ {
+ fprintf(stderr, "latex_table::print_row: fatal alloca failure\n");
+ exit(1);
+ }
+ delete(d);
+ }
+ basic_print_row(ncols, rd, maxw, out); // Printing the rows is actually
+ // quite complex.
+ for (i=0; i<ncols; i++)
+ {
+ if (rd[i].data!=null_string)
+ free((void *) rd[i].data); // Free data
+ }
+}
+
+
+
+/* Returns NULL or text message */
+const char *latex_table::print_table(int wd, FILE *out, const int ruled)
+{
+ int i,j;
+ struct rdata *d;
+ const struct col_info *col;
+
+ if ((d=(struct rdata *) alloca(cols*sizeof(struct rdata)))==NULL)
+ {
+ cerr<<"latex_table::print_table alloca failute (fatal)\n";
+ return "[Table omitted due to lack of memory]";
+ }
+ if (cols==0 || rows==0)
+ {
+ fputs("[empty tabel ignored]\n", out);
+ return "[Ignored empty table]";
+ }
+
+ for (i=0, col=cdata; col!=NULL; i++, col=col->next)
+ d[i].w=find_width(rows, col->data);
+
+ fputs("\\begin{tabular}{", out);
+ for (i=0; i<cols; i++)
+ {
+ if (ruled)
+ fputc('|', out);
+ switch(d[i].w.align)
+ {
+ default:
+ cerr<<"Alignment "<<d[i].w.align<<" unsupported\n";
+ /* Fall through */
+
+ case ALIGN_LEFT:
+ fputc('l', out);
+ break;
+
+ case ALIGN_CENTER:
+ fputc('c', out);
+ break;
+
+ case ALIGN_RIGHT:
+ fputc('r', out);
+ break;
+ }
+ }
+ fprintf(out, "%s}%s\n", (ruled) ? "|" : "", (ruled) ? "\\hline " : "");
+
+ for (i=0; i<rows; i++)
+ {
+ for (j=0, col=cdata; col!=NULL; j++, col=col->next)
+ d[j].data=(col->data)[i];
+ print_row(cols, d, wd, out);
+ if (i==0)
+ fputs("\\hline\n", out);
+ }
+
+ fprintf(out, "%s\\end{tabular}\\\\\n", (ruled) ? "\\hline " : "");
+ return NULL;
+}
+
+/* Set */
+int latex_table::set(int c, int r, const char *s)
+{
+ struct col_info *col;
+ int i;
+
+ if (c<0 || c>=cols || r<0 || r>=rows)
+ {
+ cerr<<"Invalid request to set "<<c<<','<<r<<" in "
+ <<cols<<'x'<<rows<<" table (value "<<s<<")\n";
+ return 0;
+ }
+
+ for (col=cdata, i=0; i<c && col!=NULL; i++, col=col->next) ;
+ if (col!=NULL)
+ {
+ if (col->data[r]!=NULL)
+ free((void *) col->data[r]);
+ col->data[r]=strdup(s);
+ }
+ return 1;
+}
+
+
+/* Constructor */
+latex_table::latex_table(int c, int r)
+{
+ int i, j;
+ struct col_info *col, **nptr;
+
+ cols=c;
+ rows=r;
+ cdata=NULL; // Hardenning against cols=0
+ for (nptr=&cdata, i=0; i<cols; i++)
+ {
+ col=new(struct col_info);
+ *nptr=col;
+ col->next=NULL;
+ nptr=&(col->next);
+ if ((col->data=
+ (const char **) malloc(rows*(sizeof(const char *))))==NULL)
+ {
+ cerr<<"latex_table::constructor: malloc failure (fatal)\n";
+ exit(1);
+ }
+ for (j=0; j<rows; j++)
+ (col->data)[j]=NULL;
+ }
+}
+
+/* Destructor */
+latex_table::~latex_table()
+{
+ int i;
+ struct col_info *col, *nxt;
+
+ for (col=cdata; col!=NULL;)
+ {
+ for (i=0; i<rows; i++)
+ if (col->data[i]==NULL)
+ free((void *) col->data[i]);
+ nxt=col->next;
+ free(col);
+ col=nxt;
+ }
+}
+
+
+
diff --git a/support/word2x/latex-table.h b/support/word2x/latex-table.h
new file mode 100644
index 0000000000..5938cc7111
--- /dev/null
+++ b/support/word2x/latex-table.h
@@ -0,0 +1,27 @@
+/* $Id: latex-table.h,v 1.1 1997/03/24 02:36:39 dps Exp $ */
+
+#ifndef __latex_table__
+#define __latex_table__
+#include <stdio.h>
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+class latex_table
+{
+private:
+ struct col_info
+ {
+ const char **data;
+ struct col_info *next;
+ };
+ int cols;
+ int rows;
+ struct col_info *cdata;
+
+public:
+ const char *print_table(int, FILE *, const int =1);
+ int set(int, int, const char *);
+ latex_table(int, int);
+ ~latex_table(void);
+};
+#endif /* __latex_table__ */
diff --git a/support/word2x/lib.h b/support/word2x/lib.h
new file mode 100644
index 0000000000..5c6236b207
--- /dev/null
+++ b/support/word2x/lib.h
@@ -0,0 +1,116 @@
+/* $Id: lib.h,v 1.21 1998/02/17 12:27:18 dps Exp $ */
+
+#ifndef __word2x_lib_h__
+#define __word2x_lib_h__
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+#include "tblock.h"
+#include "interface.h"
+#endif /* __cplusplus */
+
+
+/* Maximum section number */
+#define MAX_START_NUM 100
+
+typedef struct
+{
+ int wd[2];
+ int dot_pos;
+ int has_sign;
+} num_info;
+
+typedef enum { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_DP } align_t;
+
+struct wd_info
+{
+ int width;
+ int dp_col;
+ int has_sign;
+ align_t align;
+};
+
+/* Unit information */
+struct unit_info
+{
+ int unit_type;
+ int unit_number[NUNITS];
+};
+
+/* Numbered unit probing */
+struct unit_number
+{
+ int unit_num;
+ int offset;
+};
+
+#ifndef N
+#define N(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+
+/*
+ * Functions that need only C stuff are declared as C linkage here
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct wd_info find_width(int, const char *const *);
+extern num_info scan_num(const char *);
+extern struct unit_number n_unit_probe(const char *, struct unit_info *);
+extern int get_part_num(const char *, const char *);
+
+#ifndef HAVE_STRCASECMP
+extern int strcasecmp(const char *s, const char *t);
+#endif /* HAVE_STRCASECMP */
+#ifndef HAVE_STRNCASECMP
+extern int strncasecmp(const char *s, const char *t, int n);
+#endif /* HAVE_STRNCASECMP */
+#ifndef HAVE_STRDUP
+extern char *strdup(const char *s);
+#endif /* HAVE_STRDUP */
+
+/* Date formats */
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif /* HAVE_TIME_H */
+extern char *uk_date(time_t);
+extern char *us_date(time_t);
+extern char *de_date(time_t);
+extern char *deHTML_date(time_t);
+extern char *deL1_date(time_t);
+
+/* Basic stuff for reading numbers from files */
+extern unsigned long read_ulong(FILE *);
+extern long read_long(FILE *);
+extern short read_ushort(FILE *);
+extern unsigned short read_short(FILE *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+#ifndef N
+#define N(x) (sizeof(x)/sizeof(x[0]))
+#endif /* N */
+#include "tblock.h"
+#include "reader.h"
+
+#ifndef __EXCLUDE_READER_CLASSES
+extern void null_proc(const tok_seq::tok *, const docfmt *, FILE *, void *);
+extern void error_proc(const tok_seq::tok *, const docfmt *, FILE *, void *);
+#endif /* __EXCLUDE_READER_CLASSES */
+extern tblock *word_wrap(const char *, const char *,const char *, const int,
+ const int=0);
+extern tblock *__map_string(const char *, const cmap *, int);
+#define map_string(a,b) __map_string(a, b, N(b));
+#endif /* __cplusplus */
+
+#endif /* __word2x_lib_h__ */
diff --git a/support/word2x/liboutfmt.a b/support/word2x/liboutfmt.a
new file mode 100644
index 0000000000..d535d30bb7
--- /dev/null
+++ b/support/word2x/liboutfmt.a
Binary files differ
diff --git a/support/word2x/map_chars.cc b/support/word2x/map_chars.cc
new file mode 100644
index 0000000000..f3b112f2ce
--- /dev/null
+++ b/support/word2x/map_chars.cc
@@ -0,0 +1,57 @@
+/* $Id: map_chars.cc,v 1.2 1997/03/23 13:19:26 dps Exp $ */
+
+#include "tblock.h"
+#ifndef NULL
+#define NULL (void *) 0
+#endif
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+
+static const char *map_char(unsigned char s, const cmap *map, int n)
+{
+ int l, m, r;
+
+ l=0;
+ r=n-1;
+ while (l<=r)
+ {
+ m=(l+r)/2;
+ if (map[m].win==s)
+ return map[m].ascii;
+ if (map[m].win<s)
+ l=m+1;
+ if (map[m].win>s)
+ r=m-1;
+ }
+ return NULL;
+}
+
+tblock *__map_string(const char *s, const cmap *map, int map_size)
+{
+ const char *scan, *sptr;
+ tblock *res;
+
+ res=new(tblock);
+ scan=s;
+ while (*scan!='\0')
+ {
+ if ((sptr=map_char(*scan, map, map_size))==NULL)
+ {
+ scan++;
+ continue;
+ }
+ if (scan!=s)
+ res->add(s, scan-s);
+ res->add(sptr);
+ scan++;
+ s=scan;
+ }
+ if (scan!=s)
+ res->add(s, scan-s);
+
+ return res;
+}
+
+
+
diff --git a/support/word2x/nullproc.cc b/support/word2x/nullproc.cc
new file mode 100644
index 0000000000..9b2ae02d9a
--- /dev/null
+++ b/support/word2x/nullproc.cc
@@ -0,0 +1,12 @@
+/* $Id: nullproc.cc,v 1.1 1997/03/16 20:35:30 dps Exp $ */
+/* Do nothing function for ignoring actions */
+#include "lib.h"
+
+/* Do nothing process, handy for cases where we feel no need to act */
+void null_proc(const tok_seq::tok *t, const docfmt *fmt, FILE *out, void *v)
+{
+ fmt=fmt;
+ t=t;
+ out=out;
+ v=v;
+}
diff --git a/support/word2x/num_unit_probe.c b/support/word2x/num_unit_probe.c
new file mode 100644
index 0000000000..d1016fb43a
--- /dev/null
+++ b/support/word2x/num_unit_probe.c
@@ -0,0 +1,67 @@
+/* $Id: num_unit_probe.c,v 1.1 1997/04/22 20:32:17 dps Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+struct unit_number n_unit_probe(const char *txt, struct unit_info *dp)
+{
+ int i,j,n,c,l,unit;
+ struct unit_number u_num;
+
+ u_num.unit_num=-1;
+ unit=dp->unit_type-1;
+ l=strlen(txt);
+ i=0;
+ while(1)
+ {
+ n=0;
+ for (c=0; i<l && isdigit(txt[i]); i++, c++)
+ n=n*10+txt[i]-'0';
+ if (c==0)
+ break;
+ unit++;
+ if (unit>=NUNITS)
+ {
+ unit=NUNITS-1;
+ break;
+ }
+ if (dp->unit_number[unit]==-1)
+ {
+ if (n>MAX_START_NUM)
+ return u_num;
+
+ dp->unit_number[unit]=n;
+ for (j=unit+1; j<NUNITS; j++)
+ dp->unit_number[j]=0;
+ }
+ else if (dp->unit_number[unit]+1==n)
+ {
+ dp->unit_number[unit]++;
+ for (j=unit+1; j<NUNITS; j++)
+ dp->unit_number[j]=0;
+ }
+ else if (dp->unit_number[unit]!=n)
+ return u_num;
+
+ if (txt[i]!='.')
+ break;
+ i++;
+ }
+
+ if (unit==dp->unit_type-1)
+ return u_num;
+ u_num.unit_num=unit;
+ u_num.offset=i;
+ return u_num;
+}
diff --git a/support/word2x/part_num_probe.c b/support/word2x/part_num_probe.c
new file mode 100644
index 0000000000..61f38e254f
--- /dev/null
+++ b/support/word2x/part_num_probe.c
@@ -0,0 +1,45 @@
+/* $Id: part_num_probe.c,v 1.1 1997/04/25 17:53:00 dps Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+
+/* Find part number and return it or -1 if no number */
+int get_part_num(const char *st, const char *fence)
+{
+ int n;
+
+ while (st<fence)
+ {
+ if (isspace(*st))
+ {
+ st++;
+ continue;
+ }
+ if (isdigit(*st))
+ {
+ n=0;
+ while (st<fence && isdigit(*st))
+ {
+ n=n*10+(*st)-'0';
+ st++;
+ }
+ if (!isspace(*st))
+ return -1;
+ else
+ return n;
+
+ }
+ if (isupper(*st) && isspace(*(st+1)))
+ return (*st)-'A'+1;
+
+ if (islower(*st) && isspace(*(st+1)))
+ return (*st)-'a'+1;
+
+ /* Nothing else understood at this time */
+ return -1;
+ }
+ return -1;
+}
diff --git a/support/word2x/reader.cc b/support/word2x/reader.cc
new file mode 100644
index 0000000000..cf5ed66a33
--- /dev/null
+++ b/support/word2x/reader.cc
@@ -0,0 +1,1246 @@
+/* $Id: reader.cc,v 1.27 1997/04/17 20:24:41 dps Exp $ */
+/* Reads the word document */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* Do not have alloca.h */
+#ifdef _AIX
+ #pragma alloca
+#else /* not _AIX */
+extern "C" char *alloca(int);
+#endif /* _AIX */
+#endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+#include <iostream.h>
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include "word6.h"
+#include "interface.h"
+#include "reader.h"
+
+/* This code is basically a layered filtration process. At the bottom layer
+ is this next function that reads a character from a word document. Pointers
+ to object are used extensively to avoid implicit copies. */
+
+/* Please be aware that the junk should be stripped from in */
+static int read_character(istream *in)
+{
+ unsigned char c,d;
+ static int s_ch=-1;
+
+ if (s_ch==-1)
+ {
+ if (in->eof())
+ return EOF;
+
+ in->get(c);
+ }
+ else
+ {
+ c=(unsigned char) s_ch;
+ s_ch=-1;
+ }
+
+ if (c=='\n')
+ c='\r';
+
+ switch(c)
+ {
+ case PAR_END:
+ return (CH_PAR | CONTROL_FLAG);
+
+ case TABLE_SEP:
+ if (!in->eof())
+ in->get(d);
+ else
+ d=c+1; // Not equal to c
+ if (d!=c)
+ {
+ s_ch=d; /* Push back character */
+ return (CH_FIELD | CONTROL_FLAG);
+ }
+ return (CH_ROW | CONTROL_FLAG);
+
+ case START_CTL:
+ return (CH_SPEC | CONTROL_FLAG);
+
+ case END_CTL:
+ return (CH_ENDSPEC | CONTROL_FLAG);
+
+ case HARD_RETURN:
+ return (CH_HDRTN | CONTROL_FLAG);
+
+ case NEW_PAGE:
+ return (CH_PAGE | CONTROL_FLAG);
+
+ case FOOTNOTE:
+ return (CH_FOOTNOTE | CONTROL_FLAG);
+
+ default:
+ if (c<' ')
+ return (CH_OTHER | CONTROL_FLAG);
+ else
+ return c;
+ }
+ /* NOT REACHED */
+}
+
+
+/* This function reads a paragraph, field of a table or whatever. It copies
+ everything in any embed tags unprocessed and leaves it in the element */
+void chunk_reader::read_chunk_raw(void)
+{
+ int c, is_ctl=0;
+
+ text.zero(); // Zero text buffer
+ while ((c=read_character(in))!=(EOF | CONTROL_FLAG))
+ {
+ if (c & CONTROL_FLAG)
+ {
+ c &= ~CONTROL_FLAG;
+ /* If in embedded item then ignore all but end embed */
+ if (is_ctl)
+ {
+ if (c==CH_ENDSPEC)
+ {
+ is_ctl=0;
+ text.add(c);
+ }
+ continue;
+ }
+
+ switch(c)
+ {
+ case CH_PAR:
+ case CH_FIELD:
+ case CH_ROW:
+ break;
+
+ case CH_HDRTN:
+ text.add('\n'); // Add newline
+ continue; // Continue processing
+
+ case CH_OTHER:
+ continue; // Just ignore character
+
+ case CH_SPEC:
+ text.add(c);
+ if (!is_ctl)
+ is_ctl=1;
+ continue;
+
+ case CH_ENDSPEC:
+ cerr<<"Suprious ^U ignored\n";
+ continue;
+
+ case CH_PAGE:
+ case CH_FOOTNOTE:
+ text.add(c);
+ continue;
+
+ default:
+ cerr<<"Unexpected value "<<(c & (~CONTROL_FLAG))\
+ <<" switch\n";
+ continue;
+ }
+ type=c;
+ tptr=text;
+ return;
+ }
+ /* Not control or end of inclusion */
+ text.add(c);
+ }
+ type=CH_EOF;
+ tptr=text;
+ return;
+}
+
+
+/* This function reads chunks from using read_chunk_raw and hands them
+ out in contigous peices of the same type. Emebedded stuff gets
+ seperated from the rest here. The partial flag is set if only some
+ of a field is returned (usually because of an embedded item).
+*/
+struct chunk_rtn chunk_reader::read_chunk(void)
+{
+ const char *s; // Save stupid compilers
+ struct chunk_rtn res;
+
+ if (tptr==NULL)
+ this->read_chunk_raw();
+
+ s=tptr;
+
+ /* Embed */
+ if (*s==CH_SPEC)
+ {
+ while (*(++s))
+ {
+ if (*s==CH_ENDSPEC)
+ break;
+ res.txt.add(*s);
+ }
+ tptr=s+1;
+ res.type=CH_SPEC;
+ return res;
+ }
+
+ /* New page */
+ if (*s==CH_PAGE)
+ {
+ res.type=CH_PAGE;
+ tptr=s+1;
+ return res;
+ }
+
+ if (*s==CH_FOOTNOTE)
+ {
+ res.type=CH_FOOTNOTE;
+ tptr=s+1;
+ return res;
+ }
+
+ /* Normal */
+ while (*s)
+ {
+ if (*s==CH_SPEC || *s==CH_PAGE || *s==CH_FOOTNOTE)
+ {
+ tptr=s;
+ res.type=(PART_FLAG | type);
+ return res;
+ }
+
+ res.txt.add(*s);
+ s++;
+ }
+ res.type=type;
+ tptr=NULL;
+ text.zero(); // Save memory
+ return res;
+}
+
+
+
+/*----------------------------------------------------------------------*/
+/* Tables and basic stuff */
+
+/*
+ * Refill the token queue.
+ */
+int tok_seq::rd_token(void)
+{
+ struct chunk_rtn r;
+ tok *t;
+ char other[2];
+
+ r=read_chunk();
+ if (r.type==CH_EOF)
+ return 0;
+
+ switch(r.type & ~PART_FLAG)
+ {
+ case CH_ROW:
+ if (table==NULL)
+ table=new(table_info);
+ /* Handle 1 field rows properly */
+ if (table->col==0)
+ {
+ t=new(tok)(T_ROW, (void *) NULL, tok::TOK_START);
+ table->enqueue(t);
+ }
+ table->col++;
+ if (table->col>table->cols)
+ table->cols=table->col;
+ table->rows++;
+ table->tok_push(T_FIELD, &(r.txt));
+ t=new(tok)(T_ROW, (void *) NULL, tok::TOK_END);
+ table->enqueue(t);
+ table->col=0;
+ break;
+
+ case CH_FIELD:
+ if (table==NULL)
+ {
+ table=new(table_info);
+ }
+ if (table->col==0)
+ {
+ t=new(tok)(T_ROW, (void *) NULL, tok::TOK_START);
+ table->enqueue(t);
+ }
+ table->col++;
+ table->tok_push(T_FIELD, &(r.txt));
+ break;
+
+
+ case CH_PAR:
+ if (table!=NULL)
+ {
+ /* Table handling */
+ if (table->col!=0)
+ {
+#if 0
+ table->tok_push(T_FIELD, &(r.txt));
+ t=new(tok)(T_ROW, (void *) NULL, tok::TOK_END);
+ table->enqueue(t);
+ t=new(tok)(T_ROW, (void *) NULL, tok::TOK_START);
+ table->enqueue(t);
+ for (i=0; i<table->col; i++)
+ {
+ t=new(tok)(T_FIELD, "\0", tok::TOK_START);
+ table->enqueue(t);
+ t=new(tok)(T_FIELD, (void *) NULL, tok::TOK_END);
+ table->enqueue(t);
+ }
+ table->rows++;
+ break;
+#else
+ t=new(tok)(T_ROW, (void *) NULL, tok::TOK_END);
+ table->enqueue(t);
+ if (table->col>table->cols)
+ table->cols=table->col;
+ table->rows++;
+#endif
+ }
+ table->finish(&output);
+ delete(table);
+ table=NULL;
+ }
+
+ if (r.type & PART_FLAG)
+ {
+ tok *td;
+ td=new(tok)(T_PARAGRAPH, (const char *) (r.txt), tok::TOK_START);
+ output.enqueue(td);
+ }
+ else
+ tok_push(T_PARAGRAPH, &(r.txt));
+ break;
+
+ case CH_SPEC:
+ tok_push(T_SPEC, &(r.txt));
+ break;
+
+ case CH_PAGE:
+ case CH_FOOTNOTE:
+ other[0]=r.type;
+ other[1]='\0';
+ t=new(tok)(T_CODE, other, tok::TOK_START);
+ output.enqueue(t);
+ break;
+
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+
+
+/*----------------------------------------------------------------------*/
+/* Equations.... */
+
+/*
+ * Code that scans forward to the end of stuff that looks like an extension
+ * of some maths that was the last thing.
+ */
+const char *math_forward_scan(const char *s)
+{
+ const char *scan, *end;
+ int blvl;
+
+ end=scan=s;
+
+ /* Check whether the first part looks like more of the equation */
+ while (1)
+ {
+ /* Skip spaces */
+ while (isspace(*scan))
+ scan++;
+
+ /* Look for binary operator */
+ if (*scan=='+' || *scan=='-' || *scan=='*' || *scan=='/' ||
+ *scan=='=')
+ {
+ /* skip spaces */
+ scan++;
+ while (isspace(*scan))
+ scan++;
+
+ /* Grab next word */
+ blvl=0;
+ while (!isspace(*scan) || blvl>0)
+ {
+ switch(*scan)
+ {
+ case '(':
+ blvl++;
+ break;
+
+ case ')':
+ blvl--;
+ break;
+
+ default:
+ break;
+ }
+ if (*scan=='\0')
+ break; // Robustness fix
+ scan++;
+ }
+
+ end=scan; // Update end
+ }
+ else
+ break; // No binary operator, assume no text
+ }
+ return end;
+}
+
+/*
+ * Code that scans backwards to the start of stuff that looks like it should
+ * ohave been prepended to the current maths.
+ */
+const char *math_reverse_scan(const char *s)
+{
+ const char *scan, *start;
+ int blvl;
+
+ start=scan=s+strlen(s)-1;
+
+ /* Check whether the first part looks like more of the equation */
+ while (scan>=s)
+ {
+ /* Skip spaces */
+ while (scan>=s && isspace(*scan))
+ scan--;
+ if (scan<s)
+ return s;
+
+ /* Look for binary operator */
+ if (*scan=='+' || *scan=='-' || *scan=='*' || *scan=='/' ||
+ *scan=='=')
+ {
+ /* skip spaces */
+ scan--;
+ while (scan>=s && isspace(*scan))
+ scan--;
+ if (scan<s)
+ return s;
+
+ /* Grab next word */
+ blvl=0;
+ while (!isspace(*scan) || blvl>0 )
+ {
+ switch(*scan)
+ {
+ case ')':
+ blvl++;
+ break;
+
+ case '(':
+ blvl--;
+ break;
+
+ default:
+ break;
+ }
+ if (scan==s)
+ return s; // Robustness fix
+ scan--;
+ }
+ start=scan; // Update end
+ }
+ else
+ break; // No binary operator, assume no text
+ }
+ return start;
+}
+
+/*
+ * Code to feed a token one at a time. (private, need prostproccessing
+ * to compensate for equation abuse by word users)
+ */
+const tok_seq::tok *tok_seq::feed_token(void)
+{
+ while (output.is_empty())
+ {
+ if (!rd_token())
+ return NULL;
+ }
+ return output.dequeue();
+}
+
+/* Private token reader, compensates for equation abuse */
+const tok_seq::tok *tok_seq::math_collect(void)
+{
+ const tok *rdt, *ntok, *nntok;
+ const char *mptr, *endptr;
+ char *s, *t;
+
+ math_aggregate: ;
+ if ((rdt=this->saved_tok)==NULL)
+ {
+ if ((rdt=this->feed_token())==NULL)
+ return NULL;
+ }
+ else
+ saved_tok=NULL;
+
+ switch (rdt->tokval & (~PART_FLAG))
+ {
+ case T_PARAGRAPH:
+ if (rdt->end!=tok::TOK_START || (rdt->tokval & PART_FLAG==0)
+ || rdt->data.d==NULL)
+ break;
+ if ((ntok=this->feed_token())==NULL)
+ break;
+ /* Passed all the easy rejection cases, invoke math_reverse_scan */
+ saved_tok=ntok;
+ if (ntok->tokval==T_SPEC && ntok->end==tok::TOK_START &&
+ ntok->data.d!=NULL && strncmp(ntok->data.d, "eq ", 3)==0)
+ {
+ mptr=math_reverse_scan(rdt->data.d);
+ endptr=rdt->data.d+strlen(rdt->data.d)-1;
+ if (mptr>=endptr)
+ break;
+ /* Allocate memory */
+ if ((s=(char *) malloc(mptr-rdt->data.d+1))==NULL)
+ {
+ cerr<<"Malloc read_token::malloc failure (fatal)\n";
+ exit(1);
+ }
+ if ((t=(char *) malloc(strlen(ntok->data.d)+endptr-mptr+1))==NULL)
+ {
+ free((void *) s);
+ cerr<<"Malloc read_token::malloc failure (fatal)\n";
+ exit(1);
+ }
+ /* Compute result strings */
+ memcpy(s, rdt->data.d, mptr-rdt->data.d);
+ *(s+(mptr-rdt->data.d))='\0';
+ memcpy(t, ntok->data.d, 3);
+ memcpy(t+3, mptr, endptr-mptr+1);
+ strcpy(t+3+(endptr-mptr)+1, ntok->data.d+3);
+ /* Replace original data */
+ free((void *) rdt->data.d);
+ ((tok *) rdt)->data.d=s;
+ free((void *) ntok->data.d);
+ ((tok *) ntok)->data.d=t;
+ }
+ break;
+
+
+ case T_SPEC:
+ if (rdt->end!=tok::TOK_START || rdt->data.d==NULL ||
+ strncmp(rdt->data.d, "eq ", 3)!=0)
+ break;
+ if ((nntok=this->feed_token())==NULL)
+ break; // this is the end of the SPEC.
+ if (nntok->tokval!=T_SPEC || nntok->end!=tok::TOK_END)
+ {
+ cerr<<"Unexpected value of nntok: type "
+ <<nntok->tokval<<" end "<<nntok->end<<"\n";
+ }
+ if ((ntok=this->feed_token())==NULL)
+ {
+ output.insert(nntok);
+ break;
+ }
+ /* Passed all the easy rejection cases, invoke math_forward_scan */
+ saved_tok=ntok;
+ if (ntok->tokval==T_PARAGRAPH && ntok->end!=tok::TOK_END &&
+ ntok->data.d!=NULL)
+ {
+ mptr=math_forward_scan(ntok->data.d);
+ endptr=ntok->data.d+strlen(ntok->data.d);
+ if (mptr==ntok->data.d)
+ {
+ output.insert(ntok); // This comes out second
+ output.insert(nntok);
+ saved_tok=NULL;
+ break;
+ }
+ /* Allocate memory */
+ if (*mptr!='\0')
+ {
+ if ((s=(char *) malloc(endptr-mptr))==NULL)
+ {
+ cerr<<"Malloc read_token::malloc failure (fatal)\n";
+ exit(1);
+ }
+ memcpy(s, mptr, endptr-mptr);
+ *(s+(endptr-mptr))='\0';
+ }
+ else
+ s=NULL;
+
+ if ((t=(char *)
+ malloc(strlen(rdt->data.d)+mptr-ntok->data.d+1))==NULL)
+ {
+ if (s!=NULL)
+ free((void *) s);
+ cerr<<"Malloc read_token::malloc failure (fatal)\n";
+ exit(1);
+ }
+ endptr=rdt->data.d+strlen(rdt->data.d);
+ memcpy(t, rdt->data.d, endptr-rdt->data.d);
+ memcpy(t+(endptr-rdt->data.d), ntok->data.d, mptr-ntok->data.d);
+ *(t+(endptr-rdt->data.d)+(mptr-ntok->data.d))='\0';
+ /* Afjust result */
+ free((void *) rdt->data.d);
+ ((tok *) rdt)->data.d=t;
+ if (*mptr=='\0')
+ {
+ /* If we consumed 100% continue seeking */
+ delete(ntok);
+ saved_tok=rdt;
+ output.insert(nntok); // Re-insert end of spec.
+ goto math_aggregate;
+ }
+ free((void *) ntok->data.d);
+ ((tok *) ntok)->data.d=s;
+ /* Not all consumed, return result */
+ }
+ else if (ntok->tokval==T_SPEC && ntok->end==tok::TOK_START &&
+ ntok->data.d!=NULL && strncmp(ntok->data.d, "eq ", 3)==0)
+ {
+ /* Combine consecutive eq's */
+ endptr=rdt->data.d+strlen(rdt->data.d);
+ if ((t=(char *)
+ malloc((endptr-rdt->data.d)+strlen(ntok->data.d)-2))==NULL)
+ {
+ cerr<<"Malloc read_token::malloc failure (fatal)\n";
+ exit(1);
+ }
+ memcpy(t, rdt->data.d, endptr-rdt->data.d);
+ strcpy(t+(endptr-rdt->data.d), ntok->data.d+3);
+ delete(nntok); // Reply on end of spec following this eq
+ delete(ntok); // Junk this eq
+ free((void *) rdt->data.d);
+ ((tok *) rdt)->data.d=t;
+ saved_tok=rdt;
+ goto math_aggregate;
+ }
+ output.insert(ntok); // This comes out second
+ output.insert(nntok);
+ saved_tok=NULL;
+ break;
+
+
+ default:
+ break;
+ }
+ return rdt;
+}
+
+
+/* Private choke point between equations and lists token reader */
+const tok_seq::tok *tok_seq::eqn_rd_token(void)
+{
+ const tok *t, *n;
+ fifo<tok> *tf;
+ int tot, specs;
+
+ if ((t=this->math_collect())==NULL)
+ return NULL;
+
+ switch(t->tokval)
+ {
+ case T_PARAGRAPH:
+ if (t->end!=tok::TOK_START)
+ return t;
+ /* Check for spec only paragraph */
+
+ tf=new(fifo<tok>);
+ n=t;
+ tot=0;
+ specs=0;
+ /*
+ * This loop counts the number of characters in paragraphs and other
+ * items untilt the end of the paragraph. Each item is dumped on tf
+ * and this is inserted onto the beginning of the output queue.
+ */
+ while(1)
+ {
+ tf->enqueue(n);
+ if (n->tokval==T_PARAGRAPH)
+ {
+ if (n->end==tok::TOK_END)
+ break;
+ if (n->data.d!=NULL)
+ tot+=strlen(n->data.d);
+ if (tot>DISPL_TRESHOLD)
+ break;
+ }
+ else
+ specs++;
+
+ if (n->tokval!=T_SPEC && n->tokval!=T_OTHER && n->tokval!=T_PARAGRAPH)
+ {
+ tot+=DISPL_TRESHOLD;
+ break;
+ }
+ if ((n=this->math_collect())==NULL)
+ break;
+ }
+ /*
+ * If the total is small enough and there is one or more item that
+ * will make it through the filter. Since insert()ed things end up
+ * in reverse order we must first reverse the queue (this is the
+ * uncommon case, so it is OK if it costs a bit more).
+ */
+ if (tot<DISPL_TRESHOLD && specs>0)
+ {
+ tf->rev();
+ while ((n=tf->dequeue())!=NULL)
+ {
+ if (n->tokval!=T_PARAGRAPH)
+ output.insert(n);
+ else
+ delete(n);
+ }
+ }
+ else
+ {
+ output.ins_trans(tf);
+ }
+ delete(tf);
+ t=output.dequeue();
+ break;
+
+ default:
+ break;
+ }
+
+ return t;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* Now move on to lists.... */
+
+/* Return NULL or a new list record */
+struct tok_seq::list_info *tok_seq::list_type(const char *txt)
+{
+ struct list_info *nl;
+ int i,n;
+
+ /* Determine initial number, if any */
+ if (!isdigit(txt[0]))
+ n=-1;
+ else
+ {
+ n=i=0;
+ for (n=0, i=0; isdigit(txt[i]); i++)
+ n=n*10+txt[i]-'0';
+ }
+
+ if (n==1)
+ {
+ nl=new(struct list_info);
+ nl->list_type=LIST_ENUMERATE;
+ nl->ldata.item_no=0;
+ nl->obj_cnt=0;
+ nl->text_cnt=0;
+ nl->last_item=new(fifo<tok_seq::tok>);
+ nl->items=0;
+ return nl;
+ }
+
+ /* a., b., c. */
+ if (txt[0]=='a')
+ {
+ i=(txt[1]=='.') ? 2 : 1;
+ if (isspace(txt[i]))
+ {
+ nl=new(struct list_info);
+ nl->list_type=LIST_ENUM_ALPHA;
+ nl->ldata.lbullet=txt[0]-1;
+ nl->obj_cnt=0;
+ nl->text_cnt=0;
+ nl->last_item=new(fifo<tok_seq::tok>);
+ nl->items=0;
+ return nl;
+ }
+ }
+
+ /* A., B., C. */
+ if (txt[0]=='A')
+ {
+ i=(txt[1]=='.') ? 2 : 1;
+ if (isspace(txt[i]))
+ {
+ nl=new(struct list_info);
+ nl->list_type=LIST_ENUM_ALPHA;
+ nl->ldata.lbullet=txt[0]-1;
+ nl->obj_cnt=0;
+ nl->text_cnt=0;
+ nl->last_item=new(fifo<tok_seq::tok>);
+ nl->items=0;
+ return nl;
+ }
+ }
+
+ /* At present we only know about one of bullet */
+ if (txt[0]==(char) BULLET_CODE)
+ {
+ nl=new(struct list_info);
+ nl->list_type=LIST_BULLET;
+ nl->ldata.lbullet=txt[0];
+ nl->obj_cnt=0;
+ nl->text_cnt=0;
+ nl->last_item=new(fifo<tok_seq::tok>);
+ nl->items=0;
+ return nl;
+ }
+
+ return NULL;
+}
+
+
+const char *tok_seq::l_type_name(const struct list_info *lp)
+{
+ switch(lp->list_type)
+ {
+ case LIST_BULLET:
+ return "itemize";
+ /* Not reached */
+
+ case LIST_ENUMERATE:
+ return "enumerate";
+ /* Not reached */
+
+ case LIST_ENUM_ALPHA:
+ return "listalpha";
+ /* Not reached */
+
+ default:
+ return "programming error";
+ /* Not reached */
+ }
+ /* Not reached */
+}
+
+
+/* Dequeue a list and queue it is as paragraphs */
+static void list_to_para(fifo<tok_seq::tok> *out, fifo<tok_seq::tok> *add)
+{
+ tblock txt;
+ int was_item_st;
+ const tok_seq::tok *t;
+
+ was_item_st=0;
+ while(!add->is_empty())
+ {
+ t=add->dequeue();
+ switch(t->tokval)
+ {
+ case T_LIST:
+ delete(t);
+ continue;
+ /* Not reached */
+
+ case T_ITEM:
+ if (t->end==tok_seq::tok::TOK_START)
+ {
+ txt.add(t->data.d);
+ txt.add(' ');
+ was_item_st=1;
+ }
+ delete(t);
+ continue;
+ /* not reached */
+
+ case T_PARAGRAPH:
+ if (t->end!=tok_seq::tok::TOK_START)
+ break;
+ if (!was_item_st)
+ break;
+
+ txt.add(t->data.d);
+ delete(t);
+ t=new(tok_seq::tok)(T_PARAGRAPH, (const char *) txt,
+ tok_seq::tok::TOK_START);
+ txt.zero();
+ was_item_st=0;
+ break;
+
+ default:
+ break;
+ }
+ out->enqueue(t);
+ }
+}
+
+/*
+ * This handles cues for lists and the like. if ( ) else if ()
+ * ... gets messy fast
+ */
+const char *tok_seq::list_check(const char *txt, list_info **lh)
+{
+ struct list_info *lp, *nl;
+ char *s;
+ tok *t;
+ int i,n;
+
+ /* Determine initial number. This will not change */
+ if (!isdigit(txt[0]))
+ n=-1;
+ else
+ {
+ n=i=0;
+ for (n=0, i=0; isdigit(txt[i]); i++)
+ n=n*10+txt[i]-'0';
+ }
+
+ lp=*lh;
+ list_reconsider:
+ while (lp!=NULL)
+ {
+ *lh=lp; // Makes no change unless lp changed below
+ switch (lp->list_type)
+ {
+ case LIST_ENUMERATE:
+ if (n==lp->ldata.item_no+1)
+ {
+ if (txt[i]=='.')
+ i++;
+ while (isspace(txt[i]))
+ i++;
+ if ((s=(char *) alloca(i+1))==NULL)
+ {
+ fprintf(stderr,
+ "Warning: item label skipped due to lack"
+ " of memory\n");
+ }
+ else
+ {
+ memcpy(s, txt, i);
+ *(s+i)='\0';
+ }
+ if (lp->items!=0)
+ {
+ outqueue.transfer(lp->last_item);
+ t=new(tok)(T_ITEM, (void *) NULL, tok::TOK_END);
+ outqueue.enqueue(t);
+ }
+ t=new(tok)(T_ITEM, s, tok::TOK_START);
+ lp->last_item->enqueue(t);
+ t=new(tok)(T_PARAGRAPH, txt+i, tok::TOK_START);
+ lp->last_item->enqueue(t);
+
+ lp->ldata.item_no++;
+ lp->obj_cnt=0; // No not list objects after this one
+ lp->text_cnt=0;
+ lp->items++;
+ return NULL;
+ }
+ break;
+
+
+ case LIST_BULLET:
+ if (txt[0]==lp->ldata.lbullet)
+ {
+ for (i=0; (isspace(txt[i])); i++ ) ;
+ if ((s=(char *) alloca(2))==NULL)
+ {
+ fprintf(stderr,
+ "Warning: item label skipped due to lack"
+ " of memory\n");
+ }
+ else
+ {
+ *s=lp->ldata.lbullet;
+ *(s+1)='\0';
+ }
+ if (lp->items!=0)
+ {
+ outqueue.transfer(lp->last_item);
+ t=new(tok)(T_ITEM, (void *) NULL, tok::TOK_END);
+ outqueue.enqueue(t);
+ }
+ t=new(tok)(T_ITEM, s, tok::TOK_START);
+ lp->last_item->enqueue(t);
+
+ while (isspace(*(++txt)));
+ t=new(tok)(T_PARAGRAPH, txt, tok::TOK_START);
+ lp->last_item->enqueue(t);
+
+ lp->obj_cnt=0; // No not list objects after this one
+ lp->text_cnt=0;
+ lp->items++;
+ return NULL;
+ }
+ break;
+
+ case LIST_ENUM_ALPHA:
+ if (txt[0]==lp->ldata.lbullet+1)
+ {
+ lp->ldata.lbullet++;
+ if ((s=(char *) alloca(3))==NULL)
+ {
+ fprintf(stderr,
+ "Warning: item label skipped due to lack"
+ " of memory\n");
+ }
+ else
+ {
+ *s=lp->ldata.lbullet;
+ if (txt[1]=='.')
+ {
+ *(s+1)='.';
+ *(s+2)='\0';
+ }
+ else
+ *(s+1)='\0';
+ }
+ if (lp->items!=0)
+ {
+ outqueue.transfer(lp->last_item);
+ t=new(tok)(T_ITEM, (void *) NULL, tok::TOK_END);
+ outqueue.enqueue(t);
+ }
+ t=new(tok)(T_ITEM, s, tok::TOK_START);
+ lp->last_item->enqueue(t);
+
+ for (i=0; (!isspace(txt[i])); i++ ) ;
+ for ( ;(isspace(txt[i])); i++) ;
+ t=new(tok)(T_PARAGRAPH, txt+i, tok::TOK_START);
+ lp->last_item->enqueue(t);
+
+ lp->obj_cnt=0; // No not list objects after this one
+ lp->text_cnt=0;
+ lp->items++;
+ return NULL;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Popping invalid list type %d\n",
+ lp->ldata.item_no);
+ nl=lp->next_list;
+ free(lp);
+ continue;
+ }
+
+ /* Not the right thing */
+ if ((nl=list_type(txt))!=NULL)
+ {
+ if (lp!=NULL && !(lp->last_item->is_empty()))
+ outqueue.transfer(lp->last_item); // Output outstanding items
+ t=new(tok)(T_LIST, l_type_name(nl), tok::TOK_START);
+ nl->last_item->enqueue(t);
+ nl->next_list=lp;
+ lp=nl;
+ continue;
+ }
+
+ lp->obj_cnt++;
+ lp->text_cnt +=strlen(txt);
+ if (lp->obj_cnt>PAR_ITEM_SEP_LIMIT || lp->text_cnt>TEXT_ITEM_SEP_LIMIT)
+ {
+ /* If only one item, not a list */
+ if (lp->items<2)
+ {
+ recycled=new(fifo<tok_seq::tok>);
+ list_to_para(recycled, lp->last_item);
+ delete(lp->last_item);
+ nl=lp->next_list;
+ free(lp);
+ lp=nl;
+ *lh=lp;
+ if (lp!=NULL)
+ lp->last_item->enqueue(recycled->dequeue());
+ else
+ outqueue.enqueue(recycled->dequeue());
+ return NULL;
+ }
+
+ /* Copy the list item */
+ if (!(lp->last_item->is_empty()))
+ {
+ const tok *tf;
+
+ tf=lp->last_item->dequeue();
+ while (tf->tokval!=T_PARAGRAPH || tf->end!=tok::TOK_END)
+ {
+ outqueue.enqueue(tf);
+ if (lp->last_item->is_empty())
+ goto lend_para_done;
+ tf=lp->last_item->dequeue();
+ }
+ outqueue.enqueue(tf);
+ lend_para_done: ;
+ }
+
+ /* Finish off the list */
+ t=new(tok)(T_ITEM, (void *) NULL, tok::TOK_END);
+ outqueue.enqueue(t);
+ t=new(tok)(T_LIST, l_type_name(lp), tok::TOK_END);
+ outqueue.enqueue(t);
+ nl=lp->next_list;
+ recycled=lp->last_item; // Recycle elements queued
+ t=new(tok)(T_PARAGRAPH, txt, tok::TOK_START);
+ recycled->enqueue(t);
+ free(lp);
+ lp=nl;
+ *lh=lp;
+ return NULL;
+ }
+
+ t=new(tok)(T_PARAGRAPH, txt, tok::TOK_START);
+ lp->last_item->enqueue(t);
+ return NULL;
+ }
+
+ /* lp==NULL if we get here */
+
+ if ((nl=list_type(txt))!=NULL)
+ {
+ nl->next_list=lp;
+ lp=nl;
+ t=new(tok)(T_LIST, l_type_name(nl), tok::TOK_START);
+ nl->last_item->enqueue(t);
+ goto list_reconsider;
+ }
+
+ return txt;
+
+}
+
+const tok_seq::tok *tok_seq::read_token(void)
+{
+ const tok *tf;
+ const char *tp;
+ tok *t;
+ struct list_info *nl;
+
+ while(outqueue.is_empty())
+ {
+ if (recycled!=NULL)
+ {
+ if (recycled->is_empty())
+ {
+ delete(recycled);
+ recycled=NULL;
+ continue; // outqueue still empty
+ }
+ tf=recycled->dequeue();
+ }
+ else
+ tf=this->eqn_rd_token();
+ if (tf==NULL)
+ {
+ if (!done_end)
+ {
+ tok *t;
+ t=new(tok)(T_DOC, "End of word2x output", tok::TOK_END);
+ output.enqueue(t);
+ done_end=1;
+ continue;
+ }
+ else
+ return NULL;
+ }
+
+ if (tf->tokval==T_DOC && tf->end==tok::TOK_END)
+ {
+ /* End all lists */
+ while (lp!=NULL)
+ {
+ tp=l_type_name(lp);
+ nl=lp->next_list;
+
+ if (!(lp->last_item->is_empty()))
+ outqueue.transfer(lp->last_item);
+ delete(lp->last_item);
+ free(lp);
+ t=new(tok)(T_ITEM, (void *) NULL, tok::TOK_END);
+ outqueue.enqueue(t);
+ t=new(tok)(T_LIST, tp, tok::TOK_END);
+ outqueue.enqueue(t);
+ lp=nl;
+ }
+ outqueue.enqueue(tf);
+ }
+ else if (tf->tokval==T_PARAGRAPH && tf->end==tok::TOK_START)
+ {
+ tp=list_check(tf->data.d, &lp);
+ if (tp!=NULL)
+ {
+ t=new(tok)(T_PARAGRAPH, tp, tok::TOK_START);
+ outqueue.enqueue(t);
+ /* End paragraph will come from previous stage */
+ }
+ delete(tf);
+ }
+ else
+ {
+ if (lp==NULL)
+ outqueue.enqueue(tf);
+ else
+ lp->last_item->enqueue(tf);
+ }
+ }
+ tf=outqueue.dequeue();
+ return tf;
+}
+
+
+ostream &operator<<(ostream &os, const tok_seq::tok *d)
+{
+ os<<'('<<d->tokval<<',';
+ switch(d->dtype)
+ {
+ case 1:
+ if (d->data.d!=NULL && strlen(d->data.d)>10)
+ {
+ char foo[11];
+ int i;
+
+ for(i=0; i<7; i++)
+ foo[i]=d->data.d[i];
+ for ( ; i<10; i++)
+ foo[i]='.';
+ foo[10]='\0';
+ os<<foo;
+ }
+ else
+ os<<d->data.d;
+ break;
+ case 0:
+ os<<d->data.table.rows<<'x'<<d->data.table.cols;
+ break;
+ }
+ os<<','<<((d->end==tok_seq::tok::TOK_START) ? "start" : "end")<<')';
+ return os;
+}
+
+tok_seq::tok &tok_seq::tok::operator=(const tok_seq::tok &d)
+{
+ tokval=d.tokval;
+ end=d.end;
+ dtype=d.dtype;
+ if (d.dtype==TEXT && d.data.d!=NULL)
+ {
+ data.d=strdup(d.data.d);
+ }
+ return (*this);
+}
diff --git a/support/word2x/reader.h b/support/word2x/reader.h
new file mode 100644
index 0000000000..4bcc4700dd
--- /dev/null
+++ b/support/word2x/reader.h
@@ -0,0 +1,278 @@
+/* $Id: reader.h,v 1.23 1997/04/17 15:38:19 dps Exp $ */
+/* header file for the reader */
+
+#ifndef __w6_reader_h__
+#define __w6_reader_h__
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <iostream.h>
+#include "tblock.h"
+#include "interface.h"
+#include "fifo.h"
+#include "word6.h"
+
+/* Raw reader output */
+typedef enum
+{
+ CH_PAR=0, CH_FIELD, CH_ROW, CH_SPEC, CH_ENDSPEC, CH_OTHER,
+ CH_HDRTN, CH_EOF, CH_PAGE, CH_FOOTNOTE,
+ CONTROL_FLAG=(1<<17), PART_FLAG=(1<<18)
+} chunk_type;
+
+#define CH_NONL 255
+#define CH_SUSPECT 127
+
+/*
+ * Anything shorter than in totla this is word abuse an all spec
+ * paragraph. This should be kept *very* small.
+ */
+#define DISPL_TRESHOLD 3
+#define PAR_ITEM_SEP_LIMIT 4
+#define TEXT_ITEM_SEP_LIMIT 1024
+
+#ifndef __EXCLUDE_READER_CLASSES
+
+struct chunk_rtn
+{
+ tblock txt;
+ int type;
+};
+
+/* This class converts raw word 6 into chunks for easier digestion */
+class chunk_reader
+{
+ private:
+ tblock text;
+ istream *in; /* Maybe should use istream here */
+ const char *tptr; /* Points to tblock text */
+ int type; /* Type */
+
+ void read_chunk_raw(void); /* Reads a lot */
+ protected:
+ struct chunk_rtn read_chunk(void); /* Returns the next bit */
+
+ inline chunk_reader(istream *f)
+ {
+ tptr=NULL;
+ in=f;
+ }
+ inline ~chunk_reader(void) {}; /* Avoids compiler bug */
+};
+
+
+/*
+ * This class interpolates stuff not in the chunks, for example the
+ * the start and statistics of tables.
+ */
+class tok_seq: private chunk_reader
+{
+ /* Classes used here */
+public:
+ /* Public token class */
+ class tok
+ {
+ private:
+ enum {TABLE=0, TEXT} dtype;
+
+ public:
+ enum { TOK_START=0, TOK_END };
+ token tokval;
+ union
+ {
+ struct
+ {
+ int rows;
+ int cols;
+ } table;
+ const char *d;
+ } data;
+ int end;
+
+ friend ostream &operator <<(ostream &, const tok *f);
+ tok &operator=(const tok &d);
+
+ /* Avoid the need to cast NULL everywhere for NULL defined as
+ (void *) 0 */
+ inline tok(token t, void *d, int e)
+ {
+ tokval=t;
+ data.d=(const char *) d;
+ dtype=TEXT;
+ end=e;
+ }
+ /* Avoid the need to cast NULL everywhere for NULL defined as 0 */
+ inline tok(token t, int d, int e)
+ {
+ d=d;
+ tokval=t;
+ data.d=(const char *) NULL;
+ dtype=TEXT;
+ end=e;
+ }
+ /* Avoid the need to cast NULL everywhere for NULL defined as 0L */
+ inline tok(token t, long int d, int e)
+ {
+ d=d;
+ tokval=t;
+ data.d=(const char *) NULL;
+ dtype=TEXT;
+ end=e;
+ }
+
+ inline tok(token t, const char *d, int e)
+ {
+ tokval=t;
+ if (d!=NULL)
+ data.d=strdup(d);
+ else
+ data.d=NULL;
+ dtype=TEXT;
+ end=e;
+ }
+ inline tok(token t, int c, int r, int e)
+ {
+ tokval=t;
+ data.table.rows=r;
+ data.table.cols=c;
+ dtype=TABLE;
+ end=e;
+ }
+ inline ~tok(void)
+ {
+ if (dtype==TEXT && data.d!=NULL)
+ free((void *) data.d);
+ }
+ };
+
+
+private:
+ /* Private class for table information */
+ class table_info
+ {
+ private:
+ fifo<tok> toks;
+
+ public:
+ int rows;
+ int cols;
+ int col;
+
+ inline table_info(void)
+ {
+ cols=0;
+ col=0;
+ rows=0;
+ }
+
+ inline void tok_push(token t, tblock *s)
+ {
+ tok *td;
+ td=new(tok)(t, (const char *) (*s), tok::TOK_START);
+ toks.enqueue(td);
+ td=new(tok)(t, (void *) NULL, tok::TOK_END);
+ toks.enqueue(td);
+ }
+
+ inline void enqueue(const tok *t)
+ {
+ toks.enqueue(t);
+ }
+
+ inline void finish(fifo<tok> *out)
+ {
+ tok *t;
+
+ t=new(tok)(T_TABLE, cols, rows, tok::TOK_START);
+ out->enqueue(t);
+ out->transfer(&toks);
+ t=new(tok)(T_TABLE, cols, rows, tok::TOK_END);
+ out->enqueue(t);
+ }
+ inline ~table_info(void) {} // Avoid compiler bug
+ };
+
+private:
+ fifo<tok> output; /* Output with equation cleaned up */
+ const tok *saved_tok;
+ int done_end;
+ table_info *table;
+ int rd_token(void);
+ const tok *feed_token(void);
+ const tok *math_collect(void);
+
+ /* Token pusher */
+ inline void tok_push(token t, tblock *s)
+ {
+ tok *td;
+ td=new(tok)(t, (const char *) (*s), tok::TOK_START);
+ output.enqueue(td);
+ td=new(tok)(t, (void *) NULL, tok::TOK_END);
+ output.enqueue(td);
+ }
+
+ const tok *eqn_rd_token(void);
+
+ /* List handling */
+ typedef enum { LIST_BULLET, LIST_ENUMERATE, LIST_ENUM_ALPHA } l_type;
+ struct list_info
+ {
+ struct list_info *next_list;
+ l_type list_type;
+ int obj_cnt;
+ int text_cnt;
+ int items;
+ union
+ {
+ int item_no;
+ int lbullet;
+ } ldata;
+ fifo<tok_seq::tok> *last_item;
+ };
+ struct list_info *lp; /* List pointer */
+ fifo<tok> outqueue; /* Final output (so far...) */
+ fifo<tok> *recycled; /* elements to be processed again */
+ struct list_info *list_type(const char *);
+ const char *list_check(const char *, struct list_info **);
+ const char *l_type_name(const struct list_info *);
+
+ public:
+
+
+ tok_seq(istream *in): chunk_reader(in)
+ {
+ tok *t=new(tok)(T_DOC, "Converted by word2x", tok::TOK_START);
+ table=NULL; /* No table */
+ saved_tok=NULL; /* No saved token */
+ lp=NULL; /* No list */
+ recycled=NULL; /* Nothing recycled */
+ done_end=0;
+
+ output.enqueue(t);
+ }
+
+ inline void return_toks(fifo<tok> *tp)
+ {
+ if (recycled==NULL)
+ recycled=new(fifo<tok>);
+ recycled->ins_trans(tp);
+ }
+
+ inline ~tok_seq(void) {} // Avoids compiler bug
+
+ const tok *read_token(void);
+
+};
+#endif /* __EXCLUDE_READER_CLASSES */
+#endif /* __w6_reader_h__ */
+
+
+
+
diff --git a/support/word2x/rtest2 b/support/word2x/rtest2
new file mode 100755
index 0000000000..3ca8a2a5be
--- /dev/null
+++ b/support/word2x/rtest2
Binary files differ
diff --git a/support/word2x/rtest2.cc b/support/word2x/rtest2.cc
new file mode 100644
index 0000000000..d1403702e5
--- /dev/null
+++ b/support/word2x/rtest2.cc
@@ -0,0 +1,113 @@
+/* $Id: rtest2.cc,v 1.8 1997/04/13 12:59:00 dps Exp $ */
+/* Reader test program */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include "strip.h"
+#include "interface.h"
+
+/* Dummy to just read the files out */
+void reader_test_raw(istream *f)
+{
+ const char *s;
+ const tok_seq::tok *d;
+ tok_seq rd(f);
+ static const char null[]={ '\0' };
+
+ while ((d=rd.read_token())!=NULL)
+ {
+
+ printf((d->end==tok_seq::tok::TOK_START) ? "<" : "</");
+ if (d->tokval!=T_TABLE)
+ {
+ s=(d->data.d==NULL) ? null : d->data.d;
+ }
+
+ switch(d->tokval)
+ {
+ case T_TABLE:
+ printf("TABLE %d x %d>\n", d->data.table.cols, d->data.table.rows);
+ break;
+
+ case T_PARAGRAPH:
+ printf("PARAGRAPH>%s\n\n", s);
+ break;
+
+ case T_FIELD:
+ printf("FIELD>%s", s);
+ break;
+
+ case T_ROW:
+ printf("ROW>%s\n", s);
+ break;
+
+ case T_SPEC:
+ printf("SPEC>%s", s);
+ break;
+
+ case T_LIST:
+ printf("LIST>%s\n", s);
+ break;
+
+ case T_ITEM:
+ printf("ITEM>%s\n", s);
+ break;
+
+ case T_DOC:
+ printf("DOCUMENT>%s", s);
+ break;
+
+ case T_CODE:
+ fputs("CODE ", stdout);
+ switch(*s)
+ {
+ case CH_PAGE:
+ fputs("page break", stdout);
+ break;
+
+ case CH_FOOTNOTE:
+ fputs("footnote", stdout);
+ break;
+
+ default:
+ printf("unexpected value %d", *s);
+ break;
+ }
+ puts(">");
+ break;
+
+ case T_OTHER:
+ printf("OTHER>%s\n", s);
+ break;
+
+ default:
+ printf("?>%s\n", s);
+ break;
+ }
+ fflush(stdout);
+ }
+}
+
+
+int main(int argc, const char **argv)
+{
+ FILE *f;
+
+ argc=argc;
+ f=fopen(argv[1],"r");
+ if (f==NULL)
+ {
+ fprintf(stderr,"%s not found\n", argv[1]);
+ exit(1);
+ }
+ else
+ {
+ fclose(f);
+ word_junk_filter filt(argv[1]);
+ istream in(&filt);
+ reader_test_raw(&in);
+ }
+ return 0;
+}
+
diff --git a/support/word2x/scan_num.cc b/support/word2x/scan_num.cc
new file mode 100644
index 0000000000..f0f2d639d5
--- /dev/null
+++ b/support/word2x/scan_num.cc
@@ -0,0 +1,76 @@
+/* $Id: scan_num.cc,v 1.4 1997/04/10 20:42:47 dps Exp $ */
+/* Simple number analyser */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+num_info scan_num(const char *scan)
+{
+ int nd, p;
+ num_info r;
+
+ r.wd[0]=r.wd[1]=r.has_sign=nd=0;
+ p=1;
+
+ switch (*scan)
+ {
+ case '-':
+ case '+':
+ scan++;
+ r.wd[0]++;
+ p++;
+ r.has_sign=1;
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ break;
+
+ default:
+ r.dot_pos=-1;
+ return r;
+ }
+
+ for ( ; *scan!='\0'; scan++, p++)
+ {
+ switch (*scan)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ r.wd[nd]++; // Digit
+ break;
+
+ case '.':
+ r.dot_pos=p;
+ if ((++nd)==1)
+ break;
+ /* Fall through */
+ default:
+ r.dot_pos=-1;
+ return r;
+ }
+ }
+ if (r.wd[0]+r.wd[1]<=r.has_sign)
+ {
+ r.dot_pos=-1;
+ return r;
+ }
+ if (nd==0)
+ r.dot_pos=p;
+ return r;
+}
diff --git a/support/word2x/shrink_width.cc b/support/word2x/shrink_width.cc
new file mode 100644
index 0000000000..70a020eb8c
--- /dev/null
+++ b/support/word2x/shrink_width.cc
@@ -0,0 +1,35 @@
+
+/* $Id: shrink_width.cc,v 1.1 1997/03/31 23:12:33 dps Exp $ */
+/* O(n^2) table width reduction algorithm, n is small in almost all cases */
+static void shrink_widths(int ncols, struct rdata *cols, int mtw)
+{
+ int i, j, tw, maxw;
+
+ for (tw=0, i=0; i<ncols; i++)
+ tw+=cols[i].w.width;
+
+ mtw-=ncols; // Take account of column seperators
+
+ /* Simply reduce the maximum width column width by one until
+ enougn has been trimed */
+ while (tw>mtw)
+ {
+ maxw=0; j=-1;
+ for (i=0; i<ncols; i++)
+ {
+ if (maxw<cols[i].w.width && cols[i].w.align!=ALIGN_DP)
+ {
+ j=i;
+ maxw=cols[i].w.width;
+ }
+ }
+
+ if (j==-1)
+ {
+ fprintf(stderr, "Can not shrink overwidth table\n");
+ continue;
+ }
+ cols[j].w.width--;
+ tw--;
+ }
+}
diff --git a/support/word2x/strip.cc b/support/word2x/strip.cc
new file mode 100644
index 0000000000..5ab4b6794f
--- /dev/null
+++ b/support/word2x/strip.cc
@@ -0,0 +1,527 @@
+/* $Id: junk_filter.cc,v 1.40 1998/06/14 06:25:36 dps Exp $ */
+
+/* This code filters out almost all the "junk" in word documents and
+ * is useful for extracting the text from word documents. I think this
+ * program produces better signal to noise that catdoc. */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include <stream.h>
+#include <iostream.h>
+#include <fstream.h>
+#include "strip.h"
+#include "tune.h"
+
+/* Note: This is a two stage filter that outputs 0 or 1 characters
+ per input character and thus can use the same buffer safely. */
+
+/* Read more */
+int word_junk_filter::__fill(const char *b, int n, int sp, int offset)
+{
+ int end, nr;
+
+ if (n>0)
+ memmove(buf+offset, b, n);
+ offset+=n+sp;
+ if (offset>JUNK_FILT_BUFSIZE)
+ {
+ cerr<<"junk_filter::__fill: start offset "<<offset<<" >buffer size"
+ "(fatal)\n";
+ exit(1);
+ }
+ if (offset<JUNK_FILT_BUFSIZE)
+ {
+ is->read(buf+offset, JUNK_FILT_BUFSIZE-offset);
+ nr=is->gcount();
+ }
+ else
+ nr=0;
+ pos+=nr;
+ end=nr+n;
+ return end;
+}
+
+
+/* Junk filtering. Buffer size must be >=RESUME_CHARS */
+int word_junk_filter::filter_junk(const char *b, int ns)
+{
+ int i, d, n, top_run;
+
+ if ((n=__fill(b, ns, junk_end_usage, 1))==0)
+ return 0;
+ if (junk_end_usage>0)
+ memcpy(buf+ns+1, junk_end_buf, junk_end_usage);
+ if (init==INIT_SKIPPED)
+ {
+ init=INIT_DONE; // Finished init
+ ns=0; // Process all the data
+ text_size=0; // Text size is zero
+ }
+
+#ifdef DEBUG_FILTER_FILL
+ printf("\n---refill ns=%d junk_end_usage=%d\n", ns, junk_end_usage);
+ printf("---end=%d mode=%d\n", n, mode);
+#endif
+
+ /* Correctness of this loop depends on d<=i at the top of the
+ loop. The claims * by inductioon about the fake variable __adj__ suffice
+ to prove this. All the relevant commments are prefixed by CS */
+
+ top_run=0;
+ /*** CS: __adj__=1 ****/
+ for (i=ns+1, d=ns; i<=n; i++) // Ignore already processed data pushed back
+ {
+ /*** CS: i==d+junk_end_usage+__adj__ and __adj__>=0 here by induction ***/
+ /*** CS: if mode==SKIP_JUNK or SKIP_JUNK_WASPRN then __adj__>=1 ***/
+#ifdef DEBUG_FILTER
+ printf("mode %d, char[%i] (t=%d) %c, asc=%d\n", mode, i, n,
+ buf[i], junk_end_usage);
+#endif
+ switch(mode)
+ {
+ case NORMAL:
+ /* Normal mode. OK becasue change in d at most 1 and junk_end_usage=0 */
+ if (buf[i]==0)
+ {
+ junk_end_usage=0;
+ junk_size=0;
+ mode=SKIP_JUNK;
+ break;
+ }
+ if (buf[i] & 0x80)
+ {
+ /*** CS: by induction junk_end_usage==top_run ***/
+ junk_end_buf[junk_end_usage++]=buf[i]; // Save character
+ top_run++; // Increment top run counter
+ /*** CS: __adj__++ ***/
+ if (top_run==tune.max_top_run)
+ {
+ junk_size=top_run; // Top bit characters are junk
+ junk_end_usage=0; // Throw away characters
+ mode=SKIP_JUNK; // End junk skipping mode
+ /*** CS: __adj__ += top_run ***/
+ break;
+ }
+ break; // Exit switch
+ }
+ /* Top bit not set */
+ if (top_run)
+ {
+ memcpy(buf+d, junk_end_buf, junk_end_usage); // OK by ind hyp.
+ d+=junk_end_usage;
+ junk_end_usage=0; // Ind. hyp now true
+ top_run=0; // Reset top_run counter.
+ }
+ /* Add character */
+ buf[d++]=buf[i];
+ text_size++;
+ if (unicode!=__UNI_NO)
+ mode=UNICODE_Z;
+ break;
+
+ case UNICODE_Z:
+ /* unicode zero mode. OK because change in d is 0 and junk_end_usage=0 */
+ if (buf[i]==0)
+ {
+ mode=NORMAL; // 0 => Back to printable character mode
+ /*** CS: __adj__++ ***/
+ }
+ else
+ {
+#ifdef UNICODE_MARKERS
+ printf("\n*** Mode %d: %d Got %d expected 0\n", mode,
+ UNICODE_Z, buf[i]);
+#endif
+ junk_end_usage=0;
+ junk_size=0;
+ mode=SKIP_JUNK;
+ /*** CS: __adj__++ ***/
+ }
+ break;
+
+ case SKIP_JUNK_WASPRN:
+ /* Skip junk was printable, added for unicode documents */
+ /* OK because junk_end_usage chages by at most 1 and d stays fixed */
+ if ((++junk_size)==tune.max_junk && text_size>tune.min_text)
+ {
+#ifdef DEBUG_SINK_START
+ cerr<<"Enter sink mode\n";
+#endif /* DEBUG_SINK_START */
+ /*** CS: __adj__++ ***/
+ mode=SINK_JUNK; // Sink junk
+ break;
+ }
+ if (tune.options.unicode_aggresive)
+ {
+ /* Agresive unicode mode: insist on the MSBs appearing */
+ if (unicode!=__UNI_NO)
+ {
+ if (buf[i]!=0)
+ {
+ /*** CS: __adj__+=junk_end_usage ***/
+ junk_end_usage=0;
+ }
+ mode=SKIP_JUNK;
+ /*** CS: __adj__++ ***/
+ break;
+ }
+ }
+ else
+ {
+ /* Non-aggersive unicode mode: simply skip the MSB */
+ if (buf[i]==0 && unicode!=__UNI_NO)
+ {
+ /*** CS: __adj__++ ***/
+ break; // Accept zeros
+ }
+ }
+ /* Fall thru */
+
+ case SKIP_JUNK:
+ /* Junk skipping mode */
+ if ((++junk_size)==tune.max_junk && text_size>tune.min_text)
+ {
+#ifdef DEBUG_SINK_START
+ cerr<<"Enter sink mode\n";
+#endif /* DEBUG_SINK_START */
+ mode=SINK_JUNK; // Sink junk
+ /*** CS: __adj__++ ***/
+ break;
+ }
+ if (isprint(buf[i]) || buf[i]=='\r' || buf[i]=='\n'
+ || buf[i]=='\t')
+ {
+#ifdef DEBUG_RESTART
+ printf("---Accepted *%c*, usage=%d\n", buf[i], junk_end_usage);
+#endif
+ junk_end_buf[junk_end_usage++]=buf[i]; // Save character
+ if (unicode!=__UNI_NO)
+ mode=SKIP_JUNK_WASPRN; // For unicode documents
+ }
+ else
+ {
+ /* Reset junk buffer usage counter */
+ /*** CS: __adj__+=junk_end_usage+1 ***/
+#ifdef DEBUG_RESTART
+ if (junk_end_usage!=0)
+ printf("---Rejected %d, usage=%d\n", buf[i], junk_end_usage);
+#endif
+ junk_end_usage=0;
+ break;
+ }
+ if (junk_end_usage<tune.resume_chars)
+ break;
+ /* Turn nomral mode back on */
+#ifdef DEBUG_RESTART
+ printf("---back normal mode count=%d\n", junk_size);
+#endif
+ /* The __adj__ analysis is *vital* here; if __Adj__=0 then d>i occurs */
+ /* however forutnately this is impossible by the claims that __adj__ */
+ /* and indcution proves. */
+
+ /**** CS: __adj__>=1 here by indcution. Thus i>=d+junk_end_usage+1 ****/
+ mode=(unicode==__UNI_NO) ? NORMAL : UNICODE_Z;
+ buf[d]=0x7f; // Mark suspect position
+ memcpy(buf+d+1, junk_end_buf, junk_end_usage); // Nothing clobbered by [1]
+ d+=junk_end_usage+1; // Advance d
+ junk_end_usage=0; // Clear junk end buffer
+ /*** CS: __adj__-- ***/
+ break;
+
+ case SINK_JUNK:
+ /*** CS: __adj__++ ***/
+ break;
+
+ default:
+ cerr<<"word_junk_filter::filter_junk: Invalid mode "<<mode
+ <<" (fatal)\n";
+ exit(1);
+ }
+ }
+ return d;
+}
+
+int word_junk_filter::underflow(void)
+{
+ int s,d,last;
+ int end;
+
+ do // While no characters
+ {
+ /* Fill the buffer */
+ if (init==INIT_NONE)
+ {
+ if (is!=NULL)
+ {
+ init=INIT_SKIPPED;
+ ns=this->skip_to_start();
+ end=this->filter_junk(buf, ns);
+ }
+ else
+ return EOF; // If no input stream return EOF
+ }
+ else
+ {
+ end=this->filter_junk(&save, ns);
+ ns=0;
+ }
+
+ /* Check for EOF */
+ if (end==0 && is->eof())
+ return EOF;
+
+ ns=0;
+ /* Collapse multi-character sequeneces */
+ for (s=0, d=0, last=-1; s<end; s++)
+ {
+ switch(buf[s])
+ {
+ case '\n':
+ if (last=='\r')
+ continue; // \n \r to \r
+ break;
+
+
+ case '\r':
+ if (last=='\n')
+ d--; // \r \n to \r
+ break;
+
+
+ case 0x07:
+ if (last=='\r')
+ d--; // \n <TAB SEP> to <TAB SEP>
+ break;
+
+ default:
+ break;
+ }
+ last=buf[d]=buf[s];
+ d++;
+ }
+
+ if (end!=1 && (buf[d-1]=='\r' || buf[d-1]=='\n'))
+ {
+ d--;
+ ns=1;
+ save=buf[d];
+ }
+ } while (d==0);
+ setg(buf, buf, buf+d);
+ return(buf[0] & 0xff);
+}
+
+
+/* Skip to start */
+int word_junk_filter::skip_to_start(void)
+{
+ int zc,ffc,c,n,i,rej,limit=-1;
+ char back[2*ST_ASC_VCHARS_UNICODE+ST_REJ_LIMIT+4];
+ int bp;
+ long pos=0;
+
+ enum { FIND_BEGIN, SKIP_ONE, FIND_ASC, FIND_ASC_WASASC, DONE } mode;
+ zc=0; ffc=0; i=0; n=0; bp=0; rej=-1;
+ mode=FIND_BEGIN;
+ while (mode!=DONE)
+ {
+ /* If need a refill */
+ if (i==n)
+ {
+ /* Fill buffer */
+ n=this->__fill(back,bp,0,1);
+ if (n==0)
+ return 0;
+ pos+=n-bp;
+#ifdef DEBUG_SKIP_FILL
+ printf("---skip--- refill bp=%x, pos=%x\n", bp, pos);
+#endif
+ /* Ignore first saved character */
+ if (mode==FIND_ASC)
+ mode=SKIP_ONE;
+ i=0;
+ bp=0;
+ }
+
+#ifdef DEBUG_SKIP
+ printf("char %c mode %d, c=%d, pos=%x, i=%d l=%d, rej=%d\n", buf[i+1],
+ mode, c, pos++, i, limit, rej);
+#endif
+ switch(mode)
+ {
+ case FIND_BEGIN:
+ switch(buf[i+1])
+ {
+ case 0:
+ zc++;
+ ffc=0;
+ break;
+
+ case ((char) 0xff):
+ ffc++;
+ zc=0;
+ break;
+
+ default:
+ if (zc>=tune.st_min_zeros ||
+ (ffc>=tune.st_min_ff && tune.options.ff_intro))
+ {
+ unicode=__UNI_PROBE;
+ back[bp++]=buf[i+1];
+ c=0;
+ rej=0;
+ mode=FIND_ASC_WASASC; // Ignore this character deliberately
+ }
+ else
+ {
+ zc=0;
+ ffc=0;
+ }
+ break;
+ }
+ break;
+
+ case SKIP_ONE:
+ back[bp++]=buf[i+1];
+ c=0;
+ rej=0;
+ mode=FIND_ASC_WASASC;
+ break;
+
+ case FIND_ASC_WASASC: // unicode support
+ if (buf[i+1]==0 && unicode!=__UNI_NO)
+ {
+ if (unicode==__UNI_PROBE)
+ {
+ limit=tune.unicode_st; // Start characters needed
+ /* FIXME: Anyone got a better method of doing this? */
+ if ((pos+i) % 2==0)
+ {
+ unicode=__UNI_YES_BE; // 0 is first (even) bu#yte
+ }
+ else
+ {
+ unicode=__UNI_YES_LE; // 0 is second (odd) byte
+ }
+ back[bp++]=buf[i+1];
+ mode=FIND_ASC; // Inist next character not zero
+#ifdef DEBUG_SKIP_UNI
+ cerr<<"Characters are unicode "
+ <<((unicode==__UNI_YES_LE) ? "litle" : "big")
+ <<" endian\n";
+#endif
+ }
+ else
+ back[bp++]=buf[i+1];
+ c++;
+ break;
+ }
+ else if (unicode==__UNI_PROBE)
+ {
+#ifdef DEBUG_SKIP_UNI
+ if (unicode==__UNI_PROBE)
+ cerr<<"Characters are not unicode\n";
+#endif
+ limit=tune.non_unicode_st; // Start characters needed
+ unicode=__UNI_NO; // Non unicode
+ mode=FIND_ASC; // Finding printable mode
+ }
+ /* fall thru */
+
+ case FIND_ASC:
+ if (isprint(buf[i+1]) || buf[i+1]=='\r' || buf[i+1]=='\n'
+ || buf[i+1]=='\t') // If is printable
+ {
+ back[bp++]=buf[i+1]; // Store character
+ c++; // Increase count
+ if (unicode!=__UNI_NO)
+ mode=FIND_ASC_WASASC; // Unicode hack...
+ }
+ else
+ {
+ back[bp++]=buf[i+1]; // Store caharcetr
+ if (buf[i+1]!=0)
+ rej++; // Adjust reject count
+ if (buf[i+1]==0 || rej>tune.st_rej_limit) // 0 or reject limit
+ {
+ bp=0; // Reset buffer pointer
+ unicode=__UNI_PROBE; // Set unicode status to unknonw
+ ffc=(buf[i+1]== (char) 0xff) ? 1 : 0; // reset ff count
+ zc=(buf[i+1]==0) ? 1 : 0; // reset zeros count
+ mode=FIND_BEGIN ; // Find leading characters mode
+ }
+ }
+ if (limit==-1) // Bug catcher
+ {
+ cerr<<"Bug: limit still -1 at point #1\n";
+ exit(2);
+ }
+ if (c==limit) // IF found enough
+ {
+#ifdef DEBUG_SKIP
+ printf("***** Enter exit phase ****\n");
+#endif
+ mode=DONE; // Finished skipping
+ }
+ break;
+
+ case DONE:
+ cerr<<"skip_to_start: loop called in done mode\n";
+ break;
+
+ default:
+ cerr<<"skip_to_start: Mode invalid\n";
+ break;
+ }
+ i++;
+ }
+#ifdef DEBUG_SKIP_MOVE
+ printf("%c%c%c\n", buf[i-bp+1], buf[i-bp+2], buf[i-bp+3]);
+#endif
+ memmove(buf, buf+i-bp+1, n-i+bp); // Move memory
+ return(n-i+bp); // Return count
+}
+
+
+/* Option handling stuff for tuning this module. Note that only long options
+ * are supported. If you lack long options these features are not avialable. */
+/* set default tuning */
+void word_junk_filter::set_dfl_tuning(void)
+{
+#ifdef AGGRESIVE_UNICODE
+ tune.options.unicode_aggresive=AGGRESIVE_UNICODE; // Aggresive unicode mode
+#else
+ tune.options.unicode_aggresive=1; // Aggresive unicode mode
+#endif /* AGGRESIVE_UNICODE */
+ tune.resume_chars=RESUME_CHARS; // Resume characters
+ tune.st_min_zeros=ST_MIN_ZEROS; // Minimum zeros
+ tune.st_rej_limit=ST_REJ_LIMIT; // Reject chars tolerance
+ tune.st_min_ff=ST_MIN_FF; // Minimum ff's (alternative to 0s)
+ tune.options.ff_intro=ALLOW_FF_LEADIN; // Enable leading ff's
+ tune.non_unicode_st=ST_ASC_VCHARS; // ok characters leadin
+ tune.unicode_st=ST_ASC_VCHARS_UNICODE; // ok unicode characters
+ tune.min_text=SINK_MIN_TEXT; // text required before sink mode
+ tune.max_junk=SINK_JUNK_CNT; // junk required for sink mode
+ tune.max_top_run=MAX_TOP_RUN; // Max run length of top bits set
+}
+
+int word_junk_filter::do_reset(void)
+{
+ pos=0;
+ init=INIT_NONE;
+ mode=NORMAL;
+ junk_end_usage=0;
+ ns=0;
+ return 1; // Success
+}
+
diff --git a/support/word2x/strip.cc.orig b/support/word2x/strip.cc.orig
new file mode 100644
index 0000000000..5d0af50e56
--- /dev/null
+++ b/support/word2x/strip.cc.orig
@@ -0,0 +1,522 @@
+/* $Id: junk_filter.cc,v 1.40 1998/06/14 06:25:36 dps Exp $ */
+
+/* This code filters out almost all the "junk" in word documents and
+ * is useful for extracting the text from word documents. I think this
+ * program produces better signal to noise that catdoc. */
+
+/* #include "config.h" */
+#define HAVE_STRING_H 1
+#define HAVE_STRINGS_H 1
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <ctype.h>
+#include <stream.h>
+#include <iostream.h>
+#include <fstream.h>
+#include "strip.h"
+#include "tune.h"
+
+/* Note: This is a two stage filter that outputs 0 or 1 characters
+ per input character and thus can use the same buffer safely. */
+
+/* Read more */
+int word_junk_filter::__fill(const char *b, int n, int sp, int offset)
+{
+ int end, nr;
+
+ if (n>0)
+ memmove(buf+offset, b, n);
+ offset+=n+sp;
+ if (offset>=JUNK_FILT_BUFSIZE)
+ {
+ cerr<<"junk_filter::__fill: start offset "<<offset<<" >= buffer size"
+ "(fatal)\n";
+ exit(1);
+ }
+ is->read(buf+offset, JUNK_FILT_BUFSIZE-offset);
+ nr=is->gcount();
+ pos+=nr;
+ end=nr+n;
+ return end;
+}
+
+
+/* Junk filtering. Buffer size must be >=RESUME_CHARS */
+int word_junk_filter::filter_junk(const char *b, int ns)
+{
+ int i, d, n, top_run;
+
+ if ((n=__fill(b, ns, junk_end_usage, 1))==0)
+ return 0;
+ if (junk_end_usage>0)
+ memcpy(buf+ns+1, junk_end_buf, junk_end_usage);
+ if (init==INIT_SKIPPED)
+ {
+ init=INIT_DONE; // Finished init
+ ns=0; // Process all the data
+ text_size=0; // Text size is zero
+ }
+
+#ifdef DEBUG_FILTER_FILL
+ printf("\n---refill ns=%d junk_end_usage=%d\n", ns, junk_end_usage);
+ printf("---end=%d mode=%d\n", n, mode);
+#endif
+
+ /* Correctness of this loop depends on d<=i at the top of the
+ loop. The claims * by inductioon about the fake variable __adj__ suffice
+ to prove this. All the relevant commments are prefixed by CS */
+
+ top_run=0;
+ /*** CS: __adj__=1 ****/
+ for (i=ns+1, d=ns; i<n; i++) // Ignore already processed data pushed back
+ {
+ /*** CS: i==d+junk_end_usage+__adj__ and __adj__>=0 here by induction ***/
+ /*** CS: if mode==SKIP_JUNK or SKIP_JUNK_WASPRN then __adj__>=1 ***/
+#ifdef DEBUG_FILTER
+ printf("mode %d, char[%i] (t=%d) %c, asc=%d\n", mode, i, n,
+ buf[i], junk_end_usage);
+#endif
+ switch(mode)
+ {
+ case NORMAL:
+ /* Normal mode. OK becasue change in d at most 1 and junk_end_usage=0 */
+ if (buf[i]==0)
+ {
+ junk_end_usage=0;
+ junk_size=0;
+ mode=SKIP_JUNK;
+ break;
+ }
+ if (buf[i] & 0x80)
+ {
+ /*** CS: by induction junk_end_usage==top_run ***/
+ junk_end_buf[junk_end_usage++]=buf[i]; // Save character
+ top_run++; // Increment top run counter
+ /*** CS: __adj__++ ***/
+ if (top_run==tune.max_top_run)
+ {
+ junk_size=top_run; // Top bit characters are junk
+ junk_end_usage=0; // Throw away characters
+ mode=SKIP_JUNK; // End junk skipping mode
+ /*** CS: __adj__ += top_run ***/
+ break;
+ }
+ break; // Exit switch
+ }
+ /* Top bit not set */
+ if (top_run)
+ {
+ memcpy(buf+d, junk_end_buf, junk_end_usage); // OK by ind hyp.
+ d+=junk_end_usage;
+ junk_end_usage=0; // Ind. hyp now true
+ top_run=0; // Reset top_run counter.
+ }
+ /* Add character */
+ buf[d++]=buf[i];
+ text_size++;
+ if (unicode!=__UNI_NO)
+ mode=UNICODE_Z;
+ break;
+
+ case UNICODE_Z:
+ /* unicode zero mode. OK because change in d is 0 and junk_end_usage=0 */
+ if (buf[i]==0)
+ {
+ mode=NORMAL; // 0 => Back to printable character mode
+ /*** CS: __adj__++ ***/
+ }
+ else
+ {
+#ifdef UNICODE_MARKERS
+ printf("\n*** Mode %d: %d Got %d expected 0\n", mode,
+ UNICODE_Z, buf[i]);
+#endif
+ junk_end_usage=0;
+ junk_size=0;
+ mode=SKIP_JUNK;
+ /*** CS: __adj__++ ***/
+ }
+ break;
+
+ case SKIP_JUNK_WASPRN:
+ /* Skip junk was printable, added for unicode documents */
+ /* OK because junk_end_usage chages by at most 1 and d stays fixed */
+ if ((++junk_size)==tune.max_junk && text_size>tune.min_text)
+ {
+#ifdef DEBUG_SINK_START
+ cerr<<"Enter sink mode\n";
+#endif /* DEBUG_SINK_START */
+ /*** CS: __adj__++ ***/
+ mode=SINK_JUNK; // Sink junk
+ break;
+ }
+ if (tune.options.unicode_aggresive)
+ {
+ /* Agresive unicode mode: insist on the MSBs appearing */
+ if (unicode!=__UNI_NO)
+ {
+ if (buf[i]!=0)
+ {
+ /*** CS: __adj__+=junk_end_usage ***/
+ junk_end_usage=0;
+ }
+ mode=SKIP_JUNK;
+ /*** CS: __adj__++ ***/
+ break;
+ }
+ }
+ else
+ {
+ /* Non-aggersive unicode mode: simply skip the MSB */
+ if (buf[i]==0 && unicode!=__UNI_NO)
+ {
+ /*** CS: __adj__++ ***/
+ break; // Accept zeros
+ }
+ }
+ /* Fall thru */
+
+ case SKIP_JUNK:
+ /* Junk skipping mode */
+ if ((++junk_size)==tune.max_junk && text_size>tune.min_text)
+ {
+#ifdef DEBUG_SINK_START
+ cerr<<"Enter sink mode\n";
+#endif /* DEBUG_SINK_START */
+ mode=SINK_JUNK; // Sink junk
+ /*** CS: __adj__++ ***/
+ break;
+ }
+ if (isprint(buf[i]) || buf[i]=='\r' || buf[i]=='\n'
+ || buf[i]=='\t')
+ {
+#ifdef DEBUG_RESTART
+ printf("---Accepted *%c*, usage=%d\n", buf[i], junk_end_usage);
+#endif
+ junk_end_buf[junk_end_usage++]=buf[i]; // Save character
+ if (unicode!=__UNI_NO)
+ mode=SKIP_JUNK_WASPRN; // For unicode documents
+ }
+ else
+ {
+ /* Reset junk buffer usage counter */
+ /*** CS: __adj__+=junk_end_usage+1 ***/
+#ifdef DEBUG_RESTART
+ if (junk_end_usage!=0)
+ printf("---Rejected %d, usage=%d\n", buf[i], junk_end_usage);
+#endif
+ junk_end_usage=0;
+ break;
+ }
+ if (junk_end_usage<tune.resume_chars)
+ break;
+ /* Turn nomral mode back on */
+#ifdef DEBUG_RESTART
+ printf("---back normal mode count=%d\n", junk_size);
+#endif
+ /* The __adj__ analysis is *vital* here; if __Adj__=0 then d>i occurs */
+ /* however forutnately this is impossible by the claims that __adj__ */
+ /* and indcution proves. */
+
+ /**** CS: __adj__>=1 here by indcution. Thus i>=d+junk_end_usage+1 ****/
+ mode=(unicode==__UNI_NO) ? NORMAL : UNICODE_Z;
+ buf[d]=0x7f; // Mark suspect position
+ memcpy(buf+d+1, junk_end_buf, junk_end_usage); // Nothing clobbered by [1]
+ d+=junk_end_usage+1; // Advance d
+ junk_end_usage=0; // Clear junk end buffer
+ /*** CS: __adj__-- ***/
+ break;
+
+ case SINK_JUNK:
+ /*** CS: __adj__++ ***/
+ break;
+
+ default:
+ cerr<<"word_junk_filter::filter_junk: Invalid mode "<<mode
+ <<" (fatal)\n";
+ exit(1);
+ }
+ }
+ return d;
+}
+
+int word_junk_filter::underflow(void)
+{
+ int s,d,last;
+ int end;
+
+ do // While no characters
+ {
+ /* Fill the buffer */
+ if (init==INIT_NONE)
+ {
+ if (is!=NULL)
+ {
+ init=INIT_SKIPPED;
+ ns=this->skip_to_start();
+ end=this->filter_junk(buf, ns);
+ }
+ else
+ return EOF; // If no input stream return EOF
+ }
+ else
+ {
+ end=this->filter_junk(&save, ns);
+ ns=0;
+ }
+
+ /* Check for EOF */
+ if (end==0 && is->eof())
+ return EOF;
+
+ ns=0;
+ /* Collapse multi-character sequeneces */
+ for (s=0, d=0, last=-1; s<end; s++)
+ {
+ switch(buf[s])
+ {
+ case '\n':
+ if (last=='\r')
+ continue; // \n \r to \r
+ break;
+
+
+ case '\r':
+ if (last=='\n')
+ d--; // \r \n to \r
+ break;
+
+
+ case 0x07:
+ if (last=='\r')
+ d--; // \n <TAB SEP> to <TAB SEP>
+ break;
+
+ default:
+ break;
+ }
+ last=buf[d]=buf[s];
+ d++;
+ }
+
+ if (end!=1 && (buf[d-1]=='\r' || buf[d-1]=='\n'))
+ {
+ d--;
+ ns=1;
+ save=buf[d];
+ }
+ } while (d==0);
+ setg(buf, buf, buf+d);
+ return(buf[0] & 0xff);
+}
+
+
+/* Skip to start */
+int word_junk_filter::skip_to_start(void)
+{
+ int zc,ffc,c,n,i,rej,limit=-1;
+ char back[2*ST_ASC_VCHARS_UNICODE+ST_REJ_LIMIT+4];
+ int bp;
+ long pos=0;
+
+ enum { FIND_BEGIN, SKIP_ONE, FIND_ASC, FIND_ASC_WASASC, DONE } mode;
+ zc=0; ffc=0; i=0; n=0; bp=0; rej=-1;
+ mode=FIND_BEGIN;
+ while (mode!=DONE)
+ {
+ /* If need a refill */
+ if (i==n)
+ {
+ /* Fill buffer */
+ n=this->__fill(back,bp,0,0);
+ if (n==0)
+ return 0;
+ pos+=n-bp;
+#ifdef DEBUG_SKIP_FILL
+ printf("---skip--- refill bp=%x, pos=%x\n", bp, pos);
+#endif
+ /* Ignore first saved character */
+ if (mode==FIND_ASC)
+ mode=SKIP_ONE;
+ i=0;
+ bp=0;
+ }
+
+#ifdef DEBUG_SKIP
+ printf("char %c mode %d, c=%d, pos=%x, i=%d l=%d, rej=%d\n", buf[i],
+ mode, c, pos++, i, limit, rej);
+#endif
+ switch(mode)
+ {
+ case FIND_BEGIN:
+ switch(buf[i])
+ {
+ case 0:
+ zc++;
+ ffc=0;
+ break;
+
+ case ((char) 0xff):
+ ffc++;
+ zc=0;
+ break;
+
+ default:
+ if (zc>=tune.st_min_zeros ||
+ (ffc>=tune.st_min_ff && tune.options.ff_intro))
+ {
+ unicode=__UNI_PROBE;
+ back[bp++]=buf[i];
+ c=0;
+ rej=0;
+ mode=FIND_ASC_WASASC; // Ignore this character deliberately
+ }
+ else
+ {
+ zc=0;
+ ffc=0;
+ }
+ break;
+ }
+ break;
+
+ case SKIP_ONE:
+ back[bp++]=buf[i];
+ c=0;
+ rej=0;
+ mode=FIND_ASC_WASASC;
+ break;
+
+ case FIND_ASC_WASASC: // unicode support
+ if (buf[i]==0 && unicode!=__UNI_NO)
+ {
+ if (unicode==__UNI_PROBE)
+ {
+ limit=tune.unicode_st; // Start characters needed
+ /* FIXME: Anyone got a better method of doing this? */
+ if ((pos+i) % 2==0)
+ {
+ unicode=__UNI_YES_BE; // 0 is first (even) bu#yte
+ }
+ else
+ {
+ unicode=__UNI_YES_LE; // 0 is second (odd) byte
+ }
+ back[bp++]=buf[i];
+ mode=FIND_ASC; // Inist next character not zero
+#ifdef DEBUG_SKIP_UNI
+ cerr<<"Characters are unicode "
+ <<((unicode==__UNI_YES_LE) ? "litle" : "big")
+ <<" endian\n";
+#endif
+ }
+ else
+ back[bp++]=buf[i];
+ c++;
+ break;
+ }
+ else if (unicode==__UNI_PROBE)
+ {
+#ifdef DEBUG_SKIP_UNI
+ if (unicode==__UNI_PROBE)
+ cerr<<"Characters are not unicode\n";
+#endif
+ limit=tune.non_unicode_st; // Start characters needed
+ unicode=__UNI_NO; // Non unicode
+ mode=FIND_ASC; // Finding printable mode
+ }
+ /* fall thru */
+
+ case FIND_ASC:
+ if (isprint(buf[i]) || buf[i]=='\r' || buf[i]=='\n'
+ || buf[i]=='\t') // If is printable
+ {
+ back[bp++]=buf[i]; // Store character
+ c++; // Increase count
+ if (unicode!=__UNI_NO)
+ mode=FIND_ASC_WASASC; // Unicode hack...
+ }
+ else
+ {
+ back[bp++]=buf[i]; // Store caharcetr
+ if (buf[i]!=0)
+ rej++; // Adjust reject count
+ if (buf[i]==0 || rej>tune.st_rej_limit) // If 0 or reject limit
+ {
+ bp=0; // Reset buffer pointer
+ unicode=__UNI_PROBE; // Set unicode status to unknonw
+ ffc=(buf[i]== (char) 0xff) ? 1 : 0; // reset ff count
+ zc=(buf[i]==0) ? 1 : 0; // reset zeros count
+ mode=FIND_BEGIN ; // Find leading characters mode
+ }
+ }
+ if (limit==-1) // Bug catcher
+ {
+ cerr<<"Bug: limit still -1 at point #1\n";
+ exit(2);
+ }
+ if (c==limit) // IF found enough
+ {
+#ifdef DEBUG_SKIP
+ printf("***** Enter exit phase ****\n");
+#endif
+ mode=DONE; // Finished skipping
+ }
+ break;
+
+ case DONE:
+ cerr<<"skip_to_start: loop called in done mode\n";
+ break;
+
+ default:
+ cerr<<"skip_to_start: Mode invalid\n";
+ break;
+ }
+ i++;
+ }
+#ifdef DEBUG_SKIP_MOVE
+ printf("%c%c%c\n", buf[i-bp], buf[i-bp+1], buf[i-bp+2]);
+#endif
+ memmove(buf, buf+i-bp, n-i+bp); // Move memory
+ return(n-i+bp); // Return count
+}
+
+
+/* Option handling stuff for tuning this module. Note that only long options
+ * are supported. If you lack long options these features are not avialable. */
+/* set default tuning */
+void word_junk_filter::set_dfl_tuning(void)
+{
+#ifdef AGGRESIVE_UNICODE
+ tune.options.unicode_aggresive=AGGRESIVE_UNICODE; // Aggresive unicode mode
+#else
+ tune.options.unicode_aggresive=1; // Aggresive unicode mode
+#endif /* AGGRESIVE_UNICODE */
+ tune.resume_chars=RESUME_CHARS; // Resume characters
+ tune.st_min_zeros=ST_MIN_ZEROS; // Minimum zeros
+ tune.st_rej_limit=ST_REJ_LIMIT; // Reject chars tolerance
+ tune.st_min_ff=ST_MIN_FF; // Minimum ff's (alternative to 0s)
+ tune.options.ff_intro=ALLOW_FF_LEADIN; // Enable leading ff's
+ tune.non_unicode_st=ST_ASC_VCHARS; // ok characters leadin
+ tune.unicode_st=ST_ASC_VCHARS_UNICODE; // ok unicode characters
+ tune.min_text=SINK_MIN_TEXT; // text required before sink mode
+ tune.max_junk=SINK_JUNK_CNT; // junk required for sink mode
+ tune.max_top_run=MAX_TOP_RUN; // Max run length of top bits set
+}
+
+int word_junk_filter::do_reset(void)
+{
+ pos=0;
+ init=INIT_NONE;
+ mode=NORMAL;
+ junk_end_usage=0;
+ ns=0;
+ return 1; // Success
+}
+
diff --git a/support/word2x/strip.h b/support/word2x/strip.h
new file mode 100644
index 0000000000..57da610b64
--- /dev/null
+++ b/support/word2x/strip.h
@@ -0,0 +1,135 @@
+/* $Id: junk_filter.h,v 1.16 1998/06/14 05:17:25 dps Exp $ */
+
+#ifndef __JUNK_FILTER_H__
+#define __JUNK_FILTER_H__
+#include <iostream.h>
+#include <fstream.h>
+#include <stdlib.h>
+#include "tune.h"
+
+class word_junk_filter: public streambuf
+{
+private:
+ enum { INIT_NONE, INIT_SKIPPED, INIT_DONE } init; /* Init stage */
+ istream *is; /* Data source */
+ enum
+ {
+ __UNI_PROBE, /* Unknown, probe */
+ __UNI_NO, /* No */
+ __UNI_YES_LE, /* Yes, little endian */
+ __UNI_YES_BE /* Yes, big endian */
+ } unicode; /* Unicode flag */
+
+ char junk_end_buf[RESUME_CHARS+1]; /* Junk end characters */
+ int junk_end_usage; /* Usage of junk end buffer */
+ int text_size; /* Text characters retreived */
+ int junk_size; /* Amount of junk skipped */
+
+ char buf[JUNK_FILT_BUFSIZE+2];
+ enum {
+ NORMAL, UNICODE_Z, /* Unicode, Unicode zero expected */
+ SKIP_JUNK, SKIP_JUNK_WASPRN, /* Skip junk, Skip junk was printable */
+ SINK_JUNK, /* Like skip junk with more restart */
+ } mode;
+ char save;
+ int ns;
+
+ /* Tunable stuff */
+ struct
+ {
+ int st_min_zeros; // Minimum leading zeros
+ int st_min_ff; // Minimum leadingg ff characters
+ int st_rej_limit; // Non-printing characters tolerated
+ int non_unicode_st; // Not unicode start treshold
+ int unicode_st; // Unicode start treshold
+ int max_junk; // Junk required to trigger SINK_JUNK mode
+ int min_text; // Text required to trigger SINK_JUNK mode
+ int max_top_run; // Max top bit set run
+ struct
+ {
+ unsigned unicode_aggresive: 1; // Aggresive unicode mod
+ unsigned ff_intro:1; // Allow ff leadin characters
+ } options;
+ int resume_chars; // Good characters need to stop junk skipping
+ } tune;
+ void set_dfl_tuning(void); // Set default tuning
+
+ int __fill(const char *, int, int, int);
+ int filter_junk(const char *, int);
+ int skip_to_start(void);
+ long pos;
+
+
+
+public:
+ inline int overflow(int ch)
+ {
+ ch=ch;
+ return EOF; /* ZXZ */
+ }
+ inline int sync(void)
+ {
+ return 0;
+ }
+
+ int underflow(void);
+ int do_reset(void);
+ inline int __uflow(void) { return this->underflow(); }
+
+ inline void open(istream *s)
+ {
+ if (is!=NULL)
+ delete(is);
+ is=s;
+ pos=0;
+ init=INIT_NONE;
+ mode=NORMAL;
+ junk_end_usage=0;
+ ns=0;
+ }
+
+ inline word_junk_filter(void)
+ {
+ set_dfl_tuning(); // Set default tuning
+ is=NULL;
+ init=INIT_NONE;
+ }
+
+ inline word_junk_filter(istream *s)
+ {
+ set_dfl_tuning(); // Set default tuning
+ pos=0;
+ init=INIT_NONE;
+ junk_end_usage=0;
+ is=s;
+ mode=NORMAL;
+ ns=0;
+ }
+
+ inline word_junk_filter(const char *f)
+ {
+ ifstream *s;
+
+ set_dfl_tuning(); // Set default tuning
+ s=new(ifstream)(f);
+ if (!(*s))
+ {
+ cerr<<"Can not open "<<f<<" (fatal)\n";
+ exit(1);
+ }
+ is=s;
+ pos=0;
+ init=INIT_NONE;
+ junk_end_usage=0;
+ mode=NORMAL;
+ ns=0;
+ }
+
+ inline ~word_junk_filter(void)
+ {
+ if (is!=NULL)
+ delete(is);
+ }
+};
+
+#endif /* __JUNK_FILTER_H__ */
diff --git a/support/word2x/tblock.cc b/support/word2x/tblock.cc
new file mode 100644
index 0000000000..1ede6d9608
--- /dev/null
+++ b/support/word2x/tblock.cc
@@ -0,0 +1,242 @@
+/* $Id: tblock.cc,v 1.3 1997/03/21 20:34:11 dps Exp $ */
+/* Dynamically growinf text block */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <iostream.h>
+#include "tblock.h"
+
+const struct tblock::block tblock::dummy_init={0,0,NULL,NULL};
+
+tblock::~tblock(void)
+{
+ struct block *blk, *nblk;
+ blk=dummy_block.next;
+ while (blk!=NULL)
+ {
+ nblk=blk->next;
+ free(blk->text);
+ free(blk);
+ blk=nblk;
+ }
+}
+
+void tblock::zero(void)
+{
+ struct block *blk, *nblk;
+ blk=dummy_block.next;
+ while (blk!=NULL)
+ {
+ nblk=blk->next;
+ free(blk->text);
+ free(blk);
+ blk=nblk;
+ }
+ dummy_block=dummy_init;
+ head=&dummy_block;
+}
+
+int tblock::add(char c)
+{
+ struct block *blk, *nb;
+ blk=head;
+ if (blk->limit==blk->pos)
+ {
+ if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
+ return 0;
+ if ((nb->text=(char *) malloc(block_size))==NULL)
+ {
+ free(nb);
+ return 0;
+ }
+ nb->limit=1024;
+ nb->pos=0;
+ nb->next=NULL;
+ head->next=nb;
+ head=nb;
+ }
+ head->text[(head->pos)++]=c;
+ return 1;
+}
+
+int tblock::add(const char *s, int len)
+{
+ struct block *nb;
+ const char *t;
+ int size;
+
+ if (*s=='\0')
+ return 1;
+
+ t=s;
+
+ while (len>0)
+ {
+ if (head->limit==head->pos)
+ {
+ if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
+ return 0;
+ if ((nb->text=(char *) malloc(block_size))==NULL)
+ {
+ free(nb);
+ return 0;
+ }
+ nb->limit=block_size;
+ nb->pos=0;
+ nb->next=NULL;
+ head->next=nb;
+ head=nb;
+ }
+ size=head->limit-head->pos;
+ if (size>len)
+ size=len;
+ memcpy(head->text+head->pos, t, size);
+ head->pos+=size;
+ len-=size;
+ t+=size;
+ }
+ return 1;
+}
+
+const char *tblock::collect(void) const
+{
+ struct block *blk;
+ char *s,*t;
+ size_t size;
+
+ size=0;
+ blk=dummy_block.next;
+ while (blk!=NULL)
+ {
+ size+=blk->pos;
+ blk=blk->next;
+ }
+
+ if ((t=(char *) malloc(size+1))==NULL)
+ {
+ cerr<<"tblock::collect malloc failure\n";
+ return NULL;
+ }
+
+ s=t; blk=dummy_block.next;
+ while (blk!=NULL)
+ {
+ memcpy(s, blk->text, blk->pos);
+ s+=blk->pos;
+ blk=blk->next;
+ }
+ *s='\0';
+ return t;
+}
+
+
+tblock &tblock::operator=(const tblock &arg)
+{
+ struct block *nb,*blk;
+ const char *s;
+
+ blk=dummy_block.next;
+ while (blk!=NULL)
+ {
+ nb=blk->next;
+ free(blk->text);
+ free(blk);
+ blk=nb;
+ }
+
+ if ((s=arg.collect())==NULL)
+ {
+ cerr<<"tblock:operator= fatal malloc failure\n";
+ exit(2);
+ }
+
+ if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
+ {
+ cerr<<"tblock:operator= fatal malloc failure\n";
+ exit(2);
+ }
+
+ nb->limit=strlen(s)+1; // Limit includes '\0'
+ nb->pos=strlen(s); // Do include '\0' in used characters
+ nb->text=(char *) s;
+ nb->next=NULL;
+ dummy_block.next=nb;
+ head=nb;
+
+ return *this;
+}
+
+tblock::tblock(const tblock &cpy)
+{
+ struct block *nb;
+ const char *s;
+
+ if ((s=cpy.collect())==NULL)
+ {
+ cerr<<"tblock::tblock(const tblock &) fatal malloc failure\n";
+ exit(2);
+ }
+
+ if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
+ {
+ cerr<<"tblock::tblock(const tblock &) fatal malloc failure\n";
+ exit(2);
+ }
+
+ nb->limit=strlen(s)+1; // Inlcude '\0' in limit
+ nb->pos=strlen(s); // DO not include '\0' in used
+ nb->text=(char *) s;
+ nb->next=NULL;
+ dummy_block.next=nb;
+ dummy_block.pos=0;
+ dummy_block.limit=0;
+ dummy_block.text=NULL;
+ head=nb;
+}
+
+
+tblock::operator const char *()
+{
+ struct block *nb;
+ const char *s;
+
+
+ if (dummy_block.next==head)
+ {
+ *(head->text+head->pos)='\0';
+ return ((const char *) (head->text));
+ }
+
+ if ((s=this->collect())==NULL)
+ {
+ cerr<<"tblock::const char * fatal malloc failure\n";
+ exit(2);
+ }
+
+ if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
+ {
+ cerr<<"tblock::const char * fatal malloc failure\n";
+ exit(2);
+ }
+
+ nb->limit=strlen(s)+1; // Inlcude '\0' in limit
+ nb->pos=strlen(s); // DO not include '\0' in used
+ nb->text=(char *) s;
+ nb->next=NULL;
+ this->zero(); // Wipe current data
+ dummy_block.next=nb;
+ dummy_block.pos=0;
+ dummy_block.limit=0;
+ dummy_block.text=NULL;
+ head=nb;
+
+ return s;
+}
diff --git a/support/word2x/tblock.h b/support/word2x/tblock.h
new file mode 100644
index 0000000000..0879ace8bb
--- /dev/null
+++ b/support/word2x/tblock.h
@@ -0,0 +1,46 @@
+/* $Id: tblock.h,v 1.2 1997/03/21 20:20:53 dps Exp $ */
+/* Dynamically grown text block */
+
+#ifndef __tblock_h__
+#define __tblock_h__
+
+class tblock
+{
+private:
+ struct block
+ {
+ int limit;
+ int pos;
+ char *text;
+ struct block *next;
+ };
+
+ struct block dummy_block;
+ struct block *head;
+
+ static const struct block dummy_init;
+ static const int block_size=1024;
+
+ const char *collect(void) const;
+
+public:
+ inline tblock(void)
+ {
+ dummy_block=dummy_init;
+ head=&dummy_block;
+ }
+ tblock(const tblock &);
+
+ ~tblock(void);
+ void zero(void);
+ int add(char);
+ int add(const char *, int);
+ inline int add(const char *s)
+ {
+ return this->add(s, strlen(s));
+ }
+ tblock &operator=(const tblock &);
+ operator const char *();
+};
+
+#endif
diff --git a/support/word2x/tblock.h.orig b/support/word2x/tblock.h.orig
new file mode 100644
index 0000000000..8aef3cd471
--- /dev/null
+++ b/support/word2x/tblock.h.orig
@@ -0,0 +1,48 @@
+/* $Id: tblock.h,v 1.2 1997/03/21 20:20:53 dps Exp $ */
+/* Dynamically grown text block */
+
+#ifndef __tblock_h__
+#define __tblock_h__
+
+#include <strings.h>
+
+class tblock
+{
+private:
+ struct block
+ {
+ int limit;
+ int pos;
+ char *text;
+ struct block *next;
+ };
+
+ struct block dummy_block;
+ struct block *head;
+
+ static const struct block dummy_init;
+ static const int block_size=1024;
+
+ const char *collect(void) const;
+
+public:
+ inline tblock(void)
+ {
+ dummy_block=dummy_init;
+ head=&dummy_block;
+ }
+ tblock(const tblock &);
+
+ ~tblock(void);
+ void zero(void);
+ int add(char);
+ int add(const char *, int);
+ inline int add(const char *s)
+ {
+ return this->add(s, strlen(s));
+ }
+ tblock &operator=(const tblock &);
+ operator const char *();
+};
+
+#endif
diff --git a/support/word2x/text-fmt.cc b/support/word2x/text-fmt.cc
new file mode 100644
index 0000000000..3d032462b9
--- /dev/null
+++ b/support/word2x/text-fmt.cc
@@ -0,0 +1,287 @@
+/* $Id: text-fmt.cc,v 1.13 1997/04/13 04:15:33 dps Exp $ */
+
+/* Everything is declared as static to avoid namespace polution but */
+/* is reachable externally via the exported table (and this it the */
+/* only way they get called). */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* Do not have alloca.h */
+ #ifdef _AIX
+#pragma alloca
+#else /* not _AIX */
+extern "C" char *alloca(int);
+#endif /* _AIX */
+#endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "interface.h"
+#include "lib.h"
+#include "text-table.h"
+
+/* Local data */
+struct text_data
+{
+ text_table *tabl;
+ int col;
+ int row;
+ int margin;
+ int l_indent;
+};
+
+/* Most of these values are thanks to catdoc by
+ * Victor B. Wagner <vitus@agropc.msk.su> et al */
+static const cmap char_map[]=
+{
+ { 0x1E, "-" }, // Unbreakable join
+ { 0x1F, "" }, // Soft hypen
+ { 0x7f, "" }, // Delete 127s
+ { 0x85, "..." }, // Dots
+ { 0x91, "`" }, // 91 = left quote
+ { 0x92, "'" }, // 92 = right quote
+ { 0x93, "\"" }, // 93 = opening double quote
+ { 0x94, "\"" }, // 94 = closing double quote
+ { 0x95, "o" }, // 95 = Bullet
+ { 0x96, "-" }, // em-dash
+ { 0x97, "-" }, // en-dash
+ { 0x99, "(tm)" }, // Trademark
+ { 0xA0, " " }, // Unbreakable space
+ { 0xA3, "<=" }, // Less than or = came out as A3
+ { 0xA9, "(c)" }, // Copyright
+ { 0xAB, "<<" }, // Openning << quotes
+ { 0xAE, "(R)" }, // Reserved sign
+ { 0xB3, ">=" }, // Greater than or = came out as B3
+ { 0xBB, ">>" }, // Closing >> quotes
+};
+
+/* Allocate local data */
+static void *allocate_txt(void)
+{
+ struct text_data *tdata;
+
+ tdata=new(struct text_data);
+ tdata->tabl=NULL;
+ tdata->margin=0;
+ tdata->l_indent=0;
+ return tdata;
+}
+
+static void txt_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ d=d;
+ switch(*(t->data.d))
+ {
+ case CH_PAGE:
+ if (fmt->flags.new_pages)
+ fputc('\014', out);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Free local data */
+static void free_txt(void *d)
+{
+ struct text_data *tdata;
+
+ tdata=(struct text_data *) d;
+ if (tdata->tabl!=NULL)
+ delete(tdata->tabl);
+}
+
+
+/* list start increases margin */
+static void inc_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+ t=t;
+ fmt=fmt;
+ out=out;
+
+ tdata=(struct text_data *) d;
+ tdata->margin+=4;
+}
+
+
+/* list start decreases margin */
+static void dec_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+ t=t;
+ fmt=fmt;
+ out=out;
+
+ tdata=(struct text_data *) d;
+ tdata->margin-=4;
+}
+
+
+/* items are easy */
+static void txt_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ tblock *ts;
+ const char *s;
+ int i, m;
+ struct text_data *dp;
+
+ fmt=fmt; // No need for fmt
+ dp=(struct text_data *) d;
+ ts=map_string(t->data.d, char_map);
+ s=*ts;
+ fputc('\n', out);
+ m=dp->margin-strlen(s)-1;
+ for (i=0; i<m; i++)
+ fputc(' ', out);
+ fputs(s, out);
+ fputc(' ', out);
+ dp->l_indent=dp->margin;
+ delete(ts);
+}
+
+
+/* Paragraphs are easy */
+static void fold_para(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ tblock *b, *ts;
+ const char *s;
+ char *nl;
+ struct text_data *dp;
+ int i;
+
+ dp=(struct text_data *) d;
+ if (dp->margin==0 || (nl=(char *) alloca(dp->margin+2))==NULL)
+ nl="\n";
+ else
+ {
+ *nl='\n';
+ for (i=1; i<=dp->margin; i++)
+ *(nl+i)=' ';
+ *(nl+dp->margin+1)='\0';
+ }
+ ts=map_string(t->data.d, char_map);
+ b=word_wrap((*ts), nl, nl, fmt->maxline-(dp->margin), 0);
+ delete(ts);
+ s=*b;
+ for (i=dp->l_indent; i<dp->margin; i++)
+ fputc(' ', out);
+ fputs(s, out);
+ fputs("\n\n", out);
+ dp->l_indent=0;
+ delete(b);
+}
+
+/* Start a table === allocate table and initialise */
+static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ tdata=(struct text_data *) d;
+ tdata->col=0;
+ tdata->row=0;
+ tdata->tabl=new(text_table)(t->data.table.cols, t->data.table.rows);
+}
+
+
+/* End of a table==print the table */
+static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+
+ t=t;
+ tdata=(struct text_data *) d;
+ tdata->tabl->print_table(fmt->maxline, out); // Print table
+ delete(tdata->tabl);
+ tdata->tabl=NULL;
+}
+
+/* start row==set column to 0 */
+static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct text_data *) d;
+ tdata->col=0;
+}
+
+/* end row==add one to row */
+static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct text_data *) d;
+ tdata->row++;
+}
+
+
+/* Start field === set field */
+static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct tblock *ts;
+ struct text_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ ts=map_string(t->data.d, char_map);
+ tdata=(struct text_data *) d;
+ tdata->tabl->set(tdata->col, tdata->row, (*ts));
+ delete(ts);
+}
+
+/* end field==add one to col */
+static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
+ void *d)
+{
+ struct text_data *tdata;
+
+ out=out;
+ fmt=fmt;
+ t=t;
+ tdata=(struct text_data *) d;
+ tdata->col++;
+}
+
+/* pointers to the functions that do the work */
+docfmt txtfmt=
+{
+ { 0 }, // No page breaks
+ 76, // Width
+ "\n", // Use \n as line ends
+ allocate_txt, // Allocate space
+ free_txt, // Free text
+ {
+ { null_proc, null_proc }, // End and start of document---do nothing
+ { fold_para, null_proc }, // Paragraph
+ { alloc_tbl, format_tbl }, // Start/end table
+ { set_field, inc_col }, // Start/end field
+ { start_row, inc_row }, // Start/end row
+ { null_proc, null_proc }, // Throw away embed messages
+ { inc_margin, dec_margin }, // list start and end
+ { txt_item, null_proc}, // Items
+ { txt_code, null_proc}, // Code
+ { null_proc, null_proc } // Do not understanding anything else
+ }
+};
diff --git a/support/word2x/text-table.cc b/support/word2x/text-table.cc
new file mode 100644
index 0000000000..cd2c9887c9
--- /dev/null
+++ b/support/word2x/text-table.cc
@@ -0,0 +1,337 @@
+/* $Id: text-table.cc,v 1.14 1997/04/13 04:26:42 dps Exp $ */
+/* Ascii table layout */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* Do not have alloca.h */
+#ifdef _AIX
+ #pragma alloca
+#else /* not _AIX */
+extern "C" char *alloca(int);
+#endif /* _AIX */
+#endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include "tblock.h"
+#include "text-table.h"
+#include "lib.h"
+
+struct rdata
+{
+ struct wd_info w;
+ const char *data;
+};
+
+
+/* Print out a number of spaces */
+static inline void p_sp(int n, FILE *out)
+{
+ int i;
+
+ for (i=0; i<n; i++)
+ fputc(' ', out);
+}
+
+/* Print row after folding of columns has been done */
+static void basic_print_row(int ncols,
+ const struct rdata *cols,
+ char sep, FILE *out)
+{
+ const char **lptr, *s, *t;
+ int i, flg, nsp;
+ align_t al;
+ num_info n;
+
+ /* Alloca line position pointers */
+ if ((lptr=(const char **) alloca(ncols*sizeof(const char *)))==NULL)
+ {
+ fprintf(stderr, "basic_print_row: fatal alloca failure\n");
+ exit(1);
+ }
+
+ for (i=0; i<ncols; i++)
+ lptr[i]=cols[i].data;
+
+ while (1)
+ {
+ /* Check for some content */
+ flg=0;
+ for (i=0; i<ncols; i++)
+ if (*lptr[i]!='\0')
+ flg=1;
+ if (!flg) break;
+
+ /* Print the content */
+ for (i=0; i<ncols; i++)
+ {
+ s=lptr[i];
+
+ /* Find the extent and decimal point pos of current item */
+ for (t=s, nsp=cols[i].w.width; *t!='\0'; nsp--, t++)
+ {
+ if (*t=='\n')
+ break;
+ }
+
+ if (s==t)
+ {
+ p_sp(nsp, out);
+ }
+ else
+ {
+ /* There is some content, print it */
+ al=cols[i].w.align;
+ if (cols[i].w.dp_col>=0)
+ {
+ n=scan_num(s);
+ if (n.dot_pos!=-1)
+ {
+ p_sp(cols[i].w.dp_col-n.dot_pos, out);
+ fwrite((void *) s, sizeof(char), t-s, out);
+ p_sp(nsp-cols[i].w.dp_col+n.dot_pos, out);
+ al=ALIGN_DP;
+ }
+ }
+
+ switch(al)
+ {
+ case ALIGN_DP:
+ break;
+
+ case ALIGN_LEFT:
+ fwrite((void *) s, sizeof(char), t-s, out);
+ p_sp(nsp, out);
+ break;
+
+ case ALIGN_CENTER:
+ p_sp(nsp/2, out);
+ fwrite((void *) s, sizeof(char), t-s, out);
+ p_sp(nsp-(nsp/2), out); // Avoid rounding related problems
+ break;
+
+ case ALIGN_RIGHT:
+ p_sp(nsp, out);
+ fwrite((void *) s, sizeof(char), t-s, out);
+ break;
+
+ default:
+ fprintf(stderr,"basic_print_row: Invalid alignment\n");
+ break;
+ }
+ }
+ fputc(sep, out); // Seperate columns by a space
+
+ /* Update lptr[i] */
+ if (*t=='\n')
+ t++; // Advance past newlines;
+ lptr[i]=t;
+ }
+ fputc('\n', out); // Print out a newline
+ }
+}
+
+/* Split the elements of a row */
+static void print_row(int ncols, const struct rdata *dp, FILE *out)
+{
+ static const char null_string[]={'\0'};
+ struct rdata *rd;
+ tblock *d;
+ char *s, *t;
+ int i;
+
+ /* Allocate structures */
+ if ((rd=(struct rdata *) alloca(ncols*sizeof(rdata)))==NULL)
+ {
+ fprintf(stderr, "print_row: fatal alloca failure\n");
+ exit(1);
+ }
+
+ /* Fold lines */
+ for (i=0; i<ncols; i++)
+ {
+ rd[i].w=dp[i].w;
+ if (dp[i].data==NULL)
+ {
+ rd[i].data=null_string; // Avoid complication of null in
+ // basic_print_row
+ continue; // Move on to next item
+ }
+
+ d=word_wrap(dp[i].data, "\n", "\n", dp[i].w.width, 0);
+ if ((rd[i].data=strdup(*d))==NULL)
+ {
+ fprintf(stderr, "text_table::print_row: fatal alloca failure\n");
+ exit(1);
+ }
+ else
+ {
+ /* Filter out CH_SUSPECT */
+ for(s=t=(char *) rd[i].data; *s!='\0'; s++)
+ {
+ if (*s==CH_SUSPECT)
+ continue;
+ *(t++)=*s;
+ }
+ *t='\0';
+ }
+ delete(d);
+ }
+ basic_print_row(ncols, rd, ' ', out); // Printing the rows is actually
+ // quite complex.
+ for (i=0; i<ncols; i++)
+ {
+ if (rd[i].data!=null_string)
+ free((void *) rd[i].data); // Free data
+ }
+}
+
+
+/* O(n^2) table width reduction algorithm, n is small in almost all cases */
+static void shrink_widths(int ncols, struct rdata *cols, int mtw)
+{
+ int i, j, tw, maxw;
+
+ for (tw=0, i=0; i<ncols; i++)
+ tw+=cols[i].w.width;
+
+ mtw-=ncols; // Take account of column seperators
+
+ /* Simply reduce the maximum width column width by one until
+ enougn has been trimed */
+ while (tw>mtw)
+ {
+ maxw=0; j=-1;
+ for (i=0; i<ncols; i++)
+ {
+ if (maxw<cols[i].w.width && cols[i].w.align!=ALIGN_DP)
+ {
+ j=i;
+ maxw=cols[i].w.width;
+ }
+ }
+
+ if (j==-1)
+ {
+ fprintf(stderr, "Can not shrink overwidth table\n");
+ continue;
+ }
+ cols[j].w.width--;
+ tw--;
+ }
+}
+
+/* Returns NULL or text message */
+const char *text_table::print_table(int wd, FILE *out)
+{
+ int i,j;
+ struct rdata *d;
+ const struct col_info *col;
+
+ if ((d=(struct rdata *) alloca(cols*sizeof(struct rdata)))==NULL)
+ {
+ cerr<<"text_table::print_table alloca failute (fatal)\n";
+ return "[Table omitted due to lack of memory]";
+ }
+ if (cols==0 || rows==0)
+ {
+ fputs("[empty tabel ignored]\n", out);
+ return "[Ignored empty table]";
+ }
+
+ for (i=0, col=cdata; col!=NULL; i++, col=col->next)
+ d[i].w=find_width(rows, col->data);
+ shrink_widths(cols, d, wd);
+
+ for (i=0; i<rows; i++)
+ {
+ for (j=0, col=cdata; col!=NULL; j++, col=col->next)
+ d[j].data=(col->data)[i];
+ print_row(cols, d, out);
+ }
+ return NULL;
+}
+
+/* Set */
+int text_table::set(int c, int r, const char *s)
+{
+ struct col_info *col;
+ int i;
+
+ if (c<0 || c>=cols || r<0 || r>=rows)
+ {
+ cerr<<"Invalid request to set "<<c<<','<<r<<" in "
+ <<cols<<'x'<<rows<<" table (value "<<s<<")\n";
+ return 0;
+ }
+
+ for (col=cdata, i=0; i<c && col!=NULL; i++, col=col->next) ;
+ if (col!=NULL)
+ {
+ if (col->data[r]!=NULL)
+ free((void *) col->data[r]);
+ col->data[r]=strdup(s);
+ }
+ return 1;
+}
+
+
+/* Constructor */
+text_table::text_table(int c, int r)
+{
+ int i, j;
+ struct col_info *col, **nptr;
+
+ cols=c;
+ rows=r;
+ cdata=NULL; // Hardenning against cols=0
+ for (nptr=&cdata, i=0; i<cols; i++)
+ {
+ col=new(struct col_info);
+ *nptr=col;
+ col->next=NULL;
+ nptr=&(col->next);
+ if ((col->data=
+ (const char **) malloc(rows*(sizeof(const char *))))==NULL)
+ {
+ cerr<<"text_table::constructor: malloc failure (fatal)\n";
+ exit(1);
+ }
+ for (j=0; j<rows; j++)
+ (col->data)[j]=NULL;
+ }
+}
+
+/* Destructor */
+text_table::~text_table()
+{
+ int i;
+ struct col_info *col, *nxt;
+
+ for (col=cdata; col!=NULL;)
+ {
+ for (i=0; i<rows; i++)
+ if (col->data[i]==NULL)
+ free((void *) col->data[i]);
+ nxt=col->next;
+ free(col);
+ col=nxt;
+ }
+}
diff --git a/support/word2x/text-table.h b/support/word2x/text-table.h
new file mode 100644
index 0000000000..8536bb16e5
--- /dev/null
+++ b/support/word2x/text-table.h
@@ -0,0 +1,25 @@
+/* $Id: text-table.h,v 1.2 1997/03/22 17:07:58 dps Exp $ */
+
+#ifndef __txt_table__
+#define __txt_table__
+#include <stdio.h>
+
+class text_table
+{
+private:
+ struct col_info
+ {
+ const char **data;
+ struct col_info *next;
+ };
+ int cols;
+ int rows;
+ struct col_info *cdata;
+
+public:
+ const char *print_table(int, FILE *);
+ int set(int, int, const char *);
+ text_table(int, int);
+ ~text_table(void);
+};
+#endif /* __txt_table__ */
diff --git a/support/word2x/transcript b/support/word2x/transcript
new file mode 100644
index 0000000000..51842339c0
--- /dev/null
+++ b/support/word2x/transcript
@@ -0,0 +1,83 @@
+word2x build transcript
+Note: the prompts are simulated. All the rest is real.
+Simulation> ./configure
+creating cache ./config.cache
+checking for gcc... gcc
+checking whether the C compiler (gcc ) works... yes
+checking whether the C compiler (gcc ) is a cross-compiler... no
+checking whether we are using GNU C... yes
+checking whether gcc accepts -g... yes
+checking for c++... c++
+checking whether the C++ compiler (c++ ) works... yes
+checking whether the C++ compiler (c++ ) is a cross-compiler... no
+checking whether we are using GNU C++... yes
+checking whether c++ accepts -g... yes
+checking for ranlib... ranlib
+checking for a BSD compatible install... /usr/bin/install -c
+checking for getopt_long... yes
+checking how to run the C preprocessor... gcc -E
+checking for working alloca.h... yes
+checking for alloca... yes
+checking whether time.h and sys/time.h may both be included... yes
+checking whether struct tm is in sys/time.h or time.h... time.h
+checking header file for SEEK_SET... <stdio.h>
+checking for ANSI C header files... yes
+checking for ctype.h... yes
+checking for string.h... yes
+checking for strings.h... yes
+checking for time.h... yes
+checking for sys/time.h... yes
+checking for sys/stat.h... yes
+checking for unistd.h... yes
+checking for alloca.h... (cached) yes
+checking for strncasecmp... yes
+checking for strcasecmp... yes
+checking for strdup... yes
+checking for localtime... yes
+checking for fstat... yes
+checking for in -lsun... no
+checking if I know ld and c++ might not work together
+checking host system type... i686-pc-linux-gnu
+checking target system type... i686-pc-linux-gnu
+checking build system type... i686-pc-linux-gnu
+Using ld, as on i686-pc-linux-gnu I know ld and c++ mix
+updating cache ./config.cache
+creating ./config.status
+creating Makefile
+creating config.h
+Simulation> make all
+make[1]: Entering directory `/home/dps/word2x/word2x-0.002/word2x'
+c++ -g -Wall -DHAVE_CONFIG_H -c -o reader.o reader.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o strip.o strip.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o word2x.o word2x.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o text-fmt.o text-fmt.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o text-table.o text-table.cc
+ld -r -o fmt-text.o text-fmt.o text-table.o
+c++ -g -Wall -DHAVE_CONFIG_H -c -o latex-fmt.o latex-fmt.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o latex-table.o latex-table.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o latex-embed.o latex-embed.cc
+ld -r -o fmt-latex.o latex-fmt.o latex-table.o latex-embed.o
+c++ -g -Wall -DHAVE_CONFIG_H -c -o html-fmt.o html-fmt.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o html-table.o html-table.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o html-embed.o html-embed.cc
+ld -r -o fmt-html.o html-fmt.o html-table.o html-embed.o
+c++ -g -Wall -DHAVE_CONFIG_H -c -o dedate.o dedate.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o deL1date.o deL1date.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o deHTMLdate.o deHTMLdate.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o ukdate.o ukdate.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o usdate.o usdate.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o wordwrap.o wordwrap.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o nullproc.o nullproc.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o tblock.o tblock.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o scan_num.o scan_num.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o map_chars.o map_chars.cc
+c++ -g -Wall -DHAVE_CONFIG_H -c -o col-align.o col-align.cc
+gcc -g -Wall -DHAVE_CONFIG_H -c compat.c -o compat.o
+gcc -g -Wall -DHAVE_CONFIG_H -c num_unit_probe.c -o num_unit_probe.o
+gcc -g -Wall -DHAVE_CONFIG_H -c part_num_probe.c -o part_num_probe.o
+ar rc liboutfmt.a wordwrap.o nullproc.o tblock.o scan_num.o map_chars.o col-align.o compat.o num_unit_probe.o part_num_probe.o
+ranlib liboutfmt.a
+c++ -o word2x reader.o strip.o word2x.o fmt-text.o fmt-latex.o fmt-html.o dedate.o deL1date.o deHTMLdate.o ukdate.o usdate.o liboutfmt.a
+c++ -g -Wall -DHAVE_CONFIG_H -c -o rtest2.o rtest2.cc
+g++ -o rtest2 rtest2.o reader.o strip.o tblock.o
+make[1]: Leaving directory `/home/dps/word2x/word2x-0.002/word2x'
diff --git a/support/word2x/tune.h b/support/word2x/tune.h
new file mode 100644
index 0000000000..c589adb7ec
--- /dev/null
+++ b/support/word2x/tune.h
@@ -0,0 +1,30 @@
+/* $Id: tuneable.h,v 1.14 1998/06/14 05:20:11 dps Exp $ */
+/* These are tuneable within limits */
+
+#ifndef __TUNE_H__
+#define __TUNE_H__
+
+/* Junk filter tuneables */
+#define JUNK_FILT_BUFSIZE 1025
+#define RESUME_CHARS 30
+/* Min zeros before text to trigger document start */
+#define ST_MIN_ZEROS 16
+/* All ff text prelude options */
+#define ALLOW_FF_LEADIN 1
+#define ST_MIN_FF 30
+/* sink junk mode trigger parameters */
+#define SINK_MIN_TEXT 500
+#define SINK_JUNK_CNT 4500
+/* Max top bit ste run */
+#define MAX_TOP_RUN 5
+/* Not unicode */
+#define ST_ASC_VCHARS 30
+/* Rejects limit */
+#define ST_REJ_LIMIT 10
+/* Due to unicode OLE filename make with >32 or else */
+#define ST_ASC_VCHARS_UNICODE 40
+/* Make sure a unicode document restarts in unicode? */
+#define AGGRESSIVE_UNICODE 1
+
+#endif /* __TUNE_H__ */
+
diff --git a/support/word2x/ukdate.cc b/support/word2x/ukdate.cc
new file mode 100644
index 0000000000..5f7a09bf2e
--- /dev/null
+++ b/support/word2x/ukdate.cc
@@ -0,0 +1,61 @@
+/* $Id: ukdate.cc,v 1.4 1997/04/13 15:42:32 dps Exp $ */
+/* Date formatter for the UK */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#ifdef TM_IN_SYS_TIME
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+char *uk_date(time_t when)
+{
+ static const char *months[]=
+ {
+ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December",
+ };
+
+ struct tm *tim;
+ char date_buf[200];
+ const char *postfix;
+
+ tim=localtime(&when);
+ switch (tim->tm_mday % 10)
+ {
+ case 1:
+ postfix="st";
+ break;
+
+ case 2:
+ postfix="nd";
+ break;
+
+ case 3:
+ postfix="rd";
+ break;
+
+ default:
+ postfix="th";
+ break;
+ }
+ if (tim->tm_mday > 10 && tim->tm_mday < 14) postfix="th";
+
+ sprintf(date_buf, "%d%s %s, %d", tim->tm_mday, postfix,
+ months[tim->tm_mon], 1900+tim->tm_year);
+
+ return strdup(date_buf);
+}
+
+
+
diff --git a/support/word2x/usdate.cc b/support/word2x/usdate.cc
new file mode 100644
index 0000000000..1ecdd3ad51
--- /dev/null
+++ b/support/word2x/usdate.cc
@@ -0,0 +1,65 @@
+/* $Id: usdate.cc,v 1.5 1997/04/13 15:46:48 dps Exp $ */
+/* Date formatter for the UK */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef TM_IN_SYS_TIME
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#define __EXCLUDE_READER_CLASSES
+#include "lib.h"
+
+char *us_date(time_t when)
+{
+ static const char *months[]=
+ {
+ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December",
+ };
+
+ struct tm *tim;
+ char date_buf[200];
+ const char *postfix;
+
+ tim=localtime(&when);
+ switch (tim->tm_mday % 10)
+ {
+ case 1:
+ postfix="st";
+ break;
+
+ case 2:
+ postfix="nd";
+ break;
+
+ case 3:
+ postfix="rd";
+ break;
+
+ default:
+ postfix="th";
+ break;
+ }
+ if (tim->tm_mday > 10 && tim->tm_mday < 14) postfix="th";
+
+ sprintf(date_buf, "%s %d%s, %d", months[tim->tm_mon],
+ tim->tm_mday, postfix, 1900+tim->tm_year);
+
+ return strdup(date_buf);
+}
+
+
+
diff --git a/support/word2x/use_getopt.h b/support/word2x/use_getopt.h
new file mode 100644
index 0000000000..c7ef3387cb
--- /dev/null
+++ b/support/word2x/use_getopt.h
@@ -0,0 +1,8 @@
+/* $Id: use_getopt.h,v 1.1 1997/04/07 17:27:21 dps Exp $ */
+#ifndef __USE_GETOPT_H__
+#define __USE_GETOPT_H__
+
+#define getopt_long(a,b,c,d,e) getopt(a,b,c)
+#define NO_LONG_OPTS 1
+
+#endif /* __USE_GETOPT_H__ */
diff --git a/support/word2x/word2x b/support/word2x/word2x
new file mode 100755
index 0000000000..e8b419f15a
--- /dev/null
+++ b/support/word2x/word2x
Binary files differ
diff --git a/support/word2x/word2x.1 b/support/word2x/word2x.1
new file mode 100644
index 0000000000..06bf9ff9d9
--- /dev/null
+++ b/support/word2x/word2x.1
@@ -0,0 +1,103 @@
+.\" $Id: word2x.1,v 1.4 1997/04/10 21:30:05 dps Exp $
+.TH word2x 1 "1st April 1997" "Duncan Simpson" "LOCAL COMMANDS"
+.SH NAME
+word2x \- convert word 6 documents to another format
+
+.SH SYNOPSIS
+.B word2x
+[-Vhvq] [-w width] [-f format] [-d date-style] files...
+
+.SH DESCRIPTION
+.I word2x
+is a program that attempts to produce a component, if not perfect
+rendition of a word 6 document. It guesses rather a lot from context
+and can make mistakes. Pictures are not supported and will not
+appear. There is very limited maths support in LaTeX mode, mainly due
+to lack of samples of mathematics. (I probably should have done this
+using TeX catcode and macro magic, instead of writing special code).
+
+Input files must be seekable and therefore stdin is not allowed. The
+files argument is of the form
+.IR "input file" ", " "output file" ", " "input file" ", " "output file"
+etc. \- may be used for stdout in the output file. If the output file
+is not sepcified a named is generated by adding on an appropiate
+suffix in place of .DOC (or .doc). Both .DOC and .doc are added
+automatically if the file name specified can not be found.
+
+As a special exception to the above any file ending on .doc or .DOC is
+assumed to be an input file. This allows one to type
+.BR "word2x -f latex *.DOC" ,
+for example.
+
+.SH OPTIONS
+.TP
+.B -V, --version
+print version on stderr and exit.
+.TP
+.B -h, --help
+show synopsis, output and date formats supported.
+.TP
+.B -v, --verbose
+be (moderately) verbose
+.TP
+.B -q, --quiet
+supress non-error messages (this is the default).
+.TP
+.B -w, --width
+set the maximum width of a line in the output
+.TP
+.B -d, --dates
+set the date format. Currently the formats supported are
+.IR uk ", " british ", " us .
+.I uk
+dates are
+.IR "22nd April, 1997" ,
+for example and US style dates
+.IR "April 22nd, 1997" .
+.I british
+is a synonym for
+.IR uk .
+The default is
+.IR uk .
+.TP
+.B -f, --format
+Set the output format. Currently
+.I text
+and
+.I latex
+are supported. The LaTeX output requires the AMS LaTeX package and
+LaTeX 2e. It should be reasonably easy to add another format, however
+some formats do a large amount of context guesswork, for example the
+LaTeX format (esp. in the paragraph handling code).
+.I text
+is the default.
+
+.SH BUGS
+
+One argument does not produce output on stdout
+
+The reader sometimes generates error messages when it is confused.
+
+The equation support is limited to only fractions at present.
+
+The program appears to understand a lot more than it really does.
+
+Pictures are silently disguared.
+
+Fast save files are not supported.
+
+The conversion is not perfect and needs manual cleaning up.
+
+Non-word files silently produce empty output in most cases.
+
+Equations are not supported in text output.
+
+If the cues the program recognised LaTeX mode does little more than
+produce LaTeX format tables and plain text output.
+
+.SH AUTHOR
+
+word2x is (C) Duncan Simpson 1997 and may be distributed under the GPL
+version 2, or any later version at your option. I would appreciate
+patches and information emailed to dps@io.stargate.co.uk
+
diff --git a/support/word2x/word2x.cc b/support/word2x/word2x.cc
new file mode 100644
index 0000000000..18cda0a810
--- /dev/null
+++ b/support/word2x/word2x.cc
@@ -0,0 +1,395 @@
+/* $Id: word2x.cc,v 1.12 1997/04/13 05:53:11 dps Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* Do not have alloca.h */
+#ifdef _AIX
+#pragma alloca
+#else /* not _AIX */
+extern "C" char *alloca(int);
+#endif /* _AIX */
+#endif /* HAVE_ALLOCA_H */
+#endif /* __GNUC__ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif /* HAVE_TIME_H */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif /* HAVE_SYS_TIME_H */
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include "getopt.h"
+#include "interface.h"
+#include "lib.h"
+#include "strip.h"
+
+#ifndef N
+#define N(x) (sizeof(x)/sizeof(x[0]))
+#endif
+
+extern docfmt txtfmt, latexfmt, htmlfmt;
+
+/* postfix test */
+static int postfix(const char *s, const char *t)
+{
+ unsigned int n;
+
+ n=strlen(t);
+ if (strlen(s)<=n)
+ return 0;
+ return (strcasecmp(s+strlen(s)-n, t)==0) ? 1 : 0;
+}
+
+/*
+ * open file with .doc or .DOC tacked on the end if the filename alone
+ * does not exist
+ */
+static FILE *open_file(const char *f)
+{
+ char *s;
+ FILE *r;
+
+ if ((r=fopen(f, "r"))!=NULL)
+ return r;
+
+ if ((s=(char *) malloc(strlen(f)+4))==NULL)
+ {
+ fprintf(stderr,"word2x: skipping %s due to malloc failure\n", f);
+ return NULL;
+ }
+ strcpy(s, f);
+ strcat(s, ".doc");
+
+ if ((r=fopen(s, "r"))==NULL)
+ {
+ free(s);
+ return r;
+ }
+
+ strcpy(s+strlen(f), ".DOC");
+ r=fopen(s, "r");
+ free(s);
+
+ return r;
+}
+
+
+/* Just read the files and pass the results on... */
+static void convert(istream *f, FILE *out, const struct docfmt *fmt)
+{
+ const tok_seq::tok *d;
+ int i;
+ void *dptr;
+ tok_seq rd(f);
+
+ dptr=fmt->new_state();
+ while ((d=rd.read_token())!=NULL)
+ {
+ i=d->tokval;
+
+#ifndef C_ALLOCA
+ alloca(0);
+#endif
+
+ if (i<NFUNCS && d->end==tok_seq::tok::TOK_START)
+ {
+ (fmt->f[i]).start(d, fmt, out, dptr);
+ }
+ else
+ {
+ (fmt->f[i]).end(d, fmt, out, dptr);
+ }
+ }
+ fmt->free_state(dptr);
+}
+
+static const char *outname(const char *in, const char *ext)
+{
+ char *r, *s;
+ int adj;
+
+ if (postfix(in, ".doc"))
+ adj=4;
+ else
+ adj=0;
+
+ if ((r=(char *) malloc(strlen(in)+strlen(ext)-adj+1))==NULL)
+ return NULL;
+ strcpy(r, in);
+ s=r+strlen(r)-adj;
+ strcpy(s, ext);
+
+ return r;
+}
+
+int main(int argc, const char **argv)
+{
+ static const struct
+ {
+ const char *name;
+ char *(*fmt)(time_t);
+ } dates[]=
+ {
+ { "uk", uk_date },
+ { "british", uk_date },
+ { "us", us_date },
+ { "de", de_date },
+ { "deHTML", deHTML_date },
+ { "deL1", deL1_date },
+ };
+ static const struct
+ {
+ const char *name;
+ const char *ext;
+ const docfmt *fmt;
+ } formats[]=
+ {
+ { "text", ".txt", &txtfmt },
+ { "latex", ".tex", &latexfmt },
+ { "html", ".html", &htmlfmt },
+ };
+#if !defined(NO_LONG_OPTS)
+ static const struct option lopts[]=
+ {
+ { "version", 0, NULL, 'V' },
+ { "help", 0, NULL, 'h' },
+ { "format", 1, NULL, 'f' },
+ { "width", 0, NULL, 'w' },
+ { "dates", 0, NULL, 'd' },
+ { "verbose", 0, NULL, 'v' },
+ { "quiet", 0, NULL, 'q' },
+ { "pagebreak", 0, NULL, 'p' },
+ };
+#endif
+
+ char *(*dfmt)(time_t);
+ FILE *in, *out;
+ docfmt fmt;
+ int c, i, opt_index, n, wd;
+ const char *s,*t, *ext;
+ int verbose=0, name_alloced, res;
+
+ struct
+ {
+ unsigned new_pages:1;
+ } flags={ 0 };
+ res=0; // Return code 0
+ fmt=*(formats[0].fmt); // Set default format
+ dfmt=dates[0].fmt; // Set default date format
+ wd=fmt.maxline; // Set default width
+ ext=formats[0].ext; // Set default extension
+
+ while ((c=getopt_long(argc, (char *const *) argv, "Vhpvqf:w:d:",
+ lopts, &opt_index))!=-1)
+ {
+ switch(c)
+ {
+ case 'V': // Print version and exit
+ fputs("word2x 0.005\n", stderr);
+ return 0;
+
+ case 'p':
+ flags.new_pages=1;
+ break;
+
+ case 'h': // Help
+ fputs("Usage: word2x [-f <output format>] [--dates <date format>]"
+ " [-w <line length>]\n"
+ " <infile> [<outfile>]\n"
+ "Supported date formats: ", stderr);
+ for (i=0; i<(int) N(dates); i++)
+ {
+ if (i!=0)
+ fputs(", ", stderr);
+ fputs(dates[i].name, stderr);
+ }
+ fputs("\nSupported output formats: ", stderr);
+ for (i=0; i<(int) N(formats); i++)
+ {
+ if (i!=0)
+ fputs(", ", stderr);
+ fputs(formats[i].name, stderr);
+ }
+ fputc('\n', stderr);
+ return 0;
+
+ case 'v': // Verbose mode
+ verbose=1;
+ break;
+
+ case 'q': // Queit mode
+ verbose=0;
+ break;
+
+ case 'w': // Width
+ n=0;
+ if (*optarg=='\0')
+ {
+ fputs("-w requires a number\n", stderr);
+ break;
+ }
+ for (s=optarg; *s; s++)
+ {
+ if (!isdigit(*s))
+ {
+ res=1;
+ fputs("-w requires a number\n", stderr);
+ break;
+ }
+ n=n*10+(*s-'0');
+ }
+ if (*s=='\0')
+ wd=n;
+ break;
+
+ case 'd': // Date format
+ for (n=-1, i=0; i<(int) N(dates); i++)
+ {
+ if (strcasecmp(dates[i].name, optarg)==0)
+ {
+ n=i;
+ break;
+ }
+ }
+ if (n==-1)
+ {
+ res=1;
+ fprintf(stderr, "%s is not a known date format\n", optarg);
+ }
+ else
+ dfmt=dates[i].fmt;
+ break;
+
+ case 'f': // Output format
+ for (n=-1, i=0; i<(int) N(formats); i++)
+ {
+ if (strcasecmp(formats[i].name, optarg)==0)
+ {
+ n=i;
+ break;
+ }
+ }
+ if (n==-1)
+ {
+ res=1;
+ fprintf(stderr, "%s is not a known output format\n", optarg);
+ }
+ else
+ {
+ fmt=*(formats[i].fmt);
+ ext=formats[i].ext;
+ }
+ break;
+
+ case '?':
+ break;
+
+ default:
+ abort();
+ }
+ }
+
+ /* Make sure we have a filename */
+ if (optind==argc)
+ {
+ fputs("word2x: filename required (can not handle stdin)\n", stderr);
+ return 1;
+ }
+
+ /* Stop if invalid switches */
+ if (res!=0)
+ return res;
+
+ /* Set line width and date format */
+ fmt.date=dfmt;
+ fmt.maxline=wd;
+ fmt.flags.new_pages=flags.new_pages;
+
+ /* Loop through files */
+ for (i=optind; i<argc; i++)
+ {
+ s=argv[i];
+ if (i==argc-1 || postfix(argv[i+1],".doc"))
+ {
+ /* Generate output file name */
+ if ((t=outname(argv[i], ext))==NULL)
+ {
+ fprintf(stderr,
+ "word2x: skipping %s due to allocation failure\n",
+ s);
+ continue;
+ }
+ name_alloced=1;
+ }
+ else
+ {
+ t=argv[++i];
+ name_alloced=0;
+ }
+
+ /* Open input file */
+ if ((in=open_file(s))==NULL)
+ {
+ if (name_alloced)
+ free((void *) t);
+ fprintf(stderr, "Could not open %s\n", s);
+ res=1;
+ continue;
+ }
+
+ /* Open output file */
+ if (strcmp(t,"-")==0)
+ {
+ out=stdout;
+ t="standard output";
+ }
+ else
+ {
+ if ((out=fopen(t, "w"))==NULL)
+ {
+ fprintf(stderr, "Could not open %s\n", t);
+ if (name_alloced)
+ free((void *) t);
+ fclose(in);
+ res=1;
+ continue;
+ }
+ }
+
+ fclose(in);
+ word_junk_filter filt(s);
+ istream in(&filt);
+
+ /* Finally do something */
+ if (verbose)
+ fprintf(stderr, "Converting %s to %s\n", s, t);
+ convert(&in, out, &fmt);
+
+ /* Junk filter and istream go out of scope here */
+ }
+
+ return res;
+}
+
+
+
+
+
+
+
diff --git a/support/word2x/word6.h b/support/word2x/word6.h
new file mode 100644
index 0000000000..5dd17238e7
--- /dev/null
+++ b/support/word2x/word6.h
@@ -0,0 +1,37 @@
+/* $Id: word6.h,v 1.4 1997/03/31 22:29:32 dps Exp $ */
+/* Word 6 constants */
+/* Written without knowledge of for internals, just some test documents */
+
+#ifndef __word6_h__
+#define __word6_h__
+
+
+/* Registry of stuff stopped inside ^S...^U
+ * tc "foo bar"
+ * EMBED MSDraw \* mergeformat^T^A
+ */
+
+#define START_CTL ('S'-64)
+#define END_CTL ('U'-64)
+
+/* ^G seems to seperate table columns */
+/* ^G^G=End of row */
+/* ^G^G^G !=End of table */
+#define TABLE_SEP ('G'-64)
+
+/* End of paragraph */
+#define PAR_END ('M'-64)
+#define HARD_RETURN ('K'-64)
+
+/* Stuff I am still not aware about */
+/* Headers, footers, EMBEDed stuff, pictures, ... */
+#define NEW_PAGE ('L'-64)
+#define FOOTNOTE ('B'-64)
+
+/* Useful data start offset */
+#define DOC_START 06400
+
+/* Bullet */
+#define BULLET_CODE 0x95
+
+#endif
diff --git a/support/word2x/wordwrap.cc b/support/word2x/wordwrap.cc
new file mode 100644
index 0000000000..14fa764c77
--- /dev/null
+++ b/support/word2x/wordwrap.cc
@@ -0,0 +1,74 @@
+/* $Id: wordwrap.cc,v 1.5 1997/03/23 13:52:15 dps Exp $ */
+/* Wordwrap function for library */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif /* HAVE_CTYPE_H */
+#include "tblock.h"
+#define __EXLCUDE_READER_CLASSES
+#include "lib.h"
+
+
+/* Word wrap text into lines of length room */
+tblock *word_wrap(const char *txt, const char *nl, const char *expl_nl,
+ const int room, const int ilen)
+{
+ struct tblock *ans;
+ const char *wptr, *sc;
+ int wlen, croom, flg;
+ int nl_len; // Performance hack
+
+ ans=new(tblock);
+
+ wlen=0;
+ wptr=sc=txt;
+ croom=room-ilen;
+ nl_len=strlen(nl);
+ flg=0;
+
+ while (1)
+ {
+ /* FIXME: huge words might cause an oversize line */
+ /* (this is not a typesetting program like *roff) */
+ if (isspace(*sc) || *sc=='\n' || *sc=='\0')
+ {
+ if (wlen+flg>croom)
+ {
+ ans->add(nl,nl_len);
+ croom=room;
+ flg=0;
+ }
+ if (wlen>0)
+ {
+ if (flg)
+ {
+ ans->add(' ');
+ croom--;
+ }
+ ans->add(wptr, wlen);
+ croom-=wlen;
+ flg=1;
+ }
+ if (*sc=='\n')
+ {
+ ans->add(expl_nl);
+ croom=room;
+ flg=0;
+ }
+ wlen=0;
+ }
+ else
+ {
+ if (wlen==0)
+ wptr=sc;
+ wlen++;
+ }
+ if (*sc=='\0') break; // Stop condition
+ sc++;
+ }
+ return ans;
+}