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: }

Defined functions

DelMacro defined in line 470; used 2 times
ExecMacro defined in line 425; used 2 times
Forget defined in line 408; used 3 times
MacInter defined in line 430; used 2 times
MacNolen defined in line 93; used 3 times
ModMacs defined in line 439; used 1 times
NameMac defined in line 158; used 2 times
PrefChar defined in line 402; used 1 times
ReadMacs defined in line 320; used 2 times
Remember defined in line 384; used 2 times
RunMacro defined in line 187; used 2 times
WriteMacs defined in line 211; used 3 times
add_mac defined in line 15; used 3 times
del_mac defined in line 34; used 1 times
do_macro defined in line 80; used 3 times
findmac defined in line 449; used 4 times
fix_macros defined in line 57; used 2 times
htonl defined in line 287; used 2 times
htons defined in line 293; never used
in_macro defined in line 136; used 1 times
int_fmt defined in line 313; used 2 times
mac_err defined in line 71; used 2 times
mac_exists defined in line 100; used 1 times
mac_getc defined in line 141; used 2 times
mac_init defined in line 112; used 1 times
mac_io defined in line 197; used 7 times
mac_putc defined in line 123; used 1 times
ntohl defined in line 299; used 1 times
ntohs defined in line 305; never used

Defined variables

KeyMacro defined in line 50; used 72 times
LastCmd defined in line 13; used 1 times
int_how defined in line 246; used 3 times
mac_fd defined in line 195; used 6 times
macros defined in line 12; used 16 times
macstack defined in line 54; used 12 times
stackp defined in line 55; used 8 times

Defined macros

NEWWAY defined in line 243; used 3 times
NMACROS defined in line 52; used 2 times
OLDWAY defined in line 244; used 1 times
Last modified: 1986-03-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2558
Valid CSS Valid XHTML 1.0 Strict