Update to ncurses-6.0

Change-Id: I98ab2ea8a5e13cca9f8b7cf6277b9b14a4da4299
diff --git a/ncurses/tinfo/comp_parse.c b/ncurses/tinfo/comp_parse.c
index 3325a0d..82a61a5 100644
--- a/ncurses/tinfo/comp_parse.c
+++ b/ncurses/tinfo/comp_parse.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2012,2013 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            *
@@ -35,15 +35,10 @@
 /*
  *	comp_parse.c -- parser driver loop and use handling.
  *
- *	_nc_read_entry_source(FILE *, literal, bool, bool (*hook)())
- *	_nc_resolve_uses2(void)
- *	_nc_free_entries(void)
- *
  *	Use this code by calling _nc_read_entry_source() on as many source
  *	files as you like (either terminfo or termcap syntax).  If you
  *	want use-resolution, call _nc_resolve_uses2().  To free the list
  *	storage, do _nc_free_entries().
- *
  */
 
 #include <curses.priv.h>
@@ -51,9 +46,8 @@
 #include <ctype.h>
 
 #include <tic.h>
-#include <term_entry.h>
 
-MODULE_ID("$Id: comp_parse.c,v 1.69 2008/08/16 21:58:16 tom Exp $")
+MODULE_ID("$Id: comp_parse.c,v 1.90 2013/08/31 15:22:31 tom Exp $")
 
 static void sanity_check2(TERMTYPE *, bool);
 NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype2) (TERMTYPE *, bool) = sanity_check2;
@@ -62,6 +56,8 @@
 static void sanity_check(TERMTYPE *);
 NCURSES_IMPEXP void NCURSES_API(*_nc_check_termtype) (TERMTYPE *) = sanity_check;
 
+static void fixup_acsc(TERMTYPE *, int);
+
 static void
 enqueue(ENTRY * ep)
 /* add an entry to the in-core list */
@@ -87,31 +83,125 @@
 	if (len > MAX_NAME_SIZE)
 	    len = MAX_NAME_SIZE;
 	(void) strncpy(dst, src, len);
-	(void) strcpy(dst + len, "|");
+	_nc_STRCPY(dst + len, "|", MAX_NAME_SIZE);
 	src = dst;
     }
     return src;
 }
+#define ForceBar(dst, src) ((strchr(src, '|') == 0) ? force_bar(dst, src) : src)
 
-NCURSES_EXPORT(bool)
-_nc_entry_match(char *n1, char *n2)
-/* do any of the aliases in a pair of terminal names match? */
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+static char *
+skip_index(char *name)
+{
+    char *bar = strchr(name, '|');
+
+    if (bar != 0 && (bar - name) == 2)
+	name = bar + 1;
+
+    return name;
+}
+#endif
+
+static bool
+check_collisions(char *n1, char *n2, int counter)
 {
     char *pstart, *qstart, *pend, *qend;
-    char nc1[MAX_NAME_SIZE + 2], nc2[MAX_NAME_SIZE + 2];
+    char nc1[MAX_NAME_SIZE + 2];
+    char nc2[MAX_NAME_SIZE + 2];
 
-    n1 = force_bar(nc1, n1);
-    n2 = force_bar(nc2, n2);
+    n1 = ForceBar(nc1, n1);
+    n2 = ForceBar(nc2, n2);
 
-    for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1)
-	for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1)
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+    if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
+	n1 = skip_index(n1);
+	n2 = skip_index(n2);
+    }
+#endif
+
+    for (pstart = n1; (pend = strchr(pstart, '|')); pstart = pend + 1) {
+	for (qstart = n2; (qend = strchr(qstart, '|')); qstart = qend + 1) {
 	    if ((pend - pstart == qend - qstart)
-		&& memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0)
+		&& memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) {
+		if (counter > 0)
+		    (void) fprintf(stderr, "Name collision '%.*s' between\n",
+				   (int) (pend - pstart), pstart);
 		return (TRUE);
+	    }
+	}
+    }
 
     return (FALSE);
 }
 
+static char *
+next_name(char *name)
+{
+    if (*name != '\0')
+	++name;
+    return name;
+}
+
+static char *
+name_ending(char *name)
+{
+    if (*name == '\0') {
+	name = 0;
+    } else {
+	while (*name != '\0' && *name != '|')
+	    ++name;
+    }
+    return name;
+}
+
+/*
+ * Essentially, find the conflict reported in check_collisions() and remove
+ * it from the second name, unless that happens to be the last alias.
+ */
+static bool
+remove_collision(char *n1, char *n2)
+{
+    char *p2 = n2;
+    char *pstart, *qstart, *pend, *qend;
+    bool removed = FALSE;
+
+#if NCURSES_USE_TERMCAP && NCURSES_XNAMES
+    if ((_nc_syntax == SYN_TERMCAP) && _nc_user_definable) {
+	n1 = skip_index(n1);
+	p2 = n2 = skip_index(n2);
+    }
+#endif
+
+    for (pstart = n1; (pend = name_ending(pstart)); pstart = next_name(pend)) {
+	for (qstart = n2; (qend = name_ending(qstart)); qstart = next_name(qend)) {
+	    if ((pend - pstart == qend - qstart)
+		&& memcmp(pstart, qstart, (size_t) (pend - pstart)) == 0) {
+		if (qstart != p2 || *qend == '|') {
+		    if (*qend == '|')
+			++qend;
+		    while ((*qstart++ = *qend++) != '\0') ;
+		    fprintf(stderr, "...now\t%s\n", p2);
+		} else {
+		    fprintf(stderr, "Cannot remove alias '%.*s'\n",
+			    (int) (qend - qstart), qstart);
+		}
+		removed = TRUE;
+		break;
+	    }
+	}
+    }
+
+    return removed;
+}
+
+/* do any of the aliases in a pair of terminal names match? */
+NCURSES_EXPORT(bool)
+_nc_entry_match(char *n1, char *n2)
+{
+    return check_collisions(n1, n2, 0);
+}
+
 /****************************************************************************
  *
  * Entry compiler and resolution logic
@@ -197,19 +287,19 @@
 
 	for_entry_list(rp) {
 	    if (qp > rp
-		&& _nc_entry_match(qp->tterm.term_names, rp->tterm.term_names)) {
-		matchcount++;
-		if (matchcount == 1) {
-		    (void) fprintf(stderr, "Name collision between %s",
-				   _nc_first_name(qp->tterm.term_names));
-		    multiples++;
+		&& check_collisions(qp->tterm.term_names,
+				    rp->tterm.term_names,
+				    matchcount + 1)) {
+		if (!matchcount++) {
+		    (void) fprintf(stderr, "\t%s\n", rp->tterm.term_names);
 		}
-		if (matchcount >= 1)
-		    (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names));
+		(void) fprintf(stderr, "and\t%s\n", qp->tterm.term_names);
+		if (!remove_collision(rp->tterm.term_names,
+				      qp->tterm.term_names)) {
+		    ++multiples;
+		}
 	    }
 	}
-	if (matchcount >= 1)
-	    (void) putc('\n', stderr);
     }
     if (multiples > 0)
 	return (FALSE);
@@ -255,9 +345,7 @@
 		    DEBUG(2, ("%s: resolving use=%s (compiled)",
 			      child, lookfor));
 
-		    rp = typeMalloc(ENTRY, 1);
-		    if (rp == 0)
-			_nc_err_abort(MSG_NO_MEMORY);
+		    TYPE_MALLOC(ENTRY, 1, rp);
 		    rp->tterm = thisterm;
 		    rp->nuses = 0;
 		    rp->next = lastread;
@@ -273,7 +361,7 @@
 		unresolved++;
 		total_unresolved++;
 
-		_nc_curr_line = lookline;
+		_nc_curr_line = (int) lookline;
 		_nc_warning("resolution of use=%s failed", lookfor);
 		qp->uses[i].link = 0;
 	    }
@@ -375,9 +463,36 @@
 	if (_nc_check_termtype != 0) {
 	    _nc_curr_col = -1;
 	    for_entry_list(qp) {
-		_nc_curr_line = qp->startline;
+		_nc_curr_line = (int) qp->startline;
 		_nc_set_type(_nc_first_name(qp->tterm.term_names));
-		_nc_check_termtype2(&qp->tterm, literal);
+		/*
+		 * tic overrides this function pointer to provide more verbose
+		 * checking.
+		 */
+		if (_nc_check_termtype2 != sanity_check2) {
+		    SCREEN *save_SP = SP;
+		    SCREEN fake_sp;
+		    TERMINAL fake_tm;
+		    TERMINAL *save_tm = cur_term;
+
+		    /*
+		     * Setup so that tic can use ordinary terminfo interface
+		     * to obtain capability information.
+		     */
+		    memset(&fake_sp, 0, sizeof(fake_sp));
+		    memset(&fake_tm, 0, sizeof(fake_tm));
+		    fake_sp._term = &fake_tm;
+		    fake_tm.type = qp->tterm;
+		    _nc_set_screen(&fake_sp);
+		    set_curterm(&fake_tm);
+
+		    _nc_check_termtype2(&qp->tterm, literal);
+
+		    _nc_set_screen(save_SP);
+		    set_curterm(save_tm);
+		} else {
+		    fixup_acsc(&qp->tterm, literal);
+		}
 	    }
 	    DEBUG(2, ("SANITY CHECK FINISHED"));
 	}
@@ -402,6 +517,17 @@
 #define CUR tp->
 
 static void
+fixup_acsc(TERMTYPE *tp, int literal)
+{
+    if (!literal) {
+	if (acs_chars == 0
+	    && enter_alt_charset_mode != 0
+	    && exit_alt_charset_mode != 0)
+	    acs_chars = strdup(VT_ACSC);
+    }
+}
+
+static void
 sanity_check2(TERMTYPE *tp, bool literal)
 {
     if (!PRESENT(exit_attribute_mode)) {
@@ -421,16 +547,14 @@
 #endif /* __UNUSED__ */
 	PAIRED(enter_standout_mode, exit_standout_mode);
 	PAIRED(enter_underline_mode, exit_underline_mode);
+	PAIRED(enter_italics_mode, exit_italics_mode);
     }
 
     /* we do this check/fix in postprocess_termcap(), but some packagers
      * prefer to bypass it...
      */
     if (!literal) {
-	if (acs_chars == 0
-	    && enter_alt_charset_mode != 0
-	    && exit_alt_charset_mode != 0)
-	    acs_chars = strdup(VT_ACSC);
+	fixup_acsc(tp, literal);
 	ANDMISSING(enter_alt_charset_mode, acs_chars);
 	ANDMISSING(exit_alt_charset_mode, acs_chars);
     }
@@ -473,7 +597,6 @@
 {
     _nc_alloc_entry_leaks();
     _nc_captoinfo_leaks();
-    _nc_comp_captab_leaks();
     _nc_comp_scan_leaks();
 #if BROKEN_LINKER || USE_REENTRANT
     _nc_names_leaks();