update copyright notice
[unix-history] / usr / src / usr.bin / more / main.c
CommitLineData
bfe13c81
KB
1/*
2 * Copyright (c) 1988 Mark Nudleman
3 * Copyright (c) 1988 Regents of the University of California.
4 * All rights reserved.
5 *
bfe13c81
KB
6 * Redistribution and use in source and binary forms are permitted
7 * provided that the above copyright notice and this paragraph are
8 * duplicated in all such forms and that any documentation,
9 * advertising materials, and other materials related to such
10 * distribution and use acknowledge that the software was developed
a942b40b
KB
11 * by Mark Nudleman and the University of California, Berkeley. The
12 * name of Mark Nudleman or the
bfe13c81
KB
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20#ifndef lint
21char copyright[] =
22"@(#) Copyright (c) 1988 Mark Nudleman.\n\
23@(#) Copyright (c) 1988 Regents of the University of California.\n\
24 All rights reserved.\n";
25#endif /* not lint */
26
27#ifndef lint
a942b40b 28static char sccsid[] = "@(#)main.c 5.7 (Berkeley) %G%";
bfe13c81
KB
29#endif /* not lint */
30
31/*
32 * Entry point, initialization, miscellaneous routines.
33 */
34
35#include "less.h"
36#include "position.h"
37
38public int ispipe;
39public char * first_cmd;
40public char * every_first_cmd;
41public int new_file;
42public int is_tty;
43public char *current_file;
44public char *previous_file;
45public POSITION prev_pos;
46public int any_display;
47public int scroll;
48public int ac;
49public char ** av;
50public int curr_ac;
51public int quitting;
52
53extern int file;
54extern int quit_at_eof;
55extern int cbufs;
56extern int errmsgs;
57
bfe13c81 58public char * editor;
bfe13c81 59
bfe13c81
KB
60extern char * tagfile;
61extern char * tagpattern;
62extern int tagoption;
bfe13c81 63
bfe13c81
KB
64/*
65 * Edit a new file.
66 * Filename "-" means standard input.
67 * No filename means the "current" file, from the command line.
68 */
69 public void
70edit(filename)
71 register char *filename;
72{
73 register int f;
74 register char *m;
75 POSITION initial_pos;
76 char message[100];
77 static int didpipe;
78
79 initial_pos = NULL_POSITION;
80 if (filename == NULL || *filename == '\0')
81 {
82 if (curr_ac >= ac)
83 {
84 error("No current file");
85 return;
86 }
87 filename = save(av[curr_ac]);
88 } else if (strcmp(filename, "#") == 0)
89 {
90 if (*previous_file == '\0')
91 {
92 error("no previous file");
93 return;
94 }
95 filename = save(previous_file);
96 initial_pos = prev_pos;
97 } else
98 filename = save(filename);
99
100 if (strcmp(filename, "-") == 0)
101 {
102 /*
103 * Use standard input.
104 */
105 if (didpipe)
106 {
107 error("Can view standard input only once");
108 return;
109 }
110 f = 0;
111 } else if ((m = bad_file(filename, message, sizeof(message))) != NULL)
112 {
113 error(m);
114 free(filename);
115 return;
116 } else if ((f = open(filename, 0)) < 0)
117 {
118 error(errno_message(filename, message, sizeof(message)));
119 free(filename);
120 return;
121 }
122
123 if (isatty(f))
124 {
125 /*
126 * Not really necessary to call this an error,
127 * but if the control terminal (for commands)
128 * and the input file (for data) are the same,
129 * we get weird results at best.
130 */
131 error("Can't take input from a terminal");
132 if (f > 0)
133 close(f);
134 free(filename);
135 return;
136 }
137
bfe13c81
KB
138 /*
139 * We are now committed to using the new file.
140 * Close the current input file and set up to use the new one.
141 */
142 if (file > 0)
143 close(file);
144 new_file = 1;
145 if (previous_file != NULL)
146 free(previous_file);
147 previous_file = current_file;
148 current_file = filename;
149 prev_pos = position(TOP);
150 ispipe = (f == 0);
151 if (ispipe)
152 didpipe = 1;
153 file = f;
154 ch_init(cbufs, 0);
155 init_mark();
156
157 if (every_first_cmd != NULL)
158 first_cmd = every_first_cmd;
159
160 if (is_tty)
161 {
162 int no_display = !any_display;
163 any_display = 1;
164 if (no_display && errmsgs > 0)
165 {
166 /*
167 * We displayed some messages on error output
168 * (file descriptor 2; see error() function).
169 * Before erasing the screen contents,
170 * display the file name and wait for a keystroke.
171 */
172 error(filename);
173 }
174 /*
175 * Indicate there is nothing displayed yet.
176 */
177 pos_clear();
178 if (initial_pos != NULL_POSITION)
179 jump_loc(initial_pos);
180 clr_linenum();
181 }
182}
183
184/*
185 * Edit the next file in the command line list.
186 */
187 public void
188next_file(n)
189 int n;
190{
191 if (curr_ac + n >= ac)
192 {
193 if (quit_at_eof)
194 quit();
195 error("No (N-th) next file");
196 } else
197 edit(av[curr_ac += n]);
198}
199
200/*
201 * Edit the previous file in the command line list.
202 */
203 public void
204prev_file(n)
205 int n;
206{
207 if (curr_ac - n < 0)
208 error("No (N-th) previous file");
209 else
210 edit(av[curr_ac -= n]);
211}
212
213/*
214 * Copy a file directly to standard output.
215 * Used if standard output is not a tty.
216 */
217 static void
218cat_file()
219{
220 register int c;
221
222 while ((c = ch_forw_get()) != EOI)
223 putchr(c);
224 flush();
225}
226
bfe13c81
KB
227/*
228 * Entry point.
229 */
230main(argc, argv)
231 int argc;
232 char *argv[];
233{
234 char *getenv();
235
236
237 /*
238 * Process command line arguments and LESS environment arguments.
239 * Command line arguments override environment arguments.
240 */
241 init_prompt();
242 init_option();
243 scan_option(getenv("LESS"));
244 argv++;
245 while ( (--argc > 0) &&
246 (argv[0][0] == '-' || argv[0][0] == '+') &&
247 argv[0][1] != '\0')
248 scan_option(*argv++);
249
bfe13c81
KB
250 editor = getenv("EDITOR");
251 if (editor == NULL || *editor == '\0')
252 editor = EDIT_PGM;
bfe13c81
KB
253
254 /*
255 * Set up list of files to be examined.
256 */
257 ac = argc;
258 av = argv;
259 curr_ac = 0;
260
261 /*
262 * Set up terminal, etc.
263 */
264 is_tty = isatty(1);
265 if (!is_tty)
266 {
267 /*
268 * Output is not a tty.
269 * Just copy the input file(s) to output.
270 */
271 if (ac < 1)
272 {
273 edit("-");
274 cat_file();
275 } else
276 {
277 do
278 {
279 edit((char *)NULL);
280 if (file >= 0)
281 cat_file();
282 } while (++curr_ac < ac);
283 }
284 exit(0);
285 }
286
287 raw_mode(1);
288 get_term();
289 open_getchr();
290 init();
291 init_cmd();
292
293 init_signals(1);
294
295 /*
296 * Select the first file to examine.
297 */
bfe13c81
KB
298 if (tagoption)
299 {
300 /*
301 * A -t option was given.
302 * Verify that no filenames were also given.
303 * Edit the file selected by the "tags" search,
304 * and search for the proper line in the file.
305 */
306 if (ac > 0)
307 {
308 error("No filenames allowed with -t option");
309 quit();
310 }
311 if (tagfile == NULL)
312 quit();
313 edit(tagfile);
314 if (file < 0)
315 quit();
316 if (tagsearch())
317 quit();
318 } else
bfe13c81
KB
319 if (ac < 1)
320 edit("-"); /* Standard input */
321 else
322 {
323 /*
324 * Try all the files named as command arguments.
325 * We are simply looking for one which can be
326 * opened without error.
327 */
328 do
329 {
330 edit((char *)NULL);
331 } while (file < 0 && ++curr_ac < ac);
332 }
333
334 if (file >= 0)
335 commands();
336 quit();
337 /*NOTREACHED*/
338}
339
340/*
341 * Copy a string, truncating to the specified length if necessary.
342 * Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
343 */
344 public void
345strtcpy(to, from, len)
346 char *to;
347 char *from;
348 unsigned int len;
349{
350 strncpy(to, from, len);
351 to[len-1] = '\0';
352}
353
354/*
355 * Copy a string to a "safe" place
c48c82c8 356 * (that is, to a buffer allocated by malloc).
bfe13c81
KB
357 */
358 public char *
359save(s)
360 char *s;
361{
c48c82c8 362 char *p, *strcpy(), *malloc();
bfe13c81 363
c48c82c8 364 p = malloc((u_int)strlen(s)+1);
bfe13c81
KB
365 if (p == NULL)
366 {
367 error("cannot allocate memory");
368 quit();
369 }
c48c82c8 370 return(strcpy(p, s));
bfe13c81
KB
371}
372
373/*
374 * Exit the program.
375 */
376 public void
377quit()
378{
379 /*
380 * Put cursor at bottom left corner, clear the line,
381 * reset the terminal modes, and exit.
382 */
383 quitting = 1;
bfe13c81
KB
384 lower_left();
385 clear_eol();
386 deinit();
387 flush();
388 raw_mode(0);
389 exit(0);
390}