json parser refine error info

pull/37/head
yuqing 2018-08-24 16:25:29 +08:00
parent 3e28a90d0c
commit e53cbda01b
2 changed files with 50 additions and 41 deletions

View File

@ -1,5 +1,5 @@
Version 1.40 2018-08-22 Version 1.40 2018-08-24
* 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: * support directive: #@add_annotation, for example:
#@add_annotation CONFIG_GET /usr/lib/libshmcache.so /etc/libshmcache.conf #@add_annotation CONFIG_GET /usr/lib/libshmcache.so /etc/libshmcache.conf

View File

@ -3,6 +3,8 @@
#include "shared_func.h" #include "shared_func.h"
#include "json_parser.h" #include "json_parser.h"
#define EXPECT_STR_LEN 80
#define JSON_SPACE(ch) \ #define JSON_SPACE(ch) \
(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
@ -28,13 +30,29 @@ int detect_json_type(const string_t *input)
} }
typedef struct { typedef struct {
const char *p; const char *str; //input string
const char *p; //current
const char *end; const char *end;
string_t element; string_t element;
char *error_info; char *error_info;
int error_size; int error_size;
} ParseContext; } ParseContext;
static void set_parse_error(const char *str, const char *current,
const int expect_len, const char *front,
char *error_info, const int error_size)
{
const char *show_str;
int show_len;
show_len = current - str;
if (show_len > expect_len) {
show_len = expect_len;
}
show_str = current - show_len;
snprintf(error_info, error_size, "%s, input: %.*s",
front, show_len, show_str);
}
static int json_escape_string(const string_t *input, string_t *output, static int json_escape_string(const string_t *input, string_t *output,
char *error_info, const int error_size) char *error_info, const int error_size)
@ -97,6 +115,7 @@ static int json_escape_string(const string_t *input, string_t *output,
static int next_json_element(ParseContext *context) static int next_json_element(ParseContext *context)
{ {
char *dest; char *dest;
char buff[128];
char quote_ch; char quote_ch;
dest = context->element.str; dest = context->element.str;
@ -106,8 +125,9 @@ static int next_json_element(ParseContext *context)
while (context->p < context->end && *context->p != quote_ch) { while (context->p < context->end && *context->p != quote_ch) {
if (*context->p == '\\') { if (*context->p == '\\') {
if (++context->p == context->end) { if (++context->p == context->end) {
snprintf(context->error_info, context->error_size, set_parse_error(context->str, context->p,
"expect a character after \\"); EXPECT_STR_LEN, "expect a character after \\",
context->error_info, context->error_size);
return EINVAL; return EINVAL;
} }
switch (*context->p) { switch (*context->p) {
@ -136,9 +156,10 @@ static int next_json_element(ParseContext *context)
*dest++ = '\''; *dest++ = '\'';
break; break;
default: default:
snprintf(context->error_info, context->error_size, sprintf(buff, "invalid escaped character: %c(0x%x)",
"invalid escaped character: %c(0x%x)",
*context->p, (unsigned char)*context->p); *context->p, (unsigned char)*context->p);
set_parse_error(context->str, context->p + 1, EXPECT_STR_LEN,
buff, context->error_info, context->error_size);
return EINVAL; return EINVAL;
} }
context->p++; context->p++;
@ -148,8 +169,9 @@ static int next_json_element(ParseContext *context)
} }
if (context->p == context->end) { if (context->p == context->end) {
snprintf(context->error_info, context->error_size, sprintf(buff, "expect closed character: %c", quote_ch);
"expect closed character: %c", quote_ch); set_parse_error(context->str, context->p, EXPECT_STR_LEN,
buff, context->error_info, context->error_size);
return EINVAL; return EINVAL;
} }
context->p++; //skip quote char context->p++; //skip quote char
@ -217,12 +239,12 @@ static int prepare_json_parse(const string_t *input, common_array_t *array,
if (input->str[0] != lquote) { if (input->str[0] != lquote) {
snprintf(error_info, error_size, snprintf(error_info, error_size,
"json array must start with %c", lquote); "json array must start with \"%c\"", lquote);
return EINVAL; return EINVAL;
} }
if (input->str[input->len - 1] != rquote) { if (input->str[input->len - 1] != rquote) {
snprintf(error_info, error_size, snprintf(error_info, error_size,
"json array must end with %c", rquote); "json array must end with \"%c\"", rquote);
return EINVAL; return EINVAL;
} }
@ -238,6 +260,7 @@ static int prepare_json_parse(const string_t *input, common_array_t *array,
context->error_size = error_size; context->error_size = error_size;
context->element.str = array->buff; context->element.str = array->buff;
context->element.len = 0; context->element.len = 0;
context->str = input->str;
context->p = input->str + 1; context->p = input->str + 1;
context->end = input->str + input->len - 1; context->end = input->str + input->len - 1;
return 0; return 0;
@ -256,8 +279,6 @@ int decode_json_array(const string_t *input, json_array_t *array,
return result; return result;
} }
fprintf(stderr, "line: %d\n", __LINE__);
result = 0; result = 0;
while (context.p < context.end) { while (context.p < context.end) {
while (context.p < context.end && JSON_SPACE(*context.p)) { while (context.p < context.end && JSON_SPACE(*context.p)) {
@ -268,17 +289,11 @@ int decode_json_array(const string_t *input, json_array_t *array,
break; break;
} }
fprintf(stderr, "start: %s\n", context.p);
if (*context.p == ',') { if (*context.p == ',') {
context.p++; set_parse_error(input->str, context.p + 1,
while (context.p < context.end && JSON_SPACE(*context.p)) { EXPECT_STR_LEN, "unexpect comma \",\"",
context.p++; error_info, error_size);
}
if (context.p < context.end) { //ignore last comma
snprintf(error_info, error_size, "unexpect comma \",\"");
result = EINVAL; result = EINVAL;
}
break; break;
} }
@ -293,12 +308,13 @@ int decode_json_array(const string_t *input, json_array_t *array,
if (*context.p == ',') { if (*context.p == ',') {
context.p++; //skip comma context.p++; //skip comma
} else { } else {
snprintf(error_info, error_size, "expect comma \",\""); set_parse_error(input->str, context.p,
EXPECT_STR_LEN, "expect comma \",\"",
error_info, error_size);
result = EINVAL; result = EINVAL;
break; break;
} }
} }
fprintf(stderr, "end: %s\n", context.p);
if ((result=check_alloc_json_array(array, error_info, error_size)) != 0) { if ((result=check_alloc_json_array(array, error_info, error_size)) != 0) {
array->count = 0; array->count = 0;
@ -407,8 +423,6 @@ int decode_json_map(const string_t *input, json_map_t *map,
return result; return result;
} }
fprintf(stderr, "line: %d\n", __LINE__);
result = 0; result = 0;
while (context.p < context.end) { while (context.p < context.end) {
while (context.p < context.end && JSON_SPACE(*context.p)) { while (context.p < context.end && JSON_SPACE(*context.p)) {
@ -419,17 +433,11 @@ int decode_json_map(const string_t *input, json_map_t *map,
break; break;
} }
fprintf(stderr, "start: %s\n", context.p);
if (*context.p == ',') { if (*context.p == ',') {
context.p++; set_parse_error(input->str, context.p + 1,
while (context.p < context.end && JSON_SPACE(*context.p)) { EXPECT_STR_LEN, "unexpect comma \",\"",
context.p++; error_info, error_size);
}
if (context.p < context.end) { //ignore last comma
snprintf(error_info, error_size, "unexpect comma \",\"");
result = EINVAL; result = EINVAL;
}
break; break;
} }
@ -440,12 +448,13 @@ int decode_json_map(const string_t *input, json_map_t *map,
context.p++; context.p++;
} }
if (!(context.p < context.end && *context.p == ':')) { if (!(context.p < context.end && *context.p == ':')) {
snprintf(error_info, error_size, "expect colon \":\""); set_parse_error(input->str, context.p,
EXPECT_STR_LEN, "expect colon \":\"",
error_info, error_size);
result = EINVAL; result = EINVAL;
break; break;
} }
context.p++; //skip colon context.p++; //skip colon
fprintf(stderr, "end1: %s\n", context.p);
kv_pair.key = context.element; kv_pair.key = context.element;
context.element.str += context.element.len + 1; context.element.str += context.element.len + 1;
@ -459,17 +468,17 @@ int decode_json_map(const string_t *input, json_map_t *map,
while (context.p < context.end && JSON_SPACE(*context.p)) { while (context.p < context.end && JSON_SPACE(*context.p)) {
context.p++; context.p++;
} }
fprintf(stderr, "end2: %s\n", context.p);
if (context.p < context.end) { if (context.p < context.end) {
if (*context.p == ',') { if (*context.p == ',') {
context.p++; //skip comma context.p++; //skip comma
} else { } else {
snprintf(error_info, error_size, "expect comma \",\""); set_parse_error(input->str, context.p,
EXPECT_STR_LEN, "expect comma \",\"",
error_info, error_size);
result = EINVAL; result = EINVAL;
break; break;
} }
} }
fprintf(stderr, "end3: %s\n", context.p);
kv_pair.value = context.element; kv_pair.value = context.element;
context.element.str += context.element.len + 1; context.element.str += context.element.len + 1;