support directive: #@add_annotation
parent
9cd25c3686
commit
2aab8aa4c5
4
HISTORY
4
HISTORY
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
Version 1.40 2018-08-16
|
Version 1.40 2018-08-20
|
||||||
* add function conn_pool_parse_server_info and conn_pool_load_server_info
|
* add function conn_pool_parse_server_info and conn_pool_load_server_info
|
||||||
|
* support directive: #@add_annotation, for example:
|
||||||
|
#@add_annotation CONFIG_GET /usr/lib/libshmcache.so /etc/libshmcache.conf
|
||||||
|
|
||||||
Version 1.39 2018-07-31
|
Version 1.39 2018-07-31
|
||||||
* add #@function REPLACE_VARS
|
* add #@function REPLACE_VARS
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include "shared_func.h"
|
#include "shared_func.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "http_func.h"
|
#include "http_func.h"
|
||||||
|
|
@ -126,9 +127,13 @@ static void iniDoSetAnnotations(AnnotationEntry *src, const int src_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
pDest->func_name = pSrc->func_name;
|
pDest->func_name = pSrc->func_name;
|
||||||
|
pDest->arg = pSrc->arg;
|
||||||
pDest->func_init = pSrc->func_init;
|
pDest->func_init = pSrc->func_init;
|
||||||
pDest->func_destroy = pSrc->func_destroy;
|
pDest->func_destroy = pSrc->func_destroy;
|
||||||
pDest->func_get = pSrc->func_get;
|
pDest->func_get = pSrc->func_get;
|
||||||
|
pDest->func_free = pSrc->func_free;
|
||||||
|
pDest->dlhandle = pSrc->dlhandle;
|
||||||
|
pDest->inited = false;
|
||||||
if (pDest == pDestEnd) //insert
|
if (pDest == pDestEnd) //insert
|
||||||
{
|
{
|
||||||
++(*dest_count);
|
++(*dest_count);
|
||||||
|
|
@ -137,16 +142,43 @@ static void iniDoSetAnnotations(AnnotationEntry *src, const int src_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iniAnnotationFuncLocalIpGet(IniContext *context, char *param,
|
|
||||||
char **pOutValue, int max_values)
|
static AnnotationEntry *iniFindAnnotation(AnnotationEntry *annotatios,
|
||||||
|
const char *func_name)
|
||||||
|
{
|
||||||
|
AnnotationEntry *pAnnoEntry;
|
||||||
|
|
||||||
|
if (annotatios == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAnnoEntry = annotatios;
|
||||||
|
while (pAnnoEntry->func_name != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(func_name, pAnnoEntry->func_name) == 0)
|
||||||
|
{
|
||||||
|
return pAnnoEntry;
|
||||||
|
}
|
||||||
|
pAnnoEntry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iniAnnotationFuncLocalIpGet(IniContext *context,
|
||||||
|
struct ini_annotation_entry *annotation,
|
||||||
|
const IniItem *item, char **pOutValue, int max_values)
|
||||||
{
|
{
|
||||||
bool need_private_ip;
|
bool need_private_ip;
|
||||||
int count;
|
int count;
|
||||||
int index;
|
int index;
|
||||||
|
char param[FAST_INI_ITEM_VALUE_SIZE];
|
||||||
const char *next_ip;
|
const char *next_ip;
|
||||||
char *square_start;
|
char *square_start;
|
||||||
char name_part[16];
|
char name_part[16];
|
||||||
|
|
||||||
|
strcpy(param, item->value);
|
||||||
memset(name_part, 0, sizeof(name_part));
|
memset(name_part, 0, sizeof(name_part));
|
||||||
square_start = strchr(param, '[');
|
square_start = strchr(param, '[');
|
||||||
if (square_start != NULL && param[strlen(param) - 1] == ']') {
|
if (square_start != NULL && param[strlen(param) - 1] == ']') {
|
||||||
|
|
@ -197,8 +229,9 @@ static int iniAnnotationFuncLocalIpGet(IniContext *context, char *param,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iniAnnotationFuncShellExec(IniContext *context, char *param,
|
static int iniAnnotationFuncShellExec(IniContext *context,
|
||||||
char **pOutValue, int max_values)
|
struct ini_annotation_entry *annotation,
|
||||||
|
const IniItem *item, char **pOutValue, int max_values)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int result;
|
int result;
|
||||||
|
|
@ -213,24 +246,24 @@ static int iniAnnotationFuncShellExec(IniContext *context, char *param,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=getExecResult(param, output, FAST_INI_ITEM_VALUE_SIZE)) != 0)
|
if ((result=getExecResult(item->value, output, FAST_INI_ITEM_VALUE_SIZE)) != 0)
|
||||||
{
|
{
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"exec %s fail, errno: %d, error info: %s",
|
"exec %s fail, errno: %d, error info: %s",
|
||||||
__LINE__, param, result, STRERROR(result));
|
__LINE__, item->value, result, STRERROR(result));
|
||||||
free(output);
|
free(output);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
if (*output == '\0')
|
if (*output == '\0')
|
||||||
{
|
{
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"empty reply when exec: %s", __LINE__, param);
|
"empty reply when exec: %s", __LINE__, item->value);
|
||||||
}
|
}
|
||||||
pOutValue[count++] = fc_trim(output);
|
pOutValue[count++] = fc_trim(output);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iniCopyBuffer(char *dest, const int size, char *src, int len)
|
static int iniCopyBuffer(char *dest, const int size, const char *src, int len)
|
||||||
{
|
{
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -252,18 +285,19 @@ static int iniCopyBuffer(char *dest, const int size, char *src, int len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *doReplaceVars(IniContext *pContext, char *param, const int max_size)
|
static char *doReplaceVars(IniContext *pContext, const char *param,
|
||||||
|
const int max_size)
|
||||||
{
|
{
|
||||||
#define VARIABLE_TAG_MIN_LENGTH 4 //%{v}
|
#define VARIABLE_TAG_MIN_LENGTH 4 //%{v}
|
||||||
|
|
||||||
SetDirectiveVars *set;
|
SetDirectiveVars *set;
|
||||||
char *p;
|
const char *p;
|
||||||
char *e;
|
const char *e;
|
||||||
char name[64];
|
char name[64];
|
||||||
char *start;
|
const char *start;
|
||||||
char *value;
|
const char *value;
|
||||||
char *pLoopEnd;
|
const char *pLoopEnd;
|
||||||
char *pEnd;
|
const char *pEnd;
|
||||||
char *pDest;
|
char *pDest;
|
||||||
char *output;
|
char *output;
|
||||||
int name_len;
|
int name_len;
|
||||||
|
|
@ -351,11 +385,12 @@ static char *doReplaceVars(IniContext *pContext, char *param, const int max_size
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iniAnnotationReplaceVars(IniContext *pContext, char *param,
|
static int iniAnnotationReplaceVars(IniContext *pContext,
|
||||||
char **pOutValue, int max_values)
|
struct ini_annotation_entry *annotation,
|
||||||
|
const IniItem *item, char **pOutValue, int max_values)
|
||||||
{
|
{
|
||||||
char *output;
|
char *output;
|
||||||
output = doReplaceVars(pContext, param, FAST_INI_ITEM_VALUE_SIZE);
|
output = doReplaceVars(pContext, item->value, FAST_INI_ITEM_VALUE_SIZE);
|
||||||
if (output == NULL) {
|
if (output == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +400,8 @@ static int iniAnnotationReplaceVars(IniContext *pContext, char *param,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iniAnnotationFuncFree(char **values, const int count)
|
void iniAnnotationFreeValues(struct ini_annotation_entry *annotation,
|
||||||
|
char **values, const int count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<count; i++) {
|
for (i=0; i<count; i++) {
|
||||||
|
|
@ -380,28 +416,22 @@ static void iniSetBuiltinAnnotations(IniContext *pContext,
|
||||||
AnnotationEntry builtins[_BUILTIN_ANNOTATION_COUNT];
|
AnnotationEntry builtins[_BUILTIN_ANNOTATION_COUNT];
|
||||||
AnnotationEntry *pAnnotation;
|
AnnotationEntry *pAnnotation;
|
||||||
|
|
||||||
|
memset(builtins, 0, sizeof(builtins));
|
||||||
pAnnotation = builtins;
|
pAnnotation = builtins;
|
||||||
pAnnotation->func_name = "LOCAL_IP_GET";
|
pAnnotation->func_name = "LOCAL_IP_GET";
|
||||||
pAnnotation->func_init = NULL;
|
|
||||||
pAnnotation->func_destroy = NULL;
|
|
||||||
pAnnotation->func_get = iniAnnotationFuncLocalIpGet;
|
pAnnotation->func_get = iniAnnotationFuncLocalIpGet;
|
||||||
pAnnotation->func_free = NULL;
|
|
||||||
pAnnotation++;
|
pAnnotation++;
|
||||||
|
|
||||||
pAnnotation->func_name = "REPLACE_VARS";
|
pAnnotation->func_name = "REPLACE_VARS";
|
||||||
pAnnotation->func_init = NULL;
|
|
||||||
pAnnotation->func_destroy = NULL;
|
|
||||||
pAnnotation->func_get = iniAnnotationReplaceVars;
|
pAnnotation->func_get = iniAnnotationReplaceVars;
|
||||||
pAnnotation->func_free = iniAnnotationFuncFree;
|
pAnnotation->func_free = iniAnnotationFreeValues;
|
||||||
pAnnotation++;
|
pAnnotation++;
|
||||||
|
|
||||||
if ((pContext->flags & FAST_INI_FLAGS_SHELL_EXECUTE) != 0)
|
if ((pContext->flags & FAST_INI_FLAGS_SHELL_EXECUTE) != 0)
|
||||||
{
|
{
|
||||||
pAnnotation->func_name = "SHELL_EXEC";
|
pAnnotation->func_name = "SHELL_EXEC";
|
||||||
pAnnotation->func_init = NULL;
|
|
||||||
pAnnotation->func_destroy = NULL;
|
|
||||||
pAnnotation->func_get = iniAnnotationFuncShellExec;
|
pAnnotation->func_get = iniAnnotationFuncShellExec;
|
||||||
pAnnotation->func_free = iniAnnotationFuncFree;
|
pAnnotation->func_free = iniAnnotationFreeValues;
|
||||||
pAnnotation++;
|
pAnnotation++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,10 +473,9 @@ static int iniSetAnnotations(IniContext *pContext, const char annotation_type,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iniSetAnnotationCallBack(AnnotationEntry *map, int count)
|
int iniSetAnnotationCallBack(AnnotationEntry *annotations, int count)
|
||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
AnnotationEntry *pDest;
|
|
||||||
|
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
{
|
{
|
||||||
|
|
@ -466,34 +495,33 @@ int iniSetAnnotationCallBack(AnnotationEntry *map, int count)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
iniDoSetAnnotations(map, count, g_annotations, &g_annotation_count);
|
memset(g_annotations + g_annotation_count, 0,
|
||||||
|
sizeof(AnnotationEntry) * (count + 1));
|
||||||
pDest = g_annotations + g_annotation_count;
|
iniDoSetAnnotations(annotations, count, g_annotations, &g_annotation_count);
|
||||||
pDest->func_name = NULL;
|
|
||||||
pDest->func_init = NULL;
|
|
||||||
pDest->func_destroy = NULL;
|
|
||||||
pDest->func_get = NULL;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iniDestroyAnnotationCallBack()
|
void iniDestroyAnnotationCallBack()
|
||||||
{
|
{
|
||||||
AnnotationEntry *pAnnoMap;
|
AnnotationEntry *pAnnoEntry;
|
||||||
|
|
||||||
if (g_annotations == NULL)
|
if (g_annotations == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pAnnoMap = g_annotations;
|
pAnnoEntry = g_annotations;
|
||||||
while (pAnnoMap->func_name)
|
while (pAnnoEntry->func_name)
|
||||||
{
|
{
|
||||||
if (pAnnoMap->func_destroy != NULL)
|
if (pAnnoEntry->func_destroy != NULL)
|
||||||
{
|
{
|
||||||
pAnnoMap->func_destroy();
|
pAnnoEntry->func_destroy(pAnnoEntry);
|
||||||
}
|
}
|
||||||
pAnnoMap++;
|
if (pAnnoEntry->dlhandle != NULL)
|
||||||
|
{
|
||||||
|
dlclose(pAnnoEntry->dlhandle);
|
||||||
|
}
|
||||||
|
pAnnoEntry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(g_annotations);
|
free(g_annotations);
|
||||||
|
|
@ -558,6 +586,43 @@ int iniLoadFromFile(const char *szFilename, IniContext *pContext)
|
||||||
NULL, 0, FAST_INI_FLAGS_NONE);
|
NULL, 0, FAST_INI_FLAGS_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iniDestroyAnnotations(const int old_annotation_count)
|
||||||
|
{
|
||||||
|
AnnotationEntry *pAnnoEntry;
|
||||||
|
|
||||||
|
if (g_annotations == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logDebug("iniDestroyAnnotations, old_annotation_count: %d, "
|
||||||
|
"g_annotation_count: %d",
|
||||||
|
old_annotation_count, g_annotation_count);
|
||||||
|
if (old_annotation_count == 0)
|
||||||
|
{
|
||||||
|
iniDestroyAnnotationCallBack();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAnnoEntry = g_annotations + old_annotation_count;
|
||||||
|
while (pAnnoEntry->func_name)
|
||||||
|
{
|
||||||
|
if (pAnnoEntry->func_destroy != NULL)
|
||||||
|
{
|
||||||
|
pAnnoEntry->func_destroy(pAnnoEntry);
|
||||||
|
}
|
||||||
|
if (pAnnoEntry->dlhandle != NULL)
|
||||||
|
{
|
||||||
|
dlclose(pAnnoEntry->dlhandle);
|
||||||
|
}
|
||||||
|
pAnnoEntry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(g_annotations + old_annotation_count, 0,
|
||||||
|
sizeof(AnnotationEntry) * (g_annotation_count - old_annotation_count));
|
||||||
|
g_annotation_count = old_annotation_count;
|
||||||
|
}
|
||||||
|
|
||||||
int iniLoadFromFileEx(const char *szFilename, IniContext *pContext,
|
int iniLoadFromFileEx(const char *szFilename, IniContext *pContext,
|
||||||
const char annotation_type, AnnotationEntry *annotations, const int count,
|
const char annotation_type, AnnotationEntry *annotations, const int count,
|
||||||
const char flags)
|
const char flags)
|
||||||
|
|
@ -566,6 +631,7 @@ int iniLoadFromFileEx(const char *szFilename, IniContext *pContext,
|
||||||
int len;
|
int len;
|
||||||
char *pLast;
|
char *pLast;
|
||||||
char full_filename[MAX_PATH_SIZE];
|
char full_filename[MAX_PATH_SIZE];
|
||||||
|
int old_annotation_count;
|
||||||
|
|
||||||
if ((result=iniInitContext(pContext, annotation_type,
|
if ((result=iniInitContext(pContext, annotation_type,
|
||||||
annotations, count, flags)) != 0)
|
annotations, count, flags)) != 0)
|
||||||
|
|
@ -646,7 +712,13 @@ int iniLoadFromFileEx(const char *szFilename, IniContext *pContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_annotation_count = g_annotation_count;
|
||||||
result = iniDoLoadFromFile(full_filename, pContext);
|
result = iniDoLoadFromFile(full_filename, pContext);
|
||||||
|
if (g_annotation_count > old_annotation_count)
|
||||||
|
{
|
||||||
|
iniDestroyAnnotations(old_annotation_count);
|
||||||
|
}
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
iniSortItems(pContext);
|
iniSortItems(pContext);
|
||||||
|
|
@ -710,6 +782,7 @@ int iniLoadFromBufferEx(char *content, IniContext *pContext,
|
||||||
const char flags)
|
const char flags)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
int old_annotation_count;
|
||||||
|
|
||||||
if ((result=iniInitContext(pContext, annotation_type,
|
if ((result=iniInitContext(pContext, annotation_type,
|
||||||
annotations, count, flags)) != 0)
|
annotations, count, flags)) != 0)
|
||||||
|
|
@ -717,7 +790,13 @@ int iniLoadFromBufferEx(char *content, IniContext *pContext,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_annotation_count = g_annotation_count;
|
||||||
result = iniLoadItemsFromBuffer(content, pContext);
|
result = iniLoadItemsFromBuffer(content, pContext);
|
||||||
|
if (g_annotation_count > old_annotation_count)
|
||||||
|
{
|
||||||
|
iniDestroyAnnotations(old_annotation_count);
|
||||||
|
}
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
iniSortItems(pContext);
|
iniSortItems(pContext);
|
||||||
|
|
@ -737,6 +816,128 @@ int iniLoadFromBuffer(char *content, IniContext *pContext)
|
||||||
NULL, 0, FAST_INI_FLAGS_NONE);
|
NULL, 0, FAST_INI_FLAGS_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*init_annotation_func0)(AnnotationEntry *annotation);
|
||||||
|
typedef int (*init_annotation_func1)(AnnotationEntry *annotation,
|
||||||
|
const char *arg1);
|
||||||
|
typedef int (*init_annotation_func2)(AnnotationEntry *annotation,
|
||||||
|
const char *arg1, const char *arg2);
|
||||||
|
typedef int (*init_annotation_func3)(AnnotationEntry *annotation,
|
||||||
|
const char *arg1, const char *arg2, const char *arg3);
|
||||||
|
|
||||||
|
static int iniAddAnnotation(char *params)
|
||||||
|
{
|
||||||
|
#define MAX_PARAMS 5
|
||||||
|
char *cols[MAX_PARAMS];
|
||||||
|
char *func_name;
|
||||||
|
char *library;
|
||||||
|
AnnotationEntry annotation;
|
||||||
|
void *dlhandle;
|
||||||
|
void *init_func;
|
||||||
|
char symbol[64];
|
||||||
|
int argc;
|
||||||
|
int count;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
trim(params);
|
||||||
|
count = splitEx(params, ' ', cols, MAX_PARAMS);
|
||||||
|
if (count < 2)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"invalid format, correct format: "
|
||||||
|
"#@add_annotation FUNC_NAME library ...", __LINE__);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
func_name = fc_trim(cols[0]);
|
||||||
|
library = fc_trim(cols[1]);
|
||||||
|
if (func_name == '\0')
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"empty func name, correct format: "
|
||||||
|
"#@add_annotation FUNC_NAME library ...", __LINE__);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
if (library == '\0')
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"empty library, correct format: "
|
||||||
|
"#@add_annotation FUNC_NAME library ...", __LINE__);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iniFindAnnotation(g_annotations, func_name) != NULL)
|
||||||
|
{
|
||||||
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
|
"function %s already exist", __LINE__, func_name);
|
||||||
|
return EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(library, "-") == 0)
|
||||||
|
{
|
||||||
|
library = NULL;
|
||||||
|
}
|
||||||
|
else if (!fileExists(library))
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"library %s not exist", __LINE__, library);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlhandle = dlopen(library, RTLD_LAZY);
|
||||||
|
if (dlhandle == NULL)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"dlopen %s fail, error info: %s",
|
||||||
|
__LINE__, library != NULL ? library : "",
|
||||||
|
dlerror());
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(symbol, sizeof(symbol), "%s_init_annotation", func_name);
|
||||||
|
init_func = dlsym(dlhandle, symbol);
|
||||||
|
if (init_func == NULL)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"dlsym function %s fail, error info: %s",
|
||||||
|
__LINE__, symbol, dlerror());
|
||||||
|
dlclose(dlhandle);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&annotation, 0, sizeof(annotation));
|
||||||
|
argc = count - 2;
|
||||||
|
switch (argc)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
result = ((init_annotation_func0)init_func)(&annotation);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = ((init_annotation_func1)init_func)(&annotation, cols[2]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = ((init_annotation_func2)init_func)(&annotation,
|
||||||
|
cols[2], cols[3]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = ((init_annotation_func3)init_func)(&annotation,
|
||||||
|
cols[2], cols[3], cols[4]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"call function %s fail, ret: %d",
|
||||||
|
__LINE__, symbol, result);
|
||||||
|
dlclose(dlhandle);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
annotation.dlhandle = dlhandle;
|
||||||
|
return iniSetAnnotationCallBack(&annotation, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
{
|
{
|
||||||
IniSection *pSection;
|
IniSection *pSection;
|
||||||
|
|
@ -844,11 +1045,15 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
free(pIncludeFilename);
|
free(pIncludeFilename);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((*pLine == '#' && \
|
else if (*pLine == '#')
|
||||||
strncasecmp(pLine+1, "@function", 9) == 0 && \
|
|
||||||
(*(pLine+10) == ' ' || *(pLine+10) == '\t')))
|
|
||||||
{
|
{
|
||||||
if (pContext->annotation_type != FAST_INI_ANNOTATION_DISABLE)
|
if (pContext->annotation_type == FAST_INI_ANNOTATION_DISABLE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncasecmp(pLine+1, "@function", 9) == 0 &&
|
||||||
|
(*(pLine+10) == ' ' || *(pLine+10) == '\t'))
|
||||||
{
|
{
|
||||||
nNameLen = strlen(pLine + 11);
|
nNameLen = strlen(pLine + 11);
|
||||||
if (nNameLen > FAST_INI_ITEM_NAME_LEN)
|
if (nNameLen > FAST_INI_ITEM_NAME_LEN)
|
||||||
|
|
@ -870,6 +1075,16 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strncasecmp(pLine+1, "@add_annotation", 15) == 0 &&
|
||||||
|
(*(pLine+16) == ' ' || *(pLine+16) == '\t'))
|
||||||
|
{
|
||||||
|
result = iniAddAnnotation(pLine + 17);
|
||||||
|
if (!(result == 0 || result == EEXIST))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -985,16 +1200,15 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
|
|
||||||
if (isAnnotation)
|
if (isAnnotation)
|
||||||
{
|
{
|
||||||
AnnotationEntry *pAnnoMapBase;
|
AnnotationEntry *pAnnoEntryBase;
|
||||||
AnnotationEntry *pAnnoMap = NULL;
|
AnnotationEntry *pAnnoEntry = NULL;
|
||||||
bool found;
|
|
||||||
|
|
||||||
isAnnotation = 0;
|
isAnnotation = 0;
|
||||||
if ((pAnnoMapBase=iniGetAnnotations(pContext)) == NULL)
|
if ((pAnnoEntryBase=iniGetAnnotations(pContext)) == NULL)
|
||||||
{
|
{
|
||||||
pAnnoMapBase = g_annotations;
|
pAnnoEntryBase = g_annotations;
|
||||||
}
|
}
|
||||||
if (pAnnoMapBase == NULL)
|
if (pAnnoEntryBase == NULL)
|
||||||
{
|
{
|
||||||
logWarning("file: "__FILE__", line: %d, " \
|
logWarning("file: "__FILE__", line: %d, " \
|
||||||
"not set annotationMap and (%s) will use " \
|
"not set annotationMap and (%s) will use " \
|
||||||
|
|
@ -1005,38 +1219,29 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
found = false;
|
|
||||||
nItemCnt = -1;
|
nItemCnt = -1;
|
||||||
for (i=0; i<2; i++)
|
for (i=0; i<2; i++)
|
||||||
{
|
{
|
||||||
pAnnoMap = pAnnoMapBase;
|
pAnnoEntry = iniFindAnnotation(pAnnoEntryBase, pFuncName);
|
||||||
while (pAnnoMap->func_name != NULL)
|
if (pAnnoEntry != NULL)
|
||||||
{
|
{
|
||||||
if (strcmp(pFuncName, pAnnoMap->func_name) == 0)
|
if (pAnnoEntry->func_init != NULL && !pAnnoEntry->inited)
|
||||||
{
|
{
|
||||||
if (pAnnoMap->func_init != NULL)
|
pAnnoEntry->inited = true;
|
||||||
{
|
pAnnoEntry->func_init(pAnnoEntry);
|
||||||
pAnnoMap->func_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pAnnoMap->func_get != NULL)
|
|
||||||
{
|
|
||||||
nItemCnt = pAnnoMap->func_get(pContext,
|
|
||||||
pItem->value, pItemValues, 100);
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
pAnnoMap++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
if (pAnnoEntry->func_get != NULL)
|
||||||
{
|
{
|
||||||
|
nItemCnt = pAnnoEntry->func_get(pContext,
|
||||||
|
pAnnoEntry, pItem, pItemValues, 100);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (g_annotations != NULL && pAnnoMapBase != g_annotations)
|
|
||||||
|
if (g_annotations != NULL && pAnnoEntryBase != g_annotations)
|
||||||
{
|
{
|
||||||
pAnnoMapBase = g_annotations;
|
pAnnoEntryBase = g_annotations;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1094,9 +1299,9 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pAnnoMap != NULL && pAnnoMap->func_free != NULL)
|
if (pAnnoEntry != NULL && pAnnoEntry->func_free != NULL)
|
||||||
{
|
{
|
||||||
pAnnoMap->func_free(pItemValues, nItemCnt);
|
pAnnoEntry->func_free(pAnnoEntry, pItemValues, nItemCnt);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,20 @@ typedef struct ini_context
|
||||||
|
|
||||||
typedef struct ini_annotation_entry {
|
typedef struct ini_annotation_entry {
|
||||||
char *func_name;
|
char *func_name;
|
||||||
int (*func_init) ();
|
void *arg;
|
||||||
void (*func_destroy) ();
|
void *dlhandle;
|
||||||
int (*func_get) (IniContext *context, char *param, char **pOutValue, int max_values);
|
|
||||||
void (*func_free) (char **values, const int count);
|
int (*func_init) (struct ini_annotation_entry *annotation);
|
||||||
|
void (*func_destroy) (struct ini_annotation_entry *annotation);
|
||||||
|
int (*func_get) (IniContext *context,
|
||||||
|
struct ini_annotation_entry *annotation,
|
||||||
|
const IniItem *item,
|
||||||
|
char **pOutValue, int max_values);
|
||||||
|
|
||||||
|
void (*func_free) (struct ini_annotation_entry *annotation,
|
||||||
|
char **values, const int count);
|
||||||
|
|
||||||
|
bool inited;
|
||||||
} AnnotationEntry;
|
} AnnotationEntry;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -76,9 +86,12 @@ extern "C" {
|
||||||
strcasecmp(pValue, "on") == 0 || \
|
strcasecmp(pValue, "on") == 0 || \
|
||||||
strcmp(pValue, "1") == 0)
|
strcmp(pValue, "1") == 0)
|
||||||
|
|
||||||
int iniSetAnnotationCallBack(AnnotationEntry *map, int count);
|
int iniSetAnnotationCallBack(AnnotationEntry *annotations, int count);
|
||||||
void iniDestroyAnnotationCallBack();
|
void iniDestroyAnnotationCallBack();
|
||||||
|
|
||||||
|
void iniAnnotationFreeValues(struct ini_annotation_entry *annotation,
|
||||||
|
char **values, const int count);
|
||||||
|
|
||||||
/** load ini items from file
|
/** load ini items from file
|
||||||
* parameters:
|
* parameters:
|
||||||
* szFilename: the filename, can be an URL
|
* szFilename: the filename, can be an URL
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
# to support #@function CONFIG_GET
|
# to support #@function CONFIG_GET
|
||||||
|
# the version of libshmcache >= 1.0.7
|
||||||
#@add_annotation CONFIG_GET /usr/local/lib/libshmcache.so /usr/local/etc/libshmcache.conf
|
#@add_annotation CONFIG_GET /usr/local/lib/libshmcache.so /usr/local/etc/libshmcache.conf
|
||||||
|
|
||||||
|
#@function CONFIG_GET
|
||||||
|
app.version = app1.key1
|
||||||
|
|
||||||
#@set author_name = yuqing
|
#@set author_name = yuqing
|
||||||
#@set os_name = $(uname -a | awk '{print $1;}')
|
#@set os_name = $(uname -a | awk '{print $1;}')
|
||||||
|
|
||||||
|
|
@ -8,7 +12,7 @@
|
||||||
host = hostname
|
host = hostname
|
||||||
|
|
||||||
#@function LOCAL_IP_GET
|
#@function LOCAL_IP_GET
|
||||||
bind_ip = inner
|
bind_ip = inner[0]
|
||||||
|
|
||||||
#@function EXPRESS_CALC
|
#@function EXPRESS_CALC
|
||||||
thread_count = 5 * 4 + 6
|
thread_count = 5 * 4 + 6
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
#include "fastcommon/shared_func.h"
|
#include "fastcommon/shared_func.h"
|
||||||
#include "fastcommon/ini_file_reader.h"
|
#include "fastcommon/ini_file_reader.h"
|
||||||
|
|
||||||
static int iniAnnotationFuncExpressCalc(IniContext *context, char *param,
|
static int iniAnnotationFuncExpressCalc(IniContext *context,
|
||||||
|
struct ini_annotation_entry *annotation, const IniItem *item,
|
||||||
char **pOutValue, int max_values)
|
char **pOutValue, int max_values)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
@ -20,7 +21,7 @@ static int iniAnnotationFuncExpressCalc(IniContext *context, char *param,
|
||||||
static char output[256];
|
static char output[256];
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
sprintf(cmd, "echo \'%s\' | bc -l", param);
|
sprintf(cmd, "echo \'%s\' | bc -l", item->value);
|
||||||
if ((result=getExecResult(cmd, output, sizeof(output))) != 0)
|
if ((result=getExecResult(cmd, output, sizeof(output))) != 0)
|
||||||
{
|
{
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
|
|
@ -31,7 +32,7 @@ static int iniAnnotationFuncExpressCalc(IniContext *context, char *param,
|
||||||
if (*output == '\0')
|
if (*output == '\0')
|
||||||
{
|
{
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"empty reply when exec: %s", __LINE__, param);
|
"empty reply when exec: %s", __LINE__, item->value);
|
||||||
}
|
}
|
||||||
pOutValue[count++] = fc_trim(output);
|
pOutValue[count++] = fc_trim(output);
|
||||||
return count;
|
return count;
|
||||||
|
|
@ -50,11 +51,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
log_init();
|
log_init();
|
||||||
|
|
||||||
|
memset(annotations, 0, sizeof(annotations));
|
||||||
annotations[0].func_name = "EXPRESS_CALC";
|
annotations[0].func_name = "EXPRESS_CALC";
|
||||||
annotations[0].func_init = NULL;
|
|
||||||
annotations[0].func_destroy = NULL;
|
|
||||||
annotations[0].func_get = iniAnnotationFuncExpressCalc;
|
annotations[0].func_get = iniAnnotationFuncExpressCalc;
|
||||||
annotations[0].func_free = NULL;
|
|
||||||
|
|
||||||
//printf("sizeof(IniContext): %d\n", (int)sizeof(IniContext));
|
//printf("sizeof(IniContext): %d\n", (int)sizeof(IniContext));
|
||||||
result = iniLoadFromFileEx(szFilename, &context,
|
result = iniLoadFromFileEx(szFilename, &context,
|
||||||
|
|
@ -66,7 +65,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
iniPrintItems(&context);
|
iniPrintItems(&context);
|
||||||
|
iniDestroyAnnotationCallBack();
|
||||||
iniFreeContext(&context);
|
iniFreeContext(&context);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue