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