* Copyright (c) 1988 Mark Nudleman
* Copyright (c) 1988 Regents of the University of California.
* 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 Mark Nudleman and the University of California, Berkeley. The
* name of Mark Nudleman or 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.
"@(#) Copyright (c) 1988 Mark Nudleman.\n\
@(#) Copyright (c) 1988 Regents of the University of California.\n\
static char sccsid
[] = "@(#)lesskey.c 5.3 (Berkeley) %G%";
* lesskey [-o output] [input]
* If no input file is specified, standard input is used.
* If no output file is specified, $HOME/.less is used.
* The .less file is used to specify (to "less") user-defined
* key bindings. Basically any sequence of 1 to MAX_CMDLEN
* keystrokes may be bound to an existing less function.
* The input file is an ascii file consisting of a
* sequence of lines of the form:
* string <whitespace> action <newline>
* "string" is a sequence of command characters which form
* the new user-defined command. The command
* 1. The actual character itself.
* 2. A character preceeded by ^ to specify a
* control character (e.g. ^X means control-X).
* 3. Any character (other than an octal digit) preceeded by
* a \ to specify the character itself (characters which
* must be preceeded by \ include ^, \, and whitespace.
* 4. A backslash followed by one to three octal digits
* to specify a character by its octal value.
* "action" is the name of a "less" action, from the table below.
* Blank lines and lines which start with # are ignored.
* The output file is a non-ascii file, consisting of
* zero or more byte sequences of the form:
* "string" is the command string.
* "<0>" is one null byte.
* "<action>" is one byte containing the action code (the A_xxx value).
* v1: Initial version. 10/13/87 mark
char usertable
[MAX_USERCMD
];
"back-screen", A_B_SCREEN
,
"back-scroll", A_B_SCROLL
,
"back-search", A_B_SEARCH
,
"display-flag", A_DISP_OPTION
,
"display-option", A_DISP_OPTION
,
"flush-repaint", A_FREPAINT
,
"forw-screen", A_F_SCREEN
,
"forw-scroll", A_F_SCROLL
,
"forw-search", A_F_SEARCH
,
"next-file", A_NEXT_FILE
,
"prev-file", A_PREV_FILE
,
"repaint-flush", A_FREPAINT
,
"repeat-search", A_AGAIN_SEARCH
,
"toggle-flag", A_TOGGLE_OPTION
,
"toggle-option", A_TOGGLE_OPTION
,
char *p
; /* {{ Can't be register since we use &p }} */
register char *up
; /* Pointer into usertable */
FILE *desc
; /* Description file (input) */
FILE *out
; /* Output file */
int linenum
; /* Line number in input file */
char *currcmd
; /* Start of current command string */
extern char *getenv(), *strcat(), *strcpy();
* Process command line arguments.
while (--argc
> 0 && **(++argv
) == '-')
* Open the input file, or use standard input if none specified.
if ((desc
= fopen(*argv
, "r")) == NULL
)
* Read the input file, one line at a time.
* Each line consists of a command string,
* followed by white space, followed by an action name.
while (fgets(line
, sizeof(line
), desc
) != NULL
)
* Skip leading white space.
* Replace the final newline with a null byte.
* Ignore blank lines and comment lines.
while (*p
== ' ' || *p
== '\t')
for (i
= 0; p
[i
] != '\n' && p
[i
] != '\0'; i
++)
if (*p
== '#' || *p
== '\0')
* Parse the command string and store it in the usertable.
if (up
>= usertable
+ MAX_USERCMD
)
fprintf(stderr
, "too many commands, line %d\n",
if (up
>= currcmd
+ MAX_CMDLEN
)
fprintf(stderr
, "command too long on line %d\n",
} while (*p
!= ' ' && *p
!= '\t' && *p
!= '\0');
* Terminate the command string with a null byte.
* Skip white space between the command string
* Terminate the action name if it is followed
* by whitespace or a # comment.
fprintf(stderr
, "missing whitespace on line %d\n",
while (*p
== ' ' || *p
== '\t')
for (i
= 0; p
[i
] != ' ' && p
[i
] != '\t' &&
p
[i
] != '#' && p
[i
] != '\0'; i
++)
* Parse the action name and store it in the usertable.
for (i
= 0; cmdnames
[i
].cn_name
!= NULL
; i
++)
if (strcmp(cmdnames
[i
].cn_name
, p
) == 0)
if (cmdnames
[i
].cn_name
== NULL
)
fprintf(stderr
, "unknown action <%s> on line %d\n",
*up
++ = cmdnames
[i
].cn_action
;
fprintf(stderr
, "%d errors; no output produced\n", errors
);
* If no output file was specified, use "$HOME/.less"
fprintf(stderr
, "cannot find $HOME\n");
if ((out
= fopen(outfile
, "w")) == NULL
)
fwrite((char *)usertable
, 1, up
-usertable
, out
);
* Parse one character of the command string.
if (*++p
>= '0' && *p
<= '7')
while (*++p
>= '0' && *p
<= '7' && ++i
< 3);
* Backslash followed by a char just means that char.
fprintf(stderr
, "usage: lesskey [-o output] [input]\n");