@since 1.22
]]
- argv: const(array<const(stringshare)>); [[Array with loop arguments]]
+ argv: const(array<stringshare>); [[Array with loop arguments]]
initialization: bool; [[Set to $true when the program should initialize its internal state.
This happens once per process instance.]]
}
return database_expr_eval(unit, expr, EOLIAN_MASK_NULL, cb, data);
case EOLIAN_TYPE_REGULAR:
{
- if (database_type_is_ownable(unit, type, EINA_FALSE))
+ if (database_type_is_ownable(unit, type, EINA_FALSE, NULL))
return database_expr_eval(unit, expr, EOLIAN_MASK_NULL, cb, data);
int kw = eo_lexer_keyword_str_to_id(type->base.name);
if (!kw || kw < KW_byte || kw >= KW_void)
}
Eina_Bool
-database_type_is_ownable(const Eolian_Unit *unit, const Eolian_Type *tp, Eina_Bool allow_void)
+database_type_is_ownable(const Eolian_Unit *unit, const Eolian_Type *tp, Eina_Bool allow_void, const Eolian_Type **otp)
{
+ if (otp) *otp = tp;
if (tp->is_ptr)
return EINA_TRUE;
if (tp->type == EOLIAN_TYPE_REGULAR)
if (tpp->type == EOLIAN_TYPEDECL_FUNCTION_POINTER)
return EINA_TRUE;
if (tpp->type == EOLIAN_TYPEDECL_ALIAS)
- return database_type_is_ownable(unit, tpp->base_type, allow_void);
+ return database_type_is_ownable(unit, tpp->base_type, allow_void, otp);
return EINA_FALSE;
}
return (ct[strlen(ct) - 1] == '*');
|| tp->type == EOLIAN_TYPE_CLASS
|| tp->type == EOLIAN_TYPE_VOID)
&& tp->is_const
- && ((ctype != EOLIAN_C_TYPE_RETURN) || by_ref || database_type_is_ownable(NULL, tp, EINA_FALSE)))
+ && ((ctype != EOLIAN_C_TYPE_RETURN) || by_ref || database_type_is_ownable(NULL, tp, EINA_FALSE, NULL)))
{
eina_strbuf_append(buf, "const ");
}
return _validate(&doc->base);
}
-static Eina_Bool _validate_type(Validate_State *vals, Eolian_Type *tp);
+static Eina_Bool _validate_type(Validate_State *vals, Eolian_Type *tp,
+ Eina_Bool by_ref, Eina_Bool is_ret);
static Eina_Bool _validate_type_by_ref(Validate_State *vals, Eolian_Type *tp,
- Eina_Bool by_ref, Eina_Bool move);
+ Eina_Bool by_ref, Eina_Bool move,
+ Eina_Bool is_ret);
static Eina_Bool _validate_expr(Eolian_Expression *expr,
const Eolian_Type *tp,
Eolian_Expression_Mask msk,
_sf_map_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
const Eolian_Struct_Type_Field *sf, Cb_Ret *sc)
{
- sc->succ = _validate_type_by_ref(sc->vals, sf->type, sf->by_ref, sf->move);
+ sc->succ = _validate_type_by_ref(sc->vals, sf->type, sf->by_ref,
+ sf->move, EINA_FALSE);
if (!sc->succ)
return EINA_FALSE;
switch (tp->type)
{
case EOLIAN_TYPEDECL_ALIAS:
- if (!_validate_type(vals, tp->base_type))
+ if (!_validate_type(vals, tp->base_type, EINA_FALSE, EINA_FALSE))
return _reset_stable(vals, was_stable, EINA_FALSE);
if (tp->base_type->ownable)
tp->ownable = EINA_TRUE;
_validate_by_ref(Eolian_Type *tp, Eina_Bool by_ref, Eina_Bool move)
{
Eina_Bool maybe_ownable =
- database_type_is_ownable(tp->base.unit, tp, EINA_FALSE);
+ database_type_is_ownable(tp->base.unit, tp, EINA_FALSE, NULL);
/* only allow value types when @by_ref */
if (by_ref && maybe_ownable)
static Eina_Bool
_validate_type_by_ref(Validate_State *vals, Eolian_Type *tp,
- Eina_Bool by_ref, Eina_Bool move)
+ Eina_Bool by_ref, Eina_Bool move, Eina_Bool is_ret)
{
- if (!_validate_type(vals, tp))
+ if (!_validate_type(vals, tp, by_ref, is_ret))
return EINA_FALSE;
return _validate_by_ref(tp, by_ref, move);
}
static Eina_Bool
-_validate_type(Validate_State *vals, Eolian_Type *tp)
+_validate_type(Validate_State *vals, Eolian_Type *tp, Eina_Bool by_ref,
+ Eina_Bool is_ret)
{
const Eolian_Unit *src = tp->base.unit;
return EINA_FALSE;
}
tp->is_ptr = EINA_FALSE;
- Eina_Bool still_ownable = database_type_is_ownable(src, tp, EINA_FALSE);
+ Eina_Bool still_ownable = database_type_is_ownable(src, tp, EINA_FALSE, NULL);
tp->is_ptr = EINA_TRUE;
if (still_ownable)
{
}
}
+ if (tp->is_const && !tp->is_ptr)
+ {
+ if (database_type_is_ownable(src, tp, EINA_FALSE, NULL))
+ {
+ int kw = eo_lexer_keyword_str_to_id(tp->base.name);
+ switch (kw)
+ {
+ case KW_string:
+ case KW_mstring:
+ case KW_stringshare:
+ _eo_parser_log(&tp->base, "string types cannot be const");
+ return EINA_FALSE;
+ default:
+ {
+ if (!is_ret)
+ break;
+ const char *ct = eo_lexer_get_c_type(kw);
+ if (ct && ct[strlen(ct) - 1] != '*')
+ {
+ _eo_parser_log(&tp->base, "return const requires a C pointer");
+ return EINA_FALSE;
+ }
+ }
+ }
+ }
+ else if (!by_ref && is_ret)
+ {
+ _eo_parser_log(&tp->base, "value returns cannot be const");
+ return EINA_FALSE;
+ }
+ }
+
switch (tp->type)
{
case EOLIAN_TYPE_VOID:
tp->base.name);
return EINA_FALSE;
}
- if (!_validate_type_by_ref(vals, itp, EINA_FALSE, itp->move))
+ if (!_validate_type_by_ref(vals, itp, EINA_FALSE, itp->move, EINA_FALSE))
return EINA_FALSE;
itp = itp->next_type;
}
return EINA_FALSE;
}
tp->base.c_name = eina_stringshare_ref(tp->error->base.c_name);
- if (tp->next_type && !_validate_type(vals, tp->next_type))
+ if (tp->next_type && !_validate_type(vals, tp->next_type, EINA_FALSE, EINA_FALSE))
return EINA_FALSE;
return _validate(&tp->base);
}
static Eina_Bool
_validate_param(Validate_State *vals, Eolian_Function_Parameter *param)
{
- if (!_validate_type_by_ref(vals, param->type, param->by_ref, param->move))
+ if (!_validate_type_by_ref(vals, param->type, param->by_ref, param->move, EINA_FALSE))
return EINA_FALSE;
if (param->value && !_validate_expr(param->value, param->type, 0, param->by_ref))
Eina_Bool was_stable = _set_stable(vals, !func->base.is_beta && vals->stable);
if (func->get_ret_type && !_validate_type_by_ref(vals, func->get_ret_type,
- func->get_return_by_ref, func->get_return_move))
+ func->get_return_by_ref, func->get_return_move, EINA_TRUE))
return _reset_stable(vals, was_stable, EINA_FALSE);
if (func->set_ret_type && !_validate_type_by_ref(vals, func->set_ret_type,
- func->set_return_by_ref, func->set_return_move))
+ func->set_return_by_ref, func->set_return_move, EINA_TRUE))
return _reset_stable(vals, was_stable, EINA_FALSE);
if (func->get_ret_val && !_validate_expr(func->get_ret_val,
Eina_Bool was_stable = _set_stable(vals, !event->base.is_beta && vals->stable);
- if (!_validate_type(vals, event->type))
+ if (!_validate_type(vals, event->type, EINA_FALSE, EINA_FALSE))
return _reset_stable(vals, was_stable, EINA_FALSE);
/* if this is an alias we need the lowest type in the stack, this is
* this is FIXME, and decision wasn't reached before 1.22
* it is a simple search-replace anyway
*/
- if (database_type_is_ownable(tp->base.unit, tp, EINA_FALSE))
+ if (database_type_is_ownable(tp->base.unit, tp, EINA_FALSE, NULL))
{
switch (kwid)
{
Eina_Bool was_stable = _set_stable(vals, !var->base.is_beta && vals->stable);
- if (!_validate_type(vals, var->base_type))
+ if (!_validate_type(vals, var->base_type, EINA_FALSE, EINA_FALSE))
return _reset_stable(vals, was_stable, EINA_FALSE);
if (!_validate_expr(var->value, var->base_type, 0, EINA_FALSE))
return parse_expr_bin(ls, 1);
}
-static Eolian_Type *parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr);
+static Eolian_Type *parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr, Eina_Bool allow_const);
static Eolian_Type *
-parse_type(Eo_Lexer *ls, Eina_Bool allow_ptr)
+parse_type(Eo_Lexer *ls, Eina_Bool allow_ptr, Eina_Bool allow_const)
{
Eolian_Type *ret;
eo_lexer_context_push(ls);
- ret = parse_type_void(ls, allow_ptr);
+ ret = parse_type_void(ls, allow_ptr, allow_const);
if (ret->type == EOLIAN_TYPE_VOID)
{
eo_lexer_context_restore(ls);
eolian_object_ref(&fdef->base);
eo_lexer_get(ls);
check_next(ls, ':');
- tp = parse_type(ls, EINA_TRUE);
+ tp = parse_type(ls, EINA_TRUE, EINA_TRUE);
FILL_BASE(fdef->base, ls, fline, fcol, STRUCT_FIELD);
fdef->type = eo_lexer_type_release(ls, tp);
fdef->base.name = eina_stringshare_ref(fname);
}
static Eolian_Type *
-parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
+parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr, Eina_Bool allow_const)
{
Eolian_Type *def;
Eina_Strbuf *buf;
{
case KW_const:
{
+ if (!allow_const)
+ break;
int pline, pcol;
eo_lexer_get(ls);
pline = ls->line_number;
pcol = ls->column;
check_next(ls, '(');
- def = parse_type_void(ls, allow_ptr);
+ def = parse_type_void(ls, allow_ptr, EINA_FALSE);
FILL_BASE(def->base, ls, line, col, TYPE);
def->is_const = EINA_TRUE;
check_match(ls, ')', '(', pline, pcol);
pline = ls->line_number;
pcol = ls->column;
check_next(ls, '(');
- def = parse_type_void(ls, EINA_FALSE);
+ def = parse_type_void(ls, EINA_FALSE, allow_const);
FILL_BASE(def->base, ls, line, col, TYPE);
def->is_ptr = EINA_TRUE;
check_match(ls, ')', '(', pline, pcol);
int bline = ls->line_number, bcol = ls->column;
check_next(ls, '<');
if (tpid == KW_future)
- def->base_type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE));
+ def->base_type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE, EINA_TRUE));
else
- def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE));
+ def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE, EINA_TRUE));
/* view-only types are not allowed to own the contents */
if (tpid == KW_array || tpid == KW_hash || tpid == KW_list || tpid == KW_future)
if ((def->base_type->move = ls->t.kw == KW_at_move))
{
check_next(ls, ',');
def->base_type->next_type =
- eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE));
+ eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE, EINA_TRUE));
if ((def->base_type->next_type->move = ls->t.kw == KW_at_move))
eo_lexer_get(ls);
}
}
eo_lexer_context_pop(ls);
check_next(ls, ':');
- def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_FALSE));
+ def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_FALSE, EINA_FALSE));
check_next(ls, ';');
FILL_DOC(ls, def, doc);
eo_lexer_dtor_pop(ls);
}
eo_lexer_context_pop(ls);
check_next(ls, ':');
- def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE));
+ def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_FALSE, EINA_FALSE));
/* constants are required to have a value */
check(ls, '=');
ls->expr_mode = EINA_TRUE;
eo_lexer_get(ls);
check_next(ls, ':');
if (allow_void)
- ret->type = parse_type_void(ls, EINA_TRUE);
+ ret->type = parse_type_void(ls, EINA_TRUE, EINA_TRUE);
else
- ret->type = parse_type(ls, EINA_TRUE);
+ ret->type = parse_type(ls, EINA_TRUE, EINA_TRUE);
ret->doc = NULL;
ret->default_ret_val = NULL;
ret->no_unused = EINA_FALSE;
if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM)
{
/* void is allowed for out/inout for beta-api for now to make a voidptr */
- par->type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE));
+ par->type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE, EINA_TRUE));
goto type_done;
}
}
- par->type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE));
+ par->type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE, EINA_TRUE));
type_done:
if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '('))
{
}
end:
check_next(ls, ':');
- ev->type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE));
+ ev->type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE, EINA_TRUE));
check(ls, ';');
eo_lexer_get(ls);
FILL_DOC(ls, ev, doc);
Eolian_Typedecl *database_type_decl_find(const Eolian_Unit *src, const Eolian_Type *tp);
-Eina_Bool database_type_is_ownable(const Eolian_Unit *unit, const Eolian_Type *tp, Eina_Bool allow_void);
+Eina_Bool database_type_is_ownable(const Eolian_Unit *unit, const Eolian_Type *tp, Eina_Bool allow_void, const Eolian_Type **otp);
/* expressions */