2014-06-18 03:25:07 -07:00
|
|
|
#include "eo_parser.h"
|
|
|
|
#include "eolian_database.h"
|
|
|
|
|
|
|
|
#define FUNC_PUBLIC 0
|
|
|
|
#define FUNC_PROTECTED 1
|
|
|
|
|
|
|
|
#define eo_lexer_get_event_name(ls) eo_lexer_get_ident(ls, "@_.+-/\\='\"?!%,")
|
|
|
|
|
|
|
|
static void
|
|
|
|
error_expected(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char tbuf[256];
|
|
|
|
eo_lexer_token_to_str(token, tbuf);
|
|
|
|
snprintf(buf, sizeof(buf), "'%s' expected", tbuf);
|
|
|
|
eo_lexer_syntax_error(ls, buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
test_next(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
if (ls->t.token == token)
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
if (ls->t.token != token)
|
|
|
|
error_expected(ls, token);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_kw(Eo_Lexer *ls, int kw)
|
|
|
|
{
|
|
|
|
if (ls->t.kw != kw)
|
|
|
|
error_expected(ls, TOK_VALUE + kw);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_next(Eo_Lexer *ls, int token)
|
|
|
|
{
|
|
|
|
check(ls, token);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_kw_next(Eo_Lexer *ls, int kw)
|
|
|
|
{
|
|
|
|
check_kw(ls, kw);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_match(Eo_Lexer *ls, int what, int who, int where)
|
|
|
|
{
|
|
|
|
if (!test_next(ls, what))
|
|
|
|
{
|
|
|
|
if (where == ls->line_number)
|
|
|
|
error_expected(ls, what);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char tbuf[256];
|
|
|
|
char vbuf[256];
|
|
|
|
eo_lexer_token_to_str(what, tbuf);
|
|
|
|
eo_lexer_token_to_str(who , vbuf);
|
|
|
|
snprintf(buf, sizeof(buf),
|
|
|
|
"'%s' expected (to close '%s' at line %d)",
|
|
|
|
tbuf, vbuf, where);
|
|
|
|
eo_lexer_syntax_error(ls, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Strbuf *
|
|
|
|
push_strbuf(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = eina_strbuf_new();
|
|
|
|
ls->tmp.str_bufs = eina_list_prepend(ls->tmp.str_bufs, buf);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pop_strbuf(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = eina_list_data_get(ls->tmp.str_bufs);
|
|
|
|
eina_strbuf_free(buf);
|
|
|
|
ls->tmp.str_bufs = eina_list_remove_list(ls->tmp.str_bufs, ls->tmp.str_bufs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Strbuf *
|
|
|
|
parse_name(Eo_Lexer *ls, Eina_Strbuf *buf)
|
|
|
|
{
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
eina_strbuf_reset(buf);
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token != TOK_DBCOLON) break;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
eina_strbuf_append(buf, "::");
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
parse_name_list(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = push_strbuf(ls);
|
|
|
|
ls->tmp.str_items = NULL;
|
|
|
|
parse_name(ls, buf);
|
|
|
|
ls->tmp.str_items = eina_list_append(ls->tmp.str_items,
|
|
|
|
eina_stringshare_add(eina_strbuf_string_get(buf)));
|
|
|
|
while (test_next(ls, ','))
|
|
|
|
{
|
|
|
|
parse_name(ls, buf);
|
|
|
|
ls->tmp.str_items = eina_list_append(ls->tmp.str_items,
|
|
|
|
eina_stringshare_add(eina_strbuf_string_get(buf)));
|
|
|
|
}
|
|
|
|
pop_strbuf(ls);
|
|
|
|
return ls->tmp.str_items;
|
|
|
|
}
|
|
|
|
|
2014-06-18 08:27:29 -07:00
|
|
|
static Eina_Inlist *
|
|
|
|
parse_type(Eo_Lexer *ls, Eina_Inlist *types, Eina_Strbuf *sbuf)
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
Eina_Bool has_struct = EINA_FALSE, need_space = EINA_FALSE;
|
2014-06-18 08:27:29 -07:00
|
|
|
Eina_Bool is_own = EINA_FALSE;
|
|
|
|
Eina_Strbuf *buf = sbuf ? sbuf : push_strbuf(ls);
|
2014-06-18 03:25:07 -07:00
|
|
|
|
2014-06-19 03:22:35 -07:00
|
|
|
#define CHECK_KW(kwname, cond) \
|
|
|
|
if ((cond) && (ls->t.kw == KW_##kwname)) \
|
|
|
|
{ \
|
|
|
|
if (need_space) eina_strbuf_append_char(buf, ' '); \
|
|
|
|
eina_strbuf_append(buf, #kwname); \
|
|
|
|
eo_lexer_get(ls); \
|
|
|
|
need_space = EINA_TRUE; \
|
|
|
|
}
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.kw == KW_at_own)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
if (sbuf) eina_strbuf_append(buf, "@own ");
|
|
|
|
is_own = EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
|
2014-06-19 03:22:35 -07:00
|
|
|
CHECK_KW(const, EINA_TRUE)
|
2014-06-18 03:25:07 -07:00
|
|
|
|
2014-06-19 03:22:35 -07:00
|
|
|
CHECK_KW(unsigned, EINA_TRUE)
|
|
|
|
else CHECK_KW(signed, EINA_TRUE)
|
|
|
|
else CHECK_KW(struct, EINA_TRUE)
|
2014-06-18 03:25:07 -07:00
|
|
|
|
2014-06-19 03:22:35 -07:00
|
|
|
CHECK_KW(const, !has_struct)
|
2014-06-18 03:25:07 -07:00
|
|
|
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
if (need_space) eina_strbuf_append_char(buf, ' ');
|
|
|
|
eina_strbuf_append(buf, ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
need_space = EINA_TRUE;
|
|
|
|
|
2014-06-19 03:22:35 -07:00
|
|
|
CHECK_KW(const, EINA_TRUE)
|
2014-06-18 03:25:07 -07:00
|
|
|
|
|
|
|
if (ls->t.token == '*')
|
|
|
|
{
|
|
|
|
eina_strbuf_append_char(buf, ' ');
|
|
|
|
while (ls->t.token == '*')
|
|
|
|
{
|
|
|
|
eina_strbuf_append_char(buf, '*');
|
|
|
|
eo_lexer_get(ls);
|
2014-06-19 03:22:35 -07:00
|
|
|
CHECK_KW(const, EINA_TRUE)
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
2014-06-18 05:57:47 -07:00
|
|
|
}
|
|
|
|
|
2014-06-19 03:22:35 -07:00
|
|
|
#undef CHECK_KW
|
|
|
|
|
2014-06-18 08:27:29 -07:00
|
|
|
if (!sbuf)
|
|
|
|
{
|
|
|
|
types = database_type_append(types, eina_strbuf_string_get(buf), is_own);
|
|
|
|
ls->tmp.type = types;
|
|
|
|
pop_strbuf(ls);
|
|
|
|
}
|
|
|
|
|
2014-06-18 05:57:47 -07:00
|
|
|
if (ls->t.token == '<')
|
|
|
|
{
|
|
|
|
int line = ls->line_number;
|
2014-06-18 08:27:29 -07:00
|
|
|
if (sbuf) eina_strbuf_append(buf, " <");
|
2014-06-18 05:57:47 -07:00
|
|
|
eo_lexer_get(ls);
|
2014-06-18 08:27:29 -07:00
|
|
|
types = parse_type(ls, types, sbuf);
|
2014-06-18 05:57:47 -07:00
|
|
|
check_match(ls, '>', '<', line);
|
2014-06-18 08:27:29 -07:00
|
|
|
if (sbuf) eina_strbuf_append_char(buf, '>');
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
2014-06-18 08:27:29 -07:00
|
|
|
|
|
|
|
return types;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_typedef(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
ls->tmp.type_def = calloc(1, sizeof(Eo_Type_Def));
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
ls->tmp.type_def->alias = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
test_next(ls, ':');
|
2014-06-18 08:27:29 -07:00
|
|
|
ls->tmp.type_def->type = parse_type(ls, NULL, NULL);
|
|
|
|
ls->tmp.type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
check_next(ls, ';');
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_return(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eo_Ret_Def *ret = calloc(1, sizeof(Eo_Ret_Def));
|
|
|
|
ls->tmp.ret_def = ret;
|
|
|
|
eo_lexer_get(ls);
|
2014-06-18 08:27:29 -07:00
|
|
|
ret->type = parse_type(ls, NULL, NULL);
|
|
|
|
ls->tmp.type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
if (ls->t.token == '(')
|
|
|
|
{
|
|
|
|
int line = ls->line_number;
|
2014-06-19 07:05:24 -07:00
|
|
|
eo_lexer_get_balanced(ls, '(', ')');
|
2014-06-18 03:25:07 -07:00
|
|
|
ret->dflt_ret_val = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_match(ls, ')', '(', line);
|
|
|
|
}
|
|
|
|
if (ls->t.kw == KW_at_warn_unused)
|
|
|
|
{
|
|
|
|
ret->warn_unused = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
ret->comment = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_param(Eo_Lexer *ls, Eina_Bool allow_inout)
|
|
|
|
{
|
|
|
|
Eo_Param_Def *par = calloc(1, sizeof(Eo_Param_Def));
|
|
|
|
ls->tmp.param = par;
|
|
|
|
if (allow_inout)
|
|
|
|
{
|
|
|
|
if (ls->t.kw == KW_at_in)
|
|
|
|
{
|
|
|
|
par->way = PARAM_IN;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_at_out)
|
|
|
|
{
|
|
|
|
par->way = PARAM_OUT;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_at_inout)
|
|
|
|
{
|
|
|
|
par->way = PARAM_INOUT;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
par->way = PARAM_IN;
|
|
|
|
}
|
2014-06-18 08:27:29 -07:00
|
|
|
par->type = parse_type(ls, NULL, NULL);
|
|
|
|
ls->tmp.type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
par->name = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.kw == KW_at_nonull)
|
|
|
|
{
|
|
|
|
par->nonull = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
par->comment = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_legacy(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
ls->tmp.legacy_def = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_attrs(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = NULL;
|
|
|
|
Eo_Accessor_Param *acc = NULL;
|
|
|
|
Eina_Bool has_const = EINA_FALSE, has_own = EINA_FALSE,
|
|
|
|
has_nonull = EINA_FALSE, first = EINA_TRUE;
|
|
|
|
acc = calloc(1, sizeof(Eo_Accessor_Param));
|
|
|
|
ls->tmp.accessor_param = acc;
|
|
|
|
acc->name = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
buf = push_strbuf(ls);
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_const:
|
|
|
|
if (has_const)
|
|
|
|
eo_lexer_syntax_error(ls, "double const qualifier");
|
|
|
|
has_const = EINA_TRUE;
|
|
|
|
if (!first) eina_strbuf_append_char(buf, ' ');
|
|
|
|
eina_strbuf_append(buf, "const");
|
|
|
|
first = EINA_FALSE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
case KW_at_own:
|
|
|
|
if (has_own)
|
|
|
|
eo_lexer_syntax_error(ls, "double @own qualifier");
|
|
|
|
has_own = EINA_TRUE;
|
|
|
|
if (!first) eina_strbuf_append_char(buf, ' ');
|
|
|
|
eina_strbuf_append(buf, "@own");
|
|
|
|
first = EINA_FALSE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
case KW_at_nonull:
|
|
|
|
if (has_nonull)
|
|
|
|
eo_lexer_syntax_error(ls, "double @nonull qualifier");
|
|
|
|
has_nonull = EINA_TRUE;
|
|
|
|
if (!first) eina_strbuf_append_char(buf, ' ');
|
|
|
|
eina_strbuf_append(buf, "@nonull");
|
|
|
|
first = EINA_FALSE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (first) eo_lexer_syntax_error(ls, "attribute expected");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
acc->attrs = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_accessor(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
Eo_Accessor_Def *acc = NULL;
|
|
|
|
Eina_Bool has_return = EINA_FALSE, has_legacy = EINA_FALSE;
|
|
|
|
acc = calloc(1, sizeof(Eo_Accessor_Def));
|
|
|
|
ls->tmp.accessor = acc;
|
|
|
|
acc->type = (ls->t.kw == KW_get) ? GETTER : SETTER;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
acc->comment = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_return:
|
|
|
|
if (has_return)
|
|
|
|
eo_lexer_syntax_error(ls, "double return");
|
|
|
|
has_return = EINA_TRUE;
|
|
|
|
parse_return(ls);
|
|
|
|
acc->ret = ls->tmp.ret_def;
|
|
|
|
ls->tmp.ret_def = NULL;
|
|
|
|
break;
|
|
|
|
case KW_legacy:
|
|
|
|
if (has_legacy)
|
|
|
|
eo_lexer_syntax_error(ls, "double legacy name");
|
|
|
|
has_legacy = EINA_TRUE;
|
|
|
|
parse_legacy(ls);
|
|
|
|
acc->legacy = ls->tmp.legacy_def;
|
|
|
|
ls->tmp.legacy_def = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
parse_attrs(ls);
|
|
|
|
acc->params = eina_list_append(acc->params,
|
|
|
|
ls->tmp.accessor_param);
|
|
|
|
ls->tmp.accessor_param = NULL;
|
|
|
|
/* this code path is disabled for the time being,
|
|
|
|
* it's not used in regular eolian yet either...
|
|
|
|
eo_lexer_lookahead(ls);
|
|
|
|
if (ls->lookahead.token == ':')
|
|
|
|
parse_attrs(ls);
|
|
|
|
else
|
|
|
|
parse_param(ls, EINA_TRUE);*/
|
|
|
|
}
|
|
|
|
else
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_keys(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_param(ls, EINA_FALSE);
|
|
|
|
ls->tmp.params = eina_list_append(ls->tmp.params, ls->tmp.param);
|
|
|
|
ls->tmp.param = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_values(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_param(ls, EINA_FALSE);
|
|
|
|
ls->tmp.params = eina_list_append(ls->tmp.params, ls->tmp.param);
|
|
|
|
ls->tmp.param = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_property(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
Eo_Property_Def *prop = NULL;
|
|
|
|
Eina_Bool has_get = EINA_FALSE, has_set = EINA_FALSE,
|
|
|
|
has_keys = EINA_FALSE, has_values = EINA_FALSE;
|
|
|
|
prop = calloc(1, sizeof(Eo_Property_Def));
|
|
|
|
ls->tmp.prop = prop;
|
|
|
|
if (ls->t.kw == KW_protected)
|
|
|
|
{
|
|
|
|
prop->scope = FUNC_PROTECTED;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
prop->name = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_get:
|
|
|
|
if (has_get)
|
|
|
|
eo_lexer_syntax_error(ls, "double get definition");
|
|
|
|
has_get = EINA_TRUE;
|
|
|
|
parse_accessor(ls);
|
|
|
|
prop->accessors = eina_list_append(prop->accessors,
|
|
|
|
ls->tmp.accessor);
|
|
|
|
ls->tmp.accessor = NULL;
|
|
|
|
break;
|
|
|
|
case KW_set:
|
|
|
|
if (has_set)
|
|
|
|
eo_lexer_syntax_error(ls, "double set definition");
|
|
|
|
has_set = EINA_TRUE;
|
|
|
|
parse_accessor(ls);
|
|
|
|
prop->accessors = eina_list_append(prop->accessors,
|
|
|
|
ls->tmp.accessor);
|
|
|
|
ls->tmp.accessor = NULL;
|
|
|
|
break;
|
|
|
|
case KW_keys:
|
|
|
|
if (has_keys)
|
|
|
|
eo_lexer_syntax_error(ls, "double keys definition");
|
|
|
|
has_keys = EINA_TRUE;
|
|
|
|
parse_keys(ls);
|
|
|
|
prop->keys = ls->tmp.params;
|
|
|
|
ls->tmp.params = NULL;
|
|
|
|
break;
|
|
|
|
case KW_values:
|
|
|
|
if (has_values)
|
|
|
|
eo_lexer_syntax_error(ls, "double values definition");
|
|
|
|
has_values = EINA_TRUE;
|
|
|
|
parse_values(ls);
|
|
|
|
prop->values = ls->tmp.params;
|
|
|
|
ls->tmp.params = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_params(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_param(ls, EINA_TRUE);
|
|
|
|
ls->tmp.params = eina_list_append(ls->tmp.params, ls->tmp.param);
|
|
|
|
ls->tmp.param = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_method(Eo_Lexer *ls, Eina_Bool ctor)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
Eo_Method_Def *meth = NULL;
|
|
|
|
Eina_Bool has_const = EINA_FALSE, has_params = EINA_FALSE,
|
|
|
|
has_return = EINA_FALSE, has_legacy = EINA_FALSE;
|
|
|
|
meth = calloc(1, sizeof(Eo_Method_Def));
|
|
|
|
ls->tmp.meth = meth;
|
|
|
|
if (ctor)
|
|
|
|
{
|
|
|
|
if (ls->t.token != TOK_VALUE)
|
|
|
|
eo_lexer_syntax_error(ls, "expected method name");
|
|
|
|
meth->type = METH_CONSTRUCTOR;
|
|
|
|
meth->name = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meth->type = METH_REGULAR;
|
|
|
|
if (ls->t.kw == KW_protected)
|
|
|
|
{
|
|
|
|
meth->scope = FUNC_PROTECTED;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
meth->name = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
meth->comment = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_const:
|
|
|
|
if (has_const)
|
|
|
|
eo_lexer_syntax_error(ls, "double const qualifier");
|
|
|
|
has_const = EINA_TRUE;
|
|
|
|
meth->obj_const = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_return:
|
|
|
|
if (has_return)
|
|
|
|
eo_lexer_syntax_error(ls, "double return");
|
|
|
|
has_return = EINA_TRUE;
|
|
|
|
parse_return(ls);
|
|
|
|
meth->ret = ls->tmp.ret_def;
|
|
|
|
ls->tmp.ret_def = NULL;
|
|
|
|
break;
|
|
|
|
case KW_legacy:
|
|
|
|
if (has_legacy)
|
|
|
|
eo_lexer_syntax_error(ls, "double legacy name");
|
|
|
|
has_legacy = EINA_TRUE;
|
|
|
|
parse_legacy(ls);
|
|
|
|
meth->legacy = ls->tmp.legacy_def;
|
|
|
|
ls->tmp.legacy_def = NULL;
|
|
|
|
break;
|
|
|
|
case KW_params:
|
|
|
|
if (has_params)
|
|
|
|
eo_lexer_syntax_error(ls, "double params definition");
|
|
|
|
has_params = EINA_TRUE;
|
|
|
|
parse_params(ls);
|
|
|
|
meth->params = ls->tmp.params;
|
|
|
|
ls->tmp.params = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_implement(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eina_Strbuf *buf = NULL;
|
|
|
|
Eo_Implement_Def *impl = NULL;
|
|
|
|
buf = push_strbuf(ls);
|
|
|
|
impl = calloc(1, sizeof(Eo_Implement_Def));
|
|
|
|
ls->tmp.impl = impl;
|
|
|
|
if (ls->t.kw == KW_class)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, "class::");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, TOK_DBCOLON);
|
|
|
|
if (ls->t.kw == KW_destructor)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, "destructor");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
check_kw_next(ls, KW_constructor);
|
|
|
|
eina_strbuf_append(buf, "constructor");
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
impl->meth_name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (ls->t.kw == KW_virtual)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, "virtual::");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, TOK_DBCOLON);
|
|
|
|
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
|
|
|
|
eo_lexer_syntax_error(ls, "name expected");
|
|
|
|
eina_strbuf_append(buf, ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token == TOK_DBCOLON)
|
|
|
|
{
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.kw == KW_set)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, "::set");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
check_kw_next(ls, KW_get);
|
|
|
|
eina_strbuf_append(buf, "::get");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
check_next(ls, ';');
|
|
|
|
impl->meth_name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
|
|
|
|
eo_lexer_syntax_error(ls, "class name expected");
|
|
|
|
eina_strbuf_append(buf, ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, TOK_DBCOLON);
|
|
|
|
eina_strbuf_append(buf, "::");
|
|
|
|
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
|
|
|
|
eo_lexer_syntax_error(ls, "name or constructor/destructor expected");
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_constructor:
|
|
|
|
eina_strbuf_append(buf, "constructor");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
|
|
|
case KW_destructor:
|
|
|
|
eina_strbuf_append(buf, "destructor");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
|
|
|
case KW_get:
|
|
|
|
eina_strbuf_append(buf, "get");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
|
|
|
case KW_set:
|
|
|
|
eina_strbuf_append(buf, "set");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
goto end;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
eina_strbuf_append(buf, ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token != TOK_DBCOLON) break;
|
|
|
|
eina_strbuf_append(buf, "::");
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
check_next(ls, ';');
|
|
|
|
impl->meth_name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_event(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
Eo_Event_Def *ev = calloc(1, sizeof(Eo_Event_Def));
|
|
|
|
ls->tmp.event = ev;
|
|
|
|
/* code path not in use yet
|
|
|
|
if (ls->t.kw == KW_private)
|
|
|
|
{
|
|
|
|
eo_lexer_get_event_name(ls);
|
|
|
|
}*/
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
ev->name = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
if (ls->t.token == '(')
|
|
|
|
{
|
|
|
|
int line = ls->line_number;
|
2014-06-19 07:05:24 -07:00
|
|
|
eo_lexer_get_balanced(ls, '(', ')');
|
|
|
|
ev->type = eina_stringshare_add(ls->t.value);
|
2014-06-18 03:25:07 -07:00
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_match(ls, ')', '(', line);
|
|
|
|
}
|
|
|
|
check(ls, ';');
|
|
|
|
eo_lexer_get_event_name(ls);
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
ev->comment = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get_event_name(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_constructors(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_method(ls, EINA_TRUE);
|
|
|
|
ls->tmp.kls->constructors = eina_list_append(ls->tmp.kls->constructors,
|
|
|
|
ls->tmp.meth);
|
|
|
|
ls->tmp.meth = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_methods(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_method(ls, EINA_FALSE);
|
|
|
|
ls->tmp.kls->methods = eina_list_append(ls->tmp.kls->methods,
|
|
|
|
ls->tmp.meth);
|
|
|
|
ls->tmp.meth = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_properties(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_property(ls);
|
|
|
|
ls->tmp.kls->properties = eina_list_append(ls->tmp.kls->properties,
|
|
|
|
ls->tmp.prop);
|
|
|
|
ls->tmp.prop = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_implements(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_implement(ls);
|
|
|
|
ls->tmp.kls->implements = eina_list_append(ls->tmp.kls->implements,
|
|
|
|
ls->tmp.impl);
|
|
|
|
ls->tmp.impl = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_events(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check(ls, '{');
|
|
|
|
eo_lexer_get_event_name(ls);
|
|
|
|
while (ls->t.token != '}')
|
|
|
|
{
|
|
|
|
parse_event(ls);
|
|
|
|
ls->tmp.kls->events = eina_list_append(ls->tmp.kls->events,
|
|
|
|
ls->tmp.event);
|
|
|
|
ls->tmp.event = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_class_body(Eo_Lexer *ls, Eina_Bool allow_ctors)
|
|
|
|
{
|
|
|
|
Eina_Bool has_legacy_prefix = EINA_FALSE,
|
|
|
|
has_eo_prefix = EINA_FALSE,
|
|
|
|
has_data = EINA_FALSE,
|
|
|
|
has_constructors = EINA_FALSE,
|
|
|
|
has_properties = EINA_FALSE,
|
|
|
|
has_methods = EINA_FALSE,
|
|
|
|
has_implements = EINA_FALSE,
|
|
|
|
has_events = EINA_FALSE;
|
|
|
|
if (ls->t.token == TOK_COMMENT)
|
|
|
|
{
|
|
|
|
ls->tmp.kls->comment = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
}
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_legacy_prefix:
|
|
|
|
if (has_legacy_prefix)
|
|
|
|
eo_lexer_syntax_error(ls, "double legacy prefix definition");
|
|
|
|
has_legacy_prefix = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
ls->tmp.kls->legacy_prefix = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_eo_prefix:
|
|
|
|
if (has_eo_prefix)
|
|
|
|
eo_lexer_syntax_error(ls, "double eo prefix definition");
|
|
|
|
has_eo_prefix = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ':');
|
|
|
|
check(ls, TOK_VALUE);
|
|
|
|
ls->tmp.kls->eo_prefix = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_data:
|
|
|
|
if (has_data)
|
|
|
|
eo_lexer_syntax_error(ls, "double data definition");
|
|
|
|
has_data = EINA_TRUE;
|
|
|
|
eo_lexer_get(ls);
|
2014-06-19 07:05:24 -07:00
|
|
|
check(ls, ':');
|
|
|
|
eo_lexer_get_until(ls, ';');
|
2014-06-18 03:25:07 -07:00
|
|
|
ls->tmp.kls->data_type = eina_stringshare_add(ls->t.value);
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
check_next(ls, ';');
|
|
|
|
break;
|
|
|
|
case KW_constructors:
|
|
|
|
if (!allow_ctors)
|
|
|
|
return;
|
|
|
|
if (has_constructors)
|
|
|
|
eo_lexer_syntax_error(ls, "double constructors definition");
|
|
|
|
has_constructors = EINA_TRUE;
|
|
|
|
parse_constructors(ls);
|
|
|
|
break;
|
|
|
|
case KW_properties:
|
|
|
|
if (has_properties)
|
|
|
|
eo_lexer_syntax_error(ls, "double properties definition");
|
|
|
|
has_properties = EINA_TRUE;
|
|
|
|
parse_properties(ls);
|
|
|
|
break;
|
|
|
|
case KW_methods:
|
|
|
|
if (has_methods)
|
|
|
|
eo_lexer_syntax_error(ls, "double methods definition");
|
|
|
|
has_methods = EINA_TRUE;
|
|
|
|
parse_methods(ls);
|
|
|
|
break;
|
|
|
|
case KW_implements:
|
|
|
|
if (has_implements)
|
|
|
|
eo_lexer_syntax_error(ls, "double implements definition");
|
|
|
|
has_implements = EINA_TRUE;
|
|
|
|
parse_implements(ls);
|
|
|
|
break;
|
|
|
|
case KW_events:
|
|
|
|
if (has_events)
|
|
|
|
eo_lexer_syntax_error(ls, "double events definition");
|
|
|
|
has_events = EINA_TRUE;
|
|
|
|
parse_events(ls);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_class(Eo_Lexer *ls, Eina_Bool allow_ctors, Eolian_Class_Type type)
|
|
|
|
{
|
|
|
|
int line;
|
|
|
|
Eina_Strbuf *buf = push_strbuf(ls);
|
|
|
|
ls->tmp.kls = calloc(1, sizeof(Eo_Class_Def));
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
ls->tmp.kls->type = type;
|
|
|
|
parse_name(ls, buf);
|
|
|
|
ls->tmp.kls->name = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
pop_strbuf(ls);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '(');
|
|
|
|
if (ls->t.token != ')')
|
|
|
|
{
|
|
|
|
ls->tmp.kls->inherits = parse_name_list(ls);
|
|
|
|
ls->tmp.str_items = NULL;
|
|
|
|
}
|
|
|
|
check_match(ls, ')', '(', line);
|
|
|
|
line = ls->line_number;
|
|
|
|
check_next(ls, '{');
|
|
|
|
parse_class_body(ls, allow_ctors);
|
|
|
|
check_match(ls, '}', '{', line);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_unit(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
switch (ls->t.kw)
|
|
|
|
{
|
|
|
|
case KW_abstract:
|
|
|
|
{
|
|
|
|
parse_class(ls, EINA_TRUE, EOLIAN_CLASS_ABSTRACT);
|
|
|
|
ls->classes = eina_list_append(ls->classes, ls->tmp.kls);
|
|
|
|
ls->tmp.kls = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KW_class:
|
|
|
|
{
|
|
|
|
parse_class(ls, EINA_TRUE, EOLIAN_CLASS_REGULAR);
|
|
|
|
ls->classes = eina_list_append(ls->classes, ls->tmp.kls);
|
|
|
|
ls->tmp.kls = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KW_mixin:
|
|
|
|
{
|
|
|
|
parse_class(ls, EINA_FALSE, EOLIAN_CLASS_MIXIN);
|
|
|
|
ls->classes = eina_list_append(ls->classes, ls->tmp.kls);
|
|
|
|
ls->tmp.kls = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KW_interface:
|
|
|
|
{
|
|
|
|
parse_class(ls, EINA_FALSE, EOLIAN_CLASS_INTERFACE);
|
|
|
|
ls->classes = eina_list_append(ls->classes, ls->tmp.kls);
|
|
|
|
ls->tmp.kls = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KW_type:
|
|
|
|
{
|
|
|
|
parse_typedef(ls);
|
|
|
|
ls->typedefs = eina_list_append(ls->typedefs, ls->tmp.type_def);
|
|
|
|
ls->tmp.type_def = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
eo_lexer_syntax_error(ls, "invalid token");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
parse_chunk(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
while (ls->t.token != TOK_EOF)
|
|
|
|
{
|
|
|
|
parse_unit(ls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" };
|
|
|
|
static char * _param_way_str[ PARAM_WAY_LAST] = { "IN", "OUT", "INOUT" };
|
|
|
|
|
2014-06-18 08:27:29 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-18 03:25:07 -07:00
|
|
|
void
|
|
|
|
eo_parser_dump(Eo_Lexer *ls)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
Eina_List *k, *l, *m;
|
|
|
|
|
|
|
|
Eo_Type_Def *type;
|
|
|
|
Eo_Class_Def *kls;
|
|
|
|
Eo_Property_Def *prop;
|
|
|
|
Eo_Method_Def *meth;
|
|
|
|
Eo_Param_Def *param;
|
|
|
|
Eo_Accessor_Def *accessor;
|
|
|
|
Eo_Event_Def *sgn;
|
|
|
|
Eo_Implement_Def *impl;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ls->classes, k, kls)
|
|
|
|
{
|
|
|
|
printf("Class: %s (%s)\n",
|
|
|
|
kls->name, (kls->comment ? kls->comment : "-"));
|
|
|
|
printf(" inherits from :");
|
|
|
|
EINA_LIST_FOREACH(kls->inherits, l, s)
|
|
|
|
printf(" %s", s);
|
|
|
|
printf("\n");
|
|
|
|
printf(" implements:");
|
|
|
|
EINA_LIST_FOREACH(kls->implements, l, impl)
|
|
|
|
printf(" %s", impl->meth_name);
|
|
|
|
printf("\n");
|
|
|
|
printf(" events:\n");
|
|
|
|
EINA_LIST_FOREACH(kls->events, l, sgn)
|
|
|
|
printf(" %s <%s> (%s)\n", sgn->name, sgn->type, sgn->comment);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->constructors, l, meth)
|
|
|
|
{
|
|
|
|
printf(" constructors: %s\n", meth->name);
|
|
|
|
if (meth->ret)
|
2014-06-18 08:27:29 -07:00
|
|
|
{
|
|
|
|
printf(" return: ");
|
|
|
|
_print_type(stdout, meth->ret->type);
|
|
|
|
printf(" (%s)\n", meth->ret->comment);
|
|
|
|
}
|
2014-06-18 03:25:07 -07:00
|
|
|
printf(" legacy : %s\n", meth->legacy);
|
|
|
|
EINA_LIST_FOREACH(meth->params, m, param)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
printf(" param: %s %s : ", _param_way_str[param->way], param->name);
|
|
|
|
_print_type(stdout, param->type);
|
|
|
|
printf(" (%s)\n", param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->properties, l, prop)
|
|
|
|
{
|
|
|
|
printf(" property: %s\n", prop->name);
|
|
|
|
EINA_LIST_FOREACH(prop->keys, m, param)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
printf(" key: %s : ", param->name);
|
|
|
|
_print_type(stdout, param->type);
|
|
|
|
printf(" (%s)\n", param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(prop->values, m, param)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
printf(" value: %s : ", param->name);
|
|
|
|
_print_type(stdout, param->type);
|
|
|
|
printf(" (%s)\n", param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(prop->accessors, m, accessor)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
printf(" accessor: ");
|
|
|
|
if (accessor->ret)
|
|
|
|
_print_type(stdout, accessor->ret->type);
|
|
|
|
printf(" : %s (%s)\n", _accessor_type_str[accessor->type], accessor->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
printf(" legacy : %s\n", accessor->legacy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->methods, l, meth)
|
|
|
|
{
|
|
|
|
printf(" method: %s\n", meth->name);
|
|
|
|
if (meth->ret)
|
2014-06-18 08:27:29 -07:00
|
|
|
{
|
|
|
|
printf(" return: ");
|
|
|
|
_print_type(stdout, meth->ret->type);
|
|
|
|
printf(" (%s)\n", meth->ret->comment);
|
|
|
|
}
|
2014-06-18 03:25:07 -07:00
|
|
|
printf(" legacy : %s\n", meth->legacy);
|
|
|
|
printf(" obj_const : %s\n", meth->obj_const?"true":"false");
|
|
|
|
EINA_LIST_FOREACH(meth->params, m, param)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
printf(" param: %s %s : ", _param_way_str[param->way], param->name);
|
|
|
|
_print_type(stdout, param->type);
|
|
|
|
printf(" (%s)\n", param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ls->typedefs, k, type)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
printf("Typedef: %s ", type->alias);
|
|
|
|
_print_type(stdout, type->type);
|
|
|
|
printf("\n");
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
eo_parser_walk(Eo_Lexer *ls)
|
|
|
|
{
|
2014-06-19 04:02:46 -07:00
|
|
|
if (!setjmp(ls->err_jmp))
|
2014-06-18 03:25:07 -07:00
|
|
|
{
|
|
|
|
parse_chunk(ls);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
eo_parser_database_fill(const char *filename)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
Eina_List *k, *l, *m;
|
|
|
|
|
|
|
|
Eo_Class_Def *kls;
|
|
|
|
Eo_Type_Def *type_def;
|
|
|
|
Eo_Property_Def *prop;
|
|
|
|
Eo_Method_Def *meth;
|
|
|
|
Eo_Param_Def *param;
|
|
|
|
Eo_Accessor_Def *accessor;
|
|
|
|
Eo_Event_Def *event;
|
|
|
|
Eo_Implement_Def *impl;
|
|
|
|
|
|
|
|
Eo_Lexer *ls = eo_lexer_new(filename);
|
|
|
|
if (!ls)
|
|
|
|
{
|
|
|
|
ERR("unable to create lexer");
|
2014-06-18 08:36:29 -07:00
|
|
|
return EINA_FALSE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* read first token */
|
|
|
|
eo_lexer_get(ls);
|
|
|
|
|
2014-06-18 08:36:29 -07:00
|
|
|
if (!eo_parser_walk(ls))
|
|
|
|
{
|
|
|
|
eo_lexer_free(ls);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2014-06-18 03:25:07 -07:00
|
|
|
|
|
|
|
if (!ls->classes)
|
|
|
|
{
|
|
|
|
ERR("No classes for file %s", filename);
|
2014-06-18 08:36:29 -07:00
|
|
|
eo_lexer_free(ls);
|
|
|
|
return EINA_FALSE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ls->classes, k, kls)
|
|
|
|
{
|
|
|
|
Eolian_Class class = database_class_add(kls->name, kls->type);
|
|
|
|
database_class_file_set(class, filename);
|
|
|
|
|
|
|
|
if (kls->comment) database_class_description_set(class, kls->comment);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->inherits, l, s)
|
|
|
|
database_class_inherit_add(class, s);
|
|
|
|
|
|
|
|
if (kls->legacy_prefix)
|
|
|
|
{
|
|
|
|
database_class_legacy_prefix_set(class, kls->legacy_prefix);
|
|
|
|
}
|
|
|
|
if (kls->eo_prefix)
|
|
|
|
{
|
|
|
|
database_class_eo_prefix_set(class, kls->eo_prefix);
|
|
|
|
}
|
|
|
|
if (kls->data_type)
|
|
|
|
{
|
|
|
|
database_class_data_type_set(class, kls->data_type);
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(kls->constructors, l, meth)
|
|
|
|
{
|
|
|
|
Eolian_Function foo_id = database_function_new(meth->name, EOLIAN_CTOR);
|
|
|
|
database_class_function_add(class, foo_id);
|
|
|
|
if (meth->ret) database_function_return_comment_set(foo_id, EOLIAN_METHOD, meth->ret->comment);
|
|
|
|
database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
|
|
|
|
EINA_LIST_FOREACH(meth->params, m, param)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
database_method_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
|
2014-06-19 04:02:46 -07:00
|
|
|
param->type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->properties, l, prop)
|
|
|
|
{
|
|
|
|
Eolian_Function foo_id = database_function_new(prop->name, EOLIAN_UNRESOLVED);
|
|
|
|
database_function_scope_set(foo_id, prop->scope);
|
|
|
|
EINA_LIST_FOREACH(prop->keys, m, param)
|
|
|
|
{
|
|
|
|
Eolian_Function_Parameter p = database_property_key_add(
|
2014-06-18 08:27:29 -07:00
|
|
|
foo_id, param->type, param->name, param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
database_parameter_nonull_set(p, param->nonull);
|
2014-06-19 04:02:46 -07:00
|
|
|
param->type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(prop->values, m, param)
|
|
|
|
{
|
|
|
|
Eolian_Function_Parameter p = database_property_value_add(
|
2014-06-18 08:27:29 -07:00
|
|
|
foo_id, param->type, param->name, param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
database_parameter_nonull_set(p, param->nonull);
|
2014-06-19 04:02:46 -07:00
|
|
|
param->type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(prop->accessors, m, accessor)
|
|
|
|
{
|
|
|
|
database_function_type_set(foo_id, (accessor->type == SETTER?EOLIAN_PROP_SET:EOLIAN_PROP_GET));
|
|
|
|
if (accessor->ret && accessor->ret->type)
|
|
|
|
{
|
|
|
|
Eolian_Function_Type ftype =
|
|
|
|
accessor->type == SETTER?EOLIAN_PROP_SET:EOLIAN_PROP_GET;
|
2014-06-18 08:27:29 -07:00
|
|
|
database_function_return_type_set(foo_id, ftype, accessor->ret->type);
|
2014-06-18 03:25:07 -07:00
|
|
|
database_function_return_comment_set(foo_id,
|
|
|
|
ftype, accessor->ret->comment);
|
|
|
|
database_function_return_flag_set_as_warn_unused(foo_id,
|
|
|
|
ftype, accessor->ret->warn_unused);
|
|
|
|
database_function_return_dflt_val_set(foo_id,
|
|
|
|
ftype, accessor->ret->dflt_ret_val);
|
2014-06-19 04:02:46 -07:00
|
|
|
accessor->ret->type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
if (accessor->legacy)
|
|
|
|
{
|
|
|
|
database_function_data_set(foo_id,
|
|
|
|
(accessor->type == SETTER?EOLIAN_LEGACY_SET:EOLIAN_LEGACY_GET),
|
|
|
|
accessor->legacy);
|
|
|
|
}
|
|
|
|
database_function_description_set(foo_id,
|
|
|
|
(accessor->type == SETTER?EOLIAN_COMMENT_SET:EOLIAN_COMMENT_GET),
|
|
|
|
accessor->comment);
|
|
|
|
Eo_Accessor_Param *acc_param;
|
|
|
|
Eina_List *m2;
|
|
|
|
EINA_LIST_FOREACH(accessor->params, m2, acc_param)
|
|
|
|
{
|
|
|
|
Eolian_Function_Parameter desc = eolian_function_parameter_get(foo_id, acc_param->name);
|
|
|
|
if (!desc)
|
|
|
|
{
|
|
|
|
printf("Error - %s not known as parameter of property %s\n", acc_param->name, prop->name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (strstr(acc_param->attrs, "const"))
|
|
|
|
{
|
|
|
|
database_parameter_const_attribute_set(desc, accessor->type == GETTER, EINA_TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!prop->accessors) database_function_type_set(foo_id, EOLIAN_PROPERTY);
|
|
|
|
database_class_function_add(class, foo_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->methods, l, meth)
|
|
|
|
{
|
|
|
|
Eolian_Function foo_id = database_function_new(meth->name, EOLIAN_METHOD);
|
|
|
|
database_function_scope_set(foo_id, meth->scope);
|
|
|
|
database_class_function_add(class, foo_id);
|
|
|
|
if (meth->ret)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
database_function_return_type_set(foo_id, EOLIAN_METHOD, meth->ret->type);
|
2014-06-18 03:25:07 -07:00
|
|
|
database_function_return_comment_set(foo_id, EOLIAN_METHOD, meth->ret->comment);
|
|
|
|
database_function_return_flag_set_as_warn_unused(foo_id,
|
|
|
|
EOLIAN_METHOD, meth->ret->warn_unused);
|
|
|
|
database_function_return_dflt_val_set(foo_id,
|
|
|
|
EOLIAN_METHOD, meth->ret->dflt_ret_val);
|
2014-06-19 04:02:46 -07:00
|
|
|
meth->ret->type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
database_function_description_set(foo_id, EOLIAN_COMMENT, meth->comment);
|
|
|
|
database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
|
|
|
|
database_function_object_set_as_const(foo_id, meth->obj_const);
|
|
|
|
EINA_LIST_FOREACH(meth->params, m, param)
|
|
|
|
{
|
|
|
|
Eolian_Function_Parameter p = database_method_parameter_add(foo_id,
|
2014-06-18 08:27:29 -07:00
|
|
|
(Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
|
2014-06-18 03:25:07 -07:00
|
|
|
database_parameter_nonull_set(p, param->nonull);
|
2014-06-19 04:02:46 -07:00
|
|
|
param->type = NULL;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->implements, l, impl)
|
|
|
|
{
|
|
|
|
const char *impl_name = impl->meth_name;
|
|
|
|
if (!strcmp(impl_name, "class::constructor"))
|
|
|
|
{
|
|
|
|
database_class_ctor_enable_set(class, EINA_TRUE);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strcmp(impl_name, "class::destructor"))
|
|
|
|
{
|
|
|
|
database_class_dtor_enable_set(class, EINA_TRUE);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!strncmp(impl_name, "virtual::", 9))
|
|
|
|
{
|
|
|
|
char *virtual_name = strdup(impl_name);
|
|
|
|
char *func = strstr(virtual_name, "::");
|
|
|
|
if (func) *func = '\0';
|
|
|
|
func += 2;
|
|
|
|
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
|
|
|
|
char *type_as_str = strstr(func, "::");
|
|
|
|
if (type_as_str)
|
|
|
|
{
|
|
|
|
*type_as_str = '\0';
|
|
|
|
if (!strcmp(type_as_str+2, "set")) ftype = EOLIAN_PROP_SET;
|
|
|
|
else if (!strcmp(type_as_str+2, "get")) ftype = EOLIAN_PROP_GET;
|
|
|
|
}
|
|
|
|
/* Search the function into the existing functions of the current class */
|
|
|
|
Eolian_Function foo_id = eolian_class_function_find_by_name(
|
|
|
|
class, func, ftype);
|
|
|
|
free(virtual_name);
|
|
|
|
if (!foo_id)
|
|
|
|
{
|
|
|
|
ERR("Error - %s not known in class %s", impl_name + 9, eolian_class_name_get(class));
|
2014-06-18 08:36:29 -07:00
|
|
|
eo_lexer_free(ls);
|
|
|
|
return EINA_FALSE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
database_function_set_as_virtual_pure(foo_id, ftype);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Eolian_Implement impl_desc = database_implement_new(impl_name);
|
|
|
|
database_class_implement_add(class, impl_desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(kls->events, l, event)
|
|
|
|
{
|
|
|
|
Eolian_Event ev = database_event_new(event->name, event->type, event->comment);
|
|
|
|
database_class_event_add(class, ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ls->typedefs, k, type_def)
|
|
|
|
{
|
2014-06-18 08:27:29 -07:00
|
|
|
database_type_add(type_def->alias, type_def->type);
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|
|
|
|
|
2014-06-18 08:36:29 -07:00
|
|
|
eo_lexer_free(ls);
|
|
|
|
return EINA_TRUE;
|
2014-06-18 03:25:07 -07:00
|
|
|
}
|