#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 DEBUG
struct 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