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

📄 xcscrpt.c

📁 支持X/YModem和cis_b+协议的串口通讯程序
💻 C
📖 第 1 页 / 共 3 页
字号:
				continue;			case VARNAME:				if (tok_value.varptr->type != VCHAR)					sprintf(cptr,"%ld",tok_value.varptr->u.num);				else					sprintf(cptr,"%s",tok_value.varptr->u.str);				cptr += strlen(cptr);				continue;			default:				S_abort();		}		break;	}	return newstring;}/*		stack protection and break/continue stuff */static int	nest_while,		/* number of nested loops */			nest_parse,		/* number of nested calls to S_parse() */			nest_cmd;		/* number of nested commands */static time_t deadline;		/* deadline for 'timeout' keyword */static jmp_buf env;		/* cell for environment, setjmp */#define CMDNEST		8		/* max number of nested scripts */#define PARSNEST	50		/* max number of nested calls to parser */static char *areas[CMDNEST];#define DNP		--nest_parse#define BCCHK(x) if(x==SBREAK||x==SCONTNUE){DNP;return(nest_while?x:S_abort());}/* cleanup any debris left after a non-trapped keyboard interrupt */static void S_bombout(){	int i;	for (i=0; i<nest_cmd; ++i){		if (areas[i])			free(areas[i]),			areas[i] = NIL(char);	}	nest_cmd = nest_while = nest_parse = 0;	deadline = 0;}/*	S_parse() */static char	*intercom,		/* last previous value of S_parse program ctr */			*tvector;		/* trap vector */static FILE *savetfp;		/* to stash tfp when tfp redirected */static intS_parse(p_pc, t_invoke)char *p_pc;TOK_TYPE t_invoke;{	long n;					/* "leading" number for primitives */	int i,		status,				/* status of last performed operation */		retval,				/* value to be returned by this function */		testing,			/* flag set if within 'if' or 'while' clause */		direction,			/* if 1, increment, if -1, decrement */		w_status,			/* used to correct nest_parse in 'while' */		counter,			/* for WHILE and IF, to track keywords */		negating;			/* ! operator in effect for comparisons */	char *cptr, *S_WHILE, *S_DO, *S_DONE;	TOK_TYPE nexttype;	VAR *varptr1;	++nest_parse;	testing = (t_invoke==THEN || t_invoke==DO);	retval = status = negating = FALSE;	n = -1;	counter = 0;	while (TRUE){		/* we come through here only at the beginning of expressions */		if (deadline){			if (time(0)>deadline){		/* deadline; exit current script */				deadline = 0;				longjmp(env,TIMEOUT);			}		}		if (BREAK && tvector && t_invoke!=ENDTRAP)	/* interrupt trap */			BREAK = FALSE,			cptr = tvector,			status = S_parse(cptr,ENDTRAP),			DNP;		BREAK = FALSE;		retval = testing ? (retval || status) : status;		direction = 1;		intercom = p_pc;		nexttype = lexan(&p_pc);				/* check for list terminator */		if (nexttype==t_invoke || (t_invoke==ENDIF && nexttype==ELSE)){			if (debugflag && testing)				fprintf(tfp,"\r\n\t\t\t\t\t\t\tCondition: %s\r\n",					retval ? "TRUE" : "FALSE");			return retval;		}		switch (nexttype){			case NULLTOK:		/* inconsistent list terminators */			case DO:								/**/			case DONE:								/**/			case THEN:								/**/			case ELSE:								/**/			case ENDIF:								/**/			case TTERROR:							/**/			case EFLAG:			/* not at beginning of expressions */			case EQ:								/**/			case NEQ:								/**/			case MORETHAN:							/**/			case LESSTHAN:							/**/				S_abort();			case LITERAL:				if (!testing)					S_abort();				status = !!strlen(tok_value.strptr);				if (negating)					status = !status;				continue;			case NEGATE:				if (!testing || negating)					S_abort();				negating = 1;				continue;			case NUMBER:				if (n!=(-1))					S_abort();				n = tok_value.numval;				continue;			case TERMINAT:				negating = 0;				continue;			case ACTION:				status = S_perform(&p_pc);				if (negating)					status = !status;				break;			case AFFIRM:				status = S_affirm();				if (negating)					status = !status;				break;			case SBREAK:			case SCONTNUE:				if (testing || t_invoke==NULLTOK)					S_abort();				return(nexttype==SBREAK ? SBREAK : SCONTNUE);			case CALL:				lexan(&p_pc);				i = nest_while;				nest_while = 0;				S_call(S_qstrip(tok_value.strptr));				DNP;				nest_while = i;				break;			case COMMENT:				continue;			case DECR:				direction = (-1);		/* and fall through to... */			case INCR:				if ((nexttype=lexan(&p_pc))!=VARNAME)					S_abort();				if ((tok_value.varptr->type) != VNUM){					sprintf(Msg,"Error: %s is not a numeric variable",						tok_value.varptr->name);					S_abort();				}				status = S_addsub(direction);				if (negating) status =					!status;				break;			case ECHOS:				status = 1;				if ((nexttype = lexan(&p_pc))==EFLAG)					status = 0;				else					p_pc = intercom,					lexan(&p_pc);				cptr = S_construct(&p_pc);				fprintf(tfp,"%s",cptr);				if (status)					if (tfp != cfp)						fputc('\r',tfp),					fputc('\n',tfp);				else					status = 1;				break;			case EXIT:				longjmp(env,EXIT);			case READ:				status = S_read(&p_pc);				break;			case SET:				status = S_set(&p_pc);				if (negating)					status = !status;				break;			case SHELL:				sprintf(word,"!");				sprintf(line,"%s",S_construct(&p_pc));				if (tfp==cfp)					sprintf(&line[strlen(line)]," >>%s",captfile);				lptr = line;				status = !s_shell();				if (negating)					status = !status;				break;			case PIPE:				sprintf(word,"$");				sprintf(line,"%s",S_construct(&p_pc));				lptr = line;				status = !s_shell();				if (negating)					status = !status;				break;			case SFILE:				savetfp = tfp;				if (!capture){					S2("Capture option not on");					while ((nexttype=lexan(&p_pc))!=TERMINAT &&						nexttype != NULLTOK);					break;				}				tfp = cfp;				status = S_parse(p_pc,TERMINAT);				if (negating)					status = !status;				DNP;				while ((nexttype=lexan(&p_pc)) !=TERMINAT &&					nexttype != NULLTOK)					;				tfp = savetfp;				fseek(cfp,0L,2);				break;			case STRUE:			case SFALSE:				status = (nexttype==STRUE);				intercom = p_pc;				if ((nexttype=(lexan(&p_pc)))!=TERMINAT && nexttype!=NULLTOK)						S_abort();				if (negating)					status = !status;				break;			case STRAP:				tvector = p_pc;				cptr = tvector;				while ((nexttype=lexan(&p_pc))!=ENDTRAP)					if (nexttype==NULLTOK)						S_abort();				break;			case TIMEOUT:				if ((nexttype=lexan(&p_pc))!=NUMBER)					S_abort();				if (tok_value.numval>=0){					deadline = 0;					if (tok_value.numval)						deadline = time(0) + (tok_value.numval*60);				}				while ((nexttype=lexan(&p_pc))!=TERMINAT && nexttype!=NULLTOK)					;				break;			case UNSET:				if ((nexttype=lexan(&p_pc))!=VARNAME)					S_abort();				status = 1;				unsetvar(tok_value.varptr->name);				break;			case UNTRAP:				tvector = NIL(char);				if ((nexttype=lexan(&p_pc))!=TERMINAT)					S_abort();				break;			case XCSET:				i = 0;				line[0] = '\0';				while (*p_pc!='\n')					line[i++] = *(p_pc++);				line[i] = '\0';				lptr = line;				s_set();				break;			case VARNAME:				varptr1 = tok_value.varptr;				if (!testing){					if (varptr1->type==VCHAR || n!=(-1))						S_abort();					n = varptr1->u.num;					continue;				}				status = S_varcmp(varptr1,&p_pc);				if (negating)					status = !status;				break;			case IF:				if (nest_parse > PARSNEST){					sprintf(Msg,"Nesting level too deep");					S_abort();				}				status = S_parse(p_pc,THEN);				DNP;				if (status==TRUE){					lexan(&intercom);					p_pc = intercom;					status = S_parse(p_pc,ENDIF);					BCCHK(status)					DNP;					cptr = intercom;					nexttype = lexan(&cptr);					p_pc = cptr;					if (nexttype==ELSE){						counter = 0;						while (TRUE){							switch ((nexttype=lexan(&cptr))){								case IF:									++counter;									continue;								case ENDIF:									if (counter){										--counter;										continue;									}									p_pc = cptr;									break;								case NULLTOK:									S_abort();								default:									continue;							}							break;						} /* now p_pc points to just after matching 'endif' */					}				}				else {	/* intercom is now the THEN token */					counter = 0;					cptr = intercom;					while (TRUE){						switch ((nexttype=lexan(&cptr))){							case IF:								++counter;								continue;							case ELSE:							case ENDIF:								if (counter){									--counter;									continue;								}								p_pc = cptr;								break;							case NULLTOK:								S_abort();							default:								continue;						}						break;					}					if (nexttype==ELSE){						status = S_parse(p_pc,ENDIF);						BCCHK(status)						DNP;						p_pc = intercom;						lexan(&p_pc);					}					/* p_pc now points to just after ENDIF */				}				break;			case WHILE:				if (nest_parse > PARSNEST){					sprintf(Msg,"Nesting level too deep");					S_abort();				}				S_WHILE = p_pc;				S_DO = S_DONE = NIL(char);				while ((w_status=S_parse(S_WHILE,DO))==TRUE){					DNP;					--nest_while;					if (!S_DO)						lexan(&intercom),						S_DO = intercom;					status = S_parse(S_DO,DONE);					DNP;					--nest_while;					if (status == SBREAK){						status = 0;						break;					}					/* note SCONTNUE is automatic */					if (!S_DONE && status!=SCONTNUE)						lexan(&intercom),						S_DONE = intercom;				}				if (S_DONE)					p_pc = S_DONE;				else {					cptr = S_DO ? S_DO : S_WHILE;					while (TRUE){						switch ((nexttype=lexan(&cptr))){							case WHILE:								++counter;								continue;							case DONE:								if (counter){									--counter;									continue;								}								p_pc = cptr;								break;							case NULLTOK:								S_abort();							default:								continue;						}						break;					}					/* p_pc now points to just after matching 'done' */				}				if (w_status==FALSE)					DNP;				break;		} /* end of main switch, whew */		if (t_invoke==TERMINAT)			return status;		n = -1;	}}/* load a script and call S_parse to run it */static void S_call(scriptname)char *scriptname;{	int i;	jmp_buf senv;	char *oldtvec, *newptr, *oldptr, script[SM_BUFF];	long filesize;	FILE *scriptfp;	static struct stat statbuf;	strcpy(script, scriptname);	memset(Msg, 0, SM_BUFF);	if (++nest_cmd>CMDNEST){		S2("Too many nested scripts");		--nest_cmd;		return;	}	if (!(scriptfp = openfile(script))){		sprintf(Msg,"Can't open '%s'",script);		S2(Msg);		--nest_cmd;		return;	}	/* this succeeds, openfile() has called isregfile() to stat the file */	fstat(fileno(scriptfp),&statbuf);	filesize = statbuf.st_size;	areas[nest_cmd - 1] = NIL(char);	if (!(areas[nest_cmd-1]=(char*)calloc((unsigned)filesize+10,1))){		sprintf(Msg,"%s: allocation error",script);		S2(Msg);		fclose(scriptfp);		--nest_cmd;		return;	}	if (strcmp(STARTUP,script))		sprintf(Msg,"Running %s",script),		S2(Msg);	*(areas[nest_cmd - 1]) = '\n';	fread((areas[nest_cmd - 1] + 1),filesize,1,scriptfp);	*(areas[nest_cmd - 1] + filesize + 1) = '\0';	fclose(scriptfp);	oldtvec = tvector;	tvector = NIL(char);	newptr = (char *)senv;	oldptr = (char *)env;	for (i=0; i<sizeof(env); ++i)		*(newptr++) = *(oldptr++);	if ((i=setjmp(env))==0)		S_parse(areas[nest_cmd - 1],NULLTOK);	else if (i==TTERROR)		S2("Abnormal script termination");	else if (i==TIMEOUT)		S2("Timeout");	else if (i==EXIT)		S2("Script encountered 'exit'");	tvector = oldtvec;	newptr = (char *)env;	oldptr = (char *)senv;	for (i=0; i<sizeof(env); ++i)		*(newptr++) = *(oldptr++);	--nest_cmd;	if (areas[nest_cmd])		free(areas[nest_cmd]);	if (strcmp(STARTUP,script))		sprintf(Msg,"%s COMPLETE",script),		S2(Msg);}static intS_abort(){	char *cptr;	if (*Msg)		S2(Msg);	cptr = intercom;	while (*cptr && *cptr!='\n')		--cptr;	++cptr;	while (*cptr && *cptr!='\n')		fputc(*(cptr++),tfp);	fputc('\r',tfp),	fputc('\n',tfp);	if (tfp==cfp)		tfp = savetfp;	unsetall();	longjmp(env,TTERROR);}/*	get_bound_char() get a character from the user's keyboard.  If the terminal	mode escape character is seen, look ahead to the next character and act on	it. If unrecognized, simply swallow the escape character and return the	second character. Returns ASCII character code, or XCBIND function code*/intget_bound_char(){	int		c = 0, lc;	binding_t	*ptr;	static char	*emit_string = NIL(char);	if (emit_string) {		c = *(emit_string++);		if (!c)			emit_string = NIL(char);	}	if (!emit_string) {		c = getchar();		if (c == my_escape) {			lc = tolower(c=getchar());			for (ptr = first_binding; ptr; ptr = ptr->bs_next){				if (ptr->bs_c == lc){					switch (ptr->bs_function){					case EMITSTR:						emit_string = ptr->bs_string;						return *(emit_string++);					case DOSCRPT:						strcpy(ddsname, ptr->bs_string);						return DOSCRPT;					default:						return ptr->bs_function;					}				}			}		}	}	return c;}/*	default_bindings restores XC to its default key bindings.	Uppercase keys are mapped to lower case.*/void default_bindings(){	bind_key('/', HLPCHAR, "");	bind_key('?', HLPCHAR, "");	bind_key('b', BRKCHAR, "");	bind_key('c', SENDCAN, "");	bind_key('d', DIALCHR, "");	bind_key('f', DIVCHAR, "");	bind_key('h', HUPCHAR, "");	bind_key('n', CAPTEND, "");	bind_key('o', CLRGRAF, "");	bind_key('q', QUITCHR, "");	bind_key('s', SCRPCHR, "");	bind_key('x', ENDCHAR, "");	bind_key('y', CAPTYES, "");}/*	show_emit() performs an unctrl() operation on an entire buffer. */static void show_emit(str)char *str;{	while (*str)		fprintf(tfp,"%s", unctrl(*str++));}/*	get_function() returns the description corresponding to the function code	specified by (code).*/static char *get_function(code)int code;{	bindstr_t *ptr = function_list;	int i;	for (i = 0; i < FUNCTION_COUNT; i++, ptr++)		if ((int) ptr->bf_function == code)			return ptr->bf_string;	return "???";}voidshow_bindings(){	binding_t *ptr = first_binding;	char *escape_str = xc_strdup(unctrl(my_escape));	int curline = 0;	cls();	fprintf(tfp,"\tTERMINAL mode escape character is %s.\r\n\r\n", escape_str);	curline += 2;	while (ptr){		if (curline >= LI - 2){			S0("PRESS ENTER");			getline();			cls();			curline = 0;		}		fprintf(tfp,"\t%s - %-3.3s %s", escape_str, unctrl(ptr->bs_c),			get_function(ptr->bs_function));		switch (ptr->bs_function){		case EMITSTR:		case DOSCRPT:			fputc(' ',tfp);			fputc('"',tfp);			show_emit(ptr->bs_string);			fputc('"',tfp);			break;		}		fputc('\r',tfp);		fputc('\n',tfp);		curline++;		ptr = ptr->bs_next;	}	free(escape_str);}/*	find_function() returns the function code referenced by the name	pointed to by (name).  Returns BADFUNC if the name is unrecognized.*/static bindfunc_t find_function(name)char *name;{	bindstr_t *ptr = function_list;	int i;	for (i = 0; i < FUNCTION_COUNT; i++, ptr++)		if (strcmp(ptr->bf_name, name) == 0)			return ptr->bf_function;	return BADFUNC;}

⌨️ 快捷键说明

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