2 * Routines to register UI information for stats
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/stat_tap_ui.h>
33 /* structure to keep track of what stats have registered command-line
36 typedef struct _stat_cmd_arg {
39 void (*func)(const char *arg, void* userdata);
43 static wmem_list_t *stat_cmd_arg_list=NULL;
45 /* structure to keep track of what stats have been specified on the
52 static GSList *stats_requested = NULL;
54 /* **********************************************************************
55 * Function called from stat to register the stat's command-line argument
56 * and initialization routine
57 * ********************************************************************** */
59 search_duplicate(gconstpointer a, gconstpointer b)
61 return strcmp(((const stat_cmd_arg *)a)->cmd, (const char *)b);
65 sort_by_name(gconstpointer a, gconstpointer b)
67 return strcmp(((const stat_cmd_arg *)a)->cmd, ((const stat_cmd_arg *)b)->cmd);
71 register_stat_tap_ui(stat_tap_ui *ui, void *userdata)
75 if (stat_cmd_arg_list == NULL)
76 stat_cmd_arg_list = wmem_list_new(wmem_epan_scope());
78 /* Key is already present */
79 if (wmem_list_find_custom(stat_cmd_arg_list, ui->cli_string, search_duplicate))
82 newsca = wmem_new(wmem_epan_scope(), stat_cmd_arg);
83 newsca->cmd= wmem_strdup(wmem_epan_scope(), ui->cli_string);
84 newsca->func=ui->tap_init_cb;
85 newsca->userdata=userdata;
87 wmem_list_insert_sorted(stat_cmd_arg_list, newsca, sort_by_name);
90 /* **********************************************************************
91 * Function called for a stat command-line argument
92 * ********************************************************************** */
94 process_stat_cmd_arg(char *optstr)
96 wmem_list_frame_t *entry;
100 /* The strings "ipx" or "ipv6" must be tested before "ip" to select the
101 right tap so the sorting does matter. And it's also why the list is
103 for (entry = wmem_list_tail(stat_cmd_arg_list); entry; entry = wmem_list_frame_prev(entry)) {
104 sca = (stat_cmd_arg*)wmem_list_frame_data(entry);
105 if(!strncmp(sca->cmd, optstr, strlen(sca->cmd))) {
106 tr=(stat_requested *)g_malloc(sizeof (stat_requested));
108 tr->arg=g_strdup(optstr);
109 stats_requested = g_slist_append(stats_requested, tr);
116 /* **********************************************************************
117 * Function to list all possible tap command-line arguments
118 * ********************************************************************** */
120 list_stat_cmd_args_func(gpointer data, gpointer userdata _U_)
122 fprintf(stderr," %s\n", ((stat_cmd_arg*)data)->cmd);
126 list_stat_cmd_args(void)
128 wmem_list_foreach(stat_cmd_arg_list, list_stat_cmd_args_func, NULL);
131 /* **********************************************************************
132 * Function to process stats requested with command-line arguments
133 * ********************************************************************** */
135 start_requested_stats(void)
139 while(stats_requested){
140 sr=(stat_requested *)stats_requested->data;
141 (*sr->sca->func)(sr->arg,sr->sca->userdata);
142 stats_requested=g_slist_remove(stats_requested, sr);
148 static wmem_tree_t *registered_stat_tables = NULL;
150 void register_stat_tap_table_ui(stat_tap_table_ui *ui)
152 if (registered_stat_tables == NULL)
153 registered_stat_tables = wmem_tree_new(wmem_epan_scope());
155 wmem_tree_insert_string(registered_stat_tables, ui->cli_string, ui, 0);
158 stat_tap_table_ui *new_stat_tap_by_name(const char *name)
160 return (stat_tap_table_ui *) wmem_tree_lookup_string(registered_stat_tables, name, 0);
163 void new_stat_tap_iterate_tables(wmem_foreach_func func, gpointer user_data)
165 wmem_tree_foreach(registered_stat_tables, func, user_data);
168 void new_stat_tap_get_filter(stat_tap_table_ui* new_stat, const char *opt_arg, const char **filter, char** err)
170 guint len = (guint) strlen(new_stat->cli_string);
174 if (!strncmp(opt_arg, new_stat->cli_string, len))
176 if (opt_arg[len] == ',')
178 *filter = opt_arg + len+1;
182 if (new_stat->stat_filter_check_cb)
183 new_stat->stat_filter_check_cb(opt_arg, filter, err);
186 stat_tap_table* new_stat_tap_init_table(const char *name, int num_fields, int num_elements,
187 const char *filter_string, new_stat_tap_gui_init_cb gui_callback, void* gui_data)
189 stat_tap_table* new_table = g_new0(stat_tap_table, 1);
191 new_table->title = name;
192 new_table->num_elements = num_elements;
193 new_table->num_fields = num_fields;
194 new_table->filter_string = filter_string;
195 new_table->elements = g_new0(stat_tap_table_item_type*, num_elements);
198 gui_callback(new_table, gui_data);
203 void new_stat_tap_add_table(stat_tap_table_ui* new_stat, stat_tap_table* table)
205 if (new_stat->tables == NULL)
206 new_stat->tables = g_array_new(FALSE, TRUE, sizeof(stat_tap_table*));
208 g_array_insert_val(new_stat->tables, new_stat->tables->len, table);
211 void new_stat_tap_init_table_row(stat_tap_table *stat_table, guint table_index, guint num_fields, const stat_tap_table_item_type* fields)
213 /* we have discovered a new procedure. Extend the table accordingly */
214 if(table_index>=stat_table->num_elements){
215 guint old_num_elements=stat_table->num_elements;
218 stat_table->num_elements=table_index+1;
219 stat_table->elements = (stat_tap_table_item_type**)g_realloc(stat_table->elements, sizeof(stat_tap_table_item_type*)*(stat_table->num_elements));
220 for(i=old_num_elements;i<stat_table->num_elements;i++){
221 stat_table->elements[i] = g_new0(stat_tap_table_item_type, stat_table->num_fields);
224 memcpy(stat_table->elements[table_index], fields, num_fields*sizeof(stat_tap_table_item_type));
228 stat_tap_table_item_type* new_stat_tap_get_field_data(const stat_tap_table *stat_table, guint table_index, guint field_index)
230 stat_tap_table_item_type* field_value;
231 g_assert(table_index < stat_table->num_elements);
233 field_value = stat_table->elements[table_index];
235 g_assert(field_index < stat_table->num_fields);
237 return &field_value[field_index];
240 void new_stat_tap_set_field_data(stat_tap_table *stat_table, guint table_index, guint field_index, stat_tap_table_item_type* field_data)
242 stat_tap_table_item_type* field_value;
243 g_assert(table_index < stat_table->num_elements);
245 field_value = stat_table->elements[table_index];
247 g_assert(field_index < stat_table->num_fields);
249 field_value[field_index] = *field_data;
252 void reset_stat_table(stat_tap_table_ui* new_stat, new_stat_tap_gui_reset_cb gui_callback, void *callback_data)
255 stat_tap_table *stat_table;
257 for (i = 0; i < new_stat->tables->len; i++)
259 stat_table = g_array_index(new_stat->tables, stat_tap_table*, i);
261 /* Give GUI the first crack at it before we clean up */
263 gui_callback(stat_table, callback_data);
265 if (new_stat->stat_tap_reset_table_cb)
266 new_stat->stat_tap_reset_table_cb(stat_table);
270 void free_stat_tables(stat_tap_table_ui* new_stat, new_stat_tap_gui_free_cb gui_callback, void *callback_data)
272 guint i = 0, element, field_index;
273 stat_tap_table *stat_table;
274 stat_tap_table_item_type* field_data;
276 for (i = 0; i < new_stat->tables->len; i++)
278 stat_table = g_array_index(new_stat->tables, stat_tap_table*, i);
280 /* Give GUI the first crack at it before we clean up */
282 gui_callback(stat_table, callback_data);
284 for (element = 0; element < stat_table->num_elements; element++)
286 for (field_index = 0; field_index < stat_table->num_fields; field_index++)
288 field_data = new_stat_tap_get_field_data(stat_table, element, field_index);
289 /* Give dissector a crack at it */
290 /* XXX Should this be per-row instead? */
291 if (new_stat->stat_tap_free_table_item_cb)
292 new_stat->stat_tap_free_table_item_cb(stat_table, element, field_index, field_data);
294 g_free(stat_table->elements[element]);
296 g_free(stat_table->elements);
299 g_array_set_size(new_stat->tables, 0);
309 * indent-tabs-mode: nil
312 * ex: set shiftwidth=4 tabstop=8 expandtab:
313 * :indentSize=4:tabSize=8:noTabs=true: