home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / less_332.lzh / less_332 / main.c < prev    next >
C/C++ Source or Header  |  1998-03-03  |  8KB  |  358 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994,1995,1996  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 char *    every_first_cmd = NULL;
  36. public int    new_file;
  37. public int    is_tty;
  38. public IFILE    curr_ifile = NULL_IFILE;
  39. public IFILE    old_ifile = NULL_IFILE;
  40. public struct scrpos initial_scrpos;
  41. public int    any_display = FALSE;
  42. public int    wscroll;
  43. public char *    progname;
  44. public int    quitting;
  45. public int    secure;
  46. public int    dohelp;
  47.  
  48. #if LOGFILE
  49. public int    logfile = -1;
  50. public int    force_logfile = FALSE;
  51. public char *    namelogfile = NULL;
  52. #endif
  53.  
  54. #if EDITOR
  55. public char *    editor;
  56. public char *    editproto;
  57. #endif
  58.  
  59. #if TAGS
  60. extern char *    tagoption;
  61. extern int    jump_sline;
  62. #endif
  63.  
  64. extern int    missing_cap;
  65. extern int    know_dumb;
  66.  
  67.  
  68. /*
  69.  * Entry point.
  70.  */
  71. int
  72. main(argc, argv)
  73.     int argc;
  74.     char *argv[];
  75. {
  76.     IFILE ifile;
  77.     char *s;
  78.  
  79. #ifdef __EMX__
  80.     _response(&argc, &argv);
  81.     _wildcard(&argc, &argv);
  82. #endif
  83.  
  84.     progname = *argv++;
  85.     argc--;
  86.  
  87.     secure = 0;
  88.     s = lgetenv("LESSSECURE");
  89.     if (s != NULL && *s != '\0')
  90.         secure = 1;
  91.  
  92.     /*
  93.      * Process command line arguments and LESS environment arguments.
  94.      * Command line arguments override environment arguments.
  95.      */
  96.     is_tty = isatty(1);
  97.     get_term();
  98.     init_cmds();
  99.     init_prompt();
  100.     init_charset();
  101.     init_option();
  102.     scan_option(lgetenv("LESS"));
  103.  
  104. #if GNU_OPTIONS
  105.     /*
  106.      * Special case for "less --help" and "less --version".
  107.      */
  108.     if (argc == 1)
  109.     {
  110.         if (strcmp(argv[0], "--help") == 0)
  111.         {
  112.             scan_option("-?");
  113.             argc = 0;
  114.         }
  115.         if (strcmp(argv[0], "--version") == 0)
  116.         {
  117.             scan_option("-V");
  118.             argc = 0;
  119.         }
  120.     }
  121. #endif
  122. #define    isoptstring(s)    (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
  123.     while (argc > 0 && (isoptstring(*argv) || isoptpending()))
  124.     {
  125.         s = *argv++;
  126.         argc--;
  127.         if (strcmp(s, "--") == 0)
  128.             break;
  129.         scan_option(s);
  130.     }
  131. #undef isoptstring
  132.  
  133.     if (isoptpending())
  134.     {
  135.         /*
  136.          * Last command line option was a flag requiring a
  137.          * following string, but there was no following string.
  138.          */
  139.         nopendopt();
  140.         quit(QUIT_OK);
  141.     }
  142.  
  143. #if EDITOR
  144.     editor = lgetenv("VISUAL");
  145.     if (editor == NULL || *editor == '\0')
  146.     {
  147.         editor = lgetenv("EDITOR");
  148.         if (editor == NULL || *editor == '\0')
  149.             editor = EDIT_PGM;
  150.     }
  151.     editproto = lgetenv("LESSEDIT");
  152.     if (editproto == NULL || *editproto == '\0')
  153.         editproto = "%E ?lm+%lm. %f";
  154. #endif
  155.  
  156.     /*
  157.      * Call get_ifile with all the command line filenames
  158.      * to "register" them with the ifile system.
  159.      */
  160.     ifile = NULL_IFILE;
  161.     if (dohelp)
  162.         ifile = get_ifile(FAKE_HELPFILE, ifile);
  163.     while (argc-- > 0)
  164.     {
  165. #if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) || OS2
  166.         /*
  167.          * Because the "shell" doesn't expand filename patterns,
  168.          * treat each argument as a filename pattern rather than
  169.          * a single filename.  
  170.          * Expand the pattern and iterate over the expanded list.
  171.          */
  172.         struct textlist tlist;
  173.         char *gfilename;
  174.         char *filename;
  175.         
  176.         gfilename = lglob(*argv++);
  177.         init_textlist(&tlist, gfilename);
  178.         filename = NULL;
  179.         while ((filename = forw_textlist(&tlist, filename)) != NULL)
  180.             ifile = get_ifile(filename, ifile);
  181.         free(gfilename);
  182. #else
  183.         ifile = get_ifile(*argv++, ifile);
  184. #endif
  185.     }
  186.     /*
  187.      * Set up terminal, etc.
  188.      */
  189.     if (!is_tty)
  190.     {
  191.         /*
  192.          * Output is not a tty.
  193.          * Just copy the input file(s) to output.
  194.          */
  195.         SET_BINARY(1);
  196.         if (nifile() == 0)
  197.         {
  198.             if (edit_stdin() == 0)
  199.                 cat_file();
  200.         } else if (edit_first() == 0)
  201.         {
  202.             do {
  203.                 cat_file();
  204.             } while (edit_next(1) == 0);
  205.         }
  206.         quit(QUIT_OK);
  207.     }
  208.  
  209.     if (missing_cap && !know_dumb)
  210.         error("WARNING: terminal is not fully functional", NULL_PARG);
  211.     init_mark();
  212.     raw_mode(1);
  213.     open_getchr();
  214.     init_signals(1);
  215.  
  216.     /*
  217.      * Select the first file to examine.
  218.      */
  219. #if TAGS
  220.     if (tagoption != NULL)
  221.     {
  222.         /*
  223.          * A -t option was given.
  224.          * Verify that no filenames were also given.
  225.          * Edit the file selected by the "tags" search,
  226.          * and search for the proper line in the file.
  227.          */
  228.         if (nifile() > 0)
  229.         {
  230.             error("No filenames allowed with -t option", NULL_PARG);
  231.             quit(QUIT_ERROR);
  232.         }
  233.         findtag(tagoption);
  234.         if (edit_tagfile())  /* Edit file which contains the tag */
  235.             quit(QUIT_ERROR);
  236.         /*
  237.          * Search for the line which contains the tag.
  238.          * Set up initial_scrpos so we display that line.
  239.          */
  240.         initial_scrpos.pos = tagsearch();
  241.         if (initial_scrpos.pos == NULL_POSITION)
  242.             quit(QUIT_ERROR);
  243.         initial_scrpos.ln = jump_sline;
  244.     } else
  245. #endif
  246.     if (nifile() == 0)
  247.     {
  248.         if (edit_stdin())  /* Edit standard input */
  249.             quit(QUIT_ERROR);
  250.     } else 
  251.     {
  252.         if (edit_first())  /* Edit first valid file in cmd line */
  253.             quit(QUIT_ERROR);
  254.     }
  255.  
  256.     init();
  257.     commands();
  258.     quit(QUIT_OK);
  259.     /*NOTREACHED*/
  260. }
  261.  
  262. /*
  263.  * Copy a string, truncating to the specified length if necessary.
  264.  * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
  265.  */
  266.     public void
  267. strtcpy(to, from, len)
  268.     char *to;
  269.     char *from;
  270.     unsigned int len;
  271. {
  272.     strncpy(to, from, len);
  273.     to[len-1] = '\0';
  274. }
  275.  
  276. /*
  277.  * Copy a string to a "safe" place
  278.  * (that is, to a buffer allocated by calloc).
  279.  */
  280.     public char *
  281. save(s)
  282.     char *s;
  283. {
  284.     register char *p;
  285.  
  286.     p = (char *) ecalloc(strlen(s)+1, sizeof(char));
  287.     strcpy(p, s);
  288.     return (p);
  289. }
  290.  
  291. /*
  292.  * Allocate memory.
  293.  * Like calloc(), but never returns an error (NULL).
  294.  */
  295.     public VOID_POINTER
  296. ecalloc(count, size)
  297.     int count;
  298.     unsigned int size;
  299. {
  300.     register VOID_POINTER p;
  301.  
  302.     p = (VOID_POINTER) calloc(count, size);
  303.     if (p != NULL)
  304.         return (p);
  305.     error("Cannot allocate memory", NULL_PARG);
  306.     quit(QUIT_ERROR);
  307.     /*NOTREACHED*/
  308. }
  309.  
  310. /*
  311.  * Skip leading spaces in a string.
  312.  */
  313.     public char *
  314. skipsp(s)
  315.     register char *s;
  316. {
  317.     while (*s == ' ' || *s == '\t')    
  318.         s++;
  319.     return (s);
  320. }
  321.  
  322. /*
  323.  * Exit the program.
  324.  */
  325.     public void
  326. quit(status)
  327.     int status;
  328. {
  329.     static int save_status;
  330.  
  331.     /*
  332.      * Put cursor at bottom left corner, clear the line,
  333.      * reset the terminal modes, and exit.
  334.      */
  335.     if (status < 0)
  336.         status = save_status;
  337.     else
  338.         save_status = status;
  339.     quitting = 1;
  340.     edit((char*)NULL);
  341.     if (any_display && is_tty)
  342.         clear_bot();
  343.     deinit();
  344.     flush();
  345.     raw_mode(0);
  346. #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
  347.     /* 
  348.      * If we don't close 2, we get some garbage from
  349.      * 2's buffer when it flushes automatically.
  350.      * I cannot track this one down  RB
  351.      * The same bug shows up if we use ^C^C to abort.
  352.      */
  353.     close(2);
  354. #endif
  355.     close_getchr();
  356.     exit(status);
  357. }
  358.