From 48a6ea7d146737949750504e652a9ad6519a4a67 Mon Sep 17 00:00:00 2001 From: aixiao Date: Mon, 8 Jun 2020 16:46:34 +0800 Subject: [PATCH] Initial submission --- Makefile | 15 ++++++ README.md | 11 +++++ libconf.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libconf.h | 12 +++++ test.c | 7 +++ test.conf | 7 +++ 6 files changed, 197 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 libconf.c create mode 100644 libconf.h create mode 100644 test.c create mode 100644 test.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..663dfcf --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +CROSS_COMPILE ?= +CC := $(CROSS_COMPILE)gcc +STRIP := $(CROSS_COMPILE)strip +AR := $(CROSS_COMPILE)ar +CFLAGS += -g -Wall +DLIB = libconf.so +SLIB = libconf.a + +all: libconf.o + $(CC) $(CFLAGS) -FPIC -shared $^ -o $(DLIB) + $(AR) -rc $(SLIB) $^ + +clean: + rm -rf *.o + rm $(DLIB) $(SLIB) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6bb01be --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# libconf + 非常小的读取conf配置文件c库,修改自CProxy. + +# build + git clone https://github.com/niuyuling/libconf + cd libconf + make + +# test + gcc -Wall test.c -o test -L./ -lconf -static + ./test \ No newline at end of file diff --git a/libconf.c b/libconf.c new file mode 100644 index 0000000..c765e66 --- /dev/null +++ b/libconf.c @@ -0,0 +1,145 @@ +#include "libconf.h" + +/* 在content中,设置变量(var)的首地址,值(val)的位置首地址和末地址,返回下一行指针 */ +static char *set_var_val_lineEnd(char *content, char **var, char **val_begin, char **val_end) +{ + + char *p, *pn, *lineEnd; + ; + int val_len; + + while (1) + { + if (content == NULL) + return NULL; + + for (;*content == ' ' || *content == '\t' || *content == '\r' || *content == '\n'; content++); + if (*content == '\0') + return NULL; + *var = content; + pn = strchr(content, '\n'); + p = strchr(content, '='); + if (p == NULL) + { + if (pn) + { + content = pn + 1; + continue; + } + else + return NULL; + } + content = p; + //将变量以\0结束 + for (p--; *p == ' ' || *p == '\t'; p--); + *(p+1) = '\0'; + //值的首地址 + for (content++; *content == ' ' || *content == '\t'; content++); + if (*content == '\0') + return NULL; + //双引号引起来的值支持换行 + if (*content == '"') + { + *val_begin = content + 1; + *val_end = strstr(*val_begin, "\";"); + if (*val_end != NULL) + break; + } + else + *val_begin = content; + *val_end = strchr(content, ';'); + if (pn && *val_end > pn) + { + content = pn + 1; + continue; + } + break; + } + + if (*val_end) + { + **val_end = '\0'; + val_len = *val_end - *val_begin; + lineEnd = *val_end; + } + else + { + val_len = strlen(*val_begin); + *val_end = lineEnd = *val_begin + val_len; + } + *val_end = *val_begin + val_len; + //printf("var[%s]\nbegin[%s]\n\n", *var, *val_begin); + return lineEnd; +} + +static char *parse_global_module(char *content, char *key) +{ + char *var, *val_begin, *val_end, *lineEnd; + int val_begin_len; + + while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) + { + if (strcasecmp(var, key) == 0) { + //printf("%s\n", val_begin); + return val_begin; + } + content = strchr(lineEnd+1, '\n'); + } + return NULL; +} + +/* 在buff中读取模块(global http https httpdns httpudp)内容 */ +static char *read_module(char *buff, const char *module_name) +{ + int len; + char *p, *p0; + + len = strlen(module_name); + p = buff; + while (1) + { + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') + p++; + if (strncasecmp(p, module_name, len) == 0) + { + p += len; + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') + p++; + if (*p == '{') + break; + } + if ((p = strchr(p, '\n')) == NULL) + return NULL; + } + + if ((p0 = strchr(++p, '}')) == NULL) + return NULL; + return strndup(p, p0 - p); +} + +char *read_conf(char *filename, char *module, char *key) +{ + char *buff, *global_content; + FILE *file; + long file_size; + + file = fopen(filename, "r"); + if (file == NULL) + perror("cannot open config file."); + fseek(file, 0, SEEK_END); + file_size = ftell(file); + buff = (char *)alloca(file_size + 1); + if (buff == NULL) + perror("out of memory."); + rewind(file); + fread(buff, file_size, 1, file); + fclose(file); + buff[file_size] = '\0'; + + if ((global_content = read_module(buff, module)) == NULL) { + perror("read module error"); + } + return parse_global_module(global_content, key); + free(global_content); +} + diff --git a/libconf.h b/libconf.h new file mode 100644 index 0000000..0d48e5b --- /dev/null +++ b/libconf.h @@ -0,0 +1,12 @@ +#ifndef LIBCONF_H +#define LIBCONF_H + +#include +#include +#include +#include +#include + +char *read_conf(char *filename, char *module, char *key); + +#endif diff --git a/test.c b/test.c new file mode 100644 index 0000000..ca18af4 --- /dev/null +++ b/test.c @@ -0,0 +1,7 @@ +#include "libconf.h" + +int main() { + printf("%s\n", read_conf("test.conf", "global", "IP_SEGMENT")); + printf("%s\n", read_conf("test.conf", "global", "a")); + printf("%s\n", read_conf("test.conf", "http", "port")); +} \ No newline at end of file diff --git a/test.conf b/test.conf new file mode 100644 index 0000000..9683b07 --- /dev/null +++ b/test.conf @@ -0,0 +1,7 @@ +global { + IP_SEGMENT= 115.60 115.61 115.62; + a= 100; +} +http { + port = 90; +}