less -> more
[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
bc258617 21static char sccsid[] = "@(#)decode.c 5.6 (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
KB
100 ':','t',0, A_TAGFILE,
101 'Z','Z',0, A_QUIT,
bfe13c81
KB
102};
103
104char *cmdendtable = cmdtable + sizeof(cmdtable);
105
bc258617 106#define MAX_CMDLEN 16
bfe13c81
KB
107
108static char kbuf[MAX_CMDLEN+1];
109static char *kp = kbuf;
110
bc258617
KB
111/*
112 * Indicate that we're not in a prefix command
113 * by resetting the command buffer pointer.
114 */
115noprefix()
116{
117 kp = kbuf;
118}
119
bfe13c81
KB
120/*
121 * Decode a command character and return the associated action.
122 */
bfe13c81
KB
123cmd_decode(c)
124 int c;
125{
126 register int action = A_INVALID;
127
128 /*
129 * Append the new command character to the command string in kbuf.
130 */
131 *kp++ = c;
132 *kp = '\0';
133
bc258617 134 action = cmd_search(cmdtable, cmdendtable);
bfe13c81 135
bc258617 136 /* This is not a prefix character. */
bfe13c81 137 if (action != A_PREFIX)
bfe13c81 138 noprefix();
bc258617 139 return(action);
bfe13c81
KB
140}
141
142/*
143 * Search a command table for the current command string (in kbuf).
144 */
bc258617 145static
bfe13c81
KB
146cmd_search(table, endtable)
147 char *table;
148 char *endtable;
149{
bc258617 150 register char *p, *q;
bfe13c81 151
bc258617
KB
152 for (p = table, q = kbuf; p < endtable; p++, q++) {
153 if (*p == *q) {
bfe13c81
KB
154 /*
155 * Current characters match.
156 * If we're at the end of the string, we've found it.
157 * Return the action code, which is the character
158 * after the null at the end of the string
159 * in the command table.
160 */
161 if (*p == '\0')
bc258617
KB
162 return(p[1]);
163 }
164 else if (*q == '\0') {
bfe13c81
KB
165 /*
166 * Hit the end of the user's command,
167 * but not the end of the string in the command table.
168 * The user's command is incomplete.
169 */
bc258617
KB
170 return(A_PREFIX);
171 } else {
bfe13c81
KB
172 /*
173 * Not a match.
174 * Skip ahead to the next command in the
175 * command table, and reset the pointer
176 * to the user's command.
177 */
bc258617 178 while (*p++ != '\0');
bfe13c81
KB
179 q = kbuf-1;
180 }
181 }
182 /*
183 * No match found in the entire command table.
184 */
bc258617 185 return(A_INVALID);
bfe13c81 186}