source: trunk/minix/commands/elvis/main.c@ 21

Last change on this file since 21 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 10.0 KB
Line 
1/* main.c */
2
3/* Author:
4 * Steve Kirkendall
5 * 14407 SW Teal Blvd. #C
6 * Beaverton, OR 97005
7 * kirkenda@cs.pdx.edu
8 */
9
10
11/* This file contains the main() function of vi */
12
13/* HACK! bcc needs to disable use of precompiled headers for this file,
14 or else command line args will not be passed to elvis */
15#if __BORLANDC__
16#include "borland.h"
17#endif
18
19#include "config.h"
20#include <setjmp.h>
21#include "vi.h"
22
23extern trapint(); /* defined below */
24extern char *getenv();
25jmp_buf jmpenv;
26
27#ifndef NO_DIGRAPH
28static init_digraphs();
29#endif
30
31/*---------------------------------------------------------------------*/
32
33#if AMIGA
34# include "amiwild.c"
35main (argc, argv)
36#else
37# if VMS
38# include "vmswild.c"
39main (argc, argv)
40# else
41void main(argc, argv)
42# endif
43#endif
44 int argc;
45 char *argv[];
46{
47 int i;
48 char *cmd = (char *)0;
49 char *err = (char *)0;
50 char *str;
51 char *tag = (char *)0;
52
53 /* set mode to MODE_VI or MODE_EX depending on program name */
54 switch (argv[0][strlen(argv[0]) - 1])
55 {
56 case 'x': /* "ex" */
57 mode = MODE_EX;
58 break;
59
60 case 'w': /* "view" */
61 mode = MODE_VI;
62 *o_readonly = TRUE;
63 break;
64#ifndef NO_EXTENSIONS
65 case 't': /* "edit" or "input" */
66 mode = MODE_VI;
67 *o_inputmode = TRUE;
68 break;
69#endif
70 default: /* "vi" or "elvis" */
71 mode = MODE_VI;
72 }
73
74#ifndef DEBUG
75# ifdef SIGQUIT
76 /* normally, we ignore SIGQUIT. SIGINT is trapped later */
77 signal(SIGQUIT, SIG_IGN);
78# endif
79#endif
80
81 /* temporarily ignore SIGINT */
82 signal(SIGINT, SIG_IGN);
83
84 /* start curses */
85 initscr();
86 cbreak();
87 noecho();
88 scrollok(stdscr, TRUE);
89
90 /* arrange for deadly signals to be caught */
91# ifdef SIGHUP
92 signal(SIGHUP, (void(*)()) deathtrap);
93# endif
94# ifndef DEBUG
95# ifdef SIGILL
96 signal(SIGILL, (void(*)()) deathtrap);
97# endif
98# ifdef SIGBUS
99 signal(SIGBUS, (void(*)()) deathtrap);
100# endif
101# ifdef SIGSEGV
102 signal(SIGSEGV, (void(*)()) deathtrap);
103# endif
104# ifdef SIGSYS
105 signal(SIGSYS, (void(*)()) deathtrap);
106# endif
107# endif /* !DEBUG */
108# ifdef SIGPIPE
109 signal(SIGPIPE, (void(*)()) deathtrap);
110# endif
111# ifdef SIGTERM
112 signal(SIGTERM, (void(*)()) deathtrap);
113# endif
114# ifdef SIGUSR1
115 signal(SIGUSR1, (void(*)()) deathtrap);
116# endif
117# ifdef SIGUSR2
118 signal(SIGUSR2, (void(*)()) deathtrap);
119# endif
120
121 /* initialize the options - must be done after initscr(), so that
122 * we can alter LINES and COLS if necessary.
123 */
124 initopts();
125
126 /* map the arrow keys. The KU,KD,KL,and KR variables correspond to
127 * the :ku=: (etc.) termcap capabilities. The variables are defined
128 * as part of the curses package.
129 */
130 if (has_KU) mapkey(has_KU, "k", WHEN_VICMD|WHEN_INMV, "<Up>");
131 if (has_KD) mapkey(has_KD, "j", WHEN_VICMD|WHEN_INMV, "<Down>");
132 if (has_KL) mapkey(has_KL, "h", WHEN_VICMD|WHEN_INMV, "<Left>");
133 if (has_KR) mapkey(has_KR, "l", WHEN_VICMD|WHEN_INMV, "<Right>");
134 if (has_HM) mapkey(has_HM, "^", WHEN_VICMD|WHEN_INMV, "<Home>");
135 if (has_EN) mapkey(has_EN, "$", WHEN_VICMD|WHEN_INMV, "<End>");
136 if (has_PU) mapkey(has_PU, "\002", WHEN_VICMD|WHEN_INMV, "<PageUp>");
137 if (has_PD) mapkey(has_PD, "\006", WHEN_VICMD|WHEN_INMV, "<PageDn>");
138 if (has_KI) mapkey(has_KI, "i", WHEN_VICMD|WHEN_INMV, "<Insert>");
139#if MSDOS
140# if RAINBOW
141 if (!strcmp("rainbow", o_term))
142 {
143 mapkey("\033[1~", "/", WHEN_VICMD, "<Find>");
144 mapkey("\033[3~", "x", WHEN_VICMD|WHEN_INMV, "<Remove>");
145 mapkey("\033[4~", "v", WHEN_VICMD|WHEN_INMV, "<Select>");
146 mapkey("\033[17~", ":sh\n", WHEN_VICMD, "<Intrpt>");
147 mapkey("\033[19~", ":q\n", WHEN_VICMD, "<Cancel>");
148 mapkey("\033[21~", "ZZ", WHEN_VICMD, "<Exit>");
149 mapkey("\033[26~", "V", WHEN_VICMD|WHEN_INMV, "<AddlOp>");
150 mapkey("\033[28~", "\\", WHEN_VICMD|WHEN_INMV, "<Help>");
151 mapkey("\033[29~", "K", WHEN_VICMD|WHEN_INMV, "<Do>");
152 }
153 else
154# endif /* RAINBOW */
155 {
156 mapkey("#S", "x", WHEN_VICMD|WHEN_INMV, "<Delete>");
157 mapkey("#s", "B", WHEN_VICMD|WHEN_INMV, "^<Left>");
158 mapkey("#t", "W", WHEN_VICMD|WHEN_INMV, "^<Right>");
159 }
160#else /* not MSDOS */
161# if COHERENT
162 mapkey("\033[P", "x", WHEN_VICMD|WHEN_INMV, "<Del>");
163# else
164#if AMIGA
165 mapkey("\233?~", "\\", WHEN_VICMD|WHEN_INMV, "<Help>");
166#endif
167
168 if (ERASEKEY != '\177')
169 {
170 mapkey("\177", "x", WHEN_VICMD|WHEN_INMV, "<Del>");
171 }
172# endif
173#endif
174
175#ifndef NO_DIGRAPH
176 init_digraphs();
177#endif /* NO_DIGRAPH */
178
179 /* process any flags */
180 for (i = 1; i < argc && *argv[i] == '-'; i++)
181 {
182 switch (argv[i][1])
183 {
184 case 'R': /* readonly */
185 *o_readonly = TRUE;
186 break;
187
188 case 'L':
189 case 'r': /* recover */
190 msg("Use the `elvrec` program to recover lost files");
191 endmsgs();
192 refresh();
193 endwin();
194 exit(0);
195 break;
196
197 case 't': /* tag */
198 if (argv[i][2])
199 {
200 tag = argv[i] + 2;
201 }
202 else
203 {
204 tag = argv[++i];
205 }
206 break;
207
208 case 'v': /* vi mode */
209 mode = MODE_VI;
210 break;
211
212 case 'e': /* ex mode */
213 mode = MODE_EX;
214 break;
215#ifndef NO_EXTENSIONS
216 case 'i': /* input mode */
217 *o_inputmode = TRUE;
218 break;
219#endif
220#ifndef NO_ERRLIST
221 case 'm': /* use "errlist" as the errlist */
222 if (argv[i][2])
223 {
224 err = argv[i] + 2;
225 }
226 else if (i + 1 < argc)
227 {
228 err = argv[++i];
229 }
230 else
231 {
232 err = "";
233 }
234 break;
235#endif
236#ifndef CRUNCH
237 case 'c': /* run the following command, later */
238 if (argv[i][2])
239 {
240 cmd = argv[i] + 2;
241 }
242 else
243 {
244 cmd = argv[++i];
245 }
246 break;
247
248 case 'w': /* set the window size */
249 if (argv[i][2])
250 {
251 *o_window = atoi(argv[i] + 2);
252 wset = TRUE;
253 }
254 else
255 {
256 *o_window = atoi(argv[++i]);
257 wset = TRUE;
258 }
259 break;
260#endif
261 default:
262 msg("Ignoring unknown flag \"%s\"", argv[i]);
263 }
264 }
265
266 /* if we were given an initial ex command, save it... */
267 if (i < argc && *argv[i] == '+')
268 {
269 if (argv[i][1])
270 {
271 cmd = argv[i++] + 1;
272 }
273 else
274 {
275 cmd = "$"; /* "vi + file" means start at EOF */
276 i++;
277 }
278 }
279
280 /* the remaining args are file names. */
281 if (i < argc)
282 {
283 strcpy(args, argv[i]);
284 while (++i < argc && strlen(args) + 1 + strlen(argv[i]) < sizeof args)
285 {
286 strcat(args, " ");
287 strcat(args, argv[i]);
288 }
289#if MSDOS || TOS
290 /* expand wildcard characters, if necessary */
291 if (strchr(args, '*') || strchr(args, '?'))
292 {
293 strcpy(args, wildcard(args));
294 }
295#endif
296 strcpy(tmpblk.c, args);
297 cmd_args(MARK_UNSET, MARK_UNSET, CMD_ARGS, TRUE, tmpblk.c);
298 }
299 else
300 {
301 /* empty args list */
302 args[0] = '\0';
303 nargs = 1;
304 argno = -1;
305 }
306
307 /* perform the .exrc files and EXINIT environment variable */
308#ifdef SYSEXRC
309 doexrc(SYSEXRC);
310#endif
311#ifdef HMEXRC
312 str = getenv("HOME");
313 if (str && *str)
314 {
315 strcpy(tmpblk.c, str);
316 str = tmpblk.c + strlen(tmpblk.c);
317#if !VMS
318# if AMIGA /* Don't SLASH a device. "Elvis:.exrc" */
319 if (str[-1] != COLON && str[-1] != SLASH)
320# else
321 if (str[-1] != SLASH)
322# endif
323 {
324 *str++ = SLASH;
325 }
326#endif
327 strcpy(str, HMEXRC);
328 doexrc(tmpblk.c);
329 }
330#endif
331#ifndef CRUNCH
332 if (*o_exrc)
333#endif
334 {
335 doexrc(EXRC);
336 }
337#ifdef EXINIT
338 str = getenv(EXINIT);
339 if (str)
340 {
341 exstring(str, strlen(str), ctrl('V'));
342 }
343#endif
344
345 /* search for a tag (or an error) now, if desired */
346 blkinit();
347 if (tag)
348 {
349 cmd_tag(MARK_FIRST, MARK_FIRST, CMD_TAG, 0, tag);
350 }
351#ifndef NO_ERRLIST
352 else if (err)
353 {
354 cmd_errlist(MARK_FIRST, MARK_FIRST, CMD_ERRLIST, 0, err);
355 }
356#endif
357
358 /* if no tag/err, or tag failed, then start with first arg */
359 if (tmpfd < 0)
360 {
361 /* start with first arg */
362 cmd_next(MARK_UNSET, MARK_UNSET, CMD_NEXT, FALSE, "");
363
364 /* pretend to do something, just to force a recoverable
365 * version of the file out to disk
366 */
367 ChangeText
368 {
369 }
370 clrflag(file, MODIFIED);
371 }
372
373 /* now we do the immediate ex command that we noticed before */
374 if (cmd)
375 {
376 doexcmd(cmd);
377 }
378
379 /* repeatedly call ex() or vi() (depending on the mode) until the
380 * mode is set to MODE_QUIT
381 */
382 while (mode != MODE_QUIT)
383 {
384 if (setjmp(jmpenv))
385 {
386 /* Maybe we just aborted a change? */
387 abortdo();
388 }
389 signal(SIGINT, (void(*)()) trapint);
390
391 switch (mode)
392 {
393 case MODE_VI:
394 vi();
395 break;
396
397 case MODE_EX:
398 ex();
399 break;
400#ifdef DEBUG
401 default:
402 msg("mode = %d?", mode);
403 mode = MODE_QUIT;
404#endif
405 }
406 }
407
408 /* free up the cut buffers */
409 cutend();
410
411 /* end curses */
412#ifndef NO_CURSORSHAPE
413 if (has_CQ)
414 do_CQ();
415#endif
416 endmsgs();
417 move(LINES - 1, 0);
418 clrtoeol();
419 refresh();
420 endwin();
421
422 exit(0);
423 /*NOTREACHED*/
424}
425
426
427/*ARGSUSED*/
428int trapint(signo)
429 int signo;
430{
431 beep();
432 resume_curses(FALSE);
433 abortdo();
434#if OSK
435 sigmask(-1);
436#endif
437#if TURBOC || __GNUC__ || _ANSI
438 signal(signo, (void (*)())trapint);
439#else
440 signal(signo, trapint);
441#endif
442 doingglobal = FALSE;
443
444 longjmp(jmpenv, 1);
445
446 return 0;
447}
448
449
450
451#ifndef NO_DIGRAPH
452
453/* This stuff us used to build the default digraphs table. */
454static char digtable[][4] =
455{
456# ifdef CS_IBMPC
457 "C,\200", "u\"\1", "e'\2", "a^\3",
458 "a\"\4", "a`\5", "a@\6", "c,\7",
459 "e^\10", "e\"\211", "e`\12", "i\"\13",
460 "i^\14", "i`\15", "A\"\16", "A@\17",
461 "E'\20", "ae\21", "AE\22", "o^\23",
462 "o\"\24", "o`\25", "u^\26", "u`\27",
463 "y\"\30", "O\"\31", "U\"\32", "a'\240",
464 "i'!", "o'\"", "u'#", "n~$",
465 "N~%", "a-&", "o-'", "~?(",
466 "~!-", "\"<.", "\">/",
467# ifdef CS_SPECIAL
468 "2/+", "4/,", "^+;", "^q<",
469 "^c=", "^r>", "^t?", "pp]",
470 "^^^", "oo_", "*a`", "*ba",
471 "*pc", "*Sd", "*se", "*uf",
472 "*tg", "*Ph", "*Ti", "*Oj",
473 "*dk", "*Hl", "*hm", "*En",
474 "*No", "eqp", "pmq", "ger",
475 "les", "*It", "*iu", "*/v",
476 "*=w", "sq{", "^n|", "^2}",
477 "^3~", "^_\377",
478# endif /* CS_SPECIAL */
479# endif /* CS_IBMPC */
480# ifdef CS_LATIN1
481 "~!!", "a-*", "\">+", "o-:",
482 "\"<>", "~??",
483
484 "A`@", "A'A", "A^B", "A~C",
485 "A\"D", "A@E", "AEF", "C,G",
486 "E`H", "E'I", "E^J", "E\"K",
487 "I`L", "I'M", "I^N", "I\"O",
488 "-DP", "N~Q", "O`R", "O'S",
489 "O^T", "O~U", "O\"V", "O/X",
490 "U`Y", "U'Z", "U^[", "U\"\\",
491 "Y'_",
492
493 "a``", "a'a", "a^b", "a~c",
494 "a\"d", "a@e", "aef", "c,g",
495 "e`h", "e'i", "e^j", "e\"k",
496 "i`l", "i'm", "i^n", "i\"o",
497 "-dp", "n~q", "o`r", "o's",
498 "o^t", "o~u", "o\"v", "o/x",
499 "u`y", "u'z", "u^{", "u\"|",
500 "y'~",
501# endif /* CS_LATIN1 */
502 ""
503};
504
505static init_digraphs()
506{
507 int i;
508
509 for (i = 0; *digtable[i]; i++)
510 {
511 do_digraph(FALSE, digtable[i]);
512 }
513 do_digraph(FALSE, (char *)0);
514 return 0;
515}
516#endif /* NO_DIGRAPH */
Note: See TracBrowser for help on using the repository browser.