📄 table.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 + -