home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
word2x0a.zip
/
source
/
word2x.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-20
|
7KB
|
387 lines
/* $Id: word2x.cc,v 1.12 1997/04/13 05:53:11 dps Exp $ */
#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 */
char *alloca();
#endif /* _AIX */
#endif /* HAVE_ALLOCA_H */
#endif /* __GNUC__ */
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif /* HAVE_STRING_H */
#include <time.h>
#include "getopt.h"
#include <ctype.h>
#include "interface.h"
#include "lib.h"
#include "config.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(FILE *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->tok;
#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 },
};
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.001\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;
}
/* Check seekability of in file */
if (fseek(in, 0L, SEEK_SET)!=0)
{
fprintf(stderr, "word2x: %s is not seekable\n", s);
fclose(in);
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;
}
}
/* Finally do something */
if (verbose)
fprintf(stderr, "Converting %s to %s\n", s, t);
convert(in, out, &fmt);
fclose(in);
if (out!=stdout)
fclose(out);
}
return res;
}