(libretro-db) Pass tmp_error_buff around to other functions

This commit is contained in:
twinaphex 2020-07-05 02:50:46 +02:00
parent d5bdec3f60
commit 69b457a427
1 changed files with 142 additions and 94 deletions

View File

@ -91,21 +91,21 @@ struct registered_func
rarch_query_func func; rarch_query_func func;
}; };
/* TODO/FIXME - static global variable */
static char tmp_error_buff [MAX_ERROR_LEN] = {0};
/* Forward declarations */ /* Forward declarations */
static struct buffer query_parse_method_call(struct buffer buff, static struct buffer query_parse_method_call(char *s, size_t len,
struct buffer buff,
struct invocation *invocation, const char **error); struct invocation *invocation, const char **error);
static struct buffer query_parse_table(struct buffer buff, static struct buffer query_parse_table(char *s,
size_t len, struct buffer buff,
struct invocation *invocation, const char **error); struct invocation *invocation, const char **error);
/* Errors */ /* Errors */
static void query_raise_too_many_arguments(const char **error) static void query_raise_too_many_arguments(
char *tmp, size_t len, const char **error)
{ {
strlcpy(tmp_error_buff, strlcpy(tmp,
"Too many arguments in function call.", sizeof(tmp_error_buff)); "Too many arguments in function call.", len);
*error = tmp_error_buff; *error = tmp;
} }
static struct rmsgpack_dom_value query_func_is_true( static struct rmsgpack_dom_value query_func_is_true(
@ -288,71 +288,80 @@ struct registered_func registered_functions[100] = {
{NULL, NULL} {NULL, NULL}
}; };
static void query_raise_expected_number(ssize_t where, const char **error) static void query_raise_expected_number(
char *tmp, size_t len,
ssize_t where, const char **error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(tmp, len,
"%" PRIu64 "::Expected number", "%" PRIu64 "::Expected number",
(uint64_t)where); (uint64_t)where);
*error = tmp_error_buff; *error = tmp;
} }
static void query_raise_expected_string(ssize_t where, const char ** error) static void query_raise_expected_string(
char *tmp, size_t len,
ssize_t where, const char ** error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(tmp, len,
"%" PRIu64 "::Expected string", "%" PRIu64 "::Expected string",
(uint64_t)where); (uint64_t)where);
*error = tmp_error_buff; *error = tmp;
} }
static void query_raise_unexpected_eof(ssize_t where, const char ** error) static void query_raise_unexpected_eof(
char *tmp, size_t len,
ssize_t where, const char ** error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(tmp, len,
"%" PRIu64 "::Unexpected EOF", "%" PRIu64 "::Unexpected EOF",
(uint64_t)where (uint64_t)where
); );
*error = tmp_error_buff; *error = tmp;
} }
static void query_raise_enomem(const char **error) static void query_raise_enomem(char *s, size_t len, const char **error)
{ {
strlcpy(tmp_error_buff, "Out of memory", sizeof(tmp_error_buff)); strlcpy(s, "Out of memory", len);
*error = tmp_error_buff; *error = s;
} }
static void query_raise_unknown_function(ssize_t where, const char *name, static void query_raise_unknown_function(
char *s, size_t _len,
ssize_t where, const char *name,
ssize_t len, const char **error) ssize_t len, const char **error)
{ {
int n = snprintf(tmp_error_buff, MAX_ERROR_LEN, int n = snprintf(s, _len,
"%" PRIu64 "::Unknown function '", "%" PRIu64 "::Unknown function '",
(uint64_t)where (uint64_t)where
); );
if (len < (MAX_ERROR_LEN - n - 3)) if (len < (_len - n - 3))
strncpy(tmp_error_buff + n, name, len); strncpy(s + n, name, len);
strlcpy(tmp_error_buff + n + len, "'", sizeof(tmp_error_buff)); strlcpy(s + n + len, "'", _len);
*error = tmp_error_buff; *error = s;
} }
static void query_raise_expected_eof( static void query_raise_expected_eof(char *s, size_t len,
ssize_t where, char found, const char **error) ssize_t where, char found, const char **error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(s, len,
"%" PRIu64 "::Expected EOF found '%c'", "%" PRIu64 "::Expected EOF found '%c'",
(uint64_t)where, (uint64_t)where,
found found
); );
*error = tmp_error_buff; *error = s;
} }
static void query_raise_unexpected_char( static void query_raise_unexpected_char(
char *s, size_t len,
ssize_t where, char expected, char found, ssize_t where, char expected, char found,
const char **error) const char **error)
{ {
snprintf(tmp_error_buff, MAX_ERROR_LEN, snprintf(s, len,
"%" PRIu64 "::Expected '%c' found '%c'", "%" PRIu64 "::Expected '%c' found '%c'",
(uint64_t)where, expected, found); (uint64_t)where, expected, found);
*error = tmp_error_buff; *error = s;
} }
static void query_argument_free(struct argument *arg) static void query_argument_free(struct argument *arg)
@ -371,8 +380,11 @@ static void query_argument_free(struct argument *arg)
free((void*)arg->a.invocation.argv); free((void*)arg->a.invocation.argv);
} }
static struct buffer query_parse_integer(struct buffer buff, static struct buffer query_parse_integer(
struct rmsgpack_dom_value *value, const char **error) char *s, size_t len,
struct buffer buff,
struct rmsgpack_dom_value *value,
const char **error)
{ {
bool test = false; bool test = false;
@ -383,7 +395,7 @@ static struct buffer query_parse_integer(struct buffer buff,
(int64_t*)&value->val.int_) == 0); (int64_t*)&value->val.int_) == 0);
if (test) if (test)
query_raise_expected_number(buff.offset, error); query_raise_expected_number(s, len, buff.offset, error);
else else
{ {
while (isdigit((int)buff.data[buff.offset])) while (isdigit((int)buff.data[buff.offset]))
@ -400,11 +412,13 @@ static struct buffer query_chomp(struct buffer buff)
return buff; return buff;
} }
static struct buffer query_expect_eof(struct buffer buff, const char ** error) static struct buffer query_expect_eof(char *s, size_t len,
struct buffer buff, const char ** error)
{ {
buff = query_chomp(buff); buff = query_chomp(buff);
if ((unsigned)buff.offset < buff.len) if ((unsigned)buff.offset < buff.len)
query_raise_expected_eof(buff.offset, buff.data[buff.offset], error); query_raise_expected_eof(s, len,
buff.offset, buff.data[buff.offset], error);
return buff; return buff;
} }
@ -426,12 +440,15 @@ static int query_is_eot(struct buffer buff)
} }
static struct buffer query_get_char( static struct buffer query_get_char(
char *s, size_t len,
struct buffer buff, char * c, struct buffer buff, char * c,
const char ** error) const char ** error)
{ {
if (query_is_eot(buff)) if (query_is_eot(buff))
{ {
query_raise_unexpected_eof(buff.offset, error); query_raise_unexpected_eof(
s, len,
buff.offset, error);
return buff; return buff;
} }
@ -440,17 +457,16 @@ static struct buffer query_get_char(
return buff; return buff;
} }
static struct buffer query_parse_string(struct buffer buff, static struct buffer query_parse_string(
char *s, size_t len,
struct buffer buff,
struct rmsgpack_dom_value *value, const char **error) struct rmsgpack_dom_value *value, const char **error)
{ {
const char * str_start = NULL; const char * str_start = NULL;
char terminator = '\0'; char terminator = '\0';
char c = '\0'; char c = '\0';
int is_binstr = 0; int is_binstr = 0;
buff = query_get_char(s, len,buff, &terminator, error);
(void)c;
buff = query_get_char(buff, &terminator, error);
if (*error) if (*error)
return buff; return buff;
@ -458,23 +474,25 @@ static struct buffer query_parse_string(struct buffer buff,
if (terminator == 'b') if (terminator == 'b')
{ {
is_binstr = 1; is_binstr = 1;
buff = query_get_char(buff, &terminator, error); buff = query_get_char(s, len,
buff, &terminator, error);
} }
if (terminator != '"' && terminator != '\'') if (terminator != '"' && terminator != '\'')
{ {
buff.offset--; buff.offset--;
query_raise_expected_string(buff.offset, error); query_raise_expected_string(s, len,
buff.offset, error);
} }
str_start = buff.data + buff.offset; str_start = buff.data + buff.offset;
buff = query_get_char(buff, &c, error); buff = query_get_char(s, len, buff, &c, error);
while (!*error) while (!*error)
{ {
if (c == terminator) if (c == terminator)
break; break;
buff = query_get_char(buff, &c, error); buff = query_get_char(s, len, buff, &c, error);
} }
if (!*error) if (!*error)
@ -488,7 +506,7 @@ static struct buffer query_parse_string(struct buffer buff,
value->val.string.buff = (char*)calloc(count, sizeof(char)); value->val.string.buff = (char*)calloc(count, sizeof(char));
if (!value->val.string.buff) if (!value->val.string.buff)
query_raise_enomem(error); query_raise_enomem(s, len, error);
else if (is_binstr) else if (is_binstr)
{ {
unsigned i; unsigned i;
@ -522,7 +540,9 @@ static struct buffer query_parse_string(struct buffer buff,
return buff; return buff;
} }
static struct buffer query_parse_value(struct buffer buff, static struct buffer query_parse_value(
char *s, size_t len,
struct buffer buff,
struct rmsgpack_dom_value *value, const char **error) struct rmsgpack_dom_value *value, const char **error)
{ {
buff = query_chomp(buff); buff = query_chomp(buff);
@ -544,26 +564,33 @@ static struct buffer query_parse_value(struct buffer buff,
value->type = RDT_BOOL; value->type = RDT_BOOL;
value->val.bool_ = 0; value->val.bool_ = 0;
} }
else if (query_peek(buff, "b") || query_peek(buff, "\"") || query_peek(buff, "'")) else if (
buff = query_parse_string(buff, value, error); query_peek(buff, "b") ||
query_peek(buff, "\"") ||
query_peek(buff, "'"))
buff = query_parse_string(s, len,
buff, value, error);
else if (isdigit((int)buff.data[buff.offset])) else if (isdigit((int)buff.data[buff.offset]))
buff = query_parse_integer(buff, value, error); buff = query_parse_integer(s, len, buff, value, error);
return buff; return buff;
} }
static void query_peek_char(struct buffer buff, char *c, static void query_peek_char(char *s, size_t len,
struct buffer buff, char *c,
const char **error) const char **error)
{ {
if (query_is_eot(buff)) if (query_is_eot(buff))
{ {
query_raise_unexpected_eof(buff.offset, error); query_raise_unexpected_eof(s, len, buff.offset, error);
return; return;
} }
*c = buff.data[buff.offset]; *c = buff.data[buff.offset];
} }
static struct buffer query_get_ident(struct buffer buff, static struct buffer query_get_ident(
char *s, size_t _len,
struct buffer buff,
const char **ident, const char **ident,
size_t *len, const char **error) size_t *len, const char **error)
{ {
@ -571,13 +598,13 @@ static struct buffer query_get_ident(struct buffer buff,
if (query_is_eot(buff)) if (query_is_eot(buff))
{ {
query_raise_unexpected_eof(buff.offset, error); query_raise_unexpected_eof(s, _len, buff.offset, error);
return buff; return buff;
} }
*ident = buff.data + buff.offset; *ident = buff.data + buff.offset;
*len = 0; *len = 0;
query_peek_char(buff, &c, error); query_peek_char(s, _len, buff, &c, error);
if (*error) if (*error)
goto clean; goto clean;
@ -586,7 +613,7 @@ static struct buffer query_get_ident(struct buffer buff,
buff.offset++; buff.offset++;
*len = *len + 1; *len = *len + 1;
query_peek_char(buff, &c, error); query_peek_char(s, _len, buff, &c, error);
while (!*error) while (!*error)
{ {
@ -594,27 +621,31 @@ static struct buffer query_get_ident(struct buffer buff,
break; break;
buff.offset++; buff.offset++;
*len = *len + 1; *len = *len + 1;
query_peek_char(buff, &c, error); query_peek_char(s, _len, buff, &c, error);
} }
clean: clean:
return buff; return buff;
} }
static struct buffer query_expect_char(struct buffer buff, static struct buffer query_expect_char(
char *s, size_t len,
struct buffer buff,
char c, const char ** error) char c, const char ** error)
{ {
if ((unsigned)buff.offset >= buff.len) if ((unsigned)buff.offset >= buff.len)
query_raise_unexpected_eof(buff.offset, error); query_raise_unexpected_eof(s, len, buff.offset, error);
else if (buff.data[buff.offset] != c) else if (buff.data[buff.offset] != c)
query_raise_unexpected_char( query_raise_unexpected_char(s, len,
buff.offset, c, buff.data[buff.offset], error); buff.offset, c, buff.data[buff.offset], error);
else else
buff.offset++; buff.offset++;
return buff; return buff;
} }
static struct buffer query_parse_argument(struct buffer buff, static struct buffer query_parse_argument(
char *s, size_t len,
struct buffer buff,
struct argument *arg, const char **error) struct argument *arg, const char **error)
{ {
buff = query_chomp(buff); buff = query_chomp(buff);
@ -631,40 +662,44 @@ static struct buffer query_parse_argument(struct buffer buff,
) )
{ {
arg->type = AT_FUNCTION; arg->type = AT_FUNCTION;
buff = query_parse_method_call(buff, buff = query_parse_method_call(s, len, buff,
&arg->a.invocation, error); &arg->a.invocation, error);
} }
else if (query_peek(buff, "{")) else if (query_peek(buff, "{"))
{ {
arg->type = AT_FUNCTION; arg->type = AT_FUNCTION;
buff = query_parse_table(buff, &arg->a.invocation, error); buff = query_parse_table(s, len,
buff, &arg->a.invocation, error);
} }
else else
{ {
arg->type = AT_VALUE; arg->type = AT_VALUE;
buff = query_parse_value(buff, &arg->a.value, error); buff = query_parse_value(s,
len, buff, &arg->a.value, error);
} }
return buff; return buff;
} }
static struct buffer query_parse_method_call(struct buffer buff, static struct buffer query_parse_method_call(
char *s, size_t len, struct buffer buff,
struct invocation *invocation, const char **error) struct invocation *invocation, const char **error)
{ {
size_t func_name_len; size_t func_name_len;
unsigned i; unsigned i;
struct argument args[QUERY_MAX_ARGS]; struct argument args[QUERY_MAX_ARGS];
unsigned argi = 0; unsigned argi = 0;
const char *func_name = NULL; const char *func_name = NULL;
struct registered_func *rf = registered_functions; struct registered_func *rf = registered_functions;
invocation->func = NULL; invocation->func = NULL;
buff = query_get_ident(buff, &func_name, &func_name_len, error); buff = query_get_ident(s, len,
buff, &func_name, &func_name_len, error);
if (*error) if (*error)
goto clean; goto clean;
buff = query_chomp(buff); buff = query_chomp(buff);
buff = query_expect_char(buff, '(', error); buff = query_expect_char(s, len, buff, '(', error);
if (*error) if (*error)
goto clean; goto clean;
@ -680,7 +715,8 @@ static struct buffer query_parse_method_call(struct buffer buff,
if (!invocation->func) if (!invocation->func)
{ {
query_raise_unknown_function(buff.offset, func_name, query_raise_unknown_function(s, len,
buff.offset, func_name,
func_name_len, error); func_name_len, error);
goto clean; goto clean;
} }
@ -690,18 +726,18 @@ static struct buffer query_parse_method_call(struct buffer buff,
{ {
if (argi >= QUERY_MAX_ARGS) if (argi >= QUERY_MAX_ARGS)
{ {
query_raise_too_many_arguments(error); query_raise_too_many_arguments(s, len, error);
goto clean; goto clean;
} }
buff = query_parse_argument(buff, &args[argi], error); buff = query_parse_argument(s, len, buff, &args[argi], error);
if (*error) if (*error)
goto clean; goto clean;
argi++; argi++;
buff = query_chomp(buff); buff = query_chomp(buff);
buff = query_expect_char(buff, ',', error); buff = query_expect_char(s, len, buff, ',', error);
if (*error) if (*error)
{ {
@ -710,7 +746,7 @@ static struct buffer query_parse_method_call(struct buffer buff,
} }
buff = query_chomp(buff); buff = query_chomp(buff);
} }
buff = query_expect_char(buff, ')', error); buff = query_expect_char(s, len, buff, ')', error);
if (*error) if (*error)
goto clean; goto clean;
@ -721,7 +757,7 @@ static struct buffer query_parse_method_call(struct buffer buff,
if (!invocation->argv) if (!invocation->argv)
{ {
query_raise_enomem(error); query_raise_enomem(s, len, error);
goto clean; goto clean;
} }
memcpy(invocation->argv, args, memcpy(invocation->argv, args,
@ -789,7 +825,9 @@ clean:
return res; return res;
} }
static struct buffer query_parse_table(struct buffer buff, static struct buffer query_parse_table(
char *s, size_t len,
struct buffer buff,
struct invocation *invocation, const char **error) struct invocation *invocation, const char **error)
{ {
unsigned i; unsigned i;
@ -799,7 +837,7 @@ static struct buffer query_parse_table(struct buffer buff,
unsigned argi = 0; unsigned argi = 0;
buff = query_chomp(buff); buff = query_chomp(buff);
buff = query_expect_char(buff, '{', error); buff = query_expect_char(s, len, buff, '{', error);
if (*error) if (*error)
goto clean; goto clean;
@ -810,13 +848,14 @@ static struct buffer query_parse_table(struct buffer buff,
{ {
if (argi >= QUERY_MAX_ARGS) if (argi >= QUERY_MAX_ARGS)
{ {
query_raise_too_many_arguments(error); query_raise_too_many_arguments(s, len, error);
goto clean; goto clean;
} }
if (isalpha((int)buff.data[buff.offset])) if (isalpha((int)buff.data[buff.offset]))
{ {
buff = query_get_ident(buff, &ident_name, &ident_len, error); buff = query_get_ident(s, len,
buff, &ident_name, &ident_len, error);
if (!*error) if (!*error)
{ {
@ -838,7 +877,8 @@ static struct buffer query_parse_table(struct buffer buff,
} }
} }
else else
buff = query_parse_string(buff, &args[argi].a.value, error); buff = query_parse_string(s, len,
buff, &args[argi].a.value, error);
if (*error) if (*error)
goto clean; goto clean;
@ -846,7 +886,7 @@ static struct buffer query_parse_table(struct buffer buff,
args[argi].type = AT_VALUE; args[argi].type = AT_VALUE;
buff = query_chomp(buff); buff = query_chomp(buff);
argi++; argi++;
buff = query_expect_char(buff, ':', error); buff = query_expect_char(s, len, buff, ':', error);
if (*error) if (*error)
goto clean; goto clean;
@ -855,17 +895,17 @@ static struct buffer query_parse_table(struct buffer buff,
if (argi >= QUERY_MAX_ARGS) if (argi >= QUERY_MAX_ARGS)
{ {
query_raise_too_many_arguments(error); query_raise_too_many_arguments(s, len, error);
goto clean; goto clean;
} }
buff = query_parse_argument(buff, &args[argi], error); buff = query_parse_argument(s, len, buff, &args[argi], error);
if (*error) if (*error)
goto clean; goto clean;
argi++; argi++;
buff = query_chomp(buff); buff = query_chomp(buff);
buff = query_expect_char(buff, ',', error); buff = query_expect_char(s, len, buff, ',', error);
if (*error) if (*error)
{ {
@ -875,7 +915,7 @@ static struct buffer query_parse_table(struct buffer buff,
buff = query_chomp(buff); buff = query_chomp(buff);
} }
buff = query_expect_char(buff, '}', error); buff = query_expect_char(s, len, buff, '}', error);
if (*error) if (*error)
goto clean; goto clean;
@ -887,7 +927,7 @@ static struct buffer query_parse_table(struct buffer buff,
if (!invocation->argv) if (!invocation->argv)
{ {
query_raise_enomem(error); query_raise_enomem(s, len, error);
goto clean; goto clean;
} }
memcpy(invocation->argv, args, memcpy(invocation->argv, args,
@ -923,6 +963,8 @@ void *libretrodb_query_compile(libretrodb_t *db,
const char *query, size_t buff_len, const char **error_string) const char *query, size_t buff_len, const char **error_string)
{ {
struct buffer buff; struct buffer buff;
/* TODO/FIXME - static local variable */
static char tmp_error_buff [MAX_ERROR_LEN] = {0};
struct query *q = (struct query*)malloc(sizeof(*q)); struct query *q = (struct query*)malloc(sizeof(*q));
if (!q) if (!q)
@ -942,20 +984,26 @@ void *libretrodb_query_compile(libretrodb_t *db,
if (query_peek(buff, "{")) if (query_peek(buff, "{"))
{ {
buff = query_parse_table(buff, &q->root, error_string); buff = query_parse_table(tmp_error_buff,
sizeof(tmp_error_buff), buff, &q->root, error_string);
if (*error_string) if (*error_string)
goto error; goto error;
} }
else if (isalpha((int)buff.data[buff.offset])) else if (isalpha((int)buff.data[buff.offset]))
buff = query_parse_method_call(buff, &q->root, error_string); buff = query_parse_method_call(tmp_error_buff,
sizeof(tmp_error_buff),
buff, &q->root, error_string);
buff = query_expect_eof(buff, error_string); buff = query_expect_eof(tmp_error_buff,
sizeof(tmp_error_buff), buff, error_string);
if (*error_string) if (*error_string)
goto error; goto error;
if (!q->root.func) if (!q->root.func)
{ {
query_raise_unexpected_eof(buff.offset, error_string); query_raise_unexpected_eof(
tmp_error_buff, sizeof(tmp_error_buff),
buff.offset, error_string);
goto error; goto error;
} }