eolian: remove the ugly old type extractor, instead build the inlist during parsing

This commit is contained in:
Daniel Kolesa 2014-06-18 16:27:29 +01:00
parent 3c621045cd
commit 9d48e256dc
3 changed files with 86 additions and 166 deletions

View File

@ -2,11 +2,11 @@
#include <stdlib.h> #include <stdlib.h>
#include "eo_definitions.h" #include "eo_definitions.h"
#include "eolian_database.h"
static void static void
eo_definitions_ret_free(Eo_Ret_Def *ret) eo_definitions_ret_free(Eo_Ret_Def *ret)
{ {
if (ret->type) eina_stringshare_del(ret->type);
if (ret->comment) eina_stringshare_del(ret->comment); if (ret->comment) eina_stringshare_del(ret->comment);
if (ret->dflt_ret_val) eina_stringshare_del(ret->dflt_ret_val); if (ret->dflt_ret_val) eina_stringshare_del(ret->dflt_ret_val);
free(ret); free(ret);
@ -15,7 +15,6 @@ eo_definitions_ret_free(Eo_Ret_Def *ret)
static void static void
eo_definitions_param_free(Eo_Param_Def *param) eo_definitions_param_free(Eo_Param_Def *param)
{ {
if (param->type) eina_stringshare_del(param->type);
if (param->name) eina_stringshare_del(param->name); if (param->name) eina_stringshare_del(param->name);
if (param->comment) eina_stringshare_del(param->comment); if (param->comment) eina_stringshare_del(param->comment);
free(param); free(param);
@ -117,8 +116,6 @@ eo_definitions_type_def_free(Eo_Type_Def *type)
{ {
if (type->alias) if (type->alias)
eina_stringshare_del(type->alias); eina_stringshare_del(type->alias);
if (type->type)
eina_stringshare_del(type->type);
free(type); free(type);
} }
@ -212,4 +209,7 @@ eo_definitions_temps_free(Eo_Lexer_Temps *tmp)
if (tmp->impl) if (tmp->impl)
eo_definitions_impl_def_free(tmp->impl); eo_definitions_impl_def_free(tmp->impl);
if (tmp->type)
database_type_del(tmp->type);
} }

View File

@ -8,7 +8,7 @@
typedef struct _eo_ret_def typedef struct _eo_ret_def
{ {
const char *type; Eolian_Type type;
const char *comment; const char *comment;
const char *dflt_ret_val; const char *dflt_ret_val;
Eina_Bool warn_unused:1; Eina_Bool warn_unused:1;
@ -27,7 +27,7 @@ typedef enum _param_way
typedef struct _eo_param_def typedef struct _eo_param_def
{ {
Param_Way way; Param_Way way;
const char *type; Eolian_Type type;
const char *name; const char *name;
const char *comment; const char *comment;
Eina_Bool nonull:1; Eina_Bool nonull:1;
@ -127,7 +127,7 @@ typedef struct _eo_class_def
typedef struct _eo_type_def typedef struct _eo_type_def
{ {
const char *alias; const char *alias;
const char *type; Eolian_Type type;
} Eo_Type_Def; } Eo_Type_Def;
/* TEMPS */ /* TEMPS */
@ -148,6 +148,7 @@ typedef struct _Eo_Lexer_Temps
Eina_List *str_items; Eina_List *str_items;
Eo_Event_Def *event; Eo_Event_Def *event;
Eo_Implement_Def *impl; Eo_Implement_Def *impl;
Eolian_Type type;
} Eo_Lexer_Temps; } Eo_Lexer_Temps;
void eo_definitions_class_def_free(Eo_Class_Def *kls); void eo_definitions_class_def_free(Eo_Class_Def *kls);

View File

@ -128,21 +128,22 @@ parse_name_list(Eo_Lexer *ls)
return ls->tmp.str_items; return ls->tmp.str_items;
} }
static void static Eina_Inlist *
parse_type(Eo_Lexer *ls, Eina_Strbuf *buf) parse_type(Eo_Lexer *ls, Eina_Inlist *types, Eina_Strbuf *sbuf)
{ {
Eina_Bool has_struct = EINA_FALSE, need_space = EINA_FALSE; Eina_Bool has_struct = EINA_FALSE, need_space = EINA_FALSE;
Eina_Bool is_own = EINA_FALSE;
Eina_Strbuf *buf = sbuf ? sbuf : push_strbuf(ls);
if (ls->t.kw == KW_at_own) if (ls->t.kw == KW_at_own)
{ {
eina_strbuf_append(buf, "@own"); if (sbuf) eina_strbuf_append(buf, "@own ");
is_own = EINA_TRUE;
eo_lexer_get(ls); eo_lexer_get(ls);
need_space = EINA_TRUE;
} }
if (ls->t.kw == KW_const) if (ls->t.kw == KW_const)
{ {
if (need_space) eina_strbuf_append_char(buf, ' ');
eina_strbuf_append(buf, "const"); eina_strbuf_append(buf, "const");
eo_lexer_get(ls); eo_lexer_get(ls);
need_space = EINA_TRUE; need_space = EINA_TRUE;
@ -205,30 +206,37 @@ parse_type(Eo_Lexer *ls, Eina_Strbuf *buf)
} }
} }
if (!sbuf)
{
types = database_type_append(types, eina_strbuf_string_get(buf), is_own);
ls->tmp.type = types;
pop_strbuf(ls);
}
if (ls->t.token == '<') if (ls->t.token == '<')
{ {
int line = ls->line_number; int line = ls->line_number;
eina_strbuf_append(buf, " <"); if (sbuf) eina_strbuf_append(buf, " <");
eo_lexer_get(ls); eo_lexer_get(ls);
parse_type(ls, buf); types = parse_type(ls, types, sbuf);
check_match(ls, '>', '<', line); check_match(ls, '>', '<', line);
eina_strbuf_append_char(buf, '>'); if (sbuf) eina_strbuf_append_char(buf, '>');
} }
return types;
} }
static void static void
parse_typedef(Eo_Lexer *ls) parse_typedef(Eo_Lexer *ls)
{ {
Eina_Strbuf *buf = push_strbuf(ls);
ls->tmp.type_def = calloc(1, sizeof(Eo_Type_Def)); ls->tmp.type_def = calloc(1, sizeof(Eo_Type_Def));
eo_lexer_get(ls); eo_lexer_get(ls);
check(ls, TOK_VALUE); check(ls, TOK_VALUE);
ls->tmp.type_def->alias = eina_stringshare_add(ls->t.value); ls->tmp.type_def->alias = eina_stringshare_add(ls->t.value);
eo_lexer_get(ls); eo_lexer_get(ls);
test_next(ls, ':'); test_next(ls, ':');
parse_type(ls, buf); ls->tmp.type_def->type = parse_type(ls, NULL, NULL);
ls->tmp.type_def->type = eina_stringshare_add(eina_strbuf_string_get(buf)); ls->tmp.type = NULL;
pop_strbuf(ls);
check_next(ls, ';'); check_next(ls, ';');
} }
@ -236,12 +244,10 @@ static void
parse_return(Eo_Lexer *ls) parse_return(Eo_Lexer *ls)
{ {
Eo_Ret_Def *ret = calloc(1, sizeof(Eo_Ret_Def)); Eo_Ret_Def *ret = calloc(1, sizeof(Eo_Ret_Def));
Eina_Strbuf *buf = push_strbuf(ls);
ls->tmp.ret_def = ret; ls->tmp.ret_def = ret;
eo_lexer_get(ls); eo_lexer_get(ls);
parse_type(ls, buf); ret->type = parse_type(ls, NULL, NULL);
ret->type = eina_stringshare_add(eina_strbuf_string_get(buf)); ls->tmp.type = NULL;
pop_strbuf(ls);
if (ls->t.token == '(') if (ls->t.token == '(')
{ {
int line = ls->line_number; int line = ls->line_number;
@ -268,7 +274,6 @@ static void
parse_param(Eo_Lexer *ls, Eina_Bool allow_inout) parse_param(Eo_Lexer *ls, Eina_Bool allow_inout)
{ {
Eo_Param_Def *par = calloc(1, sizeof(Eo_Param_Def)); Eo_Param_Def *par = calloc(1, sizeof(Eo_Param_Def));
Eina_Strbuf *buf = NULL;
ls->tmp.param = par; ls->tmp.param = par;
if (allow_inout) if (allow_inout)
{ {
@ -290,10 +295,8 @@ parse_param(Eo_Lexer *ls, Eina_Bool allow_inout)
else else
par->way = PARAM_IN; par->way = PARAM_IN;
} }
buf = push_strbuf(ls); par->type = parse_type(ls, NULL, NULL);
parse_type(ls, buf); ls->tmp.type = NULL;
par->type = eina_stringshare_add(eina_strbuf_string_get(buf));
pop_strbuf(ls);
check(ls, TOK_VALUE); check(ls, TOK_VALUE);
par->name = eina_stringshare_add(ls->t.value); par->name = eina_stringshare_add(ls->t.value);
eo_lexer_get(ls); eo_lexer_get(ls);
@ -748,7 +751,7 @@ parse_event(Eo_Lexer *ls)
int line = ls->line_number; int line = ls->line_number;
eo_lexer_get(ls); eo_lexer_get(ls);
buf = push_strbuf(ls); buf = push_strbuf(ls);
parse_type(ls, buf); parse_type(ls, NULL, buf);
ev->type = eina_stringshare_add(eina_strbuf_string_get(buf)); ev->type = eina_stringshare_add(eina_strbuf_string_get(buf));
pop_strbuf(ls); pop_strbuf(ls);
check_match(ls, ')', '(', line); check_match(ls, ')', '(', line);
@ -1024,6 +1027,23 @@ parse_chunk(Eo_Lexer *ls)
static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" }; static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" };
static char * _param_way_str[ PARAM_WAY_LAST] = { "IN", "OUT", "INOUT" }; static char * _param_way_str[ PARAM_WAY_LAST] = { "IN", "OUT", "INOUT" };
static void
_print_type(FILE *f, Eolian_Type tp)
{
const char *type;
Eina_Bool own;
Eolian_Type ntp = eolian_type_information_get(tp, &type, &own);
if (own)
fputs("@own ", f);
fputs(type, f);
if (ntp)
{
fputc('<', f);
_print_type(f, ntp);
fputc('>', f);
}
}
void void
eo_parser_dump(Eo_Lexer *ls) eo_parser_dump(Eo_Lexer *ls)
{ {
@ -1059,13 +1079,17 @@ eo_parser_dump(Eo_Lexer *ls)
{ {
printf(" constructors: %s\n", meth->name); printf(" constructors: %s\n", meth->name);
if (meth->ret) if (meth->ret)
printf(" return: %s (%s)\n", meth->ret->type, meth->ret->comment); {
printf(" return: ");
_print_type(stdout, meth->ret->type);
printf(" (%s)\n", meth->ret->comment);
}
printf(" legacy : %s\n", meth->legacy); printf(" legacy : %s\n", meth->legacy);
EINA_LIST_FOREACH(meth->params, m, param) EINA_LIST_FOREACH(meth->params, m, param)
{ {
printf(" param: %s %s : %s (%s)\n", printf(" param: %s %s : ", _param_way_str[param->way], param->name);
_param_way_str[param->way], param->name, _print_type(stdout, param->type);
param->type, param->comment); printf(" (%s)\n", param->comment);
} }
} }
@ -1074,20 +1098,22 @@ eo_parser_dump(Eo_Lexer *ls)
printf(" property: %s\n", prop->name); printf(" property: %s\n", prop->name);
EINA_LIST_FOREACH(prop->keys, m, param) EINA_LIST_FOREACH(prop->keys, m, param)
{ {
printf(" key: %s : %s (%s)\n", printf(" key: %s : ", param->name);
param->name, param->type, param->comment); _print_type(stdout, param->type);
printf(" (%s)\n", param->comment);
} }
EINA_LIST_FOREACH(prop->values, m, param) EINA_LIST_FOREACH(prop->values, m, param)
{ {
printf(" value: %s : %s (%s)\n", printf(" value: %s : ", param->name);
param->name, param->type, param->comment); _print_type(stdout, param->type);
printf(" (%s)\n", param->comment);
} }
EINA_LIST_FOREACH(prop->accessors, m, accessor) EINA_LIST_FOREACH(prop->accessors, m, accessor)
{ {
printf(" accessor: %s : %s (%s)\n", printf(" accessor: ");
(accessor->ret?accessor->ret->type:""), if (accessor->ret)
_accessor_type_str[accessor->type], _print_type(stdout, accessor->ret->type);
accessor->comment); printf(" : %s (%s)\n", _accessor_type_str[accessor->type], accessor->comment);
printf(" legacy : %s\n", accessor->legacy); printf(" legacy : %s\n", accessor->legacy);
} }
} }
@ -1096,131 +1122,30 @@ eo_parser_dump(Eo_Lexer *ls)
{ {
printf(" method: %s\n", meth->name); printf(" method: %s\n", meth->name);
if (meth->ret) if (meth->ret)
printf(" return: %s (%s)\n", meth->ret->type, meth->ret->comment); {
printf(" return: ");
_print_type(stdout, meth->ret->type);
printf(" (%s)\n", meth->ret->comment);
}
printf(" legacy : %s\n", meth->legacy); printf(" legacy : %s\n", meth->legacy);
printf(" obj_const : %s\n", meth->obj_const?"true":"false"); printf(" obj_const : %s\n", meth->obj_const?"true":"false");
EINA_LIST_FOREACH(meth->params, m, param) EINA_LIST_FOREACH(meth->params, m, param)
{ {
printf(" param: %s %s : %s (%s)\n", printf(" param: %s %s : ", _param_way_str[param->way], param->name);
_param_way_str[param->way], param->name, _print_type(stdout, param->type);
param->type, param->comment); printf(" (%s)\n", param->comment);
} }
} }
} }
EINA_LIST_FOREACH(ls->typedefs, k, type) EINA_LIST_FOREACH(ls->typedefs, k, type)
{ {
printf("Typedef: %s (%s)\n", type->alias, type->type); printf("Typedef: %s ", type->alias);
_print_type(stdout, type->type);
printf("\n");
} }
} }
static Eina_Inlist *
_types_extract(const char *buf, int len)
{
const char *save_buf = buf;
Eolian_Type types = NULL;
long depth = 0;
char *tmp_type = malloc(2 * len + 1);
while (len > 0)
{
char *d = tmp_type;
Eina_Bool end_type = EINA_FALSE;
Eina_Bool is_own = EINA_FALSE;
char c;
Eina_Bool in_spaces = EINA_TRUE, in_stars = EINA_FALSE;
while (len > 0 && !end_type)
{
switch (c = *buf++)
{
/* @own */
case '@':
{
if (!strncmp(buf, "own ", 4))
{
is_own = EINA_TRUE;
buf += 4; len -= 4;
}
break;
}
/* if '*', we have to add a space. We set in_spaces to true in
* case spaces are between stars, to be sure we remove them.
*/
case '*':
{
if (!in_stars && !in_spaces)
{
*d++ = ' ';
in_stars = EINA_TRUE;
in_spaces = EINA_TRUE;
}
*d++ = c;
break;
}
/* Only the first space is inserted. */
case ' ':
{
if (!in_spaces) *d++ = c;
in_spaces = EINA_TRUE;
break;
}
case '<':
{
if (depth < 0)
{
ERR("%s: Cannot reopen < after >", save_buf);
goto error;
}
depth++;
end_type = EINA_TRUE;
break;
}
case '>':
{
if (depth == 0)
{
ERR("%s: Too much >", save_buf);
goto error;
}
if (depth > 0 && d == tmp_type)
{
ERR("%s: empty type inside <>", save_buf);
goto error;
}
if (depth > 0) depth *= -1;
depth++;
end_type = EINA_TRUE;
break;
}
default:
{
*d++ = c;
in_spaces = EINA_FALSE;
in_stars = EINA_FALSE;
}
}
len--;
}
if (d != tmp_type)
{
*d = '\0';
types = database_type_append(types, tmp_type, is_own);
}
}
if (depth)
{
ERR("%s: < and > are not well used.", save_buf);
goto error;
}
goto success;
error:
database_type_del(types);
types = NULL;
success:
free(tmp_type);
return types;
}
Eina_Bool Eina_Bool
eo_parser_walk(Eo_Lexer *ls) eo_parser_walk(Eo_Lexer *ls)
{ {
@ -1296,8 +1221,7 @@ eo_parser_database_fill(const char *filename)
database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy); database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
EINA_LIST_FOREACH(meth->params, m, param) EINA_LIST_FOREACH(meth->params, m, param)
{ {
Eolian_Type type = _types_extract(param->type, strlen(param->type)); database_method_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
database_method_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, type, param->name, param->comment);
} }
} }
@ -1307,16 +1231,14 @@ eo_parser_database_fill(const char *filename)
database_function_scope_set(foo_id, prop->scope); database_function_scope_set(foo_id, prop->scope);
EINA_LIST_FOREACH(prop->keys, m, param) EINA_LIST_FOREACH(prop->keys, m, param)
{ {
Eolian_Type type = _types_extract(param->type, strlen(param->type));
Eolian_Function_Parameter p = database_property_key_add( Eolian_Function_Parameter p = database_property_key_add(
foo_id, type, param->name, param->comment); foo_id, param->type, param->name, param->comment);
database_parameter_nonull_set(p, param->nonull); database_parameter_nonull_set(p, param->nonull);
} }
EINA_LIST_FOREACH(prop->values, m, param) EINA_LIST_FOREACH(prop->values, m, param)
{ {
Eolian_Type type = _types_extract(param->type, strlen(param->type));
Eolian_Function_Parameter p = database_property_value_add( Eolian_Function_Parameter p = database_property_value_add(
foo_id, type, param->name, param->comment); foo_id, param->type, param->name, param->comment);
database_parameter_nonull_set(p, param->nonull); database_parameter_nonull_set(p, param->nonull);
} }
EINA_LIST_FOREACH(prop->accessors, m, accessor) EINA_LIST_FOREACH(prop->accessors, m, accessor)
@ -1326,8 +1248,7 @@ eo_parser_database_fill(const char *filename)
{ {
Eolian_Function_Type ftype = Eolian_Function_Type ftype =
accessor->type == SETTER?EOLIAN_PROP_SET:EOLIAN_PROP_GET; accessor->type == SETTER?EOLIAN_PROP_SET:EOLIAN_PROP_GET;
Eolian_Type types = _types_extract(accessor->ret->type, strlen(accessor->ret->type)); database_function_return_type_set(foo_id, ftype, accessor->ret->type);
database_function_return_type_set(foo_id, ftype, types);
database_function_return_comment_set(foo_id, database_function_return_comment_set(foo_id,
ftype, accessor->ret->comment); ftype, accessor->ret->comment);
database_function_return_flag_set_as_warn_unused(foo_id, database_function_return_flag_set_as_warn_unused(foo_id,
@ -1371,8 +1292,7 @@ eo_parser_database_fill(const char *filename)
database_class_function_add(class, foo_id); database_class_function_add(class, foo_id);
if (meth->ret) if (meth->ret)
{ {
Eolian_Type types = _types_extract(meth->ret->type, strlen(meth->ret->type)); database_function_return_type_set(foo_id, EOLIAN_METHOD, meth->ret->type);
database_function_return_type_set(foo_id, EOLIAN_METHOD, types);
database_function_return_comment_set(foo_id, EOLIAN_METHOD, meth->ret->comment); database_function_return_comment_set(foo_id, EOLIAN_METHOD, meth->ret->comment);
database_function_return_flag_set_as_warn_unused(foo_id, database_function_return_flag_set_as_warn_unused(foo_id,
EOLIAN_METHOD, meth->ret->warn_unused); EOLIAN_METHOD, meth->ret->warn_unused);
@ -1384,9 +1304,8 @@ eo_parser_database_fill(const char *filename)
database_function_object_set_as_const(foo_id, meth->obj_const); database_function_object_set_as_const(foo_id, meth->obj_const);
EINA_LIST_FOREACH(meth->params, m, param) EINA_LIST_FOREACH(meth->params, m, param)
{ {
Eolian_Type type = _types_extract(param->type, strlen(param->type));
Eolian_Function_Parameter p = database_method_parameter_add(foo_id, Eolian_Function_Parameter p = database_method_parameter_add(foo_id,
(Eolian_Parameter_Dir)param->way, type, param->name, param->comment); (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
database_parameter_nonull_set(p, param->nonull); database_parameter_nonull_set(p, param->nonull);
} }
} }
@ -1444,7 +1363,7 @@ eo_parser_database_fill(const char *filename)
EINA_LIST_FOREACH(ls->typedefs, k, type_def) EINA_LIST_FOREACH(ls->typedefs, k, type_def)
{ {
database_type_add(type_def->alias, _types_extract(type_def->type, strlen(type_def->type))); database_type_add(type_def->alias, type_def->type);
} }
ret = EINA_TRUE; ret = EINA_TRUE;