RoBoard魔人的機器人日誌

2012/3/26

[RoBoRC第七回] 介紹程式碼parse

本周介紹的RoBoRC程式碼為parse

它是用於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);
}


Share:

0 留言:

張貼留言

技術提供:Blogger.

追蹤者