first cut at new makefile; file reorg, new depend
[unix-history] / usr / src / usr.bin / more / decode.c
CommitLineData
bfe13c81
KB
1/*
2 * Copyright (c) 1988 Mark Nudleman
3 * Copyright (c) 1988 Regents of the University of California.
4 * All rights reserved.
5 *
bfe13c81
KB
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
a942b40b
KB
11 * by Mark Nudleman and the University of California, Berkeley. The
12 * name of Mark Nudleman or the
bfe13c81
KB
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20#ifndef lint
e810d3c9 21static char sccsid[] = "@(#)decode.c 5.7 (Berkeley) %G%";
bfe13c81
KB
22#endif /* not lint */
23
24/*
25 * Routines to decode user commands.
26 *
27 * This is all table driven.
28 * A command table is a sequence of command descriptors.
29 * Each command descriptor is a sequence of bytes with the following format:
30 * <c1><c2>...<cN><0><action>
31 * The characters c1,c2,...,cN are the command string; that is,
32 * the characters which the user must type.
33 * It is terminated by a null <0> byte.
34 * The byte after the null byte is the action code associated
35 * with the command string.
36 *
37 * The default commands are described by cmdtable.
bfe13c81
KB
38 */
39
bc258617
KB
40#include <sys/param.h>
41#include <sys/file.h>
42#include <stdio.h>
43#include <less.h>
bfe13c81
KB
44
45/*
46 * Command table is ordered roughly according to expected
47 * frequency of use, so the common commands are near the beginning.
48 */
bc258617
KB
49#define CONTROL(c) ((c)&037)
50
51static char cmdtable[] = {
bfe13c81
KB
52 '\r',0, A_F_LINE,
53 '\n',0, A_F_LINE,
bfe13c81 54 'j',0, A_F_LINE,
bfe13c81 55 'k',0, A_B_LINE,
bfe13c81
KB
56 'd',0, A_F_SCROLL,
57 CONTROL('D'),0, A_F_SCROLL,
58 'u',0, A_B_SCROLL,
59 CONTROL('U'),0, A_B_SCROLL,
60 ' ',0, A_F_SCREEN,
61 'f',0, A_F_SCREEN,
62 CONTROL('F'),0, A_F_SCREEN,
bfe13c81
KB
63 'b',0, A_B_SCREEN,
64 CONTROL('B'),0, A_B_SCREEN,
bfe13c81
KB
65 'R',0, A_FREPAINT,
66 'r',0, A_REPAINT,
bfe13c81
KB
67 CONTROL('L'),0, A_REPAINT,
68 'g',0, A_GOLINE,
bfe13c81
KB
69 'p',0, A_PERCENT,
70 '%',0, A_PERCENT,
71 'G',0, A_GOEND,
bfe13c81
KB
72 '0',0, A_DIGIT,
73 '1',0, A_DIGIT,
74 '2',0, A_DIGIT,
75 '3',0, A_DIGIT,
76 '4',0, A_DIGIT,
77 '5',0, A_DIGIT,
78 '6',0, A_DIGIT,
79 '7',0, A_DIGIT,
80 '8',0, A_DIGIT,
81 '9',0, A_DIGIT,
82
83 '=',0, A_STAT,
84 CONTROL('G'),0, A_STAT,
85 '/',0, A_F_SEARCH,
86 '?',0, A_B_SEARCH,
87 'n',0, A_AGAIN_SEARCH,
88 'm',0, A_SETMARK,
89 '\'',0, A_GOMARK,
bfe13c81 90 'E',0, A_EXAMINE,
bfe13c81 91 'N',0, A_NEXT_FILE,
bfe13c81 92 ':','n',0, A_NEXT_FILE,
bc258617 93 'P',0, A_PREV_FILE,
bfe13c81 94 ':','p',0, A_PREV_FILE,
bfe13c81 95 'v',0, A_VISUAL,
bfe13c81 96
bfe13c81 97 'h',0, A_HELP,
bfe13c81
KB
98 'q',0, A_QUIT,
99 ':','q',0, A_QUIT,
bc258617 100 ':','t',0, A_TAGFILE,
e810d3c9 101 ':', 'a', 0, A_FILE_LIST,
bc258617 102 'Z','Z',0, A_QUIT,
bfe13c81
KB
103};
104
105char *cmdendtable = cmdtable + sizeof(cmdtable);
106
bc258617 107#define MAX_CMDLEN 16
bfe13c81
KB
108
109static char kbuf[MAX_CMDLEN+1];
110static char *kp = kbuf;
111
bc258617
KB
112/*
113 * Indicate that we're not in a prefix command
114 * by resetting the command buffer pointer.
115 */
116noprefix()
117{
118 kp = kbuf;
119}
120
bfe13c81
KB
121/*
122 * Decode a command character and return the associated action.
123 */
bfe13c81
KB
124cmd_decode(c)
125 int c;
126{
127 register int action = A_INVALID;
128
129 /*
130 * Append the new command character to the command string in kbuf.
131 */
132 *kp++ = c;
133 *kp = '\0';
134
bc258617 135 action = cmd_search(cmdtable, cmdendtable);
bfe13c81 136
bc258617 137 /* This is not a prefix character. */
bfe13c81 138 if (action != A_PREFIX)
bfe13c81 139 noprefix();
bc258617 140 return(action);
bfe13c81
KB
141}
142
143/*
144 * Search a command table for the current command string (in kbuf).
145 */
bc258617 146static
bfe13c81
KB
147cmd_search(table, endtable)
148 char *table;
149 char *endtable;
150{
bc258617 151 register char *p, *q;
bfe13c81 152
bc258617
KB
153 for (p = table, q = kbuf; p < endtable; p++, q++) {
154 if (*p == *q) {
bfe13c81
KB
155 /*
156 * Current characters match.
157 * If we're at the end of the string, we've found it.
158 * Return the action code, which is the character
159 * after the null at the end of the string
160 * in the command table.
161 */
162 if (*p == '\0')
bc258617
KB
163 return(p[1]);
164 }
165 else if (*q == '\0') {
bfe13c81
KB
166 /*
167 * Hit the end of the user's command,
168 * but not the end of the string in the command table.
169 * The user's command is incomplete.
170 */
bc258617
KB
171 return(A_PREFIX);
172 } else {
bfe13c81
KB
173 /*
174 * Not a match.
175 * Skip ahead to the next command in the
176 * command table, and reset the pointer
177 * to the user's command.
178 */
bc258617 179 while (*p++ != '\0');
bfe13c81
KB
180 q = kbuf-1;
181 }
182 }
183 /*
184 * No match found in the entire command table.
185 */
bc258617 186 return(A_INVALID);
bfe13c81 187}