Esempio n. 1
0
void char_buffer::emit_troff_output(int device_format_selector)
{
  // Handle output for BOTH html and image device formats
  // if `device_format_selector' is passed as
  //
  //   HTML_FORMAT(HTML_OUTPUT_FILTER)
  //     Buffer data is written to the output stream
  //     with template image names translated to actual image names.
  //
  //   HTML_FORMAT(IMAGE_OUTPUT_FILTER)
  //     Buffer data is written to the output stream
  //     with no translation, for image file creation in the post-processor.

  int idx = 0;
  char_block *element = head;

  while (element != NULL)
    write_upto_newline(&element, &idx, device_format_selector);

#if 0
  if (close(stdoutfd) < 0)
    sys_fatal ("close");

  // now we grab fd=1 so that the next pipe cannot use fd=1
  if (stdoutfd == 1) {
    if (dup(2) != stdoutfd)
      sys_fatal ("dup failed to use fd=1");
  }
#endif /* 0 */
}
Esempio n. 2
0
int imageList::createPage(int pageno)
{
  char *s;

  if (currentPageNo == pageno)
    return 0;

  if (currentPageNo >= 1) {
    /*
     *  We need to unlink the files which change each time a new page is
     *  processed.  The final unlink is done by xtmpfile when pre-grohtml
     *  exits.
     */
    unlink(imagePageName);
    unlink(psPageName);
  }

  if (show_progress) {
    fprintf(stderr, "[%d] ", pageno);
    fflush(stderr);
  }

#if defined(DEBUGGING)
  if (debug)
    fprintf(stderr, "creating page %d\n", pageno);
#endif

  s = make_message("psselect -q -p%d %s %s\n",
		   pageno, psFileName, psPageName);

  if (s == NULL)
    sys_fatal("make_message");
  html_system(s, 1);

  s = make_message("echo showpage | "
		   "%s%s -q -dBATCH -dSAFER "
		   "-dDEVICEHEIGHTPOINTS=792 "
		   "-dDEVICEWIDTHPOINTS=%d -dFIXEDMEDIA=true "
		   "-sDEVICE=%s -r%d %s "
		   "-sOutputFile=%s %s -\n",
		   image_gen,
		   EXE_EXT,
		   (getMaxX(pageno) * image_res) / postscriptRes,
		   image_device,
		   image_res,
		   antiAlias,
		   imagePageName,
		   psPageName);
  if (s == NULL)
    sys_fatal("make_message");
  html_system(s, 1);
  free(s);
  currentPageNo = pageno;
  return 0;
}
Esempio n. 3
0
static int makeTempFiles(void)
{
#if defined(DEBUGGING)
  psFileName = DEBUG_FILE("prehtml-ps");
  regionFileName = DEBUG_FILE("prehtml-region");
  imagePageName = DEBUG_FILE("prehtml-page");
  psPageName = DEBUG_FILE("prehtml-psn");
  troffFileName = DEBUG_FILE("prehtml-troff");
  htmlFileName = DEBUG_FILE("prehtml-html");
#else /* not DEBUGGING */
  FILE *f;

  /* psPageName contains a single page of postscript */
  f = xtmpfile(&psPageName,
	       PS_TEMPLATE_LONG, PS_TEMPLATE_SHORT,
	       TRUE);
  if (f == NULL) {
    sys_fatal("xtmpfile");
    return -1;
  }
  fclose(f);

  /* imagePageName contains a bitmap image of the single postscript page */
  f = xtmpfile(&imagePageName,
	       PAGE_TEMPLATE_LONG, PAGE_TEMPLATE_SHORT,
	       TRUE);
  if (f == NULL) {
    sys_fatal("xtmpfile");
    return -1;
  }
  fclose(f);

  /* psFileName contains a postscript file of the complete document */
  f = xtmpfile(&psFileName,
	       PS_TEMPLATE_LONG, PS_TEMPLATE_SHORT,
	       TRUE);
  if (f == NULL) {
    sys_fatal("xtmpfile");
    return -1;
  }
  fclose(f);

  /* regionFileName contains a list of the images and their boxed coordinates */
  f = xtmpfile(&regionFileName,
	       REGION_TEMPLATE_LONG, REGION_TEMPLATE_SHORT,
	       TRUE);
  if (f == NULL) {
    sys_fatal("xtmpfile");
    return -1;
  }
  fclose(f);

#endif /* not DEBUGGING */
  return 0;
}
Esempio n. 4
0
static void set_redirection(int was, int willbe)
{
  // Nothing to do if `was' and `willbe' already have same handle.
  if (was != willbe) {
    // Otherwise attempt the specified redirection.
    if (dup2 (willbe, was) < 0) {
      // Redirection failed, so issue diagnostic and bail out.
      fprintf(stderr, "failed to replace fd=%d with %d\n", was, willbe);
      if (willbe == STDOUT_FILENO)
	fprintf(stderr,
		"likely that stdout should be opened before %d\n", was);
      sys_fatal("dup2");
    }

    // When redirection has been successfully completed assume redundant
    // handle `willbe' is no longer required, so close it.
    if (close(willbe) < 0)
      // Issue diagnostic if `close' fails.
      sys_fatal("close");
  }
}
Esempio n. 5
0
pushBackBuffer::~pushBackBuffer ()
{
  if (charStack != 0) {
    free(charStack);
  }
  close(0);
  /* restore stdin in file descriptor 0 */
  if (dup(stdIn) < 0) {
    sys_fatal("restore stdin");
  }
  close(stdIn);
}
Esempio n. 6
0
static void writeNbytes(const char *s, int l)
{
  int n = 0;
  int r;

  while (n < l) {
    r = write(stdoutfd, s, l - n);
    if (r < 0)
      sys_fatal("write");
    n += r;
    s += r;
  }
}
Esempio n. 7
0
void imageList::createImage(imageItem *i)
{
  if (i->X1 != -1) {
    char *s;
    int x1 = max(min(i->X1, i->X2) * image_res / postscriptRes
		   - IMAGE_BOARDER_PIXELS,
		 0);
    int y1 = max(image_res * vertical_offset / 72
		   + min(i->Y1, i->Y2) * image_res / postscriptRes
		   - IMAGE_BOARDER_PIXELS,
		 0);
    int x2 = max(i->X1, i->X2) * image_res / postscriptRes
	     + IMAGE_BOARDER_PIXELS;
    int y2 = image_res * vertical_offset / 72
	     + max(i->Y1, i->Y2) * image_res / postscriptRes
	     + 1 + IMAGE_BOARDER_PIXELS;
    if (createPage(i->pageNo) == 0) {
      s = make_message("pnmcut%s %d %d %d %d < %s "
		       "| pnmcrop -quiet | pnmtopng%s %s > %s\n",
		       EXE_EXT,
		       x1, y1, x2 - x1 + 1, y2 - y1 + 1,
		       imagePageName,
		       EXE_EXT,
		       TRANSPARENT,
		       i->imageName);
      if (s == NULL)
	sys_fatal("make_message");

#if defined(DEBUGGING)
      if (debug) {
	fprintf(stderr, s);
	fflush(stderr);
      }
#endif
      html_system(s, 0);
      free(s);
    }
    else {
      fprintf(stderr, "failed to generate image of page %d\n", i->pageNo);
      fflush(stderr);
    }
#if defined(DEBUGGING)
  }
  else {
    if (debug) {
      fprintf(stderr, "ignoring image as x1 coord is -1\n");
      fflush(stderr);
    }
#endif
  }
}
Esempio n. 8
0
static void makeFileName(void)
{
  if ((image_dir != NULL) && (strchr(image_dir, '%') != NULL)) {
    error("cannot use a `%%' within the image directory name");
    exit(1);
  }

  if ((image_template != NULL) && (strchr(image_template, '%') != NULL)) {
    error("cannot use a `%%' within the image template");
    exit(1);
  }

  if (image_dir == NULL)
    image_dir = (char *)"";
  else if (strlen(image_dir) > 0
	   && image_dir[strlen(image_dir) - 1] != '/') {
    image_dir = make_message("%s/", image_dir);
    if (image_dir == NULL)
      sys_fatal("make_message");
  }

  if (image_template == NULL)
    macroset_template = make_message("%sgrohtml-%d", image_dir,
				     (int)getpid());
  else
    macroset_template = make_message("%s%s", image_dir, image_template);

  if (macroset_template == NULL)
    sys_fatal("make_message");

  image_template =
    (char *)malloc(strlen("-%d") + strlen(macroset_template) + 1);
  if (image_template == NULL)
    sys_fatal("malloc");
  strcpy(image_template, macroset_template);
  strcat(image_template, "-%d");
}
Esempio n. 9
0
pushBackBuffer::pushBackBuffer (char *filename)
{
  charStack = (char *)malloc(MAXPUSHBACKSTACK);
  if (charStack == 0) {
    sys_fatal("malloc");
  }
  stackPtr = 0;   /* index to push back stack        */
  debug    = 0;
  verbose  = 0;
  eofFound = FALSE;
  lineNo   = 1;
  if (strcmp(filename, "") != 0) {
    stdIn = dup(0);
    if (stdIn < 0) {
      sys_fatal("dup stdin");
    }
    close(0);
    if (open(filename, O_RDONLY) != 0) {
      sys_fatal("when trying to open file");
    } else {
      fileName = filename;
    }
  }
}
Esempio n. 10
0
static int save_and_redirect(int was, int willbe)
{
  if (was == willbe)
    // No redirection specified so don't do anything but silently bailing out.
    return (was);

  // Proceeding with redirection so first save and verify our duplicate
  // handle for `was'.
  int saved = dup(was);
  if (saved < 0) {
    fprintf(stderr, "unable to get duplicate handle for %d\n", was);
    sys_fatal("dup");
  }

  // Duplicate handle safely established so complete redirection.
  set_redirection(was, willbe);

  // Finally return the saved duplicate descriptor for the
  // original `was' stream.
  return saved;
}
Esempio n. 11
0
int char_buffer::run_output_filter(int filter, int argc, char **argv)
{
  int pipedes[2];
  PID_T child_pid;
  int status;

  print_args(argc, argv);
  if (pipe(pipedes) < 0)
    sys_fatal("pipe");

#if MAY_FORK_CHILD_PROCESS
  // This is the UNIX process model.  To invoke our post-processor,
  // we must `fork' the current process.

  if ((child_pid = fork()) < 0)
    sys_fatal("fork");

  else if (child_pid == 0) {
    // This is the child process fork.  We redirect its `stdin' stream
    // to read data emerging from our pipe.  There is no point in saving,
    // since we won't be able to restore later!

    set_redirection(STDIN_FILENO, pipedes[0]);

    // The parent process will be writing this data, so we should release
    // the child's writeable handle on the pipe, since we have no use for it.

    if (close(pipedes[1]) < 0)
      sys_fatal("close");

    // The IMAGE_OUTPUT_FILTER needs special output redirection...

    if (filter == IMAGE_OUTPUT_FILTER) {
      // with BOTH `stdout' AND `stderr' diverted to files.

      set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM);
      set_redirection(STDERR_FILENO, REGION_OUTPUT_STREAM);
    }

    // Now we are ready to launch the output filter.

    execvp(argv[0], argv);

    // If we get to here then the `exec...' request for the output filter
    // failed.  Diagnose it and bail out.

    error("couldn't exec %1: %2", argv[0], strerror(errno), ((char *)0));
    fflush(stderr);	// just in case error() didn't
    exit(1);
  }

  else {
    // This is the parent process fork.  We will be writing data to the
    // filter pipeline, and the child will be reading it.  We have no further
    // use for our read handle on the pipe, and should close it.

    if (close(pipedes[0]) < 0)
      sys_fatal("close");

    // Now we redirect the `stdout' stream to the inlet end of the pipe,
    // and push out the appropiately formatted data to the filter.

    pipedes[1] = save_and_redirect(STDOUT_FILENO, pipedes[1]);
    emit_troff_output(DEVICE_FORMAT(filter));

    // After emitting all the data we close our connection to the inlet
    // end of the pipe so the child process will detect end of data.

    set_redirection(STDOUT_FILENO, pipedes[1]);

    // Finally, we must wait for the child process to complete.

    if (WAIT(&status, child_pid, _WAIT_CHILD) != child_pid)
      sys_fatal("wait");
  }

#elif MAY_SPAWN_ASYNCHRONOUS_CHILD

  // We do not have `fork', (or we prefer not to use it),
  // but asynchronous processes are allowed, passing data through pipes.
  // This should be ok for most Win32 systems and is preferred to `fork'
  // for starting child processes under Cygwin.

  // Before we start the post-processor we bind its inherited `stdin'
  // stream to the readable end of our pipe, saving our own `stdin' stream
  // in `pipedes[0]'.

  pipedes[0] = save_and_redirect(STDIN_FILENO, pipedes[0]);

  // for the Win32 model,
  // we need special provision for saving BOTH `stdout' and `stderr'.

  int saved_stdout = dup(STDOUT_FILENO);
  int saved_stderr = STDERR_FILENO;

  // The IMAGE_OUTPUT_FILTER needs special output redirection...

  if (filter == IMAGE_OUTPUT_FILTER) {
    // with BOTH `stdout' AND `stderr' diverted to files while saving a
    // duplicate handle for `stderr'.

    set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM);
    saved_stderr = save_and_redirect(STDERR_FILENO, REGION_OUTPUT_STREAM);
  }

  // We then use an asynchronous spawn request to start the post-processor.

  if ((child_pid = spawnvp(_P_NOWAIT, argv[0], argv)) < 0) {
    // Should the spawn request fail we issue a diagnostic and bail out.

    error("cannot spawn %1: %2", argv[0], strerror(errno), ((char *)0));
    exit(1);
  }

  // Once the post-processor has been started we revert our `stdin'
  // to its original saved source, which also closes the readable handle
  // for the pipe.

  set_redirection(STDIN_FILENO, pipedes[0]);

  // if we redirected `stderr', for use by the image post-processor,
  // then we also need to reinstate its original assignment.

  if (filter == IMAGE_OUTPUT_FILTER)
    set_redirection(STDERR_FILENO, saved_stderr);

  // Now we redirect the `stdout' stream to the inlet end of the pipe,
  // and push out the appropiately formatted data to the filter.

  set_redirection(STDOUT_FILENO, pipedes[1]);
  emit_troff_output(DEVICE_FORMAT(filter));

  // After emitting all the data we close our connection to the inlet
  // end of the pipe so the child process will detect end of data.

  set_redirection(STDOUT_FILENO, saved_stdout);

  // And finally, we must wait for the child process to complete.

  if (WAIT(&status, child_pid, _WAIT_CHILD) != child_pid)
    sys_fatal("wait");

#else /* can't do asynchronous pipes! */

  // TODO: code to support an MS-DOS style process model
  //        should go here

#endif /* MAY_FORK_CHILD_PROCESS or MAY_SPAWN_ASYNCHRONOUS_CHILD */

  return 0;
}