|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.