summaryrefslogtreecommitdiff
path: root/support/word2x/word2x.cc
diff options
context:
space:
mode:
Diffstat (limited to 'support/word2x/word2x.cc')
-rw-r--r--support/word2x/word2x.cc395
1 files changed, 395 insertions, 0 deletions
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;
+}
+
+
+
+
+
+
+