home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / more / decode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-03  |  5.4 KB  |  202 lines

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