* Copyright (c) 1988 Mark Nudleman
* Copyright (c) 1988 Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)decode.c 5.1 (Berkeley) %G%";
* Routines to decode user commands.
* This is all table driven.
* A command table is a sequence of command descriptors.
* Each command descriptor is a sequence of bytes with the following format:
* <c1><c2>...<cN><0><action>
* The characters c1,c2,...,cN are the command string; that is,
* the characters which the user must type.
* It is terminated by a null <0> byte.
* The byte after the null byte is the action code associated
* with the command string.
* The default commands are described by cmdtable.
* User-defined commands are read into usertable.
* Command table is ordered roughly according to expected
* frequency of use, so the common commands are near the beginning.
CONTROL('E'),0, A_F_LINE
,
CONTROL('N'),0, A_F_LINE
,
CONTROL('Y'),0, A_B_LINE
,
CONTROL('K'),0, A_B_LINE
,
CONTROL('P'),0, A_B_LINE
,
CONTROL('D'),0, A_F_SCROLL
,
CONTROL('U'),0, A_B_SCROLL
,
CONTROL('F'),0, A_F_SCREEN
,
CONTROL('V'),0, A_F_SCREEN
,
CONTROL('B'),0, A_B_SCREEN
,
CONTROL('['),'v',0, A_B_SCREEN
,
CONTROL('R'),0, A_REPAINT
,
CONTROL('L'),0, A_REPAINT
,
CONTROL('['),'<',0, A_GOLINE
,
CONTROL('['),'>',0, A_GOEND
,
CONTROL('X'),CONTROL('X'),0, A_GOMARK
,
CONTROL('X'),CONTROL('V'),0, A_EXAMINE
,
char *cmdendtable
= cmdtable
+ sizeof(cmdtable
);
static char usertable
[MAX_USERCMD
];
char *userendtable
= usertable
;
static char kbuf
[MAX_CMDLEN
+1];
* Decode a command character and return the associated action.
register int action
= A_INVALID
;
* Append the new command character to the command string in kbuf.
* Look first for any user-defined commands.
action
= cmd_search(usertable
, userendtable
);
* If didn't find user-defined command,
* try the normal default commands.
action
= cmd_search(cmdtable
, cmdendtable
);
* This is not a prefix character.
* Indicate that we're not in a prefix command
* by resetting the command buffer pointer.
* Search a command table for the current command string (in kbuf).
cmd_search(table
, endtable
)
for (p
= table
, q
= kbuf
; p
< endtable
; p
++, q
++)
* Current characters match.
* If we're at the end of the string, we've found it.
* Return the action code, which is the character
* after the null at the end of the string
* Hit the end of the user's command,
* but not the end of the string in the command table.
* The user's command is incomplete.
* Skip ahead to the next command in the
* command table, and reset the pointer
* No match found in the entire command table.
* Initialize the user command table.
* Try to open "$HOME/.less"
* If we can't, return without doing anything.
homedir
= getenv("HOME");
filename
= calloc(strlen(homedir
)+7, sizeof(char));
sprintf(filename
, "%s/%s", homedir
, ".less");
* Read the file into the user table.
* {{ Minimal error checking is done here.
* A garbage .less file will produce strange results.
* To avoid a large amount of error checking code here, we
* rely on the lesskey program to generate a good .less file. }}
n
= read(f
, (char *)usertable
, MAX_USERCMD
);
if (n
< 3 || usertable
[n
-2] != '\0')
* Several error cases are lumped together here:
* - Cannot read user file (n < 0).
* - User file is too short (a valid file must
* have at least 3 chars: one char command string,
* the terminating null byte, and the action byte).
* - The final entry in the user file is bad (it
* doesn't have a null byte in the proper place).
* Many other error cases are not caught, such as
* invalid format in any except the last entry,
* invalid action codes, command strings too long, etc.
error("invalid user key file");
userendtable
= usertable
+ n
;