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);