DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦d29cc263c⟧ TextFile

    Length: 11673 (0x2d99)
    Types: TextFile
    Names: »dviloop.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/dvitps/src/dviloop.c« 

TextFile

/* Copyright 1988 Stephan v. Bechtolsheim */

/* This file is part of the TeXPS Software Package.

The TeXPS Software Package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the TeXPS Software Package
General Public License for full details.

Everyone is granted permission to copy, modify and redistribute
the TeXPS Software Package, but only under the conditions described in the
TeXPS Software Package General Public License.   A copy of this license is
supposed to have been given to you along with TeXPS Software Package so you
can know your rights and responsibilities.  It should be in a
file named CopyrightLong.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

#include <stdio.h>
#if SYS_V == 1
#include <string.h>
#else
#include <strings.h>
#endif
#include "defs.h"
#include "units.h"
#include "dvitps.h"
#include "extfil.h"
#include "fontd.h"
#include "emit.h"
#include "dvi-com.h"

extern char *HandleFileNameExtension();
extern int Argc;
extern char *Argv[1];
extern int Verbose;
extern int ResetOption;
extern int ResetPageNum;
extern int OrderOfOutput;
extern int ConformingDocument;
extern int StderrOutputPageNumber;
extern int StderrOutputPageNumberMod;
extern EX_FILES Ex_PsOutput;
extern void ResetBetweenPages();
extern void ReadDviPreAmble();
extern void ComputeConversionFactors();
extern void InitFontSubstitutionBusiness();
extern void PsBeginningSend();
extern void ReadDviPostAmble();
extern void PsMatrixSend();
extern int Pass1();

void HandleDviFileOpening();
void HandleDviFileClosing();
void LoopThroughDviFiles();
void ConformingDviFiles();
void NonConformingDviFiles();
void OpenNextDviFile();

int DviFileCounter; /* Number of dvi files handled by this driver */

EX_FILES ExDvi; /* File pointer, current .dvi file. */

/* Page Pointers. */
int FirstPP; /* Offset in dvi file: first page. */
int LastPP; /* Offset in dvi file: last page. */
int PrevPP; /* Offset in dvi file: previous page pointer. */

int Count[10]; /* \count0 .. 9 in dvi file. */

int CountPages;

/* Usual orientation of pages in this document. */
int UsualOrientation = PORTRAIT_MODE;
/* The orientation of the current page in particular. */
int ThisPagesOrientation = PORTRAIT_MODE;

/*
 * LoopThroughDviFiles
 * *******************
 * This routine is called by main() to start the processing of all
 * dvi files. There are two different ways of handling dvi files and
 * they are dealt with here.
 *
 * ret_decode_args: index where dvi file names start in Argv[..].
 */
void
LoopThroughDviFiles(ret_decode_args)
     int ret_decode_args;
{
  if (ConformingDocument)
    ConformingDviFiles(ret_decode_args); /* -C option of driver */
  else
    NonConformingDviFiles(ret_decode_args); /* Default. */
  if (Verbose > V_QUIET && StderrOutputPageNumber != 0)
    fprintf (stderr, "\n");
}

/*
 * NonConformingDviFiles
 * *********************
 * The output by this driver generates by default non-conforming PostScript
 * output. The following procedure handles this case.
 *
 * ret_decode_args: index where dvi file names start in Argv[..].
 *      (passed down from LoopThroughDviFiles())
 */
void
NonConformingDviFiles(ret_decode_args)
     int ret_decode_args;
{
  int dvi_i; /* Index dvi files. */
  int ret_pass0; /* Return value of pass 0. */
  int ret_pass1; /* Return value of pass 1. */
  int potential_for_vm_reset; /* Is there potential for a VM reset? */
  int command; /* Command from the dvi file. */
  int done;

  /* Loop through all dvi files. */
  for (dvi_i=ret_decode_args; dvi_i<Argc; dvi_i++) {
    OpenNextDviFile(0, dvi_i);

    /* Loop through the pages of a dvi file.
       Pass0() repositions dvi file, where it started out if so requested
       (argument is TRUE). Pass1() returns false iff it found the POST command. */
    done = FALSE;
    while (!done)    {
      CountPages++;

      /* Pass 0 is executed here. */
      ret_pass0 = Pass0(TRUE);

      /* Evaluate result of Pass 0. */
      switch (ret_pass0) {
        case PASS0_EOP_FOUND:
	  break;
	case PASS0_POSTAMBLE_FOUND:
	  break;
	default:
	  Fatal2 ("NonConformingDviFiles(): illegal return code pass0: %d",
		  ret_pass0);
      }

      /* If the orientation changed, a new matrix must be sent. */
      if (UsualOrientation != ThisPagesOrientation)
	PsMatrixSend();

      /* Pass1 is executed here. */
      ret_pass1 = Pass1();

      if (ret_pass0 == PASS0_POSTAMBLE_FOUND && ret_pass1 != PASS1_POSTAMBLE_FOUND)
	Fatal ("NonConformingDocument(): inconsistency A.");
      if (ret_pass0 != PASS0_POSTAMBLE_FOUND && ret_pass1 == PASS1_POSTAMBLE_FOUND)
	Fatal ("NonConformingDocument(): inconsistency B.");

      /* Orientation back to what it is normally in all cases. */
      if (UsualOrientation != ThisPagesOrientation) {
	ThisPagesOrientation = UsualOrientation;
	PsMatrixSend();
      }

      /* Proceed to the next page of the dvi file which may
	 be the following page or the preceding page. */
      switch (OrderOfOutput) {
        case ORDER_OUTPUT_FORWARD:
	  /* No reason to reposition dvi file (correct from pass1).
	     Done if Postamble read last. */
	  done = (ret_pass0 == PASS0_POSTAMBLE_FOUND);
	  break;
	case ORDER_OUTPUT_REVERSE:
	  if (PrevPP == -1)
	    done = TRUE;
	  else
	    FExSeek (&ExDvi, PrevPP, FSEEK_ABS);
	  break;
	default:
	  Fatal ("NonConformingDocument(): OrderOfOutput");
      }

      /*
       * A reset between pages can be triggered as follows:
       * (1) -z option when driver is invoked.
       *
       * The following is ugly code, but it works and it fixes
       * an extra prologue file which was appended to the end of
       * some of the PostScript files generated by this program.
       */

      /* Is there potential for a VM reset? If not, just go on. */
      if (ResetOption && !done && CountPages%ResetPageNum == 0) {
	/* Yes, it's worth looking. */
	switch (OrderOfOutput) {
          case ORDER_OUTPUT_FORWARD:
	    /* Read in the next command from the dvi file. We are interested
	       in finding out whether it's a DVI_POST or a DVI_BOP command.
	       If it's a DVI_BOP command, then more pages are in the dvi file
	       and we will do a VM reset. If it's a DVI_POST, the postamble
	       is coming and nothing else needs to be done. */
	    command = NoSignExtend(EX_FP(ExDvi), 1);
	    FExSeek (&ExDvi, -1, FSEEK_REL); /* Position back. */
	    switch (command) {
	      case DVI_BOP:
	        ResetBetweenPages();
		break;
	      case DVI_POST:
		break;
	      default:
		Fatal2 ("NonConformingDviFiles(): dvi: '%o illegal.", command);
	      }
	    break;

	  /* In the case of reverse output, the done variable already reflects
	     the fact, that there is no sense in an additional reset (that is
	     done is already TRUE). So the program should never come here when
	     the end of the dvi file is already reached (better, when the beginning
	     of the dvi fils is already reached, because we are talking about
	     reverse output here. */
	  case ORDER_OUTPUT_REVERSE:
	    ResetBetweenPages();
	    break;
	  }
      }
    } /* While loop pages of dvi file */

    FExClose (&ExDvi);
  } /* End of loop of all dvi file pages. */
}

/*
 * ConformingDviFiles
 * ******************
 * Generate a "conforming PostScript output" type of output. In that
 * case we first have to do all pass0s of all .dvi files, and then
 * all pass1s.
 *
 * ret_decode_args: index where dvi file names start in Argv[..].
 *      (passed down from LoopThroughDviFiles())
 */
void
ConformingDviFiles(ret_decode_args)
     int ret_decode_args;
{
  int dvi_i; /* Index dvi files. */
  int ret_pass0; /* return pass 0 */
  int ret_pass1; /* return pass 1 */
  int done;
  int n;

  /* Pass0 of all the dvi files. */
  for (dvi_i=ret_decode_args; dvi_i<Argc; dvi_i++) {
    OpenNextDviFile(1, dvi_i);
    done = FALSE;
    while (! done) {
      CountPages++;
      ret_pass0 = Pass0(FALSE);
      switch (ret_pass0) {
        case PASS0_EOP_FOUND:
	  break;
	case PASS0_POSTAMBLE_FOUND:
	  done = TRUE;
	  break;
	default:
	  Fatal2 ("ConformingDviFiles(): illegal return code pass0: %d", ret_pass0);
      }

      /* Proceed to the next page of the dvi file which may
	 be the following page or the preceding page. */
      switch (OrderOfOutput) {
        case ORDER_OUTPUT_FORWARD:
	  /* No reason to reposition dvi file. */
	  break;
	case ORDER_OUTPUT_REVERSE:
	  if (PrevPP == -1)
	    done = TRUE;
	  else
	    FExSeek (&ExDvi, PrevPP, FSEEK_ABS);
	  break;
	default:
	  Fatal ("ConformingDviFiles(): OrderOfOutput-2");
      }
    } /* while (!done) */

    FExClose (&ExDvi);
    if (StderrOutputPageNumber != 0) {
      fprintf (stderr, "\n");
      StderrOutputPageNumber = 0;
    }
  } /* Pass0 for all dvi files. */

  /* This is the end of the prologue as far as conforming documents
     are concerned. */
  fprintf (EX_FP(Ex_PsOutput), "%%%%EndProlog\n");

  /* Next round: Pass 1 of all dvi files. */
  for (dvi_i=ret_decode_args; dvi_i<Argc; dvi_i++) {
    OpenNextDviFile(1, dvi_i);

    n = CountPages;
    CountPages = 0;

    done = FALSE;
    while (! done) {
      CountPages++;
      if (CountPages != n)
	fprintf (EX_FP(Ex_PsOutput), "%%%%Page: ? %d\n", CountPages);
      ret_pass1 = Pass1();

      /* Position to the "next page" of the dvi file, which may
	 be the following page or the preceding page. */
      switch (OrderOfOutput) {
        case ORDER_OUTPUT_FORWARD:
	  /* No reason to reposition dvi file. */
	  if (ret_pass1 == PASS1_POSTAMBLE_FOUND)
	    done = TRUE;
	  break;
	case ORDER_OUTPUT_REVERSE:
	  if (PrevPP == -1)
	    done = TRUE;
	  else
	    FExSeek (&ExDvi, PrevPP, FSEEK_ABS);
	  break;
	default:
	  Fatal ("ConformingDviFiles(): OrderOfOutput-3");
	} /* switch */
    }
    FExClose (&ExDvi);
  } /* Pass 1 for all dvi files */
}

int StdinCludge = FALSE; /* Will be set to true after the first call to
			    OpenNextDviFile, control == 1, and file name == "-" */

/*
 * OpenNextDviFile
 * ***************
 * Open the next dvi file. 
 * control: 0: non-conforming document generated.
 *          1: conforming document generated so this routine will be called
 *             twice.
 * index: index into Argv[.] for the file name.
 */
void
OpenNextDviFile(control, index)
     int control;
     int index;
{
  switch(control) {
    /* A nonconforming document is generated, so the .dvi file is
       read in only once. */
    case 0:
      FExOpen (&ExDvi, EFT_READ, EFQ_STDIN_TMP_FILE, Argv[index], "dvi");
      break;

    /* A conforming document is generated. */
    case 1:
      if (Strcmp(Argv[index], "-") == 0) {
	if (StdinCludge)
	  FExOpen (&ExDvi, EFT_READ, EFQ_STDIN_TWICE_SECOND_TIME, "-", NULL);
	else {
	  StdinCludge = TRUE;
	  FExOpen (&ExDvi, EFT_READ, EFQ_STDIN_TWICE, "-", NULL);
	}
      } else /* not stdin! */
	FExOpen (&ExDvi, EFT_READ, 0, Argv[index], "dvi");
      break;

    default:
      Fatal("OpenNextDviFile(): default.");
  }

  /* Read in preamble, compute factors, set up some font business. */
  ReadDviPreAmble();
  ComputeConversionFactors();
  InitFontSubstitutionBusiness();
  PsBeginningSend();
  ReadDviPostAmble();

  /* Position correctly within the .dvi file. */
  switch (OrderOfOutput) {
    case ORDER_OUTPUT_FORWARD:
      FExSeek(&ExDvi, FirstPP, FSEEK_ABS);
      break;
    case ORDER_OUTPUT_REVERSE:
      FExSeek(&ExDvi, LastPP, FSEEK_ABS);
      break;
    }

  ThisPagesOrientation = UsualOrientation;
}