q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=60c733670d3418a9499a6637b535b07d8251fc0e

commit 60c733670d3418a9499a6637b535b07d8251fc0e
Author: Daniel Kolesa <d.kol...@osg.samsung.com>
Date:   Fri Mar 16 16:07:12 2018 +0100

    eolian: intial API for a new error mechanism
    
    Unlike panic, this will be used to handle regular errors
    such as parse errors. There will be no jumps and you
    will be able to pass in a pointer to get the error
    data into some local memory. That way you will be
    able to override printing error messages.
---
 src/lib/eolian/Eolian.h          | 52 ++++++++++++++++++++++++++++++++++------
 src/lib/eolian/eolian_database.c | 32 +++++++++++++++++++++++++
 src/lib/eolian/eolian_database.h |  3 +++
 3 files changed, 80 insertions(+), 7 deletions(-)

diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index 54300cf483..3e07f761dd 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -201,6 +201,7 @@ typedef struct _Eolian_Unit Eolian_Unit;
 #define EOLIAN_UNIT(expr) EOLIAN_CAST(Eolian_Unit, expr)
 
 typedef void (*Eolian_Panic_Cb)(const Eolian_State *state, Eina_Stringshare 
*msg);
+typedef void (*Eolian_Error_Cb)(const Eolian_Object *obj, const char *msg, 
void *data);
 
 typedef enum
 {
@@ -492,7 +493,7 @@ EAPI int eolian_shutdown(void);
  * This will assign a default panic function, which printers the error
  * message passed to it into the standard Eolian log.
  *
- * @see eolian_panic_cb_set
+ * @see eolian_state_panic_cb_set
  *
  * @return A new state (or NULL on failure).
  *
@@ -501,6 +502,18 @@ EAPI int eolian_shutdown(void);
 EAPI Eolian_State *eolian_state_new(void);
 
 /*
+ * @brief Free an Eolian state.
+ *
+ * You can use this to free an Eolian state.
+ *
+ * If the input is NULL, this function has no effect.
+ *
+ * @param[in] state the state to free
+ *
+ */
+EAPI void eolian_state_free(Eolian_State *state);
+
+/*
  * @brief Set the panic function for the state.
  *
  * When an unrecoverable error happens in an Eolian API call, the panic
@@ -520,20 +533,45 @@ EAPI Eolian_State *eolian_state_new(void);
  *
  * If you set a panic function and jump, you're responsible for the error
  * message and have to delete it with eina_stringshare_del.
+ *
+ * If you want to catch error messages that are standard (such as parse
+ * errors), there is another, separate mechanism in place.
+ *
+ * @return The old panic callback.
+ *
+ * @see eolian_state_error_cb_set
  */
-EAPI Eolian_Panic_Cb eolian_panic_cb_set(Eolian_State *state, Eolian_Panic_Cb 
cb);
+EAPI Eolian_Panic_Cb eolian_state_panic_cb_set(Eolian_State *state, 
Eolian_Panic_Cb cb);
 
 /*
- * @brief Free an Eolian state.
+ * @brief Set the error function for the state.
  *
- * You can use this to free an Eolian state.
+ * When a regular error (such as parse error) happens, you can use this
+ * callback to catch the error. There is no jump involved and the outer
+ * function will fail normally and safely. You are provided with the
+ * object the error happened on (for line/column/file/other information)
+ * as well as the error message. Additionally, a data pointer is passed
+ * in so you can pass some of the information into local memory somewhere.
  *
- * If the input is NULL, this function has no effect.
+ * @return The old error callback.
  *
- * @param[in] state the state to free
+ * @see eolian_state_panic_cb_set
+ * @see eolian_state_error_data_set
+ */
+EAPI Eolian_Error_Cb eolian_state_error_cb_set(Eolian_State *state, 
Eolian_Error_Cb cb);
+
+/*
+ * @brief Set a data pointer to be passed to the error function.
  *
+ * By default, the data is `NULL`. You can use this to set a data pointer
+ * to be passed. This is useful to e.g. expose some local memory so you can
+ * write back from the callback without using globals.
+ *
+ * @return The old data pointer.
+ *
+ * @see eolian_state_error_cb_set
  */
-EAPI void eolian_state_free(Eolian_State *state);
+EAPI void *eolian_state_error_data_set(Eolian_State *state, void *data);
 
 /*
  * @brief Get the type of an Eolian object.
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
index 70fe7a8d4d..6db89eaa5b 100644
--- a/src/lib/eolian/eolian_database.c
+++ b/src/lib/eolian/eolian_database.c
@@ -570,6 +570,12 @@ _default_panic_cb(const Eolian_State *state EINA_UNUSED, 
const char *msg)
    _eolian_log(msg);
 }
 
+static void
+_default_error_cb(const Eolian_Object *obj, const char *msg, void *data 
EINA_UNUSED)
+{
+   _eolian_log_line(obj->file, obj->line, obj->column, msg);
+}
+
 EAPI Eolian_State *
 eolian_state_new(void)
 {
@@ -586,6 +592,8 @@ eolian_state_new(void)
         exit(EXIT_FAILURE);
      }
 
+   state->error = _default_error_cb;
+
    database_unit_init(state, &state->unit, NULL);
 
    state->filenames_eo  = eina_hash_string_small_new(free);
@@ -630,6 +638,30 @@ eolian_state_free(Eolian_State *state)
    free(state);
 }
 
+EAPI Eolian_Panic_Cb
+eolian_state_panic_cb_set(Eolian_State *state, Eolian_Panic_Cb cb)
+{
+   Eolian_Panic_Cb old_cb = state->panic;
+   state->panic = cb;
+   return old_cb;
+}
+
+EAPI Eolian_Error_Cb
+eolian_state_error_cb_set(Eolian_State *state, Eolian_Error_Cb cb)
+{
+   Eolian_Error_Cb old_cb = state->error;
+   state->error = cb;
+   return old_cb;
+}
+
+EAPI void *
+eolian_state_error_data_set(Eolian_State *state, void *data)
+{
+   void *old_data = state->error_data;
+   state->error_data = data;
+   return old_data;
+}
+
 #define EO_SUFFIX ".eo"
 #define EOT_SUFFIX ".eot"
 
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 813f3f5e1c..eff2b966a5 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -55,6 +55,9 @@ struct _Eolian_State
    Eina_Stringshare *panic_msg;
    jmp_buf jmp_env;
 
+   Eolian_Error_Cb error;
+   void *error_data;
+
    Eina_Hash *filenames_eo; /* filename to full path mapping */
    Eina_Hash *filenames_eot;
 

-- 


Reply via email to