本周介紹的RoBoRC程式碼為parse
它是用於demo mode所需文件的開檔及解析內容
再看這篇的同時 資料結構可能要學好 不然可能會不知道它在做什麼事情
parse.h
parse.cpp
它是用於demo mode所需文件的開檔及解析內容
再看這篇的同時 資料結構可能要學好 不然可能會不知道它在做什麼事情
parse.h
#ifndef __PARSETOOL_H
#define __PARSETOOL_H
#include "demo.h"
#ifdef __cplusplus
extern "C" {
#endif
int tool_GetItemRBVer(char *str, int *rbidx);
int tool_GetMode(char *str, int *mode_idx);
int tool_GetGroupFRM(char *str, int *frmno);
int tool_InsertACTPool(ACT_NODE **pool, int *idx);
int tool_ParseFile_FRM(DEF_t *def, char *filename);
int tool_ReadFile(char* dirname, DEF_t* def);
int tool_InitDEF(DEF_t *def);
void tool_FreeDEF(DEF_t *def);
#ifdef __cplusplus
}
#endif
#endif
parse.cpp
#include <string.h>
#include <stdlib.h>
#include "errcode.h"
#include "userio.h"
#include "const.h"
#include "fileio.h"
#include "parse.h"
#if defined(RB_LINUX)
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#elif defined(RB_BC_DOS) || defined(RB_DJGPP)
#define _stricmp stricmp
#define _strnicmp strnicmp
#endif
#define OUT 0
#define IN 1
#define BASE_CMD (2)
#define BASE_ACT (2)
#define BASE_FRM (2)
static char FileDir[255];
static char FullFileDir[511];
static char* GetPath(char* filename);
static int txt_GetItemCH(INI_ITEM_t *item, int *ch, int *value);
static int def_ParseFile_TXT(DEF_t *def, char *filename);
static void frm_InitFRM(FRM_NODE *node);
static int frm_GetGroupFRM(char *str, int *frmno);
static int frm_InsertPool(FRM_NODE **pool, int *idx);
static int frm_GetItemCH(INI_ITEM_t *item, int *ch, int *value);
static int def_ParseFile_FRM(DEF_t *def, char *filename);
static void act_InitACT(ACT_NODE *node);
static int act_GetGroupACT(char *str, int *actno);
static int act_InsertPool(ACT_NODE **pool, int *idx);
static int act_ParseItem(DEF_t *def, INI_ITEM_t *item);
static int act_GetItemMTF(char *str, int *frmno, int *time);
static int act_GetItemPause(char *str, int *time);
static int act_GetItemSnd(char *str, char **filename);
static int def_ParseFile_ACT(DEF_t *def, char *filename);
static void cmd_InitCMD(CMD_NODE *node);
static int cmd_CheckCMD(CMD_NODE *cmd);
static int cmd_InsertPool(CMD_NODE **pool, int *idx);
static int cmd_InsertCMD(DEF_t *def, CMD_NODE *cmd);
static int cmd_GetItemACT(char *str, int *actno);
static int def_ParseFile_CMD(DEF_t *def, char *filename);
static int def_ParseItem_Settings(DEF_t* def, INI_ITEM_t* item);
static int def_GetItemInitFrm(char *str, int *frmno, int *mode);
static int def_GetValueFrmMode(char *str, int *mode);
static int def_ParseItem_Channels(DEF_t* def, INI_ITEM_t* item);
static int def_GetCH(char *str, int *ch);
static int def_GetPINS(char *str, int *pin);
static int def_GetMode(char *str, int *mode_idx);
static int def_GetItemRBVer(char *str, int *rbidx);
static int def_ParseItem_File(DEF_t *def, INI_ITEM_t *item);
static int def_ParseFile_DEF(char* filename, DEF_t* def);
static char* GetPath(char* filename) //the user should not modify the return string //合併檔案位置的字
{
// if((int)strcspn(dirname, "/"))
strcpy(FullFileDir, FileDir); //avoid the case where filepath == DEMOFILE_bufpath
return strcat(FullFileDir, filename);
}
/*=========================== tool for offset file ===========================*/
static int txt_GetItemCH(INI_ITEM_t *item, int *ch, int *value) //抓取channel的編號 與偏移的值
{
int sign, status;
char *str;
sign = 1;
status = ini_GetCH(item->itemname, ch); //抓取channel的編號 在fileio.cpp
if(status != SUCCESS)
return TXT_OFFSET + INVALID_NAME;
if(item->itemvalue[0] == '-'){
sign = -1;
str = ini_RemoveSpace(&item->itemvalue[1]); //清空前後的空白 在fileio.cpp
}
else if(item->itemvalue[0] == '+')
str = ini_RemoveSpace(&item->itemvalue[1]);
else
str = item->itemvalue;
status = ini_GetValue(str, value); //將字串轉為數字 在fileio.cpp
if(status != SUCCESS)
return TXT_OFFSET + INVALID_VALUE;
*value *= sign; //正負號
return SUCCESS;
}
static int def_ParseFile_TXT(DEF_t *def, char *filename) //去改變各個channel的偏移值
{
int status = SUCCESS;
int ch, value;
unsigned long flag = 0L;
INI_ITEM_t item;
FILEIO *fp;
fp = ini_FileOpen(GetPath(filename)); //開啟檔案
if(fp == NULL)
return TXT_OFFSET + OPEN_FILE_FAIL;
while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item) != INI_FILEEND)) //讀取內容 改為INI_ITEM_t形式
{
status = txt_GetItemCH(&item, &ch, &value);
if(status == SUCCESS){
if((flag & (1L << ch)) != 0) //check repeat //檢查是否重複用過
return TXT_REPEAT_CH;
def->channel[ch].offset = value; //依照讀取到的內容改變def的channel[].offset
flag |= (1L << ch); //用過的把該bit改為1
}
}
ini_FileClose(fp);
return status;
}
/*=========================== tool for frm file ===========================*/
static void frm_InitFRM(FRM_NODE *node) //預設frm的值
{
int i;
node->frmno = -1;
for(i = 0; i < 32; i++)
node->frm[i] = 0L;
node->next = NULL;
}
static int frm_GetGroupFRM(char *str, int *frmno) //取得frame的編號
{
int status;
status = ini_ParseNumber_pre(str, "Frame", frmno); //取得frame的編號
if(status == SUCCESS)
return status;
return FRM_OFFSET + INVALID_GROUP;
}
static int frm_GetItemCH(INI_ITEM_t *item, int *ch, int *value) //取得各個channel的位置的值
{
int status;
status = ini_GetCH(item->itemname, ch); //取得channel的編號
if(status != SUCCESS)
return FRM_OFFSET + INVALID_NAME;
status = ini_GetValue(item->itemvalue, value); //取得位置的值
if(status != SUCCESS)
return FRM_OFFSET + INVALID_VALUE;
return SUCCESS;
}
static int frm_InsertPool(FRM_NODE **pool, int *idx) //倍增空間
{
int i;
int size;
*idx += 1;
if(*idx % BASE_FRM == 0){
size = *idx * 2;
*pool = (FRM_NODE *)realloc(*pool, sizeof(FRM_NODE) * size);
if(*pool == NULL)
return MEMORY_ERROR;
for(i = *idx; i < size; i++)
frm_InitFRM(&(*pool)[i]);
}
return SUCCESS;
}
static int def_ParseFile_FRM(DEF_t *def, char *filename)
{
#define OUT 0
#define IN 1
int flag = OUT;
int status = SUCCESS;
int ch, value;
unsigned long flagch = 0L;
INI_ITEM_t item;
FILEIO *fp;
FRM_NODE *node;
fp = ini_FileOpen(GetPath(filename)); //開啟檔案
if(fp == NULL)
return FRM_OFFSET + OPEN_FILE_FAIL;
while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item)) != INI_FILEEND) //讀取內容 改為INI_ITEM_t形式
{
switch(item.type){ //依照type來分別做
case INI_GROUPTITLE: //如果是title 即為[Frame N]
if(flag == OUT)
flag = IN; //標記未讀取過改為已讀取過
else
status = frm_InsertPool(&def->frmpool, &def->frmidx); //有需要時倍增節點空間
flagch = 0L;
node = &def->frmpool[def->frmidx];
status = frm_GetGroupFRM(item.itemname, &node->frmno); //取得frame的編號
break;
case INI_GROUPITEM: //如果是item 即為channel1 = 1300
if(flag == OUT) //如果標記為未讀過 代表沒有title
status = FRM_OFFSET + NOGROUP_ITEM;
if(status == SUCCESS)
status = frm_GetItemCH(&item, &ch, &value); //取得item的channel編號
if(status == SUCCESS){
if((flagch & (1L << ch)) != 0) //防止重複讀取用
return FRM_REPEAT_CH;
node->frm[ch] = value; //把值填入節點中
flagch |= (1L << ch);
}
break;
case INI_UNKNOWNITEM: //讀到不知明物體
return FRM_OFFSET + UNKNOWN_LINE;
}
}
ini_FileClose(fp);
if(status == SUCCESS)
status = frm_InsertPool(&def->frmpool, &def->frmidx);
return status;
}
/*=========================== tool for act file ===========================*/
static void act_InitACT(ACT_NODE *node) //預設act的值
{
node->actno = -1;
node->frm = NULL;
node->next = NULL;
node->time = -1;
node->data.frmno = -1;
}
static int act_GetItemSnd(char *str, char **filename) //複製檔案名稱 聲音用
{
int i;
i = (int)strlen(str);
if(i == 0)
return ACT_OFFSET + INVALID_VALUE;
*filename = (char *)malloc(sizeof(char) * (i+1));
if(filename == NULL)
return MEMORY_ERROR;
strcpy(*filename, str);
return SUCCESS;
}
static int act_GetItemPause(char *str, int *time) //抓出時間的值
{
int status;
status = ini_ParseNumber_post(str, "ms", time);
if(status != SUCCESS)
return ACT_OFFSET + INVALID_VALUE;
return status;
}
static int act_GetItemMTF(char *str, int *frmno, int *time) //讀取MoveToFrame
{
char *str1, *str2;
int status;
status = ini_DivideString(str, &str1, &str2, ","); //分割字串以","為中間點
if(status == INI_DIVIDE_FAIL)
return ACT_OFFSET + INVALID_VALUE;
status = ini_GetValue(str1, frmno); //抓取str1的值 即為frame的編號
if(status != SUCCESS)
return ACT_INVALID_FRMNO;
status = ini_ParseNumber_post(str2, "ms", time); //抓取str2的值 即為時間的值
if(status != SUCCESS)
return ACT_INVALID_TIME;
return status;
}
static int act_ParseItem(DEF_t *def, INI_ITEM_t *item) //分辨指令
{
ACT_NODE *node;
node = &def->actpool[def->actidx];
int status;
if(ini_IsItem(item, "MoveToFrame")){
node->type = ACT_PLAYFRAMENO; //如果指令為MoveToFrame 則要讀取兩個值
status = act_GetItemMTF(item->itemvalue, &node->data.frmno, &node->time);
}
else if(ini_IsItem(item, "Pause")){
node->type = ACT_PAUSE; //如果指令為Pause 則要讀一個值
status = act_GetItemPause(item->itemvalue, &node->time);
}
else if(ini_IsItem(item, "playsnd")){
node->type = ACT_PLAYSND; //如果指令為playsnd 則要給檔案名稱
status = act_GetItemSnd(item->itemvalue, &node->data.filename);
}
else //其他沒看過的指令就回傳錯誤訊息
status = ACT_OFFSET + INVALID_NAME;
if(status == SUCCESS)
status = act_InsertPool(&def->actpool, &def->actidx);
return status;
}
static int act_InsertPool(ACT_NODE **pool, int *idx) //倍增節點
{
int i;
int size;
*idx += 1;
if(*idx % BASE_ACT == 0){
size = *idx * 2;
*pool = (ACT_NODE *)realloc(*pool, sizeof(ACT_NODE) * size);
if(*pool == NULL)
return MEMORY_ERROR;
for(i = *idx; i < size; i++)
act_InitACT(&(*pool)[i]);
}
return SUCCESS;
}
static int act_GetGroupACT(char *str, int *actno) //取得Action編號
{
int status;
status = ini_ParseNumber_pre(str, "Action", actno); //取得Action編號
if(status == SUCCESS)
return status;
return ACT_OFFSET + INVALID_GROUP;
}
static int def_ParseFile_ACT(DEF_t *def, char *filename)
{
#define OUT 0
#define IN 1
int flag = OUT;
int status = SUCCESS;
INI_ITEM_t item;
ACT_NODE *node;
FILEIO *fp;
fp = ini_FileOpen(GetPath(filename)); //開啟檔案
if(fp == NULL)
return ACT_OFFSET + OPEN_FILE_FAIL;
while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item)) != INI_FILEEND) //讀取內容 改為INI_ITEM_t形式
{
node = &def->actpool[def->actidx];
switch(item.type){ //依型態做事
case INI_GROUPTITLE: //如果是title 即為[Action N]
if(flag == OUT)
flag = IN; //標記改為已讀取
status = act_GetGroupACT(item.itemname, &node->actno); //讀取Action的編號
if(status == SUCCESS){
node->type = ACT_START; //節點type改為ACT_START
status = act_InsertPool(&def->actpool, &def->actidx);
}
break;
case INI_GROUPITEM: //如果是item
if(flag == IN) //如果標記為未讀過 代表沒有title
status = act_ParseItem(def, &item); //要依照指令去分別編寫
else
status = ACT_OFFSET + NOGROUP_ITEM;
break;
case INI_UNKNOWNITEM:
return ACT_OFFSET + UNKNOWN_LINE;
}
}
ini_FileClose(fp);
// follow code are move to def_ParseFile_DEF for not only one act file case
// node = &def->actpool[def->actidx];
// node->type = ACT_START;
// node->actno = -1;
// status = act_InsertPool(&def->actpool, &def->actidx);
return status;
}
/*=========================== tool for cmd file ===========================*/
static void cmd_InitCMD(CMD_NODE *node) //預設cmd的值
{
node->actno = -1;
node->command = -1;
node->name[0] = '\0';
node->next = NULL;
}
static int cmd_GetItemCMD(char *str, int *cmd) //讀取cmd的值
{
int i;
if(strlen(str) == 1){ //先判斷指令是否為正常的英文
if(str[0] >= 'A' && str[0] <= 'Z')
*cmd = str[0];
else if(str[0] >= 'a' && str[0] <= 'z')
*cmd = str[0] - 'a' + 'A';
else
return CMD_OFFSET + INVALID_VALUE;
}
else{ //或是特殊的按鍵 EX: F1
for(i = 0; i < NUM_SKEY; i++){
if(_stricmp(str, SKey[i].name) == 0)
break;
}
if(i == NUM_SKEY) //全部找完 還不在範圍內 代表有誤
return CMD_OFFSET + INVALID_VALUE;
*cmd = SKey[i].value; //將指令改為特定的值
}
return SUCCESS;
}
static int cmd_GetItemACT(char *str, int *actno) //取得act的編號
{
int status;
status = ini_GetValue(str, actno); //取得act的編號
if(status != SUCCESS)
return CMD_OFFSET + INVALID_VALUE;
return SUCCESS;
}
static int cmd_CheckCMD(CMD_NODE *cmd) //檢查有沒有缺少的
{
if(cmd->actno == -1)
return CMD_NO_ACTNO;
if(cmd->command == -1)
return CMD_NO_CMD;
if(strlen(cmd->name) == 0)
return CMD_NO_NAME;
return SUCCESS;
}
static int cmd_InsertPool(CMD_NODE **pool, int *idx) //倍增節點
{
int i;
int size;
*idx += 1;
if(*idx % BASE_CMD == 0){
size = *idx * 2;
*pool = (CMD_NODE *)realloc(*pool, sizeof(CMD_NODE) * size);
if(*pool == NULL)
return MEMORY_ERROR;
for(i = *idx; i < size; i++)
cmd_InitCMD(&(*pool)[i]);
}
return SUCCESS;
}
static int cmd_InsertCMD(DEF_t *def, CMD_NODE *cmd) //要插入新指令時用
{
int status = SUCCESS;
status = cmd_CheckCMD(cmd); //檢查有沒有少東西
if(status == SUCCESS)
status = cmd_InsertPool(&def->cmdpool, &def->cmdidx); //倍增節點用
return status;
}
static int def_ParseFile_CMD(DEF_t *def, char *filename)
{
int status = SUCCESS;
int flag = OUT;
CMD_NODE *cmd;
INI_ITEM_t item;
FILEIO *fp;
fp = ini_FileOpen(GetPath(filename)); //開啟檔案
if(fp == NULL)
return CMD_OFFSET + OPEN_FILE_FAIL;
while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item) != INI_FILEEND)) //讀取內容 改為INI_ITEM_t形式
{
switch(item.type){ //依型態判斷要做什麼
case INI_GROUPTITLE: //如果是title 即為[Command]
if(ini_IsGroup(&item, "command")){ //判斷title
if(flag == IN) // insert before cmd //有新增過的話
status = cmd_InsertCMD(def, cmd);
else
flag = IN;
}
else
return CMD_OFFSET + INVALID_GROUP;
cmd = &def->cmdpool[def->cmdidx];
break;
case INI_GROUPITEM: //如果是item 即name = XXX command = XX...
if(flag == OUT) //沒標記過代表沒有Title 格式有誤
return CMD_OFFSET + NOGROUP_ITEM;
if(ini_IsItem(&item, "name"))
strcpy(cmd->name, item.itemvalue); //name只要複製名稱就好
else if(ini_IsItem(&item, "action"))
status = cmd_GetItemACT(item.itemvalue, &cmd->actno); //action 要取得action的編號
else if(ini_IsItem(&item, "command"))
status = cmd_GetItemCMD(item.itemvalue, &cmd->command); //command 要讀出按鍵的值
else
return CMD_OFFSET + INVALID_NAME;
break;
case INI_UNKNOWNITEM:
return CMD_OFFSET + UNKNOWN_LINE;
}
}
if(status == SUCCESS)
status = cmd_InsertCMD(def, cmd);
ini_FileClose(fp);
return status;
}
/*=========================== tool for def file ===========================*/
static int def_GetCH(char *str, int *ch) //抓channel的編號
{
int status;
status = ini_GetCH(str, ch); //抓channel的編號
if(status == SUCCESS)
return SUCCESS;
return DEF_CH_INVALID_CH;
}
static int def_GetPINS(char *str, int *pin) //抓pin的編號
{
int status;
status = ini_ParseNumber_pre(str, "S", pin); //抓pin的編號
*pin -= 1; //判斷重複用
if(status == SUCCESS)
if((*pin <= 31) && (*pin >= 0)) //判斷要為S0 ~ S31
return SUCCESS;
return DEF_CH_INVALID_PIN;
}
static int def_GetMode(char *str, int *mode_idx)
{
int i;
for(i = 0; i < NUM_SERVO; i++){ //執行NUM_SERVO個servo名稱
if(_stricmp(str, Servo[i].name) == 0) //判斷輸入的servo是否正確
break;
}
if(i < NUM_SERVO){
*mode_idx = i;
return SUCCESS;
}
else //如果不是中途跳出 代表輸入的內容不在範圍內
return DEF_CH_INVALID_MODE;
}
static int def_ParseItem_Channels(DEF_t* def, INI_ITEM_t* item) //抓channels group的內容
{
int status;
int ch, pin, mode_idx;
char *str1, *str2;
status = def_GetCH(item->itemname, &ch); //抓channel 的編號
if(status == SUCCESS)
status = ini_DivideString(item->itemvalue, &str1, &str2, ","); //以","分割字串
if(status == SUCCESS)
status = def_GetPINS(str1, &pin); //抓pin的編號
if(status == SUCCESS)
status = def_GetMode(str2, &mode_idx); //抓模式的字串
if(status == SUCCESS){
if(def->channel[ch].pin != -1) //判斷重複用
return DEF_CH_REPEAT_CH;
if((def->usedChannels & (1L << pin)) != 0) //判斷重複用
return DEF_CH_REPEAT_PIN;
def->usedChannels |= (1L << pin); //把要用的channel加進去
def->channel[ch].pin = pin;
def->channel[ch].mode_idx = mode_idx;
}
return status;
}
static int def_GetValueFrmMode(char *str, int *mode) //判斷字串 true/false
{
if((str == NULL) || (_stricmp(str, "false") == 0))
*mode = INIT_FRM_FALSE;
else if(_stricmp(str, "true") == 0)
*mode = INIT_FRM_TRUE;
else
return DEF_SET_INVALID_MODE;
return SUCCESS;
}
static int def_GetItemRBVer(char *str, int *rbidx) //抓取RB型號
{
int i;
for(i = 0; i < NUM_RBVer; i++){ //執行NUM_RBVer次 即RB型號個數
if(_stricmp(str, RBVer[i].name) == 0)
break;
}
if(i < NUM_RBVer){
*rbidx = i;
return SUCCESS;
}
else //如果不是中途跳出 代表輸入的內容不在範圍內
return DEF_SET_OFFSET + INVALID_VALUE;
}
static int def_GetItemInitFrm(char *str, int *frmno, int *mode) //抓取HomeFrame的內容
{
int status;
char *str1, *str2;
status = ini_DivideString(str, &str1, &str2, ","); //以","作分隔分開字串
if(status == INI_DIVIDE_FAIL){
str1 = str;
str2 = NULL;
}
status = ini_GetValue(str1, frmno); //取得frm編號
if(status != SUCCESS)
return DEF_SET_INVALID_FRMNO;
status = def_GetValueFrmMode(str2, mode); //判斷字串 true/false
return status;
}
static int def_ParseItem_Settings(DEF_t* def, INI_ITEM_t* item) //判斷settings group的內容 以便去做各種事情
{
int status = SUCCESS;
if (ini_IsItem(item, "initaction") == true){ //判斷item是否為initaction
status = ini_GetValue(item->itemvalue, &def->initact); //抓取值
if(status != SUCCESS)
return DEF_SET_OFFSET + INVALID_VALUE;
}
else if(ini_IsItem(item, "homeframe") == true) //判斷item是否為homeframe
status = def_GetItemInitFrm(item->itemvalue, &def->initfrm, &def->initfrm_mode); //抓取HomeFrame的內容
else if(ini_IsItem(item, "roboard") == true) //判斷item是否為roboard
status = def_GetItemRBVer(item->itemvalue, &def->rbidx); //抓取RB型號
else
status = DEF_SET_OFFSET + INVALID_NAME;
return status;
}
static int def_ParseItem_File(DEF_t *def, INI_ITEM_t *item) //中繼站 來什麼就去開什麼黨來讀
{
int status;
if (ini_IsItem(item, "cmd") == true)
status = def_ParseFile_CMD(def, item->itemvalue);
else if(ini_IsItem(item, "act") == true)
status = def_ParseFile_ACT(def, item->itemvalue);
else if(ini_IsItem(item, "frame") == true)
status = def_ParseFile_FRM(def, item->itemvalue);
else if(ini_IsItem(item, "offset") == true)
status = def_ParseFile_TXT(def, item->itemvalue);
else
status = DEF_FIL_OFFSET + INVALID_NAME;
return status;
}
static int def_ParseFile_DEF(char* filename, DEF_t* def)
{
#define DEFGROUP_INFO (0)
#define DEFGROUP_FILES (1)
#define DEFGROUP_CHANNELS (2)
#define DEFGROUP_SETTINGS (3)
#define DEFGROUP_UNSET (4)
FILEIO *fp;
INI_ITEM_t item;
int gflag = DEFGROUP_UNSET;
int status = SUCCESS;
// demofile_InitialDEF(def);
fp = ini_FileOpen(GetPath(filename)); //開啟檔案
if(fp == NULL)
return DEF_OFFSET + OPEN_FILE_FAIL;
while ((status == SUCCESS) && (ini_ReadNextItem(fp, &item) != INI_FILEEND)) //讀取內容 並轉成INI_ITEM_t結構內容
{
switch(item.type)
{
case INI_GROUPTITLE: //如果是title 即為[Info]...
if (ini_IsGroup(&item, "Info") == true)
gflag = DEFGROUP_INFO;
else if (ini_IsGroup(&item, "Files") == true)
gflag = DEFGROUP_FILES;
else if (ini_IsGroup(&item, "Channels") == true)
gflag = DEFGROUP_CHANNELS;
else if (ini_IsGroup(&item, "Settings") == true)
gflag = DEFGROUP_SETTINGS;
else
status = DEF_OFFSET + INVALID_GROUP;
break;
case INI_GROUPITEM: //如果是item 即為 XXX = XXXX...
switch(gflag) //依照gflag去分別看
{
case DEFGROUP_CHANNELS:
status = def_ParseItem_Channels(def, &item);
break;
case DEFGROUP_SETTINGS:
status = def_ParseItem_Settings(def, &item);
break;
case DEFGROUP_FILES:
status = def_ParseItem_File(def, &item);
break;
case DEFGROUP_INFO:
break;
case DEFGROUP_UNSET:
status = DEF_OFFSET + NOGROUP_ITEM;
}
break;
case INI_UNKNOWNITEM:
if(gflag != DEFGROUP_INFO)
status = DEF_OFFSET + UNKNOWN_LINE;
break;
} //end switch(item...
} //end while(ini_...
ini_FileClose(fp); //關閉檔案
// Set "end" for last action
if(status == SUCCESS){
def->actpool[def->actidx].type = ACT_START;
def->actpool[def->actidx].actno = -1;
status = act_InsertPool(&def->actpool, &def->actidx);
}
return status;
}
/*=========================== tool function ===========================*/
int tool_GetItemRBVer(char *str, int *rbidx)
{
return def_GetItemRBVer(str, rbidx);
}
int tool_GetMode(char *str, int *mode_idx)
{
return def_GetMode(str, mode_idx);
}
int tool_GetGroupFRM(char *str, int *frmno)
{
return frm_GetGroupFRM(str, frmno);
}
int tool_InsertACTPool(ACT_NODE **pool, int *idx)
{
return act_InsertPool(pool, idx);
}
int tool_ParseFile_FRM(DEF_t *def, char *filename)
{
strcpy(FileDir, "");
return def_ParseFile_FRM(def, filename);
}
int tool_ReadFile(char* dirname, DEF_t* def)
{
int i;
char filename[255];
i = (int)strlen(dirname);
strcpy(FileDir, dirname);
if(FileDir[i-1] != '/')
strcat(FileDir, "/");
while (( i = (int)strcspn(dirname, "/\\")) != strlen(dirname))
dirname = &dirname[i + 1];
strcpy(filename, dirname);
strcat(filename, ".def");
return def_ParseFile_DEF(filename, def);
}
int tool_InitDEF(DEF_t *def) //初始化DEF_t的值
{
int i;
def->usedChannels = 0L;
def->initact = -1;
def->initfrm = -1;
def->initfrm_mode = INIT_FRM_FALSE;
def->inithome = NULL;
def->initactnode = NULL;
for (i=0; i<32; i++) {
def->channel[i].pin = -1;
def->channel[i].mode_idx = 0;
def->channel[i].offset = 0;
}
def->actidx = 0;
def->actpool = (ACT_NODE *)malloc(sizeof(ACT_NODE) * BASE_ACT);
def->acttable = NULL;
def->cmdidx = 0;
def->cmdpool = (CMD_NODE *)malloc(sizeof(CMD_NODE) * BASE_CMD);
def->cmdtable = NULL;
def->frmidx = 0;
def->frmpool = (FRM_NODE *)malloc(sizeof(FRM_NODE) * BASE_FRM);
def->frmtable = NULL;
if((def->actpool == NULL) || (def->cmdpool == NULL) || (def->frmpool == NULL))
return MEMORY_ERROR;
for(i = 0; i < BASE_ACT; i++)
act_InitACT(&def->actpool[i]);
for(i = 0; i < BASE_CMD; i++)
cmd_InitCMD(&def->cmdpool[i]);
for(i = 0; i < BASE_FRM; i++)
frm_InitFRM(&def->frmpool[i]);
return SUCCESS;
}
void tool_FreeDEF(DEF_t *def) //刪掉創出來的空間
{
free(def->actpool);
free(def->cmdpool);
free(def->frmpool);
free(def->acttable);
free(def->cmdtable);
free(def->frmtable);
}










