summaryrefslogtreecommitdiff
path: root/dviware/dvibook/Dviconcat
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvibook/Dviconcat
Initial commit
Diffstat (limited to 'dviware/dvibook/Dviconcat')
-rw-r--r--dviware/dvibook/Dviconcat/Imakefile20
-rw-r--r--dviware/dvibook/Dviconcat/dviconcat.c756
-rw-r--r--dviware/dvibook/Dviconcat/dviconcat.man46
-rw-r--r--dviware/dvibook/Dviconcat/dviconcat.pdfbin0 -> 44133 bytes
4 files changed, 822 insertions, 0 deletions
diff --git a/dviware/dvibook/Dviconcat/Imakefile b/dviware/dvibook/Dviconcat/Imakefile
new file mode 100644
index 0000000000..05ca4e87c5
--- /dev/null
+++ b/dviware/dvibook/Dviconcat/Imakefile
@@ -0,0 +1,20 @@
+#include "../Imake.Config"
+
+ BINDIR = $(TEX_BINDIR)
+ MANDIR = $(TEX_MANDIR)
+
+ FILES = Imakefile dviconcat.man $(SRCS)
+
+ INCLUDES = -I$(LIBTEXROOT)
+LOCAL_LIBRARIES = $(LIBTEX)
+ DEPLIBS = $(DEPLIBTEX) \
+ $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+SimpleProgramTarget(dviconcat)
+
+tar:
+ cd ../..;\
+ for file in $(FILES); \
+ do \
+ tar rf $(TARFILE) $(PRODUCT)/Dviconcat/$$file; \
+ done
diff --git a/dviware/dvibook/Dviconcat/dviconcat.c b/dviware/dvibook/Dviconcat/dviconcat.c
new file mode 100644
index 0000000000..5f4629286d
--- /dev/null
+++ b/dviware/dvibook/Dviconcat/dviconcat.c
@@ -0,0 +1,756 @@
+/*
+ * Copyright (c) 1987, 1989 University of Maryland
+ * Department of Computer Science. All rights reserved.
+ * Permission to copy for any purpose is hereby granted
+ * so long as this copyright notice remains intact.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/dvi/RCS/dviconcat.c,v 3.1 89/08/22 17:23:15 chris Exp $";
+#endif
+
+/*
+ * DVI page concatenation program.
+ */
+
+#include "libtex/types.h"
+#include "libtex/dviclass.h"
+#include "libtex/dvicodes.h"
+#include "libtex/error.h"
+#include "libtex/fio.h"
+#include "libtex/gripes.h"
+#include "libtex/search.h"
+#include <stdio.h>
+#include <ctype.h>
+
+char *ProgName;
+extern char *optarg;
+extern int optind;
+
+/*
+ * We use the following structure to keep track of fonts we have seen.
+ * The final DVI file lists all the fonts used in each of the input
+ * files.
+ */
+struct fontinfo {
+ struct fontinfo *fi_next;/* next in list */
+ i32 fi_index; /* font number in output file */
+ i32 fi_checksum; /* the checksum */
+ i32 fi_mag; /* the magnification */
+ i32 fi_designsize; /* the design size */
+ short fi_n1; /* the name header length */
+ short fi_n2; /* the name body length */
+ char *fi_name; /* the name itself */
+} *fonts;
+
+struct search *FontFinder; /* input indicies to ptr-to-fontinfo */
+i32 NextOutputFontIndex; /* generates output indicies */
+i32 OutputFontIndex; /* current (new) index in ouput */
+
+char *DVIFileName; /* the current input file name */
+FILE *inf; /* the current input DVI file */
+FILE *outf; /* the output DVI file */
+
+int errs; /* counts non-fatal errors */
+
+long StartOfLastPage; /* The file position just before we started
+ the last page (this is later written to
+ the output file as the previous page
+ pointer). */
+long CurrentPosition; /* The current position of the file */
+
+int NumberOfOutputPages; /* number of pages in new DVI file */
+
+i32 Numerator; /* numerator from current DVI file */
+i32 Denominator; /* denominator from current DVI file */
+i32 DVIMag; /* magnification from current DVI file */
+
+i32 OutputNumerator; /* numerator from first DVI file */
+i32 OutputDenominator; /* denominator from first DVI file */
+i32 OutputMag; /* magnification from first DVI file or arg */
+
+i32 TallestPageHeight; /* max of all tallest-page-height values */
+i32 WidestPageWidth; /* max of all widest-page-widths */
+i16 DVIStackSize; /* max of all stack sizes */
+
+/* save some string space: we use this a lot */
+char writeerr[] = "error writing DVI file";
+
+char *malloc(), *realloc();
+/*
+ * You may get lint warnings about sprintf's return value.
+ * Older versions of 4BSD have `char *sprintf()'. ANSI and
+ * SysV use `int sprintf()'; so ignore the warnings.
+ */
+
+/*
+ * Lint gets somewhat confused over putc.
+ */
+#ifdef lint
+#define putc(c, f) fputc((int) c, f)
+#endif
+
+/*
+ * Start a page (process a DVI_BOP).
+ */
+void
+BeginPage()
+{
+ register i32 t;
+ register int i;
+
+ OutputFontIndex = -1; /* new page requires respecifying font */
+ putbyte(outf, DVI_BOP);
+ /* copy the count registers */
+ for (i = 10; --i >= 0;) {
+ fGetLong(inf, t);
+ PutLong(outf, t);
+ }
+ (void) GetLong(inf); /* previous page pointer */
+ PutLong(outf, StartOfLastPage);
+ if (ferror(outf))
+ error(1, -1, writeerr);
+
+ StartOfLastPage = CurrentPosition;
+ CurrentPosition += 45; /* we just wrote this much */
+}
+
+/*
+ * End a page (process a DVI_EOP).
+ */
+void
+EndPage()
+{
+
+ putbyte(outf, DVI_EOP);
+ if (ferror(outf))
+ error(1, -1, writeerr);
+ CurrentPosition++;
+ NumberOfOutputPages++;
+}
+
+/*
+ * Write a font definition to the output file.
+ */
+void
+WriteFont(fi)
+ register struct fontinfo *fi;
+{
+ register int l;
+ register char *s;
+
+ if (fi->fi_index < 256) {
+ putbyte(outf, DVI_FNTDEF1);
+ putbyte(outf, fi->fi_index);
+ CurrentPosition += 2;
+ } else if (fi->fi_index < 65536) {
+ putbyte(outf, DVI_FNTDEF2);
+ PutWord(outf, fi->fi_index);
+ CurrentPosition += 3;
+ } else if (fi->fi_index < 16777216) {
+ putbyte(outf, DVI_FNTDEF3);
+ Put3Byte(outf, fi->fi_index);
+ CurrentPosition += 4;
+ } else {
+ putbyte(outf, DVI_FNTDEF4);
+ PutLong(outf, fi->fi_index);
+ CurrentPosition += 5;
+ }
+ PutLong(outf, fi->fi_checksum);
+ PutLong(outf, fi->fi_mag);
+ PutLong(outf, fi->fi_designsize);
+ putbyte(outf, fi->fi_n1);
+ putbyte(outf, fi->fi_n2);
+ l = fi->fi_n1 + fi->fi_n2;
+ CurrentPosition += 14 + l;
+ s = fi->fi_name;
+ while (--l >= 0)
+ putbyte(outf, *s++);
+}
+
+/*
+ * Write the postamble for the concatenation of all the input files.
+ */
+void
+WritePostAmble()
+{
+ register struct fontinfo *fi;
+ register i32 postpos = CurrentPosition; /* remember for later */
+
+ /* POST p n d m h w s pages */
+ putbyte(outf, DVI_POST);
+ PutLong(outf, StartOfLastPage);
+ PutLong(outf, OutputNumerator);
+ PutLong(outf, OutputDenominator);
+ PutLong(outf, OutputMag);
+ PutLong(outf, TallestPageHeight);
+ PutLong(outf, WidestPageWidth);
+ PutWord(outf, DVIStackSize);
+ PutWord(outf, NumberOfOutputPages);
+ CurrentPosition += 29; /* count all those `put's */
+
+ for (fi = fonts; fi != NULL; fi = fi->fi_next)
+ WriteFont(fi);
+
+ putbyte(outf, DVI_POSTPOST);
+ PutLong(outf, postpos);
+ putbyte(outf, DVI_VERSION);
+ putbyte(outf, DVI_FILLER);
+ putbyte(outf, DVI_FILLER);
+ putbyte(outf, DVI_FILLER);
+ putbyte(outf, DVI_FILLER);
+ CurrentPosition += 10;
+ while (CurrentPosition & 3) {
+ putbyte(outf, DVI_FILLER);
+ CurrentPosition++;
+ }
+ if (ferror(outf))
+ error(1, -1, writeerr);
+}
+
+/*
+ * Read the information we need from the postamble for the current DVI file.
+ */
+void
+HandlePostAmble()
+{
+ register i32 t;
+ register i16 w;
+
+ (void) GetLong(inf); /* previous page pointer */
+ if (GetLong(inf) != Numerator) {
+ error(0, 0,
+ "%s: postamble's numerator does not match preamble's",
+ DVIFileName);
+ errs++;
+ }
+ if (GetLong(inf) != Denominator) {
+ error(0, 0,
+ "%s: postamble's denominator does not match preamble's",
+ DVIFileName);
+ errs++;
+ }
+ if (GetLong(inf) != DVIMag) {
+ error(0, 0,
+ "%s: postamble's magnification does not match preamble's",
+ DVIFileName);
+ errs++;
+ }
+
+ /*
+ * Find maximum of tallest page height, widest page width, and
+ * stack size.
+ */
+ t = GetLong(inf);
+ if (t > TallestPageHeight)
+ TallestPageHeight = t;
+ t = GetLong(inf);
+ if (t > WidestPageWidth)
+ WidestPageWidth = t;
+ w = GetWord(inf);
+ if (w > DVIStackSize)
+ DVIStackSize = w;
+
+ /*
+ * The remainder of the file---number of pages, list of fonts,
+ * postpost, pointer, version, and filler---we simply ignore.
+ */
+}
+
+/*
+ * Handle a preamble.
+ * `firstone' is true if this is the first input file.
+ * Return true iff something is wrong with the file.
+ */
+int
+HandlePreAmble(firstone)
+ int firstone;
+{
+ register int n, c;
+ static char warn1[] = "%s: Warning: preamble %s of %ld";
+ static char warn2[] = "does not match first file's value of %ld";
+
+ if (getc(inf) != DVI_PRE) {
+ error(0, 0, "%s does not begin with a preamble", DVIFileName);
+ error(0, 0, "(are you sure it is a DVI file?)");
+ errs++;
+ return (1);
+ }
+ if (getc(inf) != DVI_VERSION) {
+ error(0, 0, "%s is not a DVI version %d file", DVIFileName,
+ DVI_VERSION);
+ errs++;
+ return (1);
+ }
+
+ /* committed to DVI file: now most errors are fatal */
+ if (firstone) {
+ OutputNumerator = Numerator = GetLong(inf);
+ OutputDenominator = Denominator = GetLong(inf);
+ } else {
+ Numerator = GetLong(inf);
+ if (Numerator != OutputNumerator) {
+ error(0, 0, warn1, DVIFileName, "numerator",
+ (long)Numerator);
+ error(0, 0, warn2, (long)OutputNumerator);
+ errs++;
+ }
+ Denominator = GetLong(inf);
+ if (Denominator != OutputDenominator) {
+ error(0, 0, warn1, DVIFileName, "denominator",
+ (long)Denominator);
+ error(0, 0, warn2, (long)OutputDenominator);
+ errs++;
+ }
+ }
+ DVIMag = GetLong(inf);
+ if (OutputMag == 0)
+ OutputMag = DVIMag;
+ else if (DVIMag != OutputMag) {
+ error(0, 0,
+ "%s: Warning: magnification of %ld changed to %ld",
+ DVIFileName, (long)DVIMag, (long)OutputMag);
+ errs++;
+ }
+ n = UnSign8(GetByte(inf)); /* comment length */
+ if (firstone) {
+ putbyte(outf, DVI_PRE);
+ putbyte(outf, DVI_VERSION);
+ PutLong(outf, Numerator);
+ PutLong(outf, Denominator);
+ PutLong(outf, OutputMag);
+
+ CurrentPosition = 15 + n; /* well, almost */
+ putbyte(outf, n);
+ while (--n >= 0) {
+ c = GetByte(inf);
+ putbyte(outf, c);
+ }
+ } else {
+ while (--n >= 0)
+ (void) GetByte(inf);
+ }
+ return (0);
+}
+
+/*
+ * Read one DVI file, concatenating it with the previous one (if any)
+ * or starting up the output file (otherwise).
+ */
+void
+doit(name, fp)
+ char *name;
+ FILE *fp;
+{
+ static int started;
+
+ DVIFileName = name;
+ inf = fp;
+ if (HandlePreAmble(started ? 0 : 1))
+ return;
+ SClear(FontFinder);
+ HandleDVIFile();
+ HandlePostAmble();
+ started = 1;
+}
+
+main(argc, argv)
+ int argc;
+ register char **argv;
+{
+ register int c;
+ register char *s;
+ FILE *f;
+
+ ProgName = *argv;
+
+ /*
+ * Handle arguments.
+ */
+ while ((c = getopt(argc, argv, "m:o:")) != EOF) {
+ switch (c) {
+
+ case 'm':
+ if (OutputMag)
+ goto usage;
+ OutputMag = atoi(optarg);
+ break;
+
+ case 'o':
+ if (outf != NULL)
+ goto usage;
+ if ((outf = fopen(optarg, "w")) == NULL)
+ error(1, -1, "cannot write %s", optarg);
+ break;
+
+ case '?':
+usage:
+ (void) fprintf(stderr,
+ "Usage: %s [-m mag] [-o outfile] [files]\n",
+ ProgName);
+ (void) fflush(stderr);
+ exit(1);
+ }
+ }
+
+ /* setup */
+ if (outf == NULL)
+ outf = stdout;
+ if ((FontFinder = SCreate(sizeof(struct fontinfo *))) == 0)
+ error(1, 0, "cannot create font finder (out of memory?)");
+ StartOfLastPage = -1;
+
+ /*
+ * Concatenate the named input file(s).
+ * We write a preamble based on the first input file.
+ */
+ if (optind >= argc)
+ doit("`stdin'", stdin);
+ else {
+ for (c = optind; c < argc; c++) {
+ s = argv[c];
+ if (*s == '-' && s[1] == 0)
+ doit("`stdin'", stdin);
+ else if ((f = fopen(s, "r")) == NULL) {
+ error(0, -1, "cannot read %s", s);
+ errs++;
+ } else {
+ doit(s, f);
+ (void) fclose(f);
+ }
+ }
+ }
+ if (CurrentPosition)
+ WritePostAmble();
+
+ (void) fprintf(stderr, "Wrote %d page%s, %ld bytes\n",
+ NumberOfOutputPages, NumberOfOutputPages == 1 ? "" : "s",
+ (long)CurrentPosition);
+ exit(errs ? 2 : 0);
+ /* NOTREACHED */
+}
+
+/*
+ * Handle a font definition.
+ */
+HandleFontDef(index)
+ i32 index;
+{
+ register struct fontinfo *fi;
+ register int i;
+ register char *s;
+ register i32 checksum, mag, designsize;
+ register int n1, n2;
+ struct fontinfo **p;
+ char *name;
+ int d = S_CREATE | S_EXCL;
+
+ if ((p = (struct fontinfo **)SSearch(FontFinder, index, &d)) == NULL)
+ if (d & S_COLL)
+ error(1, 0, "font %ld already defined", (long)index);
+ else
+ error(1, 0, "cannot stash font %ld (out of memory?)",
+ (long)index);
+
+ /* collect the font information */
+ checksum = GetLong(inf);
+ mag = GetLong(inf);
+ designsize = GetLong(inf);
+ n1 = UnSign8(GetByte(inf));
+ n2 = UnSign8(GetByte(inf));
+ i = n1 + n2;
+ if ((s = malloc((unsigned)i)) == NULL)
+ GripeOutOfMemory(i, "font name");
+ for (name = s; --i >= 0;)
+ *s++ = GetByte(inf);
+ s = name;
+
+ /*
+ * We have not seen the font before in this input file,
+ * but we may have seen it in a previous file, so we
+ * must search.
+ */
+ i = n1 + n2;
+ for (fi = fonts; fi != NULL; fi = fi->fi_next) {
+ if (fi->fi_designsize == designsize &&
+ fi->fi_mag == mag &&
+ fi->fi_n1 == n1 && fi->fi_n2 == n2 &&
+ bcmp(fi->fi_name, s, i) == 0) {
+ if (fi->fi_checksum == 0)
+ fi->fi_checksum = checksum;
+ else if (checksum && fi->fi_checksum != checksum) {
+ error(0, 0, "\
+%s: Warning: font checksum mismatch for %.*s detected",
+ DVIFileName, i, s);
+ errs++;
+ }
+ *p = fi;
+ return;
+ }
+ }
+ /* it is really new; add it to the list */
+ if ((fi = (struct fontinfo *)malloc(sizeof *fi)) == NULL)
+ GripeOutOfMemory(sizeof *fi, "font information");
+ fi->fi_next = fonts;
+ fi->fi_index = NextOutputFontIndex++;
+ fi->fi_checksum = checksum;
+ fi->fi_mag = mag;
+ fi->fi_designsize = designsize;
+ fi->fi_n1 = n1;
+ fi->fi_n2 = n2;
+ fi->fi_name = s;
+ fonts = fi;
+ WriteFont(fi);
+ *p = fi;
+}
+
+/*
+ * Handle a \special.
+ */
+HandleSpecial(c, l, p)
+ int c;
+ register int l;
+ register i32 p;
+{
+ register int i;
+
+ putbyte(outf, c);
+ switch (l) {
+
+ case DPL_UNS1:
+ putbyte(outf, p);
+ CurrentPosition += 2;
+ break;
+
+ case DPL_UNS2:
+ PutWord(outf, p);
+ CurrentPosition += 3;
+ break;
+
+ case DPL_UNS3:
+ Put3Byte(outf, p);
+ CurrentPosition += 4;
+ break;
+
+ case DPL_SGN4:
+ PutLong(outf, p);
+ CurrentPosition += 5;
+ break;
+
+ default:
+ panic("HandleSpecial l=%d", l);
+ /* NOTREACHED */
+ }
+ CurrentPosition += p;
+ while (--p >= 0) {
+ i = getc(inf);
+ putbyte(outf, i);
+ }
+ if (feof(inf))
+ GripeUnexpectedDVIEOF();
+ if (ferror(outf))
+ error(1, -1, writeerr);
+}
+
+UseFont(index)
+ register i32 index;
+{
+ struct fontinfo *fi, **p;
+ int look = S_LOOKUP;
+
+ p = (struct fontinfo **)SSearch(FontFinder, index, &look);
+ if (p == NULL)
+ error(1, 0, "%s requested font %ld without defining it",
+ (long)index);
+ if ((fi = *p) == NULL)
+ panic("null entry in FontFinder for %ld", (long)index);
+ index = fi->fi_index;
+ if (index < 64) {
+ putbyte(outf, index + DVI_FNTNUM0);
+ CurrentPosition++;
+ } else if (index < 256) {
+ putbyte(outf, DVI_FNT1);
+ putbyte(outf, index);
+ CurrentPosition += 2;
+ } else if (index < 65536) {
+ putbyte(outf, DVI_FNT2);
+ PutWord(outf, index);
+ CurrentPosition += 3;
+ } else if (index < 16777216) {
+ putbyte(outf, DVI_FNT3);
+ Put3Byte(outf, index);
+ CurrentPosition += 4;
+ } else {
+ putbyte(outf, DVI_FNT4);
+ PutLong(outf, index);
+ CurrentPosition += 5;
+ }
+}
+
+/*
+ * The following table describes the length (in bytes) of each of the DVI
+ * commands that we can simply copy, starting with DVI_SET1 (128).
+ */
+char oplen[128] = {
+ 2, 3, 4, 5, /* DVI_SET1 .. DVI_SET4 */
+ 9, /* DVI_SETRULE */
+ 2, 3, 4, 5, /* DVI_PUT1 .. DVI_PUT4 */
+ 9, /* DVI_PUTRULE */
+ 1, /* DVI_NOP */
+ 0, /* DVI_BOP */
+ 0, /* DVI_EOP */
+ 1, /* DVI_PUSH */
+ 1, /* DVI_POP */
+ 2, 3, 4, 5, /* DVI_RIGHT1 .. DVI_RIGHT4 */
+ 1, /* DVI_W0 */
+ 2, 3, 4, 5, /* DVI_W1 .. DVI_W4 */
+ 1, /* DVI_X0 */
+ 2, 3, 4, 5, /* DVI_X1 .. DVI_X4 */
+ 2, 3, 4, 5, /* DVI_DOWN1 .. DVI_DOWN4 */
+ 1, /* DVI_Y0 */
+ 2, 3, 4, 5, /* DVI_Y1 .. DVI_Y4 */
+ 1, /* DVI_Z0 */
+ 2, 3, 4, 5, /* DVI_Z1 .. DVI_Z4 */
+ 0, /* DVI_FNTNUM0 (171) */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 172 .. 179 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 180 .. 187 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 188 .. 195 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 196 .. 203 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 204 .. 211 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 212 .. 219 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 220 .. 227 */
+ 0, 0, 0, 0, 0, 0, 0, /* 228 .. 234 */
+ 0, 0, 0, 0, /* DVI_FNT1 .. DVI_FNT4 */
+ 0, 0, 0, 0, /* DVI_XXX1 .. DVI_XXX4 */
+ 0, 0, 0, 0, /* DVI_FNTDEF1 .. DVI_FNTDEF4 */
+ 0, /* DVI_PRE */
+ 0, /* DVI_POST */
+ 0, /* DVI_POSTPOST */
+ 0, 0, 0, 0, 0, 0, /* 250 .. 255 */
+};
+
+/*
+ * Here we read the input DVI file and copy the pages to the output
+ * DVI file, renumbering fonts. We also keep track of font changes,
+ * handle font definitions, and perform some other housekeeping.
+ */
+HandleDVIFile()
+{
+ register int c, l;
+ register i32 p;
+ int doingpage = 0;
+
+ /* Only way out is via "return" statement */
+ for (;;) {
+ c = getc(inf); /* getc() returns unsigned values */
+ if (DVI_IsChar(c)) {
+ putbyte(outf, c);
+ CurrentPosition++;
+ continue;
+ }
+ if (DVI_IsFont(c)) { /* note font change */
+ UseFont((i32)(c - DVI_FNTNUM0));
+ continue;
+ }
+ if (c == EOF)
+ GripeUnexpectedDVIEOF();
+ if ((l = (oplen - 128)[c]) != 0) { /* simple copy */
+ CurrentPosition += l;
+ putbyte(outf, c);
+ while (--l > 0) {
+ c = getc(inf);
+ putbyte(outf, c);
+ }
+ if (ferror(outf))
+ error(1, -1, writeerr);
+ continue;
+ }
+ if ((l = DVI_OpLen(c)) != 0) {
+ /*
+ * Handle other generics.
+ * N.B.: there should only be unsigned parameters
+ * here (save SGN4), for commands with negative
+ * parameters have been taken care of above.
+ */
+ switch (l) {
+
+ case DPL_UNS1:
+ p = getc(inf);
+ break;
+
+ case DPL_UNS2:
+ fGetWord(inf, p);
+ break;
+
+ case DPL_UNS3:
+ fGet3Byte(inf, p);
+ break;
+
+ case DPL_SGN4:
+ fGetLong(inf, p);
+ break;
+
+ default:
+ panic("HandleDVIFile l=%d", l);
+ }
+
+ /*
+ * Now that we have the parameter, perform the
+ * command.
+ */
+ switch (DVI_DT(c)) {
+
+ case DT_FNT:
+ UseFont(p);
+ continue;
+
+ case DT_XXX:
+ HandleSpecial(c, l, p);
+ continue;
+
+ case DT_FNTDEF:
+ HandleFontDef(p);
+ continue;
+
+ default:
+ panic("HandleDVIFile DVI_DT(%d)=%d",
+ c, DVI_DT(c));
+ }
+ continue;
+ }
+
+ switch (c) { /* handle the few remaining cases */
+
+ case DVI_BOP:
+ if (doingpage)
+ GripeUnexpectedOp("BOP (during page)");
+ BeginPage();
+ doingpage = 1;
+ break;
+
+ case DVI_EOP:
+ if (!doingpage)
+ GripeUnexpectedOp("EOP (outside page)");
+ EndPage();
+ doingpage = 0;
+ break;
+
+ case DVI_PRE:
+ GripeUnexpectedOp("PRE");
+ /* NOTREACHED */
+
+ case DVI_POST:
+ if (doingpage)
+ GripeUnexpectedOp("POST (inside page)");
+ return;
+
+ case DVI_POSTPOST:
+ GripeUnexpectedOp("POSTPOST");
+ /* NOTREACHED */
+
+ default:
+ GripeUndefinedOp(c);
+ /* NOTREACHED */
+ }
+ }
+}
diff --git a/dviware/dvibook/Dviconcat/dviconcat.man b/dviware/dvibook/Dviconcat/dviconcat.man
new file mode 100644
index 0000000000..9267446095
--- /dev/null
+++ b/dviware/dvibook/Dviconcat/dviconcat.man
@@ -0,0 +1,46 @@
+.TH DVICONCAT 1
+.SH NAME
+dviconcat \- concatenate DVI files
+.SH SYNOPSIS
+.B dviconcat
+[
+.B \-m
+.I magnification
+] [
+.B \-o
+.I outfile
+]
+.I "list of files"
+.SH DESCRIPTION
+.I Dviconcat
+concatenates the named
+.IR file s
+(or standard input, if no file names are given)
+onto the standard output
+or the given
+.IR outfile ,
+creating a new DVI file
+usable by any of the TeX conversion programs,
+or even by
+.I dviconcat
+itself.
+.PP
+The magnification of the output file
+is the same as that of the first input file
+unless the
+.B \-m
+option is given.
+When
+.I dviconcat
+changes the magnification of any input file,
+it prints a warning to this effect.
+.SH AUTHOR
+Chris Torek, University of Maryland
+.SH "SEE ALSO"
+dviselect(1), latex(1), tex(1)
+.br
+.I "MC-TeX User's Guide"
+.SH BUGS
+The program should be called
+.IR dvicat ,
+but that name was taken (for the driver for the C/A/T typesetter).
diff --git a/dviware/dvibook/Dviconcat/dviconcat.pdf b/dviware/dvibook/Dviconcat/dviconcat.pdf
new file mode 100644
index 0000000000..be3dcd2a8d
--- /dev/null
+++ b/dviware/dvibook/Dviconcat/dviconcat.pdf
Binary files differ