xref: /openbsd/usr.bin/mg/macro.c (revision a6445c1d)
1 /*	$OpenBSD: macro.c,v 1.15 2014/03/20 07:47:29 lum Exp $	*/
2 
3 /* This file is in the public domain. */
4 
5 /*
6  *	Keyboard macros.
7  */
8 
9 #include "def.h"
10 #include "key.h"
11 #include "macro.h"
12 
13 int inmacro = FALSE;	/* Macro playback in progess */
14 int macrodef = FALSE;	/* Macro recording in progress */
15 int macrocount = 0;
16 
17 struct line *maclhead = NULL;
18 struct line *maclcur;
19 
20 union macrodef macro[MAXMACRO];
21 
22 /* ARGSUSED */
23 int
24 definemacro(int f, int n)
25 {
26 	struct line	*lp1, *lp2;
27 
28 	macrocount = 0;
29 
30 	if (macrodef) {
31 		ewprintf("already defining macro");
32 		return (macrodef = FALSE);
33 	}
34 
35 	/* free lines allocated for string arguments */
36 	if (maclhead != NULL) {
37 		for (lp1 = maclhead->l_fp; lp1 != maclhead; lp1 = lp2) {
38 			lp2 = lp1->l_fp;
39 			free(lp1);
40 		}
41 		free(lp1);
42 	}
43 
44 	if ((maclhead = lp1 = lalloc(0)) == NULL)
45 		return (FALSE);
46 
47 	ewprintf("Defining Keyboard Macro...");
48 	maclcur = lp1->l_fp = lp1->l_bp = lp1;
49 	return (macrodef = TRUE);
50 }
51 
52 /* ARGSUSED */
53 int
54 finishmacro(int f, int n)
55 {
56 	if (macrodef == TRUE) {
57 		macrodef = FALSE;
58 		ewprintf("End Keyboard Macro Definition");
59 		return (TRUE);
60 	}
61 	return (FALSE);
62 }
63 
64 /* ARGSUSED */
65 int
66 executemacro(int f, int n)
67 {
68 	int	 i, j, flag, num;
69 	PF	 funct;
70 
71 	if (macrodef ||
72 	    (macrocount >= MAXMACRO && macro[MAXMACRO - 1].m_funct
73 	    != finishmacro)) {
74 		dobeep();
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