diff options
Diffstat (limited to 'support/word2x/word2x.cc')
-rw-r--r-- | support/word2x/word2x.cc | 395 |
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; +} + + + + + + + |