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