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