[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.18 and 1.19

version 1.18, 2003/04/06 21:12:07 version 1.19, 2010/01/12 23:22:14
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 /****************************************************************************  /****************************************************************************
  * Copyright (c) 1998-2000 Free Software Foundation, Inc.                   *   * Copyright (c) 1998-2007,2008 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 31 
Line 31 
 /****************************************************************************  /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *   *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *   *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
    *     and: Thomas E. Dickey                        1996 on                 *
  ****************************************************************************/   ****************************************************************************/
   
 #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.c"           /* this C file is generated */
 #include <parametrized.h>       /* so is this */  #include <parametrized.h>       /* so is this */
   
 MODULE_ID("$From: dump_entry.c,v 1.54 2000/10/01 01:34:06 tom Exp $")  MODULE_ID("$Id$")
   
 #define INDENT                  8  #define INDENT                  8
 #define DISCARD(string) string = ABSENT_STRING  #define DISCARD(string) string = ABSENT_STRING
 #define PRINTF (void) printf  #define PRINTF (void) printf
   
   #define OkIndex(index,array) ((int)(index) >= 0 && (int)(index) < (int) SIZEOF(array))
   
 typedef struct {  typedef struct {
     char *text;      char *text;
     size_t used;      size_t used;
Line 58 
Line 61 
 static int width = 60;          /* max line width for listings */  static int width = 60;          /* max line width 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 int tracelevel;          /* level of debug output */  
 static bool pretty;             /* true if we format if-then-else strings */  static bool pretty;             /* true if we format if-then-else strings */
   
   static char *save_sgr;
   
 static DYNBUF outbuf;  static DYNBUF outbuf;
 static DYNBUF tmpbuf;  static DYNBUF tmpbuf;
   
 /* indirection pointers for implementing sort and display modes */  /* indirection pointers for implementing sort and display modes */
 static const int *bool_indirect, *num_indirect, *str_indirect;  static const PredIdx *bool_indirect, *num_indirect, *str_indirect;
 static NCURSES_CONST char *const *bool_names;  static NCURSES_CONST char *const *bool_names;
 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;
Line 140 
Line 144 
 }  }
 #endif  #endif
   
   #define NameTrans(check,result) \
               if (OkIndex(np->nte_index, check) \
                   && check[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 from termcap to terminfo */
Line 149 
Line 158 
     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:
             if (bool_from_termcap[np->nte_index])              NameTrans(bool_from_termcap, boolcodes);
                 return (boolcodes[np->nte_index]);  
             break;              break;
   
         case NUMBER:          case NUMBER:
             if (num_from_termcap[np->nte_index])              NameTrans(num_from_termcap, numcodes);
                 return (numcodes[np->nte_index]);  
             break;              break;
   
         case STRING:          case STRING:
             if (str_from_termcap[np->nte_index])              NameTrans(str_from_termcap, strcodes);
                 return (strcodes[np->nte_index]);  
             break;              break;
         }          }
   
Line 169 
Line 175 
   
 void  void
 dump_init(const char *version, int mode, int sort, int twidth, int traceval,  dump_init(const char *version, int mode, int sort, int twidth, int traceval,
     bool formatted)            bool formatted)
 /* set up for entry display */  /* set up for entry display */
 {  {
     width = twidth;      width = twidth;
     pretty = formatted;      pretty = formatted;
     tracelevel = traceval;  
   
     /* versions */      /* versions */
     if (version == 0)      if (version == 0)
         tversion = V_ALLCAPS;          tversion = V_ALLCAPS;
     else if (!strcmp(version, "SVr1") || !strcmp(version, "SVR1")      else if (!strcmp(version, "SVr1") || !strcmp(version, "SVR1")
         || !strcmp(version, "Ultrix"))               || !strcmp(version, "Ultrix"))
         tversion = V_SVR1;          tversion = V_SVR1;
     else if (!strcmp(version, "HP"))      else if (!strcmp(version, "HP"))
         tversion = V_HPUX;          tversion = V_HPUX;
Line 225 
Line 230 
     case S_NOSORT:      case S_NOSORT:
         if (traceval)          if (traceval)
             (void) fprintf(stderr,              (void) fprintf(stderr,
                 "%s: sorting by term structure order\n", _nc_progname);                             "%s: sorting by term structure order\n", _nc_progname);
         break;          break;
   
     case S_TERMINFO:      case S_TERMINFO:
         if (traceval)          if (traceval)
             (void) fprintf(stderr,              (void) fprintf(stderr,
                 "%s: sorting by terminfo name order\n", _nc_progname);                             "%s: sorting by terminfo name order\n", _nc_progname);
         bool_indirect = bool_terminfo_sort;          bool_indirect = bool_terminfo_sort;
         num_indirect = num_terminfo_sort;          num_indirect = num_terminfo_sort;
         str_indirect = str_terminfo_sort;          str_indirect = str_terminfo_sort;
Line 240 
Line 245 
     case S_VARIABLE:      case S_VARIABLE:
         if (traceval)          if (traceval)
             (void) fprintf(stderr,              (void) fprintf(stderr,
                 "%s: sorting by C variable order\n", _nc_progname);                             "%s: sorting by C variable order\n", _nc_progname);
         bool_indirect = bool_variable_sort;          bool_indirect = bool_variable_sort;
         num_indirect = num_variable_sort;          num_indirect = num_variable_sort;
         str_indirect = str_variable_sort;          str_indirect = str_variable_sort;
Line 249 
Line 254 
     case S_TERMCAP:      case S_TERMCAP:
         if (traceval)          if (traceval)
             (void) fprintf(stderr,              (void) fprintf(stderr,
                 "%s: sorting by termcap name order\n", _nc_progname);                             "%s: sorting by termcap name order\n", _nc_progname);
         bool_indirect = bool_termcap_sort;          bool_indirect = bool_termcap_sort;
         num_indirect = num_termcap_sort;          num_indirect = num_termcap_sort;
         str_indirect = str_termcap_sort;          str_indirect = str_termcap_sort;
Line 258 
Line 263 
   
     if (traceval)      if (traceval)
         (void) fprintf(stderr,          (void) fprintf(stderr,
             "%s: width = %d, tversion = %d, outform = %d\n",                         "%s: width = %d, tversion = %d, outform = %d\n",
             _nc_progname, width, tversion, outform);                         _nc_progname, width, tversion, outform);
 }  }
   
 static TERMTYPE *cur_type;  static TERMTYPE *cur_type;
   
 static int  static int
 dump_predicate(int type, int idx)  dump_predicate(PredType type, PredIdx idx)
 /* predicate function to use for ordinary decompilation */  /* predicate function to use for ordinary decompilation */
 {  {
     switch (type) {      switch (type) {
Line 285 
Line 290 
     return (FALSE);             /* pacify compiler */      return (FALSE);             /* pacify compiler */
 }  }
   
 static void set_obsolete_termcaps(TERMTYPE * tp);  static void set_obsolete_termcaps(TERMTYPE *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)<= 65 && (i)>= 75) || ((i)<= 216 && (i)>= 268))
   
   /*
    * If we configure with a different Caps file, the offsets into the arrays
    * will change.  So we use an address expression.
    */
   #define BOOL_IDX(name) (PredType) (&(name) - &(CUR Booleans[0]))
   #define NUM_IDX(name)  (PredType) (&(name) - &(CUR Numbers[0]))
   #define STR_IDX(name)  (PredType) (&(name) - &(CUR Strings[0]))
   
 static bool  static bool
 version_filter(int type, int idx)  version_filter(PredType type, PredIdx idx)
 /* filter out capabilities we may want to suppress */  /* filter out capabilities we may want to suppress */
 {  {
     switch (tversion) {      switch (tversion) {
Line 301 
Line 314 
     case V_SVR1:                /* System V Release 1, Ultrix */      case V_SVR1:                /* System V Release 1, Ultrix */
         switch (type) {          switch (type) {
         case BOOLEAN:          case BOOLEAN:
             /* below and including xon_xoff */              return ((idx <= BOOL_IDX(xon_xoff)) ? TRUE : FALSE);
             return ((idx <= 20) ? TRUE : FALSE);  
         case NUMBER:          case NUMBER:
             /* below and including width_status_line */              return ((idx <= NUM_IDX(width_status_line)) ? TRUE : FALSE);
             return ((idx <= 7) ? TRUE : FALSE);  
         case STRING:          case STRING:
             /* below and including prtr_non */              return ((idx <= STR_IDX(prtr_non)) ? TRUE : FALSE);
             return ((idx <= 144) ? TRUE : FALSE);  
         }          }
         break;          break;
   
     case V_HPUX:                /* Hewlett-Packard */      case V_HPUX:                /* Hewlett-Packard */
         switch (type) {          switch (type) {
         case BOOLEAN:          case BOOLEAN:
             /* below and including xon_xoff */              return ((idx <= BOOL_IDX(xon_xoff)) ? TRUE : FALSE);
             return ((idx <= 20) ? TRUE : FALSE);  
         case NUMBER:          case NUMBER:
             /* below and including label_width */              return ((idx <= NUM_IDX(label_width)) ? TRUE : FALSE);
             return ((idx <= 10) ? TRUE : FALSE);  
         case STRING:          case STRING:
             if (idx <= 144)     /* below and including prtr_non */              if (idx <= STR_IDX(prtr_non))
                 return (TRUE);                  return (TRUE);
             else if (FNKEY(idx))        /* function keys */              else if (FNKEY(idx))        /* function keys */
                 return (TRUE);                  return (TRUE);
             else if (idx == 147 || idx == 156 || idx == 157)    /* plab_norm,label_on,label_off */              else if (idx == STR_IDX(plab_norm)
                        || idx == STR_IDX(label_on)
                        || idx == STR_IDX(label_off))
                 return (TRUE);                  return (TRUE);
             else              else
                 return (FALSE);                  return (FALSE);
Line 335 
Line 345 
     case V_AIX:         /* AIX */      case V_AIX:         /* AIX */
         switch (type) {          switch (type) {
         case BOOLEAN:          case BOOLEAN:
             /* below and including xon_xoff */              return ((idx <= BOOL_IDX(xon_xoff)) ? TRUE : FALSE);
             return ((idx <= 20) ? TRUE : FALSE);  
         case NUMBER:          case NUMBER:
             /* below and including width_status_line */              return ((idx <= NUM_IDX(width_status_line)) ? TRUE : FALSE);
             return ((idx <= 7) ? TRUE : FALSE);  
         case STRING:          case STRING:
             if (idx <= 144)     /* below and including prtr_non */              if (idx <= STR_IDX(prtr_non))
                 return (TRUE);                  return (TRUE);
             else if (FNKEY(idx))        /* function keys */              else if (FNKEY(idx))        /* function keys */
                 return (TRUE);                  return (TRUE);
Line 350 
Line 358 
         }          }
         break;          break;
   
   #define is_termcap(type) (OkIndex(idx, type##_from_termcap) && \
                             type##_from_termcap[idx])
   
     case V_BSD:         /* BSD */      case V_BSD:         /* BSD */
         switch (type) {          switch (type) {
         case BOOLEAN:          case BOOLEAN:
             return bool_from_termcap[idx];              return is_termcap(bool);
         case NUMBER:          case NUMBER:
             return num_from_termcap[idx];              return is_termcap(num);
         case STRING:          case STRING:
             return str_from_termcap[idx];              return is_termcap(str);
         }          }
         break;          break;
     }      }
Line 366 
Line 377 
 }  }
   
 static void  static void
   trim_trailing(void)
   {
       while (outbuf.used > 0 && outbuf.text[outbuf.used - 1] == ' ')
           outbuf.text[--outbuf.used] = '\0';
   }
   
   static void
 force_wrap(void)  force_wrap(void)
 {  {
     oldcol = column;      oldcol = column;
       trim_trailing();
     strcpy_DYN(&outbuf, trailer);      strcpy_DYN(&outbuf, trailer);
     column = INDENT;      column = INDENT;
 }  }
Line 376 
Line 395 
 static void  static void
 wrap_concat(const char *src)  wrap_concat(const char *src)
 {  {
     int need = strlen(src);      unsigned need = strlen(src);
     int want = strlen(separator) + need;      unsigned want = strlen(separator) + need;
   
     if (column > INDENT      if (column > INDENT
         && column + want > width) {          && column + (int) want > width) {
         force_wrap();          force_wrap();
     }      }
     strcpy_DYN(&outbuf, src);      strcpy_DYN(&outbuf, src);
     strcpy_DYN(&outbuf, separator);      strcpy_DYN(&outbuf, separator);
     column += need;      column += (int) need;
 }  }
   
 #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)) \
                 first += sizeof(sep_trail)-2                  first += sizeof(sep_trail)-2
   
 /* Returns the nominal length of the buffer assuming it is termcap format,  /* Returns the nominal length of the buffer assuming it is termcap format,
  * i.e., the continuation sequence is treated as a single character ":".   * i.e., the continuation sequence is treated as a single character ":".
Line 422 
Line 441 
 #define termcap_length(src) strlen(src)  #define termcap_length(src) strlen(src)
 #endif  #endif
   
   static void
   indent_DYN(DYNBUF * buffer, int level)
   {
       int n;
   
       for (n = 0; n < level; n++)
           strncpy_DYN(buffer, "\t", 1);
   }
   
   static bool
   has_params(const char *src)
   {
       bool result = FALSE;
       int len = (int) strlen(src);
       int n;
       bool ifthen = FALSE;
       bool params = FALSE;
   
       for (n = 0; n < len - 1; ++n) {
           if (!strncmp(src + n, "%p", 2)) {
               params = TRUE;
           } else if (!strncmp(src + n, "%;", 2)) {
               ifthen = TRUE;
               result = params;
               break;
           }
       }
       if (!ifthen) {
           result = ((len > 50) && params);
       }
       return result;
   }
   
 static char *  static char *
 fmt_complex(char *src, int level)  fmt_complex(char *src, int level)
 {  {
     int percent = 0;      bool percent = FALSE;
     int n;      bool params = has_params(src);
     bool if_then = strstr(src, "%?") != 0;  
     bool params = !if_then && (strlen(src) > 50) && (strstr(src, "%p") != 0);  
   
     while (*src != '\0') {      while (*src != '\0') {
         switch (*src) {          switch (*src) {
         case '\\':          case '\\':
             percent = 0;              percent = FALSE;
             strncpy_DYN(&tmpbuf, src++, 1);              strncpy_DYN(&tmpbuf, src++, 1);
             break;              break;
         case '%':          case '%':
             percent = 1;              percent = TRUE;
             break;              break;
         case '?':               /* "if" */          case '?':               /* "if" */
         case 't':               /* "then" */          case 't':               /* "then" */
         case 'e':               /* "else" */          case 'e':               /* "else" */
             if (percent) {              if (percent) {
                 percent = 0;                  percent = FALSE;
                 tmpbuf.text[tmpbuf.used - 1] = '\n';                  tmpbuf.text[tmpbuf.used - 1] = '\n';
                 /* treat a "%e%?" as else-if, on the same level */                  /* treat a "%e" as else-if, on the same level */
                 if (!strncmp(src, "e%?", 3)) {                  if (*src == 'e') {
                     for (n = 0; n < level; n++)                      indent_DYN(&tmpbuf, level);
                         strncpy_DYN(&tmpbuf, "\t", 1);  
                     strncpy_DYN(&tmpbuf, "%", 1);                      strncpy_DYN(&tmpbuf, "%", 1);
                     strncpy_DYN(&tmpbuf, src, 3);                      strncpy_DYN(&tmpbuf, src, 1);
                     src += 3;                      src++;
                       params = has_params(src);
                       if (!params && *src != '\0' && *src != '%') {
                           strncpy_DYN(&tmpbuf, "\n", 1);
                           indent_DYN(&tmpbuf, level + 1);
                       }
                 } else {                  } else {
                     for (n = 0; n <= level; n++)                      indent_DYN(&tmpbuf, level + 1);
                         strncpy_DYN(&tmpbuf, "\t", 1);  
                     strncpy_DYN(&tmpbuf, "%", 1);                      strncpy_DYN(&tmpbuf, "%", 1);
                     strncpy_DYN(&tmpbuf, src, 1);                      strncpy_DYN(&tmpbuf, src, 1);
                     if (*src++ == '?') {                      if (*src++ == '?') {
                         src = fmt_complex(src, level + 1);                          src = fmt_complex(src, level + 1);
                           if (*src != '\0' && *src != '%') {
                               strncpy_DYN(&tmpbuf, "\n", 1);
                               indent_DYN(&tmpbuf, level + 1);
                           }
                     } else if (level == 1) {                      } else if (level == 1) {
                         _nc_warning("%%%c without %%?", *src);                          _nc_warning("%%%c without %%?", *src);
                     }                      }
Line 468 
Line 525 
             break;              break;
         case ';':               /* "endif" */          case ';':               /* "endif" */
             if (percent) {              if (percent) {
                 percent = 0;                  percent = FALSE;
                 if (level > 1) {                  if (level > 1) {
                     tmpbuf.text[tmpbuf.used - 1] = '\n';                      tmpbuf.text[tmpbuf.used - 1] = '\n';
                     for (n = 0; n < level; n++)                      indent_DYN(&tmpbuf, level);
                         strncpy_DYN(&tmpbuf, "\t", 1);  
                     strncpy_DYN(&tmpbuf, "%", 1);                      strncpy_DYN(&tmpbuf, "%", 1);
                     strncpy_DYN(&tmpbuf, src++, 1);                      strncpy_DYN(&tmpbuf, src++, 1);
                     return src;                      return src;
Line 483 
Line 539 
         case 'p':          case 'p':
             if (percent && params) {              if (percent && params) {
                 tmpbuf.text[tmpbuf.used - 1] = '\n';                  tmpbuf.text[tmpbuf.used - 1] = '\n';
                 for (n = 0; n <= level; n++)                  indent_DYN(&tmpbuf, level + 1);
                     strncpy_DYN(&tmpbuf, "\t", 1);  
                 strncpy_DYN(&tmpbuf, "%", 1);                  strncpy_DYN(&tmpbuf, "%", 1);
             }              }
             percent = 0;              params = FALSE;
               percent = FALSE;
             break;              break;
           case ' ':
               strncpy_DYN(&tmpbuf, "\\s", 2);
               ++src;
               continue;
         default:          default:
             percent = 0;              percent = FALSE;
             break;              break;
         }          }
         strncpy_DYN(&tmpbuf, src++, 1);          strncpy_DYN(&tmpbuf, src++, 1);
Line 498 
Line 558 
     return src;      return src;
 }  }
   
   #define SAME_CAP(n,cap) (&tterm->Strings[n] == &cap)
   #define EXTRA_CAP 20
   
 int  int
 fmt_entry(TERMTYPE * tterm,  fmt_entry(TERMTYPE *tterm,
     int (*pred) (int type, int idx),            PredFunc pred,
     bool suppress_untranslatable,            bool content_only,
     bool infodump,            bool suppress_untranslatable,
     int numbers)            bool infodump,
             int numbers)
 {  {
     int i, j;      PredIdx i, j;
     char buffer[MAX_TERMINFO_LENGTH];      char buffer[MAX_TERMINFO_LENGTH + EXTRA_CAP];
       char *capability;
     NCURSES_CONST char *name;      NCURSES_CONST char *name;
     int predval, len;      int predval, len;
     int num_bools = 0;      PredIdx num_bools = 0;
     int num_values = 0;      PredIdx num_values = 0;
     int num_strings = 0;      PredIdx num_strings = 0;
     bool outcount = 0;      bool outcount = 0;
   
 #define WRAP_CONCAT     \  #define WRAP_CONCAT     \
Line 526 
Line 591 
     }      }
   
     strcpy_DYN(&outbuf, 0);      strcpy_DYN(&outbuf, 0);
     strcpy_DYN(&outbuf, tterm->term_names);      if (content_only) {
     strcpy_DYN(&outbuf, separator);          column = INDENT;        /* FIXME: workaround to prevent empty lines */
     column = outbuf.used;      } else {
     force_wrap();          strcpy_DYN(&outbuf, tterm->term_names);
           strcpy_DYN(&outbuf, separator);
           column = (int) outbuf.used;
           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, i, bool_names);
           assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
   
         if (!version_filter(BOOLEAN, i))          if (!version_filter(BOOLEAN, i))
             continue;              continue;
Line 557 
Line 627 
     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, i, num_names);
           assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
   
         if (!version_filter(NUMBER, i))          if (!version_filter(NUMBER, i))
             continue;              continue;
Line 579 
Line 650 
     if (column != INDENT)      if (column != INDENT)
         force_wrap();          force_wrap();
   
     len += num_bools      len += (int) (num_bools
         + num_values * 2                    + num_values * 2
         + strlen(tterm->term_names) + 1;                    + strlen(tterm->term_names) + 1);
     if (len & 1)      if (len & 1)
         len++;          len++;
   
Line 602 
Line 673 
     for_each_string(j, tterm) {      for_each_string(j, tterm) {
         i = StrIndirect(j);          i = StrIndirect(j);
         name = ExtStrname(tterm, i, str_names);          name = ExtStrname(tterm, i, str_names);
           assert(strlen(name) < sizeof(buffer) - EXTRA_CAP);
   
           capability = tterm->Strings[i];
   
         if (!version_filter(STRING, i))          if (!version_filter(STRING, i))
             continue;              continue;
         else if (isObsolete(outform, name))          else if (isObsolete(outform, name))
             continue;              continue;
   
   #if NCURSES_XNAMES
         /*          /*
          * Some older versions of vi want rmir/smir to be defined           * Extended names can be longer than 2 characters, but termcap programs
          * for ich/ich1 to work.  If they're not defined, force           * cannot read those (filter them out).
          * them to be output as defined and empty.  
          */           */
           if (outform == F_TERMCAP && (strlen(name) > 2))
               continue;
   #endif
   
         if (outform == F_TERMCAP) {          if (outform == F_TERMCAP) {
             if (insert_character || parm_ich) {              /*
                 if (&tterm->Strings[i] == &enter_insert_mode               * Some older versions of vi want rmir/smir to be defined
                * for ich/ich1 to work.  If they're not defined, force
                * them to be output as defined and empty.
                */
               if (PRESENT(insert_character) || PRESENT(parm_ich)) {
                   if (SAME_CAP(i, enter_insert_mode)
                     && enter_insert_mode == ABSENT_STRING) {                      && enter_insert_mode == ABSENT_STRING) {
                     (void) strlcpy(buffer, "im=", sizeof buffer);                      (void) strlcpy(buffer, "im=", sizeof(buffer));
                     WRAP_CONCAT;                      WRAP_CONCAT;
                     continue;                      continue;
                 }                  }
   
                 if (&tterm->Strings[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);                          (void) strlcpy(buffer, "ei=", sizeof(buffer));
                     WRAP_CONCAT;                      WRAP_CONCAT;
                     continue;                      continue;
                 }                  }
             }              }
               /*
                * termcap applications such as screen will be confused if sgr0
                * is translated to a string containing rmacs.  Filter that out.
                */
               if (PRESENT(exit_attribute_mode)) {
                   if (SAME_CAP(i, exit_attribute_mode)) {
                       char *trimmed_sgr0;
                       char *my_sgr = set_attributes;
   
                       set_attributes = save_sgr;
   
                       trimmed_sgr0 = _nc_trim_sgr0(tterm);
                       if (strcmp(capability, trimmed_sgr0))
                           capability = trimmed_sgr0;
   
                       set_attributes = my_sgr;
                   }
               }
         }          }
   
         predval = pred(STRING, i);          predval = pred(STRING, i);
         buffer[0] = '\0';          buffer[0] = '\0';
   
         if (predval != FAIL) {          if (predval != FAIL) {
             if (tterm->Strings[i] != ABSENT_STRING              if (capability != ABSENT_STRING
                 && i + 1 > num_strings)                  && i + 1 > num_strings)
                 num_strings = i + 1;                  num_strings = i + 1;
   
             if (!VALID_STRING(tterm->Strings[i])) {              if (!VALID_STRING(capability)) {
                 snprintf(buffer, sizeof buffer, "%s@", name);                  snprintf(buffer, sizeof(buffer), "%s@", name);
                 WRAP_CONCAT;                  WRAP_CONCAT;
             } else if (outform == F_TERMCAP || outform == F_TCONVERR) {              } else if (outform == F_TERMCAP || outform == F_TCONVERR) {
                 int params = (i < (int) SIZEOF(parametrized)) ? parametrized[i] : 0;                  int params = ((i < (int) SIZEOF(parametrized))
                 char *srccap = _nc_tic_expand(tterm->Strings[i], TRUE, numbers);                                ? parametrized[i]
                                 : 0);
                   char *srccap = _nc_tic_expand(capability, TRUE, numbers);
                 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,                          snprintf(buffer, sizeof(buffer),
                             "%s=!!! %s WILL NOT CONVERT !!!",                              "%s=!!! %s WILL NOT CONVERT !!!", name, srccap);
                             name, srccap);  
                     } else if (suppress_untranslatable) {                      } else if (suppress_untranslatable) {
                         continue;                          continue;
                     } else {                      } else {
                         char *d, *s = srccap;                          char *d, *s = srccap;
                         snprintf(buffer, sizeof buffer, "..%s=", name);                          snprintf(buffer, sizeof(buffer), "..%s=", name);
                         d = buffer + strlen(buffer);                          d = buffer + strlen(buffer);
                         while ((*d = *s++) != 0) {      /* XXX overflow? */                          while ((*d = *s++) != 0) {      /* XXX overflow */
                             if (*d == ':') {                              if (*d == ':') {
                                 *d++ = '\\';                                  *d++ = '\\';
                                 *d = ':';                                  *d = ':';
Line 671 
Line 773 
                 } else {                  } else {
                     snprintf(buffer, sizeof buffer, "%s=%s", name, cv);                      snprintf(buffer, sizeof buffer, "%s=%s", name, cv);
                 }                  }
                 len += strlen(tterm->Strings[i]) + 1;                  len += (int) strlen(capability) + 1;
                 WRAP_CONCAT;                  WRAP_CONCAT;
             } else {              } else {
                 char *src = _nc_tic_expand(tterm->Strings[i],                  char *src = _nc_tic_expand(capability,
                     outform == F_TERMINFO, numbers);                                             outform == F_TERMINFO, numbers);
   
                 strcpy_DYN(&tmpbuf, 0);                  strcpy_DYN(&tmpbuf, 0);
                 strcpy_DYN(&tmpbuf, name);                  strcpy_DYN(&tmpbuf, name);
Line 687 
Line 789 
                 } else {                  } else {
                     strcpy_DYN(&tmpbuf, src);                      strcpy_DYN(&tmpbuf, src);
                 }                  }
                 len += strlen(tterm->Strings[i]) + 1;                  len += (int) strlen(capability) + 1;
                 wrap_concat(tmpbuf.text);                  wrap_concat(tmpbuf.text);
                 outcount = TRUE;                  outcount = TRUE;
             }              }
         }          }
           /* e.g., trimmed_sgr0 */
           if (capability != tterm->Strings[i])
               free(capability);
     }      }
     len += num_strings * 2;      len += (int) (num_strings * 2);
   
     /*      /*
      * This piece of code should be an effective inverse of the functions       * This piece of code should be an effective inverse of the functions
      * postprocess_terminfo and postprocess_terminfo in parse_entry.c.       * postprocess_terminfo() and postprocess_terminfo() in parse_entry.c.
      * Much more work should be done on this to support dumping termcaps.       * Much more work should be done on this to support dumping termcaps.
      */       */
     if (tversion == V_HPUX) {      if (tversion == V_HPUX) {
         if (memory_lock) {          if (VALID_STRING(memory_lock)) {
             (void) snprintf(buffer, sizeof buffer, "meml=%s", memory_lock);              (void) snprintf(buffer, sizeof(buffer), "meml=%s", memory_lock);
             WRAP_CONCAT;              WRAP_CONCAT;
         }          }
         if (memory_unlock) {          if (VALID_STRING(memory_unlock)) {
             (void) snprintf(buffer, sizeof buffer, "memu=%s", memory_unlock);              (void) snprintf(buffer, sizeof(buffer), "memu=%s", memory_unlock);
             WRAP_CONCAT;              WRAP_CONCAT;
         }          }
     } else if (tversion == V_AIX) {      } else if (tversion == V_AIX) {
Line 729 
Line 834 
             tp[0] = '\0';              tp[0] = '\0';
   
             if (box_ok) {              if (box_ok) {
                 (void) strlcpy(buffer, "box1=", sizeof buffer);                  (void) strlcpy(buffer, "box1=", sizeof(buffer));
                 (void) strlcat(buffer, _nc_tic_expand(boxchars,                  (void) strlcat(buffer, _nc_tic_expand(boxchars,
                         outform == F_TERMINFO, numbers), sizeof buffer);                      outform == F_TERMINFO, numbers), sizeof(buffer));
                 WRAP_CONCAT;                  WRAP_CONCAT;
             }              }
         }          }
Line 750 
Line 855 
             outbuf.used -= 2;              outbuf.used -= 2;
             trimmed = TRUE;              trimmed = TRUE;
         } else if (j >= 4          } else if (j >= 4
                 && outbuf.text[j - 1] == ':'                     && outbuf.text[j - 1] == ':'
                 && outbuf.text[j - 2] == '\t'                     && outbuf.text[j - 2] == '\t'
                 && outbuf.text[j - 3] == '\n'                     && outbuf.text[j - 3] == '\n'
             && outbuf.text[j - 4] == '\\') {                     && outbuf.text[j - 4] == '\\') {
             outbuf.used -= 4;              outbuf.used -= 4;
             trimmed = TRUE;              trimmed = TRUE;
         }          }
         if (trimmed) {          if (trimmed) {
             outbuf.text[outbuf.used] = '\0';              outbuf.text[outbuf.used] = '\0';
             column = oldcol;              column = oldcol;
               strcpy_DYN(&outbuf, " ");
         }          }
     }      }
 #if 0  #if 0
Line 767 
Line 873 
     fprintf(stderr, "num_values = %d\n", num_values);      fprintf(stderr, "num_values = %d\n", num_values);
     fprintf(stderr, "num_strings = %d\n", num_strings);      fprintf(stderr, "num_strings = %d\n", num_strings);
     fprintf(stderr, "term_names=%s, len=%d, strlen(outbuf)=%d, outbuf=%s\n",      fprintf(stderr, "term_names=%s, len=%d, strlen(outbuf)=%d, outbuf=%s\n",
         tterm->term_names, len, outbuf.used, outbuf.text);              tterm->term_names, len, outbuf.used, outbuf.text);
 #endif  #endif
     /*      /*
      * Here's where we use infodump to trigger a more stringent length check       * Here's where we use infodump to trigger a more stringent length check
Line 776 
Line 882 
      * It gives an idea of which entries are deadly to even *scan past*,       * It gives an idea of which entries are deadly to even *scan past*,
      * as opposed to *use*.       * as opposed to *use*.
      */       */
     return (infodump ? len : termcap_length(outbuf.text));      return (infodump ? len : (int) termcap_length(outbuf.text));
 }  }
   
 int  static bool
 dump_entry(TERMTYPE * tterm, bool limited, int numbers, int (*pred) (int  kill_string(TERMTYPE *tterm, char *cap)
         type, int idx))  
 /* dump a single entry */  
 {  {
       unsigned n;
       for (n = 0; n < NUM_STRINGS(tterm); ++n) {
           if (cap == tterm->Strings[n]) {
               tterm->Strings[n] = ABSENT_STRING;
               return TRUE;
           }
       }
       return FALSE;
   }
   
   static char *
   find_string(TERMTYPE *tterm, char *name)
   {
       PredIdx n;
       for (n = 0; n < NUM_STRINGS(tterm); ++n) {
           if (version_filter(STRING, n)
               && !strcmp(name, strnames[n])) {
               char *cap = tterm->Strings[n];
               if (VALID_STRING(cap)) {
                   return cap;
               }
               break;
           }
       }
       return ABSENT_STRING;
   }
   
   /*
    * This is used to remove function-key labels from a termcap entry to
    * make it smaller.
    */
   static int
   kill_labels(TERMTYPE *tterm, int target)
   {
       int n;
       int result = 0;
       char *cap;
       char name[10];
   
       for (n = 0; n <= 10; ++n) {
           snprintf(name, sizeof(name), "lf%d", n);
           if ((cap = find_string(tterm, name)) != ABSENT_STRING
               && kill_string(tterm, cap)) {
               target -= (int) (strlen(cap) + 5);
               ++result;
               if (target < 0)
                   break;
           }
       }
       return result;
   }
   
   /*
    * This is used to remove function-key definitions from a termcap entry to
    * make it smaller.
    */
   static int
   kill_fkeys(TERMTYPE *tterm, int target)
   {
       int n;
       int result = 0;
       char *cap;
       char name[10];
   
       for (n = 60; n >= 0; --n) {
           snprintf(name, sizeof(name), "kf%d", n);
           if ((cap = find_string(tterm, name)) != ABSENT_STRING
               && kill_string(tterm, cap)) {
               target -= (int) (strlen(cap) + 5);
               ++result;
               if (target < 0)
                   break;
           }
       }
       return result;
   }
   
   /*
    * Check if the given acsc string is a 1-1 mapping, i.e., just-like-vt100.
    * Also, since this is for termcap, we only care about the line-drawing map.
    */
   #define isLine(c) (strchr("lmkjtuvwqxn", c) != 0)
   
   static bool
   one_one_mapping(const char *mapping)
   {
       bool result = TRUE;
   
       if (mapping != ABSENT_STRING) {
           int n = 0;
           while (mapping[n] != '\0') {
               if (isLine(mapping[n]) &&
                   mapping[n] != mapping[n + 1]) {
                   result = FALSE;
                   break;
               }
               n += 2;
           }
       }
       return result;
   }
   
   #define FMT_ENTRY() \
                   fmt_entry(tterm, pred, \
                           0, \
                           suppress_untranslatable, \
                           infodump, numbers)
   
   #define SHOW_WHY PRINTF
   
   static bool
   purged_acs(TERMTYPE *tterm)
   {
       bool result = FALSE;
   
       if (VALID_STRING(acs_chars)) {
           if (!one_one_mapping(acs_chars)) {
               enter_alt_charset_mode = ABSENT_STRING;
               exit_alt_charset_mode = ABSENT_STRING;
               SHOW_WHY("# (rmacs/smacs removed for consistency)\n");
           }
           result = TRUE;
       }
       return result;
   }
   
   /*
    * Dump a single entry.
    */
   void
   dump_entry(TERMTYPE *tterm,
              bool suppress_untranslatable,
              bool limited,
              int numbers,
              PredFunc pred)
   {
       TERMTYPE save_tterm;
     int len, critlen;      int len, critlen;
     const char *legend;      const char *legend;
     bool infodump;      bool infodump;
Line 799 
Line 1040 
         infodump = TRUE;          infodump = TRUE;
     }      }
   
     if (((len = fmt_entry(tterm, pred, FALSE, infodump, numbers)) > critlen)      save_sgr = set_attributes;
   
       if (((len = FMT_ENTRY()) > critlen)
         && limited) {          && limited) {
         PRINTF("# (untranslatable capabilities removed to fit entry within %d bytes)\n",  
             critlen);          save_tterm = *tterm;
         if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers)) > critlen) {          if (!suppress_untranslatable) {
               SHOW_WHY("# (untranslatable capabilities removed to fit entry within %d bytes)\n",
                        critlen);
               suppress_untranslatable = TRUE;
           }
           if ((len = FMT_ENTRY()) > critlen) {
             /*              /*
              * We pick on sgr because it's a nice long string capability that               * We pick on sgr because it's 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.
              */               */
             char *oldsgr = set_attributes;              bool changed = FALSE;
             char *oldacsc = acs_chars;  
             set_attributes = ABSENT_STRING;  #if NCURSES_XNAMES
             PRINTF("# (sgr removed to fit entry within %d bytes)\n",              /*
                 critlen);               * Extended names are most likely function-key definitions.  Drop
             if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers)) > critlen) {               * those first.
                 acs_chars = ABSENT_STRING;               */
                 PRINTF("# (acsc removed to fit entry within %d bytes)\n",              unsigned n;
                     critlen);              for (n = STRCOUNT; n < NUM_STRINGS(tterm); n++) {
                   const char *name = ExtStrname(tterm, n, strnames);
   
                   if (VALID_STRING(tterm->Strings[n])) {
                       set_attributes = ABSENT_STRING;
                       /* we remove long names anyway - only report the short */
                       if (strlen(name) <= 2) {
                           SHOW_WHY("# (%s removed to fit entry within %d bytes)\n",
                                    name,
                                    critlen);
                       }
                       changed = TRUE;
                       if ((len = FMT_ENTRY()) <= critlen)
                           break;
                   }
             }              }
             if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers)) > critlen) {  #endif
               if (VALID_STRING(set_attributes)) {
                   set_attributes = ABSENT_STRING;
                   SHOW_WHY("# (sgr removed to fit entry within %d bytes)\n",
                            critlen);
                   changed = TRUE;
               }
               if (!changed || ((len = FMT_ENTRY()) > critlen)) {
                   if (purged_acs(tterm)) {
                       acs_chars = ABSENT_STRING;
                       SHOW_WHY("# (acsc removed to fit entry within %d bytes)\n",
                                critlen);
                       changed = TRUE;
                   }
               }
               if (!changed || ((len = FMT_ENTRY()) > critlen)) {
                 int oldversion = tversion;                  int oldversion = tversion;
   
                 tversion = V_BSD;                  tversion = V_BSD;
                 PRINTF("# (terminfo-only capabilities suppressed to fit entry within %d bytes)\n",                  SHOW_WHY("# (terminfo-only capabilities suppressed to fit entry within %d bytes)\n",
                     critlen);                           critlen);
   
                 if ((len = fmt_entry(tterm, pred, TRUE, infodump, numbers))                  len = FMT_ENTRY();
                     > critlen) {                  if (len > critlen
                       && kill_labels(tterm, len - critlen)) {
                       SHOW_WHY("# (some labels capabilities suppressed to fit entry within %d bytes)\n",
                                critlen);
                       len = FMT_ENTRY();
                   }
                   if (len > critlen
                       && kill_fkeys(tterm, len - critlen)) {
                       SHOW_WHY("# (some function-key capabilities suppressed to fit entry within %d bytes)\n",
                                critlen);
                       len = FMT_ENTRY();
                   }
                   if (len > critlen) {
                     (void) fprintf(stderr,                      (void) fprintf(stderr,
                         "warning: %s entry is %d bytes long\n",                                     "warning: %s entry is %d bytes long\n",
                         _nc_first_name(tterm->term_names),                                     _nc_first_name(tterm->term_names),
                         len);                                     len);
                     PRINTF(                      SHOW_WHY("# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n",
                         "# WARNING: this entry, %d bytes long, may core-dump %s libraries!\n",                               len, legend);
                         len, legend);  
                 }                  }
                 tversion = oldversion;                  tversion = oldversion;
             }              }
             set_attributes = oldsgr;              set_attributes = save_sgr;
             acs_chars = oldacsc;              *tterm = save_tterm;
         }          }
       } else if (!version_filter(STRING, STR_IDX(acs_chars))) {
           save_tterm = *tterm;
           if (purged_acs(tterm)) {
               len = FMT_ENTRY();
           }
           *tterm = save_tterm;
     }      }
   
     (void) fputs(outbuf.text, stdout);  
     return len;  
 }  }
   
 int  void
 dump_uses(const char *name, bool infodump)  dump_uses(const char *name, 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];
   
     strcpy_DYN(&outbuf, 0);      if (outform == F_TERMCAP || outform == F_TCONVERR)
     (void) snprintf(buffer, sizeof buffer,          trim_trailing();
         "%s%s", infodump ? "use=" : "tc=", name);      (void) snprintf(buffer, sizeof(buffer), "%s%s", infodump ? "use=" : "tc=",
           name);
     wrap_concat(buffer);      wrap_concat(buffer);
   }
   
   int
   show_entry(void)
   {
       trim_trailing();
     (void) fputs(outbuf.text, stdout);      (void) fputs(outbuf.text, stdout);
     return outbuf.used;      putchar('\n');
       return (int) outbuf.used;
 }  }
   
 void  void
 compare_entry(void (*hook) (int t, int i, const char *name), TERMTYPE * tp  compare_entry(void (*hook) (PredType t, PredIdx i, const char *name),
     GCC_UNUSED, bool quiet)                TERMTYPE *tp GCC_UNUSED,
                 bool quiet)
 /* compare two entries */  /* compare two entries */
 {  {
     int i, j;      PredIdx i, j;
     NCURSES_CONST char *name;      NCURSES_CONST char *name;
   
     if (!quiet)      if (!quiet)
Line 921 
Line 1221 
 #define CUR tp->  #define CUR tp->
   
 static void  static void
 set_obsolete_termcaps(TERMTYPE * tp)  set_obsolete_termcaps(TERMTYPE *tp)
 {  {
 #include "capdefaults.c"  #include "capdefaults.c"
 }  }
Line 931 
Line 1231 
  * unique.   * unique.
  */   */
 void  void
 repair_acsc(TERMTYPE * tp)  repair_acsc(TERMTYPE *tp)
 {  {
     if (VALID_STRING(acs_chars)) {      if (VALID_STRING(acs_chars)) {
         size_t n, m;          size_t n, m;
Line 942 
Line 1242 
         bool fix_needed = FALSE;          bool fix_needed = FALSE;
   
         for (n = 0, source = 0; acs_chars[n] != 0; n++) {          for (n = 0, source = 0; acs_chars[n] != 0; n++) {
             target = acs_chars[n];              target = UChar(acs_chars[n]);
             if (source >= target) {              if (source >= target) {
                 fix_needed = TRUE;                  fix_needed = TRUE;
                 break;                  break;
Line 954 
Line 1254 
         if (fix_needed) {          if (fix_needed) {
             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 = acs_chars[n];                  source = UChar(acs_chars[n]);
                 if ((target = (unsigned char) acs_chars[n + 1]) != 0) {                  if ((target = (unsigned char) acs_chars[n + 1]) != 0) {
                     mapped[source] = target;                      mapped[source] = (char) target;
                     n++;                      n++;
                 } else {                  } else {
                     extra = source;                      extra = (char) source;
                 }                  }
             }              }
             for (n = m = 0; n < sizeof(mapped); n++) {              for (n = m = 0; n < sizeof(mapped); n++) {
                 if (mapped[n]) {                  if (mapped[n]) {
                     acs_chars[m++] = n;                      acs_chars[m++] = (char) n;
                     acs_chars[m++] = mapped[n];                      acs_chars[m++] = mapped[n];
                 }                  }
             }              }

Legend:
Removed from v.1.18  
changed lines
  Added in v.1.19