[BACK]Return to decode.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Diff for /src/usr.bin/less/decode.c between version 1.7 and 1.8

version 1.7, 2014/04/25 13:38:21 version 1.8, 2015/11/05 22:08:44
Line 6 
Line 6 
  *   *
  * For more information, see the README file.   * For more information, see the README file.
  */   */
   /*
    * Modified for use with illumos.
    * Copyright 2014 Garrett D'Amore <garrett@damore.org>
    */
   
   
 /*  /*
  * Routines to decode user commands.   * Routines to decode user commands.
  *   *
Line 34 
Line 37 
 #include "lesskey.h"  #include "lesskey.h"
   
 extern int erase_char, erase2_char, kill_char;  extern int erase_char, erase2_char, kill_char;
 extern int secure;  extern int secure, less_is_more;
   
 #define SK(k) \  #define SK(k) \
         SK_SPECIAL_KEY, (k), 6, 1, 1, 1          SK_SPECIAL_KEY, (k), 6, 1, 1, 1
 /*  /*
  * Command table is ordered roughly according to expected   * Command table is ordered roughly according to expected
Line 45 
Line 48 
   
 static unsigned char cmdtable[] =  static unsigned char cmdtable[] =
 {  {
         '\r',0,                         A_F_LINE,          '\r', 0,                        A_F_LINE,
         '\n',0,                         A_F_LINE,          '\n', 0,                        A_F_LINE,
         'e',0,                          A_F_LINE,          'e', 0,                         A_F_LINE,
         'j',0,                          A_F_LINE,          'j', 0,                         A_F_LINE,
         SK(SK_DOWN_ARROW),0,            A_F_LINE,          SK(SK_DOWN_ARROW), 0,           A_F_LINE,
         CONTROL('E'),0,                 A_F_LINE,          CONTROL('E'), 0,                A_F_LINE,
         CONTROL('N'),0,                 A_F_LINE,          CONTROL('N'), 0,                A_F_LINE,
         'k',0,                          A_B_LINE,          'k', 0,                         A_B_LINE,
         'y',0,                          A_B_LINE,          'y', 0,                         A_B_LINE,
         CONTROL('Y'),0,                 A_B_LINE,          CONTROL('Y'), 0,                A_B_LINE,
         SK(SK_CONTROL_K),0,             A_B_LINE,          SK(SK_CONTROL_K), 0,            A_B_LINE,
         CONTROL('P'),0,                 A_B_LINE,          CONTROL('P'), 0,                A_B_LINE,
         SK(SK_UP_ARROW),0,              A_B_LINE,          SK(SK_UP_ARROW), 0,             A_B_LINE,
         'J',0,                          A_FF_LINE,          'J', 0,                         A_FF_LINE,
         'K',0,                          A_BF_LINE,          'K', 0,                         A_BF_LINE,
         'Y',0,                          A_BF_LINE,          'Y', 0,                         A_BF_LINE,
         'd',0,                          A_F_SCROLL,          'd', 0,                         A_F_SCROLL,
         CONTROL('D'),0,                 A_F_SCROLL,          CONTROL('D'), 0,                A_F_SCROLL,
         'u',0,                          A_B_SCROLL,          'u', 0,                         A_B_SCROLL,
         CONTROL('U'),0,                 A_B_SCROLL,          CONTROL('U'), 0,                A_B_SCROLL,
         ' ',0,                          A_F_SCREEN,          ' ', 0,                         A_F_SCREEN,
         'f',0,                          A_F_SCREEN,          'f', 0,                         A_F_SCREEN,
         CONTROL('F'),0,                 A_F_SCREEN,          CONTROL('F'), 0,                A_F_SCREEN,
         CONTROL('V'),0,                 A_F_SCREEN,          CONTROL('V'), 0,                A_F_SCREEN,
         SK(SK_PAGE_DOWN),0,             A_F_SCREEN,          SK(SK_PAGE_DOWN), 0,            A_F_SCREEN,
         'b',0,                          A_B_SCREEN,          'b', 0,                         A_B_SCREEN,
         CONTROL('B'),0,                 A_B_SCREEN,          CONTROL('B'), 0,                A_B_SCREEN,
         ESC,'v',0,                      A_B_SCREEN,          ESC, 'v', 0,                    A_B_SCREEN,
         SK(SK_PAGE_UP),0,               A_B_SCREEN,          SK(SK_PAGE_UP), 0,              A_B_SCREEN,
         'z',0,                          A_F_WINDOW,          'z', 0,                         A_F_WINDOW,
         'w',0,                          A_B_WINDOW,          'w', 0,                         A_B_WINDOW,
         ESC,' ',0,                      A_FF_SCREEN,          ESC, ' ', 0,                    A_FF_SCREEN,
         'F',0,                          A_F_FOREVER,          'F', 0,                         A_F_FOREVER,
         ESC,'F',0,                      A_F_UNTIL_HILITE,          ESC, 'F', 0,                    A_F_UNTIL_HILITE,
         'R',0,                          A_FREPAINT,          'R', 0,                         A_FREPAINT,
         'r',0,                          A_REPAINT,          'r', 0,                         A_REPAINT,
         CONTROL('R'),0,                 A_REPAINT,          CONTROL('R'), 0,                A_REPAINT,
         CONTROL('L'),0,                 A_REPAINT,          CONTROL('L'), 0,                A_REPAINT,
         ESC,'u',0,                      A_UNDO_SEARCH,          ESC, 'u', 0,                    A_UNDO_SEARCH,
         'g',0,                          A_GOLINE,          'g', 0,                         A_GOLINE,
         SK(SK_HOME),0,                  A_GOLINE,          SK(SK_HOME), 0,                 A_GOLINE,
         '<',0,                          A_GOLINE,          '<', 0,                         A_GOLINE,
         ESC,'<',0,                      A_GOLINE,          ESC, '<', 0,                    A_GOLINE,
         'p',0,                          A_PERCENT,          'p', 0,                         A_PERCENT,
         '%',0,                          A_PERCENT,          '%', 0,                         A_PERCENT,
         ESC,'[',0,                      A_LSHIFT,          ESC, '[', 0,                    A_LSHIFT,
         ESC,']',0,                      A_RSHIFT,          ESC, ']', 0,                    A_RSHIFT,
         ESC,'(',0,                      A_LSHIFT,          ESC, '(', 0,                    A_LSHIFT,
         ESC,')',0,                      A_RSHIFT,          ESC, ')', 0,                    A_RSHIFT,
         SK(SK_RIGHT_ARROW),0,           A_RSHIFT,          SK(SK_RIGHT_ARROW), 0,          A_RSHIFT,
         SK(SK_LEFT_ARROW),0,            A_LSHIFT,          SK(SK_LEFT_ARROW), 0,           A_LSHIFT,
         '{',0,                          A_F_BRACKET|A_EXTRA,    '{','}',0,          '{', 0,                         A_F_BRACKET|A_EXTRA,    '{', '}', 0,
         '}',0,                          A_B_BRACKET|A_EXTRA,    '{','}',0,          '}', 0,                         A_B_BRACKET|A_EXTRA,    '{', '}', 0,
         '(',0,                          A_F_BRACKET|A_EXTRA,    '(',')',0,          '(', 0,                         A_F_BRACKET|A_EXTRA,    '(', ')', 0,
         ')',0,                          A_B_BRACKET|A_EXTRA,    '(',')',0,          ')', 0,                         A_B_BRACKET|A_EXTRA,    '(', ')', 0,
         '[',0,                          A_F_BRACKET|A_EXTRA,    '[',']',0,          '[', 0,                         A_F_BRACKET|A_EXTRA,    '[', ']', 0,
         ']',0,                          A_B_BRACKET|A_EXTRA,    '[',']',0,          ']', 0,                         A_B_BRACKET|A_EXTRA,    '[', ']', 0,
         ESC,CONTROL('F'),0,             A_F_BRACKET,          ESC, CONTROL('F'), 0,           A_F_BRACKET,
         ESC,CONTROL('B'),0,             A_B_BRACKET,          ESC, CONTROL('B'), 0,           A_B_BRACKET,
         'G',0,                          A_GOEND,          'G', 0,                         A_GOEND,
         ESC,'>',0,                      A_GOEND,          ESC, '>', 0,                    A_GOEND,
         '>',0,                          A_GOEND,          '>', 0,                         A_GOEND,
         SK(SK_END),0,                   A_GOEND,          SK(SK_END), 0,                  A_GOEND,
         'P',0,                          A_GOPOS,          'P', 0,                         A_GOPOS,
   
         '0',0,                          A_DIGIT,          '0', 0,                         A_DIGIT,
         '1',0,                          A_DIGIT,          '1', 0,                         A_DIGIT,
         '2',0,                          A_DIGIT,          '2', 0,                         A_DIGIT,
         '3',0,                          A_DIGIT,          '3', 0,                         A_DIGIT,
         '4',0,                          A_DIGIT,          '4', 0,                         A_DIGIT,
         '5',0,                          A_DIGIT,          '5', 0,                         A_DIGIT,
         '6',0,                          A_DIGIT,          '6', 0,                         A_DIGIT,
         '7',0,                          A_DIGIT,          '7', 0,                         A_DIGIT,
         '8',0,                          A_DIGIT,          '8', 0,                         A_DIGIT,
         '9',0,                          A_DIGIT,          '9', 0,                         A_DIGIT,
         '.',0,                          A_DIGIT,          '.', 0,                         A_DIGIT,
   
         '=',0,                          A_STAT,          '=', 0,                         A_STAT,
         CONTROL('G'),0,                 A_STAT,          CONTROL('G'), 0,                A_STAT,
         ':','f',0,                      A_STAT,          ':', 'f', 0,                    A_STAT,
         '/',0,                          A_F_SEARCH,          '/', 0,                         A_F_SEARCH,
         '?',0,                          A_B_SEARCH,          '?', 0,                         A_B_SEARCH,
         ESC,'/',0,                      A_F_SEARCH|A_EXTRA,     '*',0,          ESC, '/', 0,                    A_F_SEARCH|A_EXTRA,     '*', 0,
         ESC,'?',0,                      A_B_SEARCH|A_EXTRA,     '*',0,          ESC, '?', 0,                    A_B_SEARCH|A_EXTRA,     '*', 0,
         'n',0,                          A_AGAIN_SEARCH,          'n', 0,                         A_AGAIN_SEARCH,
         ESC,'n',0,                      A_T_AGAIN_SEARCH,          ESC, 'n', 0,                    A_T_AGAIN_SEARCH,
         'N',0,                          A_REVERSE_SEARCH,          'N', 0,                         A_REVERSE_SEARCH,
         ESC,'N',0,                      A_T_REVERSE_SEARCH,          ESC, 'N', 0,                    A_T_REVERSE_SEARCH,
         '&',0,                          A_FILTER,          '&', 0,                         A_FILTER,
         'm',0,                          A_SETMARK,          'm', 0,                         A_SETMARK,
         '\'',0,                         A_GOMARK,          '\'', 0,                        A_GOMARK,
         CONTROL('X'),CONTROL('X'),0,    A_GOMARK,          CONTROL('X'), CONTROL('X'), 0,  A_GOMARK,
         'E',0,                          A_EXAMINE,          'E', 0,                         A_EXAMINE,
         ':','e',0,                      A_EXAMINE,          ':', 'e', 0,                    A_EXAMINE,
         CONTROL('X'),CONTROL('V'),0,    A_EXAMINE,          CONTROL('X'), CONTROL('V'), 0,  A_EXAMINE,
         ':','n',0,                      A_NEXT_FILE,          ':', 'n', 0,                    A_NEXT_FILE,
         ':','p',0,                      A_PREV_FILE,          ':', 'p', 0,                    A_PREV_FILE,
         't',0,                          A_NEXT_TAG,          't', 0,                         A_NEXT_TAG,
         'T',0,                          A_PREV_TAG,          'T', 0,                         A_PREV_TAG,
         ':','x',0,                      A_INDEX_FILE,          ':', 'x', 0,                    A_INDEX_FILE,
         ':','d',0,                      A_REMOVE_FILE,          ':', 'd', 0,                    A_REMOVE_FILE,
         '-',0,                          A_OPT_TOGGLE,          ':', 't', 0,                    A_OPT_TOGGLE|A_EXTRA,   't', 0,
         ':','t',0,                      A_OPT_TOGGLE|A_EXTRA,   't',0,          '|', 0,                         A_PIPE,
         's',0,                          A_OPT_TOGGLE|A_EXTRA,   'o',0,          'v', 0,                         A_VISUAL,
         '_',0,                          A_DISP_OPTION,          '!', 0,                         A_SHELL,
         '|',0,                          A_PIPE,          '+', 0,                         A_FIRSTCMD,
         'v',0,                          A_VISUAL,  
         '!',0,                          A_SHELL,  
         '+',0,                          A_FIRSTCMD,  
   
         'H',0,                          A_HELP,          'H', 0,                         A_HELP,
         'h',0,                          A_HELP,          'h', 0,                         A_HELP,
         SK(SK_F1),0,                    A_HELP,          SK(SK_F1), 0,                   A_HELP,
         'V',0,                          A_VERSION,          'V', 0,                         A_VERSION,
         'q',0,                          A_QUIT,          'q', 0,                         A_QUIT,
         'Q',0,                          A_QUIT,          'Q', 0,                         A_QUIT,
         ':','q',0,                      A_QUIT,          ':', 'q', 0,                    A_QUIT,
         ':','Q',0,                      A_QUIT,          ':', 'Q', 0,                    A_QUIT,
         'Z','Z',0,                      A_QUIT          'Z', 'Z', 0,                    A_QUIT
 };  };
   
   static unsigned char lesstable[] = {
           '-', 0,                         A_OPT_TOGGLE,
           's', 0,                         A_OPT_TOGGLE|A_EXTRA,   'o', 0,
           '_', 0,                         A_DISP_OPTION
   };
   
   static unsigned char moretable[] = {
           's', 0,                         A_F_SKIP
   };
   
 static unsigned char edittable[] =  static unsigned char edittable[] =
 {  {
         '\t',0,                         EC_F_COMPLETE,  /* TAB */          '\t', 0,                        EC_F_COMPLETE,  /* TAB */
         '\17',0,                        EC_B_COMPLETE,  /* BACKTAB */          '\17', 0,                       EC_B_COMPLETE,  /* BACKTAB */
         SK(SK_BACKTAB),0,               EC_B_COMPLETE,  /* BACKTAB */          SK(SK_BACKTAB), 0,              EC_B_COMPLETE,  /* BACKTAB */
         ESC,'\t',0,                     EC_B_COMPLETE,  /* ESC TAB */          ESC, '\t', 0,                   EC_B_COMPLETE,  /* ESC TAB */
         CONTROL('L'),0,                 EC_EXPAND,      /* CTRL-L */          CONTROL('L'), 0,                EC_EXPAND,      /* CTRL-L */
         CONTROL('V'),0,                 EC_LITERAL,     /* BACKSLASH */          CONTROL('V'), 0,                EC_LITERAL,     /* BACKSLASH */
         CONTROL('A'),0,                 EC_LITERAL,     /* BACKSLASH */          CONTROL('A'), 0,                EC_LITERAL,     /* BACKSLASH */
         ESC,'l',0,                      EC_RIGHT,       /* ESC l */          ESC, 'l', 0,                    EC_RIGHT,       /* ESC l */
         SK(SK_RIGHT_ARROW),0,           EC_RIGHT,       /* RIGHTARROW */          SK(SK_RIGHT_ARROW), 0,          EC_RIGHT,       /* RIGHTARROW */
         ESC,'h',0,                      EC_LEFT,        /* ESC h */          ESC, 'h', 0,                    EC_LEFT,        /* ESC h */
         SK(SK_LEFT_ARROW),0,            EC_LEFT,        /* LEFTARROW */          SK(SK_LEFT_ARROW), 0,           EC_LEFT,        /* LEFTARROW */
         ESC,'b',0,                      EC_W_LEFT,      /* ESC b */          ESC, 'b', 0,                    EC_W_LEFT,      /* ESC b */
         ESC,SK(SK_LEFT_ARROW),0,        EC_W_LEFT,      /* ESC LEFTARROW */          ESC, SK(SK_LEFT_ARROW), 0,      EC_W_LEFT,      /* ESC LEFTARROW */
         SK(SK_CTL_LEFT_ARROW),0,        EC_W_LEFT,      /* CTRL-LEFTARROW */          SK(SK_CTL_LEFT_ARROW), 0,       EC_W_LEFT,      /* CTRL-LEFTARROW */
         ESC,'w',0,                      EC_W_RIGHT,     /* ESC w */          ESC, 'w', 0,                    EC_W_RIGHT,     /* ESC w */
         ESC,SK(SK_RIGHT_ARROW),0,       EC_W_RIGHT,     /* ESC RIGHTARROW */          ESC, SK(SK_RIGHT_ARROW), 0,     EC_W_RIGHT,     /* ESC RIGHTARROW */
         SK(SK_CTL_RIGHT_ARROW),0,       EC_W_RIGHT,     /* CTRL-RIGHTARROW */          SK(SK_CTL_RIGHT_ARROW), 0,      EC_W_RIGHT,     /* CTRL-RIGHTARROW */
         ESC,'i',0,                      EC_INSERT,      /* ESC i */          ESC, 'i', 0,                    EC_INSERT,      /* ESC i */
         SK(SK_INSERT),0,                EC_INSERT,      /* INSERT */          SK(SK_INSERT), 0,               EC_INSERT,      /* INSERT */
         ESC,'x',0,                      EC_DELETE,      /* ESC x */          ESC, 'x', 0,                    EC_DELETE,      /* ESC x */
         SK(SK_DELETE),0,                EC_DELETE,      /* DELETE */          SK(SK_DELETE), 0,               EC_DELETE,      /* DELETE */
         ESC,'X',0,                      EC_W_DELETE,    /* ESC X */          ESC, 'X', 0,                    EC_W_DELETE,    /* ESC X */
         ESC,SK(SK_DELETE),0,            EC_W_DELETE,    /* ESC DELETE */          ESC, SK(SK_DELETE), 0,          EC_W_DELETE,    /* ESC DELETE */
         SK(SK_CTL_DELETE),0,            EC_W_DELETE,    /* CTRL-DELETE */          SK(SK_CTL_DELETE), 0,           EC_W_DELETE,    /* CTRL-DELETE */
         SK(SK_CTL_BACKSPACE),0,         EC_W_BACKSPACE, /* CTRL-BACKSPACE */          SK(SK_CTL_BACKSPACE), 0,        EC_W_BACKSPACE, /* CTRL-BACKSPACE */
         ESC,'\b',0,                     EC_W_BACKSPACE, /* ESC BACKSPACE */          ESC, '\b', 0,                   EC_W_BACKSPACE, /* ESC BACKSPACE */
         ESC,'0',0,                      EC_HOME,        /* ESC 0 */          ESC, '0', 0,                    EC_HOME,        /* ESC 0 */
         SK(SK_HOME),0,                  EC_HOME,        /* HOME */          SK(SK_HOME), 0,                 EC_HOME,        /* HOME */
         ESC,'$',0,                      EC_END,         /* ESC $ */          ESC, '$', 0,                    EC_END,         /* ESC $ */
         SK(SK_END),0,                   EC_END,         /* END */          SK(SK_END), 0,                  EC_END,         /* END */
         ESC,'k',0,                      EC_UP,          /* ESC k */          ESC, 'k', 0,                    EC_UP,          /* ESC k */
         SK(SK_UP_ARROW),0,              EC_UP,          /* UPARROW */          SK(SK_UP_ARROW), 0,             EC_UP,          /* UPARROW */
         ESC,'j',0,                      EC_DOWN,        /* ESC j */          ESC, 'j', 0,                    EC_DOWN,        /* ESC j */
         SK(SK_DOWN_ARROW),0,            EC_DOWN,        /* DOWNARROW */          SK(SK_DOWN_ARROW), 0,           EC_DOWN,        /* DOWNARROW */
         CONTROL('G'),0,                 EC_ABORT,       /* CTRL-G */          CONTROL('G'), 0,                EC_ABORT,       /* CTRL-G */
 };  };
   
 /*  /*
Line 227 
Line 237 
 /*  /*
  * Expand special key abbreviations in a command table.   * Expand special key abbreviations in a command table.
  */   */
         static void  static void
 expand_special_keys(table, len)  expand_special_keys(char *table, int len)
         char *table;  
         int len;  
 {  {
         register char *fm;          char *fm;
         register char *to;          char *to;
         register int a;          int a;
         char *repl;          char *repl;
         int klen;          int klen;
   
         for (fm = table;  fm < table + len; )          for (fm = table;  fm < table + len; ) {
         {  
                 /*                  /*
                  * Rewrite each command in the table with any                   * Rewrite each command in the table with any
                  * special key abbreviations expanded.                   * special key abbreviations expanded.
                  */                   */
                 for (to = fm;  *fm != '\0'; )                  for (to = fm;  *fm != '\0'; ) {
                 {                          if (*fm != SK_SPECIAL_KEY) {
                         if (*fm != SK_SPECIAL_KEY)  
                         {  
                                 *to++ = *fm++;                                  *to++ = *fm++;
                                 continue;                                  continue;
                         }                          }
Line 263 
Line 268 
                         repl = special_key_str(fm[1]);                          repl = special_key_str(fm[1]);
                         klen = fm[2] & 0377;                          klen = fm[2] & 0377;
                         fm += klen;                          fm += klen;
                         if (repl == NULL || (int) strlen(repl) > klen)                          if (repl == NULL || strlen(repl) > klen)
                                 repl = "\377";                                  repl = "\377";
                         while (*repl != '\0')                          while (*repl != '\0')
                                 *to++ = *repl++;                                  *to++ = *repl++;
                 }                  }
                 *to++ = '\0';                  *to++ = '\0';
                 /*                  /*
                  * Fill any unused bytes between end of command and                   * Fill any unused bytes between end of command and
                  * the action byte with A_SKIP.                   * the action byte with A_SKIP.
                  */                   */
                 while (to <= fm)                  while (to <= fm)
                         *to++ = A_SKIP;                          *to++ = A_SKIP;
                 fm++;                  fm++;
                 a = *fm++ & 0377;                  a = *fm++ & 0377;
                 if (a & A_EXTRA)                  if (a & A_EXTRA) {
                 {  
                         while (*fm++ != '\0')                          while (*fm++ != '\0')
                                 continue;                                  continue;
                 }                  }
Line 288 
Line 292 
 /*  /*
  * Initialize the command lists.   * Initialize the command lists.
  */   */
         public void  void
 init_cmds()  init_cmds(void)
 {  {
         /*          /*
          * Add the default command tables.           * Add the default command tables.
          */           */
         add_fcmd_table((char*)cmdtable, sizeof(cmdtable));          add_fcmd_table((char *)cmdtable, sizeof (cmdtable));
         add_ecmd_table((char*)edittable, sizeof(edittable));          add_ecmd_table((char *)edittable, sizeof (edittable));
 #if USERFILE          if (less_is_more) {
                   add_fcmd_table((char *)moretable, sizeof (moretable));
                   return;
           } else {
                   add_fcmd_table((char *)lesstable, sizeof (lesstable));
           }
   
         /*          /*
          * For backwards compatibility,  
          * try to add tables in the OLD system lesskey file.  
          */  
 #ifdef BINDIR  
         add_hometable(NULL, BINDIR "/.sysless", 1);  
 #endif  
         /*  
          * Try to add the tables in the system lesskey file.           * Try to add the tables in the system lesskey file.
          */           */
         add_hometable("LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);          add_hometable("LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);
Line 312 
Line 315 
          * Try to add the tables in the standard lesskey file "$HOME/.less".           * Try to add the tables in the standard lesskey file "$HOME/.less".
          */           */
         add_hometable("LESSKEY", LESSKEYFILE, 0);          add_hometable("LESSKEY", LESSKEYFILE, 0);
 #endif  
 }  }
   
 /*  /*
  * Add a command table.   * Add a command table.
  */   */
         static int  static int
 add_cmd_table(tlist, buf, len)  add_cmd_table(struct tablelist **tlist, char *buf, int len)
         struct tablelist **tlist;  
         char *buf;  
         int len;  
 {  {
         register struct tablelist *t;          struct tablelist *t;
   
         if (len == 0)          if (len == 0)
                 return (0);                  return (0);
         /*          /*
          * Allocate a tablelist structure, initialize it,           * Allocate a tablelist structure, initialize it,
          * and link it into the list of tables.           * and link it into the list of tables.
          */           */
         if ((t = (struct tablelist *)          if ((t = calloc(1, sizeof (struct tablelist))) == NULL) {
                         calloc(1, sizeof(struct tablelist))) == NULL)  
         {  
                 return (-1);                  return (-1);
         }          }
         expand_special_keys(buf, len);          expand_special_keys(buf, len);
Line 348 
Line 345 
 /*  /*
  * Add a command table.   * Add a command table.
  */   */
         public void  void
 add_fcmd_table(buf, len)  add_fcmd_table(char *buf, int len)
         char *buf;  
         int len;  
 {  {
         if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)          if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
                 error("Warning: some commands disabled", NULL_PARG);                  error("Warning: some commands disabled", NULL_PARG);
Line 360 
Line 355 
 /*  /*
  * Add an editing command table.   * Add an editing command table.
  */   */
         public void  void
 add_ecmd_table(buf, len)  add_ecmd_table(char *buf, int len)
         char *buf;  
         int len;  
 {  {
         if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)          if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
                 error("Warning: some edit commands disabled", NULL_PARG);                  error("Warning: some edit commands disabled", NULL_PARG);
Line 372 
Line 365 
 /*  /*
  * Add an environment variable table.   * Add an environment variable table.
  */   */
         static void  static void
 add_var_table(tlist, buf, len)  add_var_table(struct tablelist **tlist, char *buf, int len)
         struct tablelist **tlist;  
         char *buf;  
         int len;  
 {  {
         if (add_cmd_table(tlist, buf, len) < 0)          if (add_cmd_table(tlist, buf, len) < 0)
                 error("Warning: environment variables from lesskey file unavailable", NULL_PARG);                  error("Warning: environment variables from "
                       "lesskey file unavailable", NULL_PARG);
 }  }
   
 /*  /*
  * Search a single command table for the command string in cmd.   * Search a single command table for the command string in cmd.
  */   */
         static int  static int
 cmd_search(cmd, table, endtable, sp)  cmd_search(const char *cmd, char *table, char *endtable, char **sp)
         char *cmd;  
         char *table;  
         char *endtable;  
         char **sp;  
 {  {
         register char *p;          char *p;
         register char *q;          const char *q;
         register int a;          int a;
   
         *sp = NULL;          *sp = NULL;
         for (p = table, q = cmd;  p < endtable;  p++, q++)          for (p = table, q = cmd;  p < endtable;  p++, q++) {
         {                  if (*p == *q) {
                 if (*p == *q)  
                 {  
                         /*                          /*
                          * Current characters match.                           * Current characters match.
                          * If we're at the end of the string, we've found it.                           * If we're at the end of the string, we've found it.
Line 408 
Line 393 
                          * after the null at the end of the string                           * after the null at the end of the string
                          * in the command table.                           * in the command table.
                          */                           */
                         if (*p == '\0')                          if (*p == '\0') {
                         {  
                                 a = *++p & 0377;                                  a = *++p & 0377;
                                 while (a == A_SKIP)                                  while (a == A_SKIP)
                                         a = *++p & 0377;                                          a = *++p & 0377;
                                 if (a == A_END_LIST)                                  if (a == A_END_LIST) {
                                 {  
                                         /*                                          /*
                                          * We get here only if the original                                           * We get here only if the original
                                          * cmd string passed in was empty ("").                                           * cmd string passed in was empty ("").
Line 426 
Line 409 
                                 /*                                  /*
                                  * Check for an "extra" string.                                   * Check for an "extra" string.
                                  */                                   */
                                 if (a & A_EXTRA)                                  if (a & A_EXTRA) {
                                 {  
                                         *sp = ++p;                                          *sp = ++p;
                                         a &= ~A_EXTRA;                                          a &= ~A_EXTRA;
                                 }                                  }
                                 return (a);                                  return (a);
                         }                          }
                 } else if (*q == '\0')                  } else if (*q == '\0') {
                 {  
                         /*                          /*
                          * Hit the end of the user's command,                           * Hit the end of the user's command,
                          * but not the end of the string in the command table.                           * but not the end of the string in the command table.
                          * The user's command is incomplete.                           * The user's command is incomplete.
                          */                           */
                         return (A_PREFIX);                          return (A_PREFIX);
                 } else                  } else {
                 {  
                         /*                          /*
                          * Not a match.                           * Not a match.
                          * Skip ahead to the next command in the                           * Skip ahead to the next command in the
                          * command table, and reset the pointer                           * command table, and reset the pointer
                          * to the beginning of the user's command.                           * to the beginning of the user's command.
                          */                           */
                         if (*p == '\0' && p[1] == A_END_LIST)                          if (*p == '\0' && p[1] == A_END_LIST) {
                         {  
                                 /*                                  /*
                                  * A_END_LIST is a special marker that tells                                   * A_END_LIST is a special marker that tells
                                  * us to abort the cmd search.                                   * us to abort the cmd search.
                                  */                                   */
                                 return (A_UINVALID);                                  return (A_UINVALID);
Line 477 
Line 456 
  * Decode a command character and return the associated action.   * Decode a command character and return the associated action.
  * The "extra" string, if any, is returned in sp.   * The "extra" string, if any, is returned in sp.
  */   */
         static int  static int
 cmd_decode(tlist, cmd, sp)  cmd_decode(struct tablelist *tlist, const char *cmd, char **sp)
         struct tablelist *tlist;  
         char *cmd;  
         char **sp;  
 {  {
         register struct tablelist *t;          struct tablelist *t;
         register int action = A_INVALID;          int action = A_INVALID;
   
         /*          /*
          * Search thru all the command tables.           * Search thru all the command tables.
          * Stop when we find an action which is not A_INVALID.           * Stop when we find an action which is not A_INVALID.
          */           */
         for (t = tlist;  t != NULL;  t = t->t_next)          for (t = tlist;  t != NULL;  t = t->t_next) {
         {  
                 action = cmd_search(cmd, t->t_start, t->t_end, sp);                  action = cmd_search(cmd, t->t_start, t->t_end, sp);
                 if (action != A_INVALID)                  if (action != A_INVALID)
                         break;                          break;
Line 504 
Line 479 
 /*  /*
  * Decode a command from the cmdtables list.   * Decode a command from the cmdtables list.
  */   */
         public int  int
 fcmd_decode(cmd, sp)  fcmd_decode(const char *cmd, char **sp)
         char *cmd;  
         char **sp;  
 {  {
         return (cmd_decode(list_fcmd_tables, cmd, sp));          return (cmd_decode(list_fcmd_tables, cmd, sp));
 }  }
Line 515 
Line 488 
 /*  /*
  * Decode a command from the edittables list.   * Decode a command from the edittables list.
  */   */
         public int  int
 ecmd_decode(cmd, sp)  ecmd_decode(const char *cmd, char **sp)
         char *cmd;  
         char **sp;  
 {  {
         return (cmd_decode(list_ecmd_tables, cmd, sp));          return (cmd_decode(list_ecmd_tables, cmd, sp));
 }  }
Line 527 
Line 498 
  * Get the value of an environment variable.   * Get the value of an environment variable.
  * Looks first in the lesskey file, then in the real environment.   * Looks first in the lesskey file, then in the real environment.
  */   */
         public char *  char *
 lgetenv(var)  lgetenv(char *var)
         char *var;  
 {  {
         int a;          int a;
         char *s;          char *s;
   
           /*
            * Ignore lookups of any LESS* setting when we are more, and ignore
            * the less key files
            */
           if (less_is_more) {
                   if (strncmp(var, "LESS", 4) == 0) {
                           return (NULL);
                   }
                   return (getenv(var));
           }
         a = cmd_decode(list_var_tables, var, &s);          a = cmd_decode(list_var_tables, var, &s);
         if (a == EV_OK)          if (a == EV_OK)
                 return (s);                  return (s);
Line 546 
Line 526 
         return (NULL);          return (NULL);
 }  }
   
 #if USERFILE  
 /*  /*
  * Get an "integer" from a lesskey file.   * Get an "integer" from a lesskey file.
  * Integers are stored in a funny format:   * Integers are stored in a funny format:
  * two bytes, low order first, in radix KRADIX.   * two bytes, low order first, in radix KRADIX.
  */   */
         static int  static int
 gint(sp)  gint(char **sp)
         char **sp;  
 {  {
         int n;          int n;
   
Line 566 
Line 544 
 /*  /*
  * Process an old (pre-v241) lesskey file.   * Process an old (pre-v241) lesskey file.
  */   */
         static int  static int
 old_lesskey(buf, len)  old_lesskey(char *buf, int len)
         char *buf;  
         int len;  
 {  {
         /*          /*
          * Old-style lesskey file.           * Old-style lesskey file.
          * The file must end with either           * The file must end with either
          *     ...,cmd,0,action           *      ..,cmd,0,action
          * or  ...,cmd,0,action|A_EXTRA,string,0           * or   ...,cmd,0,action|A_EXTRA,string,0
          * So the last byte or the second to last byte must be zero.           * So the last byte or the second to last byte must be zero.
          */           */
         if (buf[len-1] != '\0' && buf[len-2] != '\0')          if (buf[len-1] != '\0' && buf[len-2] != '\0')
Line 584 
Line 560 
         return (0);          return (0);
 }  }
   
 /*  /*
  * Process a new (post-v241) lesskey file.   * Process a new (post-v241) lesskey file.
  */   */
         static int  static int
 new_lesskey(buf, len, sysvar)  new_lesskey(char *buf, int len, int sysvar)
         char *buf;  
         int len;  
         int sysvar;  
 {  {
         char *p;          char *p;
         register int c;          int c;
         register int n;          int n;
   
         /*          /*
          * New-style lesskey file.           * New-style lesskey file.
Line 606 
Line 579 
             buf[len-1] != C2_END_LESSKEY_MAGIC)              buf[len-1] != C2_END_LESSKEY_MAGIC)
                 return (-1);                  return (-1);
         p = buf + 4;          p = buf + 4;
         for (;;)          for (;;) {
         {  
                 c = *p++;                  c = *p++;
                 switch (c)                  switch (c) {
                 {  
                 case CMD_SECTION:                  case CMD_SECTION:
                         n = gint(&p);                          n = gint(&p);
                         add_fcmd_table(p, n);                          add_fcmd_table(p, n);
Line 623 
Line 594 
                         break;                          break;
                 case VAR_SECTION:                  case VAR_SECTION:
                         n = gint(&p);                          n = gint(&p);
                         add_var_table((sysvar) ?                          add_var_table((sysvar) ?
                                 &list_sysvar_tables : &list_var_tables, p, n);                              &list_sysvar_tables : &list_var_tables, p, n);
                         p += n;                          p += n;
                         break;                          break;
                 case END_SECTION:                  case END_SECTION:
Line 641 
Line 612 
 /*  /*
  * Set up a user command table, based on a "lesskey" file.   * Set up a user command table, based on a "lesskey" file.
  */   */
         public int  int
 lesskey(filename, sysvar)  lesskey(char *filename, int sysvar)
         char *filename;  
         int sysvar;  
 {  {
         register char *buf;          char *buf;
         register POSITION len;          off_t len;
         register long n;          long n;
         register int f;          int f;
   
         if (secure)          if (secure)
                 return (1);                  return (1);
Line 671 
Line 640 
          *    rely on the lesskey program to generate a good .less file. }}           *    rely on the lesskey program to generate a good .less file. }}
          */           */
         len = filesize(f);          len = filesize(f);
         if (len == NULL_POSITION || len < 3)          if (len == -1 || len < 3) {
         {  
                 /*                  /*
                  * Bad file (valid file must have at least 3 chars).                   * Bad file (valid file must have at least 3 chars).
                  */                   */
                 close(f);                  (void) close(f);
                 return (-1);                  return (-1);
         }          }
         if ((buf = (char *) calloc((int)len, sizeof(char))) == NULL)          if ((buf = calloc((int)len, sizeof (char))) == NULL) {
         {                  (void) close(f);
                 close(f);  
                 return (-1);                  return (-1);
         }          }
         if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK)          if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK) {
         {  
                 free(buf);                  free(buf);
                 close(f);                  (void) close(f);
                 return (-1);                  return (-1);
         }          }
         n = read(f, buf, (unsigned int) len);          n = read(f, buf, (unsigned int) len);
         close(f);          close(f);
         if (n != len)          if (n != len) {
         {  
                 free(buf);                  free(buf);
                 return (-1);                  return (-1);
         }          }
Line 711 
Line 676 
 /*  /*
  * Add the standard lesskey file "$HOME/.less"   * Add the standard lesskey file "$HOME/.less"
  */   */
         public void  void
 add_hometable(envname, def_filename, sysvar)  add_hometable(char *envname, char *def_filename, int sysvar)
         char *envname;  
         char *def_filename;  
         int sysvar;  
 {  {
         char *filename;          char *filename;
         PARG parg;          PARG parg;
Line 728 
Line 690 
                 filename = homefile(def_filename);                  filename = homefile(def_filename);
         if (filename == NULL)          if (filename == NULL)
                 return;                  return;
         if (lesskey(filename, sysvar) < 0)          if (lesskey(filename, sysvar) < 0) {
         {  
                 parg.p_string = filename;                  parg.p_string = filename;
                 error("Cannot use lesskey file \"%s\"", &parg);                  error("Cannot use lesskey file \"%s\"", &parg);
         }          }
         free(filename);          free(filename);
 }  }
 #endif  
   
 /*  /*
  * See if a char is a special line-editing command.   * See if a char is a special line-editing command.
  */   */
         public int  int
 editchar(c, flags)  editchar(int c, int flags)
         int c;  
         int flags;  
 {  {
         int action;          int action;
         int nch;          int nch;
         char *s;          char *s;
         char usercmd[MAX_CMDLEN+1];          char usercmd[MAX_CMDLEN+1];
   
         /*          /*
          * An editing character could actually be a sequence of characters;           * An editing character could actually be a sequence of characters;
          * for example, an escape sequence sent by pressing the uparrow key.           * for example, an escape sequence sent by pressing the uparrow key.
Line 761 
Line 719 
                 return (EC_BACKSPACE);                  return (EC_BACKSPACE);
         if (c == kill_char)          if (c == kill_char)
                 return (EC_LINEKILL);                  return (EC_LINEKILL);
   
         /*          /*
          * Collect characters in a buffer.           * Collect characters in a buffer.
          * Start with the one we have, and get more if we need them.           * Start with the one we have, and get more if we need them.
          */           */
         nch = 0;          nch = 0;
         do {          do {
                 if (nch > 0)                  if (nch > 0)
                         c = getcc();                          c = getcc();
                 usercmd[nch] = c;                  usercmd[nch] = (char)c;
                 usercmd[nch+1] = '\0';                  usercmd[nch+1] = '\0';
                 nch++;                  nch++;
                 action = ecmd_decode(usercmd, &s);                  action = ecmd_decode(usercmd, &s);
         } while (action == A_PREFIX);          } while (action == A_PREFIX);
   
         if (flags & EC_NORIGHTLEFT)          if (flags & EC_NORIGHTLEFT) {
         {                  switch (action) {
                 switch (action)  
                 {  
                 case EC_RIGHT:                  case EC_RIGHT:
                 case EC_LEFT:                  case EC_LEFT:
                         action = A_INVALID;                          action = A_INVALID;
                         break;                          break;
                 }                  }
         }          }
 #if CMD_HISTORY          if (flags & EC_NOHISTORY) {
         if (flags & EC_NOHISTORY)  
         {  
                 /*                  /*
                  * The caller says there is no history list.                   * The caller says there is no history list.
                  * Reject any history-manipulation action.                   * Reject any history-manipulation action.
                  */                   */
                 switch (action)                  switch (action) {
                 {  
                 case EC_UP:                  case EC_UP:
                 case EC_DOWN:                  case EC_DOWN:
                         action = A_INVALID;                          action = A_INVALID;
                         break;                          break;
                 }                  }
         }          }
 #endif          if (flags & EC_NOCOMPLETE) {
 #if TAB_COMPLETE_FILENAME  
         if (flags & EC_NOCOMPLETE)  
         {  
                 /*                  /*
                  * The caller says we don't want any filename completion cmds.                   * The caller says we don't want any filename completion cmds.
                  * Reject them.                   * Reject them.
                  */                   */
                 switch (action)                  switch (action) {
                 {  
                 case EC_F_COMPLETE:                  case EC_F_COMPLETE:
                 case EC_B_COMPLETE:                  case EC_B_COMPLETE:
                 case EC_EXPAND:                  case EC_EXPAND:
Line 818 
Line 767 
                         break;                          break;
                 }                  }
         }          }
 #endif          if ((flags & EC_PEEK) || action == A_INVALID) {
         if ((flags & EC_PEEK) || action == A_INVALID)  
         {  
                 /*                  /*
                  * We're just peeking, or we didn't understand the command.                   * We're just peeking, or we didn't understand the command.
                  * Unget all the characters we read in the loop above.                   * Unget all the characters we read in the loop above.
                  * This does NOT include the original character that was                   * This does NOT include the original character that was
                  * passed in as a parameter.                   * passed in as a parameter.
                  */                   */
                 while (nch > 1)                  while (nch > 1) {
                 {  
                         ungetcc(usercmd[--nch]);                          ungetcc(usercmd[--nch]);
                 }                  }
         } else          } else {
         {  
                 if (s != NULL)                  if (s != NULL)
                         ungetsc(s);                          ungetsc(s);
         }          }
         return action;          return (action);
 }  }
   

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8