|
|
1.1 ! root 1: /* main.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 14407 SW Teal Blvd. #C ! 6: * Beaverton, OR 97005 ! 7: * [email protected] ! 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: ! 23: extern trapint(); /* defined below */ ! 24: extern char *getenv(); ! 25: jmp_buf jmpenv; ! 26: ! 27: #ifndef NO_DIGRAPH ! 28: static init_digraphs(); ! 29: #endif ! 30: ! 31: /*---------------------------------------------------------------------*/ ! 32: ! 33: #if AMIGA ! 34: # include "amiwild.c" ! 35: main (argc, argv) ! 36: #else ! 37: # if VMS ! 38: # include "vmswild.c" ! 39: main (argc, argv) ! 40: # else ! 41: void 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(exitcode); ! 423: /*NOTREACHED*/ ! 424: } ! 425: ! 426: ! 427: /*ARGSUSED*/ ! 428: int 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__ ! 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. */ ! 454: static 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: ! 505: static int 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.