~ubuntu-branches/ubuntu/natty/hexer/natty

« back to all changes in this revision

Viewing changes to map.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Mathiasson
  • Date: 2003-06-19 09:48:34 UTC
  • Revision ID: james.westby@ubuntu.com-20030619094834-t127jo9kd93shx02
Tags: upstream-0.1.4c
ImportĀ upstreamĀ versionĀ 0.1.4c

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* map.c        8/19/1995
 
2
 * Map some key-sequences to some key-sequences, version 0.3
 
3
 * Requieres: tio.o
 
4
 */
 
5
 
 
6
/* Copyright (c) 1995,1996 Sascha Demetrio
 
7
 * All rights reserved.
 
8
 *
 
9
 * Redistribution and use in source and binary forms, with or without
 
10
 * modification, are permitted provided that the following conditions
 
11
 * are met:
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer.
 
14
 *    If you modify any part of HEXER and resitribute it, you must add
 
15
 *    a notice to the `README' file and the modified source files containing
 
16
 *    information about the  changes you made.  I do not want to take
 
17
 *    credit or be blamed for your modifications.
 
18
 * 2. Redistributions in binary form must reproduce the above copyright
 
19
 *    notice, this list of conditions and the following disclaimer in the
 
20
 *    documentation and/or other materials provided with the distribution.
 
21
 *    If you modify any part of HEXER and resitribute it in binary form,
 
22
 *    you must supply a `README' file containing information about the
 
23
 *    changes you made.
 
24
 * 3. The name of the developer may not be used to endorse or promote
 
25
 *    products derived from this software without specific prior written
 
26
 *    permission.
 
27
 *
 
28
 * HEXER WAS DEVELOPED BY SASCHA DEMETRIO.
 
29
 * THIS SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
 
30
 * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
 
31
 * NOT MAKE USE OF THIS WORK.
 
32
 *
 
33
 * DISCLAIMER:
 
34
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
 
35
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
36
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
37
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPER BE LIABLE
 
38
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
39
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
40
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
41
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
42
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
43
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
44
 * SUCH DAMAGE.
 
45
 */
 
46
 
 
47
#include "config.h"
 
48
 
 
49
#include <stdlib.h>
 
50
#include <string.h>
 
51
#include <assert.h>
 
52
#if HAVE_ALLOCA
 
53
#if NEED_ALLOCA_H
 
54
#include <alloca.h>
 
55
#endif
 
56
#else
 
57
char *alloca();
 
58
#endif
 
59
 
 
60
#include "defs.h"
 
61
 
 
62
#undef TIO_MAP
 
63
#define TIO_MAP 1
 
64
#include "tio.h"
 
65
 
 
66
#define MAP_MAXLEN 256
 
67
#define MAP_MAX 16
 
68
 
 
69
#if ('\e' == 'e')
 
70
#define MAP_ESC ((char)27)
 
71
#else
 
72
#define MAP_ESC ('\e')
 
73
#endif
 
74
 
 
75
int tio_m_remap = 0;
 
76
  /* if `tio_m_remap == 1', the sequence of keys another sequence is mapped
 
77
   * to may be mapped again, i.e. if `ab' maps to `bcd' and `bc' is mapped
 
78
   * to `cd', then `ab' maps to `cdd'.  the default is *not* to allow
 
79
   * remapping.
 
80
   */
 
81
 
 
82
struct map_s {
 
83
  int from[MAP_MAXLEN];
 
84
  int to[MAP_MAXLEN];
 
85
  struct map_s *next;
 
86
};
 
87
 
 
88
static struct map_s *map_first[MAP_MAX] = { 0 };
 
89
static int map_max = 0;
 
90
static int keys[MAP_MAXLEN];
 
91
static int keys_n = 0;
 
92
 
 
93
static int munget[MAP_MAXLEN];
 
94
static int munget_n = 0;
 
95
 
 
96
 
 
97
/* operations on strings of keys
 
98
 */
 
99
 
 
100
  static int
 
101
key_strcmp(ks1, ks2)
 
102
  const int *ks1, *ks2;
 
103
{
 
104
  while (*ks1 && *ks2 && *ks1 == *ks2) ++ks1, ++ks2;
 
105
  return *ks1 != *ks2;
 
106
}
 
107
/* key_strcmp */
 
108
 
 
109
  static int
 
110
key_strncmp(ks1, ks2, n)
 
111
  const int *ks1, *ks2;
 
112
  int n;
 
113
{
 
114
  while (*ks1 && *ks2 && *ks1 == *ks2 && n--) ++ks1, ++ks2;
 
115
  return n && *ks1 != *ks2;
 
116
}
 
117
/* key_strncmp */
 
118
 
 
119
  static int
 
120
key_strlen(ks)
 
121
  const int *ks;
 
122
{
 
123
  int n = 0;
 
124
 
 
125
  for (; *ks++; ++n);
 
126
  return n;
 
127
}
 
128
/* key_strlen */
 
129
 
 
130
  static char *
 
131
key_strrep(ks)
 
132
  const int *ks;
 
133
{
 
134
  int n;
 
135
  const int *i;
 
136
  char *s, *t;
 
137
  int key;
 
138
 
 
139
  for (n = 0, i = ks; *i; ++i) {
 
140
    if (*i == MAP_ESC)
 
141
      key = *++i + KEY_BIAS;
 
142
    else
 
143
      key = *i;
 
144
    n += strlen(tio_keyrep(key));
 
145
  }
 
146
  s = t = (char *)malloc(n + 1);
 
147
  for (i = ks; *i; ++i) {
 
148
    if (*i == MAP_ESC)
 
149
      key = *++i + KEY_BIAS;
 
150
    else
 
151
      key = *i;
 
152
    strcpy(t, tio_keyrep(key)); t += strlen(t);
 
153
  }
 
154
  return s;
 
155
}
 
156
/* key_strrep */
 
157
 
 
158
#if 0
 
159
  static char *
 
160
key_strrep_simple(ks)
 
161
  const int *ks;
 
162
  /* like `key_strrep()', but special keys are translated to 0xff.
 
163
   */
 
164
{
 
165
  char *s, *t;
 
166
 
 
167
  s = t = (char *)malloc(key_strlen(ks) + 1);
 
168
  for (; *ks; ++ks) if (*ks < 0x100) *t++ = *ks; else *t++ = 0xff;
 
169
  *t = 0;
 
170
  return s;
 
171
}
 
172
/* key_strrep_simple */
 
173
#endif
 
174
 
 
175
#if 0
 
176
  static int
 
177
key_strncpy(ks1, ks2, n)
 
178
  int *ks1;
 
179
  const int *ks2;
 
180
  int n;
 
181
{
 
182
  while (*ks2 && n--) *ks1++ = *ks2++;
 
183
  return *ks1 = 0;
 
184
}
 
185
/* key_strncpy */
 
186
#endif
 
187
 
 
188
  static int
 
189
key_strcpy(ks1, ks2)
 
190
  int *ks1;
 
191
  const int *ks2;
 
192
{
 
193
  while (*ks2) *ks1++ = *ks2++;
 
194
  return *ks1 = 0;
 
195
}
 
196
/* key_strcpy */
 
197
 
 
198
  static int
 
199
string_to_keys(keys, string)
 
200
  int *keys;
 
201
  char *string;
 
202
{
 
203
  while (*string) {
 
204
    if (*string == MAP_ESC) {
 
205
      ++string;
 
206
      if (*string == 1)
 
207
        *keys++ = (int)KEY_ESCAPE;
 
208
      else
 
209
        *keys++ = *string + (int)KEY_BIAS;
 
210
    } else
 
211
      *keys++ = *string;
 
212
    ++string;
 
213
  }
 
214
  *keys = 0;
 
215
  return 0;
 
216
}
 
217
/* string_to_keys */
 
218
 
 
219
  static int
 
220
scan_keys(keys, string, mode)
 
221
  int *keys;
 
222
  char *string;
 
223
  int mode;
 
224
{
 
225
  do {
 
226
    if (*string == MAP_ESC) {
 
227
      ++string;
 
228
      if (*string == 1)
 
229
        *keys++ = KEY_ESCAPE;
 
230
      else
 
231
        *keys++ = *string + KEY_BIAS;
 
232
      ++string;
 
233
    } else
 
234
      string = tio_keyscan(keys++, string, mode);
 
235
  } while (*string);
 
236
  *keys = 0;
 
237
  return 0;
 
238
}
 
239
/* scan_keys */
 
240
 
 
241
#if 0
 
242
  static void
 
243
mungetch(key)
 
244
  int key;
 
245
{
 
246
  if (tio_m_remap) tio_ungetch(key); else munget[munget_n++] = key;
 
247
}
 
248
/* mungetch */
 
249
#endif
 
250
 
 
251
  static void
 
252
mungets(keys)
 
253
  int *keys;
 
254
{
 
255
  int i;
 
256
 
 
257
  for (i = 0; keys[i]; ++i);
 
258
  if (tio_m_remap)
 
259
    while (i) tio_ungetch(keys[--i]);
 
260
  else
 
261
    while (i) munget[munget_n++] = keys[--i];
 
262
}
 
263
/* mungets */
 
264
 
 
265
  int
 
266
tio_mgetch(map, map_string)
 
267
  int map;
 
268
  char *map_string;
 
269
{
 
270
  int key;
 
271
  struct map_s *i;
 
272
  char *s = map_string;
 
273
  int ungets[MAP_MAXLEN], ungets_n = 0;
 
274
  int k;
 
275
  int prefix;
 
276
  extern int *tio_interrupt;
 
277
 
 
278
  if (*tio_interrupt) {
 
279
    *tio_interrupt = 0;
 
280
    return (int)KEY_BREAK;
 
281
  }
 
282
  while (map_max < map) map_first[++map_max] = 0;
 
283
  if (map_string) {
 
284
    /* create the `map_string' (a string representation of the unmapped keys
 
285
     * typed so far)  */
 
286
    if (keys_n)
 
287
      for (k = 0; k < keys_n; ++k) {
 
288
        strcpy(s, tio_keyrep(keys[k]));
 
289
        s += strlen(s);
 
290
      }
 
291
    else
 
292
      *map_string = 0;
 
293
  }
 
294
  if (tio_getmore()) return tio_getch();
 
295
  if (munget_n) return munget[--munget_n];
 
296
  key = tio_getch();
 
297
  if (key == (int)KEY_ERROR) return (int)KEY_ERROR;
 
298
  if (key == (int)KEY_ESCAPE && !keys_n)
 
299
    if (!tio_readmore()) return (int)KEY_ESCAPE;
 
300
  if (key <= 0) return key;
 
301
  keys[keys_n++] = key;
 
302
  keys[keys_n] = 0;
 
303
  for (;;) {
 
304
    /* check if `keys' matches */
 
305
    for (i = map_first[map]; i; i = i->next)
 
306
      if (!key_strcmp(keys, i->from)) { /* match */
 
307
        if (ungets_n) {
 
308
          ungets[ungets_n] = 0;
 
309
          mungets(ungets);
 
310
          ungets[ungets_n = 0] = 0;
 
311
        }
 
312
        keys[keys_n = 0] = 0;
 
313
        mungets(i->to);
 
314
        if (map_string) *map_string = 0;
 
315
        return tio_mgetch(map, map_string);
 
316
      }
 
317
    /* check if `keys' is a prefix */
 
318
    for (i = map_first[map], prefix = 0; i; i = i->next)
 
319
      if (!key_strncmp(keys, i->from, keys_n)) { prefix = 1; break; }
 
320
    if (!prefix) {
 
321
      ungets[ungets_n++] = keys[0];
 
322
      if (!--keys_n) break;
 
323
      for (k = 0; k < keys_n; ++k) keys[k] = keys[k + 1];
 
324
      continue;
 
325
    } else
 
326
      break;
 
327
  }
 
328
  if (ungets_n) {
 
329
    ungets[ungets_n] = 0;
 
330
    mungets(ungets);
 
331
    ungets[ungets_n = 0] = 0;
 
332
  }
 
333
  if (s) {
 
334
    strcpy(s, tio_keyrep(key));
 
335
    s += strlen(s);
 
336
  }
 
337
  if (munget_n) return munget[--munget_n];
 
338
  return (int)KEY_NONE;
 
339
}
 
340
/* tio_mgetch */
 
341
 
 
342
  int
 
343
tio_map(map, from, to, special_f)
 
344
  int map;
 
345
  char *from, *to;
 
346
  int special_f;
 
347
  /* define a key mapping from `from' to `to' in keymap `map'.  if `special_f'
 
348
   * is set, special characters may also be written in ascii (i.e. "~UP" for
 
349
   * cursor up).  `special_f' should be set when reading commands from a file.
 
350
   */
 
351
{
 
352
  struct map_s *i, *j;
 
353
  int *kfrom, *kto;
 
354
 
 
355
  kfrom = (int *)alloca((strlen(from) + 1) * sizeof(int));
 
356
  if (special_f)
 
357
    scan_keys(kfrom, from, 0);
 
358
  else
 
359
    string_to_keys(kfrom, from);
 
360
  kto = (int *)alloca((strlen(to) + 1) * sizeof(int));
 
361
  if (special_f)
 
362
    scan_keys(kto, to, 0);
 
363
  else
 
364
    string_to_keys(kto, to);
 
365
  while (map_max < map) map_first[++map_max] = 0;
 
366
  for (i = map_first[map], j = 0; i; j = i, i = i->next)
 
367
    if (!key_strcmp(kfrom, i->from)) {
 
368
      key_strcpy(i->to, kto);
 
369
      return 0;
 
370
    }
 
371
  i = (struct map_s *)malloc(sizeof(struct map_s));
 
372
  i->next = 0;
 
373
  key_strcpy(i->from, kfrom);
 
374
  key_strcpy(i->to, kto);
 
375
  if (j) j->next = i; else map_first[map] = i;
 
376
  return 0;
 
377
}
 
378
/* tio_map */
 
379
 
 
380
  int
 
381
tio_unmap(map, from, special_f)
 
382
  int map;
 
383
  char *from;
 
384
  int special_f;
 
385
  /* remove the mapping `from' from the keymap `map'.  the flag `special_f'
 
386
   * works the same as in `tio_map()'.
 
387
   */
 
388
{
 
389
  struct map_s *i, *j;
 
390
  int *kfrom;
 
391
 
 
392
  kfrom = (int *)alloca((strlen(from) + 1) * sizeof(int));
 
393
  if (special_f)
 
394
    scan_keys(kfrom, from, 0);
 
395
  else
 
396
    string_to_keys(kfrom, from);
 
397
  if (map > map_max) return -1;
 
398
  for (i = map_first[map], j = 0; i; j = i, i = i->next)
 
399
    if (!key_strcmp(i->from, kfrom)) {
 
400
      if (j) j->next = i->next; else map_first[map] = i->next;
 
401
      free((char *)i);
 
402
      return 0;
 
403
    }
 
404
  return -1;
 
405
}
 
406
/* tio_unmap */
 
407
 
 
408
  char **
 
409
tio_maplist(map)
 
410
  int map;
 
411
{
 
412
  int n, k;
 
413
  struct map_s *i;
 
414
  char **from, **to, **list;
 
415
  int from_maxwidth;
 
416
 
 
417
  for (i = map_first[map], n = 0; i; i = i->next, ++n);
 
418
  if (!n) {
 
419
    *(list = (char **)malloc(sizeof(char *))) = 0;
 
420
    return list;
 
421
  }
 
422
  from = (char **)alloca(n * sizeof(char *));
 
423
  to = (char **)alloca(n * sizeof(char *));
 
424
  list = (char **)malloc((n + 1) * sizeof(char *));
 
425
  for (i = map_first[map], k = 0; i; i = i->next, ++k) {
 
426
    from[k] = key_strrep(i->from);
 
427
    to[k] = key_strrep(i->to);
 
428
  }
 
429
  from_maxwidth = strlen(from[0]);
 
430
  for (k = 1; k < n; ++k)
 
431
    if (strlen(from[k]) > from_maxwidth) from_maxwidth = strlen(from[k]);
 
432
  from_maxwidth += 2;
 
433
  for (k = 0; k < n; ++k) {
 
434
    list[k] = (char *)malloc(from_maxwidth + strlen(to[k]) + 2);
 
435
    strcpy(list[k], from[k]);
 
436
    memset(list[k] + strlen(list[k]), ' ', from_maxwidth - strlen(list[k]));
 
437
    strcpy(list[k] + from_maxwidth, to[k]);
 
438
    list[k][strlen(list[k]) + 1] = 0;
 
439
    list[k][strlen(list[k])] = '\n';
 
440
    free((char *)from[k]);
 
441
    free((char *)to[k]);
 
442
  }
 
443
  list[n] = 0;
 
444
  return list;
 
445
}
 
446
/* tio_maplist */
 
447
 
 
448
#if 0
 
449
  char *
 
450
tio_mapentry(map, from)
 
451
  int map;
 
452
  char *from;
 
453
{
 
454
  struct map_s *i, *j;
 
455
  int *kfrom;
 
456
  int length;
 
457
  char *rep, *sfrom, *sto;
 
458
 
 
459
  kfrom = (int *)alloca(strlen(from) * sizeof(int));
 
460
  string_to_keys(kfrom, from);
 
461
  if (map > map_max) return -1;
 
462
  for (i = map_first[map], j = 0; i; j = i, i = i->next)
 
463
    if (!key_strcmp(i->from, kfrom)) {
 
464
      length = strlen(sfrom = key_strrep(i->from))
 
465
               + strlen(sto = key_strrep(i->to)) + 3;
 
466
      rep = (char *)malloc(length);
 
467
      strcpy(rep, sfrom);
 
468
      strcat(rep, "  ");
 
469
      strcat(rep, sto);
 
470
      free(sfrom);
 
471
      free(sto);
 
472
      return rep;
 
473
    }
 
474
  return 0;
 
475
}
 
476
/* tio_mapentry */
 
477
#endif
 
478
 
 
479
/* end of map.c */
 
480
 
 
481
 
 
482
/* VIM configuration: (do not delete this line)
 
483
 *
 
484
 * vim:aw:bk:bdir=./bak:ch=2:nodg:ef=make.log:efm=%f\:%l\:%m:et:hid:icon:
 
485
 * vim:sw=2:sc:sm:si:textwidth=79:to:ul=1024:wh=12:wrap:wb:
 
486
 */