386BSD 0.1 development
[unix-history] / usr / othersrc / public / less-177 / main.c
CommitLineData
89edd2cf
WJ
1/*
2 * Entry point, initialization, miscellaneous routines.
3 */
4
5#include "less.h"
6#include "position.h"
7
8public int ispipe;
9public char * every_first_cmd = NULL;
10public int new_file;
11public int is_tty;
12public IFILE curr_ifile = NULL_IFILE;
13public IFILE old_ifile = NULL_IFILE;
14public struct scrpos initial_scrpos;
15public int any_display = 0;
16public int scroll;
17public char * progname;
18public int quitting;
19
20extern int file;
21extern int quit_at_eof;
22extern int cbufs;
23extern int errmsgs;
24extern int screen_trashed;
25extern int force_open;
26
27#if LOGFILE
28public int logfile = -1;
29public int force_logfile = 0;
30public char * namelogfile = NULL;
31#endif
32
33#if EDITOR
34public char * editor;
35public char * editproto;
36#endif
37
38#if TAGS
39extern char * tagfile;
40extern char * tagpattern;
41extern int tagoption;
42#endif
43
44
45
46/*
47 * Entry point.
48 */
49main(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
184strtcpy(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 *
198save(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
209ecalloc(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 *
227skipsp(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
239quit(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}