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

Diff for /src/usr.bin/less/cmdbuf.c between version 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2003/04/13 18:21:21 version 1.1.1.3, 2011/09/16 17:47:01
Line 1 
Line 1 
 /*  /*
  * Copyright (C) 1984-2002  Mark Nudelman   * Copyright (C) 1984-2011  Mark Nudelman
  *   *
  * You may distribute under the terms of either the GNU General Public   * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.   * License or the Less License, as specified in the README file.
Line 16 
Line 16 
   
 #include "less.h"  #include "less.h"
 #include "cmd.h"  #include "cmd.h"
   #include "charset.h"
   #if HAVE_STAT
   #include <sys/stat.h>
   #endif
   
 extern int sc_width;  extern int sc_width;
   extern int utf_mode;
   
 static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */  static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
 static int cmd_col;             /* Current column of the cursor */  static int cmd_col;             /* Current column of the cursor */
Line 48 
Line 53 
 #endif  #endif
   
 #if CMD_HISTORY  #if CMD_HISTORY
   
   /* History file */
   #define HISTFILE_FIRST_LINE      ".less-history-file:"
   #define HISTFILE_SEARCH_SECTION  ".search"
   #define HISTFILE_SHELL_SECTION   ".shell"
   
 /*  /*
  * A mlist structure represents a command history.   * A mlist structure represents a command history.
  */   */
Line 57 
Line 68 
         struct mlist *prev;          struct mlist *prev;
         struct mlist *curr_mp;          struct mlist *curr_mp;
         char *string;          char *string;
           int modified;
 };  };
   
 /*  /*
  * These are the various command histories that exist.   * These are the various command histories that exist.
  */   */
 struct mlist mlist_search =  struct mlist mlist_search =
         { &mlist_search,  &mlist_search,  &mlist_search,  NULL };          { &mlist_search,  &mlist_search,  &mlist_search,  NULL, 0 };
 public void * constant ml_search = (void *) &mlist_search;  public void * constant ml_search = (void *) &mlist_search;
   
 struct mlist mlist_examine =  struct mlist mlist_examine =
         { &mlist_examine, &mlist_examine, &mlist_examine, NULL };          { &mlist_examine, &mlist_examine, &mlist_examine, NULL, 0 };
 public void * constant ml_examine = (void *) &mlist_examine;  public void * constant ml_examine = (void *) &mlist_examine;
   
 #if SHELL_ESCAPE || PIPEC  #if SHELL_ESCAPE || PIPEC
 struct mlist mlist_shell =  struct mlist mlist_shell =
         { &mlist_shell,   &mlist_shell,   &mlist_shell,   NULL };          { &mlist_shell,   &mlist_shell,   &mlist_shell,   NULL, 0 };
 public void * constant ml_shell = (void *) &mlist_shell;  public void * constant ml_shell = (void *) &mlist_shell;
 #endif  #endif
   
Line 93 
Line 105 
 static struct mlist *curr_mlist = NULL;  static struct mlist *curr_mlist = NULL;
 static int curr_cmdflags;  static int curr_cmdflags;
   
   static char cmd_mbc_buf[MAX_UTF_CHAR_LEN];
   static int cmd_mbc_buf_len;
   static int cmd_mbc_buf_index;
   
   
 /*  /*
  * Reset command buffer (to empty).   * Reset command buffer (to empty).
  */   */
Line 105 
Line 121 
         cmd_col = 0;          cmd_col = 0;
         cmd_offset = 0;          cmd_offset = 0;
         literal = 0;          literal = 0;
           cmd_mbc_buf_len = 0;
 }  }
   
 /*  /*
  * Clear command line on display.   * Clear command line.
  */   */
         public void          public void
 clear_cmd()  clear_cmd()
 {  {
         clear_bot();  
         cmd_col = prompt_col = 0;          cmd_col = prompt_col = 0;
           cmd_mbc_buf_len = 0;
 }  }
   
 /*  /*
Line 124 
Line 141 
 cmd_putstr(s)  cmd_putstr(s)
         char *s;          char *s;
 {  {
         putstr(s);          LWCHAR prev_ch = 0;
         cmd_col += strlen(s);          LWCHAR ch;
         prompt_col += strlen(s);          char *endline = s + strlen(s);
           while (*s != '\0')
           {
                   char *ns = s;
                   ch = step_char(&ns, +1, endline);
                   while (s < ns)
                           putchr(*s++);
                   if (!utf_mode)
                   {
                           cmd_col++;
                           prompt_col++;
                   } else if (!is_composing_char(ch) &&
                              !is_combining_char(prev_ch, ch))
                   {
                           int width = is_wide_char(ch) ? 2 : 1;
                           cmd_col += width;
                           prompt_col += width;
                   }
                   prev_ch = ch;
           }
 }  }
   
 /*  /*
Line 135 
Line 171 
         public int          public int
 len_cmdbuf()  len_cmdbuf()
 {  {
         return (strlen(cmdbuf));          char *s = cmdbuf;
           char *endline = s + strlen(s);
           int len = 0;
   
           while (*s != '\0')
           {
                   step_char(&s, +1, endline);
                   len++;
           }
           return (len);
 }  }
   
 /*  /*
    * Common part of cmd_step_right() and cmd_step_left().
    */
           static char *
   cmd_step_common(p, ch, len, pwidth, bswidth)
           char *p;
           LWCHAR ch;
           int len;
           int *pwidth;
           int *bswidth;
   {
           char *pr;
   
           if (len == 1)
           {
                   pr = prchar((int) ch);
                   if (pwidth != NULL || bswidth != NULL)
                   {
                           int len = strlen(pr);
                           if (pwidth != NULL)
                                   *pwidth = len;
                           if (bswidth != NULL)
                                   *bswidth = len;
                   }
           } else
           {
                   pr = prutfchar(ch);
                   if (pwidth != NULL || bswidth != NULL)
                   {
                           if (is_composing_char(ch))
                           {
                                   if (pwidth != NULL)
                                           *pwidth = 0;
                                   if (bswidth != NULL)
                                           *bswidth = 0;
                           } else if (is_ubin_char(ch))
                           {
                                   int len = strlen(pr);
                                   if (pwidth != NULL)
                                           *pwidth = len;
                                   if (bswidth != NULL)
                                           *bswidth = len;
                           } else
                           {
                                   LWCHAR prev_ch = step_char(&p, -1, cmdbuf);
                                   if (is_combining_char(prev_ch, ch))
                                   {
                                           if (pwidth != NULL)
                                                   *pwidth = 0;
                                           if (bswidth != NULL)
                                                   *bswidth = 0;
                                   } else
                                   {
                                           if (pwidth != NULL)
                                                   *pwidth = is_wide_char(ch)
                                                           ?       2
                                                           :       1;
                                           if (bswidth != NULL)
                                                   *bswidth = 1;
                                   }
                           }
                   }
           }
   
           return (pr);
   }
   
   /*
    * Step a pointer one character right in the command buffer.
    */
           static char *
   cmd_step_right(pp, pwidth, bswidth)
           char **pp;
           int *pwidth;
           int *bswidth;
   {
           char *p = *pp;
           LWCHAR ch = step_char(pp, +1, p + strlen(p));
   
           return cmd_step_common(p, ch, *pp - p, pwidth, bswidth);
   }
   
   /*
    * Step a pointer one character left in the command buffer.
    */
           static char *
   cmd_step_left(pp, pwidth, bswidth)
           char **pp;
           int *pwidth;
           int *bswidth;
   {
           char *p = *pp;
           LWCHAR ch = step_char(pp, -1, cmdbuf);
   
           return cmd_step_common(*pp, ch, p - *pp, pwidth, bswidth);
   }
   
   /*
  * Repaint the line from cp onwards.   * Repaint the line from cp onwards.
  * Then position the cursor just after the char old_cp (a pointer into cmdbuf).   * Then position the cursor just after the char old_cp (a pointer into cmdbuf).
  */   */
Line 146 
Line 288 
 cmd_repaint(old_cp)  cmd_repaint(old_cp)
         char *old_cp;          char *old_cp;
 {  {
         char *p;  
   
         /*          /*
          * Repaint the line from the current position.           * Repaint the line from the current position.
          */           */
         clear_eol();          clear_eol();
         for ( ;  *cp != '\0';  cp++)          while (*cp != '\0')
         {          {
                 p = prchar(*cp);                  char *np = cp;
                 if (cmd_col + (int)strlen(p) >= sc_width)                  int width;
                   char *pr = cmd_step_right(&np, &width, NULL);
                   if (cmd_col + width >= sc_width)
                         break;                          break;
                 putstr(p);                  cp = np;
                 cmd_col += strlen(p);                  putstr(pr);
                   cmd_col += width;
         }          }
           while (*cp != '\0')
           {
                   char *np = cp;
                   int width;
                   char *pr = cmd_step_right(&np, &width, NULL);
                   if (width > 0)
                           break;
                   cp = np;
                   putstr(pr);
           }
   
         /*          /*
          * Back up the cursor to the correct position.           * Back up the cursor to the correct position.
Line 177 
Line 330 
 {  {
         while (cmd_col > prompt_col)          while (cmd_col > prompt_col)
         {          {
                 putbs();                  int width, bswidth;
                 cmd_col--;  
                   cmd_step_left(&cp, &width, &bswidth);
                   while (bswidth-- > 0)
                           putbs();
                   cmd_col -= width;
         }          }
   
         cp = &cmdbuf[cmd_offset];          cp = &cmdbuf[cmd_offset];
Line 201 
Line 358 
         s = cmdbuf + cmd_offset;          s = cmdbuf + cmd_offset;
         cols = 0;          cols = 0;
         while (cols < (sc_width - prompt_col) / 2 && *s != '\0')          while (cols < (sc_width - prompt_col) / 2 && *s != '\0')
                 cols += strlen(prchar(*s++));          {
                   int width;
                   cmd_step_right(&s, &width, NULL);
                   cols += width;
           }
           while (*s != '\0')
           {
                   int width;
                   char *ns = s;
                   cmd_step_right(&ns, &width, NULL);
                   if (width > 0)
                           break;
                   s = ns;
           }
   
         cmd_offset = s - cmdbuf;          cmd_offset = s - cmdbuf;
         save_cp = cp;          save_cp = cp;
Line 216 
Line 386 
 cmd_rshift()  cmd_rshift()
 {  {
         char *s;          char *s;
         char *p;  
         char *save_cp;          char *save_cp;
         int cols;          int cols;
   
Line 229 
Line 398 
         cols = 0;          cols = 0;
         while (cols < (sc_width - prompt_col) / 2 && s > cmdbuf)          while (cols < (sc_width - prompt_col) / 2 && s > cmdbuf)
         {          {
                 p = prchar(*--s);                  int width;
                 cols += strlen(p);                  cmd_step_left(&s, &width, NULL);
                   cols += width;
         }          }
   
         cmd_offset = s - cmdbuf;          cmd_offset = s - cmdbuf;
Line 245 
Line 415 
         static int          static int
 cmd_right()  cmd_right()
 {  {
         char *p;          char *pr;
           char *ncp;
           int width;
   
         if (*cp == '\0')          if (*cp == '\0')
         {          {
                 /*                  /* Already at the end of the line. */
                  * Already at the end of the line.  
                  */  
                 return (CC_OK);                  return (CC_OK);
         }          }
         p = prchar(*cp);          ncp = cp;
         if (cmd_col + (int)strlen(p) >= sc_width)          pr = cmd_step_right(&ncp, &width, NULL);
           if (cmd_col + width >= sc_width)
                 cmd_lshift();                  cmd_lshift();
         else if (cmd_col + (int)strlen(p) == sc_width - 1 && cp[1] != '\0')          else if (cmd_col + width == sc_width - 1 && cp[1] != '\0')
                 cmd_lshift();                  cmd_lshift();
         cp++;          cp = ncp;
         putstr(p);          cmd_col += width;
         cmd_col += strlen(p);          putstr(pr);
           while (*cp != '\0')
           {
                   pr = cmd_step_right(&ncp, &width, NULL);
                   if (width > 0)
                           break;
                   putstr(pr);
                   cp = ncp;
           }
         return (CC_OK);          return (CC_OK);
 }  }
   
Line 271 
Line 450 
         static int          static int
 cmd_left()  cmd_left()
 {  {
         char *p;          char *ncp;
           int width, bswidth;
   
         if (cp <= cmdbuf)          if (cp <= cmdbuf)
         {          {
                 /* Already at the beginning of the line */                  /* Already at the beginning of the line */
                 return (CC_OK);                  return (CC_OK);
         }          }
         p = prchar(cp[-1]);          ncp = cp;
         if (cmd_col < prompt_col + (int)strlen(p))          while (ncp > cmdbuf)
           {
                   cmd_step_left(&ncp, &width, &bswidth);
                   if (width > 0)
                           break;
           }
           if (cmd_col < prompt_col + width)
                 cmd_rshift();                  cmd_rshift();
         cp--;          cp = ncp;
         cmd_col -= strlen(p);          cmd_col -= width;
         while (*p++ != '\0')          while (bswidth-- > 0)
                 putbs();                  putbs();
         return (CC_OK);          return (CC_OK);
 }  }
Line 292 
Line 478 
  * Insert a char into the command buffer, at the current position.   * Insert a char into the command buffer, at the current position.
  */   */
         static int          static int
 cmd_ichar(c)  cmd_ichar(cs, clen)
         int c;          char *cs;
           int clen;
 {  {
         char *s;          char *s;
   
         if (strlen(cmdbuf) >= sizeof(cmdbuf)-2)          if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
         {          {
                 /*                  /* No room in the command buffer for another char. */
                  * No room in the command buffer for another char.  
                  */  
                 bell();                  bell();
                 return (CC_ERROR);                  return (CC_ERROR);
         }          }
   
         /*          /*
          * Insert the character into the buffer.           * Make room for the new character (shift the tail of the buffer right).
          */           */
         for (s = &cmdbuf[strlen(cmdbuf)];  s >= cp;  s--)          for (s = &cmdbuf[strlen(cmdbuf)];  s >= cp;  s--)
                 s[1] = s[0];                  s[clen] = s[0];
         *cp = c;  
         /*          /*
            * Insert the character into the buffer.
            */
           for (s = cp;  s < cp + clen;  s++)
                   *s = *cs++;
           /*
          * Reprint the tail of the line from the inserted char.           * Reprint the tail of the line from the inserted char.
          */           */
         cmd_repaint(cp);          cmd_repaint(cp);
Line 328 
Line 517 
 cmd_erase()  cmd_erase()
 {  {
         register char *s;          register char *s;
           int clen;
   
         if (cp == cmdbuf)          if (cp == cmdbuf)
         {          {
Line 340 
Line 530 
         /*          /*
          * Move cursor left (to the char being erased).           * Move cursor left (to the char being erased).
          */           */
           s = cp;
         cmd_left();          cmd_left();
           clen = s - cp;
   
         /*          /*
          * Remove the char from the buffer (shift the buffer left).           * Remove the char from the buffer (shift the buffer left).
          */           */
         for (s = cp;  *s != '\0';  s++)          for (s = cp;  ;  s++)
                 s[0] = s[1];          {
                   s[0] = s[clen];
                   if (s[0] == '\0')
                           break;
           }
   
         /*          /*
          * Repaint the buffer after the erased char.           * Repaint the buffer after the erased char.
          */           */
Line 368 
Line 566 
 {  {
         if (*cp == '\0')          if (*cp == '\0')
         {          {
                 /*                  /* At end of string; there is no char under the cursor. */
                  * At end of string; there is no char under the cursor.  
                  */  
                 return (CC_OK);                  return (CC_OK);
         }          }
         /*          /*
Line 441 
Line 637 
 {  {
         if (cmdbuf[0] == '\0')          if (cmdbuf[0] == '\0')
         {          {
                 /*                  /* Buffer is already empty; abort the current command. */
                  * Buffer is already empty; abort the current command.  
                  */  
                 return (CC_QUIT);                  return (CC_QUIT);
         }          }
         cmd_offset = 0;          cmd_offset = 0;
Line 468 
Line 662 
         void *mlist;          void *mlist;
         int cmdflags;          int cmdflags;
 {  {
   #if CMD_HISTORY
         curr_mlist = (struct mlist *) mlist;          curr_mlist = (struct mlist *) mlist;
         curr_cmdflags = cmdflags;          curr_cmdflags = cmdflags;
   
           /* Make sure the next up-arrow moves to the last string in the mlist. */
           if (curr_mlist != NULL)
                   curr_mlist->curr_mp = curr_mlist;
   #endif
 }  }
   
 #if CMD_HISTORY  #if CMD_HISTORY
Line 505 
Line 705 
         s = curr_mlist->curr_mp->string;          s = curr_mlist->curr_mp->string;
         if (s == NULL)          if (s == NULL)
                 s = "";                  s = "";
         for (cp = cmdbuf;  *s != '\0';  s++)          strcpy(cmdbuf, s);
         {          for (cp = cmdbuf;  *cp != '\0';  )
                 *cp = *s;  
                 cmd_right();                  cmd_right();
         }  
         *cp = '\0';  
         return (CC_OK);          return (CC_OK);
 }  }
 #endif  #endif
Line 531 
Line 728 
          */           */
         if (strlen(cmd) == 0)          if (strlen(cmd) == 0)
                 return;                  return;
   
         /*          /*
          * Don't save if a duplicate of a command which is already           * Save the command unless it's a duplicate of the
          * in the history.           * last command in the history.
          * But select the one already in the history to be current.  
          */           */
         for (ml = mlist->next;  ml != mlist;  ml = ml->next)          ml = mlist->prev;
           if (ml == mlist || strcmp(ml->string, cmd) != 0)
         {          {
                 if (strcmp(ml->string, cmd) == 0)  
                         break;  
         }  
         if (ml == mlist)  
         {  
                 /*                  /*
                  * Did not find command in history.                   * Did not find command in history.
                  * Save the command and put it at the end of the history list.                   * Save the command and put it at the end of the history list.
Line 576 
Line 769 
         if (curr_mlist == NULL)          if (curr_mlist == NULL)
                 return;                  return;
         cmd_addhist(curr_mlist, cmdbuf);          cmd_addhist(curr_mlist, cmdbuf);
           curr_mlist->modified = 1;
 #endif  #endif
 }  }
   
Line 663 
Line 857 
         case EC_LINEKILL:          case EC_LINEKILL:
                 not_in_completion();                  not_in_completion();
                 return (cmd_kill());                  return (cmd_kill());
           case EC_ABORT:
                   not_in_completion();
                   (void) cmd_kill();
                   return (CC_QUIT);
         case EC_W_BACKSPACE:          case EC_W_BACKSPACE:
                 not_in_completion();                  not_in_completion();
                 return (cmd_werase());                  return (cmd_werase());
Line 705 
Line 903 
 {  {
         char *s;          char *s;
         int action;          int action;
           char *endline = str + strlen(str);
   
         for (s = str;  *s != '\0';  s++)          for (s = str;  *s != '\0';  )
         {          {
                 action = cmd_ichar(*s);                  char *os = s;
                   step_char(&s, +1, endline);
                   action = cmd_ichar(os, s - os);
                 if (action != CC_OK)                  if (action != CC_OK)
                 {                  {
                         bell();                          bell();
Line 995 
Line 1196 
         int c;          int c;
 {  {
         int action;          int action;
           int len;
   
           if (!utf_mode)
           {
                   cmd_mbc_buf[0] = c;
                   len = 1;
           } else
           {
                   /* Perform strict validation in all possible cases.  */
                   if (cmd_mbc_buf_len == 0)
                   {
                    retry:
                           cmd_mbc_buf_index = 1;
                           *cmd_mbc_buf = c;
                           if (IS_ASCII_OCTET(c))
                                   cmd_mbc_buf_len = 1;
                           else if (IS_UTF8_LEAD(c))
                           {
                                   cmd_mbc_buf_len = utf_len(c);
                                   return (CC_OK);
                           } else
                           {
                                   /* UTF8_INVALID or stray UTF8_TRAIL */
                                   bell();
                                   return (CC_ERROR);
                           }
                   } else if (IS_UTF8_TRAIL(c))
                   {
                           cmd_mbc_buf[cmd_mbc_buf_index++] = c;
                           if (cmd_mbc_buf_index < cmd_mbc_buf_len)
                                   return (CC_OK);
                           if (!is_utf8_well_formed(cmd_mbc_buf))
                           {
                                   /* complete, but not well formed (non-shortest form), sequence */
                                   cmd_mbc_buf_len = 0;
                                   bell();
                                   return (CC_ERROR);
                           }
                   } else
                   {
                           /* Flush incomplete (truncated) sequence.  */
                           cmd_mbc_buf_len = 0;
                           bell();
                           /* Handle new char.  */
                           goto retry;
                   }
   
                   len = cmd_mbc_buf_len;
                   cmd_mbc_buf_len = 0;
           }
   
         if (literal)          if (literal)
         {          {
                 /*                  /*
                  * Insert the char, even if it is a line-editing char.                   * Insert the char, even if it is a line-editing char.
                  */                   */
                 literal = 0;                  literal = 0;
                 return (cmd_ichar(c));                  return (cmd_ichar(cmd_mbc_buf, len));
         }          }
   
         /*          /*
          * See if it is a special line-editing character.           * See if it is a line-editing character.
          */           */
         if (in_mca())          if (in_mca() && len == 1)
         {          {
                 action = cmd_edit(c);                  action = cmd_edit(c);
                 switch (action)                  switch (action)
Line 1024 
Line 1275 
         /*          /*
          * Insert the char into the command buffer.           * Insert the char into the command buffer.
          */           */
         return (cmd_ichar(c));          return (cmd_ichar(cmd_mbc_buf, len));
 }  }
   
 /*  /*
  * Return the number currently in the command buffer.   * Return the number currently in the command buffer.
  */   */
         public LINENUM          public LINENUM
 cmd_int()  cmd_int(frac)
           long *frac;
 {  {
         register char *p;          char *p;
         LINENUM n = 0;          LINENUM n = 0;
           int err;
   
         for (p = cmdbuf;  *p != '\0';  p++)          for (p = cmdbuf;  *p >= '0' && *p <= '9';  p++)
                 n = (10 * n) + (*p - '0');                  n = (n * 10) + (*p - '0');
           *frac = 0;
           if (*p++ == '.')
           {
                   *frac = getfraction(&p, NULL, &err);
                   /* {{ do something if err is set? }} */
           }
         return (n);          return (n);
 }  }
   
Line 1048 
Line 1307 
 get_cmdbuf()  get_cmdbuf()
 {  {
         return (cmdbuf);          return (cmdbuf);
   }
   
   #if CMD_HISTORY
   /*
    * Return the last (most recent) string in the current command history.
    */
           public char *
   cmd_lastpattern()
   {
           if (curr_mlist == NULL)
                   return (NULL);
           return (curr_mlist->curr_mp->prev->string);
   }
   #endif
   
   #if CMD_HISTORY
   /*
    * Get the name of the history file.
    */
           static char *
   histfile_name()
   {
           char *home;
           char *name;
           int len;
   
           /* See if filename is explicitly specified by $LESSHISTFILE. */
           name = lgetenv("LESSHISTFILE");
           if (name != NULL && *name != '\0')
           {
                   if (strcmp(name, "-") == 0 || strcmp(name, "/dev/null") == 0)
                           /* $LESSHISTFILE == "-" means don't use a history file. */
                           return (NULL);
                   return (save(name));
           }
   
           /* Otherwise, file is in $HOME. */
           home = lgetenv("HOME");
           if (home == NULL || *home == '\0')
           {
   #if OS2
                   home = lgetenv("INIT");
                   if (home == NULL || *home == '\0')
   #endif
                           return (NULL);
           }
           len = strlen(home) + strlen(LESSHISTFILE) + 2;
           name = (char *) ecalloc(len, sizeof(char));
           SNPRINTF2(name, len, "%s/%s", home, LESSHISTFILE);
           return (name);
   }
   #endif /* CMD_HISTORY */
   
   /*
    * Initialize history from a .lesshist file.
    */
           public void
   init_cmdhist()
   {
   #if CMD_HISTORY
           struct mlist *ml = NULL;
           char line[CMDBUF_SIZE];
           char *filename;
           FILE *f;
           char *p;
   
           filename = histfile_name();
           if (filename == NULL)
                   return;
           f = fopen(filename, "r");
           free(filename);
           if (f == NULL)
                   return;
           if (fgets(line, sizeof(line), f) == NULL ||
               strncmp(line, HISTFILE_FIRST_LINE, strlen(HISTFILE_FIRST_LINE)) != 0)
           {
                   fclose(f);
                   return;
           }
           while (fgets(line, sizeof(line), f) != NULL)
           {
                   for (p = line;  *p != '\0';  p++)
                   {
                           if (*p == '\n' || *p == '\r')
                           {
                                   *p = '\0';
                                   break;
                           }
                   }
                   if (strcmp(line, HISTFILE_SEARCH_SECTION) == 0)
                           ml = &mlist_search;
                   else if (strcmp(line, HISTFILE_SHELL_SECTION) == 0)
                   {
   #if SHELL_ESCAPE || PIPEC
                           ml = &mlist_shell;
   #else
                           ml = NULL;
   #endif
                   } else if (*line == '"')
                   {
                           if (ml != NULL)
                                   cmd_addhist(ml, line+1);
                   }
           }
           fclose(f);
   #endif /* CMD_HISTORY */
   }
   
   /*
    *
    */
   #if CMD_HISTORY
           static void
   save_mlist(ml, f)
           struct mlist *ml;
           FILE *f;
   {
           int histsize = 0;
           int n;
           char *s;
   
           s = lgetenv("LESSHISTSIZE");
           if (s != NULL)
                   histsize = atoi(s);
           if (histsize == 0)
                   histsize = 100;
   
           ml = ml->prev;
           for (n = 0;  n < histsize;  n++)
           {
                   if (ml->string == NULL)
                           break;
                   ml = ml->prev;
           }
           for (ml = ml->next;  ml->string != NULL;  ml = ml->next)
                   fprintf(f, "\"%s\n", ml->string);
   }
   #endif /* CMD_HISTORY */
   
   /*
    *
    */
           public void
   save_cmdhist()
   {
   #if CMD_HISTORY
           char *filename;
           FILE *f;
           int modified = 0;
   
           filename = histfile_name();
           if (filename == NULL)
                   return;
           if (mlist_search.modified)
                   modified = 1;
   #if SHELL_ESCAPE || PIPEC
           if (mlist_shell.modified)
                   modified = 1;
   #endif
           if (!modified)
                   return;
           f = fopen(filename, "w");
           free(filename);
           if (f == NULL)
                   return;
   #if HAVE_FCHMOD
   {
           /* Make history file readable only by owner. */
           int do_chmod = 1;
   #if HAVE_STAT
           struct stat statbuf;
           int r = fstat(fileno(f), &statbuf);
           if (r < 0 || !S_ISREG(statbuf.st_mode))
                   /* Don't chmod if not a regular file. */
                   do_chmod = 0;
   #endif
           if (do_chmod)
                   fchmod(fileno(f), 0600);
   }
   #endif
   
           fprintf(f, "%s\n", HISTFILE_FIRST_LINE);
   
           fprintf(f, "%s\n", HISTFILE_SEARCH_SECTION);
           save_mlist(&mlist_search, f);
   
   #if SHELL_ESCAPE || PIPEC
           fprintf(f, "%s\n", HISTFILE_SHELL_SECTION);
           save_mlist(&mlist_shell, f);
   #endif
   
           fclose(f);
   #endif /* CMD_HISTORY */
 }  }

Legend:
Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3