Annotation of 43BSDTahoe/new/jove/macros.c, revision 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.