From: Pawel Kurowski Date: Thu, 1 Jun 2017 10:45:08 +0000 (+0200) Subject: Add relation-dump option to at_spi2_tool X-Git-Tag: accepted/tizen/unified/20170630.083045^0 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Fat-spi2-core.git;a=commitdiff_plain;h=e757756d750e7d736aee31c71b68116a71031f58 Add relation-dump option to at_spi2_tool Flags -d and -c now inform when object has relations to list. Change-Id: If831d8258aaf6d7b71f3f05ebf75e88d3fab56c1 --- diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 018acc7..e9b3d68 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -4,6 +4,7 @@ #include #include #include +#include #define ERROR_STATE -1 #define SAFE_BUFFER_SIZE 2048 @@ -17,6 +18,8 @@ #define DUMP 0 #define CHECK 1 #define FIRST_MATCH 2 +#define RELATION_TABLE_COLUMN_COUNT 7 +#define RELATION_COLUMN_WIDTH 20 #define VERSION "1.1" static unsigned indent_width = 2; @@ -79,12 +82,6 @@ typedef struct _Box_Size { char *width; } Box_Size; -char *_strdup(const char *c) -{ - char *result = (char *)calloc(1, strlen(c) + 1); - return result ? strcpy(result, c) : result; -} - static char *_multiply_string(char c, unsigned number) { char *result = (char *)calloc(1, number + 1); @@ -99,7 +96,7 @@ static char *_multiply_string(char c, unsigned number) static void _print_module_legend() { - printf("\n[[node],[node role name],[attributes list],[x,y,width,height],[node name],[states list][flow to node, flow from node]\n\n"); + printf("\n[[node],[node role name],[attributes list],[x,y,width,height],[node name],[states list][relations]\n\n"); } static void _print_atspi_states_legend() @@ -250,7 +247,7 @@ static char *_get_states(AtspiAccessible *node, int length_limit) state_type = g_array_index(states, AtspiStateType, i); char node_state_str[8]; - sprintf(node_state_str, "(%d)", state_type); + snprintf(node_state_str, 8, "(%d)", state_type); _combine_strings(&state_string, node_state_str); } @@ -288,32 +285,6 @@ static char *_get_attributes(AtspiAccessible *node, int length_limit) return result; } -static char *_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type) -{ - if (source == NULL) - return ""; - - GArray *relations = atspi_accessible_get_relation_set(source, NULL); - - if (relations == NULL) - return ""; - - AtspiAccessible *ret = NULL; - for (int i = 0; i < relations->len; ++i) { - AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); - AtspiRelationType type = atspi_relation_get_relation_type(relation); - - if (type == search_type) { - ret = atspi_relation_get_target(relation, 0); - break; - } - } - - g_array_free(relations, TRUE); - - return ret ? atspi_accessible_get_path(ret, NULL) : g_strdup(""); -} - static char *_get_info(AtspiAccessible *node, int length_limit) { if (!node) @@ -327,11 +298,10 @@ static char *_get_info(AtspiAccessible *node, int length_limit) Box_Size *box_size = _get_box_size(node); char *states = _get_states(node, length_limit); - char *flows_to = _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO); - char *flows_from = _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM); + GArray *relations = atspi_accessible_get_relation_set(node, NULL); char result[SAFE_BUFFER_SIZE]; - int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s,%s]]", + int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s]]", path, node_role_name, attributes, @@ -341,8 +311,7 @@ static char *_get_info(AtspiAccessible *node, int length_limit) box_size->height, node_name, states, - flows_to, - flows_from); + (relations && relations->len) ? "*" : ""); if (ret >= SAFE_BUFFER_SIZE) fprintf(stderr, "\n%s, %s %s: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__); @@ -357,10 +326,9 @@ static char *_get_info(AtspiAccessible *node, int length_limit) free(box_size); } free(states); - free(flows_to); - free(flows_from); + g_array_free(relations, TRUE); - return _strdup(result); + return g_strdup(result); } static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessible *parent_candidate, int parent_candidate_index) @@ -373,7 +341,7 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi char parent_status[NUMBER_WIDTH]; if (parent == NULL) - strcpy(parent_status, "_"); + strncpy(parent_status, NUMBER_WIDTH, "_"); else snprintf(parent_status, NUMBER_WIDTH, "%d", parent_index); @@ -438,11 +406,93 @@ void _print_help() printf("\tat_spi2_tool -i1 -c starter\n"); printf("\t show AT-SPI tree with integrity test for node \"starter\" using one-space indentation\n"); } + void _print_version() { printf("AT-SPI2-CORE-UTIL v%s\n", VERSION); } +static void _print_horizontal_line_in_relation_table() { + for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) { + for (int j = 0; j < RELATION_COLUMN_WIDTH; j++) + printf("-"); + printf("+"); + } + printf("\n"); +} + +static void _print_legend_for_relation_table() { + char *table[] = {"OBJECT", "CONTROLLER_FOR", "CONTROLLED_BY", "FLOWS_TO", "FLOWS_FROM", "DESCRIBED_BY", "OTHER RELATION [ID]"}; + assert(sizeof(table) / sizeof(table[0]) == RELATION_TABLE_COLUMN_COUNT); + for(int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) + printf("%*s|", RELATION_COLUMN_WIDTH , table[i]); + printf("\n"); + _print_horizontal_line_in_relation_table(); +} + +static char *_get_path_to_object_in_relation(AtspiRelation *relation) { + if (!relation) + return NULL; + gint last_index = atspi_relation_get_n_targets(relation) - 1; + AtspiAccessible *target = atspi_relation_get_target(relation, last_index); + return atspi_accessible_get_path(target, NULL); +} + +static void _print_relations_for_object(AtspiAccessible *node) { + GArray *relations = atspi_accessible_get_relation_set(node, NULL); + if (!relations) + return; + + if (relations->len) { + int size = RELATION_TABLE_COLUMN_COUNT * sizeof(char *); + char **table = malloc(size); + memset(table, 0, size); + table[0] = atspi_accessible_get_path(node, NULL); + char buf[8] = ""; + for (int i = 0; i < relations->len; i++) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); + AtspiRelationType type = atspi_relation_get_relation_type(relation); + switch (type) { + case ATSPI_RELATION_CONTROLLER_FOR: + table[1] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_CONTROLLED_BY: + table[2] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_FLOWS_TO: + table[3] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_FLOWS_FROM: + table[4] = _get_path_to_object_in_relation(relation); + break; + case ATSPI_RELATION_DESCRIBED_BY: + table[5] = _get_path_to_object_in_relation(relation); + break; + default: + snprintf(buf, 8, " [%d]", type); + _combine_strings(&table[RELATION_TABLE_COLUMN_COUNT - 1], buf); + } + } + + for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) { + printf("%*s|", RELATION_COLUMN_WIDTH, table[i] ? table[i] : ""); + free(table[i]); + } + free(table); + + printf("\n"); + _print_horizontal_line_in_relation_table(); + } + g_array_free(relations, TRUE); + + int count = atspi_accessible_get_child_count(node, NULL); + for (int i = 0; i < count; i++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(node, i, NULL); + if (child) + _print_relations_for_object(child); + } +} + static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, bool dump, bool check, bool first_match, int length_limit) { int count = atspi_accessible_get_child_count(desktop, NULL); @@ -472,8 +522,11 @@ static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, if (first_match) { free(name); break; - } else + } else { printf("\n"); + _print_legend_for_relation_table(); + _print_relations_for_object(child); + } free(name); }