]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/less-177/decode.c
2 * Routines to decode user commands.
4 * This is all table driven.
5 * A command table is a sequence of command descriptors.
6 * Each command descriptor is a sequence of bytes with the following format:
7 * <c1><c2>...<cN><0><action>
8 * The characters c1,c2,...,cN are the command string; that is,
9 * the characters which the user must type.
10 * It is terminated by a null <0> byte.
11 * The byte after the null byte is the action code associated
12 * with the command string.
13 * If an action byte is OR-ed with A_EXTRA, this indicates
14 * that the option byte is followed by an extra string.
16 * There may be many command tables.
17 * The first (default) table is built-in.
18 * Other tables are read in from "lesskey" files.
19 * All the tables are linked together and are searched in order.
30 * Command table is ordered roughly according to expected
31 * frequency of use, so the common commands are near the beginning.
33 static char cmdtable
[] =
38 * Note that '\0' is converted to '\200' on input.
40 '\200','\120',0, A_F_LINE
, /* down arrow */
41 '\200','\121',0, A_F_SCREEN
, /* page down */
42 '\200','\110',0, A_B_LINE
, /* up arrow */
43 '\200','\111',0, A_B_SCREEN
, /* page up */
44 '\200','\107',0, A_GOLINE
, /* home */
45 '\200','\117',0, A_GOEND
, /* end */
46 '\200','\073',0, A_HELP
, /* F1 */
47 '\200','\104',0, A_MODIFY_WINDOW
, /* F10 */
48 '\200','\103',0, A_MODIFY_COLOURS
, /* F9 */
54 CONTROL('E'),0, A_F_LINE
,
55 CONTROL('N'),0, A_F_LINE
,
58 CONTROL('Y'),0, A_B_LINE
,
59 CONTROL('K'),0, A_B_LINE
,
60 CONTROL('P'),0, A_B_LINE
,
65 CONTROL('D'),0, A_F_SCROLL
,
67 CONTROL('U'),0, A_B_SCROLL
,
70 CONTROL('F'),0, A_F_SCREEN
,
71 CONTROL('V'),0, A_F_SCREEN
,
73 CONTROL('B'),0, A_B_SCREEN
,
74 ESC
,'v',0, A_B_SCREEN
,
80 CONTROL('R'),0, A_REPAINT
,
81 CONTROL('L'),0, A_REPAINT
,
87 '{',0, A_F_BRACKET
|A_EXTRA
, '{','}',0,
88 '}',0, A_B_BRACKET
|A_EXTRA
, '{','}',0,
89 '(',0, A_F_BRACKET
|A_EXTRA
, '(',')',0,
90 ')',0, A_B_BRACKET
|A_EXTRA
, '(',')',0,
91 '[',0, A_F_BRACKET
|A_EXTRA
, '[',']',0,
92 ']',0, A_B_BRACKET
|A_EXTRA
, '[',']',0,
93 ESC
,CONTROL('F'),0, A_F_BRACKET
,
94 ESC
,CONTROL('B'),0, A_B_BRACKET
,
112 CONTROL('G'),0, A_STAT
,
116 ESC
,'/',0, A_F_SEARCH
|A_EXTRA
, '*',0,
117 ESC
,'?',0, A_B_SEARCH
|A_EXTRA
, '*',0,
118 'n',0, A_AGAIN_SEARCH
,
119 ESC
,'n',0, A_T_AGAIN_SEARCH
,
120 'N',0, A_REVERSE_SEARCH
,
121 ESC
,'N',0, A_T_REVERSE_SEARCH
,
124 CONTROL('X'),CONTROL('X'),0, A_GOMARK
,
126 ':','e',0, A_EXAMINE
,
127 CONTROL('X'),CONTROL('V'),0, A_EXAMINE
,
128 ':','n',0, A_NEXT_FILE
,
129 ':','p',0, A_PREV_FILE
,
130 ':','x',0, A_INDEX_FILE
,
132 ':','t',0, A_OPT_TOGGLE
|A_EXTRA
, 't',0,
133 's',0, A_OPT_TOGGLE
|A_EXTRA
, 'o',0,
134 '_',0, A_DISP_OPTION
,
151 * Structure to support a list of command tables.
155 struct tablelist
*t_next
;
161 * Structure for the default command table.
163 static struct tablelist deftable
=
164 { NULL
, cmdtable
, cmdtable
+sizeof(cmdtable
) };
167 * List of tables; initially contains only the default table.
169 static struct tablelist
*tables
= &deftable
;
171 static int cmd_search();
173 extern int erase_char
, kill_char
;
176 * Decode a command character and return the associated action.
177 * The "extra" string, if any, is returned in sp.
184 register struct tablelist
*t
;
188 * Search thru all the command tables.
189 * Stop when we find an action which is not A_INVALID.
191 for (t
= tables
; t
!= NULL
; t
= t
->t_next
)
193 action
= cmd_search(cmd
, t
->t_start
, t
->t_end
, sp
);
194 if (action
!= A_INVALID
)
201 * Search a command table for the current command string (in cmd).
204 cmd_search(cmd
, table
, endtable
, sp
)
214 for (p
= table
, q
= cmd
; p
< endtable
; p
++, q
++)
219 * Current characters match.
220 * If we're at the end of the string, we've found it.
221 * Return the action code, which is the character
222 * after the null at the end of the string
223 * in the command table.
229 * Check for an "extra" string.
239 } else if (*q
== '\0')
242 * Hit the end of the user's command,
243 * but not the end of the string in the command table.
244 * The user's command is incomplete.
251 * Skip ahead to the next command in the
252 * command table, and reset the pointer
253 * to the beginning of the user's command.
255 while (*p
++ != '\0') ;
257 while (*++p
!= '\0') ;
262 * No match found in the entire command table.
269 * Set up a user command table, based on a "lesskey" file.
272 add_cmdtable(filename
)
275 register struct tablelist
*t
;
276 register POSITION len
;
281 * Try to open the lesskey file.
282 * If we can't, return an error.
284 f
= open(filename
, 0);
289 * Read the file into the user table.
290 * We first figure out the size of the file and allocate space for it.
291 * {{ Minimal error checking is done here.
292 * A garbage .less file will produce strange results.
293 * To avoid a large amount of error checking code here, we
294 * rely on the lesskey program to generate a good .less file. }}
297 if (len
== NULL_POSITION
|| len
< 3)
300 * Bad file (valid file must have at least 3 chars).
305 if ((t
= (struct tablelist
*)
306 calloc(1, sizeof(struct tablelist
))) == NULL
)
311 if ((t
->t_start
= (char *) calloc(len
, sizeof(char))) == NULL
)
317 if (lseek(f
, (offset_t
)0, 0) == BAD_LSEEK
)
324 n
= read(f
, t
->t_start
, (unsigned int) len
);
328 * In a valid lesskey file, the last byte or
329 * the second to the last byte must be zero.
331 if (n
!= len
|| (t
->t_start
[n
-1] != '\0' && t
->t_start
[n
-2] != '\0'))
337 t
->t_end
= t
->t_start
+ n
;
340 * Link it into the list of tables.
348 * Try to add the lesskey file "$HOME/.less"
356 filename
= homefile("_less");
358 filename
= homefile(".less");
360 if (filename
== NULL
)
365 (void) add_cmdtable(filename
);