groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 14/25: [xtotroff]: Add `-d` option.


From: G. Branden Robinson
Subject: [groff] 14/25: [xtotroff]: Add `-d` option.
Date: Wed, 2 Mar 2022 05:12:06 -0500 (EST)

gbranden pushed a commit to branch master
in repository groff.

commit f2f12a4beb88b8b19c03e04ffb6e1116c4929207
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Sun Feb 27 01:31:07 2022 +1100

    [xtotroff]: Add `-d` option.
    
    ...to produce font description files in specified directory.
    
    * src/utils/xtotroff/xtotroff.c: Do it.  Add global `destdir` pointer.
    
      (xtotroff_exit): Add new function to clean up storage allocated by
      `strdup()` (below) for destination directory.
    
      (MapFont): Introduce new variable `file_name`, into which we assemble
      a destination file name from `destdir` (if not null) and the troff
      font name.  Handle memory allocation failure (by carefully dying).
      Free allocated storage on success and failure paths out of the
      function.
    
      (usage): Document new `-d` option.
    
      (main): Instruct `getopt_long` to expect a `-d` flag with an argument.
      Use `strdup()` to make a copy of any such option argument.  Call
      `xtotroff_exit()` instead of `exit()`.
    
    * src/utils/xtotroff/xtotroff.1.man: Document new `-d` option.
---
 ChangeLog                         | 21 +++++++++++++++
 NEWS                              |  3 +++
 src/utils/xtotroff/xtotroff.1.man | 10 +++++--
 src/utils/xtotroff/xtotroff.c     | 56 +++++++++++++++++++++++++++++----------
 4 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7e1af4ba..717b7261 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2022-02-26  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       [xtotroff]: Add `-d` option to produce font description files in
+       specified directory.
+
+       * src/utils/xtotroff/xtotroff.c: Do it.  Add global `destdir`
+       pointer.
+       (xtotroff_exit): Add new function to clean up storage allocated
+       by `strdup()` (below) for destination directory.
+       (MapFont): Introduce new variable `file_name`, into which we
+       assemble a destination file name from `destdir` (if not null)
+       and the troff font name.  Handle memory allocation failure (by
+       carefully dying).  Free allocated storage on success and failure
+       paths out of the function.
+       (usage): Document new `-d` option.
+       (main): Instruct `getopt_long` to expect a `-d` flag with an
+       argument.  Use `strdup()` to make a copy of any such option
+       argument.  Call `xtotroff_exit()` instead of `exit()`.
+
+       * src/utils/xtotroff/xtotroff.1.man: Document new `-d` option.
+
 2022-02-26  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        [xtotroff]: Trivially refactor.
diff --git a/NEWS b/NEWS
index 6ae1ed1b..1c65f0f1 100644
--- a/NEWS
+++ b/NEWS
@@ -406,6 +406,9 @@ o The semantics of the environment variable 
SOURCE_DATE_EPOCH (support
   the local time zone.  Users of SOURCE_DATE_EPOCH may wish to also set
   the TZ environment variable.
 
+o xtotroff now supports a "-d" option to specify the directory in which
+  to generate font description files.
+
 o groffer has been deleted from the distribution.
 
 o grog no longer supports the "--warnings" option; the one diagnostic
diff --git a/src/utils/xtotroff/xtotroff.1.man 
b/src/utils/xtotroff/xtotroff.1.man
index e6499e88..317e8f79 100644
--- a/src/utils/xtotroff/xtotroff.1.man
+++ b/src/utils/xtotroff/xtotroff.1.man
@@ -7,7 +7,7 @@ xtotroff \- convert X font metrics into groff font metrics
 .\" Legal Terms
 .\" ====================================================================
 .\"
-.\" Copyright (C) 2004-2020 Free Software Foundation, Inc.
+.\" Copyright (C) 2004-2022 Free Software Foundation, Inc.
 .\"
 .\" Permission is granted to make and distribute verbatim copies of this
 .\" manual provided the copyright notice and this permission notice are
@@ -35,6 +35,8 @@ xtotroff \- convert X font metrics into groff font metrics
 .\" ====================================================================
 .
 .SY xtotroff
+.RB [ \-d\~\c
+.IR destination-directory ]
 .RB [ \-r\~\c
 .IR resolution ]
 .RB [ \-s\~\c
@@ -114,7 +116,11 @@ For each successful mapping,
 .I xtotroff
 creates a
 .I groff
-font description file in the current working directory named for each
+font description file in the the current working directory
+(or that specified by the
+.B -d
+option)
+named for each
 .I groff
 font,
 and reports the mapping to the standard output stream.
diff --git a/src/utils/xtotroff/xtotroff.c b/src/utils/xtotroff/xtotroff.c
index e9cfae27..eee39eae 100644
--- a/src/utils/xtotroff/xtotroff.c
+++ b/src/utils/xtotroff/xtotroff.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2022 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -61,6 +61,7 @@ static char *program_name;
 Display *dpy;
 unsigned resolution = 75;
 unsigned point_size = 10;
+char *destdir = NULL;
 
 static bool charExists(XFontStruct * fi, int c)
 {
@@ -121,6 +122,12 @@ FontNamesAmbiguous(const char *font_name, char **names, 
int count)
   return false;
 }
 
+static void xtotroff_exit(int status)
+{
+  free(destdir);
+  exit(status);
+}
+
 static bool MapFont(char *font_name, const char *troff_name)
 {
   XFontStruct *fi;
@@ -186,17 +193,33 @@ static bool MapFont(char *font_name, const char 
*troff_name)
   }
 
   printf("%s -> %s\n", names[0], troff_name);
+  char *file_name = (char *)troff_name;
+  size_t dirlen = strlen(destdir);
+
+  if (dirlen > 0) {
+    size_t baselen = strlen(troff_name);
+    file_name = malloc(dirlen + baselen + 2 /* '/' and '\0' */);
+    if (NULL == file_name) {
+      fprintf(stderr, "%s: fatal error: unable to allocate memory\n",
+             program_name);
+      xtotroff_exit(EXIT_FAILURE);
+    }
+    (void) strcpy(file_name, destdir);
+    file_name[dirlen] = '/';
+    (void) strcpy((file_name + dirlen + 1), troff_name);
+  }
 
   {                            /* Avoid race while opening file */
     int fd;
-    (void) unlink(troff_name);
-    fd = open(troff_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    (void) unlink(file_name);
+    fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
     out = fdopen(fd, "w");
   }
 
   if (NULL == out) {
     fprintf(stderr, "%s: unable to create '%s': %s\n", program_name,
-           troff_name, strerror(errno));
+           file_name, strerror(errno));
+    free(file_name);
     return false;
   }
   fprintf(out, "name %s\n", troff_name);
@@ -240,13 +263,15 @@ static bool MapFont(char *font_name, const char 
*troff_name)
   }
   XUnloadFont(dpy, fi->fid);
   fclose(out);
+  free(file_name);
   return true;
 }
 
 static void usage(FILE *stream)
 {
   fprintf(stream,
-         "usage: %s [-r resolution] [-s type-size] font-map\n"
+         "usage: %s [-d directory] [-r resolution] [-s type-size]"
+         " font-map\n"
          "       %s -v\n",
          program_name, program_name);
 }
@@ -267,9 +292,12 @@ int main(int argc, char **argv)
 
   program_name = argv[0];
 
-  while ((opt = getopt_long(argc, argv, "gr:s:v", long_options,
+  while ((opt = getopt_long(argc, argv, "d:gr:s:v", long_options,
                            NULL)) != EOF) {
     switch (opt) {
+    case 'd':
+      destdir = strdup(optarg);
+      break;
     case 'g':
       /* unused; just for compatibility */
       break;
@@ -281,21 +309,21 @@ int main(int argc, char **argv)
       break;
     case 'v':
       printf("xtotroff (groff) version %s\n", Version_string);
-      exit(EXIT_SUCCESS);
+      xtotroff_exit(EXIT_SUCCESS);
       break;
     case CHAR_MAX + 1: /* --help */
       usage(stdout);
-      exit(EXIT_SUCCESS);
+      xtotroff_exit(EXIT_SUCCESS);
       break;
     case '?':
       usage(stderr);
-      exit(EXIT_FAILURE);
+      xtotroff_exit(EXIT_FAILURE);
       break;
     }
   }
   if (argc - optind != 1) {
     usage(stderr);
-    exit(EXIT_FAILURE);
+    xtotroff_exit(EXIT_FAILURE);
   }
 
   dpy = XOpenDisplay(0);
@@ -303,14 +331,14 @@ int main(int argc, char **argv)
     fprintf(stderr, "%s: fatal error: can't connect to the X server;"
            " make sure the DISPLAY environment variable is set"
            " correctly\n", program_name);
-    exit(EXIT_FAILURE);
+    xtotroff_exit(EXIT_FAILURE);
   }
 
   map = fopen(argv[optind], "r");
   if (NULL == map) {
     fprintf(stderr, "%s: fatal error: unable to open map file '%s':"
            " %s\n", program_name, argv[optind], strerror(errno));
-    exit(EXIT_FAILURE);
+    xtotroff_exit(EXIT_FAILURE);
   }
 
   while (fgets(line, sizeof(line), map)) {
@@ -327,9 +355,9 @@ int main(int argc, char **argv)
        break;
     *b = '\0';
     if (!MapFont(font_name, troff_name))
-      exit(EXIT_FAILURE);
+      xtotroff_exit(EXIT_FAILURE);
   }
-  exit(EXIT_SUCCESS);
+  xtotroff_exit(EXIT_SUCCESS);
 }
 
 // Local Variables:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]