[BACK]Return to dump_entry.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tic

Diff for /src/usr.bin/tic/dump_entry.c between version 1.20 and 1.21

version 1.20, 2017/05/11 19:13:17 version 1.21, 2023/10/17 09:52:10
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 /****************************************************************************  /****************************************************************************
  * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *   * Copyright 2018-2022,2023 Thomas E. Dickey                                *
    * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
  *                                                                          *   *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *   * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *   * copy of this software and associated documentation files (the            *
Line 37 
Line 38 
 #define __INTERNAL_CAPS_VISIBLE  #define __INTERNAL_CAPS_VISIBLE
 #include <progs.priv.h>  #include <progs.priv.h>
   
 #include "dump_entry.h"  #include <dump_entry.h>
 #include "termsort.c"           /* this C file is generated */  #include <termsort.h>           /* this C file is generated */
 #include <parametrized.h>       /* so is this */  #include <parametrized.h>       /* so is this */
   
 MODULE_ID("$Id$")  MODULE_ID("$Id$")
   
 #define INDENT                  8  
 #define DISCARD(string) string = ABSENT_STRING  #define DISCARD(string) string = ABSENT_STRING
 #define PRINTF (void) printf  #define PRINTF (void) printf
   #define WRAPPED 32
   
 #define OkIndex(index,array) ((int)(index) >= 0 && (int)(index) < (int) SIZEOF(array))  #define OkIndex(index,array) ((int)(index) >= 0 && (int)(index) < (int) SIZEOF(array))
   #define TcOutput() (outform == F_TERMCAP || outform == F_TCONVERR)
   
 typedef struct {  typedef struct {
     char *text;      char *text;
Line 59 
Line 61 
 static int outform;             /* output format to use */  static int outform;             /* output format to use */
 static int sortmode;            /* sort mode to use */  static int sortmode;            /* sort mode to use */
 static int width = 60;          /* max line width for listings */  static int width = 60;          /* max line width for listings */
   static int height = 65535;      /* max number of lines for listings */
 static int column;              /* current column, limited by 'width' */  static int column;              /* current column, limited by 'width' */
 static int oldcol;              /* last value of column before wrap */  static int oldcol;              /* last value of column before wrap */
 static bool pretty;             /* true if we format if-then-else strings */  static bool pretty;             /* true if we format if-then-else strings */
   static bool wrapped;            /* true if we wrap too-long strings */
   static bool did_wrap;           /* true if last wrap_concat did wrapping */
   static bool checking;           /* true if we are checking for tic */
   static int quickdump;           /* true if we are dumping compiled data */
   
 static char *save_sgr;  static char *save_sgr;
   
Line 74 
Line 81 
 static NCURSES_CONST char *const *num_names;  static NCURSES_CONST char *const *num_names;
 static NCURSES_CONST char *const *str_names;  static NCURSES_CONST char *const *str_names;
   
 static const char *separator, *trailer;  static const char *separator = "", *trailer = "";
   static int indent = 8;
   
 /* cover various ports and variants of terminfo */  /* cover various ports and variants of terminfo */
 #define V_ALLCAPS       0       /* all capabilities (SVr4, XSI, ncurses) */  #define V_ALLCAPS       0       /* all capabilities (SVr4, XSI, ncurses) */
 #define V_SVR1          1       /* SVR1, Ultrix */  #define V_SVR1          1       /* SVR1, Ultrix */
 #define V_HPUX          2       /* HP/UX */  #define V_HPUX          2       /* HP-UX */
 #define V_AIX           3       /* AIX */  #define V_AIX           3       /* AIX */
 #define V_BSD           4       /* BSD */  #define V_BSD           4       /* BSD */
   
Line 89 
Line 97 
 #define OBSOLETE(n) (n[0] == 'O' && n[1] == 'T')  #define OBSOLETE(n) (n[0] == 'O' && n[1] == 'T')
 #endif  #endif
   
 #define isObsolete(f,n) ((f == F_TERMINFO || f == F_VARIABLE) && OBSOLETE(n))  #define isObsolete(f,n) ((f == F_TERMINFO || f == F_VARIABLE) && (sortmode != S_VARIABLE) && OBSOLETE(n))
   
 #if NCURSES_XNAMES  #if NCURSES_XNAMES
 #define BoolIndirect(j) ((j >= BOOLCOUNT) ? (j) : ((sortmode == S_NOSORT) ? j : bool_indirect[j]))  #define BoolIndirect(j) ((j >= BOOLCOUNT) ? (j) : ((sortmode == S_NOSORT) ? j : bool_indirect[j]))
Line 101 
Line 109 
 #define StrIndirect(j)  ((sortmode == S_NOSORT) ? (j) : str_indirect[j])  #define StrIndirect(j)  ((sortmode == S_NOSORT) ? (j) : str_indirect[j])
 #endif  #endif
   
   static GCC_NORETURN void
   failed(const char *s)
   {
       perror(s);
       ExitProgram(EXIT_FAILURE);
   }
   
 static void  static void
 strncpy_DYN(DYNBUF * dst, const char *src, size_t need)  strncpy_DYN(DYNBUF * dst, const char *src, size_t need)
 {  {
Line 108 
Line 123 
     if (want > dst->size) {      if (want > dst->size) {
         dst->size += (want + 1024);     /* be generous */          dst->size += (want + 1024);     /* be generous */
         dst->text = typeRealloc(char, dst->size, dst->text);          dst->text = typeRealloc(char, dst->size, dst->text);
           if (dst->text == 0)
               failed("strncpy_DYN");
     }      }
     (void) strncpy(dst->text + dst->used, src, need);      _nc_STRNCPY(dst->text + dst->used, src, need + 1);
     dst->used += need;      dst->used += need;
     dst->text[dst->used] = 0;      dst->text[dst->used] = 0;
 }  }
Line 145 
Line 162 
 #endif  #endif
   
 #define NameTrans(check,result) \  #define NameTrans(check,result) \
             if (OkIndex(np->nte_index, check) \              if ((np->nte_index <= OK_ ## check) \
                 && check[np->nte_index]) \                  && check[np->nte_index]) \
                 return (result[np->nte_index])                  return (result[np->nte_index])
   
 NCURSES_CONST char *  NCURSES_CONST char *
 nametrans(const char *name)  nametrans(const char *name)
 /* translate a capability name from termcap to terminfo */  /* translate a capability name to termcap from terminfo */
 {  {
     const struct name_table_entry *np;      const struct name_table_entry *np;
   
     if ((np = _nc_find_entry(name, _nc_get_hash_table(0))) != 0)      if ((np = _nc_find_entry(name, _nc_get_hash_table(0))) != 0) {
         switch (np->nte_type) {          switch (np->nte_type) {
         case BOOLEAN:          case BOOLEAN:
             NameTrans(bool_from_termcap, boolcodes);              NameTrans(bool_from_termcap, boolcodes);
Line 169 
Line 186 
             NameTrans(str_from_termcap, strcodes);              NameTrans(str_from_termcap, strcodes);
             break;              break;
         }          }
       }
   
     return (0);      return (0);
 }  }
   
 void  void
 dump_init(const char *version, int mode, int sort, int twidth, int traceval,  dump_init(const char *version,
           bool formatted)            int mode,
             int sort,
             bool wrap_strings,
             int twidth,
             int theight,
             unsigned traceval,
             bool formatted,
             bool check,
             int quick)
 /* set up for entry display */  /* set up for entry display */
 {  {
     width = twidth;      width = twidth;
       height = theight;
     pretty = formatted;      pretty = formatted;
       wrapped = wrap_strings;
       checking = check;
       quickdump = (quick & 3);
   
       did_wrap = (width <= 0);
   
     /* versions */      /* versions */
     if (version == 0)      if (version == 0)
         tversion = V_ALLCAPS;          tversion = V_ALLCAPS;
Line 203 
Line 235 
         bool_names = boolnames;          bool_names = boolnames;
         num_names = numnames;          num_names = numnames;
         str_names = strnames;          str_names = strnames;
         separator = twidth ? ", " : ",";          separator = (twidth > 0 && theight > 1) ? ", " : ",";
         trailer = "\n\t";          trailer = "\n\t";
         break;          break;
   
Line 211 
Line 243 
         bool_names = boolfnames;          bool_names = boolfnames;
         num_names = numfnames;          num_names = numfnames;
         str_names = strfnames;          str_names = strfnames;
         separator = twidth ? ", " : ",";          separator = (twidth > 0 && theight > 1) ? ", " : ",";
         trailer = "\n\t";          trailer = "\n\t";
         break;          break;
   
Line 224 
Line 256 
         trailer = "\\\n\t:";          trailer = "\\\n\t:";
         break;          break;
     }      }
       indent = 8;
   
     /* implement sort modes */      /* implement sort modes */
     switch (sortmode = sort) {      switch (sortmode = sort) {
Line 267 
Line 300 
                        _nc_progname, width, tversion, outform);                         _nc_progname, width, tversion, outform);
 }  }
   
 static TERMTYPE *cur_type;  static TERMTYPE2 *cur_type;
   
 static int  static int
 dump_predicate(PredType type, PredIdx idx)  dump_predicate(PredType type, PredIdx idx)
Line 290 
Line 323 
     return (FALSE);             /* pacify compiler */      return (FALSE);             /* pacify compiler */
 }  }
   
 static void set_obsolete_termcaps(TERMTYPE *tp);  static void set_obsolete_termcaps(TERMTYPE2 *tp);
   
 /* is this the index of a function key string? */  /* is this the index of a function key string? */
 #define FNKEY(i)        (((i)>= 65 && (i)<= 75) || ((i)>= 216 && (i)<= 268))  #define FNKEY(i) \
       (((i) >= STR_IDX(key_f0) && \
         (i) <= STR_IDX(key_f9)) || \
        ((i) >= STR_IDX(key_f11) && \
         (i) <= STR_IDX(key_f63)))
   
 /*  /*
  * If we configure with a different Caps file, the offsets into the arrays   * If we configure with a different Caps file, the offsets into the arrays
Line 389 
Line 426 
     oldcol = column;      oldcol = column;
     trim_trailing();      trim_trailing();
     strcpy_DYN(&outbuf, trailer);      strcpy_DYN(&outbuf, trailer);
     column = INDENT;      column = indent;
 }  }
   
   static int
   op_length(const char *src, int offset)
   {
       int result = 0;
   
       if (offset > 0 && src[offset - 1] == '\\') {
           result = 0;
       } else {
           int ch;
   
           result++;               /* for '%' mark */
           ch = src[offset + result];
           if (TcOutput()) {
               if (ch == '>') {
                   result += 3;
               } else if (ch == '+') {
                   result += 2;
               } else {
                   result++;
               }
           } else if (ch == '\'') {
               result += 3;
           } else if (ch == L_CURL[0]) {
               int n = result;
               while ((ch = src[offset + n]) != '\0') {
                   if (ch == R_CURL[0]) {
                       result = ++n;
                       break;
                   }
                   n++;
               }
           } else if (strchr("pPg", ch) != 0) {
               result += 2;
           } else {
               result++;           /* ordinary operator */
           }
       }
       return result;
   }
   
   /*
    * When wrapping too-long strings, avoid splitting a backslash sequence, or
    * a terminfo '%' operator.  That will leave things a little ragged, but avoids
    * a stray backslash at the end of the line, as well as making the result a
    * little more readable.
    */
   static int
   find_split(const char *src, int step, int size)
   {
       int result = size;
   
       if (size > 0) {
           /* check if that would split a backslash-sequence */
           int mark = size;
           int n;
   
           for (n = size - 1; n > 0; --n) {
               int ch = UChar(src[step + n]);
               if (ch == '\\') {
                   if (n > 0 && src[step + n - 1] == ch)
                       --n;
                   mark = n;
                   break;
               } else if (!isalnum(ch)) {
                   break;
               }
           }
           if (mark < size) {
               result = mark;
           } else {
               /* check if that would split a backslash-sequence */
               for (n = size - 1; n > 0; --n) {
                   int ch = UChar(src[step + n]);
                   if (ch == '%') {
                       int need = op_length(src, step + n);
                       if ((n + need) > size) {
                           mark = n;
                       }
                       break;
                   }
               }
               if (mark < size) {
                   result = mark;
               }
           }
       }
       return result;
   }
   
   /*
    * If we are going to wrap lines, we cannot leave literal spaces because that
    * would be ambiguous if we split on that space.
    */
   static char *
   fill_spaces(const char *src)
   {
       const char *fill = "\\s";
       size_t need = strlen(src);
       size_t size = strlen(fill);
       char *result = 0;
       int pass;
       size_t s, d;
       for (pass = 0; pass < 2; ++pass) {
           for (s = d = 0; src[s] != '\0'; ++s) {
               if (src[s] == ' ') {
                   if (pass) {
                       _nc_STRCPY(&result[d], fill, need + 1 - d);
                       d += size;
                   } else {
                       need += size;
                   }
               } else {
                   if (pass) {
                       result[d++] = src[s];
                   } else {
                       ++d;
                   }
               }
           }
           if (pass) {
               result[d] = '\0';
           } else {
               result = calloc(need + 1, sizeof(char));
               if (result == 0)
                   failed("fill_spaces");
           }
       }
       return result;
   }
   
   typedef enum {
       wOFF = 0
       ,w1ST = 1
       ,w2ND = 2
       ,wEND = 4
       ,wERR = 8
   } WRAPMODE;
   
   #define wrap_1ST(mode) ((mode)&w1ST)
   #define wrap_END(mode) ((mode)&wEND)
   #define wrap_ERR(mode) ((mode)&wERR)
   
 static void  static void
 wrap_concat(const char *src)  wrap_concat(const char *src, int need, unsigned mode)
 {  {
     unsigned need = strlen(src);      int gaps = (int) strlen(separator);
     unsigned want = strlen(separator) + need;      int want = gaps + need;
   
     if (column > INDENT      did_wrap = (width <= 0);
         && column + (int) want > width) {      if (wrap_1ST(mode)
           && column > indent
           && column + want > width) {
         force_wrap();          force_wrap();
     }      }
     strcpy_DYN(&outbuf, src);      if ((wrap_END(mode) && !wrap_ERR(mode)) &&
     strcpy_DYN(&outbuf, separator);          wrapped &&
     column += (int) need;          (width >= 0) &&
           (column + want) > width) {
           int step = 0;
           int used = width > WRAPPED ? width : WRAPPED;
           int base = 0;
           char *p, align[9];
           const char *my_t = trailer;
           char *fill = fill_spaces(src);
           int last = (int) strlen(fill);
   
           need = last;
   
           if (TcOutput())
               trailer = "\\\n\t ";
   
           if (!TcOutput() && (p = strchr(fill, '=')) != 0) {
               base = (int) (p + 1 - fill);
               if (base > 8)
                   base = 8;
               _nc_SPRINTF(align, _nc_SLIMIT(align) "%*s", base, " ");
           } else if (column > 8) {
               base = column - 8;
               if (base > 8)
                   base = 8;
               _nc_SPRINTF(align, _nc_SLIMIT(align) "%*s", base, " ");
           } else {
               align[base] = '\0';
           }
           /* "pretty" overrides wrapping if it already split the line */
           if (!pretty || strchr(fill, '\n') == 0) {
               int tag = 0;
   
               if (TcOutput() && outbuf.used && !wrap_1ST(mode)) {
                   tag = 3;
               }
   
               while ((column + (need + gaps)) > used) {
                   int size = used - tag;
                   if (step) {
                       strcpy_DYN(&outbuf, align);
                       size -= base;
                   }
                   if (size > (last - step)) {
                       size = (last - step);
                   }
                   size = find_split(fill, step, size);
                   strncpy_DYN(&outbuf, fill + step, (size_t) size);
                   step += size;
                   need -= size;
                   if (need > 0) {
                       force_wrap();
                       did_wrap = TRUE;
                       tag = 0;
                   }
               }
           }
           if (need > 0) {
               if (step)
                   strcpy_DYN(&outbuf, align);
               strcpy_DYN(&outbuf, fill + step);
           }
           if (wrap_END(mode))
               strcpy_DYN(&outbuf, separator);
           trailer = my_t;
           force_wrap();
   
           free(fill);
       } else {
           strcpy_DYN(&outbuf, src);
           if (wrap_END(mode))
               strcpy_DYN(&outbuf, separator);
           column += (int) strlen(src);
       }
 }  }
   
   static void
   wrap_concat1(const char *src)
   {
       int need = (int) strlen(src);
       wrap_concat(src, need, w1ST | wEND);
   }
   
   static void
   wrap_concat3(const char *name, const char *eqls, const char *value)
   {
       int nlen = (int) strlen(name);
       int elen = (int) strlen(eqls);
       int vlen = (int) strlen(value);
   
       wrap_concat(name, nlen + elen + vlen, w1ST);
       wrap_concat(eqls, elen + vlen, w2ND);
       wrap_concat(value, vlen, wEND);
   }
   
 #define IGNORE_SEP_TRAIL(first,last,sep_trail) \  #define IGNORE_SEP_TRAIL(first,last,sep_trail) \
         if ((size_t)(last - first) > sizeof(sep_trail)-1 \          if ((size_t)(last - first) > sizeof(sep_trail)-1 \
          && !strncmp(first, sep_trail, sizeof(sep_trail)-1)) \           && !strncmp(first, sep_trail, sizeof(sep_trail)-1)) \
Line 447 
Line 719 
     int n;      int n;
   
     for (n = 0; n < level; n++)      for (n = 0; n < level; n++)
         strncpy_DYN(buffer, "\t", 1);          strncpy_DYN(buffer, "\t", (size_t) 1);
 }  }
   
   /*
    * Check if the current line which was begun consists only of a tab and the
    * given leading text.
    */
 static bool  static bool
 has_params(const char *src)  leading_DYN(DYNBUF * buffer, const char *leading)
 {  {
     bool result = FALSE;      bool result = FALSE;
       size_t need = strlen(leading);
       if (buffer->used > need) {
           need = buffer->used - need;
           if (!strcmp(buffer->text + need, leading)) {
               result = TRUE;
               while (--need != 0) {
                   if (buffer->text[need] == '\n') {
                       break;
                   }
                   if (buffer->text[need] != '\t') {
                       result = FALSE;
                       break;
                   }
               }
           }
       }
       return result;
   }
   
   bool
   has_params(const char *src, bool formatting)
   {
       bool result = FALSE;
     int len = (int) strlen(src);      int len = (int) strlen(src);
     int n;      int n;
     bool ifthen = FALSE;      bool ifthen = FALSE;
     bool params = FALSE;      bool params = FALSE;
   
     for (n = 0; n < len - 1; ++n) {      for (n = 0; n < len - 1; ++n) {
         if (!strncmp(src + n, "%p", 2)) {          if (!strncmp(src + n, "%p", (size_t) 2)) {
             params = TRUE;              params = TRUE;
         } else if (!strncmp(src + n, "%;", 2)) {          } else if (!strncmp(src + n, "%;", (size_t) 2)) {
             ifthen = TRUE;              ifthen = TRUE;
             result = params;              result = params;
             break;              break;
         }          }
     }      }
     if (!ifthen) {      if (!ifthen) {
         result = ((len > 50) && params);          if (formatting) {
               result = ((len > 50) && params);
           } else {
               result = params;
           }
     }      }
     return result;      return result;
 }  }
   
 static char *  static char *
 fmt_complex(char *src, int level)  fmt_complex(TERMTYPE2 *tterm, const char *capability, char *src, int level)
 {  {
     bool percent = FALSE;      bool percent = FALSE;
     bool params = has_params(src);      bool params = has_params(src, TRUE);
   
     while (*src != '\0') {      while (*src != '\0') {
         switch (*src) {          switch (*src) {
           case '^':
               percent = FALSE;
               strncpy_DYN(&tmpbuf, src++, (size_t) 1);
               break;
         case '\\':          case '\\':
             percent = FALSE;              percent = FALSE;
             strncpy_DYN(&tmpbuf, src++, 1);              strncpy_DYN(&tmpbuf, src++, (size_t) 1);
             break;              break;
         case '%':          case '%':
             percent = TRUE;              percent = TRUE;
Line 498 
Line 805 
                 /* treat a "%e" as else-if, on the same level */                  /* treat a "%e" as else-if, on the same level */
                 if (*src == 'e') {                  if (*src == 'e') {
                     indent_DYN(&tmpbuf, level);                      indent_DYN(&tmpbuf, level);
                     strncpy_DYN(&tmpbuf, "%", 1);                      strncpy_DYN(&tmpbuf, "%", (size_t) 1);
                     strncpy_DYN(&tmpbuf, src, 1);                      strncpy_DYN(&tmpbuf, src, (size_t) 1);
                     src++;                      src++;
                     params = has_params(src);                      params = has_params(src, TRUE);
                     if (!params && *src != '\0' && *src != '%') {                      if (!params && *src != '\0' && *src != '%') {
                         strncpy_DYN(&tmpbuf, "\n", 1);                          strncpy_DYN(&tmpbuf, "\n", (size_t) 1);
                         indent_DYN(&tmpbuf, level + 1);                          indent_DYN(&tmpbuf, level + 1);
                     }                      }
                 } else {                  } else {
                     indent_DYN(&tmpbuf, level + 1);                      indent_DYN(&tmpbuf, level + 1);
                     strncpy_DYN(&tmpbuf, "%", 1);                      strncpy_DYN(&tmpbuf, "%", (size_t) 1);
                     strncpy_DYN(&tmpbuf, src, 1);                      strncpy_DYN(&tmpbuf, src, (size_t) 1);
                     if (*src++ == '?') {                      if (*src++ == '?') {
                         src = fmt_complex(src, level + 1);                          src = fmt_complex(tterm, capability, src, level + 1);
                         if (*src != '\0' && *src != '%') {                          if (*src != '\0' && *src != '%') {
                             strncpy_DYN(&tmpbuf, "\n", 1);                              strncpy_DYN(&tmpbuf, "\n", (size_t) 1);
                             indent_DYN(&tmpbuf, level + 1);                              indent_DYN(&tmpbuf, level + 1);
                         }                          }
                     } else if (level == 1) {                      } else if (level == 1) {
                         _nc_warning("%%%c without %%?", *src);                          if (checking)
                               _nc_warning("%s: %%%c without %%? in %s",
                                           _nc_first_name(tterm->term_names),
                                           *src, capability);
                     }                      }
                 }                  }
                 continue;                  continue;
Line 529 
Line 839 
                 if (level > 1) {                  if (level > 1) {
                     tmpbuf.text[tmpbuf.used - 1] = '\n';                      tmpbuf.text[tmpbuf.used - 1] = '\n';
                     indent_DYN(&tmpbuf, level);                      indent_DYN(&tmpbuf, level);
                     strncpy_DYN(&tmpbuf, "%", 1);                      strncpy_DYN(&tmpbuf, "%", (size_t) 1);
                     strncpy_DYN(&tmpbuf, src++, 1);                      strncpy_DYN(&tmpbuf, src++, (size_t) 1);
                       if (src[0] == '%'
                           && src[1] != '\0'
                           && (strchr("?e;", src[1])) == 0) {
                           tmpbuf.text[tmpbuf.used++] = '\n';
                           indent_DYN(&tmpbuf, level);
                       }
                     return src;                      return src;
                 }                  }
                 _nc_warning("%%; without %%?");                  if (checking)
                       _nc_warning("%s: %%; without %%? in %s",
                                   _nc_first_name(tterm->term_names),
                                   capability);
             }              }
             break;              break;
         case 'p':          case 'p':
             if (percent && params) {              if (percent && params && !leading_DYN(&tmpbuf, "%")) {
                 tmpbuf.text[tmpbuf.used - 1] = '\n';                  tmpbuf.text[tmpbuf.used - 1] = '\n';
                 indent_DYN(&tmpbuf, level + 1);                  indent_DYN(&tmpbuf, level + 1);
                 strncpy_DYN(&tmpbuf, "%", 1);                  strncpy_DYN(&tmpbuf, "%", (size_t) 1);
             }              }
             params = FALSE;  
             percent = FALSE;              percent = FALSE;
             break;              break;
         case ' ':          case ' ':
             strncpy_DYN(&tmpbuf, "\\s", 2);              strncpy_DYN(&tmpbuf, "\\s", (size_t) 2);
             ++src;              ++src;
             continue;              continue;
         default:          default:
             percent = FALSE;              percent = FALSE;
             break;              break;
         }          }
         strncpy_DYN(&tmpbuf, src++, 1);          strncpy_DYN(&tmpbuf, src++, (size_t) 1);
     }      }
     return src;      return src;
 }  }
   
   /*
    * Make "large" numbers a little easier to read by showing them in hexadecimal
    * if they are "close" to a power of two.
    */
   static const char *
   number_format(int value)
   {
       const char *result = "%d";
   
       if ((outform != F_TERMCAP) && (value > 255)) {
           unsigned long lv = (unsigned long) value;
           int bits = sizeof(unsigned long) * 8;
           int nn;
   
           for (nn = 8; nn < bits; ++nn) {
               unsigned long mm;
   
               mm = 1UL << nn;
               if ((mm - 16) <= lv && (mm + 16) > lv) {
                   result = "%#x";
                   break;
               }
           }
       }
       return result;
   }
   
 #define SAME_CAP(n,cap) (&tterm->Strings[n] == &cap)  #define SAME_CAP(n,cap) (&tterm->Strings[n] == &cap)
 #define EXTRA_CAP 20  #define EXTRA_CAP 20
   
 int  int
 fmt_entry(TERMTYPE *tterm,  fmt_entry(TERMTYPE2 *tterm,
           PredFunc pred,            PredFunc pred,
           bool content_only,            int content_only,
           bool suppress_untranslatable,            int suppress_untranslatable,
           bool infodump,            int infodump,
           int numbers)            int numbers)
 {  {
     PredIdx i, j;      PredIdx i, j;
     char buffer[MAX_TERMINFO_LENGTH + EXTRA_CAP];      char buffer[MAX_TERMINFO_LENGTH + EXTRA_CAP];
     char *capability;  
     NCURSES_CONST char *name;      NCURSES_CONST char *name;
     int predval, len;      int predval, len;
     PredIdx num_bools = 0;      PredIdx num_bools = 0;
Line 579 
Line 923 
     PredIdx num_strings = 0;      PredIdx num_strings = 0;
     bool outcount = 0;      bool outcount = 0;
   
 #define WRAP_CONCAT     \  #define WRAP_CONCAT1(s)         wrap_concat1(s); outcount = TRUE
         wrap_concat(buffer); \  #define WRAP_CONCAT             WRAP_CONCAT1(buffer)
         outcount = TRUE  
   
     len = 12;                   /* terminfo file-header */      len = 12;                   /* terminfo file-header */
   
Line 592 
Line 935 
   
     strcpy_DYN(&outbuf, 0);      strcpy_DYN(&outbuf, 0);
     if (content_only) {      if (content_only) {
         column = INDENT;        /* FIXME: workaround to prevent empty lines */          column = indent;        /* workaround to prevent empty lines */
     } else {      } else {
         strcpy_DYN(&outbuf, tterm->term_names);          strcpy_DYN(&outbuf, tterm->term_names);
   
           /*
            * Colon is legal in terminfo descriptions, but not in termcap.
            */
           if (!infodump) {
               char *p = outbuf.text;
               while (*p) {
                   if (*p == ':') {
                       *p = '=';
                   }
                   ++p;
               }
           }
         strcpy_DYN(&outbuf, separator);          strcpy_DYN(&outbuf, separator);
         column = (int) outbuf.used;          column = (int) outbuf.used;
         force_wrap();          if (height > 1)
               force_wrap();
     }      }
   
     for_each_boolean(j, tterm) {      for_each_boolean(j, tterm) {
         i = BoolIndirect(j);          i = BoolIndirect(j);
         name = ExtBoolname(tterm, i, bool_names);          name = ExtBoolname(tterm, (int) i, bool_names);
         assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);          assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
   
         if (!version_filter(BOOLEAN, i))          if (!version_filter(BOOLEAN, i))
Line 612 
Line 969 
   
         predval = pred(BOOLEAN, i);          predval = pred(BOOLEAN, i);
         if (predval != FAIL) {          if (predval != FAIL) {
             (void) strlcpy(buffer, name, sizeof buffer);              _nc_STRCPY(buffer, name, sizeof(buffer));
             if (predval <= 0)              if (predval <= 0)
                 (void) strlcat(buffer, "@", sizeof buffer);                  _nc_STRCAT(buffer, "@", sizeof(buffer));
             else if (i + 1 > num_bools)              else if (i + 1 > num_bools)
                 num_bools = i + 1;                  num_bools = i + 1;
             WRAP_CONCAT;              WRAP_CONCAT;
         }          }
     }      }
   
     if (column != INDENT)      if (column != indent && height > 1)
         force_wrap();          force_wrap();
   
     for_each_number(j, tterm) {      for_each_number(j, tterm) {
         i = NumIndirect(j);          i = NumIndirect(j);
         name = ExtNumname(tterm, i, num_names);          name = ExtNumname(tterm, (int) i, num_names);
         assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);          assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
   
         if (!version_filter(NUMBER, i))          if (!version_filter(NUMBER, i))
Line 637 
Line 994 
         predval = pred(NUMBER, i);          predval = pred(NUMBER, i);
         if (predval != FAIL) {          if (predval != FAIL) {
             if (tterm->Numbers[i] < 0) {              if (tterm->Numbers[i] < 0) {
                 snprintf(buffer, sizeof buffer, "%s@", name);                  _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                               "%s@", name);
             } else {              } else {
                 snprintf(buffer, sizeof buffer, "%s#%d", name, tterm->Numbers[i]);                  size_t nn;
                   _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                               "%s#", name);
                   nn = strlen(buffer);
                   _nc_SPRINTF(buffer + nn, _nc_SLIMIT(sizeof(buffer) - nn)
                               number_format(tterm->Numbers[i]),
                               tterm->Numbers[i]);
                 if (i + 1 > num_values)                  if (i + 1 > num_values)
                     num_values = i + 1;                      num_values = i + 1;
             }              }
Line 647 
Line 1011 
         }          }
     }      }
   
     if (column != INDENT)      if (column != indent && height > 1)
         force_wrap();          force_wrap();
   
     len += (int) (num_bools      len += (int) (num_bools
Line 659 
Line 1023 
 #undef CUR  #undef CUR
 #define CUR tterm->  #define CUR tterm->
     if (outform == F_TERMCAP) {      if (outform == F_TERMCAP) {
         if (termcap_reset != ABSENT_STRING) {          if (VALID_STRING(termcap_reset)) {
             if (init_3string != ABSENT_STRING              if (VALID_STRING(init_3string)
                 && !strcmp(init_3string, termcap_reset))                  && !strcmp(init_3string, termcap_reset))
                 DISCARD(init_3string);                  DISCARD(init_3string);
   
             if (reset_2string != ABSENT_STRING              if (VALID_STRING(reset_2string)
                 && !strcmp(reset_2string, termcap_reset))                  && !strcmp(reset_2string, termcap_reset))
                 DISCARD(reset_2string);                  DISCARD(reset_2string);
         }          }
     }      }
   
     for_each_string(j, tterm) {      for_each_string(j, tterm) {
           char *capability;
         i = StrIndirect(j);          i = StrIndirect(j);
         name = ExtStrname(tterm, i, str_names);          name = ExtStrname(tterm, (int) i, str_names);
         assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);          assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
   
         capability = tterm->Strings[i];          capability = tterm->Strings[i];
Line 700 
Line 1065 
             if (PRESENT(insert_character) || PRESENT(parm_ich)) {              if (PRESENT(insert_character) || PRESENT(parm_ich)) {
                 if (SAME_CAP(i, enter_insert_mode)                  if (SAME_CAP(i, enter_insert_mode)
                     && enter_insert_mode == ABSENT_STRING) {                      && enter_insert_mode == ABSENT_STRING) {
                     (void) strlcpy(buffer, "im=", sizeof(buffer));                      _nc_STRCPY(buffer, "im=", sizeof(buffer));
                     WRAP_CONCAT;                      WRAP_CONCAT;
                     continue;                      continue;
                 }                  }
   
                 if (SAME_CAP(i, exit_insert_mode)                  if (SAME_CAP(i, exit_insert_mode)
                     && exit_insert_mode == ABSENT_STRING) {                      && exit_insert_mode == ABSENT_STRING) {
                         (void) strlcpy(buffer, "ei=", sizeof(buffer));                      _nc_STRCPY(buffer, "ei=", sizeof(buffer));
                     WRAP_CONCAT;                      WRAP_CONCAT;
                     continue;                      continue;
                 }                  }
Line 724 
Line 1089 
                     set_attributes = save_sgr;                      set_attributes = save_sgr;
   
                     trimmed_sgr0 = _nc_trim_sgr0(tterm);                      trimmed_sgr0 = _nc_trim_sgr0(tterm);
                     if (strcmp(capability, trimmed_sgr0))                      if (strcmp(capability, trimmed_sgr0)) {
                         capability = trimmed_sgr0;                          capability = trimmed_sgr0;
                       } else {
                           if (trimmed_sgr0 != exit_attribute_mode)
                               free(trimmed_sgr0);
                       }
   
                     set_attributes = my_sgr;                      set_attributes = my_sgr;
                 }                  }
Line 736 
Line 1105 
         buffer[0] = '\0';          buffer[0] = '\0';
   
         if (predval != FAIL) {          if (predval != FAIL) {
             if (capability != ABSENT_STRING              if (VALID_STRING(capability)
                 && i + 1 > num_strings)                  && i + 1 > num_strings)
                 num_strings = i + 1;                  num_strings = i + 1;
   
             if (!VALID_STRING(capability)) {              if (!VALID_STRING(capability)) {
                 snprintf(buffer, sizeof(buffer), "%s@", name);                  _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                               "%s@", name);
                 WRAP_CONCAT;                  WRAP_CONCAT;
             } else if (outform == F_TERMCAP || outform == F_TCONVERR) {              } else if (TcOutput()) {
                   char *srccap = _nc_tic_expand(capability, TRUE, numbers);
                 int params = ((i < (int) SIZEOF(parametrized))                  int params = ((i < (int) SIZEOF(parametrized))
                               ? parametrized[i]                                ? parametrized[i]
                               : 0);                                : ((*srccap == 'k')
                 char *srccap = _nc_tic_expand(capability, TRUE, numbers);                                   ? 0
                                    : has_params(srccap, FALSE)));
                 char *cv = _nc_infotocap(name, srccap, params);                  char *cv = _nc_infotocap(name, srccap, params);
   
                 if (cv == 0) {                  if (cv == 0) {
                     if (outform == F_TCONVERR) {                      if (outform == F_TCONVERR) {
                         snprintf(buffer, sizeof(buffer),                          _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                             "%s=!!! %s WILL NOT CONVERT !!!", name, srccap);                                      "%s=!!! %s WILL NOT CONVERT !!!",
                                       name, srccap);
                           WRAP_CONCAT;
                     } else if (suppress_untranslatable) {                      } else if (suppress_untranslatable) {
                         continue;                          continue;
                     } else {                      } else {
                         char *d, *s = srccap;                          char *s = srccap, *d = buffer;
                         snprintf(buffer, sizeof(buffer), "..%s=", name);                          int need = 3 + (int) strlen(name);
                         d = buffer + strlen(buffer);                          while ((*d = *s++) != 0) {
                         while ((*d = *s++) != 0) {      /* XXX overflow */                              if ((d - buffer + 2) >= (int) sizeof(buffer)) {
                                   fprintf(stderr,
                                           "%s: value for %s is too long\n",
                                           _nc_progname,
                                           name);
                                   *d = '\0';
                                   break;
                               }
                             if (*d == ':') {                              if (*d == ':') {
                                 *d++ = '\\';                                  *d++ = '\\';
                                 *d = ':';                                  *d = ':';
                             } else if (*d == '\\') {                              } else if (*d == '\\') {
                                 *++d = *s++;                                  if ((*++d = *s++) == '\0')
                                       break;
                             }                              }
                             d++;                              d++;
                               *d = '\0';
                         }                          }
                           need += (int) (d - buffer);
                           wrap_concat("..", need, w1ST | wERR);
                           need -= 2;
                           wrap_concat(name, need, wOFF | wERR);
                           need -= (int) strlen(name);
                           wrap_concat("=", need, w2ND | wERR);
                           need -= 1;
                           wrap_concat(buffer, need, wEND | wERR);
                           outcount = TRUE;
                     }                      }
                 } else {                  } else {
                     snprintf(buffer, sizeof buffer, "%s=%s", name, cv);                      wrap_concat3(name, "=", cv);
                 }                  }
                 len += (int) strlen(capability) + 1;                  len += (int) strlen(capability) + 1;
                 WRAP_CONCAT;  
             } else {              } else {
                 char *src = _nc_tic_expand(capability,                  char *src = _nc_tic_expand(capability,
                                            outform == F_TERMINFO, numbers);                                             outform == F_TERMINFO, numbers);
Line 785 
Line 1176 
                 if (pretty                  if (pretty
                     && (outform == F_TERMINFO                      && (outform == F_TERMINFO
                         || outform == F_VARIABLE)) {                          || outform == F_VARIABLE)) {
                     fmt_complex(src, 1);                      fmt_complex(tterm, name, src, 1);
                 } else {                  } else {
                     strcpy_DYN(&tmpbuf, src);                      strcpy_DYN(&tmpbuf, src);
                 }                  }
                 len += (int) strlen(capability) + 1;                  len += (int) strlen(capability) + 1;
                 wrap_concat(tmpbuf.text);                  WRAP_CONCAT1(tmpbuf.text);
                 outcount = TRUE;  
             }              }
         }          }
         /* e.g., trimmed_sgr0 */          /* e.g., trimmed_sgr0 */
         if (capability != tterm->Strings[i])          if (VALID_STRING(capability) &&
               capability != tterm->Strings[i])
             free(capability);              free(capability);
     }      }
     len += (int) (num_strings * 2);      len += (int) (num_strings * 2);
Line 807 
Line 1198 
      */       */
     if (tversion == V_HPUX) {      if (tversion == V_HPUX) {
         if (VALID_STRING(memory_lock)) {          if (VALID_STRING(memory_lock)) {
             (void) snprintf(buffer, sizeof(buffer), "meml=%s", memory_lock);              _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                           "meml=%s", memory_lock);
             WRAP_CONCAT;              WRAP_CONCAT;
         }          }
         if (VALID_STRING(memory_unlock)) {          if (VALID_STRING(memory_unlock)) {
             (void) snprintf(buffer, sizeof(buffer), "memu=%s", memory_unlock);              _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                           "memu=%s", memory_unlock);
             WRAP_CONCAT;              WRAP_CONCAT;
         }          }
     } else if (tversion == V_AIX) {      } else if (tversion == V_AIX) {
Line 823 
Line 1216 
   
             tp = boxchars;              tp = boxchars;
             for (cp = acstrans; *cp; cp++) {              for (cp = acstrans; *cp; cp++) {
                 sp = strchr(acs_chars, *cp);                  sp = (strchr) (acs_chars, *cp);
                 if (sp)                  if (sp)
                     *tp++ = sp[1];                      *tp++ = sp[1];
                 else {                  else {
Line 834 
Line 1227 
             tp[0] = '\0';              tp[0] = '\0';
   
             if (box_ok) {              if (box_ok) {
                 (void) strlcpy(buffer, "box1=", sizeof(buffer));                  char *tmp = _nc_tic_expand(boxchars,
                 (void) strlcat(buffer, _nc_tic_expand(boxchars,                                             (outform == F_TERMINFO),
                     outform == F_TERMINFO, numbers), sizeof(buffer));                                             numbers);
                   _nc_STRCPY(buffer, "box1=", sizeof(buffer));
                   while (*tmp != '\0') {
                       size_t have = strlen(buffer);
                       size_t next = strlen(tmp);
                       size_t want = have + next + 1;
                       size_t last = next;
                       char save = '\0';
   
                       /*
                        * If the expanded string is too long for the buffer,
                        * chop it off and save the location where we chopped it.
                        */
                       if (want >= sizeof(buffer)) {
                           save = tmp[last];
                           tmp[last] = '\0';
                       }
                       _nc_STRCAT(buffer, tmp, sizeof(buffer));
   
                       /*
                        * If we chopped the buffer, replace the missing piece and
                        * shift everything to append the remainder.
                        */
                       if (save != '\0') {
                           next = 0;
                           tmp[last] = save;
                           while ((tmp[next] = tmp[last + next]) != '\0') {
                               ++next;
                           }
                       } else {
                           break;
                       }
                   }
                 WRAP_CONCAT;                  WRAP_CONCAT;
             }              }
         }          }
Line 848 
Line 1273 
      */       */
     if (outcount) {      if (outcount) {
         bool trimmed = FALSE;          bool trimmed = FALSE;
         j = outbuf.used;          j = (PredIdx) outbuf.used;
         if (j >= 2          if (wrapped && did_wrap) {
             && outbuf.text[j - 1] == '\t'              /* EMPTY */ ;
             && outbuf.text[j - 2] == '\n') {          } else if (j >= 2
                      && outbuf.text[j - 1] == '\t'
                      && outbuf.text[j - 2] == '\n') {
             outbuf.used -= 2;              outbuf.used -= 2;
             trimmed = TRUE;              trimmed = TRUE;
         } else if (j >= 4          } else if (j >= 4
Line 886 
Line 1313 
 }  }
   
 static bool  static bool
 kill_string(TERMTYPE *tterm, char *cap)  kill_string(TERMTYPE2 *tterm, const char *const cap)
 {  {
     unsigned n;      unsigned n;
     for (n = 0; n < NUM_STRINGS(tterm); ++n) {      for (n = 0; n < NUM_STRINGS(tterm); ++n) {
Line 899 
Line 1326 
 }  }
   
 static char *  static char *
 find_string(TERMTYPE *tterm, char *name)  find_string(TERMTYPE2 *tterm, char *name)
 {  {
     PredIdx n;      PredIdx n;
     for (n = 0; n < NUM_STRINGS(tterm); ++n) {      for (n = 0; n < NUM_STRINGS(tterm); ++n) {
Line 920 
Line 1347 
  * make it smaller.   * make it smaller.
  */   */
 static int  static int
 kill_labels(TERMTYPE *tterm, int target)  kill_labels(TERMTYPE2 *tterm, int target)
 {  {
     int n;      int n;
     int result = 0;      int result = 0;
     char *cap;      char name[20];
     char name[10];  
   
     for (n = 0; n <= 10; ++n) {      for (n = 0; n <= 10; ++n) {
         snprintf(name, sizeof(name), "lf%d", n);          char *cap;
         if ((cap = find_string(tterm, name)) != ABSENT_STRING  
           _nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "lf%d", n);
           cap = find_string(tterm, name);
           if (VALID_STRING(cap)
             && kill_string(tterm, cap)) {              && kill_string(tterm, cap)) {
             target -= (int) (strlen(cap) + 5);              target -= (int) (strlen(cap) + 5);
             ++result;              ++result;
Line 945 
Line 1374 
  * make it smaller.   * make it smaller.
  */   */
 static int  static int
 kill_fkeys(TERMTYPE *tterm, int target)  kill_fkeys(TERMTYPE2 *tterm, int target)
 {  {
     int n;      int n;
     int result = 0;      int result = 0;
     char *cap;      char name[20];
     char name[10];  
   
     for (n = 60; n >= 0; --n) {      for (n = 60; n >= 0; --n) {
         snprintf(name, sizeof(name), "kf%d", n);          char *cap;
         if ((cap = find_string(tterm, name)) != ABSENT_STRING  
           _nc_SPRINTF(name, _nc_SLIMIT(sizeof(name)) "kf%d", n);
           cap = find_string(tterm, name);
           if (VALID_STRING(cap)
             && kill_string(tterm, cap)) {              && kill_string(tterm, cap)) {
             target -= (int) (strlen(cap) + 5);              target -= (int) (strlen(cap) + 5);
             ++result;              ++result;
Line 976 
Line 1407 
 {  {
     bool result = TRUE;      bool result = TRUE;
   
     if (mapping != ABSENT_STRING) {      if (VALID_STRING(mapping)) {
         int n = 0;          int n = 0;
         while (mapping[n] != '\0') {          while (mapping[n] != '\0' && mapping[n + 1] != '\0') {
             if (isLine(mapping[n]) &&              if (isLine(mapping[n]) &&
                 mapping[n] != mapping[n + 1]) {                  mapping[n] != mapping[n + 1]) {
                 result = FALSE;                  result = FALSE;
Line 999 
Line 1430 
 #define SHOW_WHY PRINTF  #define SHOW_WHY PRINTF
   
 static bool  static bool
 purged_acs(TERMTYPE *tterm)  purged_acs(TERMTYPE2 *tterm)
 {  {
     bool result = FALSE;      bool result = FALSE;
   
Line 1014 
Line 1445 
     return result;      return result;
 }  }
   
   static void
   encode_b64(char *target, char *source, unsigned state, int *saved)
   {
       /* RFC-4648 */
       static const char data[] =
       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
       "abcdefghijklmnopqrstuvwxyz"
       "0123456789" "-_";
       int ch = UChar(source[state]);
   
       switch (state % 3) {
       case 0:
           *target++ = data[(ch >> 2) & 077];
           *saved = (ch << 4);
           break;
       case 1:
           *target++ = data[((ch >> 4) | *saved) & 077];
           *saved = (ch << 2);
           break;
       case 2:
           *target++ = data[((ch >> 6) | *saved) & 077];
           *target++ = data[ch & 077];
           *saved = 0;
           break;
       }
       *target = '\0';
   }
   
 /*  /*
  * Dump a single entry.   * Dump a single entry.
  */   */
 void  void
 dump_entry(TERMTYPE *tterm,  dump_entry(TERMTYPE2 *tterm,
            bool suppress_untranslatable,             int suppress_untranslatable,
            bool limited,             int limited,
            int numbers,             int numbers,
            PredFunc pred)             PredFunc pred)
 {  {
     TERMTYPE save_tterm;      TERMTYPE2 save_tterm;
     int len, critlen;      int critlen;
     const char *legend;      const char *legend;
     bool infodump;      bool infodump;
   
     if (outform == F_TERMCAP || outform == F_TCONVERR) {      if (quickdump) {
           char bigbuf[65536];
           unsigned offset = 0;
   
           separator = "";
           trailer = "\n";
           indent = 0;
   
           if (_nc_write_object(tterm, bigbuf, &offset, sizeof(bigbuf)) == OK) {
               char numbuf[80];
               unsigned n;
   
               if (quickdump & 1) {
                   if (outbuf.used)
                       wrap_concat1("\n");
                   wrap_concat1("hex:");
                   for (n = 0; n < offset; ++n) {
                       _nc_SPRINTF(numbuf, _nc_SLIMIT(sizeof(numbuf))
                                   "%02X", UChar(bigbuf[n]));
                       wrap_concat1(numbuf);
                   }
               }
               if (quickdump & 2) {
                   static char padding[] =
                   {0, 0};
                   int value = 0;
   
                   if (outbuf.used)
                       wrap_concat1("\n");
                   wrap_concat1("b64:");
                   for (n = 0; n < offset; ++n) {
                       encode_b64(numbuf, bigbuf, n, &value);
                       wrap_concat1(numbuf);
                   }
                   switch (n % 3) {
                   case 0:
                       break;
                   case 1:
                       encode_b64(numbuf, padding, 1, &value);
                       wrap_concat1(numbuf);
                       wrap_concat1("==");
                       break;
                   case 2:
                       encode_b64(numbuf, padding, 1, &value);
                       wrap_concat1(numbuf);
                       wrap_concat1("=");
                       break;
                   }
               }
           }
           return;
       }
   
       if (TcOutput()) {
         critlen = MAX_TERMCAP_LENGTH;          critlen = MAX_TERMCAP_LENGTH;
         legend = "older termcap";          legend = "older termcap";
         infodump = FALSE;          infodump = FALSE;
Line 1042 
Line 1554 
   
     save_sgr = set_attributes;      save_sgr = set_attributes;
   
     if (((len = FMT_ENTRY()) > critlen)      if ((FMT_ENTRY() > critlen)
           && TcOutput()
         && limited) {          && limited) {
   
         save_tterm = *tterm;          save_tterm = *tterm;
Line 1051 
Line 1564 
                      critlen);                       critlen);
             suppress_untranslatable = TRUE;              suppress_untranslatable = TRUE;
         }          }
         if ((len = FMT_ENTRY()) > critlen) {          if (FMT_ENTRY() > critlen) {
             /*              /*
              * We pick on sgr because it's a nice long string capability that               * We pick on sgr because it is a nice long string capability that
              * is really just an optimization hack.  Another good candidate is               * is really just an optimization hack.  Another good candidate is
              * acsc since it is both long and unused by BSD termcap.               * acsc since it is both long and unused by BSD termcap.
              */               */
Line 1066 
Line 1579 
              */               */
             unsigned n;              unsigned n;
             for (n = STRCOUNT; n < NUM_STRINGS(tterm); n++) {              for (n = STRCOUNT; n < NUM_STRINGS(tterm); n++) {
                 const char *name = ExtStrname(tterm, n, strnames);                  const char *name = ExtStrname(tterm, (int) n, strnames);
   
                 if (VALID_STRING(tterm->Strings[n])) {                  if (VALID_STRING(tterm->Strings[n])) {
                     set_attributes = ABSENT_STRING;                      set_attributes = ABSENT_STRING;
Line 1077 
Line 1590 
                                  critlen);                                   critlen);
                     }                      }
                     changed = TRUE;                      changed = TRUE;
                     if ((len = FMT_ENTRY()) <= critlen)                      if (FMT_ENTRY() <= critlen)
                         break;                          break;
                 }                  }
             }              }
Line 1088 
Line 1601 
                          critlen);                           critlen);
                 changed = TRUE;                  changed = TRUE;
             }              }
             if (!changed || ((len = FMT_ENTRY()) > critlen)) {              if (!changed || (FMT_ENTRY() > critlen)) {
                 if (purged_acs(tterm)) {                  if (purged_acs(tterm)) {
                     acs_chars = ABSENT_STRING;                      acs_chars = ABSENT_STRING;
                     SHOW_WHY("# (acsc removed to fit entry within %d bytes)\n",                      SHOW_WHY("# (acsc removed to fit entry within %d bytes)\n",
Line 1096 
Line 1609 
                     changed = TRUE;                      changed = TRUE;
                 }                  }
             }              }
             if (!changed || ((len = FMT_ENTRY()) > critlen)) {              if (!changed || (FMT_ENTRY() > critlen)) {
                 int oldversion = tversion;                  int oldversion = tversion;
                   int len;
   
                 tversion = V_BSD;                  tversion = V_BSD;
                 SHOW_WHY("# (terminfo-only capabilities suppressed to fit entry within %d bytes)\n",                  SHOW_WHY("# (terminfo-only capabilities suppressed to fit entry within %d bytes)\n",
Line 1118 
Line 1632 
                 }                  }
                 if (len > critlen) {                  if (len > critlen) {
                     (void) fprintf(stderr,                      (void) fprintf(stderr,
                                    "warning: %s entry is %d bytes long\n",                                     "%s: %s entry is %d bytes long\n",
                                      _nc_progname,
                                    _nc_first_name(tterm->term_names),                                     _nc_first_name(tterm->term_names),
                                    len);                                     len);
                     SHOW_WHY("# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n",                      SHOW_WHY("# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n",
Line 1132 
Line 1647 
     } else if (!version_filter(STRING, STR_IDX(acs_chars))) {      } else if (!version_filter(STRING, STR_IDX(acs_chars))) {
         save_tterm = *tterm;          save_tterm = *tterm;
         if (purged_acs(tterm)) {          if (purged_acs(tterm)) {
             len = FMT_ENTRY();              (void) FMT_ENTRY();
         }          }
         *tterm = save_tterm;          *tterm = save_tterm;
     }      }
 }  }
   
 void  void
 dump_uses(const char *name, bool infodump)  dump_uses(const char *value, bool infodump)
 /* dump "use=" clauses in the appropriate format */  /* dump "use=" clauses in the appropriate format */
 {  {
     char buffer[MAX_TERMINFO_LENGTH];      char buffer[MAX_TERMINFO_LENGTH + EXTRA_CAP];
       int limit = (VALID_STRING(value) ? (int) strlen(value) : 0);
       const char *cap = infodump ? "use" : "tc";
   
     if (outform == F_TERMCAP || outform == F_TCONVERR)      if (TcOutput())
         trim_trailing();          trim_trailing();
     (void) snprintf(buffer, sizeof(buffer), "%s%s", infodump ? "use=" : "tc=",      if (limit == 0) {
         name);          _nc_warning("empty \"%s\" field", cap);
     wrap_concat(buffer);          value = "";
       } else if (limit > MAX_ALIAS) {
           _nc_warning("\"%s\" field too long (%d), limit to %d",
                       cap, limit, MAX_ALIAS);
           limit = MAX_ALIAS;
       }
       _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer))
                   "%s=%.*s", cap, limit, value);
       wrap_concat1(buffer);
 }  }
   
 int  int
 show_entry(void)  show_entry(void)
 {  {
     trim_trailing();      /*
     (void) fputs(outbuf.text, stdout);       * Trim any remaining whitespace.
     putchar('\n');       */
       if (outbuf.used != 0) {
           bool infodump = !TcOutput();
           char delim = (char) (infodump ? ',' : ':');
           int j;
   
           for (j = (int) outbuf.used - 1; j > 0; --j) {
               char ch = outbuf.text[j];
               if (ch == '\n') {
                   ;
               } else if (isspace(UChar(ch))) {
                   outbuf.used = (size_t) j;
               } else if (!infodump && ch == '\\') {
                   outbuf.used = (size_t) j;
               } else if (ch == delim && (outbuf.text[j - 1] != '\\')) {
                   outbuf.used = (size_t) (j + 1);
               } else {
                   break;
               }
           }
           outbuf.text[outbuf.used] = '\0';
       }
       if (outbuf.text != 0) {
           (void) fputs(outbuf.text, stdout);
           putchar('\n');
       }
     return (int) outbuf.used;      return (int) outbuf.used;
 }  }
   
 void  void
 compare_entry(void (*hook) (PredType t, PredIdx i, const char *name),  compare_entry(PredHook hook,
               TERMTYPE *tp GCC_UNUSED,                TERMTYPE2 *tp GCC_UNUSED,
               bool quiet)                bool quiet)
 /* compare two entries */  /* compare two entries */
 {  {
Line 1173 
Line 1723 
         fputs("    comparing booleans.\n", stdout);          fputs("    comparing booleans.\n", stdout);
     for_each_boolean(j, tp) {      for_each_boolean(j, tp) {
         i = BoolIndirect(j);          i = BoolIndirect(j);
         name = ExtBoolname(tp, i, bool_names);          name = ExtBoolname(tp, (int) i, bool_names);
   
         if (isObsolete(outform, name))          if (isObsolete(outform, name))
             continue;              continue;
Line 1185 
Line 1735 
         fputs("    comparing numbers.\n", stdout);          fputs("    comparing numbers.\n", stdout);
     for_each_number(j, tp) {      for_each_number(j, tp) {
         i = NumIndirect(j);          i = NumIndirect(j);
         name = ExtNumname(tp, i, num_names);          name = ExtNumname(tp, (int) i, num_names);
   
         if (isObsolete(outform, name))          if (isObsolete(outform, name))
             continue;              continue;
Line 1197 
Line 1747 
         fputs("    comparing strings.\n", stdout);          fputs("    comparing strings.\n", stdout);
     for_each_string(j, tp) {      for_each_string(j, tp) {
         i = StrIndirect(j);          i = StrIndirect(j);
         name = ExtStrname(tp, i, str_names);          name = ExtStrname(tp, (int) i, str_names);
   
         if (isObsolete(outform, name))          if (isObsolete(outform, name))
             continue;              continue;
Line 1221 
Line 1771 
 #define CUR tp->  #define CUR tp->
   
 static void  static void
 set_obsolete_termcaps(TERMTYPE *tp)  set_obsolete_termcaps(TERMTYPE2 *tp)
 {  {
 #include "capdefaults.c"  #include "capdefaults.c"
 }  }
Line 1231 
Line 1781 
  * unique.   * unique.
  */   */
 void  void
 repair_acsc(TERMTYPE *tp)  repair_acsc(TERMTYPE2 *tp)
 {  {
     if (VALID_STRING(acs_chars)) {      if (VALID_STRING(acs_chars)) {
         size_t n, m;          size_t n;
         char mapped[256];          char mapped[256];
         char extra = 0;  
         unsigned source;          unsigned source;
         unsigned target;          unsigned target;
         bool fix_needed = FALSE;          bool fix_needed = FALSE;
Line 1251 
Line 1800 
             if (acs_chars[n + 1])              if (acs_chars[n + 1])
                 n++;                  n++;
         }          }
   
         if (fix_needed) {          if (fix_needed) {
               size_t m;
               char extra = 0;
   
             memset(mapped, 0, sizeof(mapped));              memset(mapped, 0, sizeof(mapped));
             for (n = 0; acs_chars[n] != 0; n++) {              for (n = 0; acs_chars[n] != 0; n++) {
                 source = UChar(acs_chars[n]);                  source = UChar(acs_chars[n]);

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21