ncurses 6.0 - patch 20170729
[ncurses.git] / ncurses / tinfo / parse_entry.c
index 339c7c821648e315365cd1b252e022f9995259f6..3fa2f254cb91dd650137efe1f3ed20e690f21adb 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2012,2016 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2016,2017 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -47,7 +47,7 @@
 #include <ctype.h>
 #include <tic.h>
 
-MODULE_ID("$Id: parse_entry.c,v 1.81 2016/05/28 23:22:52 tom Exp $")
+MODULE_ID("$Id: parse_entry.c,v 1.86 2017/06/28 00:53:12 tom Exp $")
 
 #ifdef LINT
 static short const parametrized[] =
@@ -56,8 +56,8 @@ static short const parametrized[] =
 #include <parametrized.h>
 #endif
 
-static void postprocess_termcap(TERMTYPE *, bool);
-static void postprocess_terminfo(TERMTYPE *);
+static void postprocess_termcap(TERMTYPE2 *, bool);
+static void postprocess_terminfo(TERMTYPE2 *);
 static struct name_table_entry const *lookup_fullname(const char *name);
 
 #if NCURSES_XNAMES
@@ -66,7 +66,7 @@ static struct name_table_entry const *
 _nc_extend_names(ENTRY * entryp, char *name, int token_type)
 {
     static struct name_table_entry temp;
-    TERMTYPE *tp = &(entryp->tterm);
+    TERMTYPE2 *tp = &(entryp->tterm);
     unsigned offset = 0;
     unsigned actual;
     unsigned tindex;
@@ -152,7 +152,7 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
        case NUMBER:
            tp->ext_Numbers++;
            tp->num_Numbers++;
-           TYPE_REALLOC(short, tp->num_Numbers, tp->Numbers);
+           TYPE_REALLOC(NCURSES_INT2, tp->num_Numbers, tp->Numbers);
            for_each_value(tp->num_Numbers)
                tp->Numbers[last] = tp->Numbers[last - 1];
            break;
@@ -206,7 +206,7 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type)
 #define MAX_NUMBER 0x7fff      /* positive shorts only */
 
 NCURSES_EXPORT(int)
-_nc_parse_entry(struct entry *entryp, int literal, bool silent)
+_nc_parse_entry(ENTRY * entryp, int literal, bool silent)
 {
     int token_type;
     struct name_table_entry const *entry_ptr;
@@ -220,7 +220,7 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
     if (token_type != NAMES)
        _nc_err_abort("Entry does not start with terminal names in column one");
 
-    _nc_init_entry(&entryp->tterm);
+    _nc_init_entry(entryp);
 
     entryp->cstart = _nc_comment_start;
     entryp->cend = _nc_comment_end;
@@ -236,13 +236,14 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
      * implemented it.  Note that the resulting terminal type was never the
      * 2-character name, but was instead the first alias after that.
      */
+#define ok_TC2(s) (isgraph(UChar(s)) && (s) != '|')
     ptr = _nc_curr_token.tk_name;
     if (_nc_syntax == SYN_TERMCAP
 #if NCURSES_XNAMES
        && !_nc_user_definable
 #endif
        ) {
-       if (ptr[2] == '|') {
+       if (ok_TC2(ptr[0]) && ok_TC2(ptr[1]) && (ptr[2] == '|')) {
            ptr += 3;
            _nc_curr_token.tk_name[2] = '\0';
        }
@@ -284,9 +285,11 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
        if (is_use || is_tc) {
            entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
            entryp->uses[entryp->nuses].line = _nc_curr_line;
-           entryp->nuses++;
-           if (entryp->nuses > 1 && is_tc) {
-               BAD_TC_USAGE
+           if (VALID_STRING(entryp->uses[entryp->nuses].name)) {
+               entryp->nuses++;
+               if (entryp->nuses > 1 && is_tc) {
+                   BAD_TC_USAGE
+               }
            }
        } else {
            /* normal token lookup */
@@ -369,7 +372,16 @@ _nc_parse_entry(struct entry *entryp, int literal, bool silent)
            }
 
            /* deal with bad type/value combinations. */
-           if (token_type != CANCEL && entry_ptr->nte_type != token_type) {
+           if (token_type == CANCEL) {
+               /*
+                * Prefer terminfo in this (long-obsolete) ambiguity:
+                */
+               if (!strcmp("ma", _nc_curr_token.tk_name)) {
+                   entry_ptr = _nc_find_type_entry("ma", NUMBER,
+                                                   _nc_syntax != 0);
+                   assert(entry_ptr != 0);
+               }
+           } else if (entry_ptr->nte_type != token_type) {
                /*
                 * Nasty special cases here handle situations in which type
                 * information can resolve name clashes.  Normal lookup
@@ -518,43 +530,50 @@ NCURSES_EXPORT(int)
 _nc_capcmp(const char *s, const char *t)
 /* compare two string capabilities, stripping out padding */
 {
-    if (!VALID_STRING(s) && !VALID_STRING(t))
-       return (0);
-    else if (!VALID_STRING(s) || !VALID_STRING(t))
-       return (1);
-
-    for (;;) {
-       if (s[0] == '$' && s[1] == '<') {
-           for (s += 2;; s++)
-               if (!(isdigit(UChar(*s))
-                     || *s == '.'
-                     || *s == '*'
-                     || *s == '/'
-                     || *s == '>'))
-                   break;
-       }
+    bool ok_s = VALID_STRING(s);
+    bool ok_t = VALID_STRING(t);
+
+    if (ok_s && ok_t) {
+       for (;;) {
+           if (s[0] == '$' && s[1] == '<') {
+               for (s += 2;; s++) {
+                   if (!(isdigit(UChar(*s))
+                         || *s == '.'
+                         || *s == '*'
+                         || *s == '/'
+                         || *s == '>')) {
+                       break;
+                   }
+               }
+           }
 
-       if (t[0] == '$' && t[1] == '<') {
-           for (t += 2;; t++)
-               if (!(isdigit(UChar(*t))
-                     || *t == '.'
-                     || *t == '*'
-                     || *t == '/'
-                     || *t == '>'))
-                   break;
-       }
+           if (t[0] == '$' && t[1] == '<') {
+               for (t += 2;; t++) {
+                   if (!(isdigit(UChar(*t))
+                         || *t == '.'
+                         || *t == '*'
+                         || *t == '/'
+                         || *t == '>')) {
+                       break;
+                   }
+               }
+           }
 
-       /* we've now pushed s and t past any padding they were pointing at */
+           /* we've now pushed s and t past any padding they pointed at */
 
-       if (*s == '\0' && *t == '\0')
-           return (0);
+           if (*s == '\0' && *t == '\0')
+               return (0);
 
-       if (*s != *t)
-           return (*t - *s);
+           if (*s != *t)
+               return (*t - *s);
 
-       /* else *s == *t but one is not NUL, so continue */
-       s++, t++;
+           /* else *s == *t but one is not NUL, so continue */
+           s++, t++;
+       }
+    } else if (ok_s || ok_t) {
+       return 1;
     }
+    return 0;
 }
 
 static void
@@ -572,7 +591,7 @@ append_acs0(string_desc * dst, int code, int src)
 static void
 append_acs(string_desc * dst, int code, char *src)
 {
-    if (src != 0 && strlen(src) == 1) {
+    if (VALID_STRING(src) && strlen(src) == 1) {
        append_acs0(dst, code, *src);
     }
 }
@@ -638,7 +657,7 @@ static const char C_HT[] = "\t";
 #define CUR tp->
 
 static void
-postprocess_termcap(TERMTYPE *tp, bool has_base)
+postprocess_termcap(TERMTYPE2 *tp, bool has_base)
 {
     char buf[MAX_LINE * 2 + 2];
     string_desc result;
@@ -833,15 +852,14 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
            }
 
            if (tp->Strings[to_ptr->nte_index]) {
+               const char *s = tp->Strings[from_ptr->nte_index];
+               const char *t = tp->Strings[to_ptr->nte_index];
                /* There's no point in warning about it if it's the same
                 * string; that's just an inefficiency.
                 */
-               if (strcmp(
-                             tp->Strings[from_ptr->nte_index],
-                             tp->Strings[to_ptr->nte_index]) != 0)
+               if (VALID_STRING(s) && VALID_STRING(t) && strcmp(s, t) != 0)
                    _nc_warning("%s (%s) already has an explicit value %s, ignoring ko",
-                               ap->to, ap->from,
-                               _nc_visbuf(tp->Strings[to_ptr->nte_index]));
+                               ap->to, ap->from, t);
                continue;
            }
 
@@ -928,7 +946,7 @@ postprocess_termcap(TERMTYPE *tp, bool has_base)
 }
 
 static void
-postprocess_terminfo(TERMTYPE *tp)
+postprocess_terminfo(TERMTYPE2 *tp)
 {
     /*
      * TERMINFO-TO-TERMINFO MAPPINGS FOR SOURCE TRANSLATION