Annotation of 43BSDTahoe/new/jove/macros.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
                      3:  * is provided to you without charge, and with no warranty.  You may give  *
                      4:  * away copies of JOVE, including sources, provided that this notice is    *
                      5:  * included in all the files.                                              *
                      6:  ***************************************************************************/
                      7: 
                      8: #include "jove.h"
                      9: #include "ctype.h"
                     10: #include "io.h"
                     11: 
                     12: #ifdef MAC
                     13: #      undef private
                     14: #      define private
                     15: #endif
                     16: 
                     17: #ifdef LINT_ARGS
                     18: private void
                     19:        add_mac(struct macro *),
                     20:        del_mac(struct macro *),
                     21:        pop_macro_stack(void),
                     22:        push_macro_stack(struct macro *, int);
                     23:        
                     24: private int
                     25:        PrefChar(int);
                     26: 
                     27: private struct macro * mac_exists(char *);
                     28: #else
                     29: private void
                     30:        add_mac(),
                     31:        del_mac(),
                     32:        pop_macro_stack(),
                     33:        push_macro_stack();
                     34:        
                     35: private int
                     36:        PrefChar();
                     37: 
                     38: private struct macro * mac_exists();
                     39: #endif /* LINT_ARGS */
                     40: 
                     41: #ifdef MAC
                     42: #      undef private
                     43: #      define private static
                     44: #endif
                     45: 
                     46: struct macro   *macros = 0;            /* macros */
                     47: int    InMacDefine = NO;
                     48: 
                     49: private void
                     50: add_mac(new)
                     51: struct macro   *new;
                     52: {
                     53:        register struct macro   *mp,
                     54:                                *prev = 0;
                     55: 
                     56:        for (mp = macros; mp != 0; prev = mp, mp = mp->m_nextm)
                     57:                if (mp == new)
                     58:                        return;
                     59: 
                     60:        if (prev)
                     61:                prev->m_nextm = new;
                     62:        else
                     63:                macros = new;
                     64:        new->m_nextm = 0;
                     65:        new->Type = MACRO;
                     66: }
                     67: 
                     68: private void
                     69: del_mac(mac)
                     70: struct macro   *mac;
                     71: {
                     72:        register struct macro   *m;
                     73: 
                     74:        for (m = macros; m != 0; m = m->m_nextm)
                     75:                if (m->m_nextm == mac) {
                     76:                        m->m_nextm = mac->m_nextm;
                     77:                        break;
                     78:                }
                     79:        free(mac->Name);
                     80:        free(mac->m_body);
                     81:        free((char *) mac);
                     82: }
                     83: 
                     84: struct macro   KeyMacro;       /* Macro used for defining */
                     85: 
                     86: /* To execute a macro, we have a "stack" of running macros.  Whenever
                     87:    we execute a macro, we push it on the stack, run it, then pop it
                     88:    from the stack.  */
                     89: struct m_thread {
                     90:        struct m_thread *mt_prev;
                     91:        struct macro    *mt_mp;
                     92:        int     mt_offset,
                     93:                mt_count;
                     94: };
                     95: 
                     96: private struct m_thread        *mac_stack = 0;
                     97: 
                     98: void
                     99: unwind_macro_stack()
                    100: {
                    101:        while (mac_stack != 0)
                    102:                pop_macro_stack();
                    103: }
                    104: 
                    105: private void
                    106: pop_macro_stack()
                    107: {
                    108:        register struct m_thread        *m;
                    109: 
                    110:        if ((m = mac_stack) == 0)
                    111:                return;
                    112:        mac_stack = m->mt_prev;
                    113:        free_mthread(m);
                    114: }
                    115: 
                    116: struct m_thread *
                    117: alloc_mthread()
                    118: {
                    119:        return (struct m_thread *) emalloc(sizeof (struct m_thread));
                    120: }
                    121: 
                    122: void
                    123: free_mthread(t)
                    124: struct m_thread        *t;
                    125: {
                    126:        free((char *) t);
                    127: }
                    128: 
                    129: private void
                    130: push_macro_stack(m, count)
                    131: struct macro   *m;
                    132: {
                    133:        struct m_thread *t;
                    134: 
                    135:        if (count <= 0)
                    136:                complain("[Cannot execute macro a negative number of times]");
                    137:        t = alloc_mthread();
                    138:        t->mt_prev = mac_stack;
                    139:        mac_stack = t;
                    140:        t->mt_offset = 0;
                    141:        t->mt_mp = m;
                    142:        t->mt_count = count;
                    143: }
                    144: 
                    145: void
                    146: do_macro(mac)
                    147: struct macro   *mac;
                    148: {
                    149:        push_macro_stack(mac, arg_value());
                    150: }
                    151: 
                    152: private struct macro *
                    153: mac_exists(name)
                    154: char   *name;
                    155: {
                    156:        register struct macro   *mp;
                    157: 
                    158:        for (mp = macros; mp; mp = mp->m_nextm)
                    159:                if (strcmp(mp->Name, name) == 0)
                    160:                        return mp;
                    161:        return 0;
                    162: }
                    163: 
                    164: void
                    165: mac_init()
                    166: {
                    167:        add_mac(&KeyMacro);
                    168:        KeyMacro.Name = "keyboard-macro";
                    169:        KeyMacro.m_len = 0;
                    170:        KeyMacro.m_buflen = 16;
                    171:        KeyMacro.m_body = emalloc(KeyMacro.m_buflen);
                    172: }
                    173: 
                    174: void
                    175: mac_putc(c)
                    176: int    c;
                    177: {
                    178:        if (KeyMacro.m_len >= KeyMacro.m_buflen) {
                    179:                KeyMacro.m_buflen += 16;
                    180:                KeyMacro.m_body = realloc(KeyMacro.m_body, (unsigned) KeyMacro.m_buflen);
                    181:                if (KeyMacro.m_body == 0) {
                    182:                        KeyMacro.m_buflen = KeyMacro.m_len = 0;
                    183:                        complain("[Can't allocate storage for keyboard macro]");
                    184:                }
                    185:        }
                    186:        KeyMacro.m_body[KeyMacro.m_len++] = c;
                    187: }
                    188: 
                    189: int
                    190: in_macro()
                    191: {
                    192:        return (mac_stack != 0);
                    193: }
                    194: 
                    195: int
                    196: mac_getc()
                    197: {
                    198:        struct m_thread *mthread;
                    199:        struct macro    *m;
                    200: 
                    201:        if ((mthread = mac_stack) == 0)
                    202:                return -1;
                    203:        m = mthread->mt_mp;
                    204:        if (mthread->mt_offset == m->m_len) {
                    205:                mthread->mt_offset = 0;
                    206:                if (--mthread->mt_count == 0)
                    207:                        pop_macro_stack();
                    208:                return mac_getc();
                    209:        }
                    210:        return m->m_body[mthread->mt_offset++];
                    211: }
                    212: 
                    213: void
                    214: NameMac()
                    215: {
                    216:        char    *name;
                    217:        struct macro    *m;
                    218: 
                    219:        if (KeyMacro.m_len == 0)
                    220:                complain("[No keyboard macro to name!]");
                    221:        if (in_macro() || InMacDefine)
                    222:                complain("[Can't name while defining/executing]");
                    223:        if ((m = mac_exists(name = ask((char *) 0, ProcFmt))) == 0)
                    224:                m = (struct macro *) emalloc(sizeof *m);
                    225:        else {
                    226:                if (strcmp(name, KeyMacro.Name) == 0)
                    227:                        complain("[Can't name it that!]");
                    228:                free(m->Name);
                    229:                free(m->m_body);
                    230:        }
                    231:        name = copystr(name);
                    232:        m->Type = KeyMacro.Type;
                    233:        m->m_len = KeyMacro.m_len;
                    234:        m->m_buflen = KeyMacro.m_buflen;
                    235:        m->m_body = emalloc(m->m_buflen);
                    236:        byte_copy(KeyMacro.m_body, m->m_body, m->m_len);
                    237:        m->m_flags = SAVE;
                    238:        m->Name = name;
                    239:        add_mac(m);
                    240: }
                    241: 
                    242: void
                    243: RunMacro()
                    244: {
                    245:        struct macro    *m;
                    246: 
                    247:        if (m = (struct macro *) findmac(ProcFmt))
                    248:                do_macro(m);
                    249: }
                    250: 
                    251: void
                    252: pr_putc(c, fp)
                    253: File   *fp;
                    254: {
                    255:        if (c == '\\' || c == '^')
                    256:                putc('\\', fp);
                    257:         else if (isctrl(c)) {
                    258:                putc('^', fp);
                    259:                c = (c == RUBOUT) ? '?' : (c + '@');
                    260:        }
                    261:        putc(c, fp);
                    262: }
                    263: 
                    264: void
                    265: WriteMacs()
                    266: {
                    267:        struct macro    *m;
                    268:        char    *file,
                    269:                filebuf[FILESIZE];
                    270:        File    *fp;
                    271:        int     i;
                    272: 
                    273:        file = ask_file((char *) 0, (char *) 0, filebuf);
                    274:        fp = open_file(file, iobuff, F_WRITE, COMPLAIN, QUIET);
                    275: 
                    276:        /* Don't write the keyboard macro which is always the first */
                    277:        for (m = macros->m_nextm; m != 0; m = m->m_nextm) {
                    278:                fprintf(fp, "define-macro %s ", m->Name);
                    279:                for (i = 0; i < m->m_len; i++)
                    280:                        pr_putc(m->m_body[i], fp);
                    281:                putc('\n', fp);
                    282:                m->m_flags &= ~SAVE;
                    283:        }
                    284:        close_file(fp);
                    285: }
                    286: 
                    287: void
                    288: DefKBDMac()
                    289: {
                    290:        char    *macro_name,
                    291:                *macro_body,
                    292:                nextc,
                    293:                c,
                    294:                macro_buffer[LBSIZE];
                    295:        int     i;
                    296:        struct macro    *m;
                    297: 
                    298:        macro_name = do_ask(" \r\n", (int (*)()) 0, (char *) 0, ProcFmt);
                    299:        if (macro_name == 0)
                    300:                complain("[No default]");
                    301:        macro_name = copystr(macro_name);
                    302:        if (m = mac_exists(macro_name))
                    303:                del_mac(m);
                    304:        macro_body = ask((char *) 0, ": %f %s enter body: ", macro_name);
                    305:        i = 0;
                    306:        while ((c = *macro_body++) != '\0') {
                    307:                if (c == '\\') {
                    308:                        if ((nextc = *macro_body++) == LF)
                    309:                                complain("[Premature end of line]");
                    310:                        c = nextc;
                    311:                } else if (c == '^') {
                    312:                        if ((nextc = *macro_body++) == '?')
                    313:                                c = RUBOUT;
                    314:                        else if (isalpha(nextc) || index("@[\\]^_", nextc))
                    315:                                c = CTL(nextc);
                    316:                        else
                    317:                                complain("Bad control-character: '%c'", nextc);
                    318:                }
                    319:                macro_buffer[i++] = c;
                    320:        }
                    321:        m = (struct macro *) emalloc(sizeof (*m));
                    322:        m->Name = macro_name;
                    323:        m->m_len = m->m_buflen = i;
                    324:        m->m_body = emalloc(i);
                    325:        m->m_flags = InJoverc ? 0 : SAVE;
                    326:        byte_copy(macro_buffer, m->m_body, i);
                    327:        add_mac(m);
                    328: }
                    329: 
                    330: void
                    331: Remember()
                    332: {
                    333:        /* We're already executing the macro; ignore any attempts
                    334:           to define the keyboard macro while we are executing. */
                    335:        if (in_macro())
                    336:                return;
                    337:        if (InMacDefine)
                    338:                message("[Already defining ... continue with definition]");
                    339:        else {
                    340:                UpdModLine = YES;
                    341:                InMacDefine = YES;
                    342:                KeyMacro.m_len = 0;
                    343:                message("Defining...");
                    344:        }
                    345: }
                    346: 
                    347: /* Is `c' a prefix character */
                    348: 
                    349: private int
                    350: PrefChar(c)
                    351: {
                    352:        return (int) IsPrefix(mainmap[c]);
                    353: }
                    354: 
                    355: void
                    356: Forget()
                    357: {
                    358:        char    *cp;
                    359:        struct macro    *m = &KeyMacro;
                    360: 
                    361:        UpdModLine = YES;
                    362:        if (InMacDefine) {
                    363:                message("Keyboard macro defined.");
                    364:                InMacDefine = NO;
                    365: 
                    366:                /* try and strip off the key sequence that invoked us */
                    367:                cp = &m->m_body[m->m_len - 2];
                    368:                if (PrefChar(*cp))
                    369:                        m->m_len -= 2;
                    370:                else if (commands[cp[1]].c_proc == Forget)
                    371:                        m->m_len -= 1;
                    372:        } else
                    373:                complain("[end-kbd-macro: not currently defining macro!]");
                    374: }
                    375: 
                    376: void
                    377: ExecMacro()
                    378: {
                    379:        do_macro(&KeyMacro);
                    380: }
                    381: 
                    382: void
                    383: MacInter()
                    384: {
                    385:        extern int      Interactive;
                    386: 
                    387:        if (!Asking)
                    388:                return;
                    389:        Interactive = 1;
                    390: }
                    391: 
                    392: int
                    393: ModMacs()
                    394: {
                    395:        register struct macro   *m;
                    396: 
                    397:        for (m = macros->m_nextm; m != 0; m = m->m_nextm)
                    398:                if (m->m_flags & SAVE)
                    399:                        return YES;
                    400:        return NO;
                    401: }
                    402: 
                    403: data_obj *
                    404: findmac(prompt)
                    405: char   *prompt;
                    406: {
                    407:        char    *strings[100];
                    408:        register char   **strs = strings;
                    409:        register int    com;
                    410:        register struct macro   *m = macros;
                    411: 
                    412:        for (; m != 0; m = m->m_nextm)
                    413:                *strs++ = m->Name;
                    414:        *strs = 0;
                    415: 
                    416:        if ((com = complete(strings, prompt, NOTHING)) < 0)
                    417:                return 0;
                    418:        m = macros;
                    419:        while (--com >= 0)
                    420:                m = m->m_nextm;
                    421:        return (data_obj *) m;
                    422: }
                    423: 
                    424: void
                    425: DelMacro()
                    426: {
                    427:        struct macro    *m;
                    428: 
                    429:        if ((m = (struct macro *) findmac(ProcFmt)) == 0)
                    430:                return;
                    431:        if (m == &KeyMacro)
                    432:                complain("[It's illegal to delete the keyboard-macro!]");
                    433:        del_mac(m);
                    434: }

unix.superglobalmegacorp.com

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