Exemple #1
0
int close_pdf_file(struct pdf_info * info)
{
    try {
        finish_page(info); // any active

        QPDFWriter output(info->pdf,NULL);
        output.write();
    } catch (...) {
        return 1;
    }

    return 0;
}
Exemple #2
0
static void
top_parse_file (const char *fname, FILE *fp)
{
  char *section_name = NULL;  /* Name of the current section or NULL
                                 if not in a section.  */
  while (macrolist)
    {
      macro_t m = macrolist->next;
      free (m->value);
      free (m);
      macrolist = m;
    }

  parse_file (fname, fp, &section_name, 0);
  free (section_name);
  finish_page ();
}
Exemple #3
0
int add_pdf_page(struct pdf_info * info, int pagen, unsigned width, unsigned height, int bpp, unsigned dpi)
{
    try {
        finish_page(info); // any active

        info->width = width;
        info->height = height;
        info->pixel_bytes = bpp/8;
        info->line_bytes = (width*info->pixel_bytes);
        info->bpp = bpp;
    
        if (info->height > (std::numeric_limits<unsigned>::max() / info->line_bytes)) {
            die("Page too big");
        }
        info->page_data = PointerHolder<Buffer>(new Buffer(info->line_bytes*info->height));

        QPDFObjectHandle page = QPDFObjectHandle::parse(
            "<<"
            "  /Type /Page"
            "  /Resources <<"
            "    /XObject << >> "
            "  >>"
            "  /MediaBox null "
            "  /Contents null "
            ">>");
        page.replaceKey("/Contents",QPDFObjectHandle::newStream(&info->pdf)); // data will be provided later
    
        // Convert to pdf units
        info->page_width=((double)info->width/dpi)*DEFAULT_PDF_UNIT;
        info->page_height=((double)info->height/dpi)*DEFAULT_PDF_UNIT;
        page.replaceKey("/MediaBox",makeBox(0,0,info->page_width,info->page_height));
    
        info->page = info->pdf.makeIndirectObject(page); // we want to keep a reference
        info->pdf.addPage(info->page, false);
    } catch (std::bad_alloc &ex) {
        die("Unable to allocate page data");
    } catch (...) {
        return 1;
    }

    return 0;
}
static void
top_parse_file (const char *fname, FILE *fp)
{
  char *section_name = NULL;  /* Name of the current section or NULL
                                 if not in a section.  */
  macro_t m;

  while (macrolist)
    {
      macro_t next = macrolist->next;
      free (macrolist->value);
      free (macrolist);
      macrolist = next;
    }
  for (m=predefinedmacrolist; m; m = m->next)
    set_macro (m->name, xstrdup ("1"));
  cond_is_active = 1;
  cond_in_verbatim = 0;

  parse_file (fname, fp, &section_name, 0);
  free (section_name);
  finish_page ();
}
/* Parse one Texinfo file and create manpages according to the
   embedded instructions.  */
static void
parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
{
  char *line;
  int lnr = 0;
  /* Fixme: The following state variables don't carry over to include
     files. */
  int skip_to_end = 0;        /* Used to skip over menu entries. */
  int skip_sect_line = 0;     /* Skip after @mansect.  */
  int item_indent = 0;        /* How far is the current @item indented.  */

  /* Helper to define a macro. */
  char *macroname = NULL;
  char *macrovalue = NULL;
  size_t macrovaluesize = 0;
  size_t macrovalueused = 0;

  line = xmalloc (LINESIZE);
  while (fgets (line, LINESIZE, fp))
    {
      size_t n = strlen (line);
      int got_line = 0;
      char *p, *pend;

      lnr++;
      if (!n || line[n-1] != '\n')
        {
          err ("%s:%d: trailing linefeed missing, line too long or "
               "embedded Nul character", fname, lnr);
          break;
        }
      line[--n] = 0;

      /* Kludge to allow indentation of tables.  */
      for (p=line; *p == ' ' || *p == '\t'; p++)
        ;
      if (*p)
        {
          if (*p == '@' && !strncmp (p+1, "item", 4))
            item_indent = p - line;  /* Set a new indent level.  */
          else if (p - line < item_indent)
            item_indent = 0;         /* Switch off indention.  */

          if (item_indent)
            {
              memmove (line, line+item_indent, n - item_indent + 1);
              n -= item_indent;
            }
        }


      if (*line == '@')
        {
          for (p=line+1, n=1; *p && *p != ' ' && *p != '\t'; p++)
            n++;
          while (*p == ' ' || *p == '\t')
            p++;
        }
      else
        p = line;

      /* Take action on macro.  */
      if (macroname)
        {
          if (n == 4 && !memcmp (line, "@end", 4)
              && (line[4]==' '||line[4]=='\t'||!line[4])
              && !strncmp (p, "macro", 5)
              && (p[5]==' '||p[5]=='\t'||!p[5]))
            {
              if (macrovalueused)
                macrovalue[--macrovalueused] = 0; /* Kill the last LF. */
              macrovalue[macrovalueused] = 0;     /* Terminate macro. */
              macrovalue = xrealloc (macrovalue, macrovalueused+1);

              set_macro (macroname, macrovalue);
              macrovalue = NULL;
              free (macroname);
              macroname = NULL;
            }
          else
            {
              if (macrovalueused + strlen (line) + 2 >= macrovaluesize)
                {
                  macrovaluesize += strlen (line) + 256;
                  macrovalue = xrealloc (macrovalue,  macrovaluesize);
                }
              strcpy (macrovalue+macrovalueused, line);
              macrovalueused += strlen (line);
              macrovalue[macrovalueused++] = '\n';
            }
          continue;
        }


      if (n >= 5 && !memcmp (line, "@node", 5)
          && (line[5]==' '||line[5]=='\t'||!line[5]))
        {
          /* Completey ignore @node lines.  */
          continue;
        }


      if (skip_sect_line)
        {
          skip_sect_line = 0;
          if (!strncmp (line, "@section", 8)
              || !strncmp (line, "@subsection", 11)
              || !strncmp (line, "@chapheading", 12))
            continue;
        }

      /* We only parse lines we need and ignore the rest.  There are a
         few macros used to control this as well as one @ifset
         command.  Parts we know about are saved away into containers
         separate for each section. */

      /* First process ifset/ifclear commands. */
      if (*line == '@')
        {
          if (n == 6 && !memcmp (line, "@ifset", 6)
                   && (line[6]==' '||line[6]=='\t'))
            {
              for (p=line+7; *p == ' ' || *p == '\t'; p++)
                ;
              if (!*p)
                {
                  err ("%s:%d: name missing after \"@ifset\"", fname, lnr);
                  continue;
                }
              for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
                ;
              *pend = 0;  /* Ignore rest of the line.  */
              push_condition (p, 1, fname, lnr);
              continue;
            }
          else if (n == 8 && !memcmp (line, "@ifclear", 8)
                   && (line[8]==' '||line[8]=='\t'))
            {
              for (p=line+9; *p == ' ' || *p == '\t'; p++)
                ;
              if (!*p)
                {
                  err ("%s:%d: name missing after \"@ifsclear\"", fname, lnr);
                  continue;
                }
              for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
                ;
              *pend = 0;  /* Ignore rest of the line.  */
              push_condition (p, 0, fname, lnr);
              continue;
            }
          else if (n == 4 && !memcmp (line, "@end", 4)
                   && (line[4]==' '||line[4]=='\t')
                   && !strncmp (p, "ifset", 5)
                   && (p[5]==' '||p[5]=='\t'||!p[5]))
            {
              pop_condition (1, fname, lnr);
              continue;
            }
          else if (n == 4 && !memcmp (line, "@end", 4)
                   && (line[4]==' '||line[4]=='\t')
                   && !strncmp (p, "ifclear", 7)
                   && (p[7]==' '||p[7]=='\t'||!p[7]))
            {
              pop_condition (0, fname, lnr);
              continue;
            }
        }

      /* Take action on ifset/ifclear.  */
      if (!cond_is_active)
        continue;

      /* Process commands. */
      if (*line == '@')
        {
          if (skip_to_end
              && n == 4 && !memcmp (line, "@end", 4)
              && (line[4]==' '||line[4]=='\t'||!line[4]))
            {
              skip_to_end = 0;
            }
          else if (cond_in_verbatim)
            {
                got_line = 1;
            }
          else if (n == 6 && !memcmp (line, "@macro", 6))
            {
              macroname = xstrdup (p);
              macrovalue = xmalloc ((macrovaluesize = 1024));
              macrovalueused = 0;
            }
          else if (n == 8 && !memcmp (line, "@manpage", 8))
            {
              free (*section_name);
              *section_name = NULL;
              finish_page ();
              start_page (p);
              in_pause = 0;
            }
          else if (n == 8 && !memcmp (line, "@mansect", 8))
            {
              if (!thepage.name)
                err ("%s:%d: section outside of a man page", fname, lnr);
              else
                {
                  free (*section_name);
                  *section_name = ascii_strupr (xstrdup (p));
                  in_pause = 0;
                  skip_sect_line = 1;
                }
            }
          else if (n == 9 && !memcmp (line, "@manpause", 9))
            {
              if (!*section_name)
                err ("%s:%d: pausing outside of a man section", fname, lnr);
              else if (in_pause)
                err ("%s:%d: already pausing", fname, lnr);
              else
                in_pause = 1;
            }
          else if (n == 8 && !memcmp (line, "@mancont", 8))
            {
              if (!*section_name)
                err ("%s:%d: continue outside of a man section", fname, lnr);
              else if (!in_pause)
                err ("%s:%d: continue while not pausing", fname, lnr);
              else
                in_pause = 0;
            }
          else if (n == 5 && !memcmp (line, "@menu", 5)
                   && (line[5]==' '||line[5]=='\t'||!line[5]))
            {
              skip_to_end = 1;
            }
          else if (n == 8 && !memcmp (line, "@include", 8)
                   && (line[8]==' '||line[8]=='\t'||!line[8]))
            {
              char *incname = xstrdup (p);
              FILE *incfp = fopen (incname, "r");

              if (!incfp && opt_include && *opt_include && *p != '/')
                {
                  free (incname);
                  incname = xmalloc (strlen (opt_include) + 1
                                     + strlen (p) + 1);
                  strcpy (incname, opt_include);
                  if ( incname[strlen (incname)-1] != '/' )
                    strcat (incname, "/");
                  strcat (incname, p);
                  incfp = fopen (incname, "r");
                }

              if (!incfp)
                err ("can't open include file '%s':%s",
                     incname, strerror (errno));
              else
                {
                  parse_file (incname, incfp, section_name, in_pause);
                  fclose (incfp);
                }
              free (incname);
            }
          else if (n == 4 && !memcmp (line, "@bye", 4)
                   && (line[4]==' '||line[4]=='\t'||!line[4]))
            {
              break;
            }
          else if (!skip_to_end)
            got_line = 1;
        }
      else if (!skip_to_end)
        got_line = 1;

      if (got_line && cond_in_verbatim)
        add_content (*section_name, line, 1);
      else if (got_line && thepage.name && *section_name && !in_pause)
        add_content (*section_name, line, 0);

    }
  if (ferror (fp))
    err ("%s:%d: read error: %s", fname, lnr, strerror (errno));
  free (macroname);
  free (macrovalue);
  free (line);
}
Exemple #6
0
/* Parse one Texinfo file and create manpages according to the
   embedded instructions.  */
static void
parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
{
  char *line;
  int lnr = 0;
  /* Fixme: The following state variables don't carry over to include
     files. */
  int in_verbatim = 0;
  int skip_to_end = 0;        /* Used to skip over menu entries. */
  int skip_sect_line = 0;     /* Skip after @mansect.  */
  int ifset_nesting = 0;      /* How often a ifset has been seen. */
  int ifclear_nesting = 0;    /* How often a ifclear has been seen. */
  int in_gpgone = 0;          /* Keep track of "@ifset gpgone" parts.  */
  int not_in_gpgone = 0;      /* Keep track of "@ifclear gpgone" parts.  */
  int not_in_man = 0;         /* Keep track of "@ifclear isman" parts.  */

  /* Helper to define a macro. */
  char *macroname = NULL;
  char *macrovalue = NULL;
  size_t macrovaluesize = 0;
  size_t macrovalueused = 0;

  line = xmalloc (LINESIZE);
  while (fgets (line, LINESIZE, fp))
    {
      size_t n = strlen (line);
      int got_line = 0;
      char *p;

      lnr++;
      if (!n || line[n-1] != '\n')
        {
          err ("%s:%d: trailing linefeed missing, line too long or "
               "embedded Nul character", fname, lnr);
          break;
        }
      line[--n] = 0;

      if (*line == '@')
        {
          for (p=line+1, n=1; *p && *p != ' ' && *p != '\t'; p++)
            n++;
          while (*p == ' ' || *p == '\t')
            p++;
        }
      else
        p = line;

      /* Take action on macro.  */
      if (macroname)
        {
          if (n == 4 && !memcmp (line, "@end", 4)
              && (line[4]==' '||line[4]=='\t'||!line[4])
              && !strncmp (p, "macro", 5)
              && (p[5]==' '||p[5]=='\t'||!p[5]))
            {
              macro_t m;

              if (macrovalueused)
                macrovalue[--macrovalueused] = 0; /* Kill the last LF. */
              macrovalue[macrovalueused] = 0;     /* Terminate macro. */
              macrovalue = xrealloc (macrovalue, macrovalueused+1);

              for (m= macrolist; m; m = m->next)
                if (!strcmp (m->name, macroname))
                  break;
              if (m)
                free (m->value);
              else
                {
                  m = xcalloc (1, sizeof *m + strlen (macroname));
                  strcpy (m->name, macroname);
                  m->next = macrolist;
                  macrolist = m;
                }
              m->value = macrovalue;
              macrovalue = NULL;
              free (macroname);
              macroname = NULL;
            }
          else
            {
              if (macrovalueused + strlen (line) + 2 >= macrovaluesize)
                {
                  macrovaluesize += strlen (line) + 256;
                  macrovalue = xrealloc (macrovalue,  macrovaluesize);
                }
              strcpy (macrovalue+macrovalueused, line);
              macrovalueused += strlen (line);
              macrovalue[macrovalueused++] = '\n';
            }
          continue;
        }


      if (n >= 5 && !memcmp (line, "@node", 5)
          && (line[5]==' '||line[5]=='\t'||!line[5]))
        {
          /* Completey ignore @node lines.  */
          continue;
        }


      if (skip_sect_line)
        {
          skip_sect_line = 0;
          if (!strncmp (line, "@section", 8)
              || !strncmp (line, "@subsection", 11)
              || !strncmp (line, "@chapheading", 12))
            continue;
        }

      /* We only parse lines we need and ignore the rest.  There are a
         few macros used to control this as well as one @ifset
         command.  Parts we know about are saved away into containers
         separate for each section. */

      /* First process ifset/ifclear commands. */
      if (*line == '@')
        {
          if (n == 6 && !memcmp (line, "@ifset", 6)
                   && (line[6]==' '||line[6]=='\t'))
            {
              ifset_nesting++;

              if (!strncmp (p, "manverb", 7) && (p[7]==' '||p[7]=='\t'||!p[7]))
                {
                  if (in_verbatim)
                    err ("%s:%d: nested \"@ifset manverb\"", fname, lnr);
                  else
                    in_verbatim = ifset_nesting;
                }
              else if (!strncmp (p, "gpgone", 6)
                       && (p[6]==' '||p[6]=='\t'||!p[6]))
                {
                  if (in_gpgone)
                    err ("%s:%d: nested \"@ifset gpgone\"", fname, lnr);
                  else
                    in_gpgone = ifset_nesting;
                }
              continue;
            }
          else if (n == 4 && !memcmp (line, "@end", 4)
                   && (line[4]==' '||line[4]=='\t')
                   && !strncmp (p, "ifset", 5)
                   && (p[5]==' '||p[5]=='\t'||!p[5]))
            {
              if (in_verbatim && ifset_nesting == in_verbatim)
                in_verbatim = 0;
              if (in_gpgone && ifset_nesting == in_gpgone)
                in_gpgone = 0;

              if (ifset_nesting)
                ifset_nesting--;
              else
                err ("%s:%d: unbalanced \"@end ifset\"", fname, lnr);
              continue;
            }
          else if (n == 8 && !memcmp (line, "@ifclear", 8)
                   && (line[8]==' '||line[8]=='\t'))
            {
              ifclear_nesting++;

              if (!strncmp (p, "gpgone", 6)
                  && (p[6]==' '||p[6]=='\t'||!p[6]))
                {
                  if (not_in_gpgone)
                    err ("%s:%d: nested \"@ifclear gpgone\"", fname, lnr);
                  else
                    not_in_gpgone = ifclear_nesting;
                }

              else if (!strncmp (p, "isman", 5)
                       && (p[5]==' '||p[5]=='\t'||!p[5]))
                {
                  if (not_in_man)
                    err ("%s:%d: nested \"@ifclear isman\"", fname, lnr);
                  else
                    not_in_man = ifclear_nesting;
                }

              continue;
            }
          else if (n == 4 && !memcmp (line, "@end", 4)
                   && (line[4]==' '||line[4]=='\t')
                   && !strncmp (p, "ifclear", 7)
                   && (p[7]==' '||p[7]=='\t'||!p[7]))
            {
              if (not_in_gpgone && ifclear_nesting == not_in_gpgone)
                not_in_gpgone = 0;
              if (not_in_man && ifclear_nesting == not_in_man)
                not_in_man = 0;

              if (ifclear_nesting)
                ifclear_nesting--;
              else
                err ("%s:%d: unbalanced \"@end ifclear\"", fname, lnr);
              continue;
            }
        }

      /* Take action on ifset/ifclear.  */
      if ( (in_gpgone && !gpgone_defined)
           || (not_in_gpgone && gpgone_defined)
           || not_in_man)
        continue;

      /* Process commands. */
      if (*line == '@')
        {
          if (skip_to_end
              && n == 4 && !memcmp (line, "@end", 4)
              && (line[4]==' '||line[4]=='\t'||!line[4]))
            {
              skip_to_end = 0;
            }
          else if (in_verbatim)
            {
                got_line = 1;
            }
          else if (n == 6 && !memcmp (line, "@macro", 6))
            {
              macroname = xstrdup (p);
              macrovalue = xmalloc ((macrovaluesize = 1024));
              macrovalueused = 0;
            }
          else if (n == 8 && !memcmp (line, "@manpage", 8))
            {
              free (*section_name);
              *section_name = NULL;
              finish_page ();
              start_page (p);
              in_pause = 0;
            }
          else if (n == 8 && !memcmp (line, "@mansect", 8))
            {
              if (!thepage.name)
                err ("%s:%d: section outside of a man page", fname, lnr);
              else
                {
                  free (*section_name);
                  *section_name = ascii_strupr (xstrdup (p));
                  in_pause = 0;
                  skip_sect_line = 1;
                }
            }
          else if (n == 9 && !memcmp (line, "@manpause", 9))
            {
              if (!*section_name)
                err ("%s:%d: pausing outside of a man section", fname, lnr);
              else if (in_pause)
                err ("%s:%d: already pausing", fname, lnr);
              else
                in_pause = 1;
            }
          else if (n == 8 && !memcmp (line, "@mancont", 8))
            {
              if (!*section_name)
                err ("%s:%d: continue outside of a man section", fname, lnr);
              else if (!in_pause)
                err ("%s:%d: continue while not pausing", fname, lnr);
              else
                in_pause = 0;
            }
          else if (n == 5 && !memcmp (line, "@menu", 5)
                   && (line[5]==' '||line[5]=='\t'||!line[5]))
            {
              skip_to_end = 1;
            }
          else if (n == 8 && !memcmp (line, "@include", 8)
                   && (line[8]==' '||line[8]=='\t'||!line[8]))
            {
              char *incname = xstrdup (p);
              FILE *incfp = fopen (incname, "r");

              if (!incfp && opt_include && *opt_include && *p != '/')
                {
                  free (incname);
                  incname = xmalloc (strlen (opt_include) + 1
                                     + strlen (p) + 1);
                  strcpy (incname, opt_include);
                  if ( incname[strlen (incname)-1] != '/' )
                    strcat (incname, "/");
                  strcat (incname, p);
                  incfp = fopen (incname, "r");
                }

              if (!incfp)
                err ("can't open include file `%s':%s",
                     incname, strerror (errno));
              else
                {
                  parse_file (incname, incfp, section_name, in_pause);
                  fclose (incfp);
                }
              free (incname);
            }
          else if (n == 4 && !memcmp (line, "@bye", 4)
                   && (line[4]==' '||line[4]=='\t'||!line[4]))
            {
              break;
            }
          else if (!skip_to_end)
            got_line = 1;
        }
      else if (!skip_to_end)
        got_line = 1;

      if (got_line && in_verbatim)
        add_content (*section_name, line, 1);
      else if (got_line && thepage.name && *section_name && !in_pause)
        add_content (*section_name, line, 0);

    }
  if (ferror (fp))
    err ("%s:%d: read error: %s", fname, lnr, strerror (errno));
  free (macroname);
  free (macrovalue);
  free (line);
}