Annotation of 43BSD/contrib/jove/macros.c, revision 1.1.1.1

1.1       root        1: /*************************************************************************
                      2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
                      3:  * provided to you without charge for use only on a licensed Unix        *
                      4:  * system.  You may copy JOVE provided that this notice is included with *
                      5:  * the copy.  You may not sell copies of this program or versions        *
                      6:  * modified for use on microcomputer systems, unless the copies are      *
                      7:  * included with a Unix system distribution and the source is provided.  *
                      8:  *************************************************************************/
                      9: 
                     10: #include "jove.h"
                     11: 
                     12: struct macro   *macros = 0;            /* Macros */
                     13: data_obj       *LastCmd;
                     14: 
                     15: static
                     16: add_mac(new)
                     17: struct macro   *new;
                     18: {
                     19:        register struct macro   *mp,
                     20:                                *prev = 0;
                     21: 
                     22:        for (mp = macros; mp != 0; prev = mp, mp = mp->m_nextm)
                     23:                if (mp == new)
                     24:                        return;
                     25: 
                     26:        if (prev)
                     27:                prev->m_nextm = new;
                     28:        else
                     29:                macros = new;
                     30:        new->m_nextm = 0;
                     31:        new->Type = MACRO;
                     32: }
                     33: 
                     34: static
                     35: del_mac(mac)
                     36: struct macro   *mac;
                     37: {
                     38:        register struct macro   *m;
                     39: 
                     40:        for (m = macros; m != 0; m = m->m_nextm)
                     41:                if (m->m_nextm == mac) {
                     42:                        m->m_nextm = mac->m_nextm;
                     43:                        break;
                     44:                }
                     45:        free(mac->Name);
                     46:        free(mac->m_body);
                     47:        free((char *) mac);
                     48: }
                     49: 
                     50: struct macro   KeyMacro;       /* Macro used for defining */
                     51: 
                     52: #define NMACROS        40              /* This is bad, bad, BAD! */
                     53: 
                     54: struct macro   *macstack[NMACROS];
                     55: static int     stackp = 0;
                     56: 
                     57: fix_macros()
                     58: {
                     59:        register int    i;
                     60:        register struct macro   *mp;
                     61: 
                     62:        for (i = 0; macstack[i]; i++) {
                     63:                mp = macstack[i];
                     64:                macstack[i] = 0;
                     65:                mp->m_flags = mp->m_offset = 0;
                     66:        }
                     67:        stackp = -1;
                     68:        KeyMacro.m_flags = KeyMacro.m_offset = 0;
                     69: }
                     70: 
                     71: static
                     72: mac_err(err)
                     73: char   *err;
                     74: {
                     75:        KeyMacro.m_flags = 0;
                     76:        MacNolen(&KeyMacro);
                     77:        complain(err);
                     78: }
                     79: 
                     80: do_macro(mac)
                     81: struct macro   *mac;
                     82: {
                     83:        if (mac->m_flags & EXECUTE)
                     84:                mac_err("[Attempt to execute macro recursively!]");
                     85:        if (++stackp >= NMACROS)
                     86:                complain("[Too many macros at once!]");
                     87:        macstack[stackp] = mac;
                     88:        mac->m_offset = 0;
                     89:        mac->m_ntimes = exp;
                     90:        mac->m_flags |= EXECUTE;
                     91: }
                     92: 
                     93: static
                     94: MacNolen(m)
                     95: struct macro   *m;
                     96: {
                     97:        m->m_len = m->m_offset = 0;
                     98: }
                     99: 
                    100: static struct macro *
                    101: mac_exists(name)
                    102: char   *name;
                    103: {
                    104:        register struct macro   *mp;
                    105: 
                    106:        for (mp = macros; mp; mp = mp->m_nextm)
                    107:                if (strcmp(mp->Name, name) == 0)
                    108:                        return mp;
                    109:        return 0;
                    110: }
                    111: 
                    112: mac_init()
                    113: {
                    114:        add_mac(&KeyMacro);
                    115:        MacNolen(&KeyMacro);
                    116:        KeyMacro.Name = "keyboard-macro";
                    117:        KeyMacro.m_buflen = 16;
                    118:        KeyMacro.m_body = emalloc(KeyMacro.m_buflen);
                    119:        KeyMacro.m_ntimes = KeyMacro.m_flags = 0;
                    120:        fix_macros();
                    121: }
                    122: 
                    123: mac_putc(c)
                    124: int    c;
                    125: {
                    126:        if (KeyMacro.m_len >= KeyMacro.m_buflen) {
                    127:                KeyMacro.m_buflen += 16;
                    128:                KeyMacro.m_body = realloc(KeyMacro.m_body, (unsigned) KeyMacro.m_buflen);
                    129:                if (KeyMacro.m_body == 0)
                    130:                        mac_err("[Can't allocate storage for keyboard macro]");
                    131:        }
                    132:        KeyMacro.m_body[KeyMacro.m_offset++] = c;
                    133:        KeyMacro.m_len++;
                    134: }
                    135: 
                    136: in_macro()
                    137: {
                    138:        return ((stackp >= 0) && ((macstack[stackp])->m_flags & EXECUTE));
                    139: }
                    140: 
                    141: mac_getc()
                    142: {
                    143:        struct macro    *m;
                    144: 
                    145:        if (stackp < 0 || ((m = macstack[stackp])->m_flags & EXECUTE) == 0)
                    146:                return -1;
                    147:        if (m->m_offset == m->m_len) {
                    148:                m->m_offset = 0;
                    149:                if (--m->m_ntimes == 0) {
                    150:                        m->m_flags &= ~EXECUTE;
                    151:                        stackp--;
                    152:                }
                    153:                return mac_getc();
                    154:        }
                    155:        return m->m_body[m->m_offset++];
                    156: }
                    157: 
                    158: NameMac()
                    159: {
                    160:        char    *name;
                    161:        struct macro    *m;
                    162: 
                    163:        if (KeyMacro.m_len == 0)
                    164:                complain("[No keyboard macro to name!]");
                    165:        if (KeyMacro.m_flags & (DEFINE | EXECUTE))
                    166:                complain("[Can't name while defining/executing]");
                    167:        if ((m = mac_exists(name = ask((char *) 0, ProcFmt))) == 0)
                    168:                m = (struct macro *) emalloc(sizeof *m);
                    169:        else {
                    170:                if (strcmp(name, KeyMacro.Name) == 0)
                    171:                        complain("[Can't name it that!]");
                    172:                free(m->Name);
                    173:                free(m->m_body);
                    174:        }
                    175:        name = copystr(name);
                    176:        m->Type = KeyMacro.Type;
                    177:        m->m_len = KeyMacro.m_len;
                    178:        m->m_buflen = KeyMacro.m_buflen;
                    179:        m->m_body = emalloc(m->m_buflen);
                    180:        byte_copy(KeyMacro.m_body, m->m_body, m->m_len);
                    181:        m->m_ntimes = m->m_offset = 0;  /* At the beginning */
                    182:        m->m_flags = SAVE;
                    183:        m->Name = name;
                    184:        add_mac(m);
                    185: }      
                    186: 
                    187: RunMacro()
                    188: {
                    189:        struct macro    *m;
                    190: 
                    191:        if (m = (struct macro *) findmac(ProcFmt))
                    192:                do_macro(m);
                    193: }
                    194: 
                    195: static int     mac_fd;
                    196: 
                    197: static
                    198: mac_io(fcn, ptr, nbytes)
                    199: int    (*fcn)();
                    200: char   *ptr;
                    201: {
                    202:        int     nio;
                    203: 
                    204:        if ((nio = (*fcn)(mac_fd, ptr, nbytes)) != nbytes)
                    205:                complain("[Macro %s error: %d got %d]",
                    206:                         (fcn == read) ? "read" : "write",
                    207:                         nbytes,
                    208:                         nio);
                    209: }
                    210: 
                    211: WriteMacs()
                    212: {
                    213:        struct macro    *m;
                    214:        int     namelen,
                    215:                netl,
                    216:                nmacs = 0;
                    217:        char    *file,
                    218:                filebuf[FILESIZE];
                    219: 
                    220:        file = ask_file((char *) 0, filebuf);
                    221:        if ((mac_fd = creat(file, 0666)) == -1)
                    222:                complain(IOerr("create", file));
                    223:        f_mess("\"%s\"", file);
                    224: 
                    225:        /* Don't write the keyboard macro which is always the first */
                    226:        for (m = macros->m_nextm; m != 0; m = m->m_nextm) {
                    227:                if (m->m_len == 0)
                    228:                        continue;
                    229:                nmacs++;
                    230:                netl = htonl(m->m_len);
                    231:                mac_io(write, (char *) &netl, sizeof m->m_len);
                    232:                namelen = strlen(m->Name) + 1;  /* Including the null */
                    233:                netl = htonl(namelen);
                    234:                mac_io(write, (char *) &netl, sizeof namelen);
                    235:                mac_io(write, m->Name, namelen);
                    236:                mac_io(write, m->m_body, m->m_len);
                    237:                m->m_flags &= ~SAVE;
                    238:        }
                    239:        (void) close(mac_fd);
                    240:        add_mess(" %d macro%n saved.", nmacs, nmacs);
                    241: }
                    242: 
                    243: #define NEWWAY 1
                    244: #define OLDWAY 0
                    245: 
                    246: static int     int_how = NEWWAY;
                    247: 
                    248: /* Formatting int's the old way or the new "improved" way? */
                    249: 
                    250: #ifndef BSD4_2
                    251: 
                    252: /* 4.2 (at least) has these functions defined. */
                    253: 
                    254: #if vax || pdp11
                    255: long htonl(x)
                    256: register long x;
                    257: {
                    258:        return( (((x >>  0) & 0377) << 24) |
                    259:                (((x >>  8) & 0377) << 16) |
                    260:                (((x >> 16) & 0377) <<  8) |
                    261:                (((x >> 24) & 0377) <<  0) );
                    262: }
                    263: 
                    264: short htons(x)
                    265: register short x;
                    266: {
                    267:        return( (((x >>  0) & 0377) << 8) |
                    268:                (((x >>  8) & 0377) << 0) );
                    269: }
                    270: 
                    271: long ntohl(x)
                    272: register long x;
                    273: {
                    274:        return( (((x >>  0) & 0377) << 24) |
                    275:                (((x >>  8) & 0377) << 16) |
                    276:                (((x >> 16) & 0377) <<  8) |
                    277:                (((x >> 24) & 0377) <<  0) );
                    278: }
                    279: 
                    280: short ntohs(x)
                    281: register short x;
                    282: {
                    283:        return( (((x >>  0) & 0377) << 8) |
                    284:                (((x >>  8) & 0377) << 0) );
                    285: }
                    286: #else
                    287: long htonl(x)
                    288: register long x;
                    289: {
                    290:        return(x);
                    291: }
                    292: 
                    293: short htons(x)
                    294: register short x;
                    295: {
                    296:        return(x);
                    297: }
                    298: 
                    299: long ntohl(x)
                    300: register long x;
                    301: {
                    302:        return(x);
                    303: }
                    304: 
                    305: short ntohs(x)
                    306: register short x;
                    307: {
                    308:        return(x);
                    309: }
                    310: #endif
                    311: #endif BSD4_2
                    312: 
                    313: int_fmt(i)
                    314: {
                    315:        if (int_how == NEWWAY)
                    316:                return ntohl(i);
                    317:        return i;
                    318: }
                    319: 
                    320: ReadMacs()
                    321: {
                    322:        char    *file,
                    323:                filebuf[FILESIZE];
                    324:        struct macro    *m;
                    325:        int     nmacs = 0,
                    326:                namelen,
                    327:                bodylen,
                    328:                tmp,
                    329:                he_is_sure = 0,
                    330:                save_em = FALSE;
                    331: 
                    332:        file = ask_file((char *) 0, filebuf);
                    333:        if ((mac_fd = open(file, 0)) == -1)
                    334:                complain(IOerr("open", file));
                    335: 
                    336:        f_mess("\"%s\"", file);
                    337:        while (read(mac_fd, (char *) &tmp, sizeof tmp) == (sizeof tmp)) {
                    338: retry:         bodylen = int_fmt(tmp);
                    339:                if (!he_is_sure && (bodylen <= 0 || bodylen > 10000)) {
                    340:                        if (int_how == NEWWAY) {
                    341:                                int_how = OLDWAY;
                    342:                                save_em = TRUE;
                    343:                                goto retry;
                    344:                        } else {
                    345:                                confirm("Are you sure \"%s\" is a JOVE macro file? ", filebuf);
                    346:                                he_is_sure = 1;
                    347:                        }
                    348:                }
                    349:                nmacs++;
                    350:                m = (struct macro *) emalloc (sizeof *m);
                    351:                m->m_flags = 0;
                    352:                m->m_len = bodylen;
                    353:                m->m_buflen = m->m_len;
                    354:                mac_io(read, (char *) &namelen, sizeof namelen);
                    355:                namelen = int_fmt(namelen);
                    356:                m->Name = emalloc(namelen);
                    357:                mac_io(read, m->Name, namelen);
                    358:                m->m_body = emalloc(m->m_buflen);
                    359:                mac_io(read, m->m_body, m->m_len);
                    360:                add_mac(m);
                    361:        }
                    362:        (void) close(mac_fd);
                    363:        add_mess(" %d macro%n defined.", nmacs, nmacs);
                    364:        if (save_em) {
                    365:                char    *msg = "OK to convert to the new format? ",
                    366:                        ibuf[FILESIZE + 1];
                    367: 
                    368:                if (!InJoverc) {
                    369:                        TOstart("Warning", TRUE);
                    370:                        Typeout("Warning: your macros file is in the old format.");
                    371:                        Typeout("Do you want me to convert \"%s\" to the new", pr_name(file));
                    372:                        Typeout("format?");
                    373:                        f_mess(msg);
                    374:                        TOstop();
                    375:                        confirm(msg);
                    376:                }
                    377:                /* WriteMacs requests a file name.  This is what it'll get. */
                    378:                sprintf(ibuf, "%s\n", file);
                    379:                Inputp = ibuf;
                    380:                WriteMacs();
                    381:        }               
                    382: }
                    383: 
                    384: Remember()
                    385: {
                    386:        if (KeyMacro.m_flags & EXECUTE)
                    387:                /* We're already executing the macro; ignore any attempts
                    388:                   to define the keyboard macro while we are executing. */
                    389:                return;
                    390:        if (KeyMacro.m_flags & DEFINE)
                    391:                message("[Already remembering ... continue with definition]");
                    392:        else {
                    393:                UpdModLine++;
                    394:                KeyMacro.m_flags |= DEFINE;
                    395:                MacNolen(&KeyMacro);
                    396:                message("Remembering...");
                    397:        }
                    398: }
                    399: 
                    400: /* Is `c' a prefix character */
                    401: 
                    402: static
                    403: PrefChar(c)
                    404: {
                    405:        return (int) IsPrefix(mainmap[c]);
                    406: }
                    407: 
                    408: Forget()
                    409: {
                    410:        char    *cp;
                    411:        struct macro    *m = &KeyMacro;
                    412: 
                    413:        UpdModLine++;
                    414:        if (m->m_flags & DEFINE) {
                    415:                message("Keyboard macro defined.");
                    416:                m->m_flags &= ~DEFINE;
                    417:                cp = &m->m_body[m->m_len - 2];
                    418:                if (PrefChar(*cp))
                    419:                        m->m_len -= 2;
                    420:                else if (commands[*++cp].c_proc == Forget)
                    421:                        m->m_len--;
                    422:        }
                    423: }
                    424: 
                    425: ExecMacro()
                    426: {
                    427:        do_macro(&KeyMacro);
                    428: }
                    429: 
                    430: MacInter()
                    431: {
                    432:        extern int      Interactive;
                    433: 
                    434:        if (!Asking)
                    435:                return;
                    436:        Interactive = 1;
                    437: }
                    438: 
                    439: ModMacs()
                    440: {
                    441:        register struct macro   *m;
                    442: 
                    443:        for (m = macros->m_nextm; m != 0; m = m->m_nextm)
                    444:                if (m->m_flags & SAVE)
                    445:                        return 1;
                    446:        return 0;
                    447: }
                    448: 
                    449: data_obj *
                    450: findmac(prompt)
                    451: char   *prompt;
                    452: {
                    453:        char    *strings[100];
                    454:        register char   **strs = strings;
                    455:        register int    com;
                    456:        register struct macro   *m = macros;
                    457: 
                    458:        for (; m != 0; m = m->m_nextm)
                    459:                *strs++ = m->Name;
                    460:        *strs = 0;
                    461: 
                    462:        if ((com = complete(strings, prompt, NOTHING)) < 0)
                    463:                return 0;
                    464:        m = macros;
                    465:        while (--com >= 0)
                    466:                m = m->m_nextm;
                    467:        return (data_obj *) m;
                    468: }
                    469: 
                    470: DelMacro()
                    471: {
                    472:        struct macro    *m;
                    473: 
                    474:        if ((m = (struct macro *) findmac(ProcFmt)) == 0)
                    475:                return;
                    476:        if (m == &KeyMacro)
                    477:                complain("[It's illegal to delete the keyboard-macro!]");
                    478:        del_mac(m);
                    479: }

unix.superglobalmegacorp.com

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