|
|
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: #if _I386 ! 175: { ! 176: /* ! 177: * Speed up processing on 80386 for small files. ! 178: */ ! 179: char *junk; ! 180: ! 181: if (NULL != (junk = malloc(128L * 1024L))) ! 182: free(junk); ! 183: } ! 184: #endif ! 185: topen(); /* Force the length setup */ ! 186: strcpy(bname, "main"); /* Work out the name of */ ! 187: if (cfilecnt > 0) /* the default buffer. */ ! 188: makename(bname, cfiles[0]); /* Make a buffer name */ ! 189: edinit(bname); /* Buffers, windows. */ ! 190: vtinit(); /* Displays. */ ! 191: if (cfilecnt > 0) { /* If there are files */ ! 192: update(); /* You have to update */ ! 193: readin(cfiles[0]); /* in case "[New file]" */ ! 194: } ! 195: if (cfilecnt > 1) { /* If more than one */ ! 196: n = (term.t_nrow - cfilecnt - 1) / cfilecnt; ! 197: for (c = 1; c < cfilecnt ; c++) { /* For all other files... */ ! 198: splitwind(0,0); /* Split this window... */ ! 199: if ((f=curwp->w_ntrows-n) != 0) ! 200: shrinkwind(0,f); /* Even out the windows */ ! 201: nextwind(0,0); /* Go on to the next one */ ! 202: visitfile(cfiles[c]); /* Read in that file */ ! 203: } ! 204: } ! 205: if ((runswitch & CF_ERROR) != 0) { ! 206: splitwind(0,0); /* Split this window */ ! 207: f = curwp->w_ntrows - ERRLINES; /* Make error window small */ ! 208: if (f > 0) ! 209: shrinkwind(0,f); ! 210: readerr(); ! 211: nextwind(); ! 212: mlerase(); ! 213: update(); ! 214: nexterr(0,1); ! 215: update(); ! 216: } ! 217: lastflag = 0; /* Fake last flags. */ ! 218: if (NULL != bind.macs[MAXMAC]) /* initialization macro */ ! 219: doMac(bind.macs + MAXMAC, FALSE, 1); ! 220: ! 221: for (;;) { ! 222: update(); /* Fix up the screen */ ! 223: c = getbind(0); /* Get a key */ ! 224: if (mpresf != FALSE) { /* If a message there */ ! 225: mlerase(); /* get rid of it... */ ! 226: update(); /* Fix screen */ ! 227: if (c == ' ') /* ITS EMACS does this */ ! 228: continue; /* (eat a space) */ ! 229: } ! 230: f = FALSE; ! 231: n = 1; ! 232: if (c == bind.repeat) { /* ^U, start argument */ ! 233: int ctmp; ! 234: ! 235: f = TRUE; /* We have a count */ ! 236: n = getnum("Arg", 4, &ctmp); /* get the count */ ! 237: c = ctmp; /* And get the last chr */ ! 238: } ! 239: if (kbdmip != NULL) { /* Save macro strokes. */ ! 240: if (kbdmip > (kbdm + ((NKBDM - 3)/2))) { ! 241: ctrlg(FALSE, 0); ! 242: continue; ! 243: } ! 244: if (f != FALSE) { ! 245: *kbdmip++ = bind.repeat; ! 246: *kbdmip++ = n; ! 247: } ! 248: *kbdmip++ = c; ! 249: } ! 250: bracketoff(); ! 251: execute(c, f, n); /* Do it. */ ! 252: } ! 253: } ! 254: ! 255: /* ! 256: * Initialize all of the buffers and windows. ! 257: * The buffer name is passed down as an argument, because the main routine may ! 258: * have been told to read in a file by default, and we want the buffer name to ! 259: * be right. ! 260: */ ! 261: edinit(bname) ! 262: uchar bname[]; ! 263: { ! 264: register BUFFER *bp; ! 265: register WINDOW *wp; ! 266: ! 267: bp = bfind(bname, TRUE, 0); /* First buffer */ ! 268: blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */ ! 269: #if LIBHELP ! 270: helpbp = bfind("[Help]", TRUE, BFTEMP|BFHELP); /* Help buffer */ ! 271: #endif ! 272: wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */ ! 273: if (bp==NULL || wp==NULL || blistp==NULL) ! 274: abort(); ! 275: curbp = bp; /* Make this current */ ! 276: wheadp = wp; ! 277: curwp = wp; ! 278: wp->w_wndp = NULL; /* Initialize window */ ! 279: wp->w_bufp = bp; ! 280: bp->b_nwnd = 1; /* Displayed. */ ! 281: wp->w_linep = bp->b_linep; ! 282: wp->w_dotp = bp->b_linep; ! 283: wp->w_doto = 0; ! 284: wp->w_markp = NULL; ! 285: wp->w_marko = 0; ! 286: wp->w_toprow = 0; ! 287: wp->w_ntrows = term.t_nrow-1; /* "-1" for mode line. */ ! 288: wp->w_force = 0; ! 289: wp->w_flag = WFMODE|WFHARD; /* Full. */ ! 290: } ! 291: ! 292: ! 293: /* ! 294: * Read in a key. Do the standard keyboard preprocessing. ! 295: * Convert the keys to the internal character set. On the LK201, which lacks ! 296: * a reasonable ESC key, make the grave accent a meta key too; this is a fairly ! 297: * common customization around Digital. Also read and decode the arrow keys, ! 298: * and other special keys. This is done in Rainbow mode; does this work on all ! 299: * the terminals with LK201 keyboards? ! 300: */ ! 301: getkey() ! 302: { ! 303: register int c; ! 304: #if LK201 ! 305: register int n; ! 306: for (;;) { ! 307: if ((c = tgetc()) == AGRAVE) /* Alternate M- prefix. */ ! 308: return (META | getCtl()); ! 309: if (c == METACH) { /* M-, or special key. */ ! 310: if ((c = tgetc()) == '[') { /* Arrows and extras. */ ! 311: switch (c = tgetc()) { ! 312: case 'A': ! 313: return (OBND | CTRL | 'P'); ! 314: case 'B': ! 315: return (OBND | CTRL | 'N'); ! 316: case 'C': ! 317: return (OBND | CTRL | 'F'); ! 318: case 'D': ! 319: return (OBND | CTRL | 'B'); ! 320: } ! 321: if (c >= '0' && c <= '9') { ! 322: n = 0; ! 323: do { ! 324: n = 10*n + c - '0'; ! 325: } ! 326: while ((c = tgetc()) >= '0' && c <= '9'); ! 327: if (c == '~' && n <= 34 && (c = lkmap[n])) ! 328: return (c); ! 329: } ! 330: continue; ! 331: } ! 332: if (c == 'O') { ! 333: switch (tgetc()) { ! 334: case 'P': /* PF1 => M-X (Future) */ ! 335: return (OBND | META | 'X'); ! 336: case 'Q': /* PF2 => C-Q */ ! 337: return (OBND | CTRL | 'Q'); ! 338: case 'R': /* PF3 => C-S */ ! 339: return (OBND | CTRL | 'S'); ! 340: case 'S': /* PF4 => C-R */ ! 341: return (OBND | CTRL | 'R'); ! 342: } ! 343: continue; ! 344: } ! 345: return (META | toCtl(c)); ! 346: } ! 347: break; ! 348: } ! 349: #else ! 350: #if VT100 ! 351: for (;;) { ! 352: if ((c = tgetc()) == METACH) { /* Apply M- prefix */ ! 353: if ((c = tgetc()) == '[') { /* Arrow keys. */ ! 354: switch (tgetc()) { ! 355: case 'A': /* up arrow */ ! 356: return (OBND | CTRL | 'P'); ! 357: case 'B': /* down arrow */ ! 358: return (OBND | CTRL | 'N'); ! 359: case 'C': /* right arrow */ ! 360: return (OBND | CTRL | 'F'); ! 361: case 'D': /* left arrow */ ! 362: return (OBND | CTRL | 'B'); ! 363: case 'F': /* END key */ ! 364: return (OBND | CTRL | 'E'); ! 365: case 'H': /* home key */ ! 366: return (OBND | CTRL | 'A'); ! 367: case 'M': /* F1 key, help */ ! 368: return (OBND | META | '?'); ! 369: case 'N': /* F2 key, newfile */ ! 370: return (OBND | PFX1 | CTRL | 'V'); ! 371: case 'I': /* PGUP key */ ! 372: return (OBND | META | 'V'); ! 373: case 'G': /* PGDN key */ ! 374: return (OBND | CTRL | 'V'); ! 375: case 'O': /* F3 search forward */ ! 376: return (OBND | META | 'S'); ! 377: case 'P': /* F4 search backward */ ! 378: return (OBND | META | 'R'); ! 379: case 'Q': /* F5 search & replace */ ! 380: return (OBND | META | '%'); ! 381: case 'R': /* F6 next window */ ! 382: return (OBND | PFX1 | 'N'); ! 383: case 'T': /* F8 save/exit */ ! 384: return (OBND | CTRL | 'Z'); ! 385: case 'V': /* F10 close other wndws */ ! 386: return (OBND | PFX1 | '1'); ! 387: } ! 388: continue; ! 389: } ! 390: if (c == 'O') { /* function keys */ ! 391: switch (tgetc()) { ! 392: case 'P': /* PF1 => M-X (Future) */ ! 393: return (OBND | META | 'X'); ! 394: case 'Q': /* PF2 => C-Q */ ! 395: return (OBND | CTRL | 'Q'); ! 396: case 'R': /* PF3 => C-S */ ! 397: return (OBND | CTRL | 'S'); ! 398: case 'S': /* PF4 => C-R */ ! 399: return (OBND | CTRL | 'R'); ! 400: } ! 401: continue; ! 402: } ! 403: return (META | toCtl(c)); ! 404: } ! 405: break; ! 406: } ! 407: #else ! 408: if ((c = tgetc()) == METACH) /* Apply M- prefix */ ! 409: return (META | getCtl()); ! 410: #endif ! 411: #endif ! 412: if (c == 0x0D && bind.autoindent) ! 413: return (OBND | CTRL | 'J'); ! 414: if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */ ! 415: return (CTRL | '@' | c); ! 416: if (c == 127) ! 417: return (OBND | CTRL | 'D'); ! 418: return (c); ! 419: } ! 420: ! 421: /* ! 422: * Apply control modifications to a key ! 423: */ ! 424: toCtl(c) ! 425: register int c; ! 426: { ! 427: if (c>='a' && c<='z') /* Force to upper */ ! 428: return (c - 0x20); ! 429: if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ ! 430: return (c | CTRL | '@'); ! 431: return (c); ! 432: } ! 433: ! 434: getCtl() ! 435: { ! 436: return (toCtl(tgetc())); ! 437: } ! 438: ! 439: /* ! 440: * Fancy quit command, as implemented by Norm. ! 441: * If the current buffer has changed do a write current buffer and exit emacs, ! 442: * otherwise simply exit. ! 443: */ ! 444: quickexit(f, n) ! 445: { ! 446: if ((curbp->b_flag&BFCHG) != 0 /* Changed. */ ! 447: && (curbp->b_flag&(BFTEMP|BFERROR|BFNOWRT)) == 0) ! 448: /* Real and not R/O... */ ! 449: filesave(f, n); ! 450: quit(f, n); /* conditionally quit */ ! 451: } ! 452: ! 453: /* ! 454: * Quit command. If an argument, always quit. Otherwise confirm ! 455: * if a buffer has been changed and not written out. ! 456: * Normally bound to "C-X C-C". ! 457: */ ! 458: quit(f, n) ! 459: { ! 460: register int s = FALSE; ! 461: ! 462: if (f != FALSE /* Argument forces it. */ ! 463: || anycb() == FALSE /* All buffers clean. */ ! 464: || (s=mlyesno("Quit")) == TRUE) { /* User says it's OK. */ ! 465: vttidy(); ! 466: #if MSDOS ! 467: resetkeys(); ! 468: #endif ! 469: if (f != FALSE || s != FALSE) ! 470: exit(BAD); ! 471: else ! 472: exit(GOOD); ! 473: } ! 474: #if MSDOS ! 475: setkeys(); ! 476: #endif ! 477: return (s); ! 478: } ! 479: ! 480: /* ! 481: * Get binding char. Turn prefix chars into or'ed bits. ! 482: */ ! 483: getbind(bound) ! 484: register int bound; ! 485: { ! 486: register int c; ! 487: ! 488: if (((c = getkey()) == bind.pfx1) && !(bound & PFX1)) ! 489: return (PFX1 | toCtl(getbind(bound | PFX1))); ! 490: if ((c == bind.pfx2) && !(bound & PFX2)) ! 491: return (PFX2 | toCtl(getbind(bound | PFX2))); ! 492: if ((c == bind.pfx3) && !(bound & PFX3)) ! 493: return (PFX3 | toCtl(getbind(bound | PFX3))); ! 494: return (c); ! 495: } ! 496: ! 497: /* ! 498: * Abort. ! 499: * Beep the beeper. ! 500: * Kill off any keyboard macro, ! 501: * etc., that is in progress. ! 502: * Sometimes called as a routine, ! 503: * to do general aborting of ! 504: * stuff. ! 505: */ ! 506: ctrlg(f, n) ! 507: { ! 508: tbeep(); ! 509: if (kbdmip != NULL) { ! 510: if (NULL != kbdm) { ! 511: free(kbdm); ! 512: kbdm = NULL; ! 513: } ! 514: kbdmip = NULL; ! 515: } ! 516: return (ABORT); ! 517: } ! 518: ! 519: #if MSDOS ! 520: setkeys() /* redefine cursor keys */ ! 521: /* so that they make */ ! 522: /* sense to microEMACS */ ! 523: /* as described in IBM */ ! 524: /* DOS tech. reference */ ! 525: /* manual */ ! 526: { ! 527: #if !IBM ! 528: static uchar *ctlseq[] = { ! 529: "\033[0;72;16p", /* up = <ctrl-p> */ ! 530: "\033[0;77;6p", /* right = <ctrl-f> */ ! 531: "\033[0;75;2p", /* left = <ctrl-b> */ ! 532: "\033[0;80;14p", /* down = <ctrl-n> */ ! 533: "\033[0;81;22p", /* pg dn = <ctrl-v> */ ! 534: "\033[0;73;27;86p", /* pg up = <esc>V */ ! 535: "\033[0;71;27;60p", /* home = <esc>< */ ! 536: "\033[0;79;27;62p", /* end = <esc>> */ ! 537: "\033[0;83;127p", /* del = del */ ! 538: "\033[0;3;27;46p", /* <ctrl-@> = <exc>. */ ! 539: NULL ! 540: }; ! 541: register uchar **ctlp; ! 542: ! 543: for (ctlp = ctlseq; NULL != *ctlp; ctlp++) ! 544: mlwrite(*ctlp); ! 545: #endif ! 546: } ! 547: ! 548: ! 549: ! 550: resetkeys() /* redefine cursor keys */ ! 551: /* to default values */ ! 552: { ! 553: #if !IBM ! 554: static uchar *ctlseq[] = { ! 555: "\033[0;72;0;72p", ! 556: "\033[0;77;0;77p", ! 557: "\033[0;75;0;75p", ! 558: "\033[0;80;0;80p", ! 559: "\033[0;81;0;81p", ! 560: "\033[0;73;0;73p", ! 561: "\033[0;71;0;71p", ! 562: "\033[0;79;0;79p", ! 563: "\033[0;83;0;83p", ! 564: "\033[0;3;0;3p", ! 565: NULL ! 566: }; ! 567: register uchar **ctlp; ! 568: ! 569: for (ctlp = ctlseq; NULL != *ctlp; ctlp++) ! 570: mlwrite(*ctlp); ! 571: #endif ! 572: } ! 573: #endif ! 574: ! 575: argproc(argc, argv) ! 576: int argc; ! 577: uchar **argv; ! 578: { ! 579: int i; ! 580: uchar *flexn; ! 581: extern uchar *flexName(); ! 582: uchar *ptr; ! 583: ! 584: if (!bind.tabsiz && ! 585: (NULL == (ptr = getenv("TABSIZ")) || ! 586: !(bind.tabsiz = atoi(ptr)))) ! 587: bind.tabsiz = 8; ! 588: cfilecnt = 0; ! 589: flexn = NULL; ! 590: for (i = 1; i < argc; i++) { ! 591: ptr = argv[i]; /* Get this argument... */ ! 592: if (*ptr == '-') { /* Is this a switch? */ ! 593: switch (ptr[1]) { ! 594: case 'd': ! 595: runswitch |= CF_DEBUG; ! 596: break; ! 597: case 'e': ! 598: runswitch |= CF_ERROR; ! 599: if (ptr[2] == 0) { ! 600: if (++i == argc) { ! 601: runswitch &= ~CF_ERROR; ! 602: continue; ! 603: } ! 604: strcpy(errfile, argv[i]); ! 605: } ! 606: else { ! 607: strcpy(errfile, &ptr[2]); ! 608: } ! 609: break; ! 610: case 'f': ! 611: if (ptr[2] == 0) { ! 612: if (++i == argc) ! 613: continue; ! 614: flexn = argv[i]; ! 615: } ! 616: else ! 617: flexn = ptr + 1; ! 618: break; ! 619: #if LIBHELP ! 620: case 'h': /* Alternate help */ ! 621: if (ptr[2] == 0) { ! 622: if (++i == argc) { ! 623: continue; ! 624: } ! 625: strcpy(hfname, argv[i]); ! 626: } ! 627: else { ! 628: strcpy(hfname, &ptr[2]); ! 629: } ! 630: strcpy(hiname, hfname); ! 631: #if GEM || MSDOS ! 632: strcat(hfname, ".hlp"); ! 633: #endif ! 634: strcat(hiname, ".idx"); ! 635: helpfile = hfname; ! 636: helpindex = hiname; ! 637: break; ! 638: #endif ! 639: case 'w': ! 640: runswitch |= CF_WARN; ! 641: break; ! 642: #if NATIVE && GEM ! 643: case 'l': /* long screen */ ! 644: runswitch |= CF_LONGSCR; ! 645: break; ! 646: case 't': /* very long screen */ ! 647: runswitch |= CF_VLONG; ! 648: break; ! 649: #endif ! 650: #if GEM ! 651: case 'x': /* grab all memory */ ! 652: runswitch |= CF_GRABMEM; ! 653: break; ! 654: #endif ! 655: default: ! 656: break; ! 657: } ! 658: /* Process this switch */ ! 659: } ! 660: else { /* Otherwise... */ ! 661: if (cfilecnt >= NCFILES) ! 662: continue; ! 663: cfiles[cfilecnt++] = ptr; /* This is a file. */ ! 664: #if GEM ! 665: fixname(cfiles[cfilecnt-1]); ! 666: #endif ! 667: } ! 668: } ! 669: if (NULL == flexn) ! 670: loadBup(flexName(), TRUE); ! 671: else ! 672: loadBup(flexn, ABORT); ! 673: } ! 674: ! 675: #if EXKEYS ! 676: /* ! 677: * Do nothing. ("Dead") ! 678: */ ! 679: ignore() ! 680: { ! 681: return TRUE; ! 682: } ! 683: #endif ! 684: ! 685: /* ! 686: * Get a numeric argument... ! 687: */ ! 688: getnum(prompt, n, lastc) ! 689: register uchar *prompt; ! 690: register int n; ! 691: register int *lastc; ! 692: { ! 693: register int mflag = 0; ! 694: register int c; ! 695: ! 696: mflag = 0; /* that can be discarded. */ ! 697: mlwrite("%s: %d", prompt, n); ! 698: while ((c = getbind(0)) >='0' && c<='9' ! 699: || c==bind.repeat || c=='-'){ ! 700: if (c == bind.repeat) ! 701: n = n*4; ! 702: /* ! 703: * If dash, and start of argument string, set arg. ! 704: * to -1. Otherwise, insert it. ! 705: */ ! 706: else if (c == '-') { ! 707: if (mflag) ! 708: break; ! 709: n = 0; ! 710: mflag = -1; ! 711: } ! 712: /* ! 713: * If first digit entered, replace previous argument ! 714: * with digit and set sign. Otherwise, append to arg. ! 715: */ ! 716: else { ! 717: if (!mflag) { ! 718: n = 0; ! 719: mflag = 1; ! 720: } ! 721: n = 10*n + c - '0'; ! 722: } ! 723: mlwrite("%s: %d", prompt, (mflag >=0) ? n : (n ? -n : -1)); ! 724: } ! 725: *lastc = c; /* Return the terminal char. */ ! 726: /* ! 727: * Make arguments preceded by a minus sign negative and change ! 728: * the special argument "^U -" to an effective "^U -1". ! 729: */ ! 730: if (mflag == -1) { ! 731: if (n == 0) ! 732: n++; ! 733: n = -n; ! 734: } ! 735: return n; ! 736: } ! 737: ! 738: #if GEM ! 739: /* ! 740: * The following routine gets around a problem with GEMDOS Malloc(), ! 741: * it forces a single, very large Malloc() so very large files can ! 742: * be read. ! 743: * It is available only on the Atari ST, and is bound to M-+ ! 744: * it can also be specified using the -x switch ! 745: */ ! 746: #include <osbind.h> ! 747: ! 748: grabmem(f, n) ! 749: int f, n; ! 750: { ! 751: extern char *lmalloc(); ! 752: register char *p = NULL; ! 753: register long t; ! 754: ! 755: t = Malloc(-1L); /* How big is free memory? */ ! 756: while (p == NULL) { /* Until we have a block */ ! 757: t -= 4096L; /* shrink the block */ ! 758: if (t < 2048) { /* if too small, tell user */ ! 759: mlwrite( "[Cannot allocate memory]" ); ! 760: return 1; /* and fail */ ! 761: } ! 762: p = lmalloc(t); /* Try to get this chunk */ ! 763: } /* loop until success or fail */ ! 764: free(p); /* return chunk to arena */ ! 765: mlwrite( "[Allocated %ld bytes]", t ); /* tell user how much */ ! 766: return 0; /* and return success */ ! 767: } ! 768: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.