/* $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 #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 #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STRINGS_H #include #endif /* HAVE_STRINGS_H */ #ifdef HAVE_TIME_H #include #endif /* HAVE_TIME_H */ #ifdef HAVE_SYS_TIME_H #include #endif /* HAVE_SYS_TIME_H */ #ifdef HAVE_CTYPE_H #include #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 (iend==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 ] [--dates ]" " [-w ]\n" " []\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