eolian: make use of panics for certain alloc errors

This commit is contained in:
Daniel Kolesa 2018-03-20 17:34:38 +01:00
parent 7c6d8010a8
commit 2db8e8e914
4 changed files with 47 additions and 8 deletions

View File

@ -116,7 +116,7 @@ throw(Eo_Lexer *ls, const char *fmt, ...)
tmp.column = ls->column;
eolian_state_log_obj(ls->state, &tmp, "%s", eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
longjmp(ls->err_jmp, EINA_TRUE);
longjmp(ls->err_jmp, EO_LEXER_ERROR_NORMAL);
}
void
@ -462,6 +462,9 @@ static void
read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
{
Eolian_Documentation *doc = calloc(1, sizeof(Eolian_Documentation));
if (!doc)
longjmp(ls->err_jmp, EO_LEXER_ERROR_OOM);
doc->base.file = ls->filename;
doc->base.line = line;
doc->base.column = column;
@ -1061,7 +1064,7 @@ eo_lexer_set_input(Eo_Lexer *ls, Eolian_State *state, const char *source)
if (!f)
{
eolian_state_log(ls->state, "%s", strerror(errno));
longjmp(ls->err_jmp, EINA_TRUE);
longjmp(ls->err_jmp, EO_LEXER_ERROR_NORMAL);
}
ls->lookahead.token = -1;
ls->state = state;
@ -1079,6 +1082,11 @@ eo_lexer_set_input(Eo_Lexer *ls, Eolian_State *state, const char *source)
next_char(ls);
Eolian_Unit *ncunit = calloc(1, sizeof(Eolian_Unit));
if (!ncunit)
{
eo_lexer_free(ls);
eolian_state_panic(state, "out of memory");
}
ls->unit = ncunit;
database_unit_init(state, ncunit, ls->filename);
eina_hash_add(state->units, ls->filename, ncunit);
@ -1098,6 +1106,8 @@ Eolian_Object *
eo_lexer_node_new(Eo_Lexer *ls, size_t objsize)
{
Eolian_Object *obj = calloc(1, objsize);
if (!obj)
longjmp(ls->err_jmp, EO_LEXER_ERROR_OOM);
eina_hash_add(ls->nodes, &obj, obj);
eolian_object_ref(obj);
return obj;
@ -1137,6 +1147,11 @@ void
eo_lexer_dtor_push(Eo_Lexer *ls, Eina_Free_Cb free_cb, void *data)
{
Eo_Lexer_Dtor *dt = malloc(sizeof(Eo_Lexer_Dtor));
if (!dt)
{
free_cb(data);
longjmp(ls->err_jmp, EO_LEXER_ERROR_OOM);
}
dt->free_cb = free_cb;
dt->data = data;
ls->dtors = eina_list_prepend(ls->dtors, dt);
@ -1176,6 +1191,8 @@ Eo_Lexer *
eo_lexer_new(Eolian_State *state, const char *source)
{
volatile Eo_Lexer *ls = calloc(1, sizeof(Eo_Lexer));
if (!ls)
eolian_state_panic(state, "out of memory");
if (!setjmp(((Eo_Lexer *)(ls))->err_jmp))
{
@ -1294,11 +1311,7 @@ eo_lexer_context_push(Eo_Lexer *ls)
{
Lexer_Ctx *ctx = malloc(sizeof(Lexer_Ctx));
if (!ctx)
{
/* FIXME unrecoverable */
_eolian_log("out of memory pushing context");
longjmp(ls->err_jmp, EINA_TRUE);
}
longjmp(ls->err_jmp, EO_LEXER_ERROR_OOM);
ctx->line = ls->line_number;
ctx->column = ls->column;
ctx->linestr = ls->stream_line;

View File

@ -193,6 +193,13 @@ typedef struct _Eo_Lexer
char decpoint;
} Eo_Lexer;
typedef enum _Eo_Lexer_Error
{
EO_LEXER_ERROR_UNKNOWN = 0,
EO_LEXER_ERROR_NORMAL,
EO_LEXER_ERROR_OOM
} Eo_Lexer_Error;
void eo_lexer_init (void);
void eo_lexer_shutdown (void);
Eo_Lexer *eo_lexer_new (Eolian_State *state, const char *source);

View File

@ -2195,6 +2195,7 @@ parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
Eolian_Unit *
eo_parser_database_fill(Eolian_Unit *parent, const char *filename, Eina_Bool eot)
{
int status = 0;
const char *fsl = strrchr(filename, '/');
const char *bsl = strrchr(filename, '\\');
const char *fname = NULL;
@ -2224,7 +2225,7 @@ eo_parser_database_fill(Eolian_Unit *parent, const char *filename, Eina_Bool eot
/* read first token */
eo_lexer_get(ls);
if (setjmp(ls->err_jmp))
if ((status = setjmp(ls->err_jmp)))
goto error;
parse_chunk(ls, eot);
@ -2252,5 +2253,13 @@ done:
error:
eina_stringshare_del(fname);
eo_lexer_free(ls);
switch (status)
{
case EO_LEXER_ERROR_OOM:
eolian_state_panic(parent->state, "out of memory");
break;
default:
break;
}
return NULL;
}

View File

@ -114,6 +114,7 @@ static inline void eolian_state_vlog(const Eolian_State *state, const Eolian_Obj
static inline void eolian_state_log(const Eolian_State *state, const char *fmt, ...) EINA_ARG_NONNULL(1, 2) EINA_PRINTF(2, 3);
static inline void eolian_state_log_obj(const Eolian_State *state, const Eolian_Object *obj, const char *fmt, ...) EINA_ARG_NONNULL(1, 2, 3) EINA_PRINTF(3, 4);
static inline void eolian_state_panic(Eolian_State *state, const char *fmt, ...) EINA_ARG_NONNULL(1, 2) EINA_PRINTF(2, 3);
static inline void
eolian_state_vlog(const Eolian_State *state, const Eolian_Object *obj,
@ -144,6 +145,15 @@ eolian_state_log_obj(const Eolian_State *state, const Eolian_Object *obj,
va_end(args);
}
static inline void
eolian_state_panic(Eolian_State *state, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
state->panic_msg = eina_stringshare_vprintf(fmt, args);
va_end(args);
longjmp(state->jmp_env, 1);
}
struct _Eolian_Documentation
{