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

Diff for /src/usr.bin/less/edit.c between version 1.3 and 1.4

version 1.3, 2001/11/19 19:02:14 version 1.4, 2003/04/13 18:26:25
Line 1 
Line 1 
 /*      $OpenBSD$       */  
   
 /*  /*
  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman   * Copyright (C) 1984-2002  Mark Nudelman
  * All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * You may distribute under the terms of either the GNU General Public
  * modification, are permitted provided that the following conditions   * License or the Less License, as specified in the README file.
  * are met:  
  * 1. Redistributions of source code must retain the above copyright  
  *    notice, this list of conditions and the following disclaimer.  
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice in the documentation and/or other materials provided with  
  *    the distribution.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY   * For more information about less, or for information on how to
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * contact the author, see the README file.
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE  
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN  
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  */   */
   
   
Line 33 
Line 15 
   
 extern int new_file;  extern int new_file;
 extern int errmsgs;  extern int errmsgs;
 extern int quit_at_eof;  
 extern int cbufs;  extern int cbufs;
 extern char *every_first_cmd;  extern char *every_first_cmd;
 extern int any_display;  extern int any_display;
 extern int force_open;  extern int force_open;
 extern int is_tty;  extern int is_tty;
   extern int sigs;
 extern IFILE curr_ifile;  extern IFILE curr_ifile;
 extern IFILE old_ifile;  extern IFILE old_ifile;
 extern struct scrpos initial_scrpos;  extern struct scrpos initial_scrpos;
   extern void constant *ml_examine;
   #if SPACES_IN_FILENAMES
   extern char openquote;
   extern char closequote;
   #endif
   
 #if LOGFILE  #if LOGFILE
 extern int logfile;  extern int logfile;
Line 66 
Line 53 
         char *str;          char *str;
 {  {
         char *s;          char *s;
   #if SPACES_IN_FILENAMES
           int meta_quoted = 0;
           int delim_quoted = 0;
           char *esc = get_meta_escape();
           int esclen = strlen(esc);
   #endif
   
         tlist->string = skipsp(str);          tlist->string = skipsp(str);
         tlist->endstring = tlist->string + strlen(tlist->string);          tlist->endstring = tlist->string + strlen(tlist->string);
         for (s = str;  s < tlist->endstring;  s++)          for (s = str;  s < tlist->endstring;  s++)
         {          {
   #if SPACES_IN_FILENAMES
                   if (meta_quoted)
                   {
                           meta_quoted = 0;
                   } else if (esclen > 0 && s + esclen < tlist->endstring &&
                              strncmp(s, esc, esclen) == 0)
                   {
                           meta_quoted = 1;
                           s += esclen - 1;
                   } else if (delim_quoted)
                   {
                           if (*s == closequote)
                                   delim_quoted = 0;
                   } else /* (!delim_quoted) */
                   {
                           if (*s == openquote)
                                   delim_quoted = 1;
                           else if (*s == ' ')
                                   *s = '\0';
                   }
   #else
                 if (*s == ' ')                  if (*s == ' ')
                         *s = '\0';                          *s = '\0';
   #endif
         }          }
 }  }
   
Line 136 
Line 151 
   
         if (curr_ifile == NULL_IFILE)          if (curr_ifile == NULL_IFILE)
                 return;                  return;
   
         /*          /*
          * Save the current position so that we can return to           * Save the current position so that we can return to
          * the same position if we edit this file again.           * the same position if we edit this file again.
Line 157 
Line 173 
         if (curr_altfilename != NULL)          if (curr_altfilename != NULL)
         {          {
                 close_altfile(curr_altfilename, get_filename(curr_ifile),                  close_altfile(curr_altfilename, get_filename(curr_ifile),
                         curr_altpipe);                                  curr_altpipe);
                 free(curr_altfilename);                  free(curr_altfilename);
                 curr_altfilename = NULL;                  curr_altfilename = NULL;
         }          }
Line 192 
Line 208 
         int chflags;          int chflags;
         char *filename;          char *filename;
         char *open_filename;          char *open_filename;
           char *qopen_filename;
         char *alt_filename;          char *alt_filename;
         void *alt_pipe;          void *alt_pipe;
         IFILE was_curr_ifile;          IFILE was_curr_ifile;
Line 215 
Line 232 
 #if LOGFILE  #if LOGFILE
         end_logfile();          end_logfile();
 #endif  #endif
         was_curr_ifile = curr_ifile;          was_curr_ifile = save_curr_ifile();
         if (curr_ifile != NULL_IFILE)          if (curr_ifile != NULL_IFILE)
         {          {
                   chflags = ch_getflags();
                 close_file();                  close_file();
                   if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1)
                   {
                           /*
                            * Don't keep the help file in the ifile list.
                            */
                           del_ifile(was_curr_ifile);
                           was_curr_ifile = old_ifile;
                   }
         }          }
   
         if (ifile == NULL_IFILE)          if (ifile == NULL_IFILE)
Line 229 
Line 255 
                  *  you're supposed to have saved curr_ifile yourself,                   *  you're supposed to have saved curr_ifile yourself,
                  *  and you'll restore it if necessary.)                   *  and you'll restore it if necessary.)
                  */                   */
                   unsave_ifile(was_curr_ifile);
                 return (0);                  return (0);
         }          }
   
         filename = get_filename(ifile);          filename = save(get_filename(ifile));
         /*          /*
          * See if LESSOPEN specifies an "alternate" file to open.           * See if LESSOPEN specifies an "alternate" file to open.
          */           */
         alt_pipe = NULL;          alt_pipe = NULL;
         alt_filename = open_altfile(filename, &f, &alt_pipe);          alt_filename = open_altfile(filename, &f, &alt_pipe);
         open_filename = (alt_filename != NULL) ? alt_filename : filename;          open_filename = (alt_filename != NULL) ? alt_filename : filename;
           qopen_filename = shell_unquote(open_filename);
   
         chflags = 0;          chflags = 0;
         if (alt_pipe != NULL)          if (alt_pipe != NULL)
Line 259 
Line 287 
                  */                   */
                 f = fd0;                  f = fd0;
                 chflags |= CH_KEEPOPEN;                  chflags |= CH_KEEPOPEN;
                   /*
                    * Must switch stdin to BINARY mode.
                    */
                   SET_BINARY(f);
   #if MSDOS_COMPILER==DJGPPC
                   /*
                    * Setting stdin to binary by default causes
                    * Ctrl-C to not raise SIGINT.  We must undo
                    * that side-effect.
                    */
                   __djgpp_set_ctrl_c(1);
   #endif
           } else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
           {
                   f = -1;
                   chflags |= CH_HELPFILE;
         } else if ((parg.p_string = bad_file(open_filename)) != NULL)          } else if ((parg.p_string = bad_file(open_filename)) != NULL)
         {          {
                 /*                  /*
Line 273 
Line 317 
                         free(alt_filename);                          free(alt_filename);
                 }                  }
                 del_ifile(ifile);                  del_ifile(ifile);
                   free(qopen_filename);
                   free(filename);
                 /*                  /*
                  * Re-open the current file.                   * Re-open the current file.
                  */                   */
                 (void) edit_ifile(was_curr_ifile);                  reedit_ifile(was_curr_ifile);
                 return (1);                  return (1);
         } else if ((f = open(open_filename, OPEN_READ)) < 0)          } else if ((f = open(qopen_filename, OPEN_READ)) < 0)
         {          {
                 /*                  /*
                  * Got an error trying to open it.                   * Got an error trying to open it.
Line 287 
Line 333 
                 error("%s", &parg);                  error("%s", &parg);
                 free(parg.p_string);                  free(parg.p_string);
                 goto err1;                  goto err1;
         } else if (!force_open && !opened(ifile) && bin_file(f))          } else
         {          {
                 /*                  chflags |= CH_CANSEEK;
                  * Looks like a binary file.  Ask user if we should proceed.                  if (!force_open && !opened(ifile) && bin_file(f))
                  */  
                 parg.p_string = filename;  
                 answer = query("\"%s\" may be a binary file.  See it anyway? ",  
                         &parg);  
                 if (answer != 'y' && answer != 'Y')  
                 {                  {
                         close(f);                          /*
                         goto err1;                           * Looks like a binary file.
                            * Ask user if we should proceed.
                            */
                           parg.p_string = filename;
                           answer = query("\"%s\" may be a binary file.  See it anyway? ",
                                   &parg);
                           if (answer != 'y' && answer != 'Y')
                           {
                                   close(f);
                                   goto err1;
                           }
                 }                  }
         }          }
           free(qopen_filename);
   
         /*          /*
          * Get the new ifile.           * Get the new ifile.
          * Get the saved position for the file.           * Get the saved position for the file.
          */           */
         if (was_curr_ifile != NULL_IFILE)          if (was_curr_ifile != NULL_IFILE)
           {
                 old_ifile = was_curr_ifile;                  old_ifile = was_curr_ifile;
                   unsave_ifile(was_curr_ifile);
           }
         curr_ifile = ifile;          curr_ifile = ifile;
         curr_altfilename = alt_filename;          curr_altfilename = alt_filename;
         curr_altpipe = alt_pipe;          curr_altpipe = alt_pipe;
Line 315 
Line 370 
         get_pos(curr_ifile, &initial_scrpos);          get_pos(curr_ifile, &initial_scrpos);
         new_file = TRUE;          new_file = TRUE;
         ch_init(f, chflags);          ch_init(f, chflags);
   
           if (!(chflags & CH_HELPFILE))
           {
 #if LOGFILE  #if LOGFILE
         if (namelogfile != NULL && is_tty)                  if (namelogfile != NULL && is_tty)
                 use_logfile(namelogfile);                          use_logfile(namelogfile);
 #endif  #endif
                   if (every_first_cmd != NULL)
                           ungetsc(every_first_cmd);
           }
   
         if (every_first_cmd != NULL)  
                 ungetsc(every_first_cmd);  
   
         no_display = !any_display;          no_display = !any_display;
         flush();          flush();
         any_display = TRUE;          any_display = TRUE;
Line 341 
Line 399 
 #if HILITE_SEARCH  #if HILITE_SEARCH
                 clr_hilite();                  clr_hilite();
 #endif  #endif
                   cmd_addhist(ml_examine, filename);
                 if (no_display && errmsgs > 0)                  if (no_display && errmsgs > 0)
                 {                  {
                         /*                          /*
Line 353 
Line 412 
                         error("%s", &parg);                          error("%s", &parg);
                 }                  }
         }          }
           free(filename);
         return (0);          return (0);
 }  }
   
Line 365 
Line 425 
 edit_list(filelist)  edit_list(filelist)
         char *filelist;          char *filelist;
 {  {
         IFILE save_curr_ifile;          IFILE save_ifile;
         char *good_filename;          char *good_filename;
         char *filename;          char *filename;
         char *gfilelist;          char *gfilelist;
Line 373 
Line 433 
         struct textlist tl_files;          struct textlist tl_files;
         struct textlist tl_gfiles;          struct textlist tl_gfiles;
   
         save_curr_ifile = curr_ifile;          save_ifile = save_curr_ifile();
         good_filename = NULL;          good_filename = NULL;
   
         /*          /*
Line 386 
Line 446 
         filename = NULL;          filename = NULL;
         while ((filename = forw_textlist(&tl_files, filename)) != NULL)          while ((filename = forw_textlist(&tl_files, filename)) != NULL)
         {          {
                 gfilelist = glob(filename);                  gfilelist = lglob(filename);
                 init_textlist(&tl_gfiles, gfilelist);                  init_textlist(&tl_gfiles, gfilelist);
                 gfilename = NULL;                  gfilename = NULL;
                 while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)                  while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
Line 400 
Line 460 
          * Edit the first valid filename in the list.           * Edit the first valid filename in the list.
          */           */
         if (good_filename == NULL)          if (good_filename == NULL)
           {
                   unsave_ifile(save_ifile);
                 return (1);                  return (1);
           }
         if (get_ifile(good_filename, curr_ifile) == curr_ifile)          if (get_ifile(good_filename, curr_ifile) == curr_ifile)
           {
                 /*                  /*
                  * Trying to edit the current file; don't reopen it.                   * Trying to edit the current file; don't reopen it.
                  */                   */
                   unsave_ifile(save_ifile);
                 return (0);                  return (0);
         if (edit_ifile(save_curr_ifile))          }
                 quit(QUIT_ERROR);          reedit_ifile(save_ifile);
         return (edit(good_filename));          return (edit(good_filename));
 }  }
   
Line 433 
Line 498 
   
   
 /*  /*
  * Edit the next file in the command line (ifile) list.   * Edit the next or previous file in the command line (ifile) list.
  */   */
         public int          static int
 edit_next(n)  edit_istep(h, n, dir)
           IFILE h;
         int n;          int n;
           int dir;
 {  {
         IFILE h;  
         IFILE next;          IFILE next;
   
         h = curr_ifile;  
         /*          /*
          * Skip n filenames, then try to edit each filename.           * Skip n filenames, then try to edit each filename.
          */           */
         for (;;)          for (;;)
         {          {
                 next = next_ifile(h);                  next = (dir > 0) ? next_ifile(h) : prev_ifile(h);
                 if (--n < 0)                  if (--n < 0)
                 {                  {
                         if (edit_ifile(h) == 0)                          if (edit_ifile(h) == 0)
Line 461 
Line 526 
                          */                           */
                         return (1);                          return (1);
                 }                  }
                   if (ABORT_SIGS())
                   {
                           /*
                            * Interrupt breaks out, if we're in a long
                            * list of files that can't be opened.
                            */
                           return (1);
                   }
                 h = next;                  h = next;
         }          }
         /*          /*
Line 469 
Line 542 
         return (0);          return (0);
 }  }
   
 /*          static int
  * Edit the previous file in the command line list.  edit_inext(h, n)
  */          IFILE h;
           int n;
   {
           return (edit_istep(h, n, 1));
   }
   
         public int          public int
 edit_prev(n)  edit_next(n)
         int n;          int n;
 {  {
           return edit_istep(curr_ifile, n, 1);
   }
   
           static int
   edit_iprev(h, n)
         IFILE h;          IFILE h;
         IFILE next;          int n;
   {
           return (edit_istep(h, n, -1));
   }
   
         h = curr_ifile;          public int
         /*  edit_prev(n)
          * Skip n filenames, then try to edit each filename.          int n;
          */  {
         for (;;)          return edit_istep(curr_ifile, n, -1);
         {  
                 next = prev_ifile(h);  
                 if (--n < 0)  
                 {  
                         if (edit_ifile(h) == 0)  
                                 break;  
                 }  
                 if (next == NULL_IFILE)  
                 {  
                         /*  
                          * Reached beginning of the ifile list.  
                          */  
                         return (1);  
                 }  
                 h = next;  
         }  
         /*  
          * Found a file that we can edit.  
          */  
         return (0);  
 }  }
   
 /*  /*
Line 530 
Line 596 
         return (edit_ifile(h));          return (edit_ifile(h));
 }  }
   
           public IFILE
   save_curr_ifile()
   {
           if (curr_ifile != NULL_IFILE)
                   hold_ifile(curr_ifile, 1);
           return (curr_ifile);
   }
   
           public void
   unsave_ifile(save_ifile)
           IFILE save_ifile;
   {
           if (save_ifile != NULL_IFILE)
                   hold_ifile(save_ifile, -1);
   }
   
 /*  /*
    * Reedit the ifile which was previously open.
    */
           public void
   reedit_ifile(save_ifile)
           IFILE save_ifile;
   {
           IFILE next;
           IFILE prev;
   
           /*
            * Try to reopen the ifile.
            * Note that opening it may fail (maybe the file was removed),
            * in which case the ifile will be deleted from the list.
            * So save the next and prev ifiles first.
            */
           unsave_ifile(save_ifile);
           next = next_ifile(save_ifile);
           prev = prev_ifile(save_ifile);
           if (edit_ifile(save_ifile) == 0)
                   return;
           /*
            * If can't reopen it, open the next input file in the list.
            */
           if (next != NULL_IFILE && edit_inext(next, 0) == 0)
                   return;
           /*
            * If can't open THAT one, open the previous input file in the list.
            */
           if (prev != NULL_IFILE && edit_iprev(prev, 0) == 0)
                   return;
           /*
            * If can't even open that, we're stuck.  Just quit.
            */
           quit(QUIT_ERROR);
   }
   
   /*
  * Edit standard input.   * Edit standard input.
  */   */
         public int          public int
Line 538 
Line 657 
 {  {
         if (isatty(fd0))          if (isatty(fd0))
         {          {
 #if MSOFTC || OS2                  error("Missing filename (\"less --help\" for help)", NULL_PARG);
                 error("Missing filename (\"less -?\" for help)", NULL_PARG);  
 #else  
                 error("Missing filename (\"less -\\?\" for help)", NULL_PARG);  
 #endif  
                 quit(QUIT_OK);                  quit(QUIT_OK);
         }          }
         return (edit("-"));          return (edit("-"));
Line 555 
Line 670 
         public void          public void
 cat_file()  cat_file()
 {  {
         int c;          register int c;
   
         while ((c = ch_forw_get()) != EOI)          while ((c = ch_forw_get()) != EOI)
                 putchr(c);                  putchr(c);
Line 573 
Line 688 
 use_logfile(filename)  use_logfile(filename)
         char *filename;          char *filename;
 {  {
         int exists;          register int exists;
         int answer;          register int answer;
         PARG parg;          PARG parg;
   
         if (ch_getflags() & CH_CANSEEK)          if (ch_getflags() & CH_CANSEEK)
Line 586 
Line 701 
         /*          /*
          * {{ We could use access() here. }}           * {{ We could use access() here. }}
          */           */
           filename = shell_unquote(filename);
         exists = open(filename, OPEN_READ);          exists = open(filename, OPEN_READ);
         close(exists);          close(exists);
         exists = (exists >= 0);          exists = (exists >= 0);
Line 633 
Line 749 
                 /*                  /*
                  * Don't do anything.                   * Don't do anything.
                  */                   */
                   free(filename);
                 return;                  return;
         case 'q':          case 'q':
                 quit(QUIT_OK);                  quit(QUIT_OK);
Line 652 
Line 769 
                  */                   */
                 parg.p_string = filename;                  parg.p_string = filename;
                 error("Cannot write to \"%s\"", &parg);                  error("Cannot write to \"%s\"", &parg);
                   free(filename);
                   return;
         }          }
           free(filename);
           SET_BINARY(logfile);
 }  }
   
 #endif  #endif

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4