+#if NCURSES_XNAMES
+static unsigned
+find_capname(TERMTYPE2 *p, const char *name)
+{
+ unsigned num_names = NUM_EXT_NAMES(p);
+ unsigned n;
+ for (n = 0; n < num_names; ++n) {
+ if (!strcmp(p->ext_Names[n], name))
+ break;
+ }
+ return n;
+}
+
+static int
+extended_captype(TERMTYPE2 *p, unsigned which)
+{
+ int result = UNDEF;
+ unsigned limit = 0;
+ limit += p->ext_Booleans;
+ if (limit != 0 && which < limit) {
+ result = BOOLEAN;
+ } else {
+ limit += p->ext_Numbers;
+ if (limit != 0 && which < limit) {
+ result = NUMBER;
+ } else {
+ limit += p->ext_Strings;
+ if (limit != 0 && which < limit) {
+ result = STRING;
+ } else if (which >= limit) {
+ result = CANCEL;
+ }
+ }
+ }
+ return result;
+}
+
+static const char *
+name_of_captype(int which)
+{
+ const char *result = "?";
+ switch (which) {
+ case BOOLEAN:
+ result = "boolean";
+ break;
+ case NUMBER:
+ result = "number";
+ break;
+ case STRING:
+ result = "string";
+ break;
+ }
+ return result;
+}
+
+/*
+ * Disallow changing the type of an extended capability when doing a "use"
+ * if one or the other is a string.
+ */
+static int
+invalid_merge(TERMTYPE2 *to, TERMTYPE2 *from)
+{
+ int rc = FALSE;
+ char *to_name = _nc_first_name(to->term_names);
+ char *from_name = strdup(_nc_first_name(from->term_names));
+ unsigned num_names = NUM_EXT_NAMES(from);
+ unsigned n;
+
+ for (n = 0; n < num_names; ++n) {
+ const char *capname = from->ext_Names[n];
+ int tt = extended_captype(to, find_capname(to, capname));
+ int tf = extended_captype(from, n);
+
+ if (tt <= STRING
+ && tf <= STRING
+ && (tt == STRING) != (tf == STRING)) {
+ if (from_name != 0 && strcmp(to_name, from_name)) {
+ DEBUG(2,
+ ("merge of %s to %s changes type of %s from %s to %s",
+ from_name,
+ to_name,
+ from->ext_Names[n],
+ name_of_captype(tf),
+ name_of_captype(tt)));
+ } else {
+ DEBUG(2, ("merge of %s changes type of %s from %s to %s",
+ to_name,
+ from->ext_Names[n],
+ name_of_captype(tf),
+ name_of_captype(tt)));
+ }
+ _nc_warning("merge changes type of %s from %s to %s",
+ from->ext_Names[n],
+ name_of_captype(tf),
+ name_of_captype(tt));
+ rc = TRUE;
+ }
+ }
+ free(from_name);
+ return rc;
+}
+#define validate_merge(p, q) \
+ if (invalid_merge(&((p)->tterm), &((q)->tterm))) \
+ return FALSE
+#else
+#define validate_merge(p, q) /* nothing */
+#endif
+