/****************************************************************************
- * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2013,2016 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 *
#include <tic.h>
#include <ctype.h>
-#include <term_entry.h>
-
#ifndef CUR
#define CUR SP_TERMTYPE
#endif
-MODULE_ID("$Id: lib_termcap.c,v 1.67 2009/05/30 20:05:20 tom Exp $")
+MODULE_ID("$Id: lib_termcap.c,v 1.81 2016/05/28 23:22:52 tom Exp $")
NCURSES_EXPORT_VAR(char *) UP = 0;
NCURSES_EXPORT_VAR(char *) BC = 0;
#define LAST_USE MyCache[CacheInx].last_used
#define LAST_SEQ MyCache[CacheInx].sequence
+/*
+ * Termcap names are matched only using the first two bytes.
+ * Ignore any extended names longer than two bytes, to avoid problems
+ * with legacy code which passes in parameters whose use is long forgotten.
+ */
+#define ValidCap(cap) (((cap)[0] != '\0') && ((cap)[1] != '\0'))
+#define SameCap(a,b) (((a)[0] == (b)[0]) && ((a)[1] == (b)[1]))
+#define ValidExt(ext) (ValidCap(ext) && (ext)[2] == '\0')
+
/***************************************************************************
*
* tgetent(bufp, term)
NCURSES_EXPORT(int)
NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
{
- int errcode = ERR;
+ int rc = ERR;
int n;
bool found_cache = FALSE;
#ifdef USE_TERM_DRIVER
START_TRACE();
T((T_CALLED("tgetent()")));
-#ifdef USE_TERM_DRIVER
- _nc_setupterm_ex(&termp, (NCURSES_CONST char *) name,
- STDOUT_FILENO, &errcode, TRUE);
+ TINFO_SETUP_TERM(&termp, (NCURSES_CONST char *) name,
+ STDOUT_FILENO, &rc, TRUE);
+#ifdef USE_TERM_DRIVER
if (termp == 0 ||
!((TERMINAL_CONTROL_BLOCK *) termp)->drv->isTerminfo)
- return (errcode);
-#else
- _nc_setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode, TRUE);
+ returnCode(rc);
#endif
/*
BC = 0;
FIX_SGR0 = 0; /* don't free it - application may still use */
- if (errcode == 1) {
+ if (rc == 1) {
if (cursor_left)
if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
#endif*/
}
- returnCode(errcode);
+ returnCode(rc);
}
#if NCURSES_SP_FUNCS
}
#endif
+#if 0
+static bool
+same_tcname(const char *a, const char *b)
+{
+ bool code = SameCap(a, b);
+ fprintf(stderr, "compare(%s,%s) %s\n", a, b, code ? "same" : "diff");
+ return code;
+}
+
+#else
+#define same_tcname(a,b) SameCap(a,b)
+#endif
+
/***************************************************************************
*
* tgetflag(str)
NCURSES_EXPORT(int)
NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx NCURSES_CONST char *id)
{
- unsigned i;
+ int result = 0; /* Solaris returns zero for missing flag */
- T((T_CALLED("tgetflag(%p, %s)"), SP_PARM, id));
- if (HasTInfoTerminal(SP_PARM)) {
+ T((T_CALLED("tgetflag(%p, %s)"), (void *) SP_PARM, id));
+ if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
- for_each_boolean(i, tp) {
- const char *capname = ExtBoolname(tp, i, boolcodes);
- if (!strncmp(id, capname, 2)) {
- /* setupterm forces invalid booleans to false */
- returnCode(tp->Booleans[i]);
+ struct name_table_entry const *entry_ptr;
+ int j = -1;
+
+ entry_ptr = _nc_find_type_entry(id, BOOLEAN, TRUE);
+ if (entry_ptr != 0) {
+ j = entry_ptr->nte_index;
+ }
+#if NCURSES_XNAMES
+ else {
+ int i;
+ for_each_ext_boolean(i, tp) {
+ const char *capname = ExtBoolname(tp, i, boolcodes);
+ if (same_tcname(id, capname) && ValidExt(capname)) {
+ j = i;
+ break;
+ }
}
}
+#endif
+ if (j >= 0) {
+ /* note: setupterm forces invalid booleans to false */
+ result = tp->Booleans[j];
+ }
}
- returnCode(0); /* Solaris does this */
+ returnCode(result);
}
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(int)
NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx NCURSES_CONST char *id)
{
- unsigned i;
+ int result = ABSENT_NUMERIC;
- T((T_CALLED("tgetnum(%p, %s)"), SP_PARM, id));
- if (HasTInfoTerminal(SP_PARM)) {
+ T((T_CALLED("tgetnum(%p, %s)"), (void *) SP_PARM, id));
+ if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
- for_each_number(i, tp) {
- const char *capname = ExtNumname(tp, i, numcodes);
- if (!strncmp(id, capname, 2)) {
- if (!VALID_NUMERIC(tp->Numbers[i]))
- returnCode(ABSENT_NUMERIC);
- returnCode(tp->Numbers[i]);
+ struct name_table_entry const *entry_ptr;
+ int j = -1;
+
+ entry_ptr = _nc_find_type_entry(id, NUMBER, TRUE);
+ if (entry_ptr != 0) {
+ j = entry_ptr->nte_index;
+ }
+#if NCURSES_XNAMES
+ else {
+ int i;
+ for_each_ext_number(i, tp) {
+ const char *capname = ExtNumname(tp, i, numcodes);
+ if (same_tcname(id, capname) && ValidExt(capname)) {
+ j = i;
+ break;
+ }
}
}
+#endif
+ if (j >= 0) {
+ if (VALID_NUMERIC(tp->Numbers[j]))
+ result = tp->Numbers[j];
+ }
}
- returnCode(ABSENT_NUMERIC);
+ returnCode(result);
}
#if NCURSES_SP_FUNCS
NCURSES_EXPORT(char *)
NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area)
{
- unsigned i;
char *result = NULL;
- T((T_CALLED("tgetstr(%s,%p)"), id, area));
- if (HasTInfoTerminal(SP_PARM)) {
+ T((T_CALLED("tgetstr(%s,%p)"), id, (void *) area));
+ if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
- for_each_string(i, tp) {
- const char *capname = ExtStrname(tp, i, strcodes);
- if (!strncmp(id, capname, 2)) {
- result = tp->Strings[i];
- TR(TRACE_DATABASE, ("found match : %s", _nc_visbuf(result)));
- /* setupterm forces canceled strings to null */
- if (VALID_STRING(result)) {
- if (result == exit_attribute_mode
- && FIX_SGR0 != 0) {
- result = FIX_SGR0;
- TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
- }
- if (area != 0
- && *area != 0) {
- (void) strcpy(*area, result);
- result = *area;
- *area += strlen(*area) + 1;
- }
+ struct name_table_entry const *entry_ptr;
+ int j = -1;
+
+ entry_ptr = _nc_find_type_entry(id, STRING, TRUE);
+ if (entry_ptr != 0) {
+ j = entry_ptr->nte_index;
+ }
+#if NCURSES_XNAMES
+ else {
+ int i;
+ for_each_ext_string(i, tp) {
+ const char *capname = ExtStrname(tp, i, strcodes);
+ if (same_tcname(id, capname) && ValidExt(capname)) {
+ j = i;
+ break;
+ }
+ }
+ }
+#endif
+ if (j >= 0) {
+ result = tp->Strings[j];
+ TR(TRACE_DATABASE, ("found match %d: %s", j, _nc_visbuf(result)));
+ /* setupterm forces canceled strings to null */
+ if (VALID_STRING(result)) {
+ if (result == exit_attribute_mode
+ && FIX_SGR0 != 0) {
+ result = FIX_SGR0;
+ TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
+ }
+ if (area != 0
+ && *area != 0) {
+ _nc_STRCPY(*area, result, 1024);
+ result = *area;
+ *area += strlen(*area) + 1;
}
- break;
}
}
}