From: Pawel Kurowski Date: Mon, 17 Jul 2017 20:15:35 +0000 (+0200) Subject: add attributes table to at_spi2_tool X-Git-Tag: accepted/tizen/4.0/unified/20170816.011001~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F72%2F139172%2F3;p=platform%2Fupstream%2Fat-spi2-core.git add attributes table to at_spi2_tool atributes table will be printed, when atributes string is too long add relations_found flag which tells if relation table legend should be printed Change-Id: I2a0b71f5e8b439881f5b83e9b7f1a17556f9e713 --- diff --git a/test/at_spi2_tool.c b/test/at_spi2_tool.c index 15adca5..08c2af5 100644 --- a/test/at_spi2_tool.c +++ b/test/at_spi2_tool.c @@ -20,7 +20,9 @@ #define CHECK 1 #define FIRST_MATCH 2 #define RELATION_TABLE_COLUMN_COUNT 7 -#define RELATION_COLUMN_WIDTH 20 +#define ATTRIBUTE_TABLE_COLUMN_COUNT 3 +#define RELATION_TABLE_COLUMN_WIDTH 20 +#define ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH 20 #define VERSION "1.1" static unsigned indent_width = 2; @@ -260,7 +262,7 @@ static char *_get_states(AtspiAccessible *node, int length_limit) return state_string; } -static char *_get_attributes(AtspiAccessible *node, int length_limit) +static char *_get_attributes(AtspiAccessible *node, int length_limit, bool *attributes_are_too_long) { GHashTable *attributes = atspi_accessible_get_attributes(node, NULL); @@ -273,20 +275,24 @@ static char *_get_attributes(AtspiAccessible *node, int length_limit) g_hash_table_iter_init (&attributes_iter, attributes); char *result = NULL; while (g_hash_table_iter_next (&attributes_iter, &attr_key, &attr_value)) { - char attributes_string[ATTR_WIDTH]; - int ret = snprintf(attributes_string, ATTR_WIDTH, "(%s=%s)", (char *)attr_key, (char *)attr_value); - if (ret >= ATTR_WIDTH) - fprintf(stderr, "\n_get_attributes: generated string is too long. Buffer overflow\n"); + char attributes_string[SAFE_BUFFER_SIZE]; + int ret = snprintf(attributes_string, SAFE_BUFFER_SIZE, "(%s=%s)", (char *)attr_key, (char *)attr_value); + if (ret >= SAFE_BUFFER_SIZE) + fprintf(stderr, "\n%s, %s %d: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__); _combine_strings(&result, attributes_string); } g_hash_table_unref(attributes); - _truncate_string(result, length_limit); + int real_truncate_size = (length_limit < ATTR_WIDTH && length_limit > MINIMAL_MODULE_WIDTH) ? length_limit : ATTR_WIDTH; + if (result && attributes_are_too_long && strlen(result) > real_truncate_size) + *attributes_are_too_long = true; + + _truncate_string(result, real_truncate_size); return result; } -static char *_get_info(AtspiAccessible *node, int length_limit) +static char *_get_info(AtspiAccessible *node, int length_limit, bool *attributes_are_too_long, bool *app_has_relations) { if (!node) return NULL; @@ -295,11 +301,12 @@ static char *_get_info(AtspiAccessible *node, int length_limit) char *node_role_name = atspi_accessible_get_role_name(node, NULL); char *unique_id = atspi_accessible_get_unique_id(node, NULL); - char *attributes = _get_attributes(node, length_limit); + char *attributes = _get_attributes(node, length_limit, attributes_are_too_long); Box_Size *box_size = _get_box_size(node); char *states = _get_states(node, length_limit); GArray *relations = atspi_accessible_get_relation_set(node, NULL); + bool current_node_has_relations = (relations && relations->len); char result[SAFE_BUFFER_SIZE]; int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s]]", @@ -312,11 +319,14 @@ static char *_get_info(AtspiAccessible *node, int length_limit) box_size->height, node_name, states, - (relations && relations->len) ? "*" : ""); + current_node_has_relations ? "*" : ""); if (ret >= SAFE_BUFFER_SIZE) fprintf(stderr, "\n%s, %s %d: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__); + if (current_node_has_relations) + *app_has_relations = true; + free(node_name); free(node_role_name); free(unique_id); @@ -360,7 +370,8 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi printf("%-*s\t", CHECK_OUTPUT_WIDTH, output); } -static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible *object, bool check_integrity, int length_limit) +static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible *object, bool check_integrity, int length_limit, + bool *attributes_are_too_long, bool *app_has_relations) { char *indent = _multiply_string(' ', indent_number*indent_width); if (indent != NULL) { @@ -368,7 +379,7 @@ static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible * free(indent); } - char *node_info = _get_info(object, length_limit); + char *node_info = _get_info(object, length_limit, attributes_are_too_long, app_has_relations); if (node_info != NULL) { printf("%s\n", node_info); free(node_info); @@ -381,7 +392,7 @@ static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible * if (check_integrity) _test_atspi_parent_child_relation(child, object, i); - _print_atspi_tree_verify_maybe_r(indent_number + 1, child, check_integrity, length_limit); + _print_atspi_tree_verify_maybe_r(indent_number + 1, child, check_integrity, length_limit, attributes_are_too_long, app_has_relations); } } return 0; @@ -415,24 +426,15 @@ void _print_version() printf("AT-SPI2-CORE-UTIL v%s\n", VERSION); } -static void _print_horizontal_line_in_relation_table() { +static void _print_horizontal_line_in_relations_table() { for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) { - for (int j = 0; j < RELATION_COLUMN_WIDTH; j++) + for (int j = 0; j < RELATION_TABLE_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(ARRAY_SIZE(table) == 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_unique_id_of_object_in_relation(AtspiRelation *relation) { if (!relation) return NULL; @@ -482,32 +484,116 @@ static void _print_relations_for_object(AtspiAccessible *node) { } for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) { - printf("%*s|", RELATION_COLUMN_WIDTH, table[i] ? table[i] : ""); + printf("%*s|", RELATION_TABLE_COLUMN_WIDTH, table[i] ? table[i] : ""); free(table[i]); } free(table); printf("\n"); - _print_horizontal_line_in_relation_table(); + _print_horizontal_line_in_relations_table(); g_array_free(relations, TRUE); } -static void _print_relations_for_objects_in_tree(AtspiAccessible *node) { - _print_relations_for_object(node); +typedef void (*print_information_about_object_function)(AtspiAccessible *); + +static void _iterate_over_tree(print_information_about_object_function func, AtspiAccessible *node) { + func(node); 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_objects_in_tree(child); + _iterate_over_tree(func, child); } } +static void _print_relations_for_objects_in_tree(AtspiAccessible *node) { + _iterate_over_tree(_print_relations_for_object, node); +} + +static void _print_header_for_relation_table() { + char *table[] = {"OBJECT", "CONTROLLER_FOR", "CONTROLLED_BY", "FLOWS_TO", "FLOWS_FROM", "DESCRIBED_BY", "OTHER RELATION [ID]"}; + assert(ARRAY_SIZE(table) == RELATION_TABLE_COLUMN_COUNT); + + _print_horizontal_line_in_relations_table(); + + for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) + printf("%*s|", RELATION_TABLE_COLUMN_WIDTH , table[i]); + + printf("\n"); + _print_horizontal_line_in_relations_table(); +} + static void _print_relations_table(AtspiAccessible *node) { - _print_legend_for_relation_table(); + printf("\nRELATIONS TABLE\n"); + _print_header_for_relation_table(); _print_relations_for_objects_in_tree(node); } +static void _print_horizontal_line_in_attributes_table() { + int size_factor = 1; + for (int i = 0; i < ATTRIBUTE_TABLE_COLUMN_COUNT; i++) { + if (i == ATTRIBUTE_TABLE_COLUMN_COUNT - 1) + size_factor = 4; + for (int j = 0; j < ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH * size_factor; j++) + printf("-"); + printf("+"); + } + printf("\n"); +} + +static void _print_attributes_for_object(AtspiAccessible *node) { + GHashTable *attributes = atspi_accessible_get_attributes(node, NULL); + + if (!attributes) + return; + + char *unique_id = atspi_accessible_get_unique_id(node, NULL); + GHashTableIter attributes_iter; + gpointer attr_key; + gpointer attr_value; + + g_hash_table_iter_init (&attributes_iter, attributes); + while (g_hash_table_iter_next (&attributes_iter, &attr_key, &attr_value)) { + printf("%*s|", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH, unique_id ? unique_id : ""); + printf("%*s|", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH, attr_key ? (char *) attr_key : ""); + printf("%*s|\n", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH * 4, attr_value ? (char *) attr_value : ""); + } + + if (g_hash_table_size (attributes)) + _print_horizontal_line_in_attributes_table(); + + g_hash_table_unref(attributes); + free(unique_id); +} + +static void _print_attributes_for_objects_in_tree(AtspiAccessible *node) { + _iterate_over_tree(_print_attributes_for_object, node); +} + +static void _print_header_for_attributes_table() { + char *table[] = {"OBJECT", "ATTRIBUTE KEY", "ATTRIBUTE VALUE"}; + assert(ARRAY_SIZE(table) == ATTRIBUTE_TABLE_COLUMN_COUNT); + + _print_horizontal_line_in_attributes_table(); + + int size_factor = 1; + for (int i = 0; i < ATTRIBUTE_TABLE_COLUMN_COUNT; i++) { + if (i == ATTRIBUTE_TABLE_COLUMN_COUNT - 1) + size_factor = 4; + printf("%*s|", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH * size_factor , table[i]); + } + + printf("\n"); + _print_horizontal_line_in_attributes_table(); +} + +static void _print_attributes_table(AtspiAccessible *node) { + printf("\nATTRIBUTES TABLE\n"); + _print_header_for_attributes_table(); + _print_attributes_for_objects_in_tree(node); +} + static void _atspi_tree_traverse(const char *app_name, bool dump, bool check, bool first_match, int length_limit) { @@ -519,6 +605,7 @@ static void _atspi_tree_traverse(const char *app_name, bool dump, bool check, bo int count = atspi_accessible_get_child_count(desktop, NULL); bool app_name_matched = false; + for (int i = 0; i < count; i++) { AtspiAccessible *child = atspi_accessible_get_child_at_index(desktop, i, NULL); if (child == NULL) { @@ -527,6 +614,8 @@ static void _atspi_tree_traverse(const char *app_name, bool dump, bool check, bo } char *name = atspi_accessible_get_name(child, NULL); + bool attributes_are_too_long = false; + bool app_has_relations = false; if (!dump && !check) printf("%s\n", name); @@ -539,9 +628,13 @@ static void _atspi_tree_traverse(const char *app_name, bool dump, bool check, bo if (check) _test_atspi_parent_child_relation(child, desktop, i); - _print_atspi_tree_verify_maybe_r(0, child, check, length_limit); - printf("\n"); - _print_relations_table(child); + _print_atspi_tree_verify_maybe_r(0, child, check, length_limit, &attributes_are_too_long, &app_has_relations); + + if (app_has_relations) + _print_relations_table(child); + + if (attributes_are_too_long) + _print_attributes_table(child); if (first_match) { free(name); @@ -647,7 +740,7 @@ static void _run_command(int argc, char *argv[]) case 'a': enable_at_spi_client = TRUE; - if(optarg[0] == 'f' || optarg[0] == '0') + if (optarg[0] == 'f' || optarg[0] == '0') enable_at_spi_client = FALSE; _at_spi_client_enable(enable_at_spi_client);