home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / GNU / LES177AS.ZIP / EDIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-08  |  8.2 KB  |  453 lines

  1. #include "less.h"
  2.  
  3. #if __MSDOS__
  4. #include <fcntl.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <io.h>
  8. #endif
  9.  
  10. #define    ISPIPE(fd)    ((fd)==0)
  11. extern int ispipe;
  12. extern int new_file;
  13. extern int errmsgs;
  14. extern int quit_at_eof;
  15. extern int file;
  16. extern int cbufs;
  17. extern char *every_first_cmd;
  18. extern int any_display;
  19. extern int force_open;
  20. extern int is_tty;
  21. extern IFILE curr_ifile;
  22. extern IFILE old_ifile;
  23. extern struct scrpos initial_scrpos;
  24.  
  25. #if LOGFILE
  26. extern int logfile;
  27. extern int force_logfile;
  28. extern char *namelogfile;
  29. #endif
  30.  
  31.  
  32. /*
  33.  * Edit a new file.
  34.  * Filename == "-" means standard input.
  35.  * Filename == NULL means just close the current file.
  36.  */
  37.     public int
  38. edit(filename, just_looking)
  39.     register char *filename;
  40.     int just_looking;
  41. {
  42.     register int f;
  43. #if LOGFILE
  44.     char *s;
  45. #endif
  46.     int answer;
  47.     int no_display;
  48.     struct scrpos scrpos;
  49.     PARG parg;
  50.  
  51.     if (filename == NULL)
  52.     {
  53.         /*
  54.          * Close the current file, but don't open a new one.
  55.          */
  56.         f = -1;
  57.     } else if (strcmp(filename, "-") == 0)
  58.     {
  59.         /* 
  60.          * Use standard input.
  61.          */
  62.         f = 0;
  63.     } else if ((parg.p_string = bad_file(filename)) != NULL)
  64.     {
  65.         error("%s", &parg);
  66.         free(parg.p_string);
  67.         return (1);
  68. #if __MSDOS__
  69.     } else if ((f = open(filename, O_RDONLY|O_BINARY)) < 0)
  70. #else
  71.     } else if ((f = open(filename, 0)) < 0)
  72. #endif
  73.     {
  74.         parg.p_string = errno_message(filename);
  75.         error("%s", &parg);
  76.         free(parg.p_string);
  77.         return (1);
  78.     } else if (!force_open && !just_looking && bin_file(f))
  79.     {
  80.         parg.p_string = filename;
  81.         answer = query("\"%s\" may be a binary file.  Continue? ",
  82.             &parg);
  83.         if (answer != 'y' && answer != 'Y')
  84.         {
  85.             close(f);
  86.             return (1);
  87.         }
  88.     }
  89.  
  90.     if (f >= 0 && isatty(f))
  91.     {
  92.         /*
  93.          * Not really necessary to call this an error,
  94.          * but if the control terminal (for commands)
  95.          * and the input file (for data) are the same,
  96.          * we get weird results at best.
  97.          */
  98. #if __MSDOS__
  99.         parg.p_string = "less -?";
  100. #else
  101.         parg.p_string = "less -\\?";
  102. #endif
  103.         error("Cannot take input from a terminal (\"%s\" for help)", 
  104.             &parg);
  105.         if (!ISPIPE(f))
  106.             close(f);
  107.         return (1);
  108.     }
  109.  
  110. #if LOGFILE
  111.     s = namelogfile;
  112.     end_logfile();
  113.     if (f >= 0 && ISPIPE(f) && s != NULL && is_tty)
  114.         use_logfile(s);
  115. #endif
  116.  
  117.     /*
  118.      * We are now committed to using the new file.
  119.      * Close the current input file and set up to use the new one.
  120.      */
  121.     if (curr_ifile != NULL_IFILE)
  122.     {
  123.         /*
  124.          * Save the current position so that we can return to
  125.          * the same position if we edit this file again.
  126.          */
  127.         get_scrpos(&scrpos);
  128.         if (scrpos.pos != NULL_POSITION)
  129.         {
  130.             store_pos(curr_ifile, &scrpos);
  131.             lastmark();
  132.         }
  133.     }
  134.  
  135.     /*
  136.      * Close the current file, unless it is a pipe.
  137.      */
  138.     if (!ISPIPE(file))
  139.         close(file);
  140.     file = f;
  141.  
  142.     if (f < 0)
  143.         return (1);
  144.  
  145.     /*
  146.      * Get the new ifile.
  147.      * Get the saved position for that file.
  148.      */
  149.     old_ifile = curr_ifile;
  150.     curr_ifile = get_ifile(filename, curr_ifile);
  151.     get_pos(curr_ifile, &initial_scrpos);
  152.  
  153.     ispipe = ISPIPE(f);
  154.     if (ispipe)
  155.         ch_pipe();
  156.     else
  157.         ch_nonpipe();
  158.     (void) ch_nbuf(cbufs);
  159.     ch_flush();
  160.  
  161.     new_file = 1;
  162.  
  163. #if  __MSDOS__
  164. #ifndef TURBOC
  165.     top_filename();
  166. #endif
  167. #endif
  168.  
  169.     if (every_first_cmd != NULL)
  170.         ungetsc(every_first_cmd);
  171.  
  172.     no_display = !any_display;
  173.     flush();
  174.     any_display = 1;
  175.  
  176.     if (is_tty)
  177.     {
  178.         /*
  179.          * Output is to a real tty.
  180.          */
  181.  
  182.         /*
  183.          * Indicate there is nothing displayed yet.
  184.          */
  185.         pos_clear();
  186.         clr_linenum();
  187.         if (no_display && errmsgs > 0)
  188.         {
  189.             /*
  190.              * We displayed some messages on error output
  191.              * (file descriptor 2; see error() function).
  192.              * Before erasing the screen contents,
  193.              * display the file name and wait for a keystroke.
  194.              */
  195.             parg.p_string = filename;
  196.             error("%s", &parg);
  197.         }
  198.     }
  199.     return (0);
  200. }
  201.  
  202. /*
  203.  * Edit a space-separated list of files.
  204.  * For each filename in the list, enter it into the ifile list.
  205.  * Then edit the first one.
  206.  */
  207.     public void
  208. edit_list(list)
  209.     char *list;
  210. {
  211.     register char *s;
  212.     register char *es;
  213.     register char *filename;
  214.     char *good_filename;
  215.  
  216.     /*
  217.      * good_filename keeps track of the first valid filename.
  218.      */
  219.     good_filename = NULL;
  220.     s = list;
  221.     es = s + strlen(s);
  222.     while ((s = skipsp(s)) < es)
  223.     {
  224.         /*
  225.          * Get the next filename and null terminate it.
  226.          */
  227.         filename = s;
  228.         while (*s != ' ' && *s != '\0')
  229.             s++;
  230.         if (*s != '\0')
  231.             *s++ = '\0';
  232.         /*
  233.          * Try to edit the file.
  234.          * This enters it into the command line list (if it is good).
  235.          * If it is the first good file we've seen, remember it.
  236.          * {{ A little weirdness here: if any of the filenames
  237.          *    are already in the list, subsequent ones get
  238.          *    entered after the position where that one already
  239.          *    was, instead of at the end. }}
  240.          */
  241.         if (edit(filename, 0) == 0 && good_filename == NULL)
  242.             good_filename = filename;
  243.     }
  244.  
  245.     /*
  246.      * Edit the first valid filename in the list.
  247.      */
  248.     if (good_filename != NULL)
  249.     {
  250.         (void) edit(good_filename, 0);
  251.     }
  252. }
  253.  
  254. /*
  255.  * Edit the first file in the command line (ifile) list.
  256.  */
  257.     public int
  258. edit_first()
  259. {
  260.     curr_ifile = NULL_IFILE;
  261.     return (edit_next(1));
  262. }
  263.  
  264. /*
  265.  * Edit the last file in the command line (ifile) list.
  266.  */
  267.     public int
  268. edit_last()
  269. {
  270.     curr_ifile = NULL_IFILE;
  271.     return (edit_prev(1));
  272. }
  273.  
  274.  
  275. /*
  276.  * Edit the next file in the command line (ifile) list.
  277.  */
  278.     public int
  279. edit_next(n)
  280.     int n;
  281. {
  282.     IFILE h;
  283.  
  284.     h = curr_ifile;
  285.     while (--n >= 0 || edit(get_filename(h), 0))
  286.     {
  287.         if ((h = next_ifile(h)) == NULL_IFILE)
  288.             /*
  289.              * Reached end of the ifile list.
  290.              */
  291.             return (1);
  292.     } 
  293.     /*
  294.      * Found a file that we can edit.
  295.      */
  296.     return (0);
  297. }
  298.  
  299. /*
  300.  * Edit the previous file in the command line list.
  301.  */
  302.     public int
  303. edit_prev(n)
  304.     int n;
  305. {
  306.     IFILE h;
  307.  
  308.     h = curr_ifile;
  309.     while (--n >= 0 || edit(get_filename(h), 0))
  310.     {
  311.         if ((h = prev_ifile(h)) == NULL_IFILE)
  312.             /*
  313.              * Reached beginning of the ifile list.
  314.              */
  315.             return (1);
  316.     } 
  317.     /*
  318.      * Found a file that we can edit.
  319.      */
  320.     return (0);
  321. }
  322.  
  323. /*
  324.  * Edit a specific file in the command line (ifile) list.
  325.  */
  326.     public int
  327. edit_index(n)
  328.     int n;
  329. {
  330.     IFILE h;
  331.  
  332.     h = NULL_IFILE;
  333.     do
  334.     {
  335.         if ((h = next_ifile(h)) == NULL_IFILE)
  336.         {
  337.             /*
  338.              * Reached end of the list without finding it.
  339.              */
  340.             return (1);
  341.         }
  342.     } while (get_index(h) != n);
  343.  
  344.     return (edit(get_filename(h), 0));
  345. }
  346.  
  347. /*
  348.  * Copy a file directly to standard output.
  349.  * Used if standard output is not a tty.
  350.  */
  351.     public void
  352. cat_file()
  353. {
  354.     register int c;
  355.  
  356.     while ((c = ch_forw_get()) != EOI)
  357.         putchr(c);
  358.     flush();
  359. }
  360.  
  361. #if LOGFILE
  362.  
  363. /*
  364.  * If the user asked for a log file and our input file
  365.  * is standard input, create the log file.  
  366.  * We take care not to blindly overwrite an existing file.
  367.  */
  368.     public void
  369. use_logfile(filename)
  370.     char *filename;
  371. {
  372.     register int exists;
  373.     register int answer;
  374.     PARG parg;
  375.  
  376.     /*
  377.      * {{ We could use access() here. }}
  378.      */
  379.     exists = open(filename, 0);
  380.     close(exists);
  381.     exists = (exists >= 0);
  382.  
  383.     /*
  384.      * Decide whether to overwrite the log file or append to it.
  385.      * (If it doesn't exist we "overwrite" it.
  386.      */
  387.     if (!exists || force_logfile)
  388.     {
  389.         /*
  390.          * Overwrite (or create) the log file.
  391.          */
  392.         answer = 'O';
  393.     } else
  394.     {
  395.         /*
  396.          * Ask user what to do.
  397.          */
  398.         parg.p_string = filename;
  399.         answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg);
  400.     }
  401.  
  402. loop:
  403.     switch (answer)
  404.     {
  405.     case 'O': case 'o':
  406.         /*
  407.          * Overwrite: create the file.
  408.          */
  409.         logfile = creat(filename, 0644);
  410.         break;
  411.     case 'A': case 'a':
  412.         /*
  413.          * Append: open the file and seek to the end.
  414.          */
  415. #if __MSDOS__
  416.         logfile = open(filename, O_APPEND|O_WRONLY);
  417. #else
  418.         logfile = open(filename, 1);
  419. #endif
  420.         if (lseek(logfile, (offset_t)0, 2) == BAD_LSEEK)
  421.         {
  422.             close(logfile);
  423.             logfile = -1;
  424.         }
  425.         break;
  426.     case 'D': case 'd':
  427.         /*
  428.          * Don't do anything.
  429.          */
  430.         return;
  431.     case 'q':
  432.         quit(0);
  433.         /*NOTREACHED*/
  434.     default:
  435.         /*
  436.          * Eh?
  437.          */
  438.         answer = query("Overwrite, Append, or Don't log? ", NULL_PARG);
  439.         goto loop;
  440.     }
  441.  
  442.     if (logfile < 0)
  443.     {
  444.         /*
  445.          * Error in opening logfile.
  446.          */
  447.         parg.p_string = filename;
  448.         error("Cannot write to \"%s\"", &parg);
  449.     }
  450. }
  451.  
  452. #endif
  453.