From 0bd5e3a4d02231148eb3159667fde9544f332cb1 Mon Sep 17 00:00:00 2001
From: winckel <winckel@eurecom.fr>
Date: Mon, 25 Nov 2013 09:56:12 +0000
Subject: [PATCH] Added error strings for return code. Added a function to free
 previous message definitions. Added some asserts. fixed a warning issue.
 Added an error notification when message definitions parse failed.

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4507 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 common/utils/itti_analyzer/common/rc.h        | 31 +++----
 .../utils/itti_analyzer/libparser/xml_parse.c | 82 ++++++++++++++-----
 .../itti_analyzer/libresolver/locate_root.c   | 29 ++++---
 .../utils/itti_analyzer/libui/ui_callbacks.c  |  5 +-
 .../utils/itti_analyzer/libui/ui_notebook.c   |  4 +-
 .../itti_analyzer/libui/ui_notifications.c    | 67 ++++++++-------
 6 files changed, 142 insertions(+), 76 deletions(-)

diff --git a/common/utils/itti_analyzer/common/rc.h b/common/utils/itti_analyzer/common/rc.h
index 174f725c11..ff72228fc7 100644
--- a/common/utils/itti_analyzer/common/rc.h
+++ b/common/utils/itti_analyzer/common/rc.h
@@ -9,13 +9,16 @@
 #define RC_BAD_PARAM    -2
 #define RC_NULL_POINTER -3
 
-#define CHECK_FCT(fCT)      \
-do {                        \
-    int rET;                \
+static const char * const rc_strings[] =
+    {"Ok", "fail", "bad parameter", "null pointer"};
+
+#define CHECK_FCT(fCT)              \
+do {                                \
+    int rET;                        \
     if ((rET = fCT) != RC_OK) {     \
         fprintf(stderr, #fCT" has failed (%s:%d)\n", __FILE__, __LINE__);   \
-        return rET;         \
-    }                       \
+        return rET;                 \
+    }                               \
 } while(0)
 
 #define CHECK_FCT_POSIX(fCT)        \
@@ -23,25 +26,25 @@ do {                                \
     if (fCT == -1) {                \
         fprintf(stderr, #fCT" has failed (%d:%s) (%s:%d)\n", errno, \
                 strerror(errno), __FILE__, __LINE__);               \
-        return RC_FAIL;         \
-    }                           \
+        return RC_FAIL;             \
+    }                               \
 } while(0)
 
-#define CHECK_FCT_DO(fCT, dO)      \
-do {                        \
-    int rET;                \
+#define CHECK_FCT_DO(fCT, dO)       \
+do {                                \
+    int rET;                        \
     if ((rET = fCT) != RC_OK) {     \
         fprintf(stderr, #fCT" has returned %d (%s:%d)\n", rET, __FILE__, __LINE__);   \
-        dO;                 \
-    }                       \
+        dO;                         \
+    }                               \
 } while(0)
 
 #define CHECK_BUFFER(bUFFER)        \
 do {                                \
     if ((bUFFER) == NULL) {         \
         fprintf(stderr, #bUFFER" is NULL (%s:%d)\n", __FILE__, __LINE__);   \
-        return RC_NULL_POINTER;         \
-    }                       \
+        return RC_NULL_POINTER;     \
+    }                               \
 } while(0)
 
 #endif /* RC_H_ */
diff --git a/common/utils/itti_analyzer/libparser/xml_parse.c b/common/utils/itti_analyzer/libparser/xml_parse.c
index 5d5e622ab2..fcea5210e7 100644
--- a/common/utils/itti_analyzer/libparser/xml_parse.c
+++ b/common/utils/itti_analyzer/libparser/xml_parse.c
@@ -8,6 +8,7 @@
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 
+#include "logs.h"
 #include "types.h"
 #include "xml_parse.h"
 #include "union_type.h"
@@ -28,7 +29,8 @@ extern int debug_parser;
 # define INDENT_START 0
 #endif
 
-types_t *root = NULL;
+types_t *xml_head;
+types_t *root;
 
 static int xml_parse_doc(xmlDocPtr doc);
 
@@ -647,14 +649,53 @@ static int parse_elements(xmlNode * a_node, types_t **head) {
     return RC_OK;
 }
 
+static int free_elements(types_t *parent, int indent) {
+    types_t *cur_node = parent;
+    types_t *child_node;
+
+    g_debug("%*s%p %s", indent, "", cur_node, cur_node->name != NULL ? cur_node->name : "");
+
+    for (; cur_node != NULL; cur_node = cur_node->next) {
+        if (cur_node->child != NULL) {
+            child_node = cur_node->child;
+            cur_node->child = NULL; /* Clear the child pointer to avoid re-processing it, we are handling a graph with loops */
+            CHECK_FCT_DO(free_elements((child_node), indent + 2), return RC_FAIL);
+        }
+    }
+    free (cur_node);
+
+    return RC_OK;
+}
+
 int xml_parse_buffer(const char *xml_buffer, const int size) {
     xmlDocPtr doc; /* the resulting document tree */
 
     if (xml_buffer == NULL) {
-        return -1;
+        return RC_NULL_POINTER;
+    }
+
+    if (xml_head != NULL)
+    {
+        /* Free previous definitions */
+        free_elements(xml_head, 0);
+
+        g_info("xml_parse_buffer freed previous definitions");
     }
 
-    g_debug("Parsing XML definition from buffer ...");
+    xml_head = NULL;
+    root = NULL;
+    messages_id_enum = NULL;
+    lte_time_type = NULL;
+    lte_time_frame_type = NULL;
+    lte_time_slot_type = NULL;
+    origin_task_id_type = NULL;
+    destination_task_id_type = NULL;
+    instance_type = NULL;
+    message_header_type = NULL;
+    message_type = NULL;
+    message_size_type = NULL;
+
+    g_info("Parsing XML definition from buffer ...");
 
     doc = xmlReadMemory(xml_buffer, size, NULL, NULL, 0);
 
@@ -667,11 +708,12 @@ int xml_parse_buffer(const char *xml_buffer, const int size) {
     return xml_parse_doc(doc);
 }
 
+#if 0 /* Not used anymore */
 int xml_parse_file(const char *filename) {
     xmlDocPtr doc; /* the resulting document tree */
 
     if (filename == NULL) {
-        return -1;
+        return RC_NULL_POINTER;
     }
 
     doc = xmlReadFile (filename, NULL, 0);
@@ -683,6 +725,7 @@ int xml_parse_file(const char *filename) {
 
     return xml_parse_doc(doc);
 }
+#endif
 
 static int update_filters() {
     types_t *types;
@@ -737,7 +780,6 @@ static int update_filters() {
 
 static int xml_parse_doc(xmlDocPtr doc) {
     xmlNode *root_element = NULL;
-    types_t *head = NULL;
     int ret = 0;
     FILE *dissect_file = NULL;
 
@@ -748,39 +790,39 @@ static int xml_parse_doc(xmlDocPtr doc) {
     /* Get the root element node */
     root_element = xmlDocGetRootElement(doc);
 
-    ret = parse_elements(root_element, &head);
+    ret = parse_elements(root_element, &xml_head);
 
     /* Free the document */
     xmlFreeDoc(doc);
 
     if (ret == RC_OK) {
-        resolve_typedefs (&head);
-        resolve_pointer_type (&head);
-        resolve_field (&head);
-        resolve_array (&head);
-        resolve_reference (&head);
-        resolve_struct (&head);
-        resolve_file (&head);
-        resolve_union (&head);
-        resolve_function (&head);
+        resolve_typedefs (&xml_head);
+        resolve_pointer_type (&xml_head);
+        resolve_field (&xml_head);
+        resolve_array (&xml_head);
+        resolve_reference (&xml_head);
+        resolve_struct (&xml_head);
+        resolve_file (&xml_head);
+        resolve_union (&xml_head);
+        resolve_function (&xml_head);
 
         /* Locate the root element which corresponds to the MessageDef struct */
-        CHECK_FCT(locate_root("MessageDef", head, &root));
+        CHECK_FCT(locate_root("MessageDef", xml_head, &root));
 
         /* Locate the LTE time fields */
-        if (locate_type("lte_time", head, &lte_time_type) == RC_OK)
+        if (locate_type("lte_time", xml_head, &lte_time_type) == RC_OK)
         {
             CHECK_FCT(locate_type("frame", lte_time_type->child->child, &lte_time_frame_type));
             CHECK_FCT(locate_type("slot", lte_time_type->child->child, &lte_time_slot_type));
         }
 
         /* Locate the message id field */
-        CHECK_FCT(locate_type("MessagesIds", head, &messages_id_enum));
+        CHECK_FCT(locate_type("MessagesIds", xml_head, &messages_id_enum));
 
         /* Locate the header part of a message */
-        CHECK_FCT(locate_type("ittiMsgHeader", head, &message_header_type));
+        CHECK_FCT(locate_type("ittiMsgHeader", xml_head, &message_header_type));
         /* Locate the main message part */
-        CHECK_FCT(locate_type("ittiMsg", head, &message_type));
+        CHECK_FCT(locate_type("ittiMsg", xml_head, &message_type));
 
         /* Locate the origin task id field */
         CHECK_FCT(locate_type("originTaskId", message_header_type, &origin_task_id_type));
diff --git a/common/utils/itti_analyzer/libresolver/locate_root.c b/common/utils/itti_analyzer/libresolver/locate_root.c
index 1d450c4281..7bec706f61 100644
--- a/common/utils/itti_analyzer/libresolver/locate_root.c
+++ b/common/utils/itti_analyzer/libresolver/locate_root.c
@@ -5,6 +5,7 @@
 
 #include <glib.h>
 
+#include "logs.h"
 #include "rc.h"
 
 #include "types.h"
@@ -12,19 +13,20 @@
 #include "locate_root.h"
 #include "xml_parse.h"
 
-types_t *messages_id_enum = NULL;
-types_t *lte_time_type = NULL;
-types_t *lte_time_frame_type = NULL;
-types_t *lte_time_slot_type = NULL;
-types_t *origin_task_id_type = NULL;
-types_t *destination_task_id_type = NULL;
-types_t *instance_type = NULL;
-types_t *message_header_type = NULL;
-types_t *message_type = NULL;
-types_t *message_size_type = NULL;
+types_t *messages_id_enum;
+types_t *lte_time_type;
+types_t *lte_time_frame_type;
+types_t *lte_time_slot_type;
+types_t *origin_task_id_type;
+types_t *destination_task_id_type;
+types_t *instance_type;
+types_t *message_header_type;
+types_t *message_type;
+types_t *message_size_type;
 
 int locate_root(const char *root_name, types_t *head, types_t **root_elm) {
     types_t *next_type;
+    int next_counter = 0;
 
     /* The root element is for example : MessageDef.
      * This element is the entry for other sub-types.
@@ -49,13 +51,17 @@ int locate_root(const char *root_name, types_t *head, types_t **root_elm) {
             /* Matching reference */
             break;
         }
+        next_counter ++;
     }
+    g_info("locate_root: %s %d", root_name, next_counter);
+
     *root_elm = next_type;
     return (next_type == NULL) ? -2 : 0;
 }
 
 int locate_type(const char *type_name, types_t *head, types_t **type) {
     types_t *next_type;
+    int next_counter = 0;
 
     /* The root element is for example : MessageDef.
      * This element is the entry for other sub-types.
@@ -76,7 +82,10 @@ int locate_type(const char *type_name, types_t *head, types_t **type) {
             /* Matching reference */
             break;
         }
+        next_counter ++;
     }
+    g_info("locate_type: %s %d", type_name, next_counter);
+
     if (type)
         *type = next_type;
     return (next_type == NULL) ? RC_FAIL : RC_OK;
diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.c b/common/utils/itti_analyzer/libui/ui_callbacks.c
index 67ce26d07e..2d8e75e18c 100644
--- a/common/utils/itti_analyzer/libui/ui_callbacks.c
+++ b/common/utils/itti_analyzer/libui/ui_callbacks.c
@@ -390,9 +390,12 @@ void ui_signal_add_to_list(gpointer data, gpointer user_data)
     uint32_t origin_task_id;
     uint32_t destination_task_id;
     uint32_t instance;
-
     char lte_time[15];
 
+    g_assert(data != NULL);
+    g_assert(origin_task_id_type != NULL);
+    g_assert(destination_task_id_type != NULL);
+
     gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), &path, &focus_column);
 
     signal_buffer = (buffer_t *) data;
diff --git a/common/utils/itti_analyzer/libui/ui_notebook.c b/common/utils/itti_analyzer/libui/ui_notebook.c
index 8a293f7041..cf664cc6e5 100644
--- a/common/utils/itti_analyzer/libui/ui_notebook.c
+++ b/common/utils/itti_analyzer/libui/ui_notebook.c
@@ -4,10 +4,10 @@
 
 #include <stdio.h>
 #include <stdint.h>
-#include <gtk/gtk.h>
-
 #define G_LOG_DOMAIN ("UI")
 
+#include <gtk/gtk.h>
+
 #include "rc.h"
 
 #include "ui_notebook.h"
diff --git a/common/utils/itti_analyzer/libui/ui_notifications.c b/common/utils/itti_analyzer/libui/ui_notifications.c
index dfa188a33f..40c12ab183 100644
--- a/common/utils/itti_analyzer/libui/ui_notifications.c
+++ b/common/utils/itti_analyzer/libui/ui_notifications.c
@@ -96,11 +96,10 @@ int ui_messages_read(char *filename)
         int size;
         double read_fraction = 0.f;
 
-        if (stat(filename, &st) < 0) {
+        if (stat (filename, &st) < 0)
+        {
             ui_notification_dialog (GTK_MESSAGE_ERROR, "get file length",
-                                    "Failed to retrieve length for file \"%s\": %s",
-                                    filename,
-                                    g_strerror (errno));
+                                    "Failed to retrieve length for file \"%s\": %s", filename, g_strerror (errno));
             result = RC_FAIL;
         }
         size = st.st_size;
@@ -109,7 +108,7 @@ int ui_messages_read(char *filename)
         ui_main_data.follow_last = TRUE;
 
         /* Initialize the progress bar */
-        ui_progress_bar_set_fraction(0);
+        ui_progress_bar_set_fraction (0);
 
         do
         {
@@ -125,11 +124,11 @@ int ui_messages_read(char *filename)
 
             if (read_data > 0)
             {
-                read_fraction += (double)read_data / size;
+                read_fraction += (double) read_data / size;
 
                 input_data_length = message_header.message_size - sizeof(itti_socket_header_t);
 
-                g_debug ("%x, %x, %zd", message_header.message_type, message_header.message_size, input_data_length);
+                g_debug("%x, %x, %zd", message_header.message_type, message_header.message_size, input_data_length);
 
                 /* Checking for non-header part */
                 if (input_data_length > 0)
@@ -145,7 +144,7 @@ int ui_messages_read(char *filename)
                         break;
                     }
 
-                    read_fraction += (double)input_data_length / size;
+                    read_fraction += (double) input_data_length / size;
                 }
 
                 switch (message_header.message_type)
@@ -165,11 +164,11 @@ int ui_messages_read(char *filename)
 
                         buffer->message_number = itti_signal_header->message_number;
 
-                        ui_signal_add_to_list (buffer, ((read_messages % 100) == 0) ? (gpointer) 1: NULL);
+                        ui_signal_add_to_list (buffer, ((read_messages % 100) == 0) ? (gpointer) 1 : NULL);
 
                         if ((read_messages % 100) == 0)
                         {
-                            ui_progress_bar_set_fraction(read_fraction);
+                            ui_progress_bar_set_fraction (read_fraction);
                             ui_gtk_flush_events ();
                         }
 
@@ -179,14 +178,21 @@ int ui_messages_read(char *filename)
 
                     case ITTI_DUMP_XML_DEFINITION:
                         ui_gtk_flush_events ();
-                        xml_parse_buffer (input_data, input_data_length);
+                        result = xml_parse_buffer (input_data, input_data_length);
+                        if (result != RC_OK)
+                        {
+                            ui_notification_dialog (GTK_MESSAGE_ERROR, "open messages",
+                                                    "Error in parsing XML definitions in file \"%s\": %s", filename,
+                                                    rc_strings[-result]);
+                            read_data = 0;
+                        }
                         ui_gtk_flush_events ();
                         break;
 
                     case ITTI_STATISTIC_MESSAGE_TYPE:
                     default:
                         ui_notification_dialog (GTK_MESSAGE_WARNING, "open messages",
-                                                "Unknown (or not implemented) record type %d in file \"%s\"",
+                                                "Unknown (or not implemented) record type: %d in file \"%s\"",
                                                 message_header.message_type, filename);
                         break;
                 }
@@ -205,16 +211,17 @@ int ui_messages_read(char *filename)
             if (ui_main_data.follow_last)
             {
                 /* Advance to the last signal */
-                ui_tree_view_select_row (ui_tree_view_get_filtered_number() - 1);
+                ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1);
             }
 
-            basename = g_path_get_basename(filename);
+            basename = g_path_get_basename (filename);
             ui_set_title ("\"%s\"", basename);
         }
 
-        ui_progress_bar_terminate();
+        ui_progress_bar_terminate ();
 
-        g_message("Read %d messages (%d to display) from file \"%s\"\n", read_messages, ui_tree_view_get_filtered_number(), filename);
+        g_message(
+                "Read %d messages (%d to display) from file \"%s\"\n", read_messages, ui_tree_view_get_filtered_number(), filename);
 
         close (source);
     }
@@ -353,23 +360,23 @@ int ui_filters_save_file_chooser(void)
 int ui_progress_bar_set_fraction(double fraction)
 {
     /* If not exist instantiate */
-    if (!ui_main_data.progressbar && !ui_main_data.progressbar_window) {
+    if (!ui_main_data.progressbar && !ui_main_data.progressbar_window)
+    {
         ui_main_data.progressbar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
         /* Set the window at center of window */
-        gtk_window_set_position(GTK_WINDOW(ui_main_data.progressbar_window), GTK_WIN_POS_CENTER);
-        gtk_window_set_title(GTK_WINDOW(ui_main_data.progressbar_window), "Processing");
+        gtk_window_set_position (GTK_WINDOW(ui_main_data.progressbar_window), GTK_WIN_POS_CENTER);
+        gtk_window_set_title (GTK_WINDOW(ui_main_data.progressbar_window), "Processing");
 
-        gtk_container_set_border_width(GTK_CONTAINER (ui_main_data.progressbar_window), 10);
+        gtk_container_set_border_width (GTK_CONTAINER (ui_main_data.progressbar_window), 10);
 
-        ui_main_data.progressbar = gtk_progress_bar_new();
+        ui_main_data.progressbar = gtk_progress_bar_new ();
 
-        gtk_container_add (GTK_CONTAINER (ui_main_data.progressbar_window),
-                           ui_main_data.progressbar);
+        gtk_container_add (GTK_CONTAINER (ui_main_data.progressbar_window), ui_main_data.progressbar);
         gtk_widget_show_all (ui_main_data.progressbar_window);
     }
 
-    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ui_main_data.progressbar), fraction);
+    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(ui_main_data.progressbar), fraction);
 
 //     ui_gtk_flush_events();
 
@@ -378,14 +385,16 @@ int ui_progress_bar_set_fraction(double fraction)
 
 int ui_progress_bar_terminate(void)
 {
-    if (ui_main_data.progressbar) {
-        gtk_widget_destroy(ui_main_data.progressbar);
+    if (ui_main_data.progressbar)
+    {
+        gtk_widget_destroy (ui_main_data.progressbar);
     }
-    if (ui_main_data.progressbar_window) {
-        gtk_widget_destroy(ui_main_data.progressbar_window);
+    if (ui_main_data.progressbar_window)
+    {
+        gtk_widget_destroy (ui_main_data.progressbar_window);
     }
 
-    ui_main_data.progressbar        = NULL;
+    ui_main_data.progressbar = NULL;
     ui_main_data.progressbar_window = NULL;
 
     return RC_OK;
-- 
GitLab