⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macro.c

📁 举世闻名的joe记事本源程序
💻 C
字号:
/* *	Keyboard macros *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"MACRO *freemacros = NULL;/* Create a macro */MACRO *mkmacro(int k, int flg, int n, CMD *cmd){	MACRO *macro;	if (!freemacros) {		int x;		macro = (MACRO *) joe_malloc(sizeof(MACRO) * 64);		for (x = 0; x != 64; ++x) {			macro[x].steps = (MACRO **) freemacros;			freemacros = macro + x;		}	}	macro = freemacros;	freemacros = (MACRO *) macro->steps;	macro->steps = NULL;	macro->size = 0;	macro->flg = flg;	macro->n = n;	macro->cmd = cmd;	macro->k = k;	return macro;}/* Eliminate a macro */void rmmacro(MACRO *macro){	if (macro) {		if (macro->steps) {			int x;			for (x = 0; x != macro->n; ++x)				rmmacro(macro->steps[x]);			joe_free(macro->steps);		}		macro->steps = (MACRO **) freemacros;		freemacros = macro;	}}/* Add a step to block macro */void addmacro(MACRO *macro, MACRO *m){	if (macro->n == macro->size) {		if (macro->steps)			macro->steps = (MACRO **) joe_realloc(macro->steps, (macro->size += 8) * sizeof(MACRO *));		else			macro->steps = (MACRO **) joe_malloc((macro->size = 8) * sizeof(MACRO *));	}	macro->steps[macro->n++] = m;}/* Duplicate a macro */MACRO *dupmacro(MACRO *mac){	MACRO *m = mkmacro(mac->k, mac->flg, mac->n, mac->cmd);	if (mac->steps) {		int x;		m->steps = (MACRO **) joe_malloc((m->size = mac->n) * sizeof(MACRO *));		for (x = 0; x != m->n; ++x)			m->steps[x] = dupmacro(mac->steps[x]);	}	return m;}/* Set key part of macro */MACRO *macstk(MACRO *m, int k){	m->k = k;	return m;}/* Set flg part of macro */MACRO *macsta(MACRO *m, int a){	m->flg = a;	return m;}/* Parse text into a macro * sta is set to:  ending position in buffer for no error. *                 -1 for syntax error *                 -2 for need more input */MACRO *mparse(MACRO *m, unsigned char *buf, int *sta){	int y, c, x = 0;      macroloop:	/* Skip whitespace */	while (joe_isblank(locale_map,buf[x]))		++x;	/* Do we have a string? */	if (buf[x] == '\"') {		++x;		while (buf[x] && buf[x] != '\"') {			if (buf[x] == '\\' && buf[x + 1]) {				++x;				switch (buf[x]) {				case 'n':					buf[x] = 10;					break;				case 'r':					buf[x] = 13;					break;				case 'b':					buf[x] = 8;					break;				case 'f':					buf[x] = 12;					break;				case 'a':					buf[x] = 7;					break;				case 't':					buf[x] = 9;					break;				case 'x':					c = 0;					if (buf[x + 1] >= '0' && buf[x + 1] <= '9')						c = c * 16 + buf[++x] - '0';					else if ((buf[x + 1] >= 'a' && buf[x + 1] <= 'f') || (buf[x + 1] >= 'A' && buf[x + 1] <= 'F'))						c = c * 16 + (buf[++x] & 0xF) + 9;					if (buf[x + 1] >= '0' && buf[x + 1] <= '9')						c = c * 16 + buf[++x] - '0';					else if ((buf[x + 1] >= 'a' && buf[x + 1] <= 'f') || (buf[x + 1] >= 'A' && buf[x + 1] <= 'F'))						c = c * 16 + (buf[++x] & 0xF) + 9;					buf[x] = c;					break;				case '0':				case '1':				case '2':				case '3':				case '4':				case '5':				case '6':				case '7':				case '8':				case '9':					c = buf[x] - '0';					if (buf[x + 1] >= '0' && buf[x + 1] <= '7')						c = c * 8 + buf[++x] - '0';					if (buf[x + 1] >= '0' && buf[x + 1] <= '7')						c = c * 8 + buf[++x] - '0';					buf[x] = c;					break;				}			}			if (m) {				if (!m->steps) {					MACRO *macro = m;					m = mkmacro(-1, 0, 0, NULL);					addmacro(m, macro);				}			} else				m = mkmacro(-1, 0, 0, NULL);			addmacro(m, mkmacro(buf[x], 0, 0, findcmd(USTR "type")));			++x;		}		if (buf[x] == '\"')			++x;	}	/* Do we have a command? */	else {		for (y = x; buf[y] && buf[y]!='#' && buf[y] != '!' &&		            buf[y] != '~' && buf[y] !='-' && buf[y] != ',' &&		            buf[y] != ' ' && buf[y] != '\t' &&		            buf[y] != '\n' && buf[x] != '\r'; ++y) ;		if (y != x) {			CMD *cmd;			int flg = 0;			c = buf[y];			buf[y] = 0;			cmd = findcmd(buf + x);			buf[x = y] = c;			/* Parse flags */			while (buf[x]=='-' || buf[x]=='!' || buf[x]=='#' || buf[x]=='~') {				if (buf[x]=='-') flg |= 1;				if (buf[x]=='!') flg |= 2;				if (buf[x]=='#') flg |= 4;				if (buf[x]=='~') flg |= 8;				++x;			}			if (!cmd) {				*sta = -1;				return NULL;			} else if (m) {				if (!m->steps) {					MACRO *macro = m;					m = mkmacro(-1, 0, 0, NULL);					addmacro(m, macro);				}				addmacro(m, mkmacro(-1, flg, 0, cmd));			} else				m = mkmacro(-1, flg, 0, cmd);		}	}	/* Skip whitespace */	while (joe_isblank(locale_map,buf[x]))		++x;	/* Do we have a comma? */	if (buf[x] == ',') {		++x;		while (joe_isblank(locale_map,buf[x]))			++x;		if (buf[x] && buf[x] != '\r' && buf[x] != '\n')			goto macroloop;		*sta = -2;		return m;	}	/* Done */	*sta = x;	return m;}/* Convert macro to text */static unsigned char *ptr;static int first;static int instr;unsigned char *unescape(unsigned char *ptr, int c){	if (c == '"') {		*ptr++ = '\\';		*ptr++ = '"';	} else if (c == '\\') {		*ptr++ = '\\';		*ptr++ = '\\';	} else if (c == '\'') {		*ptr++ = '\\';		*ptr++ = '\'';	} else if (c < 32 || c > 126) {		/* FIXME: what if c > 256 or c < 0 ? */		*ptr++ = '\\';		*ptr++ = 'x';		*ptr++ = "0123456789ABCDEF"[c >> 4];		*ptr++ = "0123456789ABCDEF"[c & 15];	} else		*ptr++ = c;	return ptr;}static void domtext(MACRO *m){	int x;	if (!m)		return;	if (m->steps)		for (x = 0; x != m->n; ++x)			domtext(m->steps[x]);	else {		if (instr && zcmp(m->cmd->name, USTR "type")) {			*ptr++ = '\"';			instr = 0;		}		if (first)			first = 0;		else if (!instr)			*ptr++ = ',';		if (!zcmp(m->cmd->name, USTR "type")) {			if (!instr) {				*ptr++ = '\"';				instr = 1;			}			ptr = unescape(ptr, m->k);		} else {			for (x = 0; m->cmd->name[x]; ++x)				*ptr++ = m->cmd->name[x];			if (!zcmp(m->cmd->name, USTR "play") || !zcmp(m->cmd->name, USTR "gomark") || !zcmp(m->cmd->name, USTR "setmark") || !zcmp(m->cmd->name, USTR "record") || !zcmp(m->cmd->name, USTR "uarg")) {				*ptr++ = ',';				*ptr++ = '"';				ptr = unescape(ptr, m->k);				*ptr++ = '"';			}		}	}}unsigned char *mtext(unsigned char *s, MACRO *m){	ptr = s;	first = 1;	instr = 0;	domtext(m);	if (instr)		*ptr++ = '\"';	*ptr = 0;	return s;}/* Keyboard macro recorder */static MACRO *kbdmacro[10];static int playmode[10];struct recmac *recmac = NULL;static void unmac(void){	if (recmac)		rmmacro(recmac->m->steps[--recmac->m->n]);}void chmac(void){	if (recmac && recmac->m->n)		recmac->m->steps[recmac->m->n - 1]->k = 3;}static void record(MACRO *m){	if (recmac)		addmacro(recmac->m, dupmacro(m));}static int ifdepth=0;		/* JM: Nesting level of if cmds */static int ifflag=1;		/* JM: Truth flag for if */static int iffail=0;		/* JM: Depth where ifflag became 0 *//* Suspend macro record/play to allow for user input. * * Stop recording current macro, make recursive call to edit loop, which * runs until dialog is complete, then continue with macro recording. * * When the macro is played, edit loop is run as a subroutine until dialog * is complete, then uquery returns, which continues macro execution. * * Completion of a dialog is indicated with 'notify' flag

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -