mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 11:08:34 +08:00
add func_call_parser
This commit is contained in:
parent
fab3d865ed
commit
8911bc3dad
74
src/base/func_call_parser.c
Normal file
74
src/base/func_call_parser.c
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* File: func_call_parser.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: func_call_parser
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is difunc_call_parseributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-10-20 Li XianJing <xianjimli@hotmail.com> adapt from uclib
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/utils.h"
|
||||
#include "base/func_call_parser.h"
|
||||
|
||||
func_call_parser_t* func_call_parser_init(func_call_parser_t* parser, const char* str,
|
||||
uint32_t size) {
|
||||
return_value_if_fail(parser != NULL && str != NULL, NULL);
|
||||
|
||||
tokenizer_init(&(parser->tokenizer), str, size, "(=,) ");
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
ret_t func_call_parser_parse(func_call_parser_t* parser) {
|
||||
const char* token = NULL;
|
||||
char name[NAME_LEN + 1];
|
||||
tokenizer_t* tokenizer = NULL;
|
||||
return_value_if_fail(parser != NULL, RET_BAD_PARAMS);
|
||||
|
||||
tokenizer = &(parser->tokenizer);
|
||||
return_value_if_fail(tokenizer_has_more(tokenizer) == TRUE, RET_BAD_PARAMS);
|
||||
|
||||
token = tokenizer_next(tokenizer);
|
||||
if (parser->on_name != NULL) {
|
||||
parser->on_name(parser, token);
|
||||
}
|
||||
|
||||
while (tokenizer_has_more(tokenizer)) {
|
||||
token = tokenizer_next(tokenizer);
|
||||
tk_strncpy(name, token, NAME_LEN);
|
||||
|
||||
ENSURE(tokenizer_has_more(tokenizer));
|
||||
token = tokenizer_next(tokenizer);
|
||||
|
||||
if (parser->on_param != NULL) {
|
||||
parser->on_param(parser, name, token);
|
||||
}
|
||||
}
|
||||
|
||||
if (parser->on_done != NULL) {
|
||||
parser->on_done(parser);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t func_call_parser_deinit(func_call_parser_t* parser) {
|
||||
return_value_if_fail(parser != NULL, RET_BAD_PARAMS);
|
||||
|
||||
tokenizer_deinit(&(parser->tokenizer));
|
||||
memset(parser, 0x00, sizeof(func_call_parser_t));
|
||||
|
||||
return RET_OK;
|
||||
}
|
91
src/base/func_call_parser.h
Normal file
91
src/base/func_call_parser.h
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* File: func_call_parser.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: func_call_parser
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is difunc_call_parseributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-10-20 Li XianJing <xianjimli@hotmail.com> adapt from uclib
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_FUNC_CALL_PARSER_H
|
||||
#define TK_FUNC_CALL_PARSER_H
|
||||
|
||||
#include "base/tokenizer.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
struct _func_call_parser_t;
|
||||
typedef struct _func_call_parser_t func_call_parser_t;
|
||||
|
||||
/*子类需要实现的虚函数*/
|
||||
typedef ret_t (*func_call_parser_on_name_t)(func_call_parser_t* parser, const char* func_name);
|
||||
typedef ret_t (*func_call_parser_on_param_t)(func_call_parser_t* parser, const char* name,
|
||||
const char* value);
|
||||
typedef ret_t (*func_call_parser_on_done_t)(func_call_parser_t* parser);
|
||||
|
||||
/**
|
||||
* @class func_call_parser_t
|
||||
* 从字符串中解析出函数调用需要的参数。
|
||||
* func_call => func_name '(' params ')'
|
||||
* params => param ',' params
|
||||
* param => name '=' value
|
||||
* func_name => ID
|
||||
* name = ID
|
||||
* value = int | float | ID
|
||||
*
|
||||
* 如:move(x=10, y=20)
|
||||
* 如:rename(old_name=aa, new_name=bb)
|
||||
*/
|
||||
struct _func_call_parser_t {
|
||||
tokenizer_t tokenizer;
|
||||
func_call_parser_on_name_t on_name;
|
||||
func_call_parser_on_param_t on_param;
|
||||
func_call_parser_on_done_t on_done;
|
||||
};
|
||||
|
||||
/**
|
||||
* @method func_call_parser_init
|
||||
* 初始化parser对象。
|
||||
* @annotation ["constructor"]
|
||||
* @param {func_call_parser_t*} parser parser对象。
|
||||
* @param {char*} str 要解析的字符串。
|
||||
* @param {uint32_t} size 字符串长度。
|
||||
*
|
||||
* @return {func_call_parser_t*} parser对象本身。
|
||||
*/
|
||||
func_call_parser_t* func_call_parser_init(func_call_parser_t* parser, const char* str,
|
||||
uint32_t size);
|
||||
|
||||
/**
|
||||
* @method func_call_parser_parse
|
||||
* 开始解析。
|
||||
* @param {func_call_parser_t*} parser parser对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t func_call_parser_parse(func_call_parser_t* parser);
|
||||
|
||||
/**
|
||||
* @method func_call_parser_deinit
|
||||
* 重置parser。
|
||||
* @param {func_call_parser_t*} parser parser对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t func_call_parser_deinit(func_call_parser_t* parser);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_FUNC_CALL_PARSER_H*/
|
60
tests/func_call_parser_test.cc
Normal file
60
tests/func_call_parser_test.cc
Normal file
@ -0,0 +1,60 @@
|
||||
#include "base/utils.h"
|
||||
#include "base/func_call_parser.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <math.h>
|
||||
|
||||
typedef struct _parser_t {
|
||||
func_call_parser_t base;
|
||||
char name[NAME_LEN + 1];
|
||||
int x;
|
||||
int y;
|
||||
} parser_t;
|
||||
|
||||
static ret_t parser_on_name(func_call_parser_t* parser, const char* func_name) {
|
||||
parser_t* p = (parser_t*)parser;
|
||||
|
||||
tk_strncpy(p->name, func_name, NAME_LEN);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t parser_on_param(func_call_parser_t* parser, const char* name, const char* value) {
|
||||
parser_t* p = (parser_t*)parser;
|
||||
if (tk_str_eq(name, "x")) {
|
||||
p->x = tk_atoi(value);
|
||||
} else if (tk_str_eq(name, "y")) {
|
||||
p->y = tk_atoi(value);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t parser_on_done(func_call_parser_t* parser) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static void parser_test(const char* str) {
|
||||
parser_t parser;
|
||||
|
||||
memset(&parser, 0x00, sizeof(parser));
|
||||
func_call_parser_init(&(parser.base), str, strlen(str));
|
||||
|
||||
parser.base.on_name = parser_on_name;
|
||||
parser.base.on_param = parser_on_param;
|
||||
parser.base.on_done = parser_on_done;
|
||||
|
||||
func_call_parser_parse(&(parser.base));
|
||||
|
||||
ASSERT_EQ(parser.x, 10);
|
||||
ASSERT_EQ(parser.y, 20);
|
||||
ASSERT_EQ(tk_str_eq(parser.name, "move"), true);
|
||||
|
||||
func_call_parser_deinit(&parser.base);
|
||||
}
|
||||
|
||||
TEST(FuncCallParser, basic) {
|
||||
parser_test("move(x=10, y=20)");
|
||||
parser_test("move (x=10, y=20)");
|
||||
parser_test("move(x = 10, y = 20 )");
|
||||
parser_test(" move(x = 10, y = 20 )");
|
||||
}
|
Loading…
Reference in New Issue
Block a user