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

Diff for /src/usr.bin/tic/tic.c between version 1.13 and 1.14

version 1.13, 1999/12/06 02:14:34 version 1.14, 1999/12/12 04:49:19
Line 1 
Line 1 
 /*      $OpenBSD$       */  
   
 /****************************************************************************  /****************************************************************************
  * Copyright (c) 1998,1999 Free Software Foundation, Inc.                   *   * Copyright (c) 1998,1999 Free Software Foundation, Inc.                   *
  *                                                                          *   *                                                                          *
Line 44 
Line 42 
 #include <dump_entry.h>  #include <dump_entry.h>
 #include <term_entry.h>  #include <term_entry.h>
   
 MODULE_ID("$From: tic.c,v 1.53 1999/12/04 22:45:52 tom Exp $")  MODULE_ID("$From: tic.c,v 1.55 1999/12/11 20:20:54 tom Exp $")
   
 const char *_nc_progname = "tic";  const char *_nc_progname = "tic";
   
 static  FILE    *log_fp;  static FILE *log_fp;
 static  FILE    *tmp_fp;  static FILE *tmp_fp;
 static  bool    showsummary = FALSE;  static bool showsummary = FALSE;
 static  const char *to_remove;  static const char *to_remove;
   
 static  void    (*save_check_termtype)(TERMTYPE *);  static void (*save_check_termtype) (TERMTYPE *);
 static  void    check_termtype(TERMTYPE *tt);  static void check_termtype(TERMTYPE * tt);
   
 static  const   char usage_string[] = "[-h] [-v[n]] [-e names] [-CILNRTcfrswx1] source-file\n";  static const char usage_string[] = "[-h] [-v[n]] [-e names] [-CILNRTcfrswx1] source-file\n";
   
 static void cleanup(void)  static void
   cleanup(void)
 {  {
         if (tmp_fp != 0)      if (tmp_fp != 0)
                 fclose(tmp_fp);          fclose(tmp_fp);
         if (to_remove != 0) {      if (to_remove != 0) {
 #if HAVE_REMOVE  #if HAVE_REMOVE
                 remove(to_remove);          remove(to_remove);
 #else  #else
                 unlink(to_remove);          unlink(to_remove);
 #endif  #endif
         }      }
 }  }
   
 static void failed(const char *msg)  static void
   failed(const char *msg)
 {  {
         perror(msg);      perror(msg);
         cleanup();      cleanup();
         exit(EXIT_FAILURE);      exit(EXIT_FAILURE);
 }  }
   
 static void usage(void)  static void
   usage(void)
 {  {
         static const char *const tbl[] = {      static const char *const tbl[] =
       {
         "Options:",          "Options:",
         "  -1         format translation output one capability per line",          "  -1         format translation output one capability per line",
         "  -C         translate entries to termcap source form",          "  -C         translate entries to termcap source form",
Line 105 
Line 107 
         "",          "",
         "Parameters:",          "Parameters:",
         "  <file>     file to translate or compile"          "  <file>     file to translate or compile"
         };      };
         size_t j;      size_t j;
   
         printf("Usage: %s %s\n", _nc_progname, usage_string);      printf("Usage: %s %s\n", _nc_progname, usage_string);
         for (j = 0; j < sizeof(tbl)/sizeof(tbl[0]); j++)      for (j = 0; j < sizeof(tbl) / sizeof(tbl[0]); j++)
                 puts(tbl[j]);          puts(tbl[j]);
         exit(EXIT_FAILURE);      exit(EXIT_FAILURE);
 }  }
   
 #define L_BRACE '{'  #define L_BRACE '{'
 #define R_BRACE '}'  #define R_BRACE '}'
 #define S_QUOTE '\'';  #define S_QUOTE '\'';
   
 static void write_it(ENTRY *ep)  static void
   write_it(ENTRY * ep)
 {  {
         unsigned n;      unsigned n;
         int ch;      int ch;
         char *s, *d, *t;      char *s, *d, *t;
         char result[MAX_ENTRY_SIZE];      char result[MAX_ENTRY_SIZE];
   
         /*      /*
          * Look for strings that contain %{number}, convert them to %'char',       * Look for strings that contain %{number}, convert them to %'char',
          * which is shorter and runs a little faster.       * which is shorter and runs a little faster.
          */       */
         for (n = 0; n < STRCOUNT; n++) {      for (n = 0; n < STRCOUNT; n++) {
                 s = ep->tterm.Strings[n];          s = ep->tterm.Strings[n];
                 if (VALID_STRING(s)          if (VALID_STRING(s)
                  && strchr(s, L_BRACE) != 0) {              && strchr(s, L_BRACE) != 0) {
                         d = result;              d = result;
                         t = s;              t = s;
                         while ((ch = *t++) != 0) {              while ((ch = *t++) != 0) {
                                 *d++ = ch;                  *d++ = ch;
                                 if (ch == '\\') {                  if (ch == '\\') {
                                         *d++ = *t++;                      *d++ = *t++;
                                 } else if ((ch == '%')                  } else if ((ch == '%')
                                  && (*t == L_BRACE)) {                      && (*t == L_BRACE)) {
                                         char *v = 0;                      char *v = 0;
                                         long value = strtol(t+1, &v, 0);                      long value = strtol(t + 1, &v, 0);
                                         if (v != 0                      if (v != 0
                                          && *v == R_BRACE                          && *v == R_BRACE
                                          && value > 0                          && value > 0
                                          && value != '\\'       /* FIXME */                          && value != '\\'        /* FIXME */
                                          && value < 127                          && value < 127
                                          && isprint((int)value)) {                          && isprint((int) value)) {
                                                 *d++ = S_QUOTE;                          *d++ = S_QUOTE;
                                                 *d++ = (int)value;                          *d++ = (int) value;
                                                 *d++ = S_QUOTE;                          *d++ = S_QUOTE;
                                                 t = (v + 1);                          t = (v + 1);
                                         }                      }
                                 }  
                         }  
                         *d = 0;  
                         if (strlen(result) < strlen(s))  
                                 strcpy(s, result);  
                 }                  }
               }
               *d = 0;
               if (strlen(result) < strlen(s))
                   strcpy(s, result);
         }          }
       }
   
         _nc_set_type(_nc_first_name(ep->tterm.term_names));      _nc_set_type(_nc_first_name(ep->tterm.term_names));
         _nc_curr_line = ep->startline;      _nc_curr_line = ep->startline;
         _nc_write_entry(&ep->tterm);      _nc_write_entry(&ep->tterm);
 }  }
   
 static bool immedhook(ENTRY *ep GCC_UNUSED)  static bool
   immedhook(ENTRY * ep GCC_UNUSED)
 /* write out entries with no use capabilities immediately to save storage */  /* write out entries with no use capabilities immediately to save storage */
 {  {
 #ifndef HAVE_BIG_CORE  #ifndef HAVE_BIG_CORE
Line 204 
Line 208 
      * make tic a bit faster (because the resolution code won't have to do       * make tic a bit faster (because the resolution code won't have to do
      * disk I/O nearly as often).       * disk I/O nearly as often).
      */       */
     if (ep->nuses == 0)      if (ep->nuses == 0) {
     {          int oldline = _nc_curr_line;
         int     oldline = _nc_curr_line;  
   
         write_it(ep);          write_it(ep);
         _nc_curr_line = oldline;          _nc_curr_line = oldline;
         free(ep->tterm.str_table);          free(ep->tterm.str_table);
         return(TRUE);          return (TRUE);
     }      }
 #endif /* HAVE_BIG_CORE */  #endif /* HAVE_BIG_CORE */
     return(FALSE);      return (FALSE);
 }  }
   
 static void put_translate(int c)  static void
   put_translate(int c)
 /* emit a comment char, translating terminfo names to termcap names */  /* emit a comment char, translating terminfo names to termcap names */
 {  {
     static bool in_name = FALSE;      static bool in_name = FALSE;
     static char namebuf[132], suffix[132], *sp;      static size_t have, used;
       static char *namebuf, *suffix;
   
     if (!in_name)      if (in_name) {
     {          if (used + 1 >= have) {
         if (c == '<')              have += 132;
         {              namebuf = (namebuf != 0) ? realloc(namebuf, have) : malloc(have);
             in_name = TRUE;              suffix = (suffix != 0) ? realloc(suffix, have) : malloc(have);
             sp = namebuf;  
         }          }
         else          if (c == '\n' || c == '@') {
               namebuf[used++] = '\0';
               (void) putchar('<');
               (void) fputs(namebuf, stdout);
             putchar(c);              putchar(c);
     }              in_name = FALSE;
     else if (c == '\n' || c == '@')          } else if (c != '>') {
     {              namebuf[used++] = c;
         *sp++ = '\0';          } else {                /* ah! candidate name! */
         (void) putchar('<');              char *up;
         (void) fputs(namebuf, stdout);              NCURSES_CONST char *tp;
         putchar(c);  
         in_name = FALSE;  
     }  
     else if (c != '>')  
         *sp++ = c;  
     else                /* ah! candidate name! */  
     {  
         char    *up;  
         NCURSES_CONST char *tp;  
   
         *sp++ = '\0';              namebuf[used++] = '\0';
         in_name = FALSE;              in_name = FALSE;
   
         suffix[0] = '\0';              suffix[0] = '\0';
         if ((up = strchr(namebuf, '#')) != 0              if ((up = strchr(namebuf, '#')) != 0
          || (up = strchr(namebuf, '=')) != 0                  || (up = strchr(namebuf, '=')) != 0
          || ((up = strchr(namebuf, '@')) != 0 && up[1] == '>'))                  || ((up = strchr(namebuf, '@')) != 0 && up[1] == '>')) {
         {                  (void) strcpy(suffix, up);
             (void) strcpy(suffix, up);                  *up = '\0';
             *up = '\0';              }
         }  
   
         if ((tp = nametrans(namebuf)) != 0)              if ((tp = nametrans(namebuf)) != 0) {
         {                  (void) putchar(':');
             (void) putchar(':');                  (void) fputs(tp, stdout);
             (void) fputs(tp, stdout);                  (void) fputs(suffix, stdout);
             (void) fputs(suffix, stdout);                  (void) putchar(':');
             (void) putchar(':');              } else {
                   /* couldn't find a translation, just dump the name */
                   (void) putchar('<');
                   (void) fputs(namebuf, stdout);
                   (void) fputs(suffix, stdout);
                   (void) putchar('>');
               }
         }          }
         else      } else {
         {          used = 0;
             /* couldn't find a translation, just dump the name */          if (c == '<') {
             (void) putchar('<');              in_name = TRUE;
             (void) fputs(namebuf, stdout);          } else {
             (void) fputs(suffix, stdout);              putchar(c);
             (void) putchar('>');  
         }          }
   
     }      }
 }  }
   
 /* Returns a string, stripped of leading/trailing whitespace */  /* Returns a string, stripped of leading/trailing whitespace */
 static char *stripped(char *src)  static char *
   stripped(char *src)
 {  {
         while (isspace(*src))      while (isspace(*src))
                 src++;          src++;
         if (*src != '\0') {      if (*src != '\0') {
                 char *dst = strcpy(malloc(strlen(src)+1), src);          char *dst = strcpy(malloc(strlen(src) + 1), src);
                 size_t len = strlen(dst);          size_t len = strlen(dst);
                 while (--len != 0 && isspace(dst[len]))          while (--len != 0 && isspace(dst[len]))
                         dst[len] = '\0';              dst[len] = '\0';
                 return dst;          return dst;
         }      }
         return 0;      return 0;
 }  }
   
 /* Parse the "-e" option-value into a list of names */  /* Parse the "-e" option-value into a list of names */
 static const char **make_namelist(char *src)  static const char **
   make_namelist(char *src)
 {  {
         const char **dst = 0;      const char **dst = 0;
   
         char *s, *base;      char *s, *base;
         unsigned pass, n, nn;      unsigned pass, n, nn;
         char buffer[BUFSIZ];      char buffer[BUFSIZ];
   
         if (src == 0) {      if (src == 0) {
                 /* EMPTY */;          /* EMPTY */ ;
         } else if (strchr(src, '/') != 0) {     /* a filename */      } else if (strchr(src, '/') != 0) {         /* a filename */
                 FILE *fp = fopen(src, "r");          FILE *fp = fopen(src, "r");
                 if (fp == 0)          if (fp == 0)
                         failed(src);              failed(src);
   
                 for (pass = 1; pass <= 2; pass++) {          for (pass = 1; pass <= 2; pass++) {
                         nn = 0;              nn = 0;
                         while (fgets(buffer, sizeof(buffer), fp) != 0) {              while (fgets(buffer, sizeof(buffer), fp) != 0) {
                                 if ((s = stripped(buffer)) != 0) {                  if ((s = stripped(buffer)) != 0) {
                                         if (dst != 0)                      if (dst != 0)
                                                 dst[nn] = s;                          dst[nn] = s;
                                         nn++;                      nn++;
                                 }  
                         }  
                         if (pass == 1) {  
                                 dst = (const char **)calloc(nn+1, sizeof(*dst));  
                                 rewind(fp);  
                         }  
                 }                  }
                 fclose(fp);              }
         } else {                        /* literal list of names */              if (pass == 1) {
                 for (pass = 1; pass <= 2; pass++) {                  dst = (const char **) calloc(nn + 1, sizeof(*dst));
                         for (n = nn = 0, base = src; ; n++) {                  rewind(fp);
                                 int mark = src[n];              }
                                 if (mark == ',' || mark == '\0') {          }
                                         if (pass == 1) {          fclose(fp);
                                                 nn++;      } else {                    /* literal list of names */
                                         } else {          for (pass = 1; pass <= 2; pass++) {
                                                 src[n] = '\0';              for (n = nn = 0, base = src;; n++) {
                                                 if ((s = stripped(base)) != 0)                  int mark = src[n];
                                                         dst[nn++] = s;                  if (mark == ',' || mark == '\0') {
                                                 base = &src[n+1];                      if (pass == 1) {
                                         }                          nn++;
                                 }                      } else {
                                 if (mark == '\0')                          src[n] = '\0';
                                         break;                          if ((s = stripped(base)) != 0)
                         }                              dst[nn++] = s;
                         if (pass == 1)                          base = &src[n + 1];
                                 dst = (const char **)calloc(nn+1, sizeof(*dst));                      }
                 }                  }
                   if (mark == '\0')
                       break;
               }
               if (pass == 1)
                   dst = (const char **) calloc(nn + 1, sizeof(*dst));
         }          }
         if (showsummary) {      }
                 fprintf(log_fp, "Entries that will be compiled:\n");      if (showsummary) {
                 for (n = 0; dst[n] != 0; n++)          fprintf(log_fp, "Entries that will be compiled:\n");
                         fprintf(log_fp, "%d:%s\n", n+1, dst[n]);          for (n = 0; dst[n] != 0; n++)
         }              fprintf(log_fp, "%d:%s\n", n + 1, dst[n]);
         return dst;      }
       return dst;
 }  }
   
 static bool matches(const char **needle, const char *haystack)  static bool
   matches(const char **needle, const char *haystack)
 /* does entry in needle list match |-separated field in haystack? */  /* does entry in needle list match |-separated field in haystack? */
 {  {
         bool code = FALSE;      bool code = FALSE;
         size_t n;      size_t n;
   
         if (needle != 0)      if (needle != 0) {
         {          for (n = 0; needle[n] != 0; n++) {
                 for (n = 0; needle[n] != 0; n++)              if (_nc_name_match(haystack, needle[n], "|")) {
                 {  
                         if (_nc_name_match(haystack, needle[n], "|"))  
                         {  
                                 code = TRUE;  
                                 break;  
                         }  
                 }  
         }  
         else  
                 code = TRUE;                  code = TRUE;
         return(code);                  break;
               }
           }
       } else
           code = TRUE;
       return (code);
 }  }
   
 int main (int argc, char *argv[])  int
   main(int argc, char *argv[])
 {  {
 char    my_tmpname[PATH_MAX];      char my_tmpname[PATH_MAX];
 int     v_opt = -1, debug_level;      int v_opt = -1, debug_level;
 int     smart_defaults = TRUE;      int smart_defaults = TRUE;
 char    *termcap;      char *termcap;
 ENTRY   *qp;      ENTRY *qp;
   
 int     this_opt, last_opt = '?';      int this_opt, last_opt = '?';
   
 int     outform = F_TERMINFO;   /* output format */      int outform = F_TERMINFO;   /* output format */
 int     sortmode = S_TERMINFO;  /* sort_mode */      int sortmode = S_TERMINFO;  /* sort_mode */
   
 int     fd;      int fd;
 int     width = 60;      int width = 60;
 bool    formatted = FALSE;      /* reformat complex strings? */      bool formatted = FALSE;     /* reformat complex strings? */
 int     numbers = 0;            /* format "%'char'" to/from "%{number}" */      int numbers = 0;            /* format "%'char'" to/from "%{number}" */
 bool    infodump = FALSE;       /* running as captoinfo? */      bool infodump = FALSE;      /* running as captoinfo? */
 bool    capdump = FALSE;        /* running as infotocap? */      bool capdump = FALSE;       /* running as infotocap? */
 bool    forceresolve = FALSE;   /* force resolution */      bool forceresolve = FALSE;  /* force resolution */
 bool    limited = TRUE;      bool limited = TRUE;
 char    *tversion = (char *)NULL;      char *tversion = (char *) NULL;
 const   char    *source_file = "terminfo";      const char *source_file = "terminfo";
 const   char    **namelst = 0;      const char **namelst = 0;
 char    *outdir = (char *)NULL;      char *outdir = (char *) NULL;
 bool    check_only = FALSE;      bool check_only = FALSE;
   
         log_fp = stderr;      log_fp = stderr;
   
         if ((_nc_progname = strrchr(argv[0], '/')) == NULL)      if ((_nc_progname = strrchr(argv[0], '/')) == NULL)
                 _nc_progname = argv[0];          _nc_progname = argv[0];
         else      else
                 _nc_progname++;          _nc_progname++;
   
         if ((infodump = (strcmp(_nc_progname, "captoinfo") == 0)) != FALSE) {      if ((infodump = (strcmp(_nc_progname, "captoinfo") == 0)) != FALSE) {
                 outform  = F_TERMINFO;          outform = F_TERMINFO;
                 sortmode = S_TERMINFO;          sortmode = S_TERMINFO;
         }      }
         if ((capdump = (strcmp(_nc_progname, "infotocap") == 0)) != FALSE) {      if ((capdump = (strcmp(_nc_progname, "infotocap") == 0)) != FALSE) {
                 outform  = F_TERMCAP;          outform = F_TERMCAP;
                 sortmode = S_TERMCAP;          sortmode = S_TERMCAP;
         }      }
 #if NCURSES_XNAMES  #if NCURSES_XNAMES
         use_extended_names(FALSE);      use_extended_names(FALSE);
 #endif  #endif
   
         /*      /*
          * Processing arguments is a little complicated, since someone made a       * Processing arguments is a little complicated, since someone made a
          * design decision to allow the numeric values for -w, -v options to       * design decision to allow the numeric values for -w, -v options to
          * be optional.       * be optional.
          */       */
         while ((this_opt = getopt(argc, argv, "0123456789CILNR:TVce:fGgo:rsvwx")) != -1) {      while ((this_opt = getopt(argc, argv,
                 if (isdigit(this_opt)) {                  "0123456789CILNR:TVce:fGgo:rsvwx")) != -1) {
                         switch (last_opt) {          if (isdigit(this_opt)) {
                         case 'v':              switch (last_opt) {
                                 v_opt = (v_opt * 10) + (this_opt - '0');              case 'v':
                                 break;                  v_opt = (v_opt * 10) + (this_opt - '0');
                         case 'w':                  break;
                                 width = (width * 10) + (this_opt - '0');              case 'w':
                                 break;                  width = (width * 10) + (this_opt - '0');
                         default:                  break;
                                 if (this_opt != '1')              default:
                                         usage();                  if (this_opt != '1')
                                 last_opt = this_opt;                      usage();
                                 width = 0;                  last_opt = this_opt;
                         }                  width = 0;
                         continue;              }
                 }              continue;
                 switch (this_opt) {          }
                 case 'C':          switch (this_opt) {
                         capdump  = TRUE;          case 'C':
                         outform  = F_TERMCAP;              capdump = TRUE;
                         sortmode = S_TERMCAP;              outform = F_TERMCAP;
                         break;              sortmode = S_TERMCAP;
                 case 'I':              break;
                         infodump = TRUE;          case 'I':
                         outform  = F_TERMINFO;              infodump = TRUE;
                         sortmode = S_TERMINFO;              outform = F_TERMINFO;
                         break;              sortmode = S_TERMINFO;
                 case 'L':              break;
                         infodump = TRUE;          case 'L':
                         outform  = F_VARIABLE;              infodump = TRUE;
                         sortmode = S_VARIABLE;              outform = F_VARIABLE;
                         break;              sortmode = S_VARIABLE;
                 case 'N':              break;
                         smart_defaults = FALSE;          case 'N':
                         break;              smart_defaults = FALSE;
                 case 'R':              break;
                         tversion = optarg;          case 'R':
                         break;              tversion = optarg;
                 case 'T':              break;
                         limited = FALSE;          case 'T':
                         break;              limited = FALSE;
                 case 'V':              break;
                         puts(NCURSES_VERSION);          case 'V':
                         return EXIT_SUCCESS;              puts(NCURSES_VERSION);
                 case 'c':              return EXIT_SUCCESS;
                         check_only = TRUE;          case 'c':
                         break;              check_only = TRUE;
                 case 'e':              break;
                         namelst = make_namelist(optarg);          case 'e':
                         break;              namelst = make_namelist(optarg);
                 case 'f':              break;
                         formatted = TRUE;          case 'f':
                         break;              formatted = TRUE;
                 case 'G':              break;
                         numbers = 1;          case 'G':
                         break;              numbers = 1;
                 case 'g':              break;
                         numbers = -1;          case 'g':
                         break;              numbers = -1;
                 case 'o':              break;
                         outdir = optarg;          case 'o':
                         break;              outdir = optarg;
                 case 'r':              break;
                         forceresolve = TRUE;          case 'r':
                         break;              forceresolve = TRUE;
                 case 's':              break;
                         showsummary = TRUE;          case 's':
                         break;              showsummary = TRUE;
                 case 'v':              break;
                         v_opt = 0;          case 'v':
                         break;              v_opt = 0;
                 case 'w':              break;
                         width = 0;          case 'w':
                         break;              width = 0;
               break;
 #if NCURSES_XNAMES  #if NCURSES_XNAMES
                 case 'x':          case 'x':
                         use_extended_names(TRUE);              use_extended_names(TRUE);
                         break;              break;
 #endif  #endif
                 default:          default:
                         usage();              usage();
                 }  
                 last_opt = this_opt;  
         }          }
           last_opt = this_opt;
       }
   
         debug_level = (v_opt > 0) ? v_opt : (v_opt == 0);      debug_level = (v_opt > 0) ? v_opt : (v_opt == 0);
         _nc_tracing = (1 << debug_level) - 1;      _nc_tracing = (1 << debug_level) - 1;
   
         if (_nc_tracing)      if (_nc_tracing) {
         {          save_check_termtype = _nc_check_termtype;
                 save_check_termtype = _nc_check_termtype;          _nc_check_termtype = check_termtype;
                 _nc_check_termtype = check_termtype;      }
         }  
   
 #ifndef HAVE_BIG_CORE  #ifndef HAVE_BIG_CORE
         /*      /*
          * Aaargh! immedhook seriously hoses us!       * Aaargh! immedhook seriously hoses us!
          *       *
          * One problem with immedhook is it means we can't do -e.  Problem       * One problem with immedhook is it means we can't do -e.  Problem
          * is that we can't guarantee that for each terminal listed, all the       * is that we can't guarantee that for each terminal listed, all the
          * terminals it depends on will have been kept in core for reference       * terminals it depends on will have been kept in core for reference
          * resolution -- in fact it's certain the primitive types at the end       * resolution -- in fact it's certain the primitive types at the end
          * of reference chains *won't* be in core unless they were explicitly       * of reference chains *won't* be in core unless they were explicitly
          * in the select list themselves.       * in the select list themselves.
          */       */
         if (namelst && (!infodump && !capdump))      if (namelst && (!infodump && !capdump)) {
         {          (void) fprintf(stderr,
             (void) fprintf(stderr,              "Sorry, -e can't be used without -I or -C\n");
                            "Sorry, -e can't be used without -I or -C\n");          cleanup();
             cleanup();          return EXIT_FAILURE;
             return EXIT_FAILURE;      }
         }  
 #endif /* HAVE_BIG_CORE */  #endif /* HAVE_BIG_CORE */
   
       if (optind < argc) {
           source_file = argv[optind++];
         if (optind < argc) {          if (optind < argc) {
                 source_file = argv[optind++];              fprintf(stderr,
                 if (optind < argc) {                  "%s: Too many file names.  Usage:\n\t%s %s",
                         fprintf (stderr,                  _nc_progname,
                                 "%s: Too many file names.  Usage:\n\t%s %s",                  _nc_progname,
                                 _nc_progname,                  usage_string);
                                 _nc_progname,              return EXIT_FAILURE;
                                 usage_string);          }
                         return EXIT_FAILURE;      } else {
                 }          if (infodump == TRUE) {
         } else {              /* captoinfo's no-argument case */
                 if (infodump == TRUE) {              source_file = "/usr/share/misc/termcap";
                         /* captoinfo's no-argument case */              if ((termcap = getenv("TERMCAP")) != 0
                         source_file = "/usr/share/misc/termcap";                  && (namelst = make_namelist(getenv("TERM"))) != 0) {
                         if ((termcap = getenv("TERMCAP")) != 0                  if (access(termcap, F_OK) == 0) {
                          && (namelst = make_namelist(getenv("TERM"))) != 0) {                      /* file exists */
                                 if (access(termcap, F_OK) == 0) {                      source_file = termcap;
                                         /* file exists */                  } else if (strcpy(my_tmpname, "/tmp/tic.XXXXXXXX")
                                         source_file = termcap;                      && (fd = mkstemp(my_tmpname)) != -1
                                 } else                      && (tmp_fp = fdopen(fd, "w")) != 0) {
                                 if (strcpy(my_tmpname, "/tmp/tic.XXXXXXXX")                      fprintf(tmp_fp, "%s\n", termcap);
                                  && (fd = mkstemp(my_tmpname)) != -1                      fclose(tmp_fp);
                                  && (tmp_fp = fdopen(fd, "w")) != 0) {                      tmp_fp = fopen(source_file, "r");
                                         fprintf(tmp_fp, "%s\n", termcap);                      to_remove = source_file;
                                         fclose(tmp_fp);  
                                         tmp_fp = fopen(source_file, "r");  
                                         to_remove = source_file;  
                                 } else {  
                                         failed("mkstemp");  
                                 }  
                         }  
                 } else {                  } else {
                 /* tic */                      failed("mkstemp");
                         fprintf (stderr,  
                                 "%s: File name needed.  Usage:\n\t%s %s",  
                                 _nc_progname,  
                                 _nc_progname,  
                                 usage_string);  
                         cleanup();  
                         return EXIT_FAILURE;  
                 }                  }
               }
           } else {
               /* tic */
               fprintf(stderr,
                   "%s: File name needed.  Usage:\n\t%s %s",
                   _nc_progname,
                   _nc_progname,
                   usage_string);
               cleanup();
               return EXIT_FAILURE;
         }          }
       }
   
         if (tmp_fp == 0      if (tmp_fp == 0
          && (tmp_fp = fopen(source_file, "r")) == 0) {          && (tmp_fp = fopen(source_file, "r")) == 0) {
                 fprintf (stderr, "%s: Can't open %s\n", _nc_progname, source_file);          fprintf(stderr, "%s: Can't open %s\n", _nc_progname, source_file);
                 return EXIT_FAILURE;          return EXIT_FAILURE;
         }      }
   
         if (infodump)      if (infodump)
                 dump_init(tversion,          dump_init(tversion,
                           smart_defaults              smart_defaults
                                 ? outform              ? outform
                                 : F_LITERAL,              : F_LITERAL,
                           sortmode, width, debug_level, formatted);              sortmode, width, debug_level, formatted);
         else if (capdump)      else if (capdump)
                 dump_init(tversion,          dump_init(tversion,
                           outform,              outform,
                           sortmode, width, debug_level, FALSE);              sortmode, width, debug_level, FALSE);
   
         /* parse entries out of the source file */      /* parse entries out of the source file */
         _nc_set_source(source_file);      _nc_set_source(source_file);
 #ifndef HAVE_BIG_CORE  #ifndef HAVE_BIG_CORE
         if (!(check_only || infodump || capdump))      if (!(check_only || infodump || capdump))
             _nc_set_writedir(outdir);          _nc_set_writedir(outdir);
 #endif /* HAVE_BIG_CORE */  #endif /* HAVE_BIG_CORE */
         _nc_read_entry_source(tmp_fp, (char *)NULL,      _nc_read_entry_source(tmp_fp, (char *) NULL,
                               !smart_defaults, FALSE,          !smart_defaults, FALSE,
                               (check_only || infodump || capdump) ? NULLHOOK : immedhook);          (check_only || infodump || capdump) ? NULLHOOK : immedhook);
   
         /* do use resolution */      /* do use resolution */
         if (check_only || (!infodump && !capdump) || forceresolve) {      if (check_only || (!infodump && !capdump) || forceresolve) {
             if (!_nc_resolve_uses() && !check_only) {          if (!_nc_resolve_uses() && !check_only) {
                 cleanup();              cleanup();
                 return EXIT_FAILURE;              return EXIT_FAILURE;
             }  
         }          }
       }
   
         /* length check */      /* length check */
         if (check_only && (capdump || infodump))      if (check_only && (capdump || infodump)) {
         {          for_entry_list(qp) {
             for_entry_list(qp)              if (matches(namelst, qp->tterm.term_names)) {
             {                  int len = fmt_entry(&qp->tterm, NULL, TRUE, infodump, numbers);
                 if (matches(namelst, qp->tterm.term_names))  
                 {  
                     int len = fmt_entry(&qp->tterm, NULL, TRUE, infodump, numbers);  
   
                     if (len>(infodump?MAX_TERMINFO_LENGTH:MAX_TERMCAP_LENGTH))                  if (len > (infodump ? MAX_TERMINFO_LENGTH : MAX_TERMCAP_LENGTH))
                             (void) fprintf(stderr,                      (void) fprintf(stderr,
                            "warning: resolved %s entry is %d bytes long\n",                          "warning: resolved %s entry is %d bytes long\n",
                            _nc_first_name(qp->tterm.term_names),                          _nc_first_name(qp->tterm.term_names),
                            len);                          len);
                 }  
             }              }
         }          }
       }
   
         /* write or dump all entries */      /* write or dump all entries */
         if (!check_only)      if (!check_only) {
         {          if (!infodump && !capdump) {
             if (!infodump && !capdump)              _nc_set_writedir(outdir);
             {              for_entry_list(qp)
                 _nc_set_writedir(outdir);                  if (matches(namelst, qp->tterm.term_names))
                 for_entry_list(qp)                  write_it(qp);
                     if (matches(namelst, qp->tterm.term_names))          } else {
                         write_it(qp);              /* this is in case infotocap() generates warnings */
             }              _nc_curr_col = _nc_curr_line = -1;
             else  
             {  
                 /* this is in case infotocap() generates warnings */  
                 _nc_curr_col = _nc_curr_line = -1;  
   
                 for_entry_list(qp)              for_entry_list(qp) {
                     if (matches(namelst, qp->tterm.term_names))                  if (matches(namelst, qp->tterm.term_names)) {
                     {                      int j = qp->cend - qp->cstart;
                         int     j = qp->cend - qp->cstart;                      int len = 0;
                         int     len = 0;  
   
                         /* this is in case infotocap() generates warnings */                      /* this is in case infotocap() generates warnings */
                         _nc_set_type(_nc_first_name(qp->tterm.term_names));                      _nc_set_type(_nc_first_name(qp->tterm.term_names));
   
                         (void) fseek(tmp_fp, qp->cstart, SEEK_SET);                      (void) fseek(tmp_fp, qp->cstart, SEEK_SET);
                         while (j-- )                      while (j--) {
                             if (infodump)                          if (infodump)
                                 (void) putchar(fgetc(tmp_fp));                              (void) putchar(fgetc(tmp_fp));
                             else                          else
                                 put_translate(fgetc(tmp_fp));                              put_translate(fgetc(tmp_fp));
   
                         len = dump_entry(&qp->tterm, limited, numbers, NULL);  
                         for (j = 0; j < qp->nuses; j++)  
                             len += dump_uses((char *)(qp->uses[j].parent), !capdump);  
                         (void) putchar('\n');  
                         if (debug_level != 0 && !limited)  
                             printf("# length=%d\n", len);  
                     }                      }
                 if (!namelst)  
                 {  
                     int  c, oldc = '\0';  
                     bool in_comment = FALSE;  
                     bool trailing_comment = FALSE;  
   
                     (void) fseek(tmp_fp, _nc_tail->cend, SEEK_SET);                      len = dump_entry(&qp->tterm, limited, numbers, NULL);
                     while ((c = fgetc(tmp_fp)) != EOF)                      for (j = 0; j < qp->nuses; j++)
                     {                          len += dump_uses((char *) (qp->uses[j].parent), !capdump);
                         if (oldc == '\n') {                      (void) putchar('\n');
                             if (c == '#') {                      if (debug_level != 0 && !limited)
                                 trailing_comment = TRUE;                          printf("# length=%d\n", len);
                                 in_comment = TRUE;                  }
                             } else {              }
                                 in_comment = FALSE;              if (!namelst) {
                             }                  int c, oldc = '\0';
                   bool in_comment = FALSE;
                   bool trailing_comment = FALSE;
   
                   (void) fseek(tmp_fp, _nc_tail->cend, SEEK_SET);
                   while ((c = fgetc(tmp_fp)) != EOF) {
                       if (oldc == '\n') {
                           if (c == '#') {
                               trailing_comment = TRUE;
                               in_comment = TRUE;
                           } else {
                               in_comment = FALSE;
                         }                          }
                         if (trailing_comment  
                          && (in_comment || (oldc == '\n' && c == '\n')))  
                             putchar(c);  
                         oldc = c;  
                     }                      }
                       if (trailing_comment
                           && (in_comment || (oldc == '\n' && c == '\n')))
                           putchar(c);
                       oldc = c;
                 }                  }
             }              }
         }          }
       }
   
         /* Show the directory into which entries were written, and the total      /* Show the directory into which entries were written, and the total
          * number of entries       * number of entries
          */       */
         if (showsummary      if (showsummary
          && (!(check_only || infodump || capdump))) {          && (!(check_only || infodump || capdump))) {
                 int total = _nc_tic_written();          int total = _nc_tic_written();
                 if (total != 0)          if (total != 0)
                         fprintf(log_fp, "%d entries written to %s\n",              fprintf(log_fp, "%d entries written to %s\n",
                                 total,                  total,
                                 _nc_tic_dir((char *)0));                  _nc_tic_dir((char *) 0));
                 else          else
                         fprintf(log_fp, "No entries written\n");              fprintf(log_fp, "No entries written\n");
         }      }
         cleanup();      cleanup();
         return(EXIT_SUCCESS);      return (EXIT_SUCCESS);
 }  }
   
 /*  /*
Line 725 
Line 715 
  * precisely what's needed (see comp_parse.c).   * precisely what's needed (see comp_parse.c).
  */   */
   
 TERMINAL *cur_term;     /* tweak to avoid linking lib_cur_term.c */  TERMINAL *cur_term;             /* tweak to avoid linking lib_cur_term.c */
   
 #undef CUR  #undef CUR
 #define CUR tp->  #define CUR tp->
Line 733 
Line 723 
 /* other sanity-checks (things that we don't want in the normal  /* other sanity-checks (things that we don't want in the normal
  * logic that reads a terminfo entry)   * logic that reads a terminfo entry)
  */   */
 static void check_termtype(TERMTYPE *tp)  static void
   check_termtype(TERMTYPE * tp)
 {  {
         bool conflict = FALSE;      bool conflict = FALSE;
         unsigned j, k;      unsigned j, k;
         char  fkeys[STRCOUNT];      char fkeys[STRCOUNT];
   
         /*      /*
          * A terminal entry may contain more than one keycode assigned to       * A terminal entry may contain more than one keycode assigned to
          * a given string (e.g., KEY_END and KEY_LL).  But curses will only       * a given string (e.g., KEY_END and KEY_LL).  But curses will only
          * return one (the last one assigned).       * return one (the last one assigned).
          */       */
         memset(fkeys, 0, sizeof(fkeys));      memset(fkeys, 0, sizeof(fkeys));
         for (j = 0; _nc_tinfo_fkeys[j].code; j++) {      for (j = 0; _nc_tinfo_fkeys[j].code; j++) {
             char *a = tp->Strings[_nc_tinfo_fkeys[j].offset];          char *a = tp->Strings[_nc_tinfo_fkeys[j].offset];
             bool first = TRUE;          bool first = TRUE;
             if (!VALID_STRING(a))          if (!VALID_STRING(a))
               continue;
           for (k = j + 1; _nc_tinfo_fkeys[k].code; k++) {
               char *b = tp->Strings[_nc_tinfo_fkeys[k].offset];
               if (!VALID_STRING(b)
                   || fkeys[k])
                 continue;                  continue;
             for (k = j+1; _nc_tinfo_fkeys[k].code; k++) {              if (!strcmp(a, b)) {
                 char *b = tp->Strings[_nc_tinfo_fkeys[k].offset];                  fkeys[j] = 1;
                 if (!VALID_STRING(b)                  fkeys[k] = 1;
                  || fkeys[k])                  if (first) {
                     continue;                      if (!conflict) {
                 if (!strcmp(a,b)) {                          _nc_warning("Conflicting key definitions (using the last)");
                     fkeys[j] = 1;                          conflict = TRUE;
                     fkeys[k] = 1;  
                     if (first) {  
                         if (!conflict) {  
                             _nc_warning("Conflicting key definitions (using the last)");  
                             conflict = TRUE;  
                         }  
                         fprintf(stderr, "... %s is the same as %s",  
                                 keyname(_nc_tinfo_fkeys[j].code),  
                                 keyname(_nc_tinfo_fkeys[k].code));  
                         first = FALSE;  
                     } else {  
                         fprintf(stderr, ", %s",  
                                 keyname(_nc_tinfo_fkeys[k].code));  
                     }                      }
                       fprintf(stderr, "... %s is the same as %s",
                           keyname(_nc_tinfo_fkeys[j].code),
                           keyname(_nc_tinfo_fkeys[k].code));
                       first = FALSE;
                   } else {
                       fprintf(stderr, ", %s",
                           keyname(_nc_tinfo_fkeys[k].code));
                 }                  }
             }              }
             if (!first)  
                 fprintf(stderr, "\n");  
         }          }
           if (!first)
               fprintf(stderr, "\n");
       }
   
         /*      /*
          * Quick check for color.  We could also check if the ANSI versus       * Quick check for color.  We could also check if the ANSI versus
          * non-ANSI strings are misused.       * non-ANSI strings are misused.
          */       */
         if ((max_colors > 0) != (max_pairs > 0)      if ((max_colors > 0) != (max_pairs > 0)
          || (max_colors > max_pairs))          || (max_colors > max_pairs))
                 _nc_warning("inconsistent values for max_colors and max_pairs");          _nc_warning("inconsistent values for max_colors and max_pairs");
   
         PAIRED(set_foreground,                  set_background)      PAIRED(set_foreground, set_background)
         PAIRED(set_a_foreground,                set_a_background)          PAIRED(set_a_foreground, set_a_background)
   
         /*      /*
          * These may be mismatched because the terminal description relies on       * These may be mismatched because the terminal description relies on
          * restoring the cursor visibility by resetting it.       * restoring the cursor visibility by resetting it.
          */       */
         ANDMISSING(cursor_invisible,            cursor_normal)          ANDMISSING(cursor_invisible, cursor_normal)
         ANDMISSING(cursor_visible,              cursor_normal)          ANDMISSING(cursor_visible, cursor_normal)
   
         /*      /*
          * From XSI & O'Reilly, we gather that sc/rc are required if csr is       * From XSI & O'Reilly, we gather that sc/rc are required if csr is
          * given, because the cursor position after the scrolling operation is       * given, because the cursor position after the scrolling operation is
          * performed is undefined.       * performed is undefined.
          */       */
         ANDMISSING(change_scroll_region,        save_cursor)          ANDMISSING(change_scroll_region, save_cursor)
         ANDMISSING(change_scroll_region,        restore_cursor)          ANDMISSING(change_scroll_region, restore_cursor)
   
         /*      /*
          * Some standard applications (e.g., vi) and some non-curses       * Some standard applications (e.g., vi) and some non-curses
          * applications (e.g., jove) get confused if we have both ich/ich1 and       * applications (e.g., jove) get confused if we have both ich/ich1 and
          * smir/rmir.  Let's be nice and warn about that, too, even though       * smir/rmir.  Let's be nice and warn about that, too, even though
          * ncurses handles it.       * ncurses handles it.
          */       */
         if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode))          if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode))
          && (PRESENT(insert_character)  || PRESENT(parm_ich))) {          && (PRESENT(insert_character) || PRESENT(parm_ich))) {
            _nc_warning("non-curses applications may be confused by ich/ich1 with smir/rmir");          _nc_warning("non-curses applications may be confused by ich/ich1 with smir/rmir");
         }      }
   
         /*      /*
          * Finally, do the non-verbose checks       * Finally, do the non-verbose checks
          */       */
         if (save_check_termtype != 0)      if (save_check_termtype != 0)
             save_check_termtype(tp);          save_check_termtype(tp);
 }  }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14