Commit | Line | Data |
---|---|---|
121b3efd PA |
1 | /* List of target connections for GDB. |
2 | ||
3 | Copyright (C) 2017-2020 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "target-connection.h" | |
22 | ||
23 | #include <map> | |
24 | ||
25 | #include "inferior.h" | |
26 | #include "target.h" | |
27 | ||
28 | /* A map between connection number and representative process_stratum | |
29 | target. */ | |
30 | static std::map<int, process_stratum_target *> process_targets; | |
31 | ||
32 | /* The highest connection number ever given to a target. */ | |
33 | static int highest_target_connection_num; | |
34 | ||
35 | /* See target-connection.h. */ | |
36 | ||
37 | void | |
38 | connection_list_add (process_stratum_target *t) | |
39 | { | |
40 | if (t->connection_number == 0) | |
41 | { | |
42 | t->connection_number = ++highest_target_connection_num; | |
43 | process_targets[t->connection_number] = t; | |
44 | } | |
45 | } | |
46 | ||
47 | /* See target-connection.h. */ | |
48 | ||
49 | void | |
50 | connection_list_remove (process_stratum_target *t) | |
51 | { | |
52 | process_targets.erase (t->connection_number); | |
53 | t->connection_number = 0; | |
54 | } | |
55 | ||
2f4fcf00 | 56 | /* See target-connection.h. */ |
121b3efd | 57 | |
2f4fcf00 | 58 | std::string |
121b3efd PA |
59 | make_target_connection_string (process_stratum_target *t) |
60 | { | |
61 | if (t->connection_string () != NULL) | |
62 | return string_printf ("%s %s", t->shortname (), | |
63 | t->connection_string ()); | |
64 | else | |
65 | return t->shortname (); | |
66 | } | |
67 | ||
68 | /* Prints the list of target connections and their details on UIOUT. | |
69 | ||
70 | If REQUESTED_CONNECTIONS is not NULL, it's a list of GDB ids of the | |
71 | target connections that should be printed. Otherwise, all target | |
72 | connections are printed. */ | |
73 | ||
74 | static void | |
75 | print_connection (struct ui_out *uiout, const char *requested_connections) | |
76 | { | |
77 | int count = 0; | |
78 | size_t what_len = 0; | |
79 | ||
80 | /* Compute number of lines we will print. */ | |
81 | for (const auto &it : process_targets) | |
82 | { | |
83 | if (!number_is_in_list (requested_connections, it.first)) | |
84 | continue; | |
85 | ||
86 | ++count; | |
87 | ||
88 | process_stratum_target *t = it.second; | |
89 | ||
90 | size_t l = strlen (t->shortname ()); | |
91 | if (t->connection_string () != NULL) | |
92 | l += 1 + strlen (t->connection_string ()); | |
93 | ||
94 | if (l > what_len) | |
95 | what_len = l; | |
96 | } | |
97 | ||
98 | if (count == 0) | |
99 | { | |
100 | uiout->message (_("No connections.\n")); | |
101 | return; | |
102 | } | |
103 | ||
104 | ui_out_emit_table table_emitter (uiout, 4, process_targets.size (), | |
105 | "connections"); | |
106 | ||
107 | uiout->table_header (1, ui_left, "current", ""); | |
108 | uiout->table_header (4, ui_left, "number", "Num"); | |
109 | /* The text in the "what" column may include spaces. Add one extra | |
110 | space to visually separate the What and Description columns a | |
111 | little better. Compare: | |
112 | "* 1 remote :9999 Remote serial target in gdb-specific protocol" | |
113 | "* 1 remote :9999 Remote serial target in gdb-specific protocol" | |
114 | */ | |
115 | uiout->table_header (what_len + 1, ui_left, "what", "What"); | |
116 | uiout->table_header (17, ui_left, "description", "Description"); | |
117 | ||
118 | uiout->table_body (); | |
119 | ||
120 | for (const auto &it : process_targets) | |
121 | { | |
122 | process_stratum_target *t = it.second; | |
123 | ||
124 | if (!number_is_in_list (requested_connections, t->connection_number)) | |
125 | continue; | |
126 | ||
127 | ui_out_emit_tuple tuple_emitter (uiout, NULL); | |
128 | ||
129 | if (current_inferior ()->process_target () == t) | |
130 | uiout->field_string ("current", "*"); | |
131 | else | |
132 | uiout->field_skip ("current"); | |
133 | ||
134 | uiout->field_signed ("number", t->connection_number); | |
135 | ||
136 | uiout->field_string ("what", make_target_connection_string (t).c_str ()); | |
137 | ||
138 | uiout->field_string ("description", t->longname ()); | |
139 | ||
140 | uiout->text ("\n"); | |
141 | } | |
142 | } | |
143 | ||
144 | /* The "info connections" command. */ | |
145 | ||
146 | static void | |
147 | info_connections_command (const char *args, int from_tty) | |
148 | { | |
149 | print_connection (current_uiout, args); | |
150 | } | |
151 | ||
6c265988 SM |
152 | void _initialize_target_connection (); |
153 | ||
121b3efd PA |
154 | void |
155 | _initialize_target_connection () | |
156 | { | |
157 | add_info ("connections", info_connections_command, | |
158 | _("\ | |
159 | Target connections in use.\n\ | |
160 | Shows the list of target connections currently in use.")); | |
161 | } |