]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - progs/infocmp.c
ncurses 6.5 - patch 20240922
[ncurses.git] / progs / infocmp.c
index ec5e07650dd43e1bf766e3e164e8d0a0ba77b1ed..af2ad7790fb2e66e86948057fb39b7b40249f5af 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright 2020-2022,2023 Thomas E. Dickey                                *
+ * Copyright 2020-2023,2024 Thomas E. Dickey                                *
  * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
 
 #include <dump_entry.h>
 
 
 #include <dump_entry.h>
 
-MODULE_ID("$Id: infocmp.c,v 1.157 2023/05/27 20:13:10 tom Exp $")
+MODULE_ID("$Id: infocmp.c,v 1.164 2024/08/24 22:57:24 tom Exp $")
+
+#ifndef ACTUAL_TIC
+#define ACTUAL_TIC "tic"
+#endif
 
 #define MAX_STRING     1024    /* maximum formatted string */
 
 
 #define MAX_STRING     1024    /* maximum formatted string */
 
@@ -61,6 +65,9 @@ typedef char path[PATH_MAX];
 static ENTRY *entries;         /* terminfo entries */
 static int termcount;          /* count of terminal entries */
 
 static ENTRY *entries;         /* terminfo entries */
 static int termcount;          /* count of terminal entries */
 
+static const char usage_string[] = \
+"Usage: %s [options] [-A directory] [-B directory] [termname...]";
+
 static bool limited = TRUE;    /* "-r" option is not set */
 static bool quiet = FALSE;
 static bool literal = FALSE;
 static bool limited = TRUE;    /* "-r" option is not set */
 static bool quiet = FALSE;
 static bool literal = FALSE;
@@ -187,10 +194,21 @@ capcmp(PredIdx idx, const char *s, const char *t)
        return (_nc_capcmp(s, t));
 }
 
        return (_nc_capcmp(s, t));
 }
 
+/*
+ * Predicate function to use for "use=" decompilation.
+ *
+ * Return value is used in fmt_entry:
+ *   FAIL  show nothing for this capability.
+ *   FALSE show cancel for booleans (a compromise)
+ *   TRUE  show capability
+ *
+ * The only difference between FALSE/TRUE returns is in the treatment of
+ * booleans.
+ */
 static int
 use_predicate(unsigned type, PredIdx idx)
 static int
 use_predicate(unsigned type, PredIdx idx)
-/* predicate function to use for use decompilation */
 {
 {
+    int result = FAIL;
     ENTRY *ep;
 
     switch (type) {
     ENTRY *ep;
 
     switch (type) {
@@ -209,16 +227,18 @@ use_predicate(unsigned type, PredIdx idx)
             * unlike numbers and strings, whose cancelled/absent state is
             * recorded in the terminfo database.
             */
             * unlike numbers and strings, whose cancelled/absent state is
             * recorded in the terminfo database.
             */
-           for (ep = &entries[1]; ep < entries + termcount; ep++)
-               if (ep->tterm.Booleans[idx] == TRUE) {
-                   is_set = entries[0].tterm.Booleans[idx];
-                   break;
+           if (idx < NUM_BOOLEANS(&(entries[0].tterm))) {
+               for (ep = &entries[1]; ep < entries + termcount; ep++) {
+                   if (idx < NUM_BOOLEANS(&(ep->tterm))
+                       && (is_set = ep->tterm.Booleans[idx])) {
+                       break;
+                   }
                }
                }
-           if (is_set != entries[0].tterm.Booleans[idx])
-               return (!is_set);
-           else
-               return (FAIL);
+               if (is_set != entries[0].tterm.Booleans[idx])
+                   result = (!is_set);
+           }
        }
        }
+       break;
 
     case NUMBER:
        {
 
     case NUMBER:
        {
@@ -229,45 +249,56 @@ use_predicate(unsigned type, PredIdx idx)
             * capability gets the first non-default value found
             * in the sequence of use entries'.
             */
             * capability gets the first non-default value found
             * in the sequence of use entries'.
             */
-           for (ep = &entries[1]; ep < entries + termcount; ep++)
-               if (VALID_NUMERIC(ep->tterm.Numbers[idx])) {
-                   value = ep->tterm.Numbers[idx];
-                   break;
-               }
+           if (idx < NUM_NUMBERS(&(entries[0].tterm))) {
+               for (ep = &entries[1]; ep < entries + termcount; ep++)
+                   if (idx < NUM_NUMBERS(&(ep->tterm))
+                       && VALID_NUMERIC(ep->tterm.Numbers[idx])) {
+                       value = ep->tterm.Numbers[idx];
+                       break;
+                   }
 
 
-           if (value != entries[0].tterm.Numbers[idx])
-               return (value != ABSENT_NUMERIC);
-           else
-               return (FAIL);
+               if (value != entries[0].tterm.Numbers[idx])
+                   result = (value != ABSENT_NUMERIC);
+           }
        }
        }
+       break;
 
     case STRING:
        {
 
     case STRING:
        {
-           char *termstr, *usestr = ABSENT_STRING;
-
-           termstr = entries[0].tterm.Strings[idx];
+           char *termstr = entries[0].tterm.Strings[idx];
+           char *usestr = ABSENT_STRING;
 
            /*
             * We take the semantics of multiple uses to be 'each
             * capability gets the first non-default value found
             * in the sequence of use entries'.
             */
 
            /*
             * We take the semantics of multiple uses to be 'each
             * capability gets the first non-default value found
             * in the sequence of use entries'.
             */
-           for (ep = &entries[1]; ep < entries + termcount; ep++)
-               if (ep->tterm.Strings[idx]) {
-                   usestr = ep->tterm.Strings[idx];
-                   break;
-               }
+           if (idx < NUM_STRINGS(&(entries[0].tterm))) {
+               for (ep = &entries[1]; ep < entries + termcount; ep++)
+                   if (idx < NUM_STRINGS(&(ep->tterm))
+                       && ep->tterm.Strings[idx]) {
+                       usestr = ep->tterm.Strings[idx];
+                       break;
+                   }
 
 
-           if (usestr == ABSENT_STRING && termstr == ABSENT_STRING)
-               return (FAIL);
-           else if (!usestr || !termstr || capcmp(idx, usestr, termstr))
-               return (TRUE);
-           else
-               return (FAIL);
+               if (usestr == CANCELLED_STRING && termstr == ABSENT_STRING)
+                   result = (FAIL);
+               else if (usestr == CANCELLED_STRING && termstr == CANCELLED_STRING)
+                   result = (TRUE);
+               else if (usestr == ABSENT_STRING && termstr == ABSENT_STRING)
+                   result = (FAIL);
+               else if (!usestr || !termstr || capcmp(idx, usestr, termstr))
+                   result = (TRUE);
+           }
        }
        }
+       break;
+
+    default:
+       result = FALSE;
+       break;
     }
 
     }
 
-    return (FALSE);            /* pacify compiler */
+    return (result);
 }
 
 static bool
 }
 
 static bool
@@ -1192,7 +1223,6 @@ usage(void)
 #define DATA(s) s "\n"
     static const char head[] =
     {
 #define DATA(s) s "\n"
     static const char head[] =
     {
-       DATA("Usage: infocmp [options] [-A directory] [-B directory] [termname...]")
        DATA("")
        DATA("Options:")
     };
        DATA("")
        DATA("Options:")
     };
@@ -1247,14 +1277,16 @@ usage(void)
     const size_t last = SIZEOF(options);
     const size_t left = (last + 1) / 2;
     size_t n;
     const size_t last = SIZEOF(options);
     const size_t left = (last + 1) / 2;
     size_t n;
+    FILE *fp = stderr;
 
 
-    fputs(head, stderr);
+    fprintf(fp, usage_string, _nc_progname);
+    fputs(head, fp);
     for (n = 0; n < left; n++) {
        size_t m = n + left;
        if (m < last)
     for (n = 0; n < left; n++) {
        size_t m = n + left;
        if (m < last)
-           fprintf(stderr, "%-40.40s%s\n", options[n], options[m]);
+           fprintf(fp, "%-40.40s%s\n", options[n], options[m]);
        else
        else
-           fprintf(stderr, "%s\n", options[n]);
+           fprintf(fp, "%s\n", options[n]);
     }
     ExitProgram(EXIT_FAILURE);
 }
     }
     ExitProgram(EXIT_FAILURE);
 }
@@ -1858,8 +1890,16 @@ main(int argc, char *argv[])
        }
 
 #if NCURSES_XNAMES
        }
 
 #if NCURSES_XNAMES
-       if (termcount > 1)
-           _nc_align_termtype(&entries[0].tterm, &entries[1].tterm);
+       if (termcount > 1) {
+           /*
+            * User-defined capabilities in different terminal descriptions
+            * may have the same name/type but different indices.  Line up
+            * the names to use comparable indices.  We may have more than two
+            * entries to compare when processing the "-u" option.
+            */
+           for (c = 1; c < termcount; ++c)
+               _nc_align_termtype(&entries[c].tterm, &entries[0].tterm);
+       }
 #endif
 
        /* dump as C initializer for the terminal type */
 #endif
 
        /* dump as C initializer for the terminal type */
@@ -1901,8 +1941,8 @@ main(int argc, char *argv[])
                                   tname[0]);
                if (!quiet)
                    (void)
                                   tname[0]);
                if (!quiet)
                    (void)
-                       printf("#\tReconstructed via infocmp from file: %s\n",
-                              tfile[0]);
+                       printf("#\tReconstructed via %s from file: %s\n",
+                              _nc_progname, tfile[0]);
                dump_entry(&entries[0].tterm,
                           suppress_untranslatable,
                           limited,
                dump_entry(&entries[0].tterm,
                           suppress_untranslatable,
                           limited,
@@ -1948,7 +1988,8 @@ main(int argc, char *argv[])
     } else if (compare == C_USEALL) {
        (void) fprintf(stderr, "Sorry, -u doesn't work with -F\n");
     } else if (compare == C_DEFAULT) {
     } else if (compare == C_USEALL) {
        (void) fprintf(stderr, "Sorry, -u doesn't work with -F\n");
     } else if (compare == C_DEFAULT) {
-       (void) fprintf(stderr, "Use `tic -[CI] <file>' for this.\n");
+       (void) fprintf(stderr,
+                      "Use `" ACTUAL_TIC " -[CI] <file>' for this.\n");
     } else if (argc - optind != 2) {
        (void) fprintf(stderr,
                       "File comparison needs exactly two file arguments.\n");
     } else if (argc - optind != 2) {
        (void) fprintf(stderr,
                       "File comparison needs exactly two file arguments.\n");