Compare commits
7 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
f5e412a47b | |
|
|
1d07c8bf44 | |
|
|
b2a60737a1 | |
|
|
abf645c4c5 | |
|
|
6c166e1b54 | |
|
|
4da5e92ef6 | |
|
|
74bf1f92e1 |
|
|
@ -0,0 +1,26 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(conf-c)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
#set(CMAKE_C_FLAGS_RELEASE "$ENV${CFLAGS} -O3 -Wall")
|
||||
|
||||
include_directories(src)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(example)
|
||||
|
||||
# uninstall target
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
|
||||
include (CTest)
|
||||
|
||||
add_test(example example/example)
|
||||
|
||||
6
Makefile
6
Makefile
|
|
@ -7,13 +7,13 @@ libconf.a:conf.o stack.o hash.o
|
|||
cp libconf.a lib/
|
||||
|
||||
conf.o:src/conf.h src/conf.c
|
||||
gcc -c src/conf.c
|
||||
gcc -c src/conf.c -O2 -Wall
|
||||
|
||||
stack.o:src/stack/stack.h src/stack/stack.c
|
||||
gcc -c src/stack/stack.c
|
||||
gcc -c src/stack/stack.c -O2 -Wall
|
||||
|
||||
hash.o:src/hash/hash.h src/hash/hash.c
|
||||
gcc -c src/hash/hash.c
|
||||
gcc -c src/hash/hash.c -O2 -Wall
|
||||
|
||||
clean:
|
||||
rm -rfv include lib *.o *.a
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
#这是一个测试文件
|
||||
|
||||
#单个参数
|
||||
arg1 = abc
|
||||
#多个参数
|
||||
arg2 = abc,def
|
||||
#空白符
|
||||
arg3 = 'abc def'
|
||||
#特殊符号
|
||||
arg4 = "abc ' def"
|
||||
#多参数,特殊符号
|
||||
arg5 = "abc,def","#this is value",hello
|
||||
|
||||
#文件结束
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
/* conf-c一个基于c语言的轻量级读取/创建配置文件的库函数。
|
||||
* 该库使用MIT许可协议,被授权人有权利有使用、复制、修改、合并、出版发布、散布、再授权和/或贩售软件及软件的副本,及授予被供应人同等权利,惟服从以下义务。
|
||||
* 在软件和软件的所有副本中都必须包含以上版权声明和本许可声明。
|
||||
*/
|
||||
|
||||
#ifndef _CONF_H
|
||||
#define _CONF_H
|
||||
|
||||
/*配置文件中健/值以hash的方式存储在内存中*/
|
||||
//#include "hash/hash.h"
|
||||
//#include "stack/stack.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//定义错误代码
|
||||
#define CONF_OK 0 //操作成功
|
||||
#define CONF_NO_DATA -1 //没有数据
|
||||
#define CONF_NO_INIT -2 //未初始化
|
||||
#define CONF_NO_MEM -3 //申请内存出错
|
||||
#define CONF_KEY_ERR -4 //键错误
|
||||
#define CONF_VALUE_ERR -5 //值错误
|
||||
|
||||
/*值数据结构*/
|
||||
typedef struct conf_value
|
||||
{
|
||||
char *key;
|
||||
char **value;
|
||||
}CONF_VALUE;
|
||||
|
||||
/* 键/值对数据结构
|
||||
* len为当前结点个数
|
||||
* next为冲突时的链表
|
||||
*/
|
||||
typedef struct arg
|
||||
{
|
||||
int len;
|
||||
CONF_VALUE *value;
|
||||
|
||||
struct arg *next;
|
||||
}CONF_ARG;
|
||||
|
||||
/* conf-c的数据结构
|
||||
* fp为指向配置文件的FILE指针
|
||||
* len为键/值对个数
|
||||
* hash_data为存储键/值的数据结构
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
FILE *fp;
|
||||
int len;
|
||||
CONF_ARG *hash_data;
|
||||
}CONF;
|
||||
|
||||
//保存配置文件数据结构
|
||||
//len为当前参数个数
|
||||
//key为键
|
||||
//value值
|
||||
//note为注释
|
||||
typedef struct creater
|
||||
{
|
||||
FILE *fp;
|
||||
int len;
|
||||
|
||||
char *key;
|
||||
char *value;
|
||||
char *note;
|
||||
|
||||
struct creater *next;
|
||||
}CONF_CREATER;
|
||||
//打开并初始化,path为配置文件的路经,返回CONF数据
|
||||
CONF *conf_open(const char *path);
|
||||
|
||||
//解析配置文件,解析正确返回0,出错返回小于0的错误代码
|
||||
int conf_parse(CONF *conf);
|
||||
|
||||
//获取当前配置文件中键值对个数
|
||||
int conf_count(CONF *conf);
|
||||
|
||||
//得到所有键
|
||||
char **conf_key_list(CONF *conf);
|
||||
|
||||
//创建一个配置文件,path为配置文件的路经
|
||||
CONF_CREATER *conf_creater_new(const char *path);
|
||||
|
||||
/* 添加一个配置键/值对
|
||||
* value为键值对
|
||||
* note为注释内容
|
||||
* 文件中以#开头
|
||||
* 返回值:
|
||||
* 正确时返回0
|
||||
* 错误时返回小于0的错误代码
|
||||
*/
|
||||
int conf_insert(CONF_CREATER *creater,char *key,char *value,char *note);
|
||||
|
||||
//保存配置文件,正确时返回0,错误时返回小于0的错误代码
|
||||
int conf_save(CONF_CREATER *creater);
|
||||
|
||||
//释放内存
|
||||
void conf_free(CONF *conf);
|
||||
|
||||
//释放CONF_CREATER内存
|
||||
void conf_creater_free(CONF_CREATER *creater);
|
||||
|
||||
//打印错误信息函数,errcode为错误代码
|
||||
void conf_error(int errcode);
|
||||
|
||||
//根据一个键查找数据
|
||||
CONF_VALUE *conf_value_get(CONF *conf,const char *key);
|
||||
|
||||
//得到所有键值对
|
||||
CONF_VALUE **conf_value_get_all(CONF *conf);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(conf-c)
|
||||
# file(GLOB sources .)
|
||||
aux_source_directory(src sources)
|
||||
message(STATUS, "lib src is ${sources}")
|
||||
add_library(${PROJECT_NAME} SHARED ${sources})
|
||||
add_library(confc::library ALIAS ${PROJECT_NAME})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 0.4 SOVERSION 1)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/src
|
||||
)
|
||||
278
src/conf.c
278
src/conf.c
|
|
@ -2,6 +2,10 @@
|
|||
#include "stack/stack.h"
|
||||
#include <ctype.h>
|
||||
|
||||
extern unsigned int conf_hash_func1(const char *key);
|
||||
extern unsigned int conf_hash_func2(const char *key);
|
||||
extern int conf_hash_search(CONF_ARG *arg,char *key,CONF_VALUE **value);
|
||||
|
||||
//解析过程的各状态
|
||||
enum conf_stat
|
||||
{
|
||||
|
|
@ -15,16 +19,16 @@ enum conf_stat
|
|||
};
|
||||
|
||||
#define POP (*data)
|
||||
#define ADVANCE (++data)
|
||||
#define BACK (--data)
|
||||
#define LEN (data-str)
|
||||
#define ADVANCE (++data,++offset)
|
||||
#define BACK (--data,--offset)
|
||||
|
||||
#define CONF_GET_VALUE(value,stack) \
|
||||
{\
|
||||
if(conf_stack_get_data(stack) == NULL)\
|
||||
{\
|
||||
retcode=CONF_KEY_ERR;\
|
||||
printf("行:%d ",line);\
|
||||
if(conferr)\
|
||||
printf("行:%d 列:%d %c",line,offset,POP);\
|
||||
goto end;\
|
||||
}\
|
||||
value=realloc(value,sizeof(char*)*(value_len+2));\
|
||||
|
|
@ -45,6 +49,8 @@ enum conf_stat
|
|||
}
|
||||
|
||||
int line=1; //行
|
||||
int offset=1; //列
|
||||
int conferr=0;
|
||||
|
||||
//解析对参数
|
||||
//data为配置文件内容
|
||||
|
|
@ -59,13 +65,15 @@ void free_data(CONF_ARG *data);
|
|||
//得到键
|
||||
void get_key(char **key,int *index,CONF_ARG *arg);
|
||||
//读取键值
|
||||
int _conf_read_key(char *data,int len,STACK *stack);
|
||||
int _conf_read_key(char *data,STACK *stack);
|
||||
//获取值状态
|
||||
enum conf_stat _conf_value_status(char c);
|
||||
//读取值
|
||||
int _conf_read_value(char *data,int len,STACK *stack);
|
||||
int _conf_read_value(char *data,STACK *stack);
|
||||
//读取带有引号的值
|
||||
int _conf_read_value_with_quote(char *data,int len,STACK *stack,char quote);
|
||||
int _conf_read_value_with_quote(char *data,STACK *stack,char quote);
|
||||
//读取带有引号的键
|
||||
int _conf_read_key_with_quote(char *data,STACK *stack,char quote);
|
||||
|
||||
//打开配置文件并初始化值
|
||||
//path为配置文件路径
|
||||
|
|
@ -77,14 +85,16 @@ CONF *conf_open(const char *path)
|
|||
conf=malloc(sizeof(CONF));
|
||||
if(conf == NULL)
|
||||
{
|
||||
printf("申请内存空间出错!\n");
|
||||
if(conferr)
|
||||
printf("申请内存空间出错!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//打开配置文件,返回FILE指针
|
||||
if((conf->fp=fopen(path,"rb")) == NULL)
|
||||
{
|
||||
printf("打开%s出错!\n",path);
|
||||
if(conferr)
|
||||
printf("打开%s出错!\n",path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -149,13 +159,15 @@ CONF_CREATER *conf_creater_new(const char *path)
|
|||
creater=malloc(sizeof(CONF_CREATER));
|
||||
if(creater == NULL)
|
||||
{
|
||||
printf("申请内存空间出错!\n");
|
||||
if(conferr)
|
||||
printf("申请内存空间出错!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((creater->fp=fopen(path,"wb")) == NULL)
|
||||
{
|
||||
printf("创建配置文件出错!\n");
|
||||
if(conferr)
|
||||
printf("创建配置文件出错!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -164,6 +176,8 @@ CONF_CREATER *conf_creater_new(const char *path)
|
|||
creater->value=NULL;
|
||||
creater->note=NULL;
|
||||
creater->next=NULL;
|
||||
|
||||
return creater;
|
||||
}
|
||||
|
||||
//插入一个参数到内存
|
||||
|
|
@ -228,7 +242,7 @@ int conf_save(CONF_CREATER *creater)
|
|||
void conf_free(CONF *conf)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
//int j;
|
||||
|
||||
for(i=0;i != conf->size;++i)
|
||||
{
|
||||
|
|
@ -278,6 +292,12 @@ void conf_error(int errcode)
|
|||
case CONF_VALUE_ERR:
|
||||
printf("错误:错误的值!\n");
|
||||
break;
|
||||
case CONF_NO_KEY:
|
||||
printf("错误:没有键名!\n");
|
||||
break;
|
||||
case CONF_NO_VALUE:
|
||||
printf("错误:没有值!\n");
|
||||
break;
|
||||
default:
|
||||
printf("未知错误!\n");
|
||||
}
|
||||
|
|
@ -286,8 +306,8 @@ void conf_error(int errcode)
|
|||
//解析参数
|
||||
int parse_value(CONF *conf,char *data)
|
||||
{
|
||||
//保存解析字符串的首地址
|
||||
char *str=data;
|
||||
/* //保存解析字符串的首地址
|
||||
char *str=data;*/
|
||||
//状态
|
||||
int status;
|
||||
int save_status;
|
||||
|
|
@ -300,6 +320,7 @@ int parse_value(CONF *conf,char *data)
|
|||
int retcode=CONF_OK;
|
||||
//多参数个数
|
||||
int value_len=0;
|
||||
int index;
|
||||
|
||||
//初始化栈和状态
|
||||
conf_stack_init(&stack);
|
||||
|
|
@ -318,8 +339,11 @@ redo:
|
|||
status=conf_stat_note;
|
||||
else if(save_status == conf_stat_key)
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_VALUE;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
free(value->key);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -330,8 +354,9 @@ redo:
|
|||
status=conf_stat_key;
|
||||
else
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_KEY;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d =",line,offset);
|
||||
if(value)
|
||||
{
|
||||
if(value->key)
|
||||
|
|
@ -354,28 +379,63 @@ redo:
|
|||
ADVANCE;
|
||||
else
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_VALUE;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %s",line,offset,value->key);
|
||||
free(value->key);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
++line;
|
||||
offset=1;
|
||||
goto redo;
|
||||
case '\0':
|
||||
if(status == conf_stat_normal)
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_VALUE;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %s",line,offset,value->key);
|
||||
free(value->key);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
status=conf_stat_done;
|
||||
break;
|
||||
case '\'':
|
||||
case '"':
|
||||
if(status == conf_stat_start && save_status != conf_stat_key)
|
||||
status=conf_stat_quote;
|
||||
else
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
if(save_status == conf_stat_key || status != conf_stat_quote)
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
if(save_status == conf_stat_key)
|
||||
{
|
||||
free(value->key);
|
||||
free(value);
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
default:
|
||||
if(save_status == conf_stat_key)
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_VALUE;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
free(value->key);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -391,10 +451,17 @@ redo:
|
|||
status=conf_stat_start;
|
||||
save_status=conf_stat_normal;
|
||||
++line;
|
||||
offset=1;
|
||||
goto redo;
|
||||
//读取键
|
||||
case conf_stat_start:
|
||||
data+=_conf_read_key(data,LEN,&stack);
|
||||
index=_conf_read_key(data,&stack);
|
||||
if(index == -1)
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
goto end;
|
||||
}
|
||||
data+=index;
|
||||
value=malloc(sizeof(CONF_VALUE));
|
||||
if(value == NULL)
|
||||
{
|
||||
|
|
@ -404,8 +471,9 @@ redo:
|
|||
}
|
||||
if(conf_stack_get_data(&stack) == NULL)
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_KEY;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d",line,offset);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
|
|
@ -431,6 +499,48 @@ redo:
|
|||
save_status=conf_stat_key;
|
||||
end_status=_conf_value_status(POP);
|
||||
break;
|
||||
case conf_stat_quote:
|
||||
quote=POP;
|
||||
ADVANCE;
|
||||
index=_conf_read_key_with_quote(data,&stack,quote);
|
||||
if(index == -1)
|
||||
{
|
||||
retcode=CONF_KEY_ERR;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
goto end;
|
||||
}
|
||||
data+=index;
|
||||
value=malloc(sizeof(CONF_VALUE));
|
||||
if(value == NULL)
|
||||
{
|
||||
retcode=CONF_NO_MEM;
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
if(conf_stack_get_data(&stack) == NULL)
|
||||
{
|
||||
retcode=CONF_NO_KEY;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d",line,offset);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
value->key=strdup(conf_stack_get_data(&stack));
|
||||
if(value->key == NULL)
|
||||
{
|
||||
retcode=CONF_NO_MEM;
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
conf_stack_cleanup(&stack);
|
||||
save_status=conf_stat_key;
|
||||
end_status=conf_stat_done;
|
||||
value->value=NULL;
|
||||
ADVANCE;
|
||||
goto redo;
|
||||
case conf_stat_done:
|
||||
retcode=CONF_OK;
|
||||
goto end;
|
||||
|
|
@ -444,8 +554,11 @@ value_redo:
|
|||
if((save_status != conf_stat_key) ||
|
||||
(status == conf_stat_key))
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
printf("行:%d ",line);
|
||||
retcode=CONF_NO_VALUE;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
free(value->key);
|
||||
free(value);
|
||||
conf_free(conf);
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -463,21 +576,50 @@ value_redo:
|
|||
break;
|
||||
//读取值
|
||||
case conf_stat_normal:
|
||||
data+=_conf_read_value(data,LEN,&stack);
|
||||
index=_conf_read_value(data,&stack);
|
||||
if(index == -1)
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
goto end;
|
||||
}
|
||||
data+=index;
|
||||
CONF_GET_VALUE(value->value,&stack);
|
||||
while(isspace(POP) && (POP != '\n'))
|
||||
ADVANCE;
|
||||
end_status=_conf_value_status(POP);
|
||||
if(end_status == conf_stat_normal || end_status == conf_stat_quote)
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
goto end;
|
||||
}
|
||||
status=conf_stat_start;
|
||||
goto value_redo;
|
||||
//读取带有引号的值
|
||||
case conf_stat_quote:
|
||||
quote=POP;
|
||||
ADVANCE;
|
||||
data+=_conf_read_value_with_quote(data,LEN,&stack,quote);
|
||||
index=_conf_read_value_with_quote(data,&stack,quote);
|
||||
if(index == -1)
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
goto end;
|
||||
}
|
||||
data+=index;
|
||||
CONF_GET_VALUE(value->value,&stack);
|
||||
ADVANCE;
|
||||
while(isspace(POP) && (POP != '\n'))
|
||||
ADVANCE;
|
||||
end_status=_conf_value_status(POP);
|
||||
status=conf_stat_start;
|
||||
if(end_status == conf_stat_normal)
|
||||
{
|
||||
retcode=CONF_VALUE_ERR;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d %c",line,offset,POP);
|
||||
goto end;
|
||||
}
|
||||
goto value_redo;
|
||||
//多参数值读取
|
||||
case conf_stat_more_key:
|
||||
|
|
@ -561,12 +703,12 @@ CONF_VALUE *conf_value_get(CONF *conf,const char *key)
|
|||
* 否则使用第二个哈希函数计算值并比对key
|
||||
* 如果都未能匹配,则返回NULL */
|
||||
hash=conf_hash_func1(key)%conf->size;
|
||||
if(conf_hash_search(&conf->hash_data[hash],key,&value))
|
||||
if(conf_hash_search(&conf->hash_data[hash],(char *)key,&value))
|
||||
return value;
|
||||
else
|
||||
{
|
||||
hash=conf_hash_func2(key)%conf->size;
|
||||
if(conf_hash_search(&conf->hash_data[hash],key,&value))
|
||||
if(conf_hash_search(&conf->hash_data[hash],(char *)key,&value))
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
@ -606,7 +748,12 @@ CONF_VALUE **conf_value_get_all(CONF *conf)
|
|||
return value;
|
||||
}
|
||||
|
||||
int _conf_read_key(char *data,int len,STACK *stack)
|
||||
void conf_pos_msg_err(int on)
|
||||
{
|
||||
conferr=on;
|
||||
}
|
||||
|
||||
int _conf_read_key(char *data,STACK *stack)
|
||||
{
|
||||
int i=0;
|
||||
char c;
|
||||
|
|
@ -618,14 +765,15 @@ int _conf_read_key(char *data,int len,STACK *stack)
|
|||
}
|
||||
if(POP == '\n')
|
||||
{
|
||||
printf("行:%d 列:%d 解析出错\n",line,i-len);
|
||||
return 0;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d 解析出错!",line,offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
c=POP;
|
||||
if(isspace(c) || c == '=' || c == '#')
|
||||
if(isspace(c) || c == '=' || c == '#' || c == ',' || c == '\'' || c == '"')
|
||||
break;
|
||||
conf_stack_push(stack,c);
|
||||
++i;
|
||||
|
|
@ -652,7 +800,7 @@ enum conf_stat _conf_value_status(char c)
|
|||
}
|
||||
}
|
||||
|
||||
int _conf_read_value(char *data,int len,STACK *stack)
|
||||
int _conf_read_value(char *data,STACK *stack)
|
||||
{
|
||||
char c;
|
||||
int i=0;
|
||||
|
|
@ -664,14 +812,15 @@ int _conf_read_value(char *data,int len,STACK *stack)
|
|||
}
|
||||
if(POP == '\n')
|
||||
{
|
||||
printf("行:%d 列:%d 解析出错!\n",line,i-len);
|
||||
return 0;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d 解析出错!",line,offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
c=POP;
|
||||
if(isspace(c) || c == ',' || c == '#')
|
||||
if(isspace(c) || c == ',' || c == '#' || c == '\'' || c == '"')
|
||||
break;
|
||||
|
||||
conf_stack_push(stack,c);
|
||||
|
|
@ -682,26 +831,22 @@ int _conf_read_value(char *data,int len,STACK *stack)
|
|||
return i;
|
||||
}
|
||||
|
||||
int _conf_read_value_with_quote(char *data,int len,STACK *stack,char quote)
|
||||
int _conf_read_value_with_quote(char *data,STACK *stack,char quote)
|
||||
{
|
||||
char c;
|
||||
int i=0;
|
||||
|
||||
while(isspace(POP) && (POP != '\n'))
|
||||
{
|
||||
ADVANCE;
|
||||
++i;
|
||||
}
|
||||
if(POP == '\n')
|
||||
{
|
||||
printf("行:%d 列:%d 解析出错!\n",line,i-len);
|
||||
return 0;
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d 解析出错!",line,offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
c=POP;
|
||||
if(c == quote)
|
||||
if(c == quote || c == '\n')
|
||||
break;
|
||||
|
||||
conf_stack_push(stack,c);
|
||||
|
|
@ -709,8 +854,37 @@ int _conf_read_value_with_quote(char *data,int len,STACK *stack,char quote)
|
|||
ADVANCE;
|
||||
}while(c);
|
||||
|
||||
if(c == '\0')
|
||||
return 0;
|
||||
if(c == '\0'|| c == '\n')
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int _conf_read_key_with_quote(char *data,STACK *stack,char quote)
|
||||
{
|
||||
char c;
|
||||
int i=0;
|
||||
|
||||
if(POP == '\n')
|
||||
{
|
||||
if(conferr)
|
||||
printf("行:%d 列:%d 解析出错!",line,offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
c=POP;
|
||||
if(c == quote || c == '\n')
|
||||
break;
|
||||
|
||||
conf_stack_push(stack,c);
|
||||
++i;
|
||||
ADVANCE;
|
||||
}while(c);
|
||||
|
||||
if(c == '\n' || c == '\0')
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
12
src/conf.h
12
src/conf.h
|
|
@ -1,5 +1,7 @@
|
|||
/* VERSION : 1.1
|
||||
* Date :2014-10-12
|
||||
/* VERSION : 1.2
|
||||
* Date : 2014-10-12
|
||||
* 作者 : 坑头哥(Brisk)
|
||||
* 邮箱&BUG报告 : briskgreen@163.com
|
||||
* conf-c一个基于c语言的轻量级读取/创建配置文件的库函数。
|
||||
* 该库使用MIT许可协议,被授权人有权利有使用、复制、修改、合并、出版发布、散布、再授权和/或贩售软件及软件的副本,及授予被供应人同等权利,惟服从以下义务。
|
||||
* 在软件和软件的所有副本中都必须包含以上版权声明和本许可声明。
|
||||
|
|
@ -13,6 +15,7 @@
|
|||
//#include "stack/stack.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//定义错误代码
|
||||
|
|
@ -22,6 +25,8 @@
|
|||
#define CONF_NO_MEM -3 //申请内存出错
|
||||
#define CONF_KEY_ERR -4 //键错误
|
||||
#define CONF_VALUE_ERR -5 //值错误
|
||||
#define CONF_NO_KEY -6 //没有键名
|
||||
#define CONF_NO_VALUE -7 //没有值
|
||||
|
||||
#define HASH_DEFAULT 100 //默认哈希表大小
|
||||
#define HASH_SP 0.7 //当前哈希表中数据个数大于等于70%时表大小动态增长70%
|
||||
|
|
@ -118,4 +123,7 @@ CONF_VALUE *conf_value_get(CONF *conf,const char *key);
|
|||
//得到所有键值对
|
||||
CONF_VALUE **conf_value_get_all(CONF *conf);
|
||||
|
||||
//是否打印错误信息位置
|
||||
void conf_pos_msg_err(int on);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue