?? treeop.cpp
字號:
/********************************************************
文 件 名: tree.c
所屬項目:
編寫單位:
作 者: 易劍
編寫日期: 2003-02-10
版 本:
功能描述: 操作配置文件的樹結構及其算法
修改日志:
修改時間:
修 改 者:
修改內容:
*********************************************************/
#include "treeOp.h"
//#include "private_tree.h"
#include "parse_cfgfile.h"
//#include "misc.h"
//#include "queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mystack.h"
/*
===============================================================
函數實現處
===============================================================
*/
/********************************************************
函 數 名稱:init_cfg
功能描述:初始化配置文件
參數說明:
cfg_filepath,配置文件
task_filepath,任務文件
argv,命令行參數
direct,裝載行為
返 回 值:成功返回樹根結點的指針,否則返回 NULL
*********************************************************/
struct tree_node *init_cfg(char *cfg_filepath, char *task_filepath, char **argv, char *direct)
{
struct tree_node *root = NULL;
struct tree_node *defaultnode = NULL;
/* 1、建立樹根結點 */
root = create_treeroot("root");
if (NULL == root)
return NULL;
#define _DEBUG_
#ifdef _DEBUG_
createtree_fromfile(cfg_filepath, &root);
return root;
#endif /* _DEBUG_ */
/* 2、建立 [DEFAULT] 結點 */
defaultnode = (struct tree_node *)malloc(sizeof(struct tree_node));
if (NULL == defaultnode)
{
free(root);
root = NULL;
return NULL;
}
memset(defaultnode, NULL, sizeof(struct tree_node));
strcpy(defaultnode->data, "DEFAULT");
defaultnode->flag = 1;
insertnode_byparent(root, defaultnode);
/* 載入環境變量到以 defaultnode 為父結點的子樹中 */
if (direct[0] == 1)
{
;//load_envvar(&defaultnode);
}
/* 載入配置文件 [DEFAULT] 段
到以 defaultnode 為父結點的子樹中 ,
并覆蓋上一步載入的環境變量
*/
if (direct[1] == 1)
{
;//load_cfgndvar(&defaultnode, cfg_filepath);
}
/* 載入任務文件 [DEFAULT] 段到以 defaultnode 為父結點的子樹中 */
if (direct[3] == 1)
{
;//load_taskdvar(&defaultnode, task_filepath);
}
/* 載入命令行到以 defaultnode 為父結點的子樹中 */
if (direct[4] == 1)
{
;//load_cmdvar(&defaultnode, argv);
}
/*
構建 defaultnode 結點的兄弟結點
*/
/* 載入配置文件[DEFAULT] 段以外的參數,
構建與 defaultnode 結點并列的結點 */
if (direct[2] == 1)
{
load_cfgndvar(&root, cfg_filepath);
}
return root;
}
/********************************************************
函 數 名稱:uninit
功能描述:釋放樹結點
參數說明:
root,樹根
返 回 值:無
*********************************************************/
void uninit(struct tree_node *root)
{
struct tree_node *child = NULL;
struct tree_node *sibling = NULL;
struct tree_node *nextsibling = NULL;
/* 樹根不存在或不是樹根時 */
if ((NULL == root))
return;
child = root->firstchild;
if (NULL != child)
{
sibling = child->nextsibling;
/* 如果是葉子結點或是空子樹時 */
if ((child->flag == 0) || (child->firstchild == NULL))
{
free(child);
child = NULL;
}
else
{
uninit(child);
child = NULL;
}
do
{
if (NULL != sibling)
{
nextsibling = sibling->nextsibling;
if ((sibling->flag == 0) || (sibling->firstchild == NULL))
{
free(sibling);
sibling = NULL;
}
else
{
uninit(sibling);
sibling = NULL;
}
sibling = nextsibling->nextsibling;
}
} while (NULL != sibling);
}
/* 釋放根結點 */
free(root);
root = NULL;
}
/********************************************************
函 數 名稱:createtree_fromfile
功能描述:從文件中獲取數據創建以為 root 根的樹
參數說明:
filename,存儲有樹結構數據的文件的文件名
root,樹根
返 回 值:無
*********************************************************/
void createtree_fromfile(char *filename, struct tree_node **root)
{
FILE *fp = NULL;
struct mystack s;
if ((NULL == filename) || (*root == NULL))
return;
fp = fopen(filename, "r");
if (NULL == fp)
return;
init_stack(&s);
push_stack(&s, *root); /* 必須 */
read_fromcfgfile(fp, root, &s);
fclose(fp);
}
/********************************************************
函 數 名稱:createtree_fromfilefp
功能描述:從文件中獲取數據創建以為 root 根的樹
參數說明:
fp,存儲有樹結構數據的文件的文件描述符
root,樹根
返 回 值:無
*********************************************************/
void createtree_fromfilefp(FILE *fp, struct tree_node **root)
{
struct mystack s;
if ((NULL == fp) || (*root == NULL))
return;
init_stack(&s);
push_stack(&s, *root); /* 必須 */
read_fromcfgfile(fp, root, &s);
}
/********************************************************
函 數 名 稱:dump_tree
功能描述:將根為 root 的樹的子樹(根為 path 對應的結點)導出到文件 result_filepath 中
參數說明:
root,樹根
path,路徑,如果 path 為 NULL則將整個樹導出
result_filepath,導出文件
返 回 值:成功返回 1,失敗返回 -1
*********************************************************/
int dump_tree(struct tree_node *root, const char *result_filepath, const char *path)
{
FILE *fp = NULL;
struct tree_node *subroot = NULL; /* 路徑 path 對應的結點 */
if ((NULL == root) || (NULL == result_filepath))
return -1;
if (NULL != path)
{
subroot = get_node(root, path);
if (subroot == NULL)
return -1;
}
else
{
subroot = root;
}
fp = fopen(result_filepath, "w");
if (NULL == fp)
return -1;
recursion_dump(subroot, fp) ;
fclose(fp);
return 1;
}
/********************************************************
函 數 名:get_value
功能描述:得到 path 對應的結點的 value 域值;
如果該結點為內部結點,
則得到第一個類型為 flag 的子結點的路徑
參數說明:
root,樹根
path,路徑
flag,如果返回是下一個并列結點的路徑,則 flag 的返回值為 8
返 回 值:成功返回得到的子結點路徑或 value域值,失敗返回 NULL
*********************************************************/
char *get_value(struct tree_node *root, const char *path, int *flag)
{
struct tree_node *node = NULL; /* 目標結點 */
struct tree_node *firstchild = NULL;/* 目標結點的第一個孩子 */
struct tree_node *sibling = NULL; /* 目標孩子的其它孩子 */
char *value = NULL;
int valuelen = 0;
if ((NULL == root) || (NULL == path) || (NULL == flag))
return NULL;
node = get_node(root, path);
if (NULL == node)
return NULL;
if (node->flag == NODE_IS_LEAF) /* 是葉子 */
{
value = (char *)malloc(strlen(node->data)+1);
if (NULL == value)
return NULL;
strcpy(value, node->data);
return value;
}
else if (node->flag == NODE_IS_BRANCH) /* 是樹枝 */
{
firstchild = node->firstchild;
if (firstchild != NULL)
{
if (firstchild->flag == *flag)
{
/* 別忘記了路徑之間要用 ":" 隔開,故要加 2 */
valuelen = strlen(path)+strlen(firstchild->data)+2;
value = (char *)malloc(valuelen);
if (NULL == value)
return NULL;
memset(value, '\0', valuelen);
strcpy(value, path);
strcat(value, ":");
strcat(value, firstchild->data);
*flag = 8;
return value;
}
else /* 從其它兄弟中尋找 */
{
sibling = firstchild->nextsibling;
while (sibling != NULL)
{
if (sibling->flag == *flag)
{
/* 別忘記了路徑之間要用 ":" 隔開,故要加 2 */
valuelen = strlen(path)+strlen(sibling->data)+2;
value = (char *)malloc(valuelen);
if (NULL == value)
return NULL;
memset(value, '\0', valuelen);
strcpy(value, path);
strcat(value, ":");
strcat(value, sibling->data);
*flag = 8;
return value;
}
sibling = sibling->nextsibling;
}
}
}
}
return NULL;
}
/********************************************************
函 數 名:node_is_exist
功能描述:判斷路徑是否是合法路徑
參數說明:
root,樹根
path,待判斷的路徑
返 回 值:成功返回1,失敗返回-1
*********************************************************/
int node_is_exist(struct tree_node *root, const char *path)
{
char *value = NULL;
int flag = NODE_IS_LEAF;
value = get_value(root, path, &flag);
if ((NULL != value) && (NEXT_NODE_EXIST != flag))
return 1;
else
return -1;
}
/********************************************************
函 數 名:get_next_path 功能描述:得到與 path 并列的下一類型為 flag 的路徑
參數說明:
root,樹根
path,路徑
返 回 值:成功返回得到的路徑,失敗返回 NULL
*********************************************************/
char *get_next_path(struct tree_node *root, const char *path, int flag)
{
struct tree_node *node = NULL; /* 結點 */
struct tree_node *sibling = NULL; /* 兄弟結點 */
char *nextpath = NULL;
int nextpathlen = 0;
int pathlen = 0;
int len = 0;
if ((NULL == root) || (NULL == path))
return NULL;
node = get_node(root, path);
if (NULL == node) /* 路徑為 path 的結點不存在 */
return NULL;
sibling = node->nextsibling;
while (sibling != NULL)
{
if (sibling->flag == flag)
{
len = strlen(node->data);
pathlen = strlen(path);
nextpathlen = pathlen - len + strlen(sibling->data) + 1;
nextpath = (char *)malloc(nextpathlen);
if (nextpath == NULL)
return NULL;
memset(nextpath, NULL, nextpathlen);
strncpy(nextpath, path, pathlen-len);
strcat(nextpath, sibling->data);
return nextpath;
}
sibling = sibling->nextsibling;
}
return NULL;
}
/********************************************************
函 數 名:get_next_path2
功能描述:得到下一個并列結點的路徑和結點類型
參數說明:
root,樹根
path,路徑
flag,輸出參數,下一結點的類型
返 回 值:成功返回得到的路徑,失敗返回 NULL
*********************************************************/
char *get_next_path2(struct tree_node *root, const char *path, int *flag)
{
struct tree_node *node = NULL; /* 結點 */
struct tree_node *sibling = NULL; /* 兄弟結點 */
char *nextpath = NULL;
int nextpathlen = 0;
int pathlen = 0;
int len = 0;
if ((NULL == root) || (NULL == path) || (NULL == flag))
return NULL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -