/****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2008,2009 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 *
/****************************************************************************
* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
* and: Eric S. Raymond <esr@snark.thyrsus.com> *
+ * and: Thomas E. Dickey 1996-on *
****************************************************************************/
/*
* from the input stream.
*/
+#define __INTERNAL_CAPS_VISIBLE
#include <curses.priv.h>
#include <ctype.h>
#include <tic.h>
-#define __INTERNAL_CAPS_VISIBLE
#include <term_entry.h>
-MODULE_ID("$Id: parse_entry.c,v 1.48 2000/10/03 09:38:48 tom Exp $")
+MODULE_ID("$Id: parse_entry.c,v 1.71 2009/07/11 18:14:21 tom Exp $")
#ifdef LINT
static short const parametrized[] =
case NUMBER:
first = tp->ext_Booleans;
last = tp->ext_Numbers + first;
- offset = tp->ext_Booleans + tp->ext_Numbers;
+ offset = (unsigned) (tp->ext_Booleans + tp->ext_Numbers);
tindex = tp->num_Numbers;
break;
case STRING:
- first = tp->ext_Booleans + tp->ext_Numbers;
+ first = (unsigned) (tp->ext_Booleans + tp->ext_Numbers);
last = tp->ext_Strings + first;
- offset = tp->ext_Booleans + tp->ext_Numbers + tp->ext_Strings;
+ offset = (unsigned) (tp->ext_Booleans + tp->ext_Numbers + tp->ext_Strings);
tindex = tp->num_Strings;
break;
case CANCEL:
break;
}
}
+
+#define for_each_value(max) \
+ for (last = (unsigned) (max - 1); last > tindex; last--)
+
if (!found) {
switch (token_type) {
case BOOLEAN:
- tp->ext_Booleans += 1;
- tp->num_Booleans += 1;
- tp->Booleans = typeRealloc(char, tp->num_Booleans, tp->Booleans);
- for (last = tp->num_Booleans - 1; last > tindex; last--)
+ tp->ext_Booleans++;
+ tp->num_Booleans++;
+ tp->Booleans = typeRealloc(NCURSES_SBOOL, tp->num_Booleans, tp->Booleans);
+ for_each_value(tp->num_Booleans)
tp->Booleans[last] = tp->Booleans[last - 1];
break;
case NUMBER:
- tp->ext_Numbers += 1;
- tp->num_Numbers += 1;
+ tp->ext_Numbers++;
+ tp->num_Numbers++;
tp->Numbers = typeRealloc(short, tp->num_Numbers, tp->Numbers);
- for (last = tp->num_Numbers - 1; last > tindex; last--)
+ for_each_value(tp->num_Numbers)
tp->Numbers[last] = tp->Numbers[last - 1];
break;
case STRING:
- tp->ext_Strings += 1;
- tp->num_Strings += 1;
+ tp->ext_Strings++;
+ tp->num_Strings++;
tp->Strings = typeRealloc(char *, tp->num_Strings, tp->Strings);
- for (last = tp->num_Strings - 1; last > tindex; last--)
+ for_each_value(tp->num_Strings)
tp->Strings[last] = tp->Strings[last - 1];
break;
}
temp.nte_name = tp->ext_Names[offset];
temp.nte_type = token_type;
- temp.nte_index = tindex;
+ temp.nte_index = (short) tindex;
temp.nte_link = -1;
return &temp;
* if the token was not a name in column 1, complain and die
* save names in entry's string table
* while (get_token() is not EOF and not NAMES)
- * check for existance and type-correctness
+ * check for existence and type-correctness
* enter cap into structure
* if STRING
* save string in entry's string table
* push back token
*/
-int
+#define BAD_TC_USAGE if (!bad_tc_usage) \
+ { bad_tc_usage = TRUE; \
+ _nc_warning("Legacy termcap allows only a trailing tc= clause"); }
+
+NCURSES_EXPORT(int)
_nc_parse_entry(struct entry *entryp, int literal, bool silent)
{
int token_type;
struct name_table_entry const *entry_ptr;
char *ptr, *base;
+ bool bad_tc_usage = FALSE;
- token_type = _nc_get_token();
+ token_type = _nc_get_token(silent);
if (token_type == EOF)
return (EOF);
entryp->startline = _nc_start_line;
DEBUG(2, ("Comment range is %ld to %ld", entryp->cstart, entryp->cend));
- /* junk the 2-character termcap name, if present */
+ /*
+ * Strip off the 2-character termcap name, if present. Originally termcap
+ * used that as an indexing aid. We can retain 2-character terminfo names,
+ * but note that they would be lost if we translate to/from termcap. This
+ * feature is supposedly obsolete since "newer" BSD implementations do not
+ * use it; however our reference for this feature is SunOS 4.x, which
+ * implemented it. Note that the resulting terminal type was never the
+ * 2-character name, but was instead the first alias after that.
+ */
ptr = _nc_curr_token.tk_name;
- if (ptr[2] == '|') {
- ptr = _nc_curr_token.tk_name + 3;
- _nc_curr_token.tk_name[2] = '\0';
+ if (_nc_syntax == SYN_TERMCAP
+#if NCURSES_XNAMES
+ && !_nc_user_definable
+#endif
+ ) {
+ if (ptr[2] == '|') {
+ ptr += 3;
+ _nc_curr_token.tk_name[2] = '\0';
+ }
}
entryp->tterm.str_table = entryp->tterm.term_names = _nc_save_str(ptr);
+ if (entryp->tterm.str_table == 0)
+ return (ERR);
+
DEBUG(1, ("Starting '%s'", ptr));
/*
(base == entryp->tterm.term_names)
? "primary name"
: "alias",
- ptr - base, base);
+ (int) (ptr - base), base);
}
}
entryp->nuses = 0;
- for (token_type = _nc_get_token();
+ for (token_type = _nc_get_token(silent);
token_type != EOF && token_type != NAMES;
- token_type = _nc_get_token()) {
- if (strcmp(_nc_curr_token.tk_name, "use") == 0
- || strcmp(_nc_curr_token.tk_name, "tc") == 0) {
+ token_type = _nc_get_token(silent)) {
+ bool is_use = (strcmp(_nc_curr_token.tk_name, "use") == 0);
+ bool is_tc = !is_use && (strcmp(_nc_curr_token.tk_name, "tc") == 0);
+ 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
+ }
} else {
/* normal token lookup */
entry_ptr = _nc_find_entry(_nc_curr_token.tk_name,
- _nc_syntax ? _nc_cap_hash_table : _nc_info_hash_table);
+ _nc_get_hash_table(_nc_syntax));
/*
* Our kluge to handle aliasing. The reason it's done
const struct alias *ap;
if (_nc_syntax == SYN_TERMCAP) {
- for (ap = _nc_capalias_table; ap->from; ap++)
+ if (entryp->nuses != 0) {
+ BAD_TC_USAGE
+ }
+ for (ap = _nc_get_alias_table(TRUE); ap->from; ap++)
if (strcmp(ap->from, _nc_curr_token.tk_name) == 0) {
if (ap->to == (char *) 0) {
_nc_warning("%s (%s termcap extension) ignored",
goto nexttok;
}
- entry_ptr = _nc_find_entry(ap->to, _nc_cap_hash_table);
+ entry_ptr = _nc_find_entry(ap->to,
+ _nc_get_hash_table(TRUE));
if (entry_ptr && !silent)
_nc_warning("%s (%s termcap extension) aliased to %s",
ap->from, ap->source, ap->to);
break;
}
} else { /* if (_nc_syntax == SYN_TERMINFO) */
- for (ap = _nc_infoalias_table; ap->from; ap++)
+ for (ap = _nc_get_alias_table(FALSE); ap->from; ap++)
if (strcmp(ap->from, _nc_curr_token.tk_name) == 0) {
if (ap->to == (char *) 0) {
_nc_warning("%s (%s terminfo extension) ignored",
goto nexttok;
}
- entry_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);
+ entry_ptr = _nc_find_entry(ap->to,
+ _nc_get_hash_table(FALSE));
if (entry_ptr && !silent)
_nc_warning("%s (%s terminfo extension) aliased to %s",
ap->from, ap->source, ap->to);
* type, this will do the job.
*/
- /* tell max_attributes from arrow_key_map */
- if (token_type == NUMBER && !strcmp("ma", _nc_curr_token.tk_name))
+ if (token_type == NUMBER
+ && !strcmp("ma", _nc_curr_token.tk_name)) {
+ /* tell max_attributes from arrow_key_map */
entry_ptr = _nc_find_type_entry("ma", NUMBER,
- _nc_get_table(_nc_syntax
- != 0));
+ _nc_syntax != 0);
+ assert(entry_ptr != 0);
- /* map terminfo's string MT to MT */
- else if (token_type == STRING && !strcmp("MT", _nc_curr_token.tk_name))
+ } else if (token_type == STRING
+ && !strcmp("MT", _nc_curr_token.tk_name)) {
+ /* map terminfo's string MT to MT */
entry_ptr = _nc_find_type_entry("MT", STRING,
- _nc_get_table(_nc_syntax
- != 0));
+ _nc_syntax != 0);
+ assert(entry_ptr != 0);
- /* treat strings without following "=" as empty strings */
- else if (token_type == BOOLEAN && entry_ptr->nte_type == STRING)
+ } else if (token_type == BOOLEAN
+ && entry_ptr->nte_type == STRING) {
+ /* treat strings without following "=" as empty strings */
token_type = STRING;
- /* we couldn't recover; skip this token */
- else {
+ } else {
+ /* we couldn't recover; skip this token */
if (!silent) {
const char *type_name;
switch (entry_ptr->nte_type) {
case NUMBER:
entryp->tterm.Numbers[entry_ptr->nte_index] =
- _nc_curr_token.tk_valnumber;
+ (short) _nc_curr_token.tk_valnumber;
break;
case STRING:
default:
if (!silent)
_nc_warning("unknown token type");
- _nc_panic_mode((_nc_syntax == SYN_TERMCAP) ? ':' : ',');
+ _nc_panic_mode((char) ((_nc_syntax == SYN_TERMCAP) ? ':' : ','));
continue;
}
} /* end else cur_token.name != "use" */
if (!literal) {
if (_nc_syntax == SYN_TERMCAP) {
bool has_base_entry = FALSE;
- int i;
+ unsigned i;
/*
* Don't insert defaults if this is a `+' entry meant only
} else
postprocess_terminfo(&entryp->tterm);
}
- _nc_wrap_entry(entryp);
+ _nc_wrap_entry(entryp, FALSE);
return (OK);
}
-int
+NCURSES_EXPORT(int)
_nc_capcmp(const char *s, const char *t)
/* compare two string capabilities, stripping out padding */
{
for (;;) {
if (s[0] == '$' && s[1] == '<') {
for (s += 2;; s++)
- if (!(isdigit(*s) || *s == '.' || *s == '*' || *s == '/' ||
- *s == '>'))
+ if (!(isdigit(UChar(*s))
+ || *s == '.'
+ || *s == '*'
+ || *s == '/'
+ || *s == '>'))
break;
}
if (t[0] == '$' && t[1] == '<') {
for (t += 2;; t++)
- if (!(isdigit(*t) || *t == '.' || *t == '*' || *t == '/' ||
- *t == '>'))
+ if (!(isdigit(UChar(*t))
+ || *t == '.'
+ || *t == '*'
+ || *t == '/'
+ || *t == '>'))
break;
}
}
static void
-append_acs0(string_desc *dst, int code, int src)
+append_acs0(string_desc * dst, int code, int src)
{
if (src != 0) {
char temp[3];
- temp[0] = code;
- temp[1] = src;
+ temp[0] = (char) code;
+ temp[1] = (char) src;
temp[2] = 0;
_nc_safe_strcat(dst, temp);
}
}
static void
-append_acs(string_desc *dst, int code, char *src)
+append_acs(string_desc * dst, int code, char *src)
{
if (src != 0 && strlen(src) == 1) {
append_acs0(dst, code, *src);
#define CUR tp->
static void
-postprocess_termcap(TERMTYPE * tp, bool has_base)
+postprocess_termcap(TERMTYPE *tp, bool has_base)
{
char buf[MAX_LINE * 2 + 2];
string_desc result;
} else if (PRESENT(carriage_return) && PRESENT(scroll_forward)) {
_nc_str_init(&result, buf, sizeof(buf));
if (_nc_safe_strcat(&result, carriage_return)
- && _nc_safe_strcat(&result, scroll_forward))
+ && _nc_safe_strcat(&result, scroll_forward))
newline = _nc_save_str(buf);
} else if (PRESENT(carriage_return) && PRESENT(cursor_down)) {
_nc_str_init(&result, buf, sizeof(buf));
if (_nc_safe_strcat(&result, carriage_return)
- && _nc_safe_strcat(&result, cursor_down))
+ && _nc_safe_strcat(&result, cursor_down))
newline = _nc_save_str(buf);
}
}
for (base = other_non_function_keys;
(cp = strchr(base, ',')) != 0;
base = cp + 1) {
- size_t len = cp - base;
+ size_t len = (unsigned) (cp - base);
- for (ap = ko_xlate; ap->from; ap++)
+ for (ap = ko_xlate; ap->from; ap++) {
if (len == strlen(ap->from)
&& strncmp(ap->from, base, len) == 0)
break;
- if (!ap->to) {
+ }
+ if (!(ap->from && ap->to)) {
_nc_warning("unknown capability `%.*s' in ko string",
(int) len, base);
continue;
/* now we know we found a match in ko_table, so... */
- from_ptr = _nc_find_entry(ap->from, _nc_cap_hash_table);
- to_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);
+ from_ptr = _nc_find_entry(ap->from, _nc_get_hash_table(TRUE));
+ to_ptr = _nc_find_entry(ap->to, _nc_get_hash_table(FALSE));
if (!from_ptr || !to_ptr) /* should never happen! */
_nc_err_abort("ko translation table is invalid, I give up");
}
}
- if (!hard_copy) {
- if (WANTED(key_backspace))
- key_backspace = _nc_save_str(C_BS);
- if (WANTED(key_left))
- key_left = _nc_save_str(C_BS);
- if (WANTED(key_down))
- key_down = _nc_save_str(C_LF);
+ if (!has_base) {
+ if (!hard_copy) {
+ if (WANTED(key_backspace))
+ key_backspace = _nc_save_str(C_BS);
+ if (WANTED(key_left))
+ key_left = _nc_save_str(C_BS);
+ if (WANTED(key_down))
+ key_down = _nc_save_str(C_LF);
+ }
}
/*
_nc_str_init(&result, buf2, sizeof(buf2));
_nc_safe_strcat(&result, acs_chars);
- append_acs (&result, 'j', acs_lrcorner);
- append_acs (&result, 'k', acs_urcorner);
- append_acs (&result, 'l', acs_ulcorner);
- append_acs (&result, 'm', acs_llcorner);
- append_acs (&result, 'n', acs_plus);
- append_acs (&result, 'q', acs_hline);
- append_acs (&result, 't', acs_ltee);
- append_acs (&result, 'u', acs_rtee);
- append_acs (&result, 'v', acs_btee);
- append_acs (&result, 'w', acs_ttee);
- append_acs (&result, 'x', acs_vline);
+ append_acs(&result, 'j', acs_lrcorner);
+ append_acs(&result, 'k', acs_urcorner);
+ append_acs(&result, 'l', acs_ulcorner);
+ append_acs(&result, 'm', acs_llcorner);
+ append_acs(&result, 'n', acs_plus);
+ append_acs(&result, 'q', acs_hline);
+ append_acs(&result, 't', acs_ltee);
+ append_acs(&result, 'u', acs_rtee);
+ append_acs(&result, 'v', acs_btee);
+ append_acs(&result, 'w', acs_ttee);
+ append_acs(&result, 'x', acs_vline);
if (buf2[0]) {
acs_chars = _nc_save_str(buf2);
} else if (acs_chars == 0
&& enter_alt_charset_mode != 0
&& exit_alt_charset_mode != 0) {
- acs_chars =
- _nc_save_str("``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~");
+ acs_chars = _nc_save_str(VT_ACSC);
}
}
static void
-postprocess_terminfo(TERMTYPE * tp)
+postprocess_terminfo(TERMTYPE *tp)
{
/*
* TERMINFO-TO-TERMINFO MAPPINGS FOR SOURCE TRANSLATION
_nc_str_init(&result, buf2, sizeof(buf2));
_nc_safe_strcat(&result, acs_chars);
- append_acs0 (&result, 'l', box_chars_1[0]); /* ACS_ULCORNER */
- append_acs0 (&result, 'q', box_chars_1[1]); /* ACS_HLINE */
- append_acs0 (&result, 'k', box_chars_1[2]); /* ACS_URCORNER */
- append_acs0 (&result, 'x', box_chars_1[3]); /* ACS_VLINE */
- append_acs0 (&result, 'j', box_chars_1[4]); /* ACS_LRCORNER */
- append_acs0 (&result, 'm', box_chars_1[5]); /* ACS_LLCORNER */
- append_acs0 (&result, 'w', box_chars_1[6]); /* ACS_TTEE */
- append_acs0 (&result, 'u', box_chars_1[7]); /* ACS_RTEE */
- append_acs0 (&result, 'v', box_chars_1[8]); /* ACS_BTEE */
- append_acs0 (&result, 't', box_chars_1[9]); /* ACS_LTEE */
- append_acs0 (&result, 'n', box_chars_1[10]); /* ACS_PLUS */
+ append_acs0(&result, 'l', box_chars_1[0]); /* ACS_ULCORNER */
+ append_acs0(&result, 'q', box_chars_1[1]); /* ACS_HLINE */
+ append_acs0(&result, 'k', box_chars_1[2]); /* ACS_URCORNER */
+ append_acs0(&result, 'x', box_chars_1[3]); /* ACS_VLINE */
+ append_acs0(&result, 'j', box_chars_1[4]); /* ACS_LRCORNER */
+ append_acs0(&result, 'm', box_chars_1[5]); /* ACS_LLCORNER */
+ append_acs0(&result, 'w', box_chars_1[6]); /* ACS_TTEE */
+ append_acs0(&result, 'u', box_chars_1[7]); /* ACS_RTEE */
+ append_acs0(&result, 'v', box_chars_1[8]); /* ACS_BTEE */
+ append_acs0(&result, 't', box_chars_1[9]); /* ACS_LTEE */
+ append_acs0(&result, 'n', box_chars_1[10]); /* ACS_PLUS */
if (buf2[0]) {
acs_chars = _nc_save_str(buf2);