本周介紹的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); }