Added the $HOME variable to be used in AFMPATH
[enscript.git] / src / psgen.c
index 8d7a342..3990659 100644 (file)
@@ -6,25 +6,25 @@
  */
 
 /*
- * This file is part of GNU enscript.
+ * This file is part of GNU Enscript.
  *
- * This program is free software; you can redistribute it and/or modify
+ * Enscript is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
+ * Enscript is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * along with Enscript.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <limits.h>
 #include "gsint.h"
+#include <libgen.h>
 
 /*
  * Types and definitions.
@@ -124,7 +124,7 @@ struct gs_token_st
          double xscale;
          double yscale;
          int llx, lly, urx, ury; /* Bounding box. */
-         char filename[512];
+         char filename[PATH_MAX];
          char *skipbuf;
          unsigned int skipbuf_len;
          unsigned int skipbuf_pos;
@@ -135,11 +135,11 @@ struct gs_token_st
       Color bgcolor;
       struct
        {
-         char name[512];
+         char name[PATH_MAX];
          FontPoint size;
          InputEncoding encoding;
        } font;
-      char filename[512];
+      char filename[PATH_MAX];
     } u;
 };
 
@@ -248,7 +248,7 @@ static int do_print = 1;
 static int user_fontp = 0;
 
 /* The user ^@font{}-defined font. */
-static char user_font_name[256];
+static char user_font_name[PATH_MAX];
 static FontPoint user_font_pt;
 static InputEncoding user_font_encoding;
 
@@ -280,12 +280,19 @@ dump_ps_header ()
 {
   char *cp, *cp2;
   int i, j, got;
+  char *ps_version_string;     /* Version string for PS procsets. */
+
 
   /* Dump PS header only once. */
   if (ps_header_dumped)
     return;
   ps_header_dumped = 1;
 
+  /* Create version string. */
+  ps_version_string = xstrdup (VERSION);
+  cp = strrchr (ps_version_string, '.');
+  *cp = ' ';
+
   /*
    * Header.
    */
@@ -295,7 +302,7 @@ dump_ps_header ()
           media->urx, media->ury));
   OUTPUT ((cofp, "%%%%Title: %s\n", title));
   OUTPUT ((cofp, "%%%%For: %s\n", passwd->pw_gecos));
-  OUTPUT ((cofp, "%%%%Creator: %s\n", version_string));
+  OUTPUT ((cofp, "%%%%Creator: %s\n", PACKAGE_STRING));
   OUTPUT ((cofp, "%%%%CreationDate: %s\n", date_string));
   OUTPUT ((cofp, "%%%%Orientation: %s\n",
           ((nup > 1) && nup_landscape)
@@ -578,8 +585,8 @@ process_file (char *fname_arg, InputStream *is, int is_toc)
    * Count possible line number spaces.  This should be enought for 99999
    * lines
    */
-  linenumber_space = CHAR_WIDTH ('0') * 5 + 1.0;
-  linenumber_margin = CHAR_WIDTH (':') + CHAR_WIDTH ('m');
+  linenumber_space = FNT_CHAR_WIDTH ('0') * 5 + 1.0;
+  linenumber_margin = FNT_CHAR_WIDTH (':') + FNT_CHAR_WIDTH ('m');
 
   /* We got a new input file. */
   input_filenum++;
@@ -978,7 +985,8 @@ large for page\n"),
                        FATAL ((stderr,
                                _("user font encoding can be only the system's default or `ps'")));
 
-                     strcpy (user_font_name, token.u.font.name);
+                     memset  (user_font_name, 0, sizeof(user_font_name));
+                     strncpy (user_font_name, token.u.font.name, sizeof(user_font_name) - 1);
                      user_font_pt.w = token.u.font.size.w;
                      user_font_pt.h = token.u.font.size.h;
                      user_font_encoding = token.u.font.encoding;
@@ -1129,7 +1137,7 @@ large for page\n"),
 /* Help macros. */
 
 /* Check if character <ch> fits to current line. */
-#define FITS_ON_LINE(ch) ((linepos + CHAR_WIDTH (ch) < linew) || col == 0)
+#define FITS_ON_LINE(ch) ((linepos + FNT_CHAR_WIDTH (ch) < linew) || col == 0)
 
 /* Is line buffer empty? */
 #define BUFFER_EMPTY() (bufpos == 0)
@@ -1152,13 +1160,13 @@ large for page\n"),
 #define EMIT(ch)               \
   do {                         \
     APPEND_CHAR (ch);          \
-    linepos += CHAR_WIDTH (ch);        \
+    linepos += FNT_CHAR_WIDTH (ch);    \
     col++;                     \
   } while (0)
 
 #define UNEMIT(ch)             \
   do {                         \
-    linepos -= CHAR_WIDTH (ch); \
+    linepos -= FNT_CHAR_WIDTH (ch); \
     col--;                     \
   } while (0)
 
@@ -1444,7 +1452,7 @@ read_special_escape (InputStream *is, Token *token)
          buf[i] = ch;
          if (i + 1 >= sizeof (buf))
            FATAL ((stderr, _("too long argument for %s escape:\n%.*s"),
-                   escapes[i].name, i, buf));
+                   escapes[e].name, i, buf));
        }
       buf[i] = '\0';
 
@@ -1452,7 +1460,8 @@ read_special_escape (InputStream *is, Token *token)
       switch (escapes[e].escape)
        {
        case ESC_FONT:
-         strcpy (token->u.font.name, buf);
+         memset  (token->u.font.name, 0, sizeof(token->u.font.name));
+         strncpy (token->u.font.name, buf, sizeof(token->u.font.name) - 1);
 
          /* Check for the default font. */
          if (strcmp (token->u.font.name, "default") == 0)
@@ -1465,7 +1474,8 @@ read_special_escape (InputStream *is, Token *token)
                FATAL ((stderr, _("malformed font spec for ^@font escape: %s"),
                        token->u.font.name));
 
-             strcpy (token->u.font.name, cp);
+             memset  (token->u.font.name, 0, sizeof(token->u.font.name));
+             strncpy (token->u.font.name, cp, sizeof(token->u.font.name) - 1);
              xfree (cp);
            }
          token->type = tFONT;
@@ -1544,7 +1554,8 @@ read_special_escape (InputStream *is, Token *token)
          break;
 
        case ESC_SETFILENAME:
-         strcpy (token->u.filename, buf);
+         memset  (token->u.filename, 0, sizeof(token->u.filename));
+         strncpy (token->u.filename, buf, sizeof(token->u.filename) - 1);
          token->type = tSETFILENAME;
          break;
 
@@ -1679,7 +1690,7 @@ get_next_token (InputStream *is, double linestart, double linepos,
            {
              /* Proportional font. */
 
-             double grid = tabsize * CHAR_WIDTH (' ');
+             double grid = tabsize * FNT_CHAR_WIDTH (' ');
              col++;
 
              /* Move linepos to the next multiple of <grid>. */
@@ -1737,9 +1748,9 @@ get_next_token (InputStream *is, double linestart, double linepos,
          if (ch == bs)
            {
              if (BUFFER_EMPTY () || !EXISTS (buffer[bufpos - 1]))
-               linepos -= CHAR_WIDTH ('m');
+               linepos -= FNT_CHAR_WIDTH ('m');
              else
-               linepos -= CHAR_WIDTH (buffer[bufpos - 1]);
+               linepos -= FNT_CHAR_WIDTH (buffer[bufpos - 1]);
 
              done = DONE_DONE;
              break;
@@ -1764,7 +1775,7 @@ get_next_token (InputStream *is, double linestart, double linepos,
                        APPEND_CHAR (buf[i]);
 
                      /* Update current point counters manually. */
-                     linepos += CHAR_WIDTH (ch);
+                     linepos += FNT_CHAR_WIDTH (ch);
                      col++;
                    }
                  else if (ch == '(' || ch == ')' || ch == '\\')
@@ -1837,7 +1848,7 @@ get_next_token (InputStream *is, double linestart, double linepos,
 
              /* Count length. */
              for (i = 0; buf[i]; i++)
-               len += CHAR_WIDTH (buf[i]);
+               len += FNT_CHAR_WIDTH (buf[i]);
 
              if (linepos + len < linew || col == 0)
                {
@@ -2008,8 +2019,7 @@ get_next_token (InputStream *is, double linestart, double linepos,
 static void
 dump_ps_page_header (char *fname, int empty)
 {
-  char buf[512];
-  char *ftail;
+  char *dirc, *basec, *fdir, *ftail;
   int got, i;
   char *cp, *cp2;
   char *cstr = "%%";
@@ -2018,25 +2028,11 @@ dump_ps_page_header (char *fname, int empty)
   /* The N-up printing sub-page. */
   nup_subpage = (total_pages - 1) % nup;
 
-  /* Create fdir and ftail. */
-  ftail = strrchr (fname, '/');
-
-#if defined(WIN32)
-  if (ftail == NULL)
-    ftail = strrchr (fname, '\\');
-#endif /* WIN32 */
-
-  if (ftail == NULL)
-    {
-      buf[0] = '\0';
-      ftail = fname;
-    }
-  else
-    {
-      ftail++;
-      strncpy (buf, fname, ftail - fname);
-      buf[ftail - fname] = '\0';
-    }
+  /* Split fname into fdir and ftail. */
+  dirc = strdup(fname);
+  basec = strdup(fname);
+  fdir = dirname(dirc);
+  ftail = basename(basec);
 
   if (nup > 1)
     {
@@ -2182,13 +2178,15 @@ dump_ps_page_header (char *fname, int empty)
   OUTPUT ((cofp, "/fname (%s) def\n", cp));
   xfree (cp);
 
-  cp = escape_string (buf);
+  cp = escape_string (fdir);
   OUTPUT ((cofp, "/fdir (%s) def\n", cp));
   xfree (cp);
+  xfree (dirc);
 
   cp = escape_string (ftail);
   OUTPUT ((cofp, "/ftail (%s) def\n", cp));
   xfree (cp);
+  xfree (basec);
 
   /* Do we have a pending ^@font{} font? */
   if (user_fontp)
@@ -2378,6 +2376,7 @@ recognize_eps_file (Token *token)
 {
   int i;
   char buf[4096];
+  char *filename;
   int line;
   int valid_epsf;
   float llx, lly, urx, ury;
@@ -2385,52 +2384,34 @@ recognize_eps_file (Token *token)
   MESSAGE (2, (stderr, "^@epsf=\"%s\"\n", token->u.epsf.filename));
 
   i = strlen (token->u.epsf.filename);
-  if (i > 0 && token->u.epsf.filename[i - 1] == '|')
-    {
-      /* Read EPS data from pipe. */
-      token->u.epsf.pipe = 1;
-      token->u.epsf.filename[i - 1] = '\0';
-      token->u.epsf.fp = popen (token->u.epsf.filename, "r");
-      if (token->u.epsf.fp == NULL)
-       {
-         MESSAGE (0, (stderr,
-                      _("epsf: couldn't open pipe to command \"%s\": %s\n"),
-                      token->u.epsf.filename, strerror (errno)));
-         return 0;
-       }
-    }
-  else
-    {
-      char *filename;
 
-      /* Read EPS data from file. */
-      filename = tilde_subst (token->u.epsf.filename);
+  /* Read EPS data from file. */
+  filename = tilde_subst (token->u.epsf.filename);
 
-      token->u.epsf.fp = fopen (filename, "rb");
-      xfree (filename);
+  token->u.epsf.fp = fopen (filename, "rb");
+  xfree (filename);
 
-      if (token->u.epsf.fp == NULL)
+  if (token->u.epsf.fp == NULL)
+    {
+      if (token->u.epsf.filename[0] != '/')
        {
-         if (token->u.epsf.filename[0] != '/')
-           {
-             /* Name is not absolute, let's lookup path. */
-             FileLookupCtx ctx;
+         /* Name is not absolute, let's lookup path. */
+         FileLookupCtx ctx;
 
-             ctx.name = token->u.epsf.filename;
-             ctx.suffix = "";
-             ctx.fullname = buffer_alloc ();
+         ctx.name = token->u.epsf.filename;
+         ctx.suffix = "";
+         ctx.fullname = buffer_alloc ();
 
-             if (pathwalk (libpath, file_lookup, &ctx))
-               token->u.epsf.fp = fopen (buffer_ptr (ctx.fullname), "rb");
+         if (pathwalk (libpath, file_lookup, &ctx))
+           token->u.epsf.fp = fopen (buffer_ptr (ctx.fullname), "rb");
 
-             buffer_free (ctx.fullname);
-           }
-         if (token->u.epsf.fp == NULL)
-           {
-             MESSAGE (0, (stderr, _("couldn't open EPS file \"%s\": %s\n"),
-                          token->u.epsf.filename, strerror (errno)));
-             return 0;
-           }
+         buffer_free (ctx.fullname);
+       }
+      if (token->u.epsf.fp == NULL)
+       {
+         MESSAGE (0, (stderr, _("couldn't open EPS file \"%s\": %s\n"),
+                      token->u.epsf.filename, strerror (errno)));
+         return 0;
        }
     }
 
@@ -2491,7 +2472,7 @@ recognize_eps_file (Token *token)
                  /* No, this BoundingBox comment is corrupted. */
                  MESSAGE (0, (stderr, _("EPS file \"%s\" contains malformed \
 %%%%BoundingBox row:\n\"%.*s\"\n"),
-                              token->u.epsf.filename, strlen (buf) - 1, buf));
+                              token->u.epsf.filename, (int)(strlen (buf) - 1), buf));
                  break;
                }
            }
@@ -2618,7 +2599,7 @@ read_float (InputStream *is, int units, int horizontal)
 
        case 'l':               /* lines or characters */
          if (horizontal)
-           val *= CHAR_WIDTH ('m');
+           val *= FNT_CHAR_WIDTH ('m');
          else
            val *= LINESKIP;
          break;
@@ -2747,7 +2728,7 @@ print_line_number (double x, double y, double space, double margin,
   int i;
   char *saved_Fname = "";
   FontPoint saved_Fpt;
-  InputEncoding saved_Fencoding;
+  InputEncoding saved_Fencoding = 0;
 
   saved_Fpt.w = 0.0;
   saved_Fpt.h = 0.0;
@@ -2777,7 +2758,7 @@ print_line_number (double x, double y, double space, double margin,
   /* Count linenumber string length. */
   sprintf (buf, "%d", linenum);
   for (i = 0; buf[i]; i++)
-    len += CHAR_WIDTH (buf[i]);
+    len += FNT_CHAR_WIDTH (buf[i]);
 
   /* Print line numbers. */
   OUTPUT ((cofp, "%g %g M (%s:) s\n", x + space - len, y, buf));
@@ -2800,8 +2781,6 @@ print_line_number (double x, double y, double space, double margin,
  * The name of the divert file, shared between divert() and undivert()
  * functions.
  */
-static char divertfname[512];
-
 static void
 divert ()
 {