home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 036 / less232.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1994-09-24  |  7KB  |  354 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994  Mark Nudelman
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice in the documentation and/or other materials provided with 
  12.  *    the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
  15.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  17.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
  18.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  19.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
  20.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
  21.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  22.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
  23.  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 
  24.  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Entry point, initialization, miscellaneous routines.
  30.  */
  31.  
  32. #include "less.h"
  33. #include "position.h"
  34.  
  35. public int      ispipe, iscompressed, newcompressed;
  36. public char *    every_first_cmd = NULL;
  37. public int    new_file;
  38. public int    is_tty;
  39. public IFILE    curr_ifile = NULL_IFILE;
  40. public IFILE    old_ifile = NULL_IFILE;
  41. public struct scrpos initial_scrpos;
  42. public int    any_display = 0;
  43. public int    wscroll;
  44. public char *    progname;
  45. public int    quitting;
  46.  
  47. extern int    file;
  48. extern int    fd0;
  49. extern int    quit_at_eof;
  50. extern int    cbufs;
  51. extern int    errmsgs;
  52. extern int    screen_trashed;
  53. extern int    force_open;
  54.  
  55. #if LOGFILE
  56. public int    logfile = -1;
  57. public int    force_logfile = 0;
  58. public char *    namelogfile = NULL;
  59. #endif
  60.  
  61. #if EDITOR
  62. public char *    editor;
  63. public char *    editproto;
  64. #endif
  65.  
  66. #if TAGS
  67. extern char *    tagfile;
  68. extern char *    tagoption;
  69. extern int    jump_sline;
  70. #endif
  71.  
  72. extern char version[];
  73.  
  74. extern char *strchr();
  75.  
  76.  
  77. usage()
  78. {
  79.   int x = strlen(progname);
  80.  
  81.   printf("\n%s.\n", version + 5);
  82.   printf("\nUsage: %s [-[+]aABcCdeEfgimMnNqQruUsw] [-bN] [-hN] [-xN] [-[z]N]", progname);
  83.   printf("\n       %*s [-P[mM=]string] [-[lL]logfile] [-kkeyfile]", x, "");
  84.   printf("\n       %*s [+cmd] [-ttag] [filename]...\n", x, "");
  85.   printf("\n   or: %s -?\n", progname);
  86.   exit(1);
  87. }
  88.  
  89.  
  90. /*
  91.  * Entry point.
  92.  */
  93. int
  94. main(argc, argv)
  95.     int argc;
  96.     char *argv[];
  97. {
  98.     IFILE ifile;
  99.  
  100. #ifdef __EMX__
  101.     _response(&argc, &argv);
  102.     _wildcard(&argc, &argv);
  103. #endif
  104.  
  105.     progname = *argv++;
  106.  
  107.     if (isatty(0) && argc == 1)
  108.       usage();
  109.  
  110.     /*
  111.      * Process command line arguments and LESS environment arguments.
  112.      * Command line arguments override environment arguments.
  113.      */
  114.     init_prompt();
  115.     init_charset();
  116.     init_option();
  117.     scan_option(getenv("LESS"));
  118.  
  119. #define    isoptstring(s)    (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
  120.     while (--argc > 0 && (isoptstring(argv[0]) || isoptpending()))
  121.         scan_option(*argv++);
  122. #undef isoptstring
  123.  
  124.     if (isoptpending())
  125.     {
  126.         /*
  127.          * Last command line option was a flag requiring a
  128.          * following string, but there was no following string.
  129.          */
  130.         nopendopt();
  131.         quit(0);
  132.     }
  133.  
  134. #if USERFILE
  135.     /*
  136.      * Try to use the lesskey file "$HOME/.less".
  137.      */
  138.     add_hometable();
  139. #endif
  140. #if EDITOR
  141.     editor = getenv("EDITOR");
  142.     if (editor == NULL || *editor == '\0')
  143.         editor = EDIT_PGM;
  144.     editproto = getenv("LESSEDIT");
  145.     if (editproto == NULL || *editproto == '\0')
  146.         editproto = "%E ?lm+%lm. %f";
  147. #endif
  148.  
  149.     /*
  150.      * Call get_ifile with all the command line filenames
  151.      * to "register" them with the ifile system.
  152.      */
  153.     ifile = NULL_IFILE;
  154.     while (--argc >= 0)
  155.     {
  156. #if MSOFTC || OS2
  157.         /*
  158.          * Because the "shell" doesn't expand filename patterns,
  159.          * treat each argument as a filename pattern rather than
  160.          * a single filename.  
  161.          * Expand the pattern and iterate over the expanded list.
  162.          */
  163.         {
  164.             struct textlist tlist;
  165.             char *gfilename;
  166.             char *filename;
  167.             
  168.             gfilename = glob(*argv++);
  169.             init_textlist(&tlist, gfilename);
  170.             filename = NULL;
  171.             while ((filename = forw_textlist(&tlist, filename)) != NULL)
  172.                 ifile = get_ifile(filename, ifile);
  173.             free(gfilename);
  174.         }
  175. #else
  176.         ifile = get_ifile(*argv++, ifile);
  177. #endif
  178.     }
  179.     /*
  180.      * Set up terminal, etc.
  181.      */
  182.     is_tty = isatty(1);
  183.     if (!is_tty)
  184.     {
  185.         /*
  186.          * Output is not a tty.
  187.          * Just copy the input file(s) to output.
  188.          */
  189.         if (nifile() == 0)
  190.         {
  191.             if (edit_stdin() == 0)
  192.                 cat_file();
  193.         } else if (edit_first() == 0)
  194.         {
  195.             do {
  196.                 cat_file();
  197.             } while (edit_next(1) == 0);
  198.         }
  199.         quit(0);
  200.     }
  201.  
  202.     init_mark();
  203.     raw_mode(1);
  204.     get_term();
  205.     get_editkeys();
  206.     open_getchr();
  207.     cmd_init();
  208.  
  209.     init_signals(1);
  210.  
  211.     /*
  212.      * Select the first file to examine.
  213.      */
  214. #if TAGS
  215.     if (tagoption != NULL)
  216.     {
  217.         /*
  218.          * A -t option was given.
  219.          * Verify that no filenames were also given.
  220.          * Edit the file selected by the "tags" search,
  221.          * and search for the proper line in the file.
  222.          */
  223.         if (nifile() > 0)
  224.         {
  225.             error("No filenames allowed with -t option", NULL_PARG);
  226.             quit(1);
  227.         }
  228.         findtag(tagoption);
  229.         if (tagfile == NULL)
  230.             quit(1);
  231.         if (edit(tagfile))  /* Edit file which contains the tag */
  232.             quit(1);
  233.         /*
  234.          * Search for the line which contains the tag.
  235.          * Set up initial_scrpos so we display that line.
  236.          */
  237.         initial_scrpos.pos = tagsearch();
  238.         if (initial_scrpos.pos == NULL_POSITION)
  239.             quit(1);
  240.         initial_scrpos.ln = jump_sline;
  241.     } else
  242. #endif
  243.     if (nifile() == 0)
  244.     {
  245.         if (edit_stdin())  /* Edit standard input */
  246.             quit(1);
  247.     } else 
  248.     {
  249.         if (edit_first())  /* Edit first valid file in cmd line */
  250.             quit(1);
  251.     }
  252.  
  253.     init();
  254.     commands();
  255.     quit(0);
  256.     /*NOTREACHED*/
  257. }
  258.  
  259. /*
  260.  * Copy a string, truncating to the specified length if necessary.
  261.  * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
  262.  */
  263.     public void
  264. strtcpy(to, from, len)
  265.     char *to;
  266.     char *from;
  267.     unsigned int len;
  268. {
  269.     strncpy(to, from, len);
  270.     to[len-1] = '\0';
  271. }
  272.  
  273. /*
  274.  * Copy a string to a "safe" place
  275.  * (that is, to a buffer allocated by calloc).
  276.  */
  277.     public char *
  278. save(s)
  279.     char *s;
  280. {
  281.     register char *p;
  282.  
  283.     p = (char *) ecalloc(strlen(s)+1, sizeof(char));
  284.     strcpy(p, s);
  285.     return (p);
  286. }
  287.  
  288. /*
  289.  * Allocate memory.
  290.  * Like calloc(), but never returns an error (NULL).
  291.  */
  292.     public VOID_POINTER
  293. ecalloc(count, size)
  294.     int count;
  295.     unsigned int size;
  296. {
  297.     register VOID_POINTER p;
  298.  
  299.     p = (VOID_POINTER) calloc(count, size);
  300.     if (p != NULL)
  301.         return (p);
  302.     error("Cannot allocate memory", NULL_PARG);
  303.     quit(1);
  304.     /*NOTREACHED*/
  305. }
  306.  
  307. /*
  308.  * Skip leading spaces in a string.
  309.  */
  310.     public char *
  311. skipsp(s)
  312.     register char *s;
  313. {
  314.     while (*s == ' ' || *s == '\t')    
  315.         s++;
  316.     return (s);
  317. }
  318.  
  319. /*
  320.  * Exit the program.
  321.  */
  322.     public void
  323. quit(status)
  324.     int status;
  325. {
  326.     static int save_status;
  327.  
  328.     /*
  329.      * Put cursor at bottom left corner, clear the line,
  330.      * reset the terminal modes, and exit.
  331.      */
  332.     if (status < 0)
  333.         status = save_status;
  334.     else
  335.         save_status = status;
  336.     quitting = 1;
  337.     edit((char*)NULL);
  338.     if (any_display)
  339.         clear_bot();
  340.     deinit();
  341.     flush();
  342.     raw_mode(0);
  343. #if MSOFTC
  344.     /* 
  345.      * If we don't close 2, we get some garbage from
  346.      * 2's buffer when it flushes automatically.
  347.      * I cannot track this one down  RB
  348.      * The same bug shows up if we use ^C^C to abort.
  349.      */
  350.     close(2);
  351. #endif
  352.     exit(status);
  353. }
  354.