diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9b3702f68c..491e33d857 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2011-09-16 Joel Brobecker + + * ada-tasks.c (print_ada_task_info): New function, merging + short_task_info and info_tasks together. Reimplement using + ui-out instead of printing to stdout directly. Move the code + building and checking the task list here, instead of leaving it + in info_tasks_command. + (info_task): Move the code building and checking the task + list here, instead of leaving it in info_tasks_command. + (info_tasks_command): Delete code building and checking + the task list - moved elsewhere. Update calls to info_tasks + and info_task. + 2011-09-16 Joel Brobecker * ada-tasks.c (info_task): Delete parameter `from_tty'. diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index e2020f717c..6e2f2f590c 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -924,87 +924,134 @@ ada_build_task_list (void) return VEC_length (ada_task_info_s, data->task_list); } -/* Print a one-line description of the task running in inferior INF - whose number is TASKNO. - - The formatting should fit the "info tasks" array. */ +/* Print a table providing a short description of all Ada tasks + running inside inferior INF. If ARG_STR is set, it will be + interpreted as a task number, and the table will be limited to + that task only. */ static void -short_task_info (int taskno, struct inferior *inf) +print_ada_task_info (struct ui_out *uiout, + char *arg_str, + struct inferior *inf) { - struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf); - const struct ada_task_info *const task_info = - VEC_index (ada_task_info_s, data->task_list, taskno - 1); - int active_task_p; + struct ada_tasks_inferior_data *data; + int taskno, nb_tasks; + int taskno_arg = 0; + struct cleanup *old_chain; - gdb_assert (task_info != NULL); + if (ada_build_task_list () == 0) + { + ui_out_message (uiout, 0, + _("Your application does not use any Ada tasks.\n")); + return; + } - /* Print a star if this task is the current task (or the task currently - selected). */ + if (arg_str != NULL && arg_str[0] != '\0') + taskno_arg = value_as_long (parse_and_eval (arg_str)); - active_task_p = ptid_equal (task_info->ptid, inferior_ptid); - if (active_task_p) - printf_filtered ("*"); - else - printf_filtered (" "); + data = get_ada_tasks_inferior_data (inf); + nb_tasks = VEC_length (ada_task_info_s, data->task_list); - /* Print the task number. */ - printf_filtered ("%3d", taskno); + old_chain = make_cleanup_ui_out_table_begin_end (uiout, 7, nb_tasks, + "tasks"); + ui_out_table_header (uiout, 1, ui_left, "current", ""); + ui_out_table_header (uiout, 3, ui_right, "id", "ID"); + ui_out_table_header (uiout, 9, ui_right, "task-id", "TID"); + ui_out_table_header (uiout, 4, ui_right, "parent-id", "P-ID"); + ui_out_table_header (uiout, 3, ui_right, "priority", "Pri"); + ui_out_table_header (uiout, 22, ui_left, "state", "State"); + /* Use ui_noalign for the last column, to prevent the CLI uiout + from printing an extra space at the end of each row. This + is a bit of a hack, but does get the job done. */ + ui_out_table_header (uiout, 1, ui_noalign, "name", "Name"); + ui_out_table_body (uiout); - /* Print the Task ID. */ - printf_filtered (" %9lx", (long) task_info->task_id); - - /* Print the Task ID of the task parent. */ - printf_filtered (" %4d", get_task_number_from_id (task_info->parent, inf)); - - /* Print the base priority of the task. */ - printf_filtered (" %3d", task_info->priority); - - /* Print the task current state. */ - if (task_info->caller_task) - printf_filtered (_(" Accepting RV with %-4d"), - get_task_number_from_id (task_info->caller_task, inf)); - else if (task_info->state == Entry_Caller_Sleep && task_info->called_task) - printf_filtered (_(" Waiting on RV with %-3d"), - get_task_number_from_id (task_info->called_task, inf)); - else - printf_filtered (" %-22s", _(task_states[task_info->state])); - - /* Finally, print the task name. */ - if (task_info->name[0] != '\0') - printf_filtered (" %s\n", task_info->name); - else - printf_filtered (_(" \n")); -} - -/* Print a list containing a short description of all Ada tasks - running inside inferior INF. */ -/* FIXME: Shouldn't we be using ui_out??? */ - -static void -info_tasks (struct inferior *inf) -{ - struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf); - int taskno; - const int nb_tasks = VEC_length (ada_task_info_s, data->task_list); - - printf_filtered (_(" ID TID P-ID Pri State Name\n")); - for (taskno = 1; taskno <= nb_tasks; taskno++) - short_task_info (taskno, inf); + { + const struct ada_task_info *const task_info = + VEC_index (ada_task_info_s, data->task_list, taskno - 1); + int parent_id; + struct cleanup *chain2; + + gdb_assert (task_info != NULL); + + /* If the user asked for the output to be restricted + to one task only, and this is not the task, skip + to the next one. */ + if (taskno_arg && taskno != taskno_arg) + continue; + + chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + + /* Print a star if this task is the current task (or the task + currently selected). */ + if (ptid_equal (task_info->ptid, inferior_ptid)) + ui_out_field_string (uiout, "current", "*"); + else + ui_out_field_skip (uiout, "current"); + + /* Print the task number. */ + ui_out_field_int (uiout, "id", taskno); + + /* Print the Task ID. */ + ui_out_field_fmt (uiout, "task-id", "%9lx", (long) task_info->task_id); + + /* Print the ID of the parent task. */ + parent_id = get_task_number_from_id (task_info->parent, inf); + if (parent_id) + ui_out_field_int (uiout, "parent-id", parent_id); + else + ui_out_field_skip (uiout, "parent-id"); + + /* Print the base priority of the task. */ + ui_out_field_int (uiout, "priority", task_info->priority); + + /* Print the task current state. */ + if (task_info->caller_task) + ui_out_field_fmt (uiout, "state", + _("Accepting RV with %-4d"), + get_task_number_from_id (task_info->caller_task, + inf)); + else if (task_info->state == Entry_Caller_Sleep + && task_info->called_task) + ui_out_field_fmt (uiout, "state", + _("Waiting on RV with %-3d"), + get_task_number_from_id (task_info->called_task, + inf)); + else + ui_out_field_string (uiout, "state", task_states[task_info->state]); + + /* Finally, print the task name. */ + ui_out_field_fmt (uiout, "name", + "%s", + task_info->name[0] != '\0' ? task_info->name + : _("")); + + ui_out_text (uiout, "\n"); + do_cleanups (chain2); + } + + do_cleanups (old_chain); } /* Print a detailed description of the Ada task whose ID is TASKNO_STR for the given inferior (INF). */ static void -info_task (char *taskno_str, struct inferior *inf) +info_task (struct ui_out *uiout, char *taskno_str, struct inferior *inf) { const int taskno = value_as_long (parse_and_eval (taskno_str)); struct ada_task_info *task_info; int parent_taskno = 0; struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf); + if (ada_build_task_list () == 0) + { + ui_out_message (uiout, 0, + _("Your application does not use any Ada tasks.\n")); + return; + } + if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, data->task_list)) error (_("Task ID %d not known. Use the \"info tasks\" command to\n" "see the IDs of currently known tasks"), taskno); @@ -1086,17 +1133,10 @@ info_tasks_command (char *arg, int from_tty) { struct ui_out *uiout = current_uiout; - if (ada_build_task_list () == 0) - { - ui_out_message (uiout, 0, - _("Your application does not use any Ada tasks.\n")); - return; - } - if (arg == NULL || *arg == '\0') - info_tasks (current_inferior ()); + print_ada_task_info (uiout, NULL, current_inferior ()); else - info_task (arg, current_inferior ()); + info_task (uiout, arg, current_inferior ()); } /* Print a message telling the user id of the current task. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 99e220c030..7222a2d812 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-09-16 Joel Brobecker + + * gdb.ada/tasks.exp: Make the expected output for + the `info tasks' tests more resilient to spacing + changes. + 2011-09-16 Jan Kratochvil * gdb.python/py-evthreads.exp (Run to breakpoint 1) diff --git a/gdb/testsuite/gdb.ada/tasks.exp b/gdb/testsuite/gdb.ada/tasks.exp index 1ba1bb854b..17dd2b898a 100644 --- a/gdb/testsuite/gdb.ada/tasks.exp +++ b/gdb/testsuite/gdb.ada/tasks.exp @@ -37,11 +37,11 @@ runto "foo.adb:$bp_location" # Make sure that all tasks appear in the "info tasks" listing, and # that the active task is the environment task. gdb_test "info tasks" \ - [join {" ID TID P-ID Pri State Name" \ - "\\* 1 .* main_task" \ - " 2 .* task_list\\(1\\)" \ - " 3 .* task_list\\(2\\)" \ - " 4 .* task_list\\(3\\)"} \ + [join {" +ID +TID P-ID Pri State +Name" \ + "\\* +1 .* main_task" \ + " +2 .* task_list\\(1\\)" \ + " +3 .* task_list\\(2\\)" \ + " +4 .* task_list\\(3\\)"} \ "\r\n"] \ "info tasks before inserting breakpoint" @@ -59,11 +59,11 @@ gdb_test "continue" \ # Check that it is indeed task 3 that hit the breakpoint by checking # which is the active task. gdb_test "info tasks" \ - [join {" ID TID P-ID Pri State Name" \ - " 1 .* main_task" \ - " 2 .* task_list\\(1\\)" \ - "\\* 3 .* task_list\\(2\\)" \ - " 4 .* task_list\\(3\\)"} \ + [join {" +ID +TID P-ID Pri State +Name" \ + " +1 .* main_task" \ + " +2 .* task_list\\(1\\)" \ + "\\* +3 .* task_list\\(2\\)" \ + " +4 .* task_list\\(3\\)"} \ "\r\n"] \ "info tasks after hitting breakpoint"