Changeset View
Changeset View
Standalone View
Standalone View
contrib/less/lesskey.c
Show First 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | |||||
char endsection[1] = { END_SECTION }; | char endsection[1] = { END_SECTION }; | ||||
char *infile = NULL; | char *infile = NULL; | ||||
char *outfile = NULL ; | char *outfile = NULL ; | ||||
int linenum; | int linenum; | ||||
int errors; | int errors; | ||||
static void lk_error(char *s); | |||||
extern char version[]; | extern char version[]; | ||||
void | void | ||||
usage() | usage(void) | ||||
{ | { | ||||
fprintf(stderr, "usage: lesskey [-o output] [input]\n"); | fprintf(stderr, "usage: lesskey [-o output] [input]\n"); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
char * | char * | ||||
mkpathname(dirname, filename) | mkpathname(char *dirname, char *filename) | ||||
char *dirname; | |||||
char *filename; | |||||
{ | { | ||||
char *pathname; | char *pathname; | ||||
pathname = calloc(strlen(dirname) + strlen(filename) + 2, sizeof(char)); | pathname = calloc(strlen(dirname) + strlen(filename) + 2, sizeof(char)); | ||||
strcpy(pathname, dirname); | strcpy(pathname, dirname); | ||||
strcat(pathname, PATHNAME_SEP); | strcat(pathname, PATHNAME_SEP); | ||||
strcat(pathname, filename); | strcat(pathname, filename); | ||||
return (pathname); | return (pathname); | ||||
} | } | ||||
/* | /* | ||||
* Figure out the name of a default file (in the user's HOME directory). | * Figure out the name of a default file (in the user's HOME directory). | ||||
*/ | */ | ||||
char * | char * | ||||
homefile(filename) | homefile(char *filename) | ||||
char *filename; | |||||
{ | { | ||||
char *p; | char *p; | ||||
char *pathname; | char *pathname; | ||||
if ((p = getenv("HOME")) != NULL && *p != '\0') | if ((p = getenv("HOME")) != NULL && *p != '\0') | ||||
pathname = mkpathname(p, filename); | pathname = mkpathname(p, filename); | ||||
#if OS2 | #if OS2 | ||||
else if ((p = getenv("INIT")) != NULL && *p != '\0') | else if ((p = getenv("INIT")) != NULL && *p != '\0') | ||||
pathname = mkpathname(p, filename); | pathname = mkpathname(p, filename); | ||||
#endif | #endif | ||||
else | else | ||||
{ | { | ||||
fprintf(stderr, "cannot find $HOME - using current directory\n"); | fprintf(stderr, "cannot find $HOME - using current directory\n"); | ||||
pathname = mkpathname(".", filename); | pathname = mkpathname(".", filename); | ||||
} | } | ||||
return (pathname); | return (pathname); | ||||
} | } | ||||
/* | /* | ||||
* Parse command line arguments. | * Parse command line arguments. | ||||
*/ | */ | ||||
void | void | ||||
parse_args(argc, argv) | parse_args(int argc, char **argv) | ||||
int argc; | |||||
char **argv; | |||||
{ | { | ||||
char *arg; | char *arg; | ||||
outfile = NULL; | outfile = NULL; | ||||
while (--argc > 0) | while (--argc > 0) | ||||
{ | { | ||||
arg = *++argv; | arg = *++argv; | ||||
if (arg[0] != '-') | if (arg[0] != '-') | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | parse_args(int argc, char **argv) | ||||
else | else | ||||
infile = homefile(DEF_LESSKEYINFILE); | infile = homefile(DEF_LESSKEYINFILE); | ||||
} | } | ||||
/* | /* | ||||
* Initialize data structures. | * Initialize data structures. | ||||
*/ | */ | ||||
void | void | ||||
init_tables() | init_tables(void) | ||||
{ | { | ||||
cmdtable.names = cmdnames; | cmdtable.names = cmdnames; | ||||
cmdtable.pbuffer = cmdtable.buffer; | cmdtable.pbuffer = cmdtable.buffer; | ||||
edittable.names = editnames; | edittable.names = editnames; | ||||
edittable.pbuffer = edittable.buffer; | edittable.pbuffer = edittable.buffer; | ||||
vartable.names = NULL; | vartable.names = NULL; | ||||
vartable.pbuffer = vartable.buffer; | vartable.pbuffer = vartable.buffer; | ||||
} | } | ||||
/* | /* | ||||
* Parse one character of a string. | * Parse one character of a string. | ||||
*/ | */ | ||||
char * | char * | ||||
tstr(pp, xlate) | tstr(char **pp, int xlate) | ||||
char **pp; | |||||
int xlate; | |||||
{ | { | ||||
register char *p; | register char *p; | ||||
register char ch; | register char ch; | ||||
register int i; | register int i; | ||||
static char buf[10]; | static char buf[10]; | ||||
static char tstr_control_k[] = | static char tstr_control_k[] = | ||||
{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' }; | { SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' }; | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | case 'k': | ||||
case 'r': ch = SK_RIGHT_ARROW; break; | case 'r': ch = SK_RIGHT_ARROW; break; | ||||
case 'l': ch = SK_LEFT_ARROW; break; | case 'l': ch = SK_LEFT_ARROW; break; | ||||
case 'U': ch = SK_PAGE_UP; break; | case 'U': ch = SK_PAGE_UP; break; | ||||
case 'D': ch = SK_PAGE_DOWN; break; | case 'D': ch = SK_PAGE_DOWN; break; | ||||
case 'h': ch = SK_HOME; break; | case 'h': ch = SK_HOME; break; | ||||
case 'e': ch = SK_END; break; | case 'e': ch = SK_END; break; | ||||
case 'x': ch = SK_DELETE; break; | case 'x': ch = SK_DELETE; break; | ||||
default: | default: | ||||
error("illegal char after \\k"); | lk_error("illegal char after \\k"); | ||||
*pp = p+1; | *pp = p+1; | ||||
return (""); | return (""); | ||||
} | } | ||||
*pp = p+1; | *pp = p+1; | ||||
buf[0] = SK_SPECIAL_KEY; | buf[0] = SK_SPECIAL_KEY; | ||||
buf[1] = ch; | buf[1] = ch; | ||||
buf[2] = 6; | buf[2] = 6; | ||||
buf[3] = 1; | buf[3] = 1; | ||||
Show All 33 Lines | if (xlate && buf[0] == CONTROL('K')) | ||||
return tstr_control_k; | return tstr_control_k; | ||||
return (buf); | return (buf); | ||||
} | } | ||||
/* | /* | ||||
* Skip leading spaces in a string. | * Skip leading spaces in a string. | ||||
*/ | */ | ||||
public char * | public char * | ||||
skipsp(s) | skipsp(char *s) | ||||
register char *s; | |||||
{ | { | ||||
while (*s == ' ' || *s == '\t') | while (*s == ' ' || *s == '\t') | ||||
s++; | s++; | ||||
return (s); | return (s); | ||||
} | } | ||||
/* | /* | ||||
* Skip non-space characters in a string. | * Skip non-space characters in a string. | ||||
*/ | */ | ||||
public char * | public char * | ||||
skipnsp(s) | skipnsp(char *s) | ||||
register char *s; | |||||
{ | { | ||||
while (*s != '\0' && *s != ' ' && *s != '\t') | while (*s != '\0' && *s != ' ' && *s != '\t') | ||||
s++; | s++; | ||||
return (s); | return (s); | ||||
} | } | ||||
/* | /* | ||||
* Clean up an input line: | * Clean up an input line: | ||||
* strip off the trailing newline & any trailing # comment. | * strip off the trailing newline & any trailing # comment. | ||||
*/ | */ | ||||
char * | char * | ||||
clean_line(s) | clean_line(char *s) | ||||
char *s; | |||||
{ | { | ||||
register int i; | register int i; | ||||
s = skipsp(s); | s = skipsp(s); | ||||
for (i = 0; s[i] != '\n' && s[i] != '\r' && s[i] != '\0'; i++) | for (i = 0; s[i] != '\n' && s[i] != '\r' && s[i] != '\0'; i++) | ||||
if (s[i] == '#' && (i == 0 || s[i-1] != '\\')) | if (s[i] == '#' && (i == 0 || s[i-1] != '\\')) | ||||
break; | break; | ||||
s[i] = '\0'; | s[i] = '\0'; | ||||
return (s); | return (s); | ||||
} | } | ||||
/* | /* | ||||
* Add a byte to the output command table. | * Add a byte to the output command table. | ||||
*/ | */ | ||||
void | void | ||||
add_cmd_char(c) | add_cmd_char(int c) | ||||
int c; | |||||
{ | { | ||||
if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD) | if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD) | ||||
{ | { | ||||
error("too many commands"); | lk_error("too many commands"); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
*(currtable->pbuffer)++ = c; | *(currtable->pbuffer)++ = c; | ||||
} | } | ||||
/* | /* | ||||
* Add a string to the output command table. | * Add a string to the output command table. | ||||
*/ | */ | ||||
void | void | ||||
add_cmd_str(s) | add_cmd_str(char *s) | ||||
char *s; | |||||
{ | { | ||||
for ( ; *s != '\0'; s++) | for ( ; *s != '\0'; s++) | ||||
add_cmd_char(*s); | add_cmd_char(*s); | ||||
} | } | ||||
/* | /* | ||||
* See if we have a special "control" line. | * See if we have a special "control" line. | ||||
*/ | */ | ||||
int | int | ||||
control_line(s) | control_line(char *s) | ||||
char *s; | |||||
{ | { | ||||
#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0) | #define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0) | ||||
if (PREFIX(s, "#line-edit")) | if (PREFIX(s, "#line-edit")) | ||||
{ | { | ||||
currtable = &edittable; | currtable = &edittable; | ||||
return (1); | return (1); | ||||
} | } | ||||
Show All 15 Lines | #define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0) | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Output some bytes. | * Output some bytes. | ||||
*/ | */ | ||||
void | void | ||||
fputbytes(fd, buf, len) | fputbytes(FILE *fd, char *buf, int len) | ||||
FILE *fd; | |||||
char *buf; | |||||
int len; | |||||
{ | { | ||||
while (len-- > 0) | while (len-- > 0) | ||||
{ | { | ||||
fwrite(buf, sizeof(char), 1, fd); | fwrite(buf, sizeof(char), 1, fd); | ||||
buf++; | buf++; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Output an integer, in special KRADIX form. | * Output an integer, in special KRADIX form. | ||||
*/ | */ | ||||
void | void | ||||
fputint(fd, val) | fputint(FILE *fd, unsigned int val) | ||||
FILE *fd; | |||||
unsigned int val; | |||||
{ | { | ||||
char c; | char c; | ||||
if (val >= KRADIX*KRADIX) | if (val >= KRADIX*KRADIX) | ||||
{ | { | ||||
fprintf(stderr, "error: integer too big (%d > %d)\n", | fprintf(stderr, "error: integer too big (%d > %d)\n", | ||||
val, KRADIX*KRADIX); | val, KRADIX*KRADIX); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
c = val % KRADIX; | c = val % KRADIX; | ||||
fwrite(&c, sizeof(char), 1, fd); | fwrite(&c, sizeof(char), 1, fd); | ||||
c = val / KRADIX; | c = val / KRADIX; | ||||
fwrite(&c, sizeof(char), 1, fd); | fwrite(&c, sizeof(char), 1, fd); | ||||
} | } | ||||
/* | /* | ||||
* Find an action, given the name of the action. | * Find an action, given the name of the action. | ||||
*/ | */ | ||||
int | int | ||||
findaction(actname) | findaction(char *actname) | ||||
char *actname; | |||||
{ | { | ||||
int i; | int i; | ||||
for (i = 0; currtable->names[i].cn_name != NULL; i++) | for (i = 0; currtable->names[i].cn_name != NULL; i++) | ||||
if (strcmp(currtable->names[i].cn_name, actname) == 0) | if (strcmp(currtable->names[i].cn_name, actname) == 0) | ||||
return (currtable->names[i].cn_action); | return (currtable->names[i].cn_action); | ||||
error("unknown action"); | lk_error("unknown action"); | ||||
return (A_INVALID); | return (A_INVALID); | ||||
} | } | ||||
void | static void | ||||
error(s) | lk_error(char *s) | ||||
char *s; | |||||
{ | { | ||||
fprintf(stderr, "line %d: %s\n", linenum, s); | fprintf(stderr, "line %d: %s\n", linenum, s); | ||||
errors++; | errors++; | ||||
} | } | ||||
void | void | ||||
parse_cmdline(p) | parse_cmdline(char *p) | ||||
char *p; | |||||
{ | { | ||||
int cmdlen; | int cmdlen; | ||||
char *actname; | char *actname; | ||||
int action; | int action; | ||||
char *s; | char *s; | ||||
char c; | char c; | ||||
/* | /* | ||||
* Parse the command string and store it in the current table. | * Parse the command string and store it in the current table. | ||||
*/ | */ | ||||
cmdlen = 0; | cmdlen = 0; | ||||
do | do | ||||
{ | { | ||||
s = tstr(&p, 1); | s = tstr(&p, 1); | ||||
cmdlen += (int) strlen(s); | cmdlen += (int) strlen(s); | ||||
if (cmdlen > MAX_CMDLEN) | if (cmdlen > MAX_CMDLEN) | ||||
error("command too long"); | lk_error("command too long"); | ||||
else | else | ||||
add_cmd_str(s); | add_cmd_str(s); | ||||
} while (*p != ' ' && *p != '\t' && *p != '\0'); | } while (*p != ' ' && *p != '\t' && *p != '\0'); | ||||
/* | /* | ||||
* Terminate the command string with a null byte. | * Terminate the command string with a null byte. | ||||
*/ | */ | ||||
add_cmd_char('\0'); | add_cmd_char('\0'); | ||||
/* | /* | ||||
* Skip white space between the command string | * Skip white space between the command string | ||||
* and the action name. | * and the action name. | ||||
* Terminate the action name with a null byte. | * Terminate the action name with a null byte. | ||||
*/ | */ | ||||
p = skipsp(p); | p = skipsp(p); | ||||
if (*p == '\0') | if (*p == '\0') | ||||
{ | { | ||||
error("missing action"); | lk_error("missing action"); | ||||
return; | return; | ||||
} | } | ||||
actname = p; | actname = p; | ||||
p = skipnsp(p); | p = skipnsp(p); | ||||
c = *p; | c = *p; | ||||
*p = '\0'; | *p = '\0'; | ||||
/* | /* | ||||
Show All 18 Lines | if (*p == '\0') | ||||
add_cmd_char(action | A_EXTRA); | add_cmd_char(action | A_EXTRA); | ||||
while (*p != '\0') | while (*p != '\0') | ||||
add_cmd_str(tstr(&p, 0)); | add_cmd_str(tstr(&p, 0)); | ||||
add_cmd_char('\0'); | add_cmd_char('\0'); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
parse_varline(p) | parse_varline(char *p) | ||||
char *p; | |||||
{ | { | ||||
char *s; | char *s; | ||||
do | do | ||||
{ | { | ||||
s = tstr(&p, 0); | s = tstr(&p, 0); | ||||
add_cmd_str(s); | add_cmd_str(s); | ||||
} while (*p != ' ' && *p != '\t' && *p != '=' && *p != '\0'); | } while (*p != ' ' && *p != '\t' && *p != '=' && *p != '\0'); | ||||
/* | /* | ||||
* Terminate the variable name with a null byte. | * Terminate the variable name with a null byte. | ||||
*/ | */ | ||||
add_cmd_char('\0'); | add_cmd_char('\0'); | ||||
p = skipsp(p); | p = skipsp(p); | ||||
if (*p++ != '=') | if (*p++ != '=') | ||||
{ | { | ||||
error("missing ="); | lk_error("missing ="); | ||||
return; | return; | ||||
} | } | ||||
add_cmd_char(EV_OK|A_EXTRA); | add_cmd_char(EV_OK|A_EXTRA); | ||||
p = skipsp(p); | p = skipsp(p); | ||||
while (*p != '\0') | while (*p != '\0') | ||||
{ | { | ||||
s = tstr(&p, 0); | s = tstr(&p, 0); | ||||
add_cmd_str(s); | add_cmd_str(s); | ||||
} | } | ||||
add_cmd_char('\0'); | add_cmd_char('\0'); | ||||
} | } | ||||
/* | /* | ||||
* Parse a line from the lesskey file. | * Parse a line from the lesskey file. | ||||
*/ | */ | ||||
void | void | ||||
parse_line(line) | parse_line(char *line) | ||||
char *line; | |||||
{ | { | ||||
char *p; | char *p; | ||||
/* | /* | ||||
* See if it is a control line. | * See if it is a control line. | ||||
*/ | */ | ||||
if (control_line(line)) | if (control_line(line)) | ||||
return; | return; | ||||
/* | /* | ||||
* Skip leading white space. | * Skip leading white space. | ||||
* Replace the final newline with a null byte. | * Replace the final newline with a null byte. | ||||
* Ignore blank lines and comments. | * Ignore blank lines and comments. | ||||
*/ | */ | ||||
p = clean_line(line); | p = clean_line(line); | ||||
if (*p == '\0') | if (*p == '\0') | ||||
return; | return; | ||||
if (currtable == &vartable) | if (currtable == &vartable) | ||||
parse_varline(p); | parse_varline(p); | ||||
else | else | ||||
parse_cmdline(p); | parse_cmdline(p); | ||||
} | } | ||||
int | int | ||||
main(argc, argv) | main(int argc, char *argv[]) | ||||
int argc; | |||||
char *argv[]; | |||||
{ | { | ||||
FILE *desc; | FILE *desc; | ||||
FILE *out; | FILE *out; | ||||
char line[1024]; | char line[1024]; | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
if (getenv("HOME") == NULL) | if (getenv("HOME") == NULL) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 96 Lines • Show Last 20 Lines |