Reorganize source tree to use single autotools instance
[vpp.git] / src / tools / g2 / pointsel.c
diff --git a/src/tools/g2/pointsel.c b/src/tools/g2/pointsel.c
new file mode 100644 (file)
index 0000000..018dc21
--- /dev/null
@@ -0,0 +1,854 @@
+/* 
+ *------------------------------------------------------------------
+ * Copyright (c) 2005-2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <ctype.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include "g2.h"
+
+/*
+ * globals
+ */
+event_def_t g_eventdefs[NEVENTS];
+
+/*
+ * locals
+ */
+static GtkWidget *s_pointselbox;
+static FILE *s_hfp;
+static FILE *s_elog_hfp;
+static int s_basenum;
+static GtkWidget *s_event_buttons[NEVENTS];
+static int s_min_shown_pointsel;
+static int s_max_shown_pointsel;
+static GtkWidget *s_allbutton;
+static GtkWidget *s_nonebutton;
+static GtkWidget *s_pointselbuttons;
+static GtkWidget *s_ps_vscroll;
+static GtkObject *s_ps_vsadj;
+static int g_neventdefs;
+
+enum button_click {
+    ALL_BUTTON=1,
+    NONE_BUTTON,
+};
+
+/*
+ * config params
+ */
+int c_maxpointsel;
+
+/****************************************************************************
+* recompute_vscrollbar
+****************************************************************************/
+
+static void recompute_ps_vscrollbar (void)
+{
+    GtkAdjustment *adj;
+    ulong limit;
+
+    adj = GTK_ADJUSTMENT(s_ps_vsadj);
+
+#ifdef NOTDEF
+    /* This seems like the right calculation, but seems not to work */
+    if (g_neventdefs > c_maxpointsel)
+        limit = g_neventdefs - c_maxpointsel;
+    else
+        limit = g_neventdefs;
+#else
+    limit = g_neventdefs-1;
+#endif
+
+    adj->lower = (gfloat)0.00;
+    adj->upper = (gfloat)limit;
+    adj->value = (gfloat)0.00;
+    adj->step_increment = (gfloat)1.00;
+    adj->page_increment = (gfloat)(c_maxpointsel / 3);
+    adj->page_size = (gfloat)c_maxpointsel;
+    gtk_adjustment_changed(adj);
+    gtk_adjustment_value_changed(adj);
+    gtk_widget_show(s_ps_vscroll);
+}
+
+/****************************************************************************
+* point_select_callback
+****************************************************************************/
+
+static void point_select_callback(GtkToggleButton *item, gpointer data)
+{
+    int i = (int) (unsigned long long) data;
+
+    g_eventdefs[i].selected = gtk_toggle_button_get_active(
+        GTK_TOGGLE_BUTTON(s_event_buttons[i]));
+    view1_display_when_idle();
+}
+
+/****************************************************************************
+* up_button
+****************************************************************************/
+
+static void up_button(void)
+{
+    int i;
+    int increment = c_maxpointsel/4;
+
+    if (s_min_shown_pointsel == 0)
+        return;
+
+    s_min_shown_pointsel -= increment;
+
+    if (s_min_shown_pointsel < 0)
+        s_min_shown_pointsel = 0;
+
+    s_max_shown_pointsel = s_min_shown_pointsel + c_maxpointsel;
+
+    for (i = 0; i < g_neventdefs; i++) {
+        if (i >= s_min_shown_pointsel &&
+            i <= s_max_shown_pointsel)
+            gtk_widget_show(s_event_buttons[i]);
+        else
+            gtk_widget_hide(s_event_buttons[i]);
+    }
+
+}
+
+#ifdef NOTDEF
+/****************************************************************************
+* down_button
+****************************************************************************/
+
+static void down_button(void)
+{
+    int i;
+    int increment = c_maxpointsel/4;
+
+    if (s_max_shown_pointsel == g_neventdefs)
+        return;
+
+    s_max_shown_pointsel += increment;
+
+    if (s_max_shown_pointsel >= g_neventdefs)
+        s_max_shown_pointsel = (g_neventdefs-1);
+
+    s_min_shown_pointsel = s_max_shown_pointsel - c_maxpointsel;
+
+    if (s_min_shown_pointsel < 0)
+        s_min_shown_pointsel = 0;
+
+    for (i = 0; i < g_neventdefs; i++) {
+        if (i >= s_min_shown_pointsel &&
+            i <= s_max_shown_pointsel)
+            gtk_widget_show(s_event_buttons[i]);
+        else
+            gtk_widget_hide(s_event_buttons[i]);
+    }
+
+}
+#endif
+
+/****************************************************************************
+* button_click_callback
+****************************************************************************/
+
+static void button_click_callback(GtkButton *item, gpointer data)
+{
+    int i;
+    enum button_click click = (enum button_click)data;
+
+    switch (click) {
+    case ALL_BUTTON:
+        for (i = 0; i < g_neventdefs; i++) {
+            gtk_toggle_button_set_active (
+                GTK_TOGGLE_BUTTON(s_event_buttons[i]), TRUE);
+            g_eventdefs[i].selected = TRUE;
+        }
+        break;
+
+    case NONE_BUTTON:
+        for (i = 0; i < g_neventdefs; i++) {
+            gtk_toggle_button_set_active (
+                GTK_TOGGLE_BUTTON(s_event_buttons[i]), FALSE);
+            g_eventdefs[i].selected = FALSE;
+        }
+        break;
+    }
+}
+
+/****************************************************************************
+* scroll_callback
+****************************************************************************/
+
+static void scroll_callback (GtkAdjustment *adj, GtkWidget *notused)
+{
+    int i;
+
+    s_min_shown_pointsel = (int)adj->value;
+    s_max_shown_pointsel = s_min_shown_pointsel + c_maxpointsel;
+
+    for (i = 0; i < g_neventdefs; i++) {
+        if (i >= s_min_shown_pointsel &&
+            i <= s_max_shown_pointsel)
+            gtk_widget_show(s_event_buttons[i]);
+        else
+            gtk_widget_hide(s_event_buttons[i]);
+    }
+}
+
+/****************************************************************************
+* point_selector_init
+****************************************************************************/
+
+void point_selector_init(void)
+{
+
+    c_maxpointsel = atol(getprop_default("event_selector_lines", "20"));
+
+    s_pointselbox = gtk_vbox_new(FALSE,5);
+
+    s_pointselbuttons = gtk_hbox_new(FALSE,5);
+
+    s_allbutton = gtk_button_new_with_label("ALL");
+    gtk_widget_show(s_allbutton);
+    s_nonebutton = gtk_button_new_with_label("NONE");
+    gtk_widget_show(s_nonebutton);
+
+    gtk_signal_connect (GTK_OBJECT(s_allbutton), "clicked",
+                        GTK_SIGNAL_FUNC(button_click_callback), 
+                        (gpointer) ALL_BUTTON);
+
+    gtk_signal_connect (GTK_OBJECT(s_nonebutton), "clicked",
+                        GTK_SIGNAL_FUNC(button_click_callback), 
+                        (gpointer) NONE_BUTTON);
+
+    gtk_box_pack_start(GTK_BOX(s_pointselbuttons), s_allbutton, FALSE, 
+                       FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(s_pointselbuttons), s_nonebutton, FALSE, 
+                       FALSE, 0);
+    
+    gtk_widget_show(s_pointselbuttons);
+    gtk_widget_ref(s_pointselbuttons); 
+
+    gtk_box_pack_start(GTK_BOX(s_pointselbox), s_pointselbuttons, FALSE, 
+                       FALSE, 0);
+
+    gtk_box_pack_end (GTK_BOX(g_mainhbox), s_pointselbox, 
+                       FALSE, FALSE, 0);
+
+    s_ps_vsadj = gtk_adjustment_new(0.0 /* initial value */, 
+                                    0.0 /* minimum value */,
+                                    2000.0 /* maximum value */,
+                                    0.1 /* step increment */, 
+                                    10.0/* page increment */, 
+                                    10.0/* page size */);
+    
+    s_ps_vscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT(s_ps_vsadj));
+    gtk_signal_connect (GTK_OBJECT (s_ps_vsadj), "value-changed",
+                        GTK_SIGNAL_FUNC (scroll_callback), 
+                        (gpointer)s_ps_vscroll);
+    gtk_box_pack_end(GTK_BOX(g_mainhbox), s_ps_vscroll, FALSE, FALSE, 0);
+}
+
+/****************************************************************************
+* sxerox
+****************************************************************************/
+
+char *sxerox (char *s)
+{
+    char *rv;
+
+    /* Note: g_malloc does or dies... */
+    rv = (char *)g_malloc(strlen(s)+1);
+    strcpy (rv, s);
+    return (rv);
+}
+
+/****************************************************************************
+* reset_point_selector
+****************************************************************************/
+
+static void reset_point_selector(void)
+{
+    int i;
+
+    gtk_widget_hide(s_pointselbox);
+    gtk_widget_hide(s_pointselbuttons);
+    gtk_widget_hide(s_ps_vscroll);
+    gtk_container_remove(GTK_CONTAINER(s_pointselbox), 
+                         s_pointselbuttons);
+    
+    for (i = 0; i < g_neventdefs; i++) {
+        if (s_event_buttons[i]) {
+            gtk_container_remove(GTK_CONTAINER(s_pointselbox), 
+                                 s_event_buttons[i]);
+            s_event_buttons[i] = 0;
+        }
+    }
+}
+
+/****************************************************************************
+* create_point_selector
+****************************************************************************/
+
+static void create_point_selector(void)
+{
+    int i;
+    char tmpbuf [1024];
+    event_def_t *ep;
+    GtkWidget *wp;
+
+    for (i = 0; i < g_neventdefs; i++) {
+        ep = &g_eventdefs[i];
+        sprintf(tmpbuf, "[%lu] %s", ep->event, 
+                ep->name ? ep->name : "(none)");
+        /* Hack to reduce width of point selectors */
+        if (strlen(tmpbuf) > 50) {
+            tmpbuf[50] = 0;
+        }
+
+        wp = gtk_check_button_new_with_label (tmpbuf);
+        s_event_buttons[i] = wp;
+        gtk_signal_connect (GTK_OBJECT(wp), "toggled",
+                            GTK_SIGNAL_FUNC(point_select_callback), 
+                            (gpointer) (unsigned long long) i);
+        gtk_toggle_button_set_active (
+            GTK_TOGGLE_BUTTON(wp), TRUE);
+        gtk_box_pack_start(GTK_BOX(s_pointselbox), wp, FALSE, FALSE, 0);
+    }
+
+    /* set up scroll parameters by faking an up-button */
+    s_min_shown_pointsel = 1;
+    up_button();
+
+    gtk_box_pack_start(GTK_BOX(s_pointselbox), s_pointselbuttons, FALSE, 
+                       FALSE, 0);
+    gtk_widget_show(s_pointselbuttons);
+    gtk_widget_show(s_pointselbox);
+    gtk_widget_show(s_ps_vscroll);
+}
+
+/****************************************************************************
+* remove_all_events
+****************************************************************************/
+
+static void remove_all_events(void)
+{
+    event_def_t *ep;
+    int i;
+
+    for (i = 0; i < g_neventdefs; i++) {
+        ep = &g_eventdefs[i];
+        if (!ep->is_clib) {
+            if (ep->name)
+                g_free(ep->name);
+            if(ep->format)
+                g_free(ep->format);
+        }
+    }
+    g_neventdefs = 0;
+}
+
+/****************************************************************************
+* add_event
+****************************************************************************/
+
+static void add_event(ulong event, char *name, char *format)
+{
+    int i;
+    event_def_t *ep;
+
+    if (g_neventdefs >= NEVENTS) {
+        g_error("Too many event definitions, increase NEVENTS!");
+        /*NOTREACHED*/
+    }
+        
+    /* Simple dup check, probably not needed very often */
+    for (i = 0; i < g_neventdefs; i++) {
+        if (g_eventdefs[i].event == event) {
+            g_warning("Duplicate def event %lu: first definition retained\n",
+                      event);
+            return;
+        }
+    }
+
+    ep = &g_eventdefs[g_neventdefs++];
+
+    ep->event = event;
+    ep->name = sxerox(name);
+    ep->format = sxerox(format);
+    ep->selected = TRUE;
+}
+
+/****************************************************************************
+* add_event_from_cpel_file
+****************************************************************************/
+
+void add_event_from_cpel_file(ulong event, char *event_format, 
+                              char *datum_format)
+{
+    event_def_t *ep;
+
+    if (g_neventdefs >= NEVENTS) {
+        g_error("Too many event definitions, increase NEVENTS!");
+        /*NOTREACHED*/
+    }
+
+    ep = &g_eventdefs[g_neventdefs++];
+
+    ep->event = event;
+    /*
+     * Duplicate the strings for backward compatibility. Otherwise,
+     * the g_free above will barf because the name/format strings are
+     * actually in mmap'ed memory 
+     */
+    ep->name = sxerox(event_format);
+    ep->format = sxerox(datum_format);
+    ep->selected = TRUE;
+}
+
+/****************************************************************************
+* add_event_from_clib_file
+****************************************************************************/
+
+void add_event_from_clib_file(unsigned int event, char *name, 
+                              unsigned int vec_index)
+{
+    event_def_t *ep;
+
+    if (g_neventdefs >= NEVENTS) {
+        g_error("Too many event definitions, increase NEVENTS!");
+        /*NOTREACHED*/
+    }
+
+    ep = &g_eventdefs[g_neventdefs++];
+
+    ep->event = event;
+
+    ep->name = sxerox(name);
+    ep->format = (void *)(unsigned long long) vec_index;
+    ep->selected = TRUE;
+    ep->is_clib = TRUE;
+}
+
+/****************************************************************************
+* read_header_file - eats header file lines of the form
+*
+*     #define EVENT_FOO  123   / * name: %d * /
+*
+****************************************************************************/
+
+static void read_header_file (void)
+{
+    char tmpbuf [1024];
+    char *name, *format;
+    char *cp;
+    unsigned long event;
+    int ev_num_flag;
+
+    while (fgets (tmpbuf, sizeof (tmpbuf), s_hfp))
+    {
+        cp = tmpbuf;
+        ev_num_flag = 0;
+
+        if (strncmp (cp, "#define", 7))
+            continue;
+
+        /* skip #define */
+        while (*cp && !(isspace ((int)*cp)))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        /* skip ws after #define */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+            
+        if (*cp == 0)
+            continue;
+
+        /* skip symbolic name */
+        while (*cp && !(isspace ((int)*cp)))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        /* skip ws after symbolic name */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+            
+        if (*cp == 0)
+            continue;
+
+        event = 0;
+
+        if (!strncmp(cp, "EV_NUM", 6)) {
+            cp += 6;
+            ev_num_flag = 1;
+
+            while (*cp && *cp != '(')
+                cp++;
+            
+            if (*cp == 0)
+                continue;
+
+            cp++; 
+
+            while (*cp && isspace ((int)*cp))
+                cp++;
+            
+        } 
+
+        /* eat event code. */
+        while (*cp && isdigit ((int)*cp))
+        {
+            event = event * 10 + (*cp - '0');
+            cp++;
+        }
+
+        if (*cp == 0)
+            continue;
+
+        if (ev_num_flag) {
+            while (*cp && *cp != ')')
+                cp++;
+            if (*cp == 0)
+                continue;
+            cp++;
+            event += s_basenum;
+        }
+
+        /* skip ws after event code */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+            
+        if (*cp != '/')
+            continue;
+
+        cp++;
+
+        if (*cp != '*')
+            continue;
+
+        cp++;
+
+        /* skip ws after comment start */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        name = cp;
+
+        /* accumulate name */
+        while (*cp && *cp != ':' && *cp != '*')
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        *cp++ = 0;
+        
+        /* skip ws after name: */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+        
+        if (*cp == 0 || *cp == '/')
+        {
+            format = " ";
+            goto write_it;
+        }
+
+        format = cp;
+        
+        /* accumulate format string */
+        while (*cp && !isspace ((int)*cp))
+            cp++;
+
+        *cp = 0;
+
+    write_it:
+
+        add_event (event, name, format);
+    }
+}
+
+/****************************************************************************
+* read_header_files - eats header file lines of the form
+*
+*     #define FILE1_BASE  100  / * pointdefs: ../vpn/vpn_points.h * /
+*
+****************************************************************************/
+
+static boolean read_header_files (void)
+{
+    char *cp, *name;
+    char tmpbuf [1024];
+    int basenum;
+    boolean rv=FALSE;
+
+    while (fgets (tmpbuf, sizeof (tmpbuf), s_elog_hfp))
+    {
+        cp = tmpbuf;
+
+        if (strncmp (cp, "#define", 7))
+            continue;
+
+        cp += 7;
+
+        /* skip ws after #define */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        /* skip EV_COMPxxx_START */
+        while (*cp && !isspace((int)*cp))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        /* skip ws after EV_COMPxxx_START */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+        
+        if (*cp == 0)
+            continue;
+        
+        basenum = atol (cp);
+        
+        /* skip #define */
+        while (*cp && (*cp != '/'))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        cp++;
+        if (*cp != '*')
+            continue;
+
+        cp++;
+
+        /* skip ws after comment start */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+
+        if (*cp == 0)
+            continue;
+
+        if (strncmp (cp, "pointdefs:", 10))
+            continue;
+
+        cp += 10;
+
+        /* skip ws after comment start */
+        while (*cp && isspace ((int)*cp))
+            cp++;
+
+        name = cp;
+
+        while (*cp && !isspace ((int)*cp))
+            cp++;
+       
+        *cp = 0;
+
+        s_hfp = fopen (name, "rt");
+
+        if (s_hfp == NULL) {
+            g_warning ("Couldn't open header file %s\n", name);
+            continue;
+        }
+        rv = TRUE;
+
+        s_basenum = basenum;
+
+        read_header_file();
+
+        fclose (s_hfp);
+    }
+    return(rv);
+}
+
+/****************************************************************************
+* event_def_cmp
+****************************************************************************/
+
+int event_def_cmp(const void *a1, const void *a2)
+{
+    event_def_t *e1 = (event_def_t *)a1;
+    event_def_t *e2 = (event_def_t *)a2;
+
+    if (e1->event < e2->event)
+        return(-1);
+    else if (e1->event == e2->event)
+        return(0);
+    else
+        return(1);
+}
+
+/****************************************************************************
+* sort_event_definitions
+****************************************************************************/
+
+void sort_event_definitions(void)
+{
+    qsort(&g_eventdefs[0], g_neventdefs, sizeof(event_def_t), event_def_cmp);
+}
+
+static boolean remove_needed=TRUE;
+
+void finalize_events(void)
+{
+    sort_event_definitions();
+    create_point_selector();
+    recompute_ps_vscrollbar();
+    view1_display_when_idle();
+    remove_needed = TRUE;
+}
+
+void initialize_events(void)
+{
+    if (remove_needed) {
+        reset_point_selector();
+        remove_all_events();
+        remove_needed = FALSE;
+    }
+}
+
+/****************************************************************************
+* read_event_definitions
+****************************************************************************/
+
+boolean read_event_definitions (char *filename)
+{
+    char tmpbuf [128];
+
+    initialize_events();
+
+    s_elog_hfp = fopen (filename, "rt");
+    if (s_elog_hfp == NULL) {
+        sprintf (tmpbuf, "Couldn't open %s\n", filename);
+        infobox ("Open Failed", tmpbuf);
+        return(FALSE);
+    }
+    /* Presume "elog.h".  Note fallthrough... */
+    if (read_header_files()) {
+        sort_event_definitions();
+        create_point_selector();
+        recompute_ps_vscrollbar();
+        fclose(s_elog_hfp);
+        view1_display_when_idle();
+        remove_needed = TRUE;
+        return(TRUE);
+    }
+    fclose(s_elog_hfp);
+
+    s_hfp = fopen (filename, "rt");
+    if (s_hfp == NULL) {
+        sprintf (tmpbuf, "Couldn't open %s\n", filename);
+        infobox ("Read Event Definition Failure", tmpbuf);
+        return(FALSE);
+    }
+
+    read_header_file();
+
+    /* Happens if the user feeds us the wrong file, for example */
+    if (g_neventdefs == 0) {
+        sprintf (tmpbuf, "No event definitions found in %s\n", filename);
+        infobox ("No Event Definitions?", tmpbuf);
+        return(FALSE);
+    }
+    finalize_events();
+    return(TRUE);
+}
+
+static event_def_t dummy_event;
+static char dummy_string[32];
+
+/****************************************************************************
+* find_event_definition
+* Binary search for first event whose time is >= t
+****************************************************************************/
+
+event_def_t *find_event_definition (ulong code)
+{
+    int index, bottom, top;
+    event_def_t *edp;
+
+    if (g_neventdefs == 0)
+        goto use_dummy;
+
+    bottom = g_neventdefs-1;
+    top = 0;
+
+    while (1) {
+       index = (bottom + top) / 2;
+
+        edp = (g_eventdefs + index);
+        
+        if (edp->event == code)
+            return(edp);
+
+        if (top >= bottom) {
+        use_dummy:
+            edp = &dummy_event;
+            edp->selected = TRUE;
+            edp->event = code;
+            edp->format = "0x%x";
+            sprintf (dummy_string, "E%lu", code);
+            edp->name = &dummy_string[0];
+            return(edp);
+        }
+
+        if (edp->event < code)
+            top = index + 1;
+        else 
+            bottom = index - 1;
+    }
+}
+
+/****************************************************************************
+* pointsel_next_snapshot
+* Set dialog buttons from snapshot
+****************************************************************************/
+
+void pointsel_next_snapshot(void)
+{
+    int i;
+    
+    for (i = 0; i < g_neventdefs; i++) {
+        gtk_toggle_button_set_active (
+            GTK_TOGGLE_BUTTON(s_event_buttons[i]), 
+            g_eventdefs[i].selected);
+    }
+}
+
+/****************************************************************************
+* pointsel_about
+****************************************************************************/
+
+void pointsel_about (char *tmpbuf)
+{
+    sprintf (tmpbuf+strlen(tmpbuf), "%d event definitions\n", 
+             g_neventdefs);
+}