xref: /openbsd-src/usr.bin/mg/macro.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: macro.c,v 1.13 2008/06/10 02:39:22 kjell Exp $	*/
2 
3 /* This file is in the public domain. */
4 
5 /*
6  *	Keyboard macros.
7  */
8 
9 #ifndef NO_MACRO
10 #include "def.h"
11 #include "key.h"
12 #include "macro.h"
13 
14 int inmacro = FALSE;	/* Macro playback in progess */
15 int macrodef = FALSE;	/* Macro recording in progress */
16 int macrocount = 0;
17 
18 struct line *maclhead = NULL;
19 struct line *maclcur;
20 
21 union macrodef macro[MAXMACRO];
22 
23 /* ARGSUSED */
24 int
25 definemacro(int f, int n)
26 {
27 	struct line	*lp1, *lp2;
28 
29 	macrocount = 0;
30 
31 	if (macrodef) {
32 		ewprintf("already defining macro");
33 		return (macrodef = FALSE);
34 	}
35 
36 	/* free lines allocated for string arguments */
37 	if (maclhead != NULL) {
38 		for (lp1 = maclhead->l_fp; lp1 != maclhead; lp1 = lp2) {
39 			lp2 = lp1->l_fp;
40 			free(lp1);
41 		}
42 		free(lp1);
43 	}
44 
45 	if ((maclhead = lp1 = lalloc(0)) == NULL)
46 		return (FALSE);
47 
48 	ewprintf("Defining Keyboard Macro...");
49 	maclcur = lp1->l_fp = lp1->l_bp = lp1;
50 	return (macrodef = TRUE);
51 }
52 
53 /* ARGSUSED */
54 int
55 finishmacro(int f, int n)
56 {
57 	if (macrodef == TRUE) {
58 		macrodef = FALSE;
59 		ewprintf("End Keyboard Macro Definition");
60 		return (TRUE);
61 	}
62 	return (FALSE);
63 }
64 
65 /* ARGSUSED */
66 int
67 executemacro(int f, int n)
68 {
69 	int	 i, j, flag, num;
70 	PF	 funct;
71 
72 	if (macrodef ||
73 	    (macrocount >= MAXMACRO && macro[MAXMACRO - 1].m_funct
74 	    != finishmacro)) {
75 		ewprintf("Macro too long. Aborting.");
76 		return (FALSE);
77 	}
78 
79 	if (macrocount == 0)
80 		return (TRUE);
81 
82 	inmacro = TRUE;
83 
84 	for (i = n; i > 0; i--) {
85 		maclcur = maclhead->l_fp;
86 		flag = 0;
87 		num = 1;
88 		for (j = 0; j < macrocount - 1; j++) {
89 			funct = macro[j].m_funct;
90 			if (funct == universal_argument) {
91 				flag = FFARG;
92 				num = macro[++j].m_count;
93 				continue;
94 			}
95 			if ((*funct)(flag, num) != TRUE) {
96 				inmacro = FALSE;
97 				return (FALSE);
98 			}
99 			lastflag = thisflag;
100 			thisflag = 0;
101 			flag = 0;
102 			num = 1;
103 		}
104 	}
105 	inmacro = FALSE;
106 	return (TRUE);
107 }
108 #endif	/* NO_MACRO */
109