Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / miscellany / less-177 / main.c
1 /*
2  * Entry point, initialization, miscellaneous routines.
3  */
4
5 #include "less.h"
6 #include "position.h"
7
8 public int      ispipe;
9 public char *   every_first_cmd = NULL;
10 public int      new_file;
11 public int      is_tty;
12 public IFILE    curr_ifile = NULL_IFILE;
13 public IFILE    old_ifile = NULL_IFILE;
14 public struct scrpos initial_scrpos;
15 public int      any_display = 0;
16 public int      scroll;
17 public char *   progname;
18 public int      quitting;
19
20 extern int      file;
21 extern int      quit_at_eof;
22 extern int      cbufs;
23 extern int      errmsgs;
24 extern int      screen_trashed;
25 extern int      force_open;
26
27 #if LOGFILE
28 public int      logfile = -1;
29 public int      force_logfile = 0;
30 public char *   namelogfile = NULL;
31 #endif
32
33 #if EDITOR
34 public char *   editor;
35 public char *   editproto;
36 #endif
37
38 #if TAGS
39 extern char *   tagfile;
40 extern char *   tagpattern;
41 extern int      tagoption;
42 #endif
43
44
45
46 /*
47  * Entry point.
48  */
49 main(argc, argv)
50         int argc;
51         char *argv[];
52 {
53         IFILE h;
54         int nofiles;
55         extern char *getenv();
56
57         progname = *argv++;
58
59         /*
60          * Process command line arguments and LESS environment arguments.
61          * Command line arguments override environment arguments.
62          */
63         init_prompt();
64         init_charset();
65         init_option();
66         scan_option(getenv("LESS"));
67
68 #define isoptstring(s)  (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
69         while (--argc > 0 && (isoptstring(argv[0]) || isoptpending()))
70                 scan_option(*argv++);
71 #undef isoptstring
72
73         if (isoptpending())
74         {
75                 /*
76                  * Last command line option was a flag requiring a
77                  * following string, but there was no following string.
78                  */
79                 nopendopt();
80                 quit(0);
81         }
82
83 #if USERFILE
84         /*
85          * Try to use the lesskey file "$HOME/.less".
86          */
87         add_hometable();
88 #endif
89 #if EDITOR
90         editor = getenv("EDITOR");
91         if (editor == NULL || *editor == '\0')
92                 editor = EDIT_PGM;
93         editproto = getenv("LESSEDIT");
94         if (editproto == NULL || *editproto == '\0')
95                 editproto = "%E ?lm+%lm. %f";
96 #endif
97
98         /*
99          * Set up terminal, etc.
100          */
101         is_tty = isatty(1);
102         if (!is_tty)
103         {
104                 /*
105                  * Output is not a tty.
106                  * Just copy the input file(s) to output.
107                  */
108                 if (argc <= 0)
109                 {
110                         if (edit("-", 0) == 0)
111                                 cat_file();
112                 } else
113                 {
114                         while (--argc >= 0)
115                         {
116                                 if (edit(*argv++, 0) == 0)
117                                         cat_file();
118                         }
119                 }
120                 quit(0);
121         }
122
123         /*
124          * Call get_ifile with all the command line filenames
125          * to "register" them with the ifile system.
126          */
127         h = NULL_IFILE;
128         while (--argc >= 0)
129                 h = get_ifile(*argv++, h);
130
131         init_mark();
132         raw_mode(1);
133         get_term();
134         open_getchr();
135
136         init_signals(1);
137
138         /*
139          * Select the first file to examine.
140          */
141 #if TAGS
142         if (tagoption)
143         {
144                 /*
145                  * A -t option was given.
146                  * Verify that no filenames were also given.
147                  * Edit the file selected by the "tags" search,
148                  * and search for the proper line in the file.
149                  */
150                 if (nifile() > 0)
151                 {
152                         error("No filenames allowed with -t option", NULL_PARG);
153                         quit(1);
154                 }
155                 if (tagfile == NULL)
156                         quit(1);
157                 if (edit(tagfile, 0) || tagsearch())
158                         quit(1);
159                 nofiles = 0;
160         } else
161 #endif
162         if (nifile() == 0)
163                 nofiles = edit("-", 0); /* Standard input */
164         else 
165                 nofiles = edit_first();
166
167         if (nofiles)
168         {
169                 quit(1);
170                 /*NOTREACHED*/
171         }
172
173         init();
174         commands();
175         quit(0);
176         /*NOTREACHED*/
177 }
178
179 /*
180  * Copy a string, truncating to the specified length if necessary.
181  * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
182  */
183         public void
184 strtcpy(to, from, len)
185         char *to;
186         char *from;
187         unsigned int len;
188 {
189         strncpy(to, from, len);
190         to[len-1] = '\0';
191 }
192
193 /*
194  * Copy a string to a "safe" place
195  * (that is, to a buffer allocated by calloc).
196  */
197         public char *
198 save(s)
199         char *s;
200 {
201         register char *p;
202
203         p = (char *) ecalloc(strlen(s)+1, sizeof(char));
204         strcpy(p, s);
205         return (p);
206 }
207
208         public VOID_POINTER
209 ecalloc(count, size)
210         int count;
211         unsigned int size;
212 {
213         register VOID_POINTER p;
214
215         p = calloc(count, size);
216         if (p != NULL)
217                 return (p);
218         error("Cannot allocate memory", NULL_PARG);
219         quit(1);
220         /*NOTREACHED*/
221 }
222
223 /*
224  * Skip leading spaces in a string.
225  */
226         public char *
227 skipsp(s)
228         register char *s;
229 {
230         while (*s == ' ' || *s == '\t') 
231                 s++;
232         return (s);
233 }
234
235 /*
236  * Exit the program.
237  */
238         public void
239 quit(status)
240         int status;
241 {
242         static int save_status;
243
244         /*
245          * Put cursor at bottom left corner, clear the line,
246          * reset the terminal modes, and exit.
247          */
248         if (status < 0)
249                 status = save_status;
250         else
251                 save_status = status;
252         quitting = 1;
253 #if LOGFILE
254         end_logfile();
255 #endif
256         if (any_display)
257         {
258                 lower_left();
259                 clear_eol();
260         }
261         deinit();
262         flush();
263         raw_mode(0);
264 #if __MSDOS__
265         restore_screen();
266         /* 
267          * If we don't close 2, we get some garbage from
268          * 2's buffer when it flushes automatically.
269          * I cannot track this one down  RB
270          * The same bug shows up if we use ^C^C to abort.
271          */
272         close(2);
273 #endif
274         exit(status);
275 }