1 /* $OpenBSD: macro.c,v 1.18 2023/03/08 04:43:11 guenther 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 progress */
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 int
definemacro(int f,int n)28 definemacro(int f, int n)
29 {
30 struct line *lp1, *lp2;
31
32 macrocount = 0;
33
34 if (macrodef) {
35 ewprintf("already defining macro");
36 return (macrodef = FALSE);
37 }
38
39 /* free lines allocated for string arguments */
40 if (maclhead != NULL) {
41 for (lp1 = maclhead->l_fp; lp1 != maclhead; lp1 = lp2) {
42 lp2 = lp1->l_fp;
43 free(lp1);
44 }
45 free(lp1);
46 }
47
48 if ((maclhead = lp1 = lalloc(0)) == NULL)
49 return (FALSE);
50
51 ewprintf("Defining Keyboard Macro...");
52 maclcur = lp1->l_fp = lp1->l_bp = lp1;
53 return (macrodef = TRUE);
54 }
55
56 int
finishmacro(int f,int n)57 finishmacro(int f, int n)
58 {
59 if (macrodef == TRUE) {
60 macrodef = FALSE;
61 ewprintf("End Keyboard Macro Definition");
62 return (TRUE);
63 }
64 return (FALSE);
65 }
66
67 int
executemacro(int f,int n)68 executemacro(int f, int n)
69 {
70 int i, j, flag, num;
71 PF funct;
72
73 if (macrodef ||
74 (macrocount >= MAXMACRO && macro[MAXMACRO - 1].m_funct
75 != finishmacro)) {
76 dobeep();
77 ewprintf("Macro too long. Aborting.");
78 return (FALSE);
79 }
80
81 if (macrocount == 0)
82 return (TRUE);
83
84 inmacro = TRUE;
85
86 for (i = n; i > 0; i--) {
87 maclcur = maclhead->l_fp;
88 flag = 0;
89 num = 1;
90 for (j = 0; j < macrocount - 1; j++) {
91 funct = macro[j].m_funct;
92 if (funct == universal_argument) {
93 flag = FFARG;
94 num = macro[++j].m_count;
95 continue;
96 }
97 if ((*funct)(flag, num) != TRUE) {
98 inmacro = FALSE;
99 return (FALSE);
100 }
101 lastflag = thisflag;
102 thisflag = 0;
103 flag = 0;
104 num = 1;
105 }
106 }
107 inmacro = FALSE;
108 return (TRUE);
109 }
110