|
|
1.1 ! root 1: /* ! 2: * This program is in public domain; written by Dave G. Conroy. ! 3: * This file contains the main driving routine, and some keyboard processing ! 4: * code, for the MicroEMACS screen editor. ! 5: * Modified by W. L. Sheldon for use with the COHERENT Operating System - ! 6: * VT100 terminal key bindings. ! 7: */ ! 8: ! 9: #include <stdio.h> ! 10: #include "ed.h" ! 11: ! 12: #if VMS ! 13: #include <ssdef.h> ! 14: #define GOOD (SS$_NORMAL) ! 15: #define BAD (SS$_ABORT) ! 16: #endif ! 17: ! 18: #ifndef GOOD ! 19: #define GOOD 0 ! 20: #define BAD 1 ! 21: #endif ! 22: ! 23: int currow; /* Working cursor row */ ! 24: int curcol; /* Working cursor column */ ! 25: int curgoal; /* Goal column */ ! 26: BUFFER *curbp; /* Current buffer */ ! 27: WINDOW *curwp; /* Current window */ ! 28: BUFFER *bheadp; /* BUFFER listhead */ ! 29: WINDOW *wheadp; /* WINDOW listhead */ ! 30: BUFFER *blistp; /* Buffer list BUFFER */ ! 31: #if LIBHELP ! 32: BUFFER *helpbp; /* Help buffer */ ! 33: #endif ! 34: BUFFER *errbp; /* Error file BUFFER */ ! 35: uchar pat[NPAT]; /* Pattern */ ! 36: ! 37: uchar errfile[NFILEN]; /* Error file name */ ! 38: ! 39: #if LIBHELP ! 40: uchar *helpfile=0; /* Help file name ptr. */ ! 41: uchar *helpindex=0; /* Help index file name ptr. */ ! 42: uchar hfname[NFILEN]; /* Help file name place */ ! 43: uchar hiname[NFILEN]; /* Help index file name place */ ! 44: #endif ! 45: extern char *strcpy(); /* copy string */ ! 46: extern char *getenv(); ! 47: ! 48: /* ! 49: * File-name list for command line... ! 50: */ ! 51: uchar *cfiles[NCFILES]; /* Command line specified files */ ! 52: int cfilecnt; /* File count... */ ! 53: ! 54: /* ! 55: * Command line switch flags... ! 56: */ ! 57: unsigned int runswitch; ! 58: ! 59: #if LK201 ! 60: /* ! 61: * Mapping table for all of the funny keys with the numeric parameters ! 62: * on the LK201. ! 63: * Indexed by the code, which is between 0 (unused) and 34 (F20). ! 64: * An entry of 0 means no mapping. The map goes to command keys. ! 65: * If I had a "special" bit, I could use the code in the escape sequence ! 66: * as a key code, and return (for example) "do" as SPECIAL + 29. ! 67: * Then the dispatch would be done by the default keymap. This is probably a ! 68: * better way to go. ! 69: */ ! 70: short lkmap[] = { ! 71: #if EXKEYS ! 72: 0, ! 73: FN18, /* 1 Find */ ! 74: FN19, /* 2 Insert here */ ! 75: FN1A, /* 3 Remove */ ! 76: FN1B, /* 4 Select */ ! 77: FN1C, /* 5 Previous screen */ ! 78: FN1D, /* 6 Next screen */ ! 79: 0, ! 80: 0, ! 81: 0, ! 82: FN17, /* 10 Compose */ ! 83: 0, ! 84: FN3, /* 12 Print screen */ ! 85: 0, ! 86: FN4, /* 14 F4 */ ! 87: 0, ! 88: 0, ! 89: FN6, /* 17 F6 */ ! 90: FN7, /* 18 F7 */ ! 91: FN8, /* 19 F8 */ ! 92: FN9, /* 20 F9 */ ! 93: FNA, /* 21 F10 */ ! 94: 0, ! 95: 0, ! 96: 0, ! 97: 0, ! 98: FNE, /* 26 F14 */ ! 99: 0, ! 100: FN15, /* 28 Help */ ! 101: FN16, /* 29 Do C-X E */ ! 102: 0, ! 103: FN11, /* 31 F17 C-X P */ ! 104: FN12, /* 32 F18 C-X N */ ! 105: FN13, /* 33 F19 C-X Z */ ! 106: FN14 /* 34 F20 C-X C-Z */ ! 107: #else ! 108: 0, ! 109: OBND|CTRL|'S', /* 1 Find */ ! 110: OBND|CTRL|'Y', /* 2 Insert here */ ! 111: OBND|CTRL|'W', /* 3 Remove */ ! 112: OBND|CTRL|'@', /* 4 Select */ ! 113: OBND|META|'V', /* 5 Previous screen */ ! 114: OBND|CTRL|'V', /* 6 Next screen */ ! 115: 0, ! 116: 0, ! 117: 0, ! 118: 0, /* 10 Compose */ ! 119: 0, ! 120: 0, /* 12 Print screen */ ! 121: 0, ! 122: 0, /* 14 F4 */ ! 123: 0, ! 124: 0, ! 125: 0, /* 17 F6 */ ! 126: 0, /* 18 F7 */ ! 127: 0, /* 19 F8 */ ! 128: 0, /* 20 F9 */ ! 129: 0, /* 21 F10 */ ! 130: 0, ! 131: 0, ! 132: 0, ! 133: 0, ! 134: 0, /* 26 F14 */ ! 135: 0, ! 136: 0, /* 28 Help */ ! 137: OBND|PFX1|'E', /* 29 Do C-X E */ ! 138: 0, ! 139: OBND|PFX1|'P', /* 31 F17 C-X P */ ! 140: OBND|PFX1|'N', /* 32 F18 C-X N */ ! 141: OBND|PFX1|'Z', /* 33 F19 C-X Z */ ! 142: OBND|PFX1|CTRL|'Z' /* 34 F20 C-X C-Z */ ! 143: #endif ! 144: }; ! 145: #endif ! 146: ! 147: main(argc, argv) ! 148: uchar *argv[]; ! 149: { ! 150: register int c; ! 151: register int f; ! 152: register int n; ! 153: uchar bname[NBUFN]; ! 154: ! 155: #if MSDOS ! 156: setkeys(); ! 157: #endif ! 158: #if IBM ! 159: vidnit(); ! 160: #endif ! 161: for (c = 0; c < MAXREB; c++) /* nothing in the new table */ ! 162: bind.table[c].k_synonym = bind.table[c].k_code = -1; ! 163: runswitch = 0; /* Initialize the switches */ ! 164: bind.ffold = FALSE; /* initialize the fold flg */ ! 165: bind.bracket = 1; /* initialize bracket mode */ ! 166: bind.pfx1 = CTRL|'X'; /* initialize prefix keys */ ! 167: bind.pfx2 = bind.pfx3 = -1; ! 168: bind.repeat = CTRL|'U'; ! 169: argproc(argc, argv); /* Parse the arg list */ ! 170: #if GEM ! 171: if (runswitch & CF_GRABMEM) /* Get largest chunk of */ ! 172: grabmem(0, 0); /* memory (ST only) */ ! 173: #endif ! 174: topen(); /* Force the length setup */ ! 175: strcpy(bname, "main"); /* Work out the name of */ ! 176: if (cfilecnt > 0) /* the default buffer. */ ! 177: makename(bname, cfiles[0]); /* Make a buffer name */ ! 178: edinit(bname); /* Buffers, windows. */ ! 179: vtinit(); /* Displays. */ ! 180: if (cfilecnt > 0) { /* If there are files */ ! 181: update(); /* You have to update */ ! 182: readin(cfiles[0]); /* in case "[New file]" */ ! 183: } ! 184: if (cfilecnt > 1) { /* If more than one */ ! 185: n = (term.t_nrow - cfilecnt - 1) / cfilecnt; ! 186: for (c = 1; c < cfilecnt ; c++) { /* For all other files... */ ! 187: splitwind(0,0); /* Split this window... */ ! 188: if ((f=curwp->w_ntrows-n) != 0) ! 189: shrinkwind(0,f); /* Even out the windows */ ! 190: nextwind(0,0); /* Go on to the next one */ ! 191: visitfile(cfiles[c]); /* Read in that file */ ! 192: } ! 193: } ! 194: if ((runswitch & CF_ERROR) != 0) { ! 195: splitwind(0,0); /* Split this window */ ! 196: f = curwp->w_ntrows - ERRLINES; /* Make error window small */ ! 197: if (f > 0) ! 198: shrinkwind(0,f); ! 199: readerr(); ! 200: nextwind(); ! 201: mlerase(); ! 202: update(); ! 203: nexterr(0,1); ! 204: update(); ! 205: } ! 206: lastflag = 0; /* Fake last flags. */ ! 207: if (NULL != bind.macs[MAXMAC]) /* initialization macro */ ! 208: doMac(bind.macs + MAXMAC, FALSE, 1); ! 209: ! 210: for (;;) { ! 211: update(); /* Fix up the screen */ ! 212: c = getbind(0); /* Get a key */ ! 213: if (mpresf != FALSE) { /* If a message there */ ! 214: mlerase(); /* get rid of it... */ ! 215: update(); /* Fix screen */ ! 216: if (c == ' ') /* ITS EMACS does this */ ! 217: continue; /* (eat a space) */ ! 218: } ! 219: f = FALSE; ! 220: n = 1; ! 221: if (c == bind.repeat) { /* ^U, start argument */ ! 222: int ctmp; ! 223: ! 224: f = TRUE; /* We have a count */ ! 225: n = getnum("Arg", 4, &ctmp); /* get the count */ ! 226: c = ctmp; /* And get the last chr */ ! 227: } ! 228: if (kbdmip != NULL) { /* Save macro strokes. */ ! 229: if (kbdmip > (kbdm + ((NKBDM - 3)/2))) { ! 230: ctrlg(FALSE, 0); ! 231: continue; ! 232: } ! 233: if (f != FALSE) { ! 234: *kbdmip++ = bind.repeat; ! 235: *kbdmip++ = n; ! 236: } ! 237: *kbdmip++ = c; ! 238: } ! 239: bracketoff(); ! 240: execute(c, f, n); /* Do it. */ ! 241: } ! 242: } ! 243: ! 244: /* ! 245: * Initialize all of the buffers and windows. ! 246: * The buffer name is passed down as an argument, because the main routine may ! 247: * have been told to read in a file by default, and we want the buffer name to ! 248: * be right. ! 249: */ ! 250: edinit(bname) ! 251: uchar bname[]; ! 252: { ! 253: register BUFFER *bp; ! 254: register WINDOW *wp; ! 255: ! 256: bp = bfind(bname, TRUE, 0); /* First buffer */ ! 257: blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */ ! 258: #if LIBHELP ! 259: helpbp = bfind("[Help]", TRUE, BFTEMP|BFHELP); /* Help buffer */ ! 260: #endif ! 261: wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */ ! 262: if (bp==NULL || wp==NULL || blistp==NULL) ! 263: abort(); ! 264: curbp = bp; /* Make this current */ ! 265: wheadp = wp; ! 266: curwp = wp; ! 267: wp->w_wndp = NULL; /* Initialize window */ ! 268: wp->w_bufp = bp; ! 269: bp->b_nwnd = 1; /* Displayed. */ ! 270: wp->w_linep = bp->b_linep; ! 271: wp->w_dotp = bp->b_linep; ! 272: wp->w_doto = 0; ! 273: wp->w_markp = NULL; ! 274: wp->w_marko = 0; ! 275: wp->w_toprow = 0; ! 276: wp->w_ntrows = term.t_nrow-1; /* "-1" for mode line. */ ! 277: wp->w_force = 0; ! 278: wp->w_flag = WFMODE|WFHARD; /* Full. */ ! 279: } ! 280: ! 281: ! 282: /* ! 283: * Read in a key. Do the standard keyboard preprocessing. ! 284: * Convert the keys to the internal character set. On the LK201, which lacks ! 285: * a reasonable ESC key, make the grave accent a meta key too; this is a fairly ! 286: * common customization around Digital. Also read and decode the arrow keys, ! 287: * and other special keys. This is done in Rainbow mode; does this work on all ! 288: * the terminals with LK201 keyboards? ! 289: */ ! 290: getkey() ! 291: { ! 292: register int c; ! 293: #if LK201 ! 294: register int n; ! 295: for (;;) { ! 296: if ((c = tgetc()) == AGRAVE) /* Alternate M- prefix. */ ! 297: return (META | getCtl()); ! 298: if (c == METACH) { /* M-, or special key. */ ! 299: if ((c = tgetc()) == '[') { /* Arrows and extras. */ ! 300: switch (c = tgetc()) { ! 301: case 'A': ! 302: return (OBND | CTRL | 'P'); ! 303: case 'B': ! 304: return (OBND | CTRL | 'N'); ! 305: case 'C': ! 306: return (OBND | CTRL | 'F'); ! 307: case 'D': ! 308: return (OBND | CTRL | 'B'); ! 309: } ! 310: if (c >= '0' && c <= '9') { ! 311: n = 0; ! 312: do { ! 313: n = 10*n + c - '0'; ! 314: } ! 315: while ((c = tgetc()) >= '0' && c <= '9'); ! 316: if (c == '~' && n <= 34 && (c = lkmap[n])) ! 317: return (c); ! 318: } ! 319: continue; ! 320: } ! 321: if (c == 'O') { ! 322: switch (tgetc()) { ! 323: case 'P': /* PF1 => M-X (Future) */ ! 324: return (OBND | META | 'X'); ! 325: case 'Q': /* PF2 => C-Q */ ! 326: return (OBND | CTRL | 'Q'); ! 327: case 'R': /* PF3 => C-S */ ! 328: return (OBND | CTRL | 'S'); ! 329: case 'S': /* PF4 => C-R */ ! 330: return (OBND | CTRL | 'R'); ! 331: } ! 332: continue; ! 333: } ! 334: return (META | toCtl(c)); ! 335: } ! 336: break; ! 337: } ! 338: #else ! 339: #if VT100 ! 340: for (;;) { ! 341: if ((c = tgetc()) == METACH) { /* Apply M- prefix */ ! 342: if ((c = tgetc()) == '[') { /* Arrow keys. */ ! 343: switch (tgetc()) { ! 344: case 'A': ! 345: return (OBND | CTRL | 'P'); ! 346: case 'B': ! 347: return (OBND | CTRL | 'N'); ! 348: case 'C': ! 349: return (OBND | CTRL | 'F'); ! 350: case 'D': ! 351: return (OBND | CTRL | 'B'); ! 352: case 'P': ! 353: return (OBND | CTRL | 'D'); /* DEL key */ ! 354: case 'H': ! 355: return (OBND | CTRL | 'A'); /* HOME key */ ! 356: case '1': ! 357: switch (tgetc()) { ! 358: case 'x': ! 359: return (OBND | META | '?'); /* F1 help C/ASM word */ ! 360: case 'y': ! 361: return (OBND | PFX1 | '2'); /* Alt-F1 open 2nd window */ ! 362: } ! 363: case '2': ! 364: switch (tgetc()) { ! 365: case '4': ! 366: if ((tgetc()) == 'H') ! 367: return (OBND | CTRL | 'E'); /* END key */ ! 368: case 'x': ! 369: return (OBND | PFX1 | CTRL | 'V'); /* new file F2 */ ! 370: } ! 371: case 'V': ! 372: return (OBND | META | 'V'); /* PGUP key */ ! 373: case 'U': ! 374: return (OBND | CTRL | 'V'); /* PGDN key */ ! 375: case '3': ! 376: switch (tgetc()) { ! 377: case 'x': ! 378: return (OBND | META | 'S'); /* F3 search forward */ ! 379: case 'y': ! 380: return (OBND | META | '/'); /* ALT-F3 cont search */ ! 381: } ! 382: case '4': ! 383: tgetc(); ! 384: return (OBND | META | 'R'); /* F4 search backward */ ! 385: case '5': ! 386: tgetc(); ! 387: return (OBND | META | '%'); /* F5 search & replace */ ! 388: case '6': ! 389: tgetc(); ! 390: return (OBND | PFX1 | 'N'); /* F6 next window */ ! 391: case '8': ! 392: tgetc(); ! 393: return (OBND | CTRL | 'Z'); /* F8 save/exit */ ! 394: case '0': ! 395: switch (tgetc()) { ! 396: case 'x': ! 397: return (OBND | PFX1 | '1'); /* F10 close other wndws */ ! 398: case 'y': ! 399: return (OBND | META | 'J'); ! 400: } ! 401: } ! 402: continue; ! 403: } ! 404: if (c == 'O') { /* function keys */ ! 405: switch (tgetc()) { ! 406: case 'P': /* PF1 => M-X (Future) */ ! 407: return (OBND | META | 'X'); ! 408: case 'Q': /* PF2 => C-Q */ ! 409: return (OBND | CTRL | 'Q'); ! 410: case 'R': /* PF3 => C-S */ ! 411: return (OBND | CTRL | 'S'); ! 412: case 'S': /* PF4 => C-R */ ! 413: return (OBND | CTRL | 'R'); ! 414: } ! 415: continue; ! 416: } ! 417: return (META | toCtl(c)); ! 418: } ! 419: break; ! 420: } ! 421: #else ! 422: if ((c = tgetc()) == METACH) /* Apply M- prefix */ ! 423: return (META | getCtl()); ! 424: #endif ! 425: #endif ! 426: if (c == 0x0D && bind.autoindent) ! 427: return (OBND | CTRL | 'J'); ! 428: if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */ ! 429: return (CTRL | '@' | c); ! 430: return (c); ! 431: } ! 432: ! 433: /* ! 434: * Apply control modifications to a key ! 435: */ ! 436: toCtl(c) ! 437: register int c; ! 438: { ! 439: if (c>='a' && c<='z') /* Force to upper */ ! 440: return (c - 0x20); ! 441: if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ ! 442: return (c | CTRL | '@'); ! 443: return (c); ! 444: } ! 445: ! 446: getCtl() ! 447: { ! 448: return (toCtl(tgetc())); ! 449: } ! 450: ! 451: /* ! 452: * Fancy quit command, as implemented by Norm. ! 453: * If the current buffer has changed do a write current buffer and exit emacs, ! 454: * otherwise simply exit. ! 455: */ ! 456: quickexit(f, n) ! 457: { ! 458: if ((curbp->b_flag&BFCHG) != 0 /* Changed. */ ! 459: && (curbp->b_flag&(BFTEMP|BFERROR|BFNOWRT)) == 0) ! 460: /* Real and not R/O... */ ! 461: filesave(f, n); ! 462: quit(f, n); /* conditionally quit */ ! 463: } ! 464: ! 465: /* ! 466: * Quit command. If an argument, always quit. Otherwise confirm ! 467: * if a buffer has been changed and not written out. ! 468: * Normally bound to "C-X C-C". ! 469: */ ! 470: quit(f, n) ! 471: { ! 472: register int s = FALSE; ! 473: ! 474: if (f != FALSE /* Argument forces it. */ ! 475: || anycb() == FALSE /* All buffers clean. */ ! 476: || (s=mlyesno("Quit")) == TRUE) { /* User says it's OK. */ ! 477: vttidy(); ! 478: #if MSDOS ! 479: resetkeys(); ! 480: #endif ! 481: if (f != FALSE || s != FALSE) ! 482: exit(BAD); ! 483: else ! 484: exit(GOOD); ! 485: } ! 486: #if MSDOS ! 487: setkeys(); ! 488: #endif ! 489: return (s); ! 490: } ! 491: ! 492: /* ! 493: * Get binding char. Turn prefix chars into or'ed bits. ! 494: */ ! 495: getbind(bound) ! 496: register int bound; ! 497: { ! 498: register int c; ! 499: ! 500: if (((c = getkey()) == bind.pfx1) && !(bound & PFX1)) ! 501: return (PFX1 | toCtl(getbind(bound | PFX1))); ! 502: if ((c == bind.pfx2) && !(bound & PFX2)) ! 503: return (PFX2 | toCtl(getbind(bound | PFX2))); ! 504: if ((c == bind.pfx3) && !(bound & PFX3)) ! 505: return (PFX3 | toCtl(getbind(bound | PFX3))); ! 506: return (c); ! 507: } ! 508: ! 509: /* ! 510: * Abort. ! 511: * Beep the beeper. ! 512: * Kill off any keyboard macro, ! 513: * etc., that is in progress. ! 514: * Sometimes called as a routine, ! 515: * to do general aborting of ! 516: * stuff. ! 517: */ ! 518: ctrlg(f, n) ! 519: { ! 520: tbeep(); ! 521: if (kbdmip != NULL) { ! 522: if (NULL != kbdm) { ! 523: free(kbdm); ! 524: kbdm = NULL; ! 525: } ! 526: kbdmip = NULL; ! 527: } ! 528: return (ABORT); ! 529: } ! 530: ! 531: #if MSDOS ! 532: setkeys() /* redefine cursor keys */ ! 533: /* so that they make */ ! 534: /* sense to microEMACS */ ! 535: /* as described in IBM */ ! 536: /* DOS tech. reference */ ! 537: /* manual */ ! 538: { ! 539: #if !IBM ! 540: static uchar *ctlseq[] = { ! 541: "\033[0;72;16p", /* up = <ctrl-p> */ ! 542: "\033[0;77;6p", /* right = <ctrl-f> */ ! 543: "\033[0;75;2p", /* left = <ctrl-b> */ ! 544: "\033[0;80;14p", /* down = <ctrl-n> */ ! 545: "\033[0;81;22p", /* pg dn = <ctrl-v> */ ! 546: "\033[0;73;27;86p", /* pg up = <esc>V */ ! 547: "\033[0;71;27;60p", /* home = <esc>< */ ! 548: "\033[0;79;27;62p", /* end = <esc>> */ ! 549: "\033[0;83;127p", /* del = del */ ! 550: "\033[0;3;27;46p", /* <ctrl-@> = <exc>. */ ! 551: NULL ! 552: }; ! 553: register uchar **ctlp; ! 554: ! 555: for (ctlp = ctlseq; NULL != *ctlp; ctlp++) ! 556: mlwrite(*ctlp); ! 557: #endif ! 558: } ! 559: ! 560: ! 561: ! 562: resetkeys() /* redefine cursor keys */ ! 563: /* to default values */ ! 564: { ! 565: #if !IBM ! 566: static uchar *ctlseq[] = { ! 567: "\033[0;72;0;72p", ! 568: "\033[0;77;0;77p", ! 569: "\033[0;75;0;75p", ! 570: "\033[0;80;0;80p", ! 571: "\033[0;81;0;81p", ! 572: "\033[0;73;0;73p", ! 573: "\033[0;71;0;71p", ! 574: "\033[0;79;0;79p", ! 575: "\033[0;83;0;83p", ! 576: "\033[0;3;0;3p", ! 577: NULL ! 578: }; ! 579: register uchar **ctlp; ! 580: ! 581: for (ctlp = ctlseq; NULL != *ctlp; ctlp++) ! 582: mlwrite(*ctlp); ! 583: #endif ! 584: } ! 585: #endif ! 586: ! 587: argproc(argc, argv) ! 588: int argc; ! 589: uchar **argv; ! 590: { ! 591: int i; ! 592: uchar *flexn; ! 593: extern uchar *flexName(); ! 594: uchar *ptr; ! 595: ! 596: if (!bind.tabsiz && ! 597: (NULL == (ptr = getenv("TABSIZ")) || ! 598: !(bind.tabsiz = atoi(ptr)))) ! 599: bind.tabsiz = 8; ! 600: cfilecnt = 0; ! 601: flexn = NULL; ! 602: for (i = 1; i < argc; i++) { ! 603: ptr = argv[i]; /* Get this argument... */ ! 604: if (*ptr == '-') { /* Is this a switch? */ ! 605: switch (ptr[1]) { ! 606: case 'd': ! 607: runswitch |= CF_DEBUG; ! 608: break; ! 609: case 'e': ! 610: runswitch |= CF_ERROR; ! 611: if (ptr[2] == 0) { ! 612: if (++i == argc) { ! 613: runswitch &= ~CF_ERROR; ! 614: continue; ! 615: } ! 616: strcpy(errfile, argv[i]); ! 617: } ! 618: else { ! 619: strcpy(errfile, &ptr[2]); ! 620: } ! 621: break; ! 622: case 'f': ! 623: if (ptr[2] == 0) { ! 624: if (++i == argc) ! 625: continue; ! 626: flexn = argv[i]; ! 627: } ! 628: else ! 629: flexn = ptr + 1; ! 630: break; ! 631: #if LIBHELP ! 632: case 'h': /* Alternate help */ ! 633: if (ptr[2] == 0) { ! 634: if (++i == argc) { ! 635: continue; ! 636: } ! 637: strcpy(hfname, argv[i]); ! 638: } ! 639: else { ! 640: strcpy(hfname, &ptr[2]); ! 641: } ! 642: strcpy(hiname, hfname); ! 643: #if GEM || MSDOS ! 644: strcat(hfname, ".hlp"); ! 645: #endif ! 646: strcat(hiname, ".idx"); ! 647: helpfile = hfname; ! 648: helpindex = hiname; ! 649: break; ! 650: #endif ! 651: case 'w': ! 652: runswitch |= CF_WARN; ! 653: break; ! 654: #if NATIVE && GEM ! 655: case 'l': /* long screen */ ! 656: runswitch |= CF_LONGSCR; ! 657: break; ! 658: case 't': /* very long screen */ ! 659: runswitch |= CF_VLONG; ! 660: break; ! 661: #endif ! 662: #if GEM ! 663: case 'x': /* grab all memory */ ! 664: runswitch |= CF_GRABMEM; ! 665: break; ! 666: #endif ! 667: default: ! 668: break; ! 669: } ! 670: /* Process this switch */ ! 671: } ! 672: else { /* Otherwise... */ ! 673: if (cfilecnt >= NCFILES) ! 674: continue; ! 675: cfiles[cfilecnt++] = ptr; /* This is a file. */ ! 676: #if GEM ! 677: fixname(cfiles[cfilecnt-1]); ! 678: #endif ! 679: } ! 680: } ! 681: if (NULL == flexn) ! 682: loadBup(flexName(), TRUE); ! 683: else ! 684: loadBup(flexn, ABORT); ! 685: } ! 686: ! 687: #if EXKEYS ! 688: /* ! 689: * Do nothing. ("Dead") ! 690: */ ! 691: ignore() ! 692: { ! 693: return TRUE; ! 694: } ! 695: #endif ! 696: ! 697: /* ! 698: * Get a numeric argument... ! 699: */ ! 700: getnum(prompt, n, lastc) ! 701: register uchar *prompt; ! 702: register int n; ! 703: register int *lastc; ! 704: { ! 705: register int mflag = 0; ! 706: register int c; ! 707: ! 708: mflag = 0; /* that can be discarded. */ ! 709: mlwrite("%s: %d", prompt, n); ! 710: while ((c = getbind(0)) >='0' && c<='9' ! 711: || c==bind.repeat || c=='-'){ ! 712: if (c == bind.repeat) ! 713: n = n*4; ! 714: /* ! 715: * If dash, and start of argument string, set arg. ! 716: * to -1. Otherwise, insert it. ! 717: */ ! 718: else if (c == '-') { ! 719: if (mflag) ! 720: break; ! 721: n = 0; ! 722: mflag = -1; ! 723: } ! 724: /* ! 725: * If first digit entered, replace previous argument ! 726: * with digit and set sign. Otherwise, append to arg. ! 727: */ ! 728: else { ! 729: if (!mflag) { ! 730: n = 0; ! 731: mflag = 1; ! 732: } ! 733: n = 10*n + c - '0'; ! 734: } ! 735: mlwrite("%s: %d", prompt, (mflag >=0) ? n : (n ? -n : -1)); ! 736: } ! 737: *lastc = c; /* Return the terminal char. */ ! 738: /* ! 739: * Make arguments preceded by a minus sign negative and change ! 740: * the special argument "^U -" to an effective "^U -1". ! 741: */ ! 742: if (mflag == -1) { ! 743: if (n == 0) ! 744: n++; ! 745: n = -n; ! 746: } ! 747: return n; ! 748: } ! 749: ! 750: #if GEM ! 751: /* ! 752: * The following routine gets around a problem with GEMDOS Malloc(), ! 753: * it forces a single, very large Malloc() so very large files can ! 754: * be read. ! 755: * It is available only on the Atari ST, and is bound to M-+ ! 756: * it can also be specified using the -x switch ! 757: */ ! 758: #include <osbind.h> ! 759: ! 760: grabmem(f, n) ! 761: int f, n; ! 762: { ! 763: extern char *lmalloc(); ! 764: register char *p = NULL; ! 765: register long t; ! 766: ! 767: t = Malloc(-1L); /* How big is free memory? */ ! 768: while (p == NULL) { /* Until we have a block */ ! 769: t -= 4096L; /* shrink the block */ ! 770: if (t < 2048) { /* if too small, tell user */ ! 771: mlwrite( "[Cannot allocate memory]" ); ! 772: return 1; /* and fail */ ! 773: } ! 774: p = lmalloc(t); /* Try to get this chunk */ ! 775: } /* loop until success or fail */ ! 776: free(p); /* return chunk to arena */ ! 777: mlwrite( "[Allocated %ld bytes]", t ); /* tell user how much */ ! 778: return 0; /* and return success */ ! 779: } ! 780: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.