Blame sgmls-1.1/main.c

Packit Service 87bb26
/* main.c -
Packit Service 87bb26
   Main program for sgmls.
Packit Service 87bb26
Packit Service 87bb26
     Written by James Clark (jjc@jclark.com).
Packit Service 87bb26
*/
Packit Service 87bb26
Packit Service 87bb26
#include "config.h"
Packit Service 87bb26
#include "std.h"
Packit Service 87bb26
#include "getopt.h"
Packit Service 87bb26
#include "entity.h"           /* Templates for entity control blocks. */
Packit Service 87bb26
#include "adl.h"              /* Definitions for attribute list processing. */
Packit Service 87bb26
#include "sgmlmain.h"         /* Main interface to SGML services. */
Packit Service 87bb26
#include "appl.h"
Packit Service 87bb26
Packit Service 87bb26
#define READCNT 512
Packit Service 87bb26
Packit Service 87bb26
/* Before using argv[0] in error messages, strip off everything up to and
Packit Service 87bb26
including the last character in prog that occurs in PROG_PREFIX. */
Packit Service 87bb26
Packit Service 87bb26
#ifndef PROG_PREFIX
Packit Service 87bb26
#define PROG_PREFIX "/"
Packit Service 87bb26
#endif /* not PROG_PREFIX */
Packit Service 87bb26
Packit Service 87bb26
/* Message catalogue name. */
Packit Service 87bb26
#define CAT_NAME "sgmls"
Packit Service 87bb26
/* Message set to use for application error messages. */
Packit Service 87bb26
#define APP_SET 4
Packit Service 87bb26
Packit Service 87bb26
#ifdef HAVE_EXTENDED_PRINTF
Packit Service 87bb26
#define xvfprintf vfprintf
Packit Service 87bb26
#else
Packit Service 87bb26
extern int xvfprintf P((FILE *, char *, va_list));
Packit Service 87bb26
#endif
Packit Service 87bb26
Packit Service 87bb26
static VOID usage P((void));
Packit Service 87bb26
static VOID fatal VP((int, ...));
Packit Service 87bb26
static VOID do_error P((int, va_list));
Packit Service 87bb26
static VOID swinit P((struct switches *));
Packit Service 87bb26
static VOID write_caps P((char *, struct sgmlcap *));
Packit Service 87bb26
Packit Service 87bb26
static UNIV make_docent P((int, char **));
Packit Service 87bb26
static char *munge_program_name P((char *, char *));
Packit Service 87bb26
static VOID die P((void));
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
static VOID build_subargv P((struct switches *));
Packit Service 87bb26
static VOID cleanup P((void));
Packit Service 87bb26
static char *create_subcap_file P((void));
Packit Service 87bb26
#endif /* SUPPORT_SUBDOC */
Packit Service 87bb26
Packit Service 87bb26
static char *errlist[] = {
Packit Service 87bb26
     0,
Packit Service 87bb26
     "Out of memory",
Packit Service 87bb26
     "Cannot open SGML document entity",
Packit Service 87bb26
     "Cannot exec `%s': %s",
Packit Service 87bb26
     "Cannot fork: %s",
Packit Service 87bb26
     "Error waiting for process: %s",
Packit Service 87bb26
     "Program %s got fatal signal %d",
Packit Service 87bb26
     "Cannot open `%s': %s",
Packit Service 87bb26
     "Subdocument capacity botch",
Packit Service 87bb26
     "Non-existent subdocument entity `%s' not processed",
Packit Service 87bb26
};
Packit Service 87bb26
Packit Service 87bb26
int suppsw = 0;			/* Non-zero means suppress output. */
Packit Service 87bb26
int locsw = 0;			/* Non-zero means generate location info. */
Packit Service 87bb26
static char *prog;		/* Program name (for error messages). */
Packit Service 87bb26
static nl_catd catd;		/* Message catalogue descriptor. */
Packit Service 87bb26
static char *capfile = 0;	/* File for capacity report. */
Packit Service 87bb26
extern char *version_string;
Packit Service 87bb26
Packit Service 87bb26
char options[] = {
Packit Service 87bb26
     'c', ':', 'd', 'e', 'g', 'i', ':', 'l', 'o', ':', 'p', 'r', 's', 'u', 'v',
Packit Service 87bb26
#ifdef CANT_REDIRECT_STDERR
Packit Service 87bb26
     'f', ':',
Packit Service 87bb26
#endif /* CANT_REDIRECT_STDERR */
Packit Service 87bb26
#ifdef TRACE
Packit Service 87bb26
     'x', ':', 'y', ':',
Packit Service 87bb26
#endif /* TRACE */
Packit Service 87bb26
     '\0'
Packit Service 87bb26
};
Packit Service 87bb26
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
int suberr = 0;			/* Error in subdocument. */
Packit Service 87bb26
static char *subargv[sizeof(options)];
Packit Service 87bb26
static int subargc = 0;
Packit Service 87bb26
static char nopenbuf[sizeof(long)*3 + 1];
Packit Service 87bb26
static char sgmldecl_file[L_tmpnam];
Packit Service 87bb26
static char subcap_file[L_tmpnam];
Packit Service 87bb26
#endif
Packit Service 87bb26
Packit Service 87bb26
int main(argc, argv)
Packit Service 87bb26
int argc;
Packit Service 87bb26
char **argv;
Packit Service 87bb26
{
Packit Service 87bb26
     static char stderr_buf[BUFSIZ];
Packit Service 87bb26
     int opt;
Packit Service 87bb26
#ifdef CANT_REDIRECT_STDERR
Packit Service 87bb26
     char *errfile = 0;
Packit Service 87bb26
#endif
Packit Service 87bb26
     struct sgmlcap cap;
Packit Service 87bb26
     struct switches sw;
Packit Service 87bb26
     int nincludes = 0;	      /* number of -i options */
Packit Service 87bb26
     setbuf(stderr, stderr_buf);
Packit Service 87bb26
Packit Service 87bb26
     /* Define MAIN_HOOK in config.h if some function needs to be called here. */
Packit Service 87bb26
#ifdef MAIN_HOOK
Packit Service 87bb26
     MAIN_HOOK(argc, argv);
Packit Service 87bb26
#endif
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
     subargv[subargc++] = argv[0];
Packit Service 87bb26
#endif
Packit Service 87bb26
Packit Service 87bb26
     prog = argv[0] = munge_program_name(argv[0], "sgmls");
Packit Service 87bb26
Packit Service 87bb26
     catd = catopen(CAT_NAME, 0);
Packit Service 87bb26
     swinit(&sw);
Packit Service 87bb26
Packit Service 87bb26
     while ((opt = getopt(argc, argv, options)) != EOF) {
Packit Service 87bb26
	  switch (opt) {
Packit Service 87bb26
	  case 'l':	      /* Generate location information. */
Packit Service 87bb26
	       locsw = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'c':	      /* Print capacity usage. */
Packit Service 87bb26
	       capfile = optarg;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 's':	      /* Suppress output. */
Packit Service 87bb26
	       suppsw = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'd':           /* Report duplicate entity declarations. */
Packit Service 87bb26
	       sw.swdupent = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'e':           /* Provide entity stack trace in error msg. */
Packit Service 87bb26
	       sw.swenttr = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
#ifdef CANT_REDIRECT_STDERR
Packit Service 87bb26
	  case 'f':	      /* Redirect errors. */
Packit Service 87bb26
	       errfile = optarg;
Packit Service 87bb26
	       break;
Packit Service 87bb26
#endif /* CANT_REDIRECT_STDERR */
Packit Service 87bb26
	  case 'g':           /* Provide GI stack trace in error messages. */
Packit Service 87bb26
	       sw.sweltr = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'p':	      /* Parse only the prolog. */
Packit Service 87bb26
	       sw.onlypro = 1;
Packit Service 87bb26
	       suppsw = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'r':           /* Give warning for defaulted references. */
Packit Service 87bb26
	       sw.swrefmsg = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'u':
Packit Service 87bb26
	       sw.swundef = 1;
Packit Service 87bb26
	       break;
Packit Service 87bb26
#ifdef TRACE
Packit Service 87bb26
	  case 'x':	       /* Trace options for the document body. */
Packit Service 87bb26
	       sw.trace = optarg;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'y':	       /* Trace options for the prolog. */
Packit Service 87bb26
	       sw.ptrace =  optarg;
Packit Service 87bb26
	       break;
Packit Service 87bb26
#endif /* TRACE */
Packit Service 87bb26
	  case 'v':	       /* Print the version number. */
Packit Service 87bb26
	       fprintf(stderr, "sgmls version %s\n", version_string);
Packit Service 87bb26
	       fflush(stderr);
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'o':
Packit Service 87bb26
	       sw.nopen = atol(optarg);
Packit Service 87bb26
	       if (sw.nopen <= 0)
Packit Service 87bb26
		    usage();
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case 'i':	      /* Define parameter entity as "INCLUDE". */
Packit Service 87bb26
	       sw.includes = (char **)xrealloc((UNIV)sw.includes,
Packit Service 87bb26
					       (nincludes + 2)*sizeof(char *));
Packit Service 87bb26
	       sw.includes[nincludes++] = optarg;
Packit Service 87bb26
	       sw.includes[nincludes] = 0;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  case '?':
Packit Service 87bb26
	       usage();
Packit Service 87bb26
	  default:
Packit Service 87bb26
	       abort();
Packit Service 87bb26
	  }
Packit Service 87bb26
     }
Packit Service 87bb26
     
Packit Service 87bb26
#ifdef CANT_REDIRECT_STDERR
Packit Service 87bb26
     if (errfile) {
Packit Service 87bb26
	  FILE *fp;
Packit Service 87bb26
	  errno = 0;
Packit Service 87bb26
	  fp = fopen(errfile, "w");
Packit Service 87bb26
	  if (!fp)
Packit Service 87bb26
	       fatal(E_OPEN, errfile, strerror(errno));
Packit Service 87bb26
	  fclose(fp);
Packit Service 87bb26
	  errno = 0;
Packit Service 87bb26
	  if (!freopen(errfile, "w", stderr)) {
Packit Service 87bb26
	       /* Can't use fatal() since stderr is now closed */
Packit Service 87bb26
	       printf("%s: ", prog);
Packit Service 87bb26
	       printf(errlist[E_OPEN], errfile, strerror(errno));
Packit Service 87bb26
	       putchar('\n');
Packit Service 87bb26
	       exit(EXIT_FAILURE);
Packit Service 87bb26
	  }
Packit Service 87bb26
     }
Packit Service 87bb26
#endif /* CANT_REDIRECT_STDERR */
Packit Service 87bb26
Packit Service 87bb26
     (void)sgmlset(&sw);
Packit Service 87bb26
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
     build_subargv(&sw);
Packit Service 87bb26
#endif
Packit Service 87bb26
     if (sgmlsdoc(make_docent(argc - optind, argv + optind)))
Packit Service 87bb26
	  fatal(E_DOC);
Packit Service 87bb26
Packit Service 87bb26
     process_document(sw.nopen > 0);
Packit Service 87bb26
     sgmlend(&cap);
Packit Service 87bb26
     if (capfile)
Packit Service 87bb26
	  write_caps(capfile, &cap);
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
     cleanup();
Packit Service 87bb26
     if (suberr)
Packit Service 87bb26
	  exit(EXIT_FAILURE);
Packit Service 87bb26
#endif /* SUPPORT_SUBDOC */
Packit Service 87bb26
     if (sgmlgcnterr() > 0)
Packit Service 87bb26
	  exit(EXIT_FAILURE);
Packit Service 87bb26
     if (!sw.nopen)
Packit Service 87bb26
	  output_conforming();
Packit Service 87bb26
     exit(EXIT_SUCCESS);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static char *munge_program_name(arg, dflt)
Packit Service 87bb26
char *arg, *dflt;
Packit Service 87bb26
{
Packit Service 87bb26
     char *p;
Packit Service 87bb26
#ifdef PROG_STRIP_EXTENSION
Packit Service 87bb26
     char *ext;
Packit Service 87bb26
#endif
Packit Service 87bb26
     if (!arg || !*arg)
Packit Service 87bb26
	  return dflt;
Packit Service 87bb26
     p = strchr(arg, '\0');
Packit Service 87bb26
     for (;;) {
Packit Service 87bb26
	  if (p == arg)
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  --p;
Packit Service 87bb26
	  if (strchr(PROG_PREFIX, *p)) {
Packit Service 87bb26
	       p++;
Packit Service 87bb26
	       break;
Packit Service 87bb26
	  }
Packit Service 87bb26
     }
Packit Service 87bb26
     arg = p;
Packit Service 87bb26
#ifdef PROG_STRIP_EXTENSION
Packit Service 87bb26
     ext = strrchr(arg, '.');
Packit Service 87bb26
     if (ext) {
Packit Service 87bb26
	  p = (char *)xmalloc(ext - arg + 1);
Packit Service 87bb26
	  memcpy(p, arg, ext - arg);
Packit Service 87bb26
	  p[ext - arg] = '\0';
Packit Service 87bb26
	  arg = p;
Packit Service 87bb26
     }
Packit Service 87bb26
#endif /* PROG_STRIP_EXTENSION */
Packit Service 87bb26
#ifdef PROG_FOLD
Packit Service 87bb26
#ifdef PROG_STRIP_EXTENSION
Packit Service 87bb26
     if (!ext) {
Packit Service 87bb26
#endif
Packit Service 87bb26
	  p = xmalloc(strlen(arg) + 1);
Packit Service 87bb26
	  strcpy(p, arg);
Packit Service 87bb26
	  arg = p;
Packit Service 87bb26
#ifdef PROG_STRIP_EXTENSION
Packit Service 87bb26
     }
Packit Service 87bb26
#endif
Packit Service 87bb26
     for (p = arg; *p; p++)
Packit Service 87bb26
	  if (ISASCII((unsigned char)*p) && isupper((unsigned char)*p))
Packit Service 87bb26
	       *p = tolower((unsigned char)*p);
Packit Service 87bb26
#endif /* PROG_FOLD */
Packit Service 87bb26
     return arg;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static UNIV make_docent(argc, argv)
Packit Service 87bb26
int argc;
Packit Service 87bb26
char **argv;
Packit Service 87bb26
{
Packit Service 87bb26
     UNS len = 1;
Packit Service 87bb26
     int i;
Packit Service 87bb26
     UNIV res;
Packit Service 87bb26
     char *ptr;
Packit Service 87bb26
     static char *stdinname = STDINNAME;
Packit Service 87bb26
Packit Service 87bb26
     if (argc == 0) {
Packit Service 87bb26
	  argv = &stdinname;
Packit Service 87bb26
	  argc = 1;
Packit Service 87bb26
     }
Packit Service 87bb26
Packit Service 87bb26
     for (i = 0; i < argc; i++)
Packit Service 87bb26
	  len += strlen(argv[i]) + 1;
Packit Service 87bb26
     
Packit Service 87bb26
     res = xmalloc(len);
Packit Service 87bb26
     ptr = (char *)res;
Packit Service 87bb26
     for (i = 0; i < argc; i++) {
Packit Service 87bb26
	  strcpy(ptr, argv[i]);
Packit Service 87bb26
	  ptr = strchr(ptr, '\0') + 1;
Packit Service 87bb26
     }
Packit Service 87bb26
     *ptr = '\0';
Packit Service 87bb26
     return res;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
Packit Service 87bb26
static VOID usage()
Packit Service 87bb26
{
Packit Service 87bb26
     /* Don't mention -o since this are for internal use only. */
Packit Service 87bb26
     fprintf(stderr, "Usage: %s [-deglprsuv]%s [-c file] [-i entity]%s [filename ...]\n",
Packit Service 87bb26
	     prog,
Packit Service 87bb26
#ifdef CANT_REDIRECT_STDERR
Packit Service 87bb26
	     " [-f file]",
Packit Service 87bb26
#else /* not CANT_REDIRECT_STDERR */
Packit Service 87bb26
	     "",
Packit Service 87bb26
#endif /* not CANT_REDIRECT_STDERR */
Packit Service 87bb26
#ifdef TRACE
Packit Service 87bb26
	     " [-x flags] [-y flags]"
Packit Service 87bb26
#else /* not TRACE */
Packit Service 87bb26
	     ""
Packit Service 87bb26
#endif /* not TRACE */
Packit Service 87bb26
	     );
Packit Service 87bb26
     exit(EXIT_FAILURE);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static VOID die()
Packit Service 87bb26
{
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
     cleanup();
Packit Service 87bb26
#endif /* SUPPORT_SUBDOC */
Packit Service 87bb26
     exit(EXIT_FAILURE);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static VOID swinit(swp)
Packit Service 87bb26
struct switches *swp;
Packit Service 87bb26
{
Packit Service 87bb26
     swp->swenttr = 0;
Packit Service 87bb26
     swp->sweltr = 0;
Packit Service 87bb26
     swp->swbufsz = READCNT+2;
Packit Service 87bb26
     swp->prog = prog;
Packit Service 87bb26
     swp->swdupent = 0;
Packit Service 87bb26
     swp->swrefmsg = 0;
Packit Service 87bb26
#ifdef TRACE
Packit Service 87bb26
     swp->trace = 0;
Packit Service 87bb26
     swp->ptrace = 0;
Packit Service 87bb26
#endif /* TRACE */
Packit Service 87bb26
     swp->catd = catd;
Packit Service 87bb26
     swp->swambig = 1;	      /* Always check for ambiguity. */
Packit Service 87bb26
     swp->swundef = 0;
Packit Service 87bb26
     swp->nopen = 0;
Packit Service 87bb26
     swp->onlypro = 0;
Packit Service 87bb26
     swp->includes = 0;
Packit Service 87bb26
     swp->die = die;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
#ifdef SUPPORT_SUBDOC
Packit Service 87bb26
Packit Service 87bb26
static VOID build_subargv(swp)
Packit Service 87bb26
struct switches *swp;
Packit Service 87bb26
{
Packit Service 87bb26
     if (suppsw)
Packit Service 87bb26
	  subargv[subargc++] = "-s";
Packit Service 87bb26
     if (locsw)
Packit Service 87bb26
	  subargv[subargc++] = "-l";
Packit Service 87bb26
     if (swp->swdupent)
Packit Service 87bb26
	  subargv[subargc++] = "-d";
Packit Service 87bb26
     if (swp->swenttr)
Packit Service 87bb26
	  subargv[subargc++] = "-e";
Packit Service 87bb26
     if (swp->sweltr)
Packit Service 87bb26
	  subargv[subargc++] = "-g";
Packit Service 87bb26
     if (swp->swrefmsg)
Packit Service 87bb26
	  subargv[subargc++] = "-r";
Packit Service 87bb26
#ifdef TRACE
Packit Service 87bb26
     if (swp->trace) {
Packit Service 87bb26
	  subargv[subargc++] = "-x";
Packit Service 87bb26
	  subargv[subargc++] = swp->trace;
Packit Service 87bb26
     }
Packit Service 87bb26
     if (swp->ptrace) {
Packit Service 87bb26
	  subargv[subargc++] = "-y";
Packit Service 87bb26
	  subargv[subargc++] = swp->ptrace;
Packit Service 87bb26
     }
Packit Service 87bb26
#endif /* TRACE */
Packit Service 87bb26
     subargv[subargc++] = "-o";
Packit Service 87bb26
     sprintf(nopenbuf, "%ld", swp->nopen + 1);
Packit Service 87bb26
     subargv[subargc++] = nopenbuf;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
Packit Service 87bb26
static
Packit Service 87bb26
VOID handler(sig)
Packit Service 87bb26
int sig;
Packit Service 87bb26
{
Packit Service 87bb26
     signal(sig, SIG_DFL);
Packit Service 87bb26
     cleanup();
Packit Service 87bb26
     raise(sig);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static
Packit Service 87bb26
VOID cleanup()
Packit Service 87bb26
{
Packit Service 87bb26
     if (sgmldecl_file[0]) {
Packit Service 87bb26
	  (void)remove(sgmldecl_file);
Packit Service 87bb26
	  sgmldecl_file[0] = '\0';
Packit Service 87bb26
     }
Packit Service 87bb26
     if (subcap_file[0]) {
Packit Service 87bb26
	  (void)remove(subcap_file);
Packit Service 87bb26
	  subcap_file[0] = '\0';
Packit Service 87bb26
     }
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static
Packit Service 87bb26
char *store_sgmldecl()
Packit Service 87bb26
{
Packit Service 87bb26
     if (!sgmldecl_file[0]) {
Packit Service 87bb26
	  FILE *fp;
Packit Service 87bb26
	  if (signal(SIGINT, SIG_IGN) != SIG_IGN)
Packit Service 87bb26
	       signal(SIGINT, handler);
Packit Service 87bb26
#ifdef SIGTERM
Packit Service 87bb26
	  if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
Packit Service 87bb26
	       signal(SIGTERM, handler);
Packit Service 87bb26
#endif /* SIGTERM */
Packit Service 87bb26
#ifdef SIGPIPE
Packit Service 87bb26
	  if (signal(SIGPIPE, SIG_IGN) != SIG_IGN)
Packit Service 87bb26
	       signal(SIGPIPE, handler);
Packit Service 87bb26
#endif
Packit Service 87bb26
#ifdef SIGHUP
Packit Service 87bb26
	  if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
Packit Service 87bb26
	       signal(SIGHUP, handler);
Packit Service 87bb26
#endif
Packit Service 87bb26
	  tmpnam(sgmldecl_file);
Packit Service 87bb26
	  errno = 0;
Packit Service 87bb26
	  fp = fopen(sgmldecl_file, "w");
Packit Service 87bb26
	  if (!fp)
Packit Service 87bb26
	       fatal(E_OPEN, sgmldecl_file, strerror(errno));
Packit Service 87bb26
	  sgmlwrsd(fp);
Packit Service 87bb26
	  fclose(fp);
Packit Service 87bb26
     }
Packit Service 87bb26
     return sgmldecl_file;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static
Packit Service 87bb26
char *create_subcap_file()
Packit Service 87bb26
{
Packit Service 87bb26
     if (subcap_file[0] == '\0') {
Packit Service 87bb26
	  FILE *fp;
Packit Service 87bb26
	  tmpnam(subcap_file);
Packit Service 87bb26
	  fp = fopen(subcap_file, "w");
Packit Service 87bb26
	  if (!fp)
Packit Service 87bb26
	       fatal(E_OPEN, subcap_file, strerror(errno));
Packit Service 87bb26
	  fclose(fp);
Packit Service 87bb26
     }
Packit Service 87bb26
     return subcap_file;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
char **make_argv(id)
Packit Service 87bb26
UNIV id;
Packit Service 87bb26
{
Packit Service 87bb26
     int nfiles;
Packit Service 87bb26
     char *p;
Packit Service 87bb26
     char **argv;
Packit Service 87bb26
     int i;
Packit Service 87bb26
Packit Service 87bb26
     for (p = (char *)id, nfiles = 0; *p; p = strchr(p, '\0') + 1)
Packit Service 87bb26
	  nfiles++;
Packit Service 87bb26
     
Packit Service 87bb26
     argv = (char **)xmalloc((subargc + 2 + 1 + nfiles + 1)*sizeof(char *));
Packit Service 87bb26
     memcpy((UNIV)argv, (UNIV)subargv, subargc*sizeof(char *));
Packit Service 87bb26
     
Packit Service 87bb26
     i = subargc;
Packit Service 87bb26
Packit Service 87bb26
     argv[i++] = "-c";
Packit Service 87bb26
     argv[i++] = create_subcap_file();
Packit Service 87bb26
Packit Service 87bb26
     argv[i++] = store_sgmldecl();
Packit Service 87bb26
Packit Service 87bb26
     for (p = (char *)id; *p; p = strchr(p, '\0') + 1)
Packit Service 87bb26
	  argv[i++] = p;
Packit Service 87bb26
     argv[i] = 0;
Packit Service 87bb26
     return argv;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
VOID get_subcaps()
Packit Service 87bb26
{
Packit Service 87bb26
     long cap[NCAPACITY];
Packit Service 87bb26
     FILE *fp;
Packit Service 87bb26
     int i;
Packit Service 87bb26
Packit Service 87bb26
     if (!subcap_file[0])
Packit Service 87bb26
	  return;
Packit Service 87bb26
     errno = 0;
Packit Service 87bb26
     fp = fopen(subcap_file, "r");
Packit Service 87bb26
     if (!fp)
Packit Service 87bb26
	  fatal(E_OPEN, subcap_file, strerror(errno));
Packit Service 87bb26
     for (i = 0; i < NCAPACITY; i++)
Packit Service 87bb26
	  if (fscanf(fp, "%*s %ld", cap + i) != 1)
Packit Service 87bb26
	       fatal(E_CAPBOTCH);
Packit Service 87bb26
     fclose(fp);
Packit Service 87bb26
     sgmlsubcap(cap);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
Packit Service 87bb26
#endif /* SUPPORT_SUBDOC */
Packit Service 87bb26
Packit Service 87bb26
/* Print capacity statistics.*/
Packit Service 87bb26
Packit Service 87bb26
static VOID write_caps(name, p)
Packit Service 87bb26
char *name;
Packit Service 87bb26
struct sgmlcap *p;
Packit Service 87bb26
{
Packit Service 87bb26
     FILE *fp;
Packit Service 87bb26
     int i;
Packit Service 87bb26
     fp = fopen(name, "w");
Packit Service 87bb26
     if (!fp)
Packit Service 87bb26
	  fatal(E_OPEN, name, strerror(errno));
Packit Service 87bb26
     /* This is in RACT format. */
Packit Service 87bb26
     for (i = 0; i < NCAPACITY; i++)
Packit Service 87bb26
	  fprintf(fp, "%s %ld\n", p->name[i], p->number[i]*p->points[i]);
Packit Service 87bb26
     fclose(fp);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
UNIV xmalloc(n)
Packit Service 87bb26
UNS n;
Packit Service 87bb26
{
Packit Service 87bb26
     UNIV p = malloc(n);
Packit Service 87bb26
     if (!p)
Packit Service 87bb26
	  fatal(E_NOMEM);
Packit Service 87bb26
     return p;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
UNIV xrealloc(s, n)
Packit Service 87bb26
UNIV s;
Packit Service 87bb26
UNS n;
Packit Service 87bb26
{
Packit Service 87bb26
     s = s ? realloc(s, n) : malloc(n);
Packit Service 87bb26
     if (!s)
Packit Service 87bb26
	  fatal(E_NOMEM);
Packit Service 87bb26
     return s;
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static
Packit Service 87bb26
#ifdef VARARGS
Packit Service 87bb26
VOID fatal(va_alist) va_dcl
Packit Service 87bb26
#else
Packit Service 87bb26
VOID fatal(int errnum,...)
Packit Service 87bb26
#endif
Packit Service 87bb26
{
Packit Service 87bb26
#ifdef VARARGS
Packit Service 87bb26
     int errnum;
Packit Service 87bb26
#endif
Packit Service 87bb26
     va_list ap;
Packit Service 87bb26
     
Packit Service 87bb26
#ifdef VARARGS
Packit Service 87bb26
     va_start(ap);
Packit Service 87bb26
     errnum = va_arg(ap, int);
Packit Service 87bb26
#else
Packit Service 87bb26
     va_start(ap, errnum);
Packit Service 87bb26
#endif
Packit Service 87bb26
     do_error(errnum, ap);
Packit Service 87bb26
     va_end(ap);
Packit Service 87bb26
     exit(EXIT_FAILURE);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
#ifdef VARARGS
Packit Service 87bb26
VOID appl_error(va_alist) va_dcl
Packit Service 87bb26
#else
Packit Service 87bb26
VOID appl_error(int errnum,...)
Packit Service 87bb26
#endif
Packit Service 87bb26
{
Packit Service 87bb26
#ifdef VARARGS
Packit Service 87bb26
     int errnum;
Packit Service 87bb26
#endif
Packit Service 87bb26
     va_list ap;
Packit Service 87bb26
     
Packit Service 87bb26
#ifdef VARARGS
Packit Service 87bb26
     va_start(ap);
Packit Service 87bb26
     errnum = va_arg(ap, int);
Packit Service 87bb26
#else
Packit Service 87bb26
     va_start(ap, errnum);
Packit Service 87bb26
#endif
Packit Service 87bb26
     do_error(errnum, ap);
Packit Service 87bb26
     va_end(ap);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
static
Packit Service 87bb26
VOID do_error(errnum, ap)
Packit Service 87bb26
int errnum;
Packit Service 87bb26
va_list ap;
Packit Service 87bb26
{
Packit Service 87bb26
     char *text;
Packit Service 87bb26
     fprintf(stderr, "%s: ", prog);
Packit Service 87bb26
     assert(errnum > 0);
Packit Service 87bb26
     assert(errnum < sizeof(errlist)/sizeof(errlist[0]));
Packit Service 87bb26
     text = catgets(catd, APP_SET, errnum, errlist[errnum]);
Packit Service 87bb26
     assert(text != 0);
Packit Service 87bb26
     xvfprintf(stderr, text, ap);
Packit Service 87bb26
     fputc('\n', stderr);
Packit Service 87bb26
     fflush(stderr);
Packit Service 87bb26
}
Packit Service 87bb26
Packit Service 87bb26
/*
Packit Service 87bb26
Local Variables:
Packit Service 87bb26
c-indent-level: 5
Packit Service 87bb26
c-continued-statement-offset: 5
Packit Service 87bb26
c-brace-offset: -5
Packit Service 87bb26
c-argdecl-indent: 0
Packit Service 87bb26
c-label-offset: -5
Packit Service 87bb26
comment-column: 30
Packit Service 87bb26
End:
Packit Service 87bb26
*/