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

📄 xcscrpt.c

📁 支持X/YModem和cis_b+协议的串口通讯程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	xcscrpt.c -- script interpreter module for XC");	This file uses 4-character tabstops	Author: larry gensch, December 1987	Major rewrite: fred buck, Jan 1989	Binding code: larry gensch, September 1991	This code is released to the public domain*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <sys/timeb.h>#include <time.h>#include <ctype.h>#include <signal.h>#include <setjmp.h>#include <sys/stat.h>#include "xc.h"extern FILE	*cfp;extern short	eofflag;static jmp_buf 	here;short		linkflag, scriptflag;static short	ttyflag, debugflag, 		mrbstart,	/* ring buffer start pointer */		mrbcount,	/* ring buffer counter */		BREAK = 0;	/* a hook for a later 'trap' keyword */int my_escape = 1; /* Control-A; resettable at run-time */static char mringbuf[LG_BUFF];	/* ring buffer for modem input */static int  S_abort P_((void));static void unsetall P_((void)), S_bombout P_((void)), S_call P_((char *sname));static char *NO_ARG = "%s command must have an argument";static bindfunc_t find_function P_((char *fname)); /* bindfunc_t : see xc.h */typedef struct bindstruct {	int					bs_c;		/* Character prefix */	int					bs_function;/* Function code */	char				*bs_string;	/* String/script to emit */	struct bindstruct	*bs_next;	/* Pointer to next entry */} binding_t;static binding_t *first_binding = NIL(binding_t);typedef struct {	bindfunc_t	bf_function;/* Function code */	char		*bf_name;	/* bind_function() name */	char		*bf_string;	/* String/script assigned */} bindstr_t;static bindstr_t function_list[] = {	{ENDCHAR, "endchar", "Exit terminal mode"},	{QUITCHR, "quitchr", "Quit program"},	{CAPTYES, "captyes", "Turn on terminal mode capture"},	{CAPTEND, "captend", "Turn off terminal mode capture"},	{DIVCHAR, "divchar", "Send file through modem"},	{DIALCHR, "dialchr", "Dial from phonelist"},	{HUPCHAR, "hupchar", "Hang up modem"},	{SCRPCHR, "scrpchr", "Prompt for script file"},	{HLPCHAR, "hlpchar", "Display terminal mode key bindings"},	{BRKCHAR, "brkchar", "Send modem BREAK signal"},	{EMITSTR, "emitstr", "Emit string"},	{CLRGRAF, "clrgraf", "Reset crt and turn off line graphics"},			{DOSCRPT, "doscrpt", "Execute script file"},	{SENDCAN, "sendcan", "Send CAN string to cancel transfer"}};#define FUNCTION_COUNT (sizeof(function_list) / sizeof(function_list[0]))static RETSIGTYPE newsigint(junk)int junk;{	eofflag++;	show_abort();	S_bombout();	longjmp(here,1);}void do_script(file)char *file;{	RETSIGTYPE (*oldvec) P_((int));	capture = eofflag = FALSE;	ttyflag = scriptflag = TRUE;	oldvec = signal(SIGINT, newsigint);	if (!setjmp(here))		S_call(file);	unsetall();	if (capture)		capture = FALSE,		fclose(cfp);	linkflag = scriptflag = FALSE;	signal(SIGINT, oldvec);}static int k_seen(bytes,fword)long bytes;char *fword;{	int i, j, k;	char *cptr;	cptr = fword;	if (!fword || !*fword)		sprintf(Msg,NO_ARG,"SEEN"),		S2(Msg);	j = mrbstart - 1;	if (bytes<=0 || bytes>LG_BUFF)		bytes = LG_BUFF;	k = mrbcount - bytes;	/* check only most recent 'bytes' bytes */	i = 0;	while ((i++)<mrbcount){		++j;		j = j % LG_BUFF;		if (i<k)			continue;		if (mringbuf[j] != *cptr){			cptr = fword;			continue;		}		if (*(++cptr)=='\0')			return SUCCESS;	}	return FAILURE;}intk_waitfor(interval,fword)long interval;char *fword;{	register c, i = -1 ;	register time_t limit, waitfor_msec = 0;	char *ptr;	mrbstart = mrbcount = 0;	sprintf(line,"\"%s\"",fword);	lptr = line;	getword();	lc_word(word);	ptr = word;	if (interval < -1){		waitfor_msec = -interval;		goto SPITOUT;	}	if (!fword || word[0] == '\0'){		sprintf(Msg,NO_ARG,"WAITFOR");		S2(Msg);		return FAILURE;	}	waitfor_msec = 1000 * ((interval > 0) ? interval : 30);	eofflag = FALSE;SPITOUT: limit = mtime() + waitfor_msec;	while (limit >= mtime() && !eofflag){		if ((c = readbyte(1)) == -1)			continue;		if (cismode && c==ENQ){			s_cis();			goto SPITOUT;		}		++i;		i = i % LG_BUFF;		mringbuf[i] = c;		mrbstart = mrbstart % LG_BUFF;		if (mrbcount<LG_BUFF)			++mrbcount;		else			++mrbstart,			mrbstart = mrbstart % LG_BUFF;		if (ttyflag)			fputc(c,tfp);		if (capture && c != '\r')			fputc(c,cfp);		if (tolower(c) != *ptr){			ptr = word;			continue;		}		if (*++ptr == '\0')			return SUCCESS;	}	return FAILURE;}static intk_transmit(junk,fword)long junk;char *fword;{	sprintf(line,"\"%s\"",fword);	lptr = line;	getword();	if (!fword || word[0] == '\0'){		sprintf(Msg,NO_ARG,"TRANSMIT");		S2(Msg);		return FAILURE;	}	send_string(word);	return SUCCESS;}static intk_pause(pause_time,junk)long pause_time;char *junk;{	pause_time = pause_time ? pause_time : 5;	sleep((unsigned)pause_time);	return SUCCESS;}static intk_dial(junk,fword)long junk;char *fword;{	sprintf(line,"%s",fword);	lptr = line;	getword();	if (!fword || word[0] == '\0'){		sprintf(Msg,NO_ARG,"DIAL");		S2(Msg);		return FAILURE;	}	xcdial(word);	return SUCCESS;}static intk_capture(junk,fword)long junk;char *fword;{	int val = capture;	sprintf(word,"capture");	sprintf(line,"%s",fword);	lptr = line;	set_onoff(&capture);	if (val == capture)		return SUCCESS;	if (!capture)		fclose(cfp);	else {		if (!(cfp = fopen(captfile, "a"))){			sprintf(Msg,"Can't open capture file %s",captfile);			S2(Msg);			eofflag++;			return FAILURE;		}		setbuf(cfp,NIL(char));	}	return SUCCESS;}static intk_debug(junk,fword)long junk;char *fword;{	sprintf(word,"debug");	sprintf(line,"%s",fword);	lptr = line;	set_onoff(&debugflag);	return SUCCESS;}static intk_tty(junk,fword)long junk;char *fword;{	sprintf(word,"tty");	sprintf(line,"%s",fword);	lptr = line;	set_onoff(&ttyflag);	return SUCCESS;}static intk_type(junk,fword)long junk;char *fword;{	sprintf(line,"%s",fword);	lptr = line;	getword();	if (!fword || word[0] == '\0'){		sprintf(Msg,NO_ARG,"TYPE");		S2(Msg);		return FAILURE;	}	divert(TRUE);	return SUCCESS;}static intk_linked(){	return linkflag;}/*	unbind_key() removes the binding attached to the keycode specified by (c).*/static void unbind_key(c)int c;{	binding_t *ptr = first_binding, *prev = NIL(binding_t);	if (!ptr)		return;	while (ptr) {		if (ptr->bs_c == c) {			if (ptr->bs_string)				free(ptr->bs_string);			if (prev)				prev->bs_next = ptr->bs_next;			else				first_binding->bs_next = ptr->bs_next;			free(ptr);			return;		}		prev = ptr;		ptr = ptr->bs_next;	}}/*	bind_key() binds the key whose ASCII code is specified by (c) to the	function whose code is specified by (function). Emit strings	(for EMITSTR) and script names (for DOSCRPT) are specified by (string).*/static void bind_key(c,function,string)int c;int function;char *string;{	binding_t *ptr = (binding_t *) malloc(sizeof(binding_t)), *curr, *prev;	if (!ptr) {			S2("BIND_KEY allocation error");			S_abort();	}	unbind_key(c);	ptr->bs_c = c;	ptr->bs_function = function;	ptr->bs_string = xc_strdup(string);	/* The following is an insertion sort to ensure that the bindings are	   stored in ascending sequence by key code.  This makes	   show_bindings()'s display easier to read. -lg	*/	for (prev = NIL(binding_t), curr = first_binding;		curr != NIL(binding_t);		prev = curr, curr = curr->bs_next) {		if (ptr->bs_c < curr->bs_c) {			if (!prev) {				ptr->bs_next = first_binding;				first_binding = ptr;				break;			} else {				ptr->bs_next = curr;				prev->bs_next = ptr;				break;			}		}	}	if (curr == NIL(binding_t)) {		if (!prev)			first_binding = ptr;		else			prev->bs_next = ptr;		ptr->bs_next = NIL(binding_t);	}}/*	bind_function() Binds the key whose code is represented by the value in	(n) to execute the XC builtin function whose name is pointed to be (cptr).	Any previous binding of the specified keycode is forgotten.	This routine is designed to be an XC script builtin.*/static intbind_function(n,cptr)long n;char *cptr;{	int c;	bindfunc_t code;	if (n < 1L || n > 127L) {		sprintf(Msg,"Invalid key code %ld in BIND_FUNCTION command",n);		S2(Msg);		return FAILURE;	}	c = tolower((int) n);	sprintf(line, "\"%s\"", cptr);	lptr = line;	getword();	if (cptr && cptr[0] != '\0') {		lc_word(word);		code = find_function(word);		if (code == BADFUNC) {			sprintf(Msg,"Invalid function name '%s' in BIND_FUNCTION command",			word);			S2(Msg);			return FAILURE;		}		bind_key(c, code, word);	} else {		sprintf(Msg,NO_ARG,"BIND_FUNCTION");		S2(Msg);		return FAILURE;	}	return SUCCESS;}/*	bind_string() binds the key whose code is represented by the	decimal value in (n) to emit the string pointed to by (cptr).	Any previous binding of the specified keycode is forgotten.	This routine is designed to be an XC script builtin.*/static intbind_string(n,cptr)long n;char *cptr;{	int c;	if (n < 1L || n > 127L) {		sprintf(Msg,"Invalid key code %ld in BIND_STRING command",n);		S2(Msg);		return FAILURE;	}	c = tolower((int) n);	sprintf(line, "\"%s\"", cptr);	lptr = line;	getword();	if (cptr && cptr[0] != '\0')		bind_key(c, EMITSTR, word);	else {		sprintf(Msg,NO_ARG,"BIND_STRING");		S2(Msg);		return FAILURE;	}	return SUCCESS;}/*	bind_script() binds the key whose code is represented by the value in	(n) to execute the XC script whose name is pointed to by (cptr).	Any previous binding of the specified keycode is forgotten.	This routine is designed to be an XC script builtin.*/static intbind_script(n,cptr)long n;char *cptr;{	int c;	if (n < 1L || n > 127L) {		sprintf(Msg,"Invalid key code %ld in BIND_STRING command",n);		S2(Msg);		return FAILURE;	}	c = tolower((int) n);	sprintf(line, "\"%s\"", cptr);	lptr = line;	getword();	if (cptr && cptr[0] != '\0')		bind_key(c, DOSCRPT, word);	else {		sprintf(Msg,NO_ARG,"BIND_SCRIPT");		S2(Msg);		return FAILURE;	}	return SUCCESS;}/*	Variables Section *//*	Most of the variable-handling logic is credit: Steve Manes 1987 */#define VNAMELEN	16	/* maximum name length for variables */#define VMAXSIZE	256	/* maximum length for CHAR variable */#define VMAXVARS	30	/* maximum number of user variables */#define VCHAR		'C'	/* CHARACTER variable type */#define VNUM		'N'	/* NUMERIC variable type (always 'long') *//* Variable structure */typedef struct var {	char name[VNAMELEN+1];	/* variable name */	struct var	*next;		/* ptr to next structure in var_list */	char type;				/* variable type */	union {					/* pointer to CHAR or NUM/DATE */		char str[VMAXSIZE+1];		long num;	} u;} VAR;static VAR	*Varlist = NIL(VAR);	/* top of variable list */static VAR	*Lastvar = NIL(VAR);	/* bottom of variable list *//* Valid variable name characters */static unsigned char OKname[]= {	 /* control characters */	  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	 /* ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ */		1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,	 /* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` */		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,	 /* a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~	   */		1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0};/*	Return pointer to VAR structure for User or System variable	'name', otherwise return NIL(VAR).	Variable contents in vp->u.[str|num]*/static VAR *findvar(name)char *name;{	static	VAR *vp;	/* pointer to output structure */	if (!name || !*name || !Varlist)		return NIL(VAR);	vp = Varlist;	while (vp){		if (!strncmp(name, vp->name, VNAMELEN) )			return vp;		vp = vp->next;	}	return NIL(VAR);				/* not found */}/*	Delete User variable 'name' from VAR list.	If variable doesn't exist, no error is returned*/static void unsetvar(name)char *name;{	VAR *p;	VAR *lastp = NULL ;	if (!name || !*name)		return;	for (p=Varlist; p; lastp = p, p = p->next){		if (!strncmp(name, p->name, VNAMELEN) ){	/* name match? */			if (Varlist == Lastvar)					/* only 1 variable */				Varlist = Lastvar = NIL(VAR);		/* in list */			else if (p == Varlist)					/* first variable */				Varlist = p->next;			else {				lastp->next = p->next;				/* dump variable in middle													   of list */				if (p == Lastvar)					/* or last object */					Lastvar = lastp;				/* in list */			}			free(p);			/* reclaim memory */			break;		}	}}/*	Set the value of User variable 'name' to 'val' with 'type'.	If variable exists, change its contents. Otherwise, create it.	Returns: FAILURE or SUCCESS*/static intsetvar(name,type,str,val)char *name;char type;char *str;long *val;{	VAR *vp;	short i;	if (!name || !*name)		return FAILURE;	if (!(vp = findvar(name))){ /* create new variable */		for (i=0; i < VNAMELEN && name[i]; i++){			if( !OKname[(name[i] & 0x7F)] || isdigit(name[0]) ){				sprintf(Msg,"Illegal variable name '%s'",name);				S_abort();			}		}		if (!(vp = (VAR *)malloc(sizeof(VAR)))){			sprintf(Msg,"%s: allocation error",name);			S2(Msg);			return FAILURE;		}		lc_word(name);		strncpy(vp->name, name, VNAMELEN);	/* set vari name */		vp->next = NIL(VAR);				/* flag 'no next' */		if (!Varlist)			Varlist = vp;					/* first variable */		else			Lastvar->next = vp;				/* add this to the list */		Lastvar = vp;						/* set 'last' pointer */	}	if (type == VCHAR)		strncpy(vp->u.str, str, VMAXSIZE);	else		vp->u.num = *val;	vp->type = type;	return SUCCESS;}/*	Unset all user variables, deallocating memory.	No error returned*/static void unsetall(){	VAR *p;	VAR *nextp;	if (!Varlist)		return;	p = Varlist;	while (p->next){		nextp = p->next;		free(p);		p = nextp;	}	Varlist = Lastvar = NIL(VAR);}/*	end variables section *//*	Action Primitives */static struct {	char *name;	int (*funcptr)();} s_acttab[] = {	{"beep",		beep},

⌨️ 快捷键说明

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