1
1
/* infomap.c -- keymaps for Info.
2
$Id: infomap.c,v 1.28 2002/02/08 23:02:53 karl Exp $
2
$Id: infomap.c,v 1.10 2004/07/30 20:43:40 karl Exp $
4
Copyright (C) 1993, 97, 98, 99, 2001, 02 Free Software Foundation, Inc.
4
Copyright (C) 1993, 1997, 1998, 1999, 2001, 2002, 2003, 2004 Free Software
6
7
This program is free software; you can redistribute it and/or modify
7
8
it under the terms of the GNU General Public License as published by
66
static FUNCTION_KEYSEQ *
67
find_function_keyseq (Keymap map, int c, Keymap rootmap)
71
if (map[c].type != ISFUNC)
73
if (map[c].function == NULL)
75
for (k = map[c].function->keys; k; k = k->next)
77
const unsigned char *p;
79
if (k->map != rootmap)
81
for (p = (unsigned char *) k->keyseq; *p && m[*p].type == ISKMAP; p++)
82
m = (Keymap)m[*p].function;
85
if (m[*p].type != ISFUNC)
93
add_function_keyseq (InfoCommand *function,
94
const char *keyseq, Keymap rootmap)
98
if (function == NULL ||
99
function == InfoCmd(info_do_lowercase_version) ||
100
function == InfoCmd(ea_insert))
102
ks = (FUNCTION_KEYSEQ *)xmalloc (sizeof(FUNCTION_KEYSEQ));
103
ks->next = function->keys;
105
ks->keyseq = xstrdup(keyseq);
110
remove_function_keyseq (InfoCommand *function,
111
const char *keyseq, Keymap rootmap)
114
FUNCTION_KEYSEQ *k, *kp;
116
if (function == NULL ||
117
function == InfoCmd(info_do_lowercase_version) ||
118
function == InfoCmd(ea_insert))
120
for (kp = NULL, k = function->keys; k; kp = k, k = k->next)
121
if (k->map == rootmap && strcmp(k->keyseq, keyseq) == 0)
128
function->keys = k->next;
61
132
/* Return a new keymap which is a copy of MAP. */
63
keymap_copy_keymap (map)
134
keymap_copy_keymap (Keymap map, Keymap rootmap, Keymap newroot)
69
142
keymap = keymap_make_keymap ();
71
146
for (i = 0; i < 256; i++)
73
148
keymap[i].type = map[i].type;
74
keymap[i].function = map[i].function;
152
keymap[i].function = map[i].function;
154
ks = find_function_keyseq (map, i, rootmap);
156
add_function_keyseq(map[i].function, ks->keyseq, newroot);
160
keymap[i].function = (InfoCommand *)keymap_copy_keymap
161
((Keymap)map[i].function, rootmap, NULL);
79
168
/* Free the keymap and its descendants. */
81
keymap_discard_keymap (map)
170
keymap_discard_keymap (Keymap map, Keymap rootmap)
89
179
for (i = 0; i < 256; i++)
91
184
switch (map[i].type)
188
ks = find_function_keyseq(map, i, rootmap);
190
remove_function_keyseq (map[i].function, ks->keyseq, rootmap);
97
keymap_discard_keymap ((Keymap)map[i].function);
195
keymap_discard_keymap ((Keymap)map[i].function, rootmap);
104
203
/* Conditionally bind key sequence. */
106
keymap_bind_keyseq (map, keyseq, keyentry)
108
const unsigned char *keyseq;
109
KEYMAP_ENTRY *keyentry;
205
keymap_bind_keyseq (Keymap map,
206
const char *keyseq, KEYMAP_ENTRY *keyentry)
112
const unsigned char *s = keyseq;
209
const unsigned char *s = (unsigned char *) keyseq;
115
212
if (s == NULL || *s == '\0') return 0;
117
214
while ((c = *s++) != '\0')
119
219
switch (m[c].type)
223
ks = find_function_keyseq(m, c, map);
225
remove_function_keyseq (m[c].function, ks->keyseq, map);
122
227
if (!(m[c].function == NULL || (
123
#if !defined(INFOKEY)
125
#endif /* !INFOKEY */
126
229
m[c].function == InfoCmd(info_do_lowercase_version))
232
#endif /* !INFOKEY */
132
236
m[c].type = ISKMAP;
237
/* Here we are casting the Keymap pointer returned from
238
keymap_make_keymap to an InfoCommand pointer. Ugh.
239
This makes the `function' structure garbage
240
if it's actually interpreted as an InfoCommand.
241
Should really be using a union, and taking steps to
242
avoid the possible error. */
133
243
m[c].function = (InfoCommand *)keymap_make_keymap ();
250
keymap_discard_keymap ((Keymap)m[c].function, map);
1078
1182
'H', NUL, A_info_get_help_window,
1079
1183
'i', NUL, A_info_index_search,
1080
1184
'I', NUL, A_info_goto_invocation_node,
1081
'j', NUL, A_info_down_line,
1082
'k', NUL, A_info_up_line,
1185
'j', NUL, A_info_next_line,
1186
'k', NUL, A_info_prev_line,
1083
1187
'l', NUL, A_info_history_node,
1084
1188
'm', NUL, A_info_menu_item,
1085
1189
'n', NUL, A_info_search_next,
1428
1532
|| buf[len - 1] != INFOKEY_MAGIC_E3
1431
info_error(_("Invalid infokey file `%s' (bad magic numbers) -- run infokey to update it"), filename);
1535
info_error((char *) _("Invalid infokey file `%s' (bad magic numbers) -- run infokey to update it"),
1432
1537
free(filename);
1435
if (len < INFOKEY_NMAGIC + strlen(VERSION) + 1 || strcmp(VERSION, buf + 4) != 0)
1540
if (len < INFOKEY_NMAGIC + strlen(VERSION) + 1
1541
|| strcmp(VERSION, (char *) (buf + 4)) != 0)
1437
info_error(_("Your infokey file `%s' is out of date -- run infokey to update it"), filename);
1544
((char *) _("Your infokey file `%s' is out of date -- run infokey to update it"),
1438
1546
free(filename);
1442
1550
/* Extract the pieces. */
1443
for (p = buf + 4 + strlen(VERSION) + 1; p - buf < len - 4; p += n)
1551
for (p = buf + 4 + strlen(VERSION) + 1;
1552
(unsigned int) (p - buf) < len - 4;
1447
1557
n = getint(&p);
1448
if (n < 0 || n > len - 4 - (p - buf))
1558
if (n < 0 || (unsigned int) n > len - 4 - (p - buf))
1450
info_error(_("Invalid infokey file `%s' (bad section length) -- run infokey to update it"), filename);
1560
info_error((char *) _("Invalid infokey file `%s' (bad section length) -- run infokey to update it"),
1451
1562
free(filename);
1482
1594
doesn't define.
1485
decode_keys(src, slen, dst, dlen)
1597
decode_keys(unsigned char *src, unsigned int slen,
1598
unsigned char *dst, unsigned int dlen)
1491
1600
unsigned char *s = src;
1492
1601
unsigned char *d = dst;
1494
#define To_dst(c) do { if (d - dst < dlen) *d++ = (c); } while (0)
1603
#define To_dst(c) do { \
1604
if ((unsigned int) (d - dst) < dlen) *d++ = (c); \
1496
while (s - src < slen)
1607
while ((unsigned int) (s - src) < slen)
1498
1609
unsigned char c = ISMETA(*s) ? UNMETA(*s) : *s;
1500
1611
if (c == SK_ESCAPE)
1503
1614
static char lit[] = { SK_ESCAPE, NUL };
1505
switch (s + 1 - src < slen ? s[1] : '\0')
1616
switch ((unsigned int) (s + 1 - src) < slen ? s[1] : '\0')
1507
1618
case SK_RIGHT_ARROW: t = term_kr; break;
1508
1619
case SK_LEFT_ARROW: t = term_kl; break;
1543
1654
/* Convert an infokey file section to keymap bindings. Return false if
1544
1655
the default bindings are to be suppressed. */
1546
section_to_keymaps(map, table, len)
1548
unsigned char *table;
1657
section_to_keymaps(Keymap map, unsigned char *table, unsigned int len)
1552
1660
unsigned char *p;
1554
unsigned int seqlen;
1661
unsigned char *seq = NULL;
1662
unsigned int seqlen = 0;
1556
1663
enum { getseq, gotseq, getaction } state = getseq;
1558
1665
stop = len > 0 ? table[0] : 0;
1560
for (p = table + 1; p - table < len; p++)
1667
for (p = table + 1; (unsigned int) (p - table) < len; p++)
1598
1705
action < A_NCOMMANDS
1599
1706
? &function_doc_array[action]
1601
keymap_bind_keyseq(map, keyseq, &ke);
1708
keymap_bind_keyseq(map,
1709
(const char *) keyseq, &ke);
1607
1715
if (state != getseq)
1608
info_error(_("Bad data in infokey file -- some key bindings ignored"));
1716
info_error((char *) _("Bad data in infokey file -- some key bindings ignored"),
1612
1721
/* Convert an infokey file section to variable settings.
1615
section_to_vars(table, len)
1616
unsigned char *table;
1724
section_to_vars(unsigned char *table, unsigned int len)
1619
1726
enum { getvar, gotvar, getval, gotval } state = getvar;
1620
1727
unsigned char *var = NULL;
1621
1728
unsigned char *val = NULL;
1622
1729
unsigned char *p;
1624
for (p = table; p - table < len; p++)
1731
for (p = table; (unsigned int) (p - table) < len; p++)