1 /* $NetBSD: decode.c,v 1.4 2003/08/07 09:27:59 agc Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1988 Mark Nudleman 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. All advertising materials mentioning features or use of this software 44 * must display the following acknowledgement: 45 * This product includes software developed by the University of 46 * California, Berkeley and its contributors. 47 * 4. Neither the name of the University nor the names of its contributors 48 * may be used to endorse or promote products derived from this software 49 * without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 */ 63 64 #include <sys/cdefs.h> 65 #ifndef lint 66 #if 0 67 static char sccsid[] = "@(#)decode.c 8.1 (Berkeley) 6/6/93"; 68 #else 69 __RCSID("$NetBSD: decode.c,v 1.4 2003/08/07 09:27:59 agc Exp $"); 70 #endif 71 #endif /* not lint */ 72 73 /* 74 * Routines to decode user commands. 75 * 76 * This is all table driven. 77 * A command table is a sequence of command descriptors. 78 * Each command descriptor is a sequence of bytes with the following format: 79 * <c1><c2>...<cN><0><action> 80 * The characters c1,c2,...,cN are the command string; that is, 81 * the characters which the user must type. 82 * It is terminated by a null <0> byte. 83 * The byte after the null byte is the action code associated 84 * with the command string. 85 * 86 * The default commands are described by cmdtable. 87 */ 88 89 #include <sys/param.h> 90 #include <sys/file.h> 91 #include <stdio.h> 92 93 #include "less.h" 94 #include "extern.h" 95 96 /* 97 * Command table is ordered roughly according to expected 98 * frequency of use, so the common commands are near the beginning. 99 */ 100 #define CONTROL(c) ((c)&037) 101 102 static char cmdtable[] = { 103 '\r',0, A_F_LINE, 104 '\n',0, A_F_LINE, 105 'j',0, A_F_LINE, 106 'k',0, A_B_LINE, 107 'd',0, A_F_SCROLL, 108 CONTROL('D'),0, A_F_SCROLL, 109 'u',0, A_B_SCROLL, 110 CONTROL('U'),0, A_B_SCROLL, 111 ' ',0, A_F_SCREEN, 112 'f',0, A_F_SCREEN, 113 CONTROL('F'),0, A_F_SCREEN, 114 'b',0, A_B_SCREEN, 115 CONTROL('B'),0, A_B_SCREEN, 116 'R',0, A_FREPAINT, 117 'r',0, A_REPAINT, 118 CONTROL('L'),0, A_REPAINT, 119 'g',0, A_GOLINE, 120 'p',0, A_PERCENT, 121 '%',0, A_PERCENT, 122 'G',0, A_GOEND, 123 '0',0, A_DIGIT, 124 '1',0, A_DIGIT, 125 '2',0, A_DIGIT, 126 '3',0, A_DIGIT, 127 '4',0, A_DIGIT, 128 '5',0, A_DIGIT, 129 '6',0, A_DIGIT, 130 '7',0, A_DIGIT, 131 '8',0, A_DIGIT, 132 '9',0, A_DIGIT, 133 134 '=',0, A_STAT, 135 CONTROL('G'),0, A_STAT, 136 '/',0, A_F_SEARCH, 137 '?',0, A_B_SEARCH, 138 'n',0, A_AGAIN_SEARCH, 139 'm',0, A_SETMARK, 140 '\'',0, A_GOMARK, 141 'E',0, A_EXAMINE, 142 'N',0, A_NEXT_FILE, 143 ':','n',0, A_NEXT_FILE, 144 'P',0, A_PREV_FILE, 145 ':','p',0, A_PREV_FILE, 146 'v',0, A_VISUAL, 147 148 'h',0, A_HELP, 149 'q',0, A_QUIT, 150 ':','q',0, A_QUIT, 151 ':','t',0, A_TAGFILE, 152 ':', 'a', 0, A_FILE_LIST, 153 'Z','Z',0, A_QUIT, 154 }; 155 156 char *cmdendtable = cmdtable + sizeof(cmdtable); 157 158 #define MAX_CMDLEN 16 159 160 static char kbuf[MAX_CMDLEN+1]; 161 static char *kp = kbuf; 162 163 /* 164 * Indicate that we're not in a prefix command 165 * by resetting the command buffer pointer. 166 */ 167 void 168 noprefix() 169 { 170 kp = kbuf; 171 } 172 173 /* 174 * Decode a command character and return the associated action. 175 */ 176 int 177 cmd_decode(c) 178 int c; 179 { 180 int action = A_INVALID; 181 182 /* 183 * Append the new command character to the command string in kbuf. 184 */ 185 *kp++ = c; 186 *kp = '\0'; 187 188 action = cmd_search(cmdtable, cmdendtable); 189 190 /* This is not a prefix character. */ 191 if (action != A_PREFIX) 192 noprefix(); 193 return(action); 194 } 195 196 /* 197 * Search a command table for the current command string (in kbuf). 198 */ 199 int 200 cmd_search(table, endtable) 201 char *table; 202 char *endtable; 203 { 204 char *p, *q; 205 206 for (p = table, q = kbuf; p < endtable; p++, q++) { 207 if (*p == *q) { 208 /* 209 * Current characters match. 210 * If we're at the end of the string, we've found it. 211 * Return the action code, which is the character 212 * after the null at the end of the string 213 * in the command table. 214 */ 215 if (*p == '\0') 216 return(p[1]); 217 } 218 else if (*q == '\0') { 219 /* 220 * Hit the end of the user's command, 221 * but not the end of the string in the command table. 222 * The user's command is incomplete. 223 */ 224 return(A_PREFIX); 225 } else { 226 /* 227 * Not a match. 228 * Skip ahead to the next command in the 229 * command table, and reset the pointer 230 * to the user's command. 231 */ 232 while (*p++ != '\0'); 233 q = kbuf-1; 234 } 235 } 236 /* 237 * No match found in the entire command table. 238 */ 239 return(A_INVALID); 240 } 241