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

Defined functions

DefKBDMac defined in line 287; used 4 times
DelMacro defined in line 424; used 4 times
ExecMacro defined in line 376; used 4 times
Forget defined in line 355; used 6 times
MacInter defined in line 382; used 4 times
ModMacs defined in line 392; used 3 times
NameMac defined in line 213; used 4 times
PrefChar defined in line 349; used 3 times
Remember defined in line 330; used 5 times
RunMacro defined in line 242; used 4 times
WriteMacs defined in line 264; used 4 times
add_mac defined in line 49; used 5 times
alloc_mthread defined in line 116; used 3 times
del_mac defined in line 68; used 4 times
do_macro defined in line 145; used 5 times
findmac defined in line 403; used 5 times
free_mthread defined in line 122; used 3 times
in_macro defined in line 189; used 9 times
mac_exists defined in line 152; used 4 times
mac_getc defined in line 195; used 4 times
mac_init defined in line 164; used 3 times
mac_putc defined in line 174; used 3 times
pop_macro_stack defined in line 105; used 4 times
pr_putc defined in line 251; used 1 times
push_macro_stack defined in line 129; used 3 times
unwind_macro_stack defined in line 98; used 3 times

Defined variables

InMacDefine defined in line 47; used 10 times
KeyMacro defined in line 84; used 54 times
mac_stack defined in line 96; used 7 times
macros defined in line 46; used 16 times
private defined in line 349; never used

Defined struct's

m_thread defined in line 89; used 18 times

Defined macros

private defined in line 43; used 13 times
Last modified: 1988-03-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3311
Valid CSS Valid XHTML 1.0 Strict