diff options
author | delphij <delphij@FreeBSD.org> | 2009-05-08 23:34:35 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2009-05-08 23:34:35 +0000 |
commit | d069efd47cacc3156036ed37d5532d6a1d4f55c3 (patch) | |
tree | 2526f6b109843b646672c1537476dc51e56c0454 /contrib/less/lesskey.c | |
parent | 6aa3e25391d160482339ee072c010bcd22dfbbd1 (diff) | |
download | FreeBSD-src-d069efd47cacc3156036ed37d5532d6a1d4f55c3.zip FreeBSD-src-d069efd47cacc3156036ed37d5532d6a1d4f55c3.tar.gz |
Flatten all tags of the dist tree of less.
Diffstat (limited to 'contrib/less/lesskey.c')
-rw-r--r-- | contrib/less/lesskey.c | 871 |
1 files changed, 0 insertions, 871 deletions
diff --git a/contrib/less/lesskey.c b/contrib/less/lesskey.c deleted file mode 100644 index 2e95c20..0000000 --- a/contrib/less/lesskey.c +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (C) 1984-2007 Mark Nudelman - * - * You may distribute under the terms of either the GNU General Public - * License or the Less License, as specified in the README file. - * - * For more information about less, or for information on how to - * contact the author, see the README file. - */ - - -/* - * lesskey [-o output] [input] - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * Make a .less file. - * 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 [chars] <newline> - * - * "string" is a sequence of command characters which form - * the new user-defined command. The command - * characters may be: - * 1. The actual character itself. - * 2. A character preceded by ^ to specify a - * control character (e.g. ^X means control-X). - * 3. A backslash followed by one to three octal digits - * to specify a character by its octal value. - * 4. A backslash followed by b, e, n, r or t - * to specify \b, ESC, \n, \r or \t, respectively. - * 5. Any character (other than those mentioned above) preceded - * by a \ to specify the character itself (characters which - * must be preceded by \ include ^, \, and whitespace. - * "action" is the name of a "less" action, from the table below. - * "chars" is an optional sequence of characters which is treated - * as keyboard input after the command is executed. - * - * Blank lines and lines which start with # are ignored, - * except for the special control lines: - * #command Signals the beginning of the command - * keys section. - * #line-edit Signals the beginning of the line-editing - * keys section. - * #env Signals the beginning of the environment - * variable section. - * #stop Stops command parsing in less; - * causes all default keys to be disabled. - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * The output file is a non-ascii file, consisting of a header, - * one or more sections, and a trailer. - * Each section begins with a section header, a section length word - * and the section data. Normally there are three sections: - * CMD_SECTION Definition of command keys. - * EDIT_SECTION Definition of editing keys. - * END_SECTION A special section header, with no - * length word or section data. - * - * Section data consists of zero or more byte sequences of the form: - * string <0> <action> - * or - * string <0> <action|A_EXTRA> chars <0> - * - * "string" is the command string. - * "<0>" is one null byte. - * "<action>" is one byte containing the action code (the A_xxx value). - * If action is ORed with A_EXTRA, the action byte is followed - * by the null-terminated "chars" string. - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - */ - -#include "less.h" -#include "lesskey.h" -#include "cmd.h" - -struct cmdname -{ - char *cn_name; - int cn_action; -}; - -struct cmdname cmdnames[] = -{ - { "back-bracket", A_B_BRACKET }, - { "back-line", A_B_LINE }, - { "back-line-force", A_BF_LINE }, - { "back-screen", A_B_SCREEN }, - { "back-scroll", A_B_SCROLL }, - { "back-search", A_B_SEARCH }, - { "back-window", A_B_WINDOW }, - { "debug", A_DEBUG }, - { "digit", A_DIGIT }, - { "display-flag", A_DISP_OPTION }, - { "display-option", A_DISP_OPTION }, - { "end", A_GOEND }, - { "examine", A_EXAMINE }, - { "first-cmd", A_FIRSTCMD }, - { "firstcmd", A_FIRSTCMD }, - { "flush-repaint", A_FREPAINT }, - { "forw-bracket", A_F_BRACKET }, - { "forw-forever", A_F_FOREVER }, - { "forw-line", A_F_LINE }, - { "forw-line-force", A_FF_LINE }, - { "forw-screen", A_F_SCREEN }, - { "forw-screen-force", A_FF_SCREEN }, - { "forw-scroll", A_F_SCROLL }, - { "forw-search", A_F_SEARCH }, - { "forw-window", A_F_WINDOW }, - { "goto-end", A_GOEND }, - { "goto-line", A_GOLINE }, - { "goto-mark", A_GOMARK }, - { "help", A_HELP }, - { "index-file", A_INDEX_FILE }, - { "invalid", A_UINVALID }, - { "left-scroll", A_LSHIFT }, - { "next-file", A_NEXT_FILE }, - { "next-tag", A_NEXT_TAG }, - { "noaction", A_NOACTION }, - { "percent", A_PERCENT }, - { "pipe", A_PIPE }, - { "prev-file", A_PREV_FILE }, - { "prev-tag", A_PREV_TAG }, - { "quit", A_QUIT }, - { "remove-file", A_REMOVE_FILE }, - { "repaint", A_REPAINT }, - { "repaint-flush", A_FREPAINT }, - { "repeat-search", A_AGAIN_SEARCH }, - { "repeat-search-all", A_T_AGAIN_SEARCH }, - { "reverse-search", A_REVERSE_SEARCH }, - { "reverse-search-all", A_T_REVERSE_SEARCH }, - { "right-scroll", A_RSHIFT }, - { "set-mark", A_SETMARK }, - { "shell", A_SHELL }, - { "status", A_STAT }, - { "toggle-flag", A_OPT_TOGGLE }, - { "toggle-option", A_OPT_TOGGLE }, - { "undo-hilite", A_UNDO_SEARCH }, - { "version", A_VERSION }, - { "visual", A_VISUAL }, - { NULL, 0 } -}; - -struct cmdname editnames[] = -{ - { "back-complete", EC_B_COMPLETE }, - { "backspace", EC_BACKSPACE }, - { "delete", EC_DELETE }, - { "down", EC_DOWN }, - { "end", EC_END }, - { "expand", EC_EXPAND }, - { "forw-complete", EC_F_COMPLETE }, - { "home", EC_HOME }, - { "insert", EC_INSERT }, - { "invalid", EC_UINVALID }, - { "kill-line", EC_LINEKILL }, - { "left", EC_LEFT }, - { "literal", EC_LITERAL }, - { "right", EC_RIGHT }, - { "up", EC_UP }, - { "word-backspace", EC_W_BACKSPACE }, - { "word-delete", EC_W_DELETE }, - { "word-left", EC_W_LEFT }, - { "word-right", EC_W_RIGHT }, - { NULL, 0 } -}; - -struct table -{ - struct cmdname *names; - char *pbuffer; - char buffer[MAX_USERCMD]; -}; - -struct table cmdtable; -struct table edittable; -struct table vartable; -struct table *currtable = &cmdtable; - -char fileheader[] = { - C0_LESSKEY_MAGIC, - C1_LESSKEY_MAGIC, - C2_LESSKEY_MAGIC, - C3_LESSKEY_MAGIC -}; -char filetrailer[] = { - C0_END_LESSKEY_MAGIC, - C1_END_LESSKEY_MAGIC, - C2_END_LESSKEY_MAGIC -}; -char cmdsection[1] = { CMD_SECTION }; -char editsection[1] = { EDIT_SECTION }; -char varsection[1] = { VAR_SECTION }; -char endsection[1] = { END_SECTION }; - -char *infile = NULL; -char *outfile = NULL ; - -int linenum; -int errors; - -extern char version[]; - - void -usage() -{ - fprintf(stderr, "usage: lesskey [-o output] [input]\n"); - exit(1); -} - - char * -mkpathname(dirname, filename) - char *dirname; - char *filename; -{ - char *pathname; - - pathname = calloc(strlen(dirname) + strlen(filename) + 2, sizeof(char)); - strcpy(pathname, dirname); - strcat(pathname, PATHNAME_SEP); - strcat(pathname, filename); - return (pathname); -} - -/* - * Figure out the name of a default file (in the user's HOME directory). - */ - char * -homefile(filename) - char *filename; -{ - char *p; - char *pathname; - - if ((p = getenv("HOME")) != NULL && *p != '\0') - pathname = mkpathname(p, filename); -#if OS2 - else if ((p = getenv("INIT")) != NULL && *p != '\0') - pathname = mkpathname(p, filename); -#endif - else - { - fprintf(stderr, "cannot find $HOME - using current directory\n"); - pathname = mkpathname(".", filename); - } - return (pathname); -} - -/* - * Parse command line arguments. - */ - void -parse_args(argc, argv) - int argc; - char **argv; -{ - char *arg; - - outfile = NULL; - while (--argc > 0) - { - arg = *++argv; - if (arg[0] != '-') - /* Arg does not start with "-"; it's not an option. */ - break; - if (arg[1] == '\0') - /* "-" means standard input. */ - break; - if (arg[1] == '-' && arg[2] == '\0') - { - /* "--" means end of options. */ - argc--; - argv++; - break; - } - switch (arg[1]) - { - case '-': - if (strncmp(arg, "--output", 8) == 0) - { - if (arg[8] == '\0') - outfile = &arg[8]; - else if (arg[8] == '=') - outfile = &arg[9]; - else - usage(); - goto opt_o; - } - if (strcmp(arg, "--version") == 0) - { - goto opt_V; - } - usage(); - break; - case 'o': - outfile = &argv[0][2]; - opt_o: - if (*outfile == '\0') - { - if (--argc <= 0) - usage(); - outfile = *(++argv); - } - break; - case 'V': - opt_V: - printf("lesskey version %s\n", version); - exit(0); - default: - usage(); - } - } - if (argc > 1) - usage(); - /* - * Open the input file, or use DEF_LESSKEYINFILE if none specified. - */ - if (argc > 0) - infile = *argv; - else - infile = homefile(DEF_LESSKEYINFILE); -} - -/* - * Initialize data structures. - */ - void -init_tables() -{ - cmdtable.names = cmdnames; - cmdtable.pbuffer = cmdtable.buffer; - - edittable.names = editnames; - edittable.pbuffer = edittable.buffer; - - vartable.names = NULL; - vartable.pbuffer = vartable.buffer; -} - -/* - * Parse one character of a string. - */ - char * -tstr(pp, xlate) - char **pp; - int xlate; -{ - register char *p; - register char ch; - register int i; - static char buf[10]; - static char tstr_control_k[] = - { SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' }; - - p = *pp; - switch (*p) - { - case '\\': - ++p; - switch (*p) - { - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - /* - * Parse an octal number. - */ - ch = 0; - i = 0; - do - ch = 8*ch + (*p - '0'); - while (*++p >= '0' && *p <= '7' && ++i < 3); - *pp = p; - if (xlate && ch == CONTROL('K')) - return tstr_control_k; - buf[0] = ch; - buf[1] = '\0'; - return (buf); - case 'b': - *pp = p+1; - return ("\b"); - case 'e': - *pp = p+1; - buf[0] = ESC; - buf[1] = '\0'; - return (buf); - case 'n': - *pp = p+1; - return ("\n"); - case 'r': - *pp = p+1; - return ("\r"); - case 't': - *pp = p+1; - return ("\t"); - case 'k': - if (xlate) - { - switch (*++p) - { - case 'u': ch = SK_UP_ARROW; break; - case 'd': ch = SK_DOWN_ARROW; break; - case 'r': ch = SK_RIGHT_ARROW; break; - case 'l': ch = SK_LEFT_ARROW; break; - case 'U': ch = SK_PAGE_UP; break; - case 'D': ch = SK_PAGE_DOWN; break; - case 'h': ch = SK_HOME; break; - case 'e': ch = SK_END; break; - case 'x': ch = SK_DELETE; break; - default: - error("illegal char after \\k"); - *pp = p+1; - return (""); - } - *pp = p+1; - buf[0] = SK_SPECIAL_KEY; - buf[1] = ch; - buf[2] = 6; - buf[3] = 1; - buf[4] = 1; - buf[5] = 1; - buf[6] = '\0'; - return (buf); - } - /* FALLTHRU */ - default: - /* - * Backslash followed by any other char - * just means that char. - */ - *pp = p+1; - buf[0] = *p; - buf[1] = '\0'; - if (xlate && buf[0] == CONTROL('K')) - return tstr_control_k; - return (buf); - } - case '^': - /* - * Carat means CONTROL. - */ - *pp = p+2; - buf[0] = CONTROL(p[1]); - buf[1] = '\0'; - if (buf[0] == CONTROL('K')) - return tstr_control_k; - return (buf); - } - *pp = p+1; - buf[0] = *p; - buf[1] = '\0'; - if (xlate && buf[0] == CONTROL('K')) - return tstr_control_k; - return (buf); -} - -/* - * Skip leading spaces in a string. - */ - public char * -skipsp(s) - register char *s; -{ - while (*s == ' ' || *s == '\t') - s++; - return (s); -} - -/* - * Skip non-space characters in a string. - */ - public char * -skipnsp(s) - register char *s; -{ - while (*s != '\0' && *s != ' ' && *s != '\t') - s++; - return (s); -} - -/* - * Clean up an input line: - * strip off the trailing newline & any trailing # comment. - */ - char * -clean_line(s) - char *s; -{ - register int i; - - s = skipsp(s); - for (i = 0; s[i] != '\n' && s[i] != '\r' && s[i] != '\0'; i++) - if (s[i] == '#' && (i == 0 || s[i-1] != '\\')) - break; - s[i] = '\0'; - return (s); -} - -/* - * Add a byte to the output command table. - */ - void -add_cmd_char(c) - int c; -{ - if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD) - { - error("too many commands"); - exit(1); - } - *(currtable->pbuffer)++ = c; -} - -/* - * Add a string to the output command table. - */ - void -add_cmd_str(s) - char *s; -{ - for ( ; *s != '\0'; s++) - add_cmd_char(*s); -} - -/* - * See if we have a special "control" line. - */ - int -control_line(s) - char *s; -{ -#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)-1) == 0) - - if (PREFIX(s, "#line-edit")) - { - currtable = &edittable; - return (1); - } - if (PREFIX(s, "#command")) - { - currtable = &cmdtable; - return (1); - } - if (PREFIX(s, "#env")) - { - currtable = &vartable; - return (1); - } - if (PREFIX(s, "#stop")) - { - add_cmd_char('\0'); - add_cmd_char(A_END_LIST); - return (1); - } - return (0); -} - -/* - * Output some bytes. - */ - void -fputbytes(fd, buf, len) - FILE *fd; - char *buf; - int len; -{ - while (len-- > 0) - { - fwrite(buf, sizeof(char), 1, fd); - buf++; - } -} - -/* - * Output an integer, in special KRADIX form. - */ - void -fputint(fd, val) - FILE *fd; - unsigned int val; -{ - char c; - - if (val >= KRADIX*KRADIX) - { - fprintf(stderr, "error: integer too big (%d > %d)\n", - val, KRADIX*KRADIX); - exit(1); - } - c = val % KRADIX; - fwrite(&c, sizeof(char), 1, fd); - c = val / KRADIX; - fwrite(&c, sizeof(char), 1, fd); -} - -/* - * Find an action, given the name of the action. - */ - int -findaction(actname) - char *actname; -{ - int i; - - for (i = 0; currtable->names[i].cn_name != NULL; i++) - if (strcmp(currtable->names[i].cn_name, actname) == 0) - return (currtable->names[i].cn_action); - error("unknown action"); - return (A_INVALID); -} - - void -error(s) - char *s; -{ - fprintf(stderr, "line %d: %s\n", linenum, s); - errors++; -} - - - void -parse_cmdline(p) - char *p; -{ - int cmdlen; - char *actname; - int action; - char *s; - char c; - - /* - * Parse the command string and store it in the current table. - */ - cmdlen = 0; - do - { - s = tstr(&p, 1); - cmdlen += strlen(s); - if (cmdlen > MAX_CMDLEN) - error("command too long"); - else - add_cmd_str(s); - } while (*p != ' ' && *p != '\t' && *p != '\0'); - /* - * Terminate the command string with a null byte. - */ - add_cmd_char('\0'); - - /* - * Skip white space between the command string - * and the action name. - * Terminate the action name with a null byte. - */ - p = skipsp(p); - if (*p == '\0') - { - error("missing action"); - return; - } - actname = p; - p = skipnsp(p); - c = *p; - *p = '\0'; - - /* - * Parse the action name and store it in the current table. - */ - action = findaction(actname); - - /* - * See if an extra string follows the action name. - */ - *p = c; - p = skipsp(p); - if (*p == '\0') - { - add_cmd_char(action); - } else - { - /* - * OR the special value A_EXTRA into the action byte. - * Put the extra string after the action byte. - */ - add_cmd_char(action | A_EXTRA); - while (*p != '\0') - add_cmd_str(tstr(&p, 0)); - add_cmd_char('\0'); - } -} - - void -parse_varline(p) - char *p; -{ - char *s; - - do - { - s = tstr(&p, 0); - add_cmd_str(s); - } while (*p != ' ' && *p != '\t' && *p != '=' && *p != '\0'); - /* - * Terminate the variable name with a null byte. - */ - add_cmd_char('\0'); - - p = skipsp(p); - if (*p++ != '=') - { - error("missing ="); - return; - } - - add_cmd_char(EV_OK|A_EXTRA); - - p = skipsp(p); - while (*p != '\0') - { - s = tstr(&p, 0); - add_cmd_str(s); - } - add_cmd_char('\0'); -} - -/* - * Parse a line from the lesskey file. - */ - void -parse_line(line) - char *line; -{ - char *p; - - /* - * See if it is a control line. - */ - if (control_line(line)) - return; - /* - * Skip leading white space. - * Replace the final newline with a null byte. - * Ignore blank lines and comments. - */ - p = clean_line(line); - if (*p == '\0') - return; - - if (currtable == &vartable) - parse_varline(p); - else - parse_cmdline(p); -} - - int -main(argc, argv) - int argc; - char *argv[]; -{ - FILE *desc; - FILE *out; - char line[1024]; - -#ifdef WIN32 - if (getenv("HOME") == NULL) - { - /* - * If there is no HOME environment variable, - * try the concatenation of HOMEDRIVE + HOMEPATH. - */ - char *drive = getenv("HOMEDRIVE"); - char *path = getenv("HOMEPATH"); - if (drive != NULL && path != NULL) - { - char *env = (char *) calloc(strlen(drive) + - strlen(path) + 6, sizeof(char)); - strcpy(env, "HOME="); - strcat(env, drive); - strcat(env, path); - putenv(env); - } - } -#endif /* WIN32 */ - - /* - * Process command line arguments. - */ - parse_args(argc, argv); - init_tables(); - - /* - * Open the input file. - */ - if (strcmp(infile, "-") == 0) - desc = stdin; - else if ((desc = fopen(infile, "r")) == NULL) - { -#if HAVE_PERROR - perror(infile); -#else - fprintf(stderr, "Cannot open %s\n", infile); -#endif - usage(); - } - - /* - * Read and parse the input file, one line at a time. - */ - errors = 0; - linenum = 0; - while (fgets(line, sizeof(line), desc) != NULL) - { - ++linenum; - parse_line(line); - } - - /* - * Write the output file. - * If no output file was specified, use "$HOME/.less" - */ - if (errors > 0) - { - fprintf(stderr, "%d errors; no output produced\n", errors); - exit(1); - } - - if (outfile == NULL) - outfile = getenv("LESSKEY"); - if (outfile == NULL) - outfile = homefile(LESSKEYFILE); - if ((out = fopen(outfile, "wb")) == NULL) - { -#if HAVE_PERROR - perror(outfile); -#else - fprintf(stderr, "Cannot open %s\n", outfile); -#endif - exit(1); - } - - /* File header */ - fputbytes(out, fileheader, sizeof(fileheader)); - - /* Command key section */ - fputbytes(out, cmdsection, sizeof(cmdsection)); - fputint(out, cmdtable.pbuffer - cmdtable.buffer); - fputbytes(out, (char *)cmdtable.buffer, cmdtable.pbuffer-cmdtable.buffer); - /* Edit key section */ - fputbytes(out, editsection, sizeof(editsection)); - fputint(out, edittable.pbuffer - edittable.buffer); - fputbytes(out, (char *)edittable.buffer, edittable.pbuffer-edittable.buffer); - - /* Environment variable section */ - fputbytes(out, varsection, sizeof(varsection)); - fputint(out, vartable.pbuffer - vartable.buffer); - fputbytes(out, (char *)vartable.buffer, vartable.pbuffer-vartable.buffer); - - /* File trailer */ - fputbytes(out, endsection, sizeof(endsection)); - fputbytes(out, filetrailer, sizeof(filetrailer)); - return (0); -} |