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

📄 table.c

📁 本人编写的利用XML来测试多个API接口函数的程序
💻 C
字号:
#include <string.h>#include <pthread.h>#include <stdio.h>#include <errno.h>#include "table.h"//以下头文件声明可以测试的函数#include "test.h"  //用来测试本程序是否能正常运行,它只实现了几个简单的测试函数:mytest1(),mytest2(),mytest3(),mytest4().#include "demo.h" /*demo.h 文件说明: *对于打算测试的函数,本头文件及其源文件只简单的实现其封装格式,没有实现其真正功能, *要想真正测试这些函数,就需要引进其真正的头文件和源代码.*/#define DEBUGstruct funcformat table[] = {//pantilt api{"protocol_init", 	TYPE_INT,0,protocol_init,	5, MARK_5_4844b,{TYPE_INT,TYPE_ISTR,TYPE_INT,TYPE_INT,TYPE_IPTD}},{"handle_control",	TYPE_INT,0,handle_control,	2,MARK_2_48,{TYPE_INT,TYPE_ISTR}},{"set485",  		TYPE_INT,0,set485,  		5,MARK_5_4844b,   {TYPE_INT,TYPE_ISTR,TYPE_INT,TYPE_INT,TYPE_IPTD}},{"query485",		TYPE_INT,0,query485,		5,MARK_5_4966c,{TYPE_INT,TYPE_OSTR,TYPE_OPINT,TYPE_OPINT,TYPE_OPTD}},{"transparent",		TYPE_INT,0,transparent,		3,MARK_3_484,{TYPE_INT,TYPE_ISTR,TYPE_INT}},{"protocol_quit",	TYPE_INT,0,protocol_quit,	0,MARK_0,{0}},//system time api{"getsystime",		TYPE_INT,0,getsystime,		1,MARK_1_f,{TYPE_OPSM}},{"setsystime",		TYPE_INT,0,setsystime,		1,MARK_1_e,{TYPE_IPSM}},{"set_kernel_time",		TYPE_INT,0,set_kernel_time,	0,MARK_0,{0}},//time touch api{"settimetouch",	TYPE_INT,0,settimetouch,	1,MARK_1_h,{TYPE_IPTT}},{"gettimetouch",	TYPE_OPTT,1,	(struct timetouch*(*)())gettimetouch,	1,MARK_1_4,{TYPE_INT}},{"canceltimetouch",	TYPE_INT,0,canceltimetouch,	1,MARK_1_4,{TYPE_INT}},//alarm input api{"get_alarminput_status",TYPE_INT,0,get_alarminput_status,1,MARK_1_4,{TYPE_INT}},{"setalarminput",	TYPE_INT,0,setalarminput,	2,MARK_2_44,{TYPE_INT,TYPE_INT}},//alarm output api{"setalarmoutput",	TYPE_INT,0,setalarmoutput,	2,MARK_2_44,{TYPE_INT,TYPE_INT}},{"getalarmoutput",	TYPE_INT,0,getalarmoutput,	2,MARK_2_46,{TYPE_INT,TYPE_OPINT}},//API api{"API_init",		TYPE_INT,0,API_init,		0,MARK_0,{0}},{"API_destroy",		TYPE_VOID,0,(int(*)())API_dsetory,0,MARK_0,{0}},//HTTP API{"setsendhttprequest",	TYPE_INT,0,setsendhttprequest,	2,MARK_2_84,{TYPE_ISTR,TYPE_INT}},{"sendhttprequest",		TYPE_INT,0,sendhttprequest,		2,MARK_2_84,{TYPE_ISTR,TYPE_INT}},//test{"mytest1",TYPE_INT,0,mytest1,1,MARK_1_8,  {TYPE_ISTR}},{"mytest2",TYPE_INT,0,mytest2,1,MARK_1_4,  {TYPE_INT}},{"mytest3",TYPE_INT,0,mytest3,2,MARK_2_48,   {TYPE_INT,TYPE_ISTR}},{"mytest4",TYPE_INT,0,mytest4,2,MARK_2_94,   {TYPE_OSTR,TYPE_INT}},//the end{0,0,0,0}};struct struct_format stable[] = {{"TDVSSS_device",TYPE_TD,52,6,{{0,TYPE_INT},{4,TYPE_ISTR},{36,TYPE_INT},{40,TYPE_INT},{44,TYPE_INT},{48,TYPE_INT}}},{"sm",		TYPE_SM,36,9,	{{0,TYPE_INT},{4,TYPE_INT},{8,TYPE_INT},{12,TYPE_INT},{16,TYPE_INT},{20,TYPE_INT},{24,TYPE_INT},{28,TYPE_INT},{32,TYPE_INT}}},{"timetouch",TYPE_TT,44,3, {{0,TYPE_INT},{4,TYPE_SM},{40,TYPE_INT}}},{0,0,0,0,{{0,0}}}};static char* align_string(char* pTemp){	int i = 0;	while(pTemp[i] == ' ')		i++;	return pTemp+i;}static int isrule(char x){	if(x < '0')		return -1;	else if(x > '9' && x < 'A')		return -1;	else if(x > 'Z' && x < 'a')	{		if(x == '_')			return 0;		else			return -1;	}	else if(x > 'z')		return -1;	return 0;} //***************************************************************************static int parse_function(char* func,char* name,int name_len,char* arg,int arg_len){	char* off;	int n,stack;	//////////////////////////////////////////////////	memset(name,0,name_len);	memset(arg,0,arg_len);	off = func;	n = 0;	stack = 0;	while(!isrule(*off))	{		name[n++] = *off++;	}	if(*off != '(')	{		return -ENOTFUNC;	}	off++;	stack++;	n = 0;	while(*off != '\0')	{		if(*off == '(')		{			stack++;			arg[n++] = *off;		}		else if(*off == ')')		{			stack--;			if(stack == 0)				break;			else				arg[n++] = *off;		}		else			arg[n++] = *off;		off++;	}	if(stack == 0)		return 0;	return -EINVALIDARG;}static char* get_one_member(char* data,int* len){	int n = 0;	char* pos = data;	while(pos[n] !=')' && pos[n] != ',')		n++;	*len = n;	if(pos[n] == ',')	{		pos = align_string(pos + n + 1);		return pos;	}	else		return NULL;	}//***************************************************************************static int parse_struct(int type,void* pstruct,char* data){	//data format "$(1,2,...),..."	int n,j,count,len = 0;	struct member* member = NULL;	char* pos,*next,*tmp;	void* tmp1 = NULL;	if(!pstruct || !data)		return -EPOINTER;	pos = strchr(data,'(');	pos++;	for(n = 0;stable[n].name;n++)	{		if(stable[n].type == type)			break;	}	if(!stable[n].name)		return -EUNKNOWNARGV;	#ifdef DEBUG	fprintf(stderr,"parse struct:%s\t%s\n",stable[n].name,data);	#endif	memset(pstruct,0,stable[n].size);	count = stable[n].count;	if(count > MAX_MEMBER)		return -EMAXMEMBER;	member = stable[n].member;	for(j = 0; j < count; j++)	{		switch (member[j].type)		{		case TYPE_INT:			if(!pos)				return -EINVALIDARG;			next = get_one_member(pos,&len);			*((int*)(pstruct + member[j].offset)) = atoi(pos);			#ifdef DEBUG			fprintf(stderr,"get member %d of struct %s :%d\n",j,stable[n].name,atoi(pos));			#endif			pos = next;			len = 0;			break;		case TYPE_ISTR:			if(!pos)				return -EINVALIDARG;			next = get_one_member(pos,&len);			tmp = (char*)(pstruct + member[j].offset);			strncpy(tmp,pos,len);			pos = next;			len = 0;			break;		case TYPE_SM:			if(!pos)				return -EINVALIDARG;			#ifdef DEBUG			fprintf(stderr,"get member %d of struct %s :%s\n",j,stable[n].name,pos);			#endif			next = get_one_member(pos,&len);			tmp1 = (struct sm*)(pstruct + member[j].offset);			parse_struct(TYPE_SM,tmp1,pos);			pos = next;			len = 0;			break;		default:			return -EUNKNOWNARGV;		}				}	return 0;}static char* get_one_argument(char* arg,int*len){	int n = 0,stack = 0,match = 0;	char* pos = arg;	while(pos[n] != '\0')	{		if(pos[n] == '"')			(match == 0)?(match = 1):(match = 0);		else if(pos[n] == '(')			stack++;		else if(pos[n] == ')')			stack--;		else if(pos[n] == ',' && stack == 0 && match == 0)		{			*len = n;			pos = align_string(pos + n + 1);			return pos;		}		n++;	}	if(n)	{		*len = n;		return pos + n;	}	else		return NULL;}//***************************************************************************static int parse_argument(struct funcformat* pfunc,char* in,void** argv){	int argc,j,len,size,ret;	char* pos,*next = NULL;	if(!pfunc || !in || !argv)		return -EPOINTER;	#ifdef DEBUG	fprintf(stderr,"debug====> begin parse argument:%s ......\n",in);	#endif	pos = in;	argc = pfunc->argc;	for(j = 0; j< argc;j++)	{		switch (pfunc->argv[j])		{		case TYPE_INT:			if(!pos)				return -EINVALIDARG;			next = get_one_argument(pos,&len);			argv[j] = (int*)malloc(sizeof(int));			if(!argv[j])				return -ENOMEMORY;			*((int*)argv[j]) = atoi(pos);			#ifdef DEBUG			fprintf(stderr,"debug=====> get one argument: argv[%d] = %d\n",j,*((int*)argv[j]));			#endif			pos = next;			break;					case TYPE_ISTR:		{			int ii,jj;			char* tt;			if(!pos)				return -EINVALIDARG;			next = get_one_argument(pos,&len);			argv[j] = malloc(len + 3);			if(!argv[j])				return -ENOMEMORY;			memset(argv[j],0,len + 3);			tt = (char*)argv[j];			for(ii = 0,jj = 0;ii < len; ii++)				if(pos[ii] != '"')					tt[jj++] = pos[ii];//			strncpy(argv[j],pos,len);			#ifdef DEBUG			fprintf(stderr,"debug=====> get one argument: argv[%d] = %s\n",j,((char*)argv[j]));			#endif			pos = next;			break;		}		case TYPE_OSTR:		case TYPE_OPINT:		case TYPE_OPTD:		case TYPE_OPSM:			if(!pos || (*pos != '#'))				return -EINVALIDARG;			pos++;			next = get_one_argument(pos,&len);			size = atoi(pos);			if(size <= 0)				return -EINVALIDARG;			argv[j] = (char*)malloc(size);			if(!argv[j])				return -ENOMEMORY;			pos = next;			break;			case TYPE_IPTD:				if(!pos || (*pos != '$'))				return -EINVALIDARG;			next = get_one_argument(pos,&len);			argv[j] = (struct TDVSSS_device*)malloc(sizeof(struct TDVSSS_device));			if(!argv[j])				return -ENOMEMORY;			if((ret = parse_struct(TYPE_TD,argv[j],pos)) < 0)				return ret;			pos = next;			break;			case TYPE_IPSM:			if(!pos || (*pos != '$'))				return -EINVALIDARG;			next = get_one_argument(pos,&len);			argv[j] = (struct sm*)malloc(sizeof(struct sm));			if(!argv[j])				return -ENOMEMORY;			if((ret = parse_struct(TYPE_SM,argv[j],pos)) < 0)				return ret;			pos = next;			break;			case TYPE_IPTT:			if(!pos || (*pos != '$'))				return -EINVALIDARG;			#ifdef DEBUG			fprintf(stderr,"debug=====> get one argument: argv[%d] struct timetouch\n",j);			#endif			next = get_one_argument(pos,&len);			argv[j] = (struct timetouch*)malloc(sizeof(struct timetouch));			if(!argv[j])				return -ENOMEMORY;			if((ret = parse_struct(TYPE_TT,argv[j],pos)) < 0)				return ret;//			#ifdef DEBUG//			fprintf(stderr,"current arg:%s size:%d   next arg:%s\n",pos,len,next);//			#endif			pos = next;			break;			default:			return -EUNKNOWNARGV;		}	}	return 0;}//***************************************************************************static int execvefunc(struct funcformat* pfunc,void** argv,char* func){	int funcret,argc,j;	struct sm* sm;	argc = pfunc->argc;	switch(pfunc->ret_type)	{	case TYPE_INT:		fprintf(stderr,"begin call...\n");		switch (pfunc->mark)		{		case MARK_0:			funcret = pfunc->func();			break;		case MARK_1_4:			funcret = pfunc->func(*((int*)argv[0]));			break;		case MARK_1_8:		case MARK_1_9:			funcret = pfunc->func((char*)argv[0]);			break;		case MARK_2_44:			funcret = pfunc->func(*((int*)argv[0]),*((int*)argv[1]));			break;		case MARK_2_46:			funcret = pfunc->func(*((int*)argv[0]),(int*)argv[1]);			break;		case MARK_2_48:			funcret = pfunc->func(*((int*)argv[0]),(char*)argv[1]);			break;		case MARK_2_84:		case MARK_2_94:			funcret = pfunc->func((char*)argv[0],*((int*)argv[1]));			break;		case MARK_3_484:			funcret = pfunc->func(*((int*)argv[0]),(char*)argv[1],*((int*)argv[2]));			break;		case MARK_5_4844b:			funcret = pfunc->func(*((int*)argv[0]),(char*)argv[1],			*((int*)argv[2]),*((int*)argv[3]),(struct TDVSSS_device*)argv[4]);			break;		case MARK_5_4966c:			funcret = pfunc->func(*(int*)argv[0],(char*)argv[1],(int*)argv[2],(int*)argv[3],			(struct TDVSSS_device*)argv[4]);			break;		case MARK_1_e:		case MARK_1_f:			funcret = pfunc->func((struct sm*)argv[0]);			break;		default:			return -EUNKNOWNMARK;		}		fprintf(stderr,"call over!\n");		fprintf(stderr,"函数%s执行结果:",func);		if(funcret == pfunc->success)		{			fprintf(stderr,"成功!\n");		}		else			fprintf(stderr,"失败\n");		break;	case TYPE_VOID:		fprintf(stderr,"begin call...\n");		switch (pfunc->mark)		{		case MARK_0:			pfunc->func();			break;		default:			return -EUNKNOWNMARK;		}		fprintf(stderr,"call over!\n");		break;	default:		return -EUNKNOWNRET;	}	for(j = 0; j< argc;j++)	{		switch (pfunc->argv[j])		{		case TYPE_OSTR:			fprintf(stderr,"data output:argument%d=========>%s\n",j +1,(char*)argv[j]);			break;		case TYPE_OPINT:			fprintf(stderr,"data output:argument%d=========>%d\n",j +1,*((int*)argv[j]));			break;		case TYPE_OPTD:		{			struct TDVSSS_device* tt = (struct TDVSSS_device*)argv[j];			fprintf(stderr,"data output:argument%d=========>%s %d\n",j +1,tt->name,tt->baudrate);			break;		}			case TYPE_OPSM:			sm = (struct sm*)argv[j];			fprintf(stderr,"data output:argument%d=========>%d-%d-%d %d:%d:%d\n",j +1,			sm->year + 1900,sm->mon,sm->day,sm->hour,sm->min,sm->sec);			break;		}		free(argv[j]);	}	return 0;}//***************************************************************************static int singlecall(char* func){	int n,ret;	char name[64],arg[512];	void* argv[MAX_ARGUMENT];		if(!func)		return -EPOINTER;	if((ret = parse_function(func,name,64,arg,512)) < 0)		return ret;	fprintf(stderr,"=================>call function(s):%s\n",func);	#ifdef DEBUG	fprintf(stderr,"debug====> get function name:%s\n",name);	#endif		for(n = 0;table[n].name;n++)	{		if(!strcmp(table[n].name,name))		{			#ifdef DEBUG			fprintf(stderr,"debug====> exist matched function\n");			#endif				if((ret = parse_argument(&table[n],arg,argv)) < 0)				goto exit;			ret = execvefunc(&table[n],argv,func);			goto exit;		}	}	ret = -EUNKNOWNFUNC;exit:	return ret;}static void* mythread(void* arg){	char* func = (char*)arg;	int* ret;	if((ret = (int*)malloc(sizeof(int))) == NULL)		pthread_exit(NULL);	*ret = singlecall(func);	pthread_exit(ret);}static int multicall(int style,char* func){	int n,ret,j,*funcret;	char buffer[512],*pos,*pos1;	pthread_t thread_id[MAX_MULTICALL];			pos = func;	for(n = 0,j = 0;n < style;n++)	{		pos1 = strchr(pos,';');		if(pos1)		{			memset(buffer,0,512);			strncpy(buffer,pos,pos1-pos);			pos = pos1 + 1;		}		else		{			if(n == style - 1)			{				memset(buffer,0,512);				strcpy(buffer,pos);			}			else				return -EOTHER;		}		ret = pthread_create(&thread_id[n],NULL,mythread,buffer);		if(ret)		{			perror("pthread_create");		}		else			j++;			}	for(n = 0;n < j;n++)	{		if(pthread_join(thread_id[n],(void**)&funcret) != 0)		{			fprintf(stderr,"thread[%d] join error:%s\n",n,strerror(errno));		}		else		{			if(funcret == NULL)				continue;			fprintf(stderr,"thread[%d] return %d\n",n,*funcret);			free(funcret);		}	}	return 0;}void callfunc(int style,char* func){	int error;		if(style <1 || style > MAX_MULTICALL)		error = -EOTHER;	else if (style == 1)		error = singlecall(func);	else		error = multicall(style,func);	switch (error)	{	case 0:		break;	case -ENOTFUNC:		fprintf(stderr,"error code: ENOTFUNC   %s is not a func!\n",func);		break;	case -EUNKNOWNFUNC:		fprintf(stderr,"error code: EUNKNOWNFUNC    Unknown function %s\n",func);		break;	case -EUNKNOWNARGV:		fprintf(stderr,"error code: EUNKNOWNARGV    Parse argument failed,unknown argument!\n");		break;	case -EUNKNOWNMARK:		fprintf(stderr,"error code: EUNKNOWNMARK     Unknown function mark %s\n",func);		break;	case -EUNKNOWNRET:		fprintf(stderr,"error code: EUNKNOWNRET     Unknown return type!\n");		break;	case -EINVALIDARG:				fprintf(stderr,"error code: EINVALIDARG    Invalid argument!\n");		break;	case -EOTHER:		fprintf(stderr,"error code: EOTHER \n");		break;	}		return;}

⌨️ 快捷键说明

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