ecs: "ecs_mon" complied with the qemu 2.4
authorChulHo Song <ch81.song@samsung.com>
Tue, 25 Aug 2015 10:47:10 +0000 (19:47 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 28 Aug 2015 10:05:20 +0000 (19:05 +0900)
Change-Id: Ic826653f27797a067e38e4e1ce4014ac8a3c547a
Signed-off-by: ChulHo Song <ch81.song@samsung.com>
tizen/src/ecs/ecs_mon.c

index 3999402..be9dde8 100644 (file)
@@ -59,15 +59,16 @@ typedef struct mon_cmd_t {
     const char *args_type;
     const char *params;
     const char *help;
-    void (*user_print)(Monitor *mon, const QObject *data);
     union {
-        void (*info)(Monitor *mon);
         void (*cmd)(Monitor *mon, const QDict *qdict);
-        int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
-        int (*cmd_async)(Monitor *mon, const QDict *params,
-                MonitorCompletion *cb, void *opaque);
+        void (*cmd_new)(QDict *params, QObject **ret_data, Error **errp);
     } mhandler;
-    int flags;
+    /* @sub_table is a list of 2nd level of commands. If it do not exist,
+     * mhandler should be used. If it exist, sub_table[?].mhandler should be
+     * used, and mhandler of 1st level plays the role of help function.
+     */
+    struct mon_cmd_t *sub_table;
+    void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
 } mon_cmd_t;
 
 /*
@@ -157,14 +158,10 @@ static void ecs_monitor_puts(ECS_Client *clii, Monitor *mon, const char *str) {
     }
 }
 
-static inline int monitor_has_error(const Monitor *mon) {
-    return mon->error != NULL;
-}
-
-static QDict *build_qmp_error_dict(const QError *err) {
+static QDict *build_qmp_error_dict(Error *err) {
     QObject *obj = qobject_from_jsonf(
-            "{ 'error': { 'class': %s, 'desc': %p } }",
-            ErrorClass_lookup[err->err_class], qerror_human(err));
+            "{ 'error': { 'class': %s, 'desc': %s } }",
+            ErrorClass_lookup[error_get_class(err)], error_get_pretty(err));
 
     return qobject_to_qdict(obj);
 }
@@ -183,14 +180,14 @@ static void ecs_json_emitter(ECS_Client *clii, const QObject *data) {
 }
 
 static void ecs_protocol_emitter(ECS_Client *clii, const char* type,
-        QObject *data) {
+        QObject *data, Error *err) {
     QDict *qmp;
     QObject *obj;
 
     TRACE("ecs_protocol_emitter called.\n");
     //trace_monitor_protocol_emitter(clii->cs->mon);
 
-    if (!monitor_has_error(clii->cs->mon)) {
+    if (!err) {
         /* success response */
         qmp = qdict_new();
         if (data) {
@@ -210,65 +207,36 @@ static void ecs_protocol_emitter(ECS_Client *clii, const char* type,
 
     } else {
         /* error response */
-        qmp = build_qmp_error_dict(clii->cs->mon->error);
-        QDECREF(clii->cs->mon->error);
-        clii->cs->mon->error = NULL;
+        qmp = build_qmp_error_dict(err);
     }
 
     ecs_json_emitter(clii, QOBJECT(qmp));
     QDECREF(qmp);
 }
 
-static void qmp_monitor_complete(void *opaque, QObject *ret_data) {
-    //   ecs_protocol_emitter(opaque, ret_data);
-}
-
-static int ecs_qmp_async_cmd_handler(ECS_Client *clii, const mon_cmd_t *cmd,
-        const QDict *params) {
-    return cmd->mhandler.cmd_async(clii->cs->mon, params, qmp_monitor_complete,
-            clii);
-}
-
 static void ecs_qmp_call_cmd(ECS_Client *clii, Monitor *mon, const char* type,
-        const mon_cmd_t *cmd, const QDict *params) {
-    int ret;
+        const mon_cmd_t *cmd, QDict *params) {
     QObject *data = NULL;
+    Error *local_err = NULL;
 
-    ret = cmd->mhandler.cmd_new(mon, params, &data);
-    if (ret && !monitor_has_error(mon)) {
-        qerror_report(QERR_UNDEFINED_ERROR);
-    }
-    ecs_protocol_emitter(clii, type, data);
+    cmd->mhandler.cmd_new(params, &data, &local_err);
+    ecs_protocol_emitter(clii, type, data, local_err);
     qobject_decref(data);
 }
 
-static inline bool handler_is_async(const mon_cmd_t *cmd) {
-    return cmd->flags & MONITOR_CMD_ASYNC;
-}
-
-static void monitor_user_noop(Monitor *mon, const QObject *data) {
-}
-
-static int client_migrate_info(Monitor *mon, const QDict *qdict,
-        MonitorCompletion cb, void *opaque) {
-    return 0;
-}
-
-static int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data) {
-    return 0;
+static void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) {
 }
 
-static int do_qmp_capabilities(Monitor *mon, const QDict *params,
-        QObject **ret_data) {
-    return 0;
+static void qmp_capabilities(QDict *params, QObject **ret_data, Error **errp) {
 }
 
 static const mon_cmd_t qmp_cmds[] = {
 #include "qmp-commands-old.h"
         { /* NULL */}, };
 
-static int check_mandatory_args(const QDict *cmd_args, const QDict *client_args,
-        int *flags) {
+static void check_mandatory_args(const QDict *cmd_args, const QDict *client_args,
+        int *flags, Error **errp)
+{
     const QDictEntry *ent;
 
     for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) {
@@ -282,16 +250,15 @@ static int check_mandatory_args(const QDict *cmd_args, const QDict *client_args,
         } else if (qstring_get_str(type)[0] != '-'
                 && qstring_get_str(type)[1] != '?'
                 && !qdict_haskey(client_args, cmd_arg_name)) {
-            qerror_report(QERR_MISSING_PARAMETER, cmd_arg_name);
-            return -1;
+            error_setg(errp, QERR_MISSING_PARAMETER, cmd_arg_name);
+            return;
         }
     }
-
-    return 0;
 }
 
-static int check_client_args_type(const QDict *client_args,
-        const QDict *cmd_args, int flags) {
+static void check_client_args_type(const QDict *client_args,
+        const QDict *cmd_args, int flags, Error **errp)
+{
     const QDictEntry *ent;
 
     for (ent = qdict_first(client_args); ent;
@@ -306,8 +273,8 @@ static int check_client_args_type(const QDict *client_args,
             if (flags & QMP_ACCEPT_UNKNOWNS) {
                 continue;
             }
-            qerror_report(QERR_INVALID_PARAMETER, client_arg_name);
-            return -1;
+            error_setg(errp, QERR_INVALID_PARAMETER, client_arg_name);
+            return;
         }
 
         arg_type = qobject_to_qstring(obj);
@@ -318,9 +285,9 @@ static int check_client_args_type(const QDict *client_args,
         case 'B':
         case 's':
             if (qobject_type(client_arg) != QTYPE_QSTRING) {
-                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
-                        "string");
-                return -1;
+                error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+                        client_arg_name, "string");
+                return;
             }
             break;
         case 'i':
@@ -328,25 +295,25 @@ static int check_client_args_type(const QDict *client_args,
         case 'M':
         case 'o':
             if (qobject_type(client_arg) != QTYPE_QINT) {
-                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
-                        "int");
-                return -1;
+                error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+                        client_arg_name, "int");
+                return;
             }
             break;
         case 'T':
             if (qobject_type(client_arg) != QTYPE_QINT
                     && qobject_type(client_arg) != QTYPE_QFLOAT) {
-                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
-                        "number");
-                return -1;
+                error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+                        client_arg_name, "number");
+                return;
             }
             break;
         case 'b':
         case '-':
             if (qobject_type(client_arg) != QTYPE_QBOOL) {
-                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
-                        "bool");
-                return -1;
+                error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+                        client_arg_name, "bool");
+                return;
             }
             break;
         case 'O':
@@ -360,8 +327,6 @@ static int check_client_args_type(const QDict *client_args,
             abort();
         }
     }
-
-    return 0;
 }
 
 static QDict *qdict_from_args_type(const char *args_type) {
@@ -406,32 +371,34 @@ static QDict *qdict_from_args_type(const char *args_type) {
     out: return qdict;
 }
 
-static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) {
-    int flags, err;
+static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args, Error **errp)
+{
+    Error *err = NULL;
+    int flags;
     QDict *cmd_args;
 
     cmd_args = qdict_from_args_type(cmd->args_type);
 
     flags = 0;
-    err = check_mandatory_args(cmd_args, client_args, &flags);
+    check_mandatory_args(cmd_args, client_args, &flags, &err);
     if (err) {
         goto out;
     }
 
-    err = check_client_args_type(client_args, cmd_args, flags);
+    check_client_args_type(client_args, cmd_args, flags, &err);
 
-    out:
+out:
+    error_propagate(errp, err);
     QDECREF(cmd_args);
-    return err;
 }
 
-static QDict *qmp_check_input_obj(QObject *input_obj) {
+static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp) {
     const QDictEntry *ent;
     int has_exec_key = 0;
     QDict *input_dict;
 
     if (qobject_type(input_obj) != QTYPE_QDICT) {
-        qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object");
+        error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "object");
         return NULL;
     }
 
@@ -444,27 +411,28 @@ static QDict *qmp_check_input_obj(QObject *input_obj) {
 
         if (!strcmp(arg_name, "execute")) {
             if (qobject_type(arg_obj) != QTYPE_QSTRING) {
-                qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute",
-                        "string");
+                error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
+                        "execute", "string");
                 return NULL;
             }
             has_exec_key = 1;
         } else if (!strcmp(arg_name, "arguments")) {
             if (qobject_type(arg_obj) != QTYPE_QDICT) {
-                qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments",
-                        "object");
+                error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
+                           "arguments", "object");
                 return NULL;
             }
         } else if (!strcmp(arg_name, "id")) {
+            /* Any string is acceptable as "id", so nothing to check */
         } else if (!strcmp(arg_name, "type")) {
         } else {
-            qerror_report(QERR_QMP_EXTRA_MEMBER, arg_name);
+            error_setg(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
             return NULL;
         }
     }
 
     if (!has_exec_key) {
-        qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute");
+        error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
         return NULL;
     }
 
@@ -509,7 +477,7 @@ static const mon_cmd_t *qmp_find_cmd(const char *cmdname) {
 
 void handle_qmp_command(JSONMessageParser *parser, QList *tokens,
         void *opaque) {
-    int err;
+    Error *local_err = NULL;
     QObject *obj;
     QDict *input, *args;
     const mon_cmd_t *cmd;
@@ -523,11 +491,11 @@ void handle_qmp_command(JSONMessageParser *parser, QList *tokens,
     obj = json_parser_parse(tokens, NULL);
     if (!obj) {
         // FIXME: should be triggered in json_parser_parse()
-        qerror_report(QERR_JSON_PARSING);
+        error_setg(&local_err, QERR_JSON_PARSING);
         goto err_out;
     }
 
-    input = qmp_check_input_obj(obj);
+    input = qmp_check_input_obj(obj, &local_err);
     if (!input) {
         qobject_decref(obj);
         goto err_out;
@@ -538,7 +506,8 @@ void handle_qmp_command(JSONMessageParser *parser, QList *tokens,
 
     cmd = qmp_find_cmd(cmd_name);
     if (!cmd) {
-        qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
+        error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
+            "The command %s has not been found", cmd_name);
         goto err_out;
     }
 
@@ -552,25 +521,17 @@ void handle_qmp_command(JSONMessageParser *parser, QList *tokens,
         QINCREF(args);
     }
 
-    err = qmp_check_client_args(cmd, args);
-    if (err < 0) {
+    qmp_check_client_args(cmd, args, &local_err);
+    if (local_err) {
         goto err_out;
     }
 
-    if (handler_is_async(cmd)) {
-        err = ecs_qmp_async_cmd_handler(clii, cmd, args);
-        if (err) {
-            /* emit the error response */
-            goto err_out;
-        }
-    } else {
-        ecs_qmp_call_cmd(clii, mon, type_name, cmd, args);
-    }
+    ecs_qmp_call_cmd(clii, mon, type_name, cmd, args);
 
     goto out;
 
 err_out:
-    ecs_protocol_emitter(clii, NULL, NULL);
+    ecs_protocol_emitter(clii, NULL, NULL, local_err);
 out:
     QDECREF(input);
     QDECREF(args);