diff options
| -rw-r--r-- | kernel-shark.c | 29 | ||||
| -rw-r--r-- | parse-events.h | 2 | ||||
| -rw-r--r-- | parse-filter.c | 57 |
3 files changed, 83 insertions, 5 deletions
diff --git a/kernel-shark.c b/kernel-shark.c index 3a0d0fb..9ca3942 100644 --- a/kernel-shark.c +++ b/kernel-shark.c | |||
| @@ -311,9 +311,12 @@ load_filters_clicked (gpointer data) | |||
| 311 | struct shark_info *info = data; | 311 | struct shark_info *info = data; |
| 312 | struct graph_info *ginfo = info->ginfo; | 312 | struct graph_info *ginfo = info->ginfo; |
| 313 | GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview); | 313 | GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview); |
| 314 | GtkTreeModel *model; | ||
| 315 | TraceViewStore *store; | ||
| 314 | struct tracecmd_xml_handle *handle; | 316 | struct tracecmd_xml_handle *handle; |
| 315 | struct filter_task *task_filter; | 317 | struct filter_task *task_filter; |
| 316 | struct filter_task *hide_tasks; | 318 | struct filter_task *hide_tasks; |
| 319 | struct event_filter *event_filter; | ||
| 317 | gchar *filename; | 320 | gchar *filename; |
| 318 | int ret; | 321 | int ret; |
| 319 | 322 | ||
| @@ -349,7 +352,6 @@ load_filters_clicked (gpointer data) | |||
| 349 | ret = tracecmd_xml_system_exists(handle, | 352 | ret = tracecmd_xml_system_exists(handle, |
| 350 | "ListTaskFilter"); | 353 | "ListTaskFilter"); |
| 351 | if (ret) { | 354 | if (ret) { |
| 352 | |||
| 353 | task_filter = info->list_task_filter; | 355 | task_filter = info->list_task_filter; |
| 354 | hide_tasks = info->list_hide_tasks; | 356 | hide_tasks = info->list_hide_tasks; |
| 355 | filter_task_clear(task_filter); | 357 | filter_task_clear(task_filter); |
| @@ -377,6 +379,16 @@ load_filters_clicked (gpointer data) | |||
| 377 | info->list_hide_tasks)) | 379 | info->list_hide_tasks)) |
| 378 | sync_task_filters(info); | 380 | sync_task_filters(info); |
| 379 | 381 | ||
| 382 | model = gtk_tree_view_get_model(trace_tree); | ||
| 383 | if (!model) | ||
| 384 | goto out; | ||
| 385 | |||
| 386 | store = TRACE_VIEW_STORE(model); | ||
| 387 | event_filter = trace_view_store_get_event_filter(store); | ||
| 388 | |||
| 389 | if (pevent_filter_compare(event_filter, ginfo->event_filter)) | ||
| 390 | sync_event_filters(info); | ||
| 391 | |||
| 380 | out: | 392 | out: |
| 381 | g_free(filename); | 393 | g_free(filename); |
| 382 | 394 | ||
| @@ -563,10 +575,15 @@ sync_events_filter_clicked (GtkWidget *subitem, gpointer data) | |||
| 563 | return; | 575 | return; |
| 564 | 576 | ||
| 565 | store = TRACE_VIEW_STORE(model); | 577 | store = TRACE_VIEW_STORE(model); |
| 578 | event_filter = trace_view_store_get_event_filter(store); | ||
| 566 | 579 | ||
| 567 | /* Ask user which way to sync */ | 580 | /* If they are already equal, then just perminently sync them */ |
| 568 | result = trace_sync_select_menu("Sync Event Filters", | 581 | if (pevent_filter_compare(event_filter, ginfo->event_filter)) |
| 569 | selections, &keep); | 582 | result = 2; |
| 583 | else | ||
| 584 | /* Ask user which way to sync */ | ||
| 585 | result = trace_sync_select_menu("Sync Event Filters", | ||
| 586 | selections, &keep); | ||
| 570 | 587 | ||
| 571 | switch (result) { | 588 | switch (result) { |
| 572 | case 0: | 589 | case 0: |
| @@ -579,11 +596,13 @@ sync_events_filter_clicked (GtkWidget *subitem, gpointer data) | |||
| 579 | case 1: | 596 | case 1: |
| 580 | /* Sync Graph Filter with List Filter */ | 597 | /* Sync Graph Filter with List Filter */ |
| 581 | all_events = trace_view_store_get_all_events_enabled(store); | 598 | all_events = trace_view_store_get_all_events_enabled(store); |
| 582 | event_filter = trace_view_store_get_event_filter(store); | ||
| 583 | 599 | ||
| 584 | trace_graph_copy_filter(info->ginfo, all_events, | 600 | trace_graph_copy_filter(info->ginfo, all_events, |
| 585 | event_filter); | 601 | event_filter); |
| 586 | break; | 602 | break; |
| 603 | case 2: | ||
| 604 | keep = 1; | ||
| 605 | break; | ||
| 587 | default: | 606 | default: |
| 588 | keep = 0; | 607 | keep = 0; |
| 589 | } | 608 | } |
diff --git a/parse-events.h b/parse-events.h index 5afbd1a..9f56d69 100644 --- a/parse-events.h +++ b/parse-events.h | |||
| @@ -701,4 +701,6 @@ int pevent_filter_copy(struct event_filter *dest, struct event_filter *source); | |||
| 701 | int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, | 701 | int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, |
| 702 | enum filter_trivial_type type); | 702 | enum filter_trivial_type type); |
| 703 | 703 | ||
| 704 | int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2); | ||
| 705 | |||
| 704 | #endif /* _PARSE_EVENTS_H */ | 706 | #endif /* _PARSE_EVENTS_H */ |
diff --git a/parse-filter.c b/parse-filter.c index 4efce04..75512e3 100644 --- a/parse-filter.c +++ b/parse-filter.c | |||
| @@ -2026,3 +2026,60 @@ pevent_filter_make_string(struct event_filter *filter, int event_id) | |||
| 2026 | return arg_to_str(filter, filter_type->filter); | 2026 | return arg_to_str(filter, filter_type->filter); |
| 2027 | } | 2027 | } |
| 2028 | 2028 | ||
| 2029 | /** | ||
| 2030 | * pevent_filter_compare - compare two filters and return if they are the same | ||
| 2031 | * @filter1: Filter to compare with @filter2 | ||
| 2032 | * @filter2: Filter to compare with @filter1 | ||
| 2033 | * | ||
| 2034 | * Returns: | ||
| 2035 | * 1 if the two filters hold the same content. | ||
| 2036 | * 0 if they do not. | ||
| 2037 | */ | ||
| 2038 | int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2) | ||
| 2039 | { | ||
| 2040 | struct filter_type *filter_type1; | ||
| 2041 | struct filter_type *filter_type2; | ||
| 2042 | char *str1, *str2; | ||
| 2043 | int result; | ||
| 2044 | int i; | ||
| 2045 | |||
| 2046 | /* Do the easy checks first */ | ||
| 2047 | if (filter1->filters != filter2->filters) | ||
| 2048 | return 0; | ||
| 2049 | if (!filter1->filters && !filter2->filters) | ||
| 2050 | return 1; | ||
| 2051 | |||
| 2052 | /* | ||
| 2053 | * Now take a look at each of the events to see if they have the same | ||
| 2054 | * filters to them. | ||
| 2055 | */ | ||
| 2056 | for (i = 0; i < filter1->filters; i++) { | ||
| 2057 | filter_type1 = &filter1->event_filters[i]; | ||
| 2058 | filter_type2 = find_filter_type(filter2, filter_type1->event_id); | ||
| 2059 | if (!filter_type2) | ||
| 2060 | break; | ||
| 2061 | if (filter_type1->filter->type != filter_type2->filter->type) | ||
| 2062 | break; | ||
| 2063 | switch (filter_type1->filter->type) { | ||
| 2064 | case FILTER_TRIVIAL_FALSE: | ||
| 2065 | case FILTER_TRIVIAL_TRUE: | ||
| 2066 | /* trivial types just need the type compared */ | ||
| 2067 | continue; | ||
| 2068 | default: | ||
| 2069 | break; | ||
| 2070 | } | ||
| 2071 | /* The best way to compare complex filters is with strings */ | ||
| 2072 | str1 = arg_to_str(filter1, filter_type1->filter); | ||
| 2073 | str2 = arg_to_str(filter2, filter_type2->filter); | ||
| 2074 | result = strcmp(str1, str2) != 0; | ||
| 2075 | free(str1); | ||
| 2076 | free(str2); | ||
| 2077 | if (result) | ||
| 2078 | break; | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | if (i < filter1->filters) | ||
| 2082 | return 0; | ||
| 2083 | return 1; | ||
| 2084 | } | ||
| 2085 | |||
