0
|
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 }
|