Commit | Line | Data |
---|---|---|
fb40c209 AC |
1 | /* MI Command Set - varobj commands. |
2 | Copyright (C) 2000, Free Software Foundation, Inc. | |
3 | Contributed by Cygnus Solutions. | |
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 2 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, write to the Free Software | |
19 | Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | #include "defs.h" | |
23 | #include "mi-cmds.h" | |
24 | #include "ui-out.h" | |
25 | #include "mi-out.h" | |
26 | #include "varobj.h" | |
27 | #include "value.h" | |
28 | #include <ctype.h> | |
29 | ||
30 | /* Convenience macro for allocting typesafe memory. */ | |
31 | ||
32 | #undef XMALLOC | |
33 | #define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) | |
34 | ||
35 | extern int varobjdebug; /* defined in varobj.c */ | |
36 | ||
37 | static void varobj_update_one (struct varobj *var); | |
38 | ||
39 | /* VAROBJ operations */ | |
40 | ||
41 | enum mi_cmd_result | |
42 | mi_cmd_var_create (char *command, char **argv, int argc) | |
43 | { | |
44 | CORE_ADDR frameaddr; | |
45 | struct varobj *var; | |
46 | char *name; | |
47 | char *frame; | |
48 | char *expr; | |
49 | char *type; | |
50 | struct cleanup *old_cleanups; | |
51 | ||
52 | if (argc != 3) | |
53 | { | |
54 | /* asprintf (&mi_error_message, | |
55 | "mi_cmd_var_create: Usage: ."); | |
56 | return MI_CMD_ERROR; */ | |
57 | error ("mi_cmd_var_create: Usage: NAME FRAME EXPRESSION."); | |
58 | } | |
59 | ||
60 | name = xstrdup (argv[0]); | |
61 | /* Add cleanup for name. Must be free_current_contents as | |
62 | name can be reallocated */ | |
63 | old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents, | |
64 | &name); | |
65 | ||
66 | frame = xstrdup (argv[1]); | |
67 | old_cleanups = make_cleanup (free, frame); | |
68 | ||
69 | expr = xstrdup (argv[2]); | |
70 | ||
71 | if (strcmp (name, "-") == 0) | |
72 | { | |
73 | free (name); | |
74 | name = varobj_gen_name (); | |
75 | } | |
76 | else if (!isalpha (*name)) | |
77 | error ("mi_cmd_var_create: name of object must begin with a letter"); | |
78 | ||
79 | if (strcmp (frame, "*") == 0) | |
80 | frameaddr = -1; | |
81 | else | |
82 | frameaddr = parse_and_eval_address (frame); | |
83 | ||
84 | if (varobjdebug) | |
85 | fprintf_unfiltered (gdb_stdlog, | |
86 | "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n", | |
87 | name, frame, paddr (frameaddr), expr); | |
88 | ||
89 | var = varobj_create (name, expr, frameaddr); | |
90 | ||
91 | if (var == NULL) | |
92 | error ("mi_cmd_var_create: unable to create variable object"); | |
93 | ||
94 | ui_out_field_string (uiout, "name", name); | |
95 | ui_out_field_int (uiout, "numchild", varobj_get_num_children (var)); | |
96 | type = varobj_get_type (var); | |
97 | if (type == NULL) | |
98 | ui_out_field_string (uiout, "type", ""); | |
99 | else | |
100 | { | |
101 | ui_out_field_string (uiout, "type", type); | |
102 | free (type); | |
103 | } | |
104 | ||
105 | do_cleanups (old_cleanups); | |
106 | return MI_CMD_DONE; | |
107 | } | |
108 | ||
109 | enum mi_cmd_result | |
110 | mi_cmd_var_delete (char *command, char **argv, int argc) | |
111 | { | |
112 | char *name; | |
113 | char *expr; | |
114 | struct varobj *var; | |
115 | int numdel; | |
116 | int children_only_p = 0; | |
117 | struct cleanup *old_cleanups; | |
118 | ||
119 | if (argc < 1 || argc > 2) | |
120 | error ("mi_cmd_var_delete: Usage: [-c] EXPRESSION."); | |
121 | ||
122 | name = xstrdup (argv[0]); | |
123 | /* Add cleanup for name. Must be free_current_contents as | |
124 | name can be reallocated */ | |
125 | old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents, | |
126 | &name); | |
127 | ||
128 | /* If we have one single argument it cannot be '-c' or any string | |
129 | starting with '-'. */ | |
130 | if (argc == 1) | |
131 | { | |
132 | if (strcmp (name, "-c") == 0) | |
133 | error ("mi_cmd_var_delete: Missing required argument after '-c': variable object name"); | |
134 | if (*name == '-') | |
135 | error ("mi_cmd_var_delete: Illegal variable object name"); | |
136 | } | |
137 | ||
138 | /* If we have 2 arguments they must be '-c' followed by a string | |
139 | which would be the variable name. */ | |
140 | if (argc == 2) | |
141 | { | |
142 | expr = xstrdup (argv[1]); | |
143 | if (strcmp (name, "-c") != 0) | |
144 | error ("mi_cmd_var_delete: Invalid option."); | |
145 | children_only_p = 1; | |
146 | free (name); | |
147 | name = xstrdup (expr); | |
148 | free (expr); | |
149 | } | |
150 | ||
151 | /* If we didn't error out, now NAME contains the name of the | |
152 | variable. */ | |
153 | ||
154 | var = varobj_get_handle (name); | |
155 | ||
156 | if (var == NULL) | |
157 | error ("mi_cmd_var_delete: Variable object not found."); | |
158 | ||
159 | numdel = varobj_delete (var, NULL, children_only_p); | |
160 | ||
161 | ui_out_field_int (uiout, "ndeleted", numdel); | |
162 | ||
163 | do_cleanups (old_cleanups); | |
164 | return MI_CMD_DONE; | |
165 | } | |
166 | ||
167 | enum mi_cmd_result | |
168 | mi_cmd_var_set_format (char *command, char **argv, int argc) | |
169 | { | |
170 | enum varobj_display_formats format; | |
171 | int len; | |
172 | struct varobj *var; | |
173 | char *formspec; | |
174 | ||
175 | if (argc != 2) | |
176 | error ("mi_cmd_var_set_format: Usage: NAME FORMAT."); | |
177 | ||
178 | /* Get varobj handle, if a valid var obj name was specified */ | |
179 | var = varobj_get_handle (argv[0]); | |
180 | ||
181 | if (var == NULL) | |
182 | error ("mi_cmd_var_set_format: Variable object not found"); | |
183 | ||
184 | formspec = xstrdup (argv[1]); | |
185 | if (formspec == NULL) | |
186 | error ("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); | |
187 | ||
188 | len = strlen (formspec); | |
189 | ||
190 | if (STREQN (formspec, "natural", len)) | |
191 | format = FORMAT_NATURAL; | |
192 | else if (STREQN (formspec, "binary", len)) | |
193 | format = FORMAT_BINARY; | |
194 | else if (STREQN (formspec, "decimal", len)) | |
195 | format = FORMAT_DECIMAL; | |
196 | else if (STREQN (formspec, "hexadecimal", len)) | |
197 | format = FORMAT_HEXADECIMAL; | |
198 | else if (STREQN (formspec, "octal", len)) | |
199 | format = FORMAT_OCTAL; | |
200 | else | |
201 | error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); | |
202 | ||
203 | /* Set the format of VAR to given format */ | |
204 | varobj_set_display_format (var, format); | |
205 | ||
206 | /* Report the new current format */ | |
207 | ui_out_field_string (uiout, "format", varobj_format_string[(int) format]); | |
208 | return MI_CMD_DONE; | |
209 | } | |
210 | ||
211 | enum mi_cmd_result | |
212 | mi_cmd_var_show_format (char *command, char **argv, int argc) | |
213 | { | |
214 | enum varobj_display_formats format; | |
215 | struct varobj *var; | |
216 | ||
217 | if (argc != 1) | |
218 | error ("mi_cmd_var_show_format: Usage: NAME."); | |
219 | ||
220 | /* Get varobj handle, if a valid var obj name was specified */ | |
221 | var = varobj_get_handle (argv[0]); | |
222 | if (var == NULL) | |
223 | error ("mi_cmd_var_show_format: Variable object not found"); | |
224 | ||
225 | format = varobj_get_display_format (var); | |
226 | ||
227 | /* Report the current format */ | |
228 | ui_out_field_string (uiout, "format", varobj_format_string[(int) format]); | |
229 | return MI_CMD_DONE; | |
230 | } | |
231 | ||
232 | enum mi_cmd_result | |
233 | mi_cmd_var_info_num_children (char *command, char **argv, int argc) | |
234 | { | |
235 | struct varobj *var; | |
236 | ||
237 | if (argc != 1) | |
238 | error ("mi_cmd_var_info_num_children: Usage: NAME."); | |
239 | ||
240 | /* Get varobj handle, if a valid var obj name was specified */ | |
241 | var = varobj_get_handle (argv[0]); | |
242 | if (var == NULL) | |
243 | error ("mi_cmd_var_info_num_children: Variable object not found"); | |
244 | ||
245 | ui_out_field_int (uiout, "numchild", varobj_get_num_children (var)); | |
246 | return MI_CMD_DONE; | |
247 | } | |
248 | ||
249 | enum mi_cmd_result | |
250 | mi_cmd_var_list_children (char *command, char **argv, int argc) | |
251 | { | |
252 | struct varobj *var; | |
253 | struct varobj **childlist; | |
254 | struct varobj **cc; | |
255 | int numchild; | |
256 | char *type; | |
257 | ||
258 | if (argc != 1) | |
259 | error ("mi_cmd_var_list_children: Usage: NAME."); | |
260 | ||
261 | /* Get varobj handle, if a valid var obj name was specified */ | |
262 | var = varobj_get_handle (argv[0]); | |
263 | if (var == NULL) | |
264 | error ("mi_cmd_var_list_children: Variable object not found"); | |
265 | ||
266 | numchild = varobj_list_children (var, &childlist); | |
267 | ui_out_field_int (uiout, "numchild", numchild); | |
268 | ||
269 | if (numchild <= 0) | |
270 | return MI_CMD_DONE; | |
271 | ||
272 | ui_out_list_begin (uiout, "children"); | |
273 | cc = childlist; | |
274 | while (*cc != NULL) | |
275 | { | |
276 | ui_out_list_begin (uiout, "child"); | |
277 | ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); | |
278 | ui_out_field_string (uiout, "exp", varobj_get_expression (*cc)); | |
279 | ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc)); | |
280 | type = varobj_get_type (*cc); | |
281 | /* C++ pseudo-variables (public, private, protected) do not have a type */ | |
282 | if (type) | |
283 | ui_out_field_string (uiout, "type", varobj_get_type (*cc)); | |
284 | ui_out_list_end (uiout); | |
285 | cc++; | |
286 | } | |
287 | ui_out_list_end (uiout); | |
288 | free (childlist); | |
289 | return MI_CMD_DONE; | |
290 | } | |
291 | ||
292 | enum mi_cmd_result | |
293 | mi_cmd_var_info_type (char *command, char **argv, int argc) | |
294 | { | |
295 | struct varobj *var; | |
296 | ||
297 | if (argc != 1) | |
298 | error ("mi_cmd_var_info_type: Usage: NAME."); | |
299 | ||
300 | /* Get varobj handle, if a valid var obj name was specified */ | |
301 | var = varobj_get_handle (argv[0]); | |
302 | if (var == NULL) | |
303 | error ("mi_cmd_var_info_type: Variable object not found"); | |
304 | ||
305 | ui_out_field_string (uiout, "type", varobj_get_type (var)); | |
306 | return MI_CMD_DONE; | |
307 | } | |
308 | ||
309 | enum mi_cmd_result | |
310 | mi_cmd_var_info_expression (char *command, char **argv, int argc) | |
311 | { | |
312 | enum varobj_languages lang; | |
313 | struct varobj *var; | |
314 | ||
315 | if (argc != 1) | |
316 | error ("mi_cmd_var_info_expression: Usage: NAME."); | |
317 | ||
318 | /* Get varobj handle, if a valid var obj name was specified */ | |
319 | var = varobj_get_handle (argv[0]); | |
320 | if (var == NULL) | |
321 | error ("mi_cmd_var_info_expression: Variable object not found"); | |
322 | ||
323 | lang = varobj_get_language (var); | |
324 | ||
325 | ui_out_field_string (uiout, "lang", varobj_language_string[(int) lang]); | |
326 | ui_out_field_string (uiout, "exp", varobj_get_expression (var)); | |
327 | return MI_CMD_DONE; | |
328 | } | |
329 | ||
330 | enum mi_cmd_result | |
331 | mi_cmd_var_show_attributes (char *command, char **argv, int argc) | |
332 | { | |
333 | int attr; | |
334 | char *attstr; | |
335 | struct varobj *var; | |
336 | ||
337 | if (argc != 1) | |
338 | error ("mi_cmd_var_show_attributes: Usage: NAME."); | |
339 | ||
340 | /* Get varobj handle, if a valid var obj name was specified */ | |
341 | var = varobj_get_handle (argv[0]); | |
342 | if (var == NULL) | |
343 | error ("mi_cmd_var_show_attributes: Variable object not found"); | |
344 | ||
345 | attr = varobj_get_attributes (var); | |
346 | /* FIXME: define masks for attributes */ | |
347 | if (attr & 0x00000001) | |
348 | attstr = "editable"; | |
349 | else | |
350 | attstr = "noneditable"; | |
351 | ||
352 | ui_out_field_string (uiout, "attr", attstr); | |
353 | return MI_CMD_DONE; | |
354 | } | |
355 | ||
356 | enum mi_cmd_result | |
357 | mi_cmd_var_evaluate_expression (char *command, char **argv, int argc) | |
358 | { | |
359 | struct varobj *var; | |
360 | ||
361 | if (argc != 1) | |
362 | error ("mi_cmd_var_evaluate_expression: Usage: NAME."); | |
363 | ||
364 | /* Get varobj handle, if a valid var obj name was specified */ | |
365 | var = varobj_get_handle (argv[0]); | |
366 | if (var == NULL) | |
367 | error ("mi_cmd_var_evaluate_expression: Variable object not found"); | |
368 | ||
369 | ui_out_field_string (uiout, "value", varobj_get_value (var)); | |
370 | return MI_CMD_DONE; | |
371 | } | |
372 | ||
373 | enum mi_cmd_result | |
374 | mi_cmd_var_assign (char *command, char **argv, int argc) | |
375 | { | |
376 | struct varobj *var; | |
377 | char *expression; | |
378 | ||
379 | if (argc != 2) | |
380 | error ("mi_cmd_var_assign: Usage: NAME EXPRESSION."); | |
381 | ||
382 | /* Get varobj handle, if a valid var obj name was specified */ | |
383 | var = varobj_get_handle (argv[0]); | |
384 | if (var == NULL) | |
385 | error ("mi_cmd_var_assign: Variable object not found"); | |
386 | ||
387 | /* FIXME: define masks for attributes */ | |
388 | if (!(varobj_get_attributes (var) & 0x00000001)) | |
389 | error ("mi_cmd_var_assign: Variable object is not editable"); | |
390 | ||
391 | expression = xstrdup (argv[1]); | |
392 | ||
393 | if (!varobj_set_value (var, expression)) | |
394 | error ("mi_cmd_var_assign: Could not assign expression to varible object"); | |
395 | ||
396 | ui_out_field_string (uiout, "value", varobj_get_value (var)); | |
397 | return MI_CMD_DONE; | |
398 | } | |
399 | ||
400 | enum mi_cmd_result | |
401 | mi_cmd_var_update (char *command, char **argv, int argc) | |
402 | { | |
403 | struct varobj *var; | |
404 | struct varobj **rootlist; | |
405 | struct varobj **cr; | |
406 | char *name; | |
407 | int nv; | |
408 | ||
409 | if (argc != 1) | |
410 | error ("mi_cmd_var_update: Usage: NAME."); | |
411 | ||
412 | name = argv[0]; | |
413 | ||
414 | /* Check if the parameter is a "*" which means that we want | |
415 | to update all variables */ | |
416 | ||
417 | if ((*name == '*') && (*(name + 1) == '\0')) | |
418 | { | |
419 | nv = varobj_list (&rootlist); | |
420 | ui_out_list_begin (uiout, "changelist"); | |
421 | if (nv <= 0) | |
422 | { | |
423 | ui_out_list_end (uiout); | |
424 | return MI_CMD_DONE; | |
425 | } | |
426 | cr = rootlist; | |
427 | while (*cr != NULL) | |
428 | { | |
429 | varobj_update_one (*cr); | |
430 | cr++; | |
431 | } | |
432 | free (rootlist); | |
433 | ui_out_list_end (uiout); | |
434 | } | |
435 | else | |
436 | { | |
437 | /* Get varobj handle, if a valid var obj name was specified */ | |
438 | var = varobj_get_handle (name); | |
439 | if (var == NULL) | |
440 | error ("mi_cmd_var_update: Variable object not found"); | |
441 | ||
442 | ui_out_list_begin (uiout, "changelist"); | |
443 | varobj_update_one (var); | |
444 | ui_out_list_end (uiout); | |
445 | } | |
446 | return MI_CMD_DONE; | |
447 | } | |
448 | ||
449 | /* Helper for mi_cmd_var_update() */ | |
450 | ||
451 | static void | |
452 | varobj_update_one (struct varobj *var) | |
453 | { | |
454 | struct varobj **changelist; | |
455 | struct varobj **cc; | |
456 | int nc; | |
457 | ||
458 | nc = varobj_update (var, &changelist); | |
459 | ||
460 | if (nc <= 0) | |
461 | return; | |
462 | ||
463 | cc = changelist; | |
464 | while (*cc != NULL) | |
465 | { | |
466 | ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); | |
467 | cc++; | |
468 | } | |
469 | free (changelist); | |
470 | } | |
471 | ||
472 | /* Local variables: */ | |
473 | /* change-log-default-name: "ChangeLog-mi" */ | |
474 | /* End: */ |