/* $NetBSD: decode.c,v 1.5 2003/10/13 14:34:25 agc Exp $ */ /* * Copyright (c) 1988 Mark Nudelman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #ifndef lint #if 0 static char sccsid[] = "@(#)decode.c 8.1 (Berkeley) 6/6/93"; #else __RCSID("$NetBSD: decode.c,v 1.5 2003/10/13 14:34:25 agc Exp $"); #endif #endif /* not lint */ /* * 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: * ...<0> * 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. */ #include #include #include #include "less.h" #include "extern.h" /* * Command table is ordered roughly according to expected * frequency of use, so the common commands are near the beginning. */ #define CONTROL(c) ((c)&037) static char cmdtable[] = { '\r',0, A_F_LINE, '\n',0, A_F_LINE, 'j',0, A_F_LINE, 'k',0, A_B_LINE, 'd',0, A_F_SCROLL, CONTROL('D'),0, A_F_SCROLL, 'u',0, A_B_SCROLL, CONTROL('U'),0, A_B_SCROLL, ' ',0, A_F_SCREEN, 'f',0, A_F_SCREEN, CONTROL('F'),0, A_F_SCREEN, 'b',0, A_B_SCREEN, CONTROL('B'),0, A_B_SCREEN, 'R',0, A_FREPAINT, 'r',0, A_REPAINT, CONTROL('L'),0, A_REPAINT, 'g',0, A_GOLINE, 'p',0, A_PERCENT, '%',0, A_PERCENT, 'G',0, A_GOEND, '0',0, A_DIGIT, '1',0, A_DIGIT, '2',0, A_DIGIT, '3',0, A_DIGIT, '4',0, A_DIGIT, '5',0, A_DIGIT, '6',0, A_DIGIT, '7',0, A_DIGIT, '8',0, A_DIGIT, '9',0, A_DIGIT, '=',0, A_STAT, CONTROL('G'),0, A_STAT, '/',0, A_F_SEARCH, '?',0, A_B_SEARCH, 'n',0, A_AGAIN_SEARCH, 'm',0, A_SETMARK, '\'',0, A_GOMARK, 'E',0, A_EXAMINE, 'N',0, A_NEXT_FILE, ':','n',0, A_NEXT_FILE, 'P',0, A_PREV_FILE, ':','p',0, A_PREV_FILE, 'v',0, A_VISUAL, 'h',0, A_HELP, 'q',0, A_QUIT, ':','q',0, A_QUIT, ':','t',0, A_TAGFILE, ':', 'a', 0, A_FILE_LIST, 'Z','Z',0, A_QUIT, }; char *cmdendtable = cmdtable + sizeof(cmdtable); #define MAX_CMDLEN 16 static char kbuf[MAX_CMDLEN+1]; static char *kp = kbuf; /* * Indicate that we're not in a prefix command * by resetting the command buffer pointer. */ void noprefix() { kp = kbuf; } /* * Decode a command character and return the associated action. */ int cmd_decode(c) int c; { int action = A_INVALID; /* * Append the new command character to the command string in kbuf. */ *kp++ = c; *kp = '\0'; action = cmd_search(cmdtable, cmdendtable); /* This is not a prefix character. */ if (action != A_PREFIX) noprefix(); return(action); } /* * Search a command table for the current command string (in kbuf). */ int cmd_search(table, endtable) char *table; char *endtable; { char *p, *q; for (p = table, q = kbuf; p < endtable; p++, q++) { if (*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 * in the command table. */ if (*p == '\0') return(p[1]); } else if (*q == '\0') { /* * 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. */ return(A_PREFIX); } else { /* * Not a match. * Skip ahead to the next command in the * command table, and reset the pointer * to the user's command. */ while (*p++ != '\0'); q = kbuf-1; } } /* * No match found in the entire command table. */ return(A_INVALID); }