~ubuntu-branches/ubuntu/maverick/texinfo/maverick

« back to all changes in this revision

Viewing changes to info/infomap.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2005-10-28 15:10:30 UTC
  • mto: (2.1.1 dapper) (3.1.4 hardy)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20051028151030-9nsf2s2k2z3fktjt
Tags: upstream-4.8
ImportĀ upstreamĀ versionĀ 4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 $
3
3
 
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
 
5
   Foundation, Inc.
5
6
 
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
29
30
#include "variables.h"
30
31
#endif /* INFOKEY */
31
32
 
 
33
static int keymap_bind_keyseq (Keymap map, const char *keyseq,
 
34
    KEYMAP_ENTRY *keyentry);
 
35
 
32
36
/* Return a new keymap which has all the uppercase letters mapped to run
33
37
   the function info_do_lowercase_version (). */
34
38
Keymap
35
 
keymap_make_keymap ()
 
39
keymap_make_keymap (void)
36
40
{
37
41
  int i;
38
42
  Keymap keymap;
58
62
  return (keymap);
59
63
}
60
64
 
 
65
#if defined(INFOKEY)
 
66
static FUNCTION_KEYSEQ *
 
67
find_function_keyseq (Keymap map, int c, Keymap rootmap)
 
68
{
 
69
  FUNCTION_KEYSEQ *k;
 
70
 
 
71
  if (map[c].type != ISFUNC)
 
72
    abort();
 
73
  if (map[c].function == NULL)
 
74
    return NULL;
 
75
  for (k = map[c].function->keys; k; k = k->next)
 
76
    {
 
77
      const unsigned char *p;
 
78
      Keymap m = rootmap;
 
79
      if (k->map != rootmap)
 
80
        continue;
 
81
      for (p = (unsigned char *) k->keyseq; *p && m[*p].type == ISKMAP; p++)
 
82
        m = (Keymap)m[*p].function;
 
83
      if (*p != c || p[1])
 
84
        continue;
 
85
      if (m[*p].type != ISFUNC)
 
86
        abort ();
 
87
      break;
 
88
    }
 
89
  return k;
 
90
}
 
91
 
 
92
static void
 
93
add_function_keyseq (InfoCommand *function,
 
94
    const char *keyseq, Keymap rootmap)
 
95
{
 
96
  FUNCTION_KEYSEQ *ks;
 
97
 
 
98
  if (function == NULL ||
 
99
      function == InfoCmd(info_do_lowercase_version) ||
 
100
      function == InfoCmd(ea_insert))
 
101
    return;
 
102
  ks = (FUNCTION_KEYSEQ *)xmalloc (sizeof(FUNCTION_KEYSEQ));
 
103
  ks->next = function->keys;
 
104
  ks->map = rootmap;
 
105
  ks->keyseq = xstrdup(keyseq);
 
106
  function->keys = ks;
 
107
}
 
108
 
 
109
static void
 
110
remove_function_keyseq (InfoCommand *function,
 
111
    const char *keyseq, Keymap rootmap)
 
112
{
 
113
 
 
114
  FUNCTION_KEYSEQ *k, *kp;
 
115
 
 
116
  if (function == NULL ||
 
117
      function == InfoCmd(info_do_lowercase_version) ||
 
118
      function == InfoCmd(ea_insert))
 
119
    return;
 
120
  for (kp = NULL, k = function->keys; k; kp = k, k = k->next)
 
121
    if (k->map == rootmap && strcmp(k->keyseq, keyseq) == 0)
 
122
      break;
 
123
  if (!k)
 
124
    abort ();
 
125
  if (kp)
 
126
    kp->next = k->next;
 
127
  else
 
128
    function->keys = k->next;
 
129
}
 
130
#endif /* INFOKEY */
 
131
 
61
132
/* Return a new keymap which is a copy of MAP. */
62
133
Keymap
63
 
keymap_copy_keymap (map)
64
 
     Keymap map;
 
134
keymap_copy_keymap (Keymap map, Keymap rootmap, Keymap newroot)
65
135
{
66
136
  int i;
67
137
  Keymap keymap;
 
138
#if defined(INFOKEY)
 
139
  FUNCTION_KEYSEQ *ks;
 
140
#endif /* INFOKEY */
68
141
 
69
142
  keymap = keymap_make_keymap ();
 
143
  if (!newroot)
 
144
    newroot = keymap;
70
145
 
71
146
  for (i = 0; i < 256; i++)
72
147
    {
73
148
      keymap[i].type = map[i].type;
74
 
      keymap[i].function = map[i].function;
 
149
      switch (map[i].type)
 
150
        {
 
151
        case ISFUNC:
 
152
          keymap[i].function = map[i].function;
 
153
#if defined(INFOKEY)
 
154
          ks = find_function_keyseq (map, i, rootmap);
 
155
          if (ks)
 
156
            add_function_keyseq(map[i].function, ks->keyseq, newroot);
 
157
#endif /* INFOKEY */
 
158
          break;
 
159
        case ISKMAP:
 
160
          keymap[i].function = (InfoCommand *)keymap_copy_keymap
 
161
            ((Keymap)map[i].function, rootmap, NULL);
 
162
          break;
 
163
        }
75
164
    }
76
165
  return (keymap);
77
166
}
78
167
 
79
168
/* Free the keymap and its descendants. */
80
169
void
81
 
keymap_discard_keymap (map)
82
 
     Keymap (map);
 
170
keymap_discard_keymap (Keymap map, Keymap rootmap)
83
171
{
84
172
  int i;
85
173
 
86
174
  if (!map)
87
175
    return;
 
176
  if (!rootmap)
 
177
    rootmap = map;
88
178
 
89
179
  for (i = 0; i < 256; i++)
90
180
    {
 
181
#if defined(INFOKEY)
 
182
      FUNCTION_KEYSEQ *ks;
 
183
#endif /* INFOKEY */
91
184
      switch (map[i].type)
92
185
        {
93
186
        case ISFUNC:
 
187
#if defined(INFOKEY)
 
188
          ks = find_function_keyseq(map, i, rootmap);
 
189
          if (ks)
 
190
            remove_function_keyseq (map[i].function, ks->keyseq, rootmap);
 
191
#endif /* INFOKEY */
94
192
          break;
95
193
 
96
194
        case ISKMAP:
97
 
          keymap_discard_keymap ((Keymap)map[i].function);
 
195
          keymap_discard_keymap ((Keymap)map[i].function, rootmap);
98
196
          break;
99
197
 
100
198
        }
101
199
    }
 
200
  free(map);
102
201
}
103
202
 
104
203
/* Conditionally bind key sequence. */
105
 
int
106
 
keymap_bind_keyseq (map, keyseq, keyentry)
107
 
     Keymap map;
108
 
     const unsigned char *keyseq;
109
 
     KEYMAP_ENTRY *keyentry;
 
204
static int
 
205
keymap_bind_keyseq (Keymap map,
 
206
    const char *keyseq, KEYMAP_ENTRY *keyentry)
110
207
{
111
208
  Keymap m = map;
112
 
  const unsigned char *s = keyseq;
 
209
  const unsigned char *s = (unsigned char *) keyseq;
113
210
  int c;
114
211
 
115
212
  if (s == NULL || *s == '\0') return 0;
116
213
 
117
214
  while ((c = *s++) != '\0')
118
215
    {
 
216
#if defined(INFOKEY)
 
217
      FUNCTION_KEYSEQ *ks;
 
218
#endif /* INFOKEY */
119
219
      switch (m[c].type)
120
220
        {
121
221
        case ISFUNC:
 
222
#if defined(INFOKEY)
 
223
          ks = find_function_keyseq(m, c, map);
 
224
          if (ks)
 
225
            remove_function_keyseq (m[c].function, ks->keyseq, map);
 
226
#else /* !INFOKEY */
122
227
          if (!(m[c].function == NULL || (
123
 
#if !defined(INFOKEY)
124
228
                m != map &&
125
 
#endif /* !INFOKEY */
126
229
                m[c].function == InfoCmd(info_do_lowercase_version))
127
230
              ))
128
231
            return 0;
 
232
#endif /* !INFOKEY */
129
233
 
130
234
          if (*s != '\0')
131
235
            {
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 ();
134
244
            }
135
245
          break;
136
246
 
137
247
        case ISKMAP:
 
248
#if defined(INFOKEY)
 
249
          if (*s == '\0')
 
250
            keymap_discard_keymap ((Keymap)m[c].function, map);
 
251
#else /* !INFOKEY */
138
252
          if (*s == '\0')
139
253
            return 0;
 
254
#endif
140
255
          break;
141
256
        }
142
257
      if (*s != '\0')
146
261
      else
147
262
        {
148
263
#if defined(INFOKEY)
149
 
          FUNCTION_KEYSEQ *k;
150
 
 
151
 
          for (k = keyentry->function->keys; k && k->map != map; k = k->next)
152
 
            ;
153
 
          if (!k)
154
 
            {
155
 
              FUNCTION_KEYSEQ *ks = (FUNCTION_KEYSEQ *)xmalloc (sizeof(FUNCTION_KEYSEQ));
156
 
              ks->next = keyentry->function->keys;
157
 
              ks->map = map;
158
 
              ks->keyseq = xstrdup (keyseq);
159
 
              keyentry->function->keys = ks;
160
 
            }
 
264
          add_function_keyseq (keyentry->function, keyseq, map);
161
265
#endif /* INFOKEY */
162
266
          m[c] = *keyentry;
163
267
        }
505
609
  map['b'].function = ea_backward_word;
506
610
  map['d'].function = ea_kill_word;
507
611
  map['f'].function = ea_forward_word;
508
 
  map['h'].function = ea_forward;
509
 
  map['l'].function = ea_backward;
 
612
  map['h'].function = ea_backward;
 
613
  map['l'].function = ea_forward;
510
614
  map['w'].function = ea_forward_word;
511
615
  map['x'].function = ea_delete;
512
616
  map['X'].function = ea_kill_word;
600
704
  map['H'].function = info_get_help_window;
601
705
  map['i'].function = info_index_search;
602
706
  map['I'].function = info_goto_invocation_node;
603
 
  map['j'].function = info_down_line;
604
 
  map['k'].function = info_up_line;
 
707
  map['j'].function = info_next_line;
 
708
  map['k'].function = info_prev_line;
605
709
  map['l'].function = info_history_node;
606
710
  map['m'].function = info_menu_item;
607
711
  map['n'].function = info_search_next;
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,
1317
1421
 * Return the size of a file, or 0 if the size can't be determined.
1318
1422
 */
1319
1423
static unsigned long
1320
 
filesize(f)
1321
 
        int f;
 
1424
filesize(int f)
1322
1425
{
1323
1426
        long pos = lseek(f, 0L, SEEK_CUR);
1324
1427
        long sz = -1L;
1334
1437
   Integers are stored as two bytes, low order first, in radix INFOKEY_RADIX.
1335
1438
 */
1336
1439
static int
1337
 
getint(sp)
1338
 
        unsigned char **sp;
 
1440
getint(unsigned char **sp)
1339
1441
{
1340
1442
        int n;
1341
1443
 
1350
1452
/* Fetch the contents of the standard infokey file "$HOME/.info".  Return
1351
1453
   true if ok, false if not.  */
1352
1454
static int
1353
 
fetch_user_maps()
 
1455
fetch_user_maps(void)
1354
1456
{
1355
1457
        char *filename = NULL;
1356
1458
        char *homedir;
1378
1480
#endif
1379
1481
        if (filename == NULL || (f = open(filename, O_RDONLY)) == (-1))
1380
1482
        {
1381
 
                if (filename)
 
1483
                if (filename && errno != ENOENT)
1382
1484
                {
1383
 
                        info_error(filesys_error_string(filename, errno));
 
1485
                        info_error(filesys_error_string(filename, errno),
 
1486
                            NULL, NULL);
1384
1487
                        free(filename);
1385
1488
                }
1386
1489
                return 0;
1394
1497
                /* Bad file (a valid file must have at least 9 chars, and
1395
1498
                   more than 100 KB is a problem). */
1396
1499
                if (len < INFOKEY_NMAGIC + 2)
1397
 
                        info_error(_("Ignoring invalid infokey file `%s' - too small"),
1398
 
                                   filename);
 
1500
                        info_error((char *) _("Ignoring invalid infokey file `%s' - too small"),
 
1501
                                   filename, NULL);
1399
1502
                else
1400
 
                        info_error(_("Ignoring invalid infokey file `%s' - too big"),
1401
 
                                   filename);
 
1503
                        info_error((char *) _("Ignoring invalid infokey file `%s' - too big"),
 
1504
                                   filename, NULL);
1402
1505
                close(f);
1403
1506
                free(filename);
1404
1507
                return 0;
1408
1511
        buf = (unsigned char *)xmalloc((int)len);
1409
1512
        nread = read(f, buf, (unsigned int) len);
1410
1513
        close(f);
1411
 
        if (nread != len)
 
1514
        if ((unsigned int) nread != len)
1412
1515
        {
1413
 
                info_error(_("Error reading infokey file `%s' - short read"), filename);
 
1516
                info_error((char *) _("Error reading infokey file `%s' - short read"),
 
1517
                    filename, NULL);
1414
1518
                free(buf);
1415
1519
                free(filename);
1416
1520
                return 0;
1428
1532
                || buf[len - 1] != INFOKEY_MAGIC_E3
1429
1533
        )
1430
1534
        {
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"),
 
1536
                    filename, NULL);
1432
1537
                free(filename);
1433
1538
                return 0;
1434
1539
        }
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)
1436
1542
        {
1437
 
                info_error(_("Your infokey file `%s' is out of date -- run infokey to update it"), filename);
 
1543
                info_error
 
1544
                  ((char *) _("Your infokey file `%s' is out of date -- run infokey to update it"),
 
1545
                    filename, NULL);
1438
1546
                free(filename);
1439
1547
                return 0;
1440
1548
        }
1441
1549
 
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;
 
1553
             p += n)
1444
1554
        {
1445
1555
                int s = *p++;
1446
1556
 
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))
1449
1559
                {
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"),
 
1561
                            filename, NULL);
1451
1562
                        free(filename);
1452
1563
                        return 0;
1453
1564
                }
1467
1578
                        user_vars_len = n;
1468
1579
                        break;
1469
1580
                default:
1470
 
                        info_error(_("Invalid infokey file `%s' (bad section code) -- run infokey to update it"), filename);
 
1581
                        info_error((char *) _("Invalid infokey file `%s' (bad section code) -- run infokey to update it"),
 
1582
                            filename, NULL);
1471
1583
                        free(filename);
1472
1584
                        return 0;
1473
1585
                }
1482
1594
   doesn't define.
1483
1595
 */
1484
1596
static int
1485
 
decode_keys(src, slen, dst, dlen)
1486
 
        unsigned char *src;
1487
 
        unsigned int slen;
1488
 
        unsigned char *dst;
1489
 
        unsigned int dlen;
 
1597
decode_keys(unsigned char *src, unsigned int slen,
 
1598
    unsigned char *dst, unsigned int dlen)
1490
1599
{
1491
1600
        unsigned char *s = src;
1492
1601
        unsigned char *d = dst;
1493
1602
 
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); \
 
1605
} while (0)
1495
1606
 
1496
 
        while (s - src < slen)
 
1607
        while ((unsigned int) (s - src) < slen)
1497
1608
        {
1498
1609
                unsigned char c = ISMETA(*s) ? UNMETA(*s) : *s;
1499
1610
 
1500
1611
                if (c == SK_ESCAPE)
1501
1612
                {
1502
 
                        unsigned char *t;
 
1613
                        char *t;
1503
1614
                        static char lit[] = { SK_ESCAPE, NUL };
1504
1615
 
1505
 
                        switch (s + 1 - src < slen ? s[1] : '\0')
 
1616
                        switch ((unsigned int) (s + 1 - src) < slen ? s[1] : '\0')
1506
1617
                        {
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.  */
1545
1656
static int
1546
 
section_to_keymaps(map, table, len)
1547
 
        Keymap map;
1548
 
        unsigned char *table;
1549
 
        unsigned int len;
 
1657
section_to_keymaps(Keymap map, unsigned char *table, unsigned int len)
1550
1658
{
1551
1659
        int stop;
1552
1660
        unsigned char *p;
1553
 
        unsigned char *seq;
1554
 
        unsigned int seqlen;
1555
 
        KEYMAP_ENTRY ke;
 
1661
        unsigned char *seq = NULL;
 
1662
        unsigned int seqlen = 0;
1556
1663
        enum { getseq, gotseq, getaction } state = getseq;
1557
1664
 
1558
1665
        stop = len > 0 ? table[0] : 0;
1559
1666
 
1560
 
        for (p = table + 1; p - table < len; p++)
 
1667
        for (p = table + 1; (unsigned int) (p - table) < len; p++)
1561
1668
        {
1562
1669
                switch (state)
1563
1670
                {
1598
1705
                                          action < A_NCOMMANDS
1599
1706
                                          ? &function_doc_array[action]
1600
1707
                                          : NULL;
1601
 
                                        keymap_bind_keyseq(map, keyseq, &ke);
 
1708
                                        keymap_bind_keyseq(map,
 
1709
                                            (const char *) keyseq, &ke);
1602
1710
                                }
1603
1711
                        }
1604
1712
                        break;
1605
1713
                }
1606
1714
        }
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"),
 
1717
                    NULL, NULL);
1609
1718
        return !stop;
1610
1719
}
1611
1720
 
1612
1721
/* Convert an infokey file section to variable settings.
1613
1722
 */
1614
1723
static void
1615
 
section_to_vars(table, len)
1616
 
        unsigned char *table;
1617
 
        unsigned int len;
 
1724
section_to_vars(unsigned char *table, unsigned int len)
1618
1725
{
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;
1623
1730
 
1624
 
        for (p = table; p - table < len; p++)
 
1731
        for (p = table; (unsigned int) (p - table) < len; p++)
1625
1732
          {
1626
1733
            switch (state)
1627
1734
              {
1649
1756
              case gotval:
1650
1757
                if (!*p)
1651
1758
                  {
1652
 
                    set_variable_to_value(var, val);
 
1759
                    set_variable_to_value((char *) var, (char *) val);
1653
1760
                    state = getvar;
1654
1761
                  }
1655
1762
                break;
1656
1763
              }
1657
1764
          }
1658
1765
      if (state != getvar)
1659
 
        info_error(_("Bad data in infokey file -- some var settings ignored"));
 
1766
        info_error((char *) _("Bad data in infokey file -- some var settings ignored"),
 
1767
            NULL, NULL);
1660
1768
}
1661
1769
 
1662
1770
void
1663
 
initialize_info_keymaps ()
 
1771
initialize_info_keymaps (void)
1664
1772
{
1665
1773
  int i;
1666
1774
  int suppress_info_default_bindings = 0;
1667
1775
  int suppress_ea_default_bindings = 0;
1668
 
  Keymap map;
1669
1776
 
1670
1777
  if (!info_keymap)
1671
1778
    {
1721
1828
}
1722
1829
 
1723
1830
#endif /* defined(INFOKEY) */
 
1831
/* vim: set sw=2 cino={1s>2sn-s^-se-s: */