Annotation of coherent/g/usr/bin/me/main.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.