www.pudn.com > IEC104_codeamaterial.rar > cmddo.c, change:2011-02-19,size:11692b


/*------------------------------------------------------------------------ 
 Module:		cmddo.c 
 Author:		solar 
 Project:		pas300m  
 Creation Date: 2005-9-29 
 Description:	 
------------------------------------------------------------------------*/ 
/*------------------------------------------------------------------------ 
 $Log: $ 
------------------------------------------------------------------------*/ 
 
#include "syscfg.h" 
 
#include <string.h> 
#include <stdarg.h> 
#include <stdio.h> 
#include "sys.h" 
 
#define SHELL_COMM_ID   SHELL_ID 
 
#if ((TYPE_BACK&EXT_TYPE_DIO_MASK) == EXT_TYPE_DIO_DI)  
#define SHELL_NAME "DI>" 
#endif 
#if ((TYPE_BACK&EXT_TYPE_DIO_MASK) == EXT_TYPE_DIO_DO)  
#define SHELL_NAME "DO>" 
#endif 
 
#ifndef SHELL_NAME 
#define SHELL_NAME "IDA>" 
#endif 
 
enum { 
	CMDLINESIZE 	= 48, 
	ARGCNT			= 8, 
	PRINTF_BUF_LEN 	= 128 
}; 
 
/*extern int gSerialInit;*/ 		/*用于判断串口初始化时候完成*/ 
 
/*------------------------------------------------------------------------ 
 变量定义 
------------------------------------------------------------------------*/ 
 
int g_DispNum = 0; 
 
static char uprint_buf[PRINTF_BUF_LEN]; 
/*static BYTE out_buf[PRINTF_BUF_LEN];*/ 
static int g_cur = 0;					/*命令行当前指针*/ 
static char g_cmdline[CMDLINESIZE]; 
	 
/*------------------------------------------------------------------------ 
 函数原型 
------------------------------------------------------------------------*/ 
/*静态函数*/ 
static void sendmacmsg(void); 
static int  getline(char *buf,int max, int *cur); 
static int  docommand(char *cmdline,int verbose); 
static int  tokenize(char *,char **); 
static void getoptinit(void); 
static void execmd(void); 
 
/*------------------------------------------------------------------------ 
 Procedure:     ShellTask ID:1 
 Purpose:       Shell任务 
 Input:          
 Output: 
 Errors: 
------------------------------------------------------------------------*/ 
void shell(void) 
{ 
	DWORD events; 
	 
	evReceive(SHELL_ID, EV_RX_AVAIL | EV_TM1, &events); 
 
    if (events&EV_RX_AVAIL)  
	{  
		if (g_DispNum > 0) 
		{ 
		    g_DispNum = 1; 
			execmd(); 
		}		 
 
    	if (getline(g_cmdline,CMDLINESIZE,&g_cur) != 0) 
    		execmd(); 
    } 
 
	if (events&EV_TM1) 
	{ 
	    if (g_DispNum> 0) execmd(); 
 
		/*if (TestRunFlag(RUNF_MAC_NOCFG)) sendmacmsg();*/ 
	}	 
} 
 
void ShellInit(void) 
{ 
    tmEvEvery(SHELL_ID, 50); 
	tCreate(SHELL_ID, NULL, (ENTRYPTR)shell);	 
} 
 
/*void sendmacmsg(void) 
{ 
    myputs("* NO Mac!\n"); 
	faultLight_turn(); 
}*/ 
 
void execmd(void) 
{ 
	docommand(g_cmdline,0); 
	if (g_DispNum == 0) 
	{ 
		memset(g_cmdline,0,CMDLINESIZE);	/*清命令行缓存*/  
		g_cur = 0; 
		myprintf("%s",SHELL_NAME);			 
	}	 
} 
 
/*------------------------------------------------------------------------ 
 Procedure: 	myprintf ID:1 
 Purpose:		Shell格式化输出 
 Input: 		 
 Output: 
 Errors: 
------------------------------------------------------------------------*/ 
int myprintf( const char *fmt, ... ) 
{ 
	va_list varg; 
	char *pbuf = uprint_buf; 
	/*BYTE *pout = out_buf;*/ 
	int i,retv; /*int add = 0;*/ 
 
	va_start( varg, fmt ); 
	retv = vsprintf(pbuf, fmt, varg); 
	va_end( varg ); 
	 
	/*if( gSerialInit == 1){ 
		for(i=0; i<retv; i++){ 
			if(uprint_buf[i] == '\n'){ 
				*pout = '\r'; 
				pout++; add++; 
			} 
			*pout = uprint_buf[i]; 
			pout++; 
			if(uprint_buf[i] == '\0')	break; 
		} 
		SerialWrite(SHELL_COMM_ID, out_buf, retv+add, 0); 
	}else{*/ 
		for(i=0; i<retv; i++) 
		    myputchar(*(char *)(uprint_buf+i)); 
	/*}*/ 
	 
	return retv; 
} 
 
extern void uart_poll_out(int no, char outChar); 
/*------------------------------------------------------------------------ 
 Procedure: 	myputchar ID:1 
 Purpose:		输出字符, '\n'前添加'\r' 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
int myputchar(char c) 
{ 
	/*unsigned char buf[2];*/ 
 
  /*if( gSerialInit == 1){ 
	buf[0] = c; buf[1] = '\r'; 
	if (c == '\n') { 
		buf[0] = '\r'; buf[1] = c; 
		SerialWrite(SHELL_COMM_ID, buf, 2, 0); 
	}else{ 
		buf[0] = c; 
		SerialWrite(SHELL_COMM_ID, buf, 1, 0); 
	} 
  }else{*/ 
	if (c == '\n') { 
		uart_poll_out(SHELL_COMM_ID, '\r');	uart_poll_out(SHELL_COMM_ID, c);		 
	}else{ 
		uart_poll_out(SHELL_COMM_ID, c); 
	} 
  /*}*/  
  return((int)c); 
} 
/*------------------------------------------------------------------------ 
 Procedure: 	myputs ID:1 
 Purpose:		串输出 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
void myputs(char *str) 
{ 
    char *p = str; 
 
    while (*p != '\0') 
	{ 
	    myputchar(*p); 
		p++; 
    }	 
} 
/*------------------------------------------------------------------------ 
 Procedure: 	gotoxy ID:1 
 Purpose:		[VT100]调整shell光标位置 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
void gotoxy(unsigned char x, unsigned char y) 
{ 
	myputchar(0x1b); 
	myputchar('['); 
	myputchar((y%100)/10+0x30); 
	myputchar((y%10)+0x30); 
	myputchar(';'); 
	myputchar((x%100)/10+0x30); 
	myputchar((x%10)+0x30); 
	myputchar('H'); 
} 
/*------------------------------------------------------------------------ 
 Procedure: 	clrscr ID:1 
 Purpose:		[VT100]shell清屏 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
void clrscr(void) 
{ 
	gotoxy(0,0); 
	myputchar(0x1b); 
	myputs("[J");  
} 
/*------------------------------------------------------------------------ 
 Procedure: 	vt100color ID:1 
 Purpose:		[VT100]shell颜色控制 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
void vt100color(char *s) 
{ 
	myputchar(0x1b); 
	myputchar('['); 
	myputs(s); 
	myputchar('m'); 
} 
/*------------------------------------------------------------------------ 
 Procedure: 	mygetchar ID:1 
 Purpose:		从shell读取字符 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
int mygetchar(void) 
{ 
	int ret; BYTE ch; 
	 
	ret = commRead(SHELL_COMM_ID, &ch, 1, 0); 
	if (ret != 1) return -1; 
 
	return((int)ch); 
} 
/*------------------------------------------------------------------------ 
 Procedure: 	getline ID:1 
 Purpose:		接收命令行 
 Input: 		 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
int getline(char *buf,int max, int *cur) 
{ 
	static	unsigned char  crlf; 
	int	tot, i; 
	char	*base; 
	int ret; 
 
	tot = 0; 
	base = buf; 
	buf = buf + (*cur); 
	max -= 1;		/* Make sure there is space for the null terminator. */ 
	for(i=*cur;i<max;i++) { 
		ret = mygetchar(); 
		if(ret == -1) { 
			/**cur = i;*/ 
			return 0; 
		} 
		*buf = (char)ret; 
		if (!*buf) { 
			i--; 
			continue; 
		} 
		{ 
			if ((*buf == '\r') || (*buf == '\n')) { 
				if ((crlf) && (*buf != crlf)) { 
					crlf = 0; 
					continue; 
				} 
				myputs("\r\n"); 
				crlf = *buf; 
				*buf = 0; 
				break; 
			} 
			if (*buf == '\b') { 
				if (*cur) { 
					i -= 2; 
					buf--;  
					*cur = *cur - 1; 
					myputs("\b \b"); 
				} 
				/*if (tot) { 
					i -= 2; 
					buf--;  
					tot--; 
					myputs("\b \b"); 
				}*/ 
			} 
			else { 
				myputchar(*buf); 
				tot++;  
				*cur = *cur + 1; 
				buf++; 
			} 
			crlf = 0; 
		} 
	} 
	if (i == max) { 
		myprintf("\007\n输入太长(超过%d字节).\n",max+1); 
		*buf = 0; 
		*cur = 0; 
		return(0); 
	} 
	/*清空接收缓存*/ 
	while( mygetchar() != -1 ); 
	return 1; 
} 
/*------------------------------------------------------------------------ 
 Procedure:     docommand ID:1 
 Purpose:       命令执行. 
 Input: 
 Output: 
 Errors:         
------------------------------------------------------------------------*/ 
int docommand(char *cmdline,int verbose) 
{ 
	int	ret, argc, i; 
	struct	monCommand	*cmdptr; 
	char	*argv[ARGCNT], cmdcpy[CMDLINESIZE]; 
 
	if (verbose == 2)		/* print command line prior to processing */ 
		myprintf("+ %s\n",cmdline); 
	 
	strcpy(cmdcpy,cmdline); 
 
	/* Build argc/argv structure based on incoming command line. */ 
	argc = tokenize(cmdcpy,argv); 
	if (argc == 0) 
		return 0; 
	if (argc < 0) { 
		myprintf("命令行错误\n"); 
		return -1; 
	} 
 
	getoptinit(); 
	cmdptr = (struct	monCommand	*)cmdlist; 
 
	if (verbose) {		/* print the tokenized command line. */ 
		for(i=0;i<argc;i++) 
			myprintf("%s ",argv[i]); 
		myprintf("\n"); 
	} 
 
	while(cmdptr->name) { 
		if (strcmp(argv[0],cmdptr->name) == 0) 
			break; 
		cmdptr++; 
	} 
	if (cmdptr->name) { 
		ret = cmdptr->func(argc,argv); 
		if (ret == -1) { 
			myprintf("命令行错误...\n"); 
			myprintf("用法: %s %s\n", 
			    cmdptr->name,cmdptr->helptxt[1]); 
		} 
		return ret; 
	} 
 
	myprintf("命令未发现: %s\n",argv[0]); 
	return 0; 
} 
/*------------------------------------------------------------------------ 
 Procedure:     tokenize ID:1 
 Purpose:       命令行解析 
 Input: 
 Output: 
 Errors:         
------------------------------------------------------------------------*/ 
int tokenize(char *string,char *argv[]) 
{ 
	int	argc, done; 
 
	/* Null out the incoming argv array. */ 
	for(argc=0;argc<ARGCNT;argc++) 
		argv[argc] = (char *)0; 
 
	argc = 0; 
	while(1) { 
		while ((*string == ' ') || (*string == '\t')) 
			string++; 
		if (*string == 0) 
			break; 
		argv[argc] = string; 
		while ((*string != ' ') && (*string != '\t')) { 
			if ((*string == '\\') && (*(string+1) == '"')) { 
				strcpy(string,string+1); 
			} 
			else if (*string == '"') { 
				strcpy(string,string+1); 
				while(*string != '"') { 
					if ((*string == '\\') && (*(string+1) == '"')) 
						strcpy(string,string+1); 
					if (*string == 0) 
						return(-1); 
					string++; 
				} 
				strcpy(string,string+1); 
				continue; 
			} 
			if (*string == 0) 
				break; 
			string++; 
		} 
		if (*string == 0) 
			done = 1; 
		else { 
			done = 0; 
			*string++ = 0; 
		} 
 
		argc++; 
		if (done) 
			break; 
		if (argc >= ARGCNT) { 
			argc = -1; 
			break; 
		} 
	} 
	return(argc); 
} 
/* Variables used by getopt: */ 
int	 optind;	/* argv index to first cmd line arg that is not part 
			       of the option list */ 
char *optarg;	/* pointer to argument associated with an option */ 
int	 sp; 
/*------------------------------------------------------------------------ 
 Procedure: 	getoptinit ID:1 
 Purpose:		取得命令行选项初始化 
 Input: 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
void getoptinit(void) 
{ 
	sp = 1; 
	optind = 1; 
} 
/*------------------------------------------------------------------------ 
 Procedure: 	getopt ID:1 
 Purpose:		取得命令行选项 
 Input: 
 Output: 
 Errors:		 
------------------------------------------------------------------------*/ 
int getopt(int argc,char *argv[],char *opts) 
{ 
	register int c; 
	register char *cp; 
 
	if(sp == 1) { 
		if (optind >= argc) 
			return(-1); 
		else if (argv[optind][0] != '-') 
			return(-1); 
		else if (argv[optind][1] == '\0') 
			return(-1); 
		else if(strcmp(argv[optind], "--") == 0) { 
			optind++; 
			return(-1); 
		} 
	} 
	c = argv[optind][sp]; 
	cp= strchr(opts, c); 
	if(c == ':' || cp == 0) { 
		myprintf("非法选项: %c\n",c); 
		if(argv[optind][++sp] == '\0') { 
			optind++; 
			sp = 1; 
		} 
		return('?'); 
	} 
	if(*++cp == ':') { 
		if(argv[optind][sp+1] != '\0') 
			optarg = &argv[optind++][sp+1]; 
		else if(++optind >= argc) { 
			myprintf("选项需要参数: %c\n",c); 
			sp = 1; 
			return('?'); 
		} else 
			optarg = argv[optind++]; 
		sp = 1; 
	} else { 
		if(argv[optind][++sp] == '\0') { 
			sp = 1; 
			optind++; 
		} 
		optarg = 0; 
	} 
	return(c); 
}