1# Copyright 2012-2020 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16standard_testfile
17
18if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
19    return -1
20}
21
22# Skip all tests if Python scripting is not enabled.
23if { [skip_python_tests] } { continue }
24
25set SS "struct SimpleStruct"
26set SU "union SimpleUnion"
27set CS "struct ComplexStruct"
28set CU "union ComplexUnion"
29set enter_field_number_prompt  {Enter the field number of choice: }
30set return_to_parent_prompt {Press enter to return to parent value: }
31set array_index_prompt {Enter the index of the element you want to explore in .*: }
32
33proc compound_description { value_name type_desc type_name } {
34    return "The value of '$value_name' is a $type_desc of type '$type_name' with the following fields:\[\r\n\]+"
35}
36
37proc typedef_description { value_name typedef_name type_name } {
38    return "The value of '$value_name' is of type '$typedef_name' which is a typedef of type '$type_name'\.\[\r\n\]+"
39}
40
41proc scalar_description { value_name type } {
42    return "'$value_name' is a scalar value of type '$type'\.\[\r\n\]+"
43}
44
45proc array_description { value_name type } {
46    return "'$value_name' is an array of '$type'\.\[\r\n\]+"
47}
48
49proc pointer_description { value_name type_name } {
50    set type_description "'$value_name' is a pointer to a value of type '$type_name'\.\[\r\n\]+"
51    set prompt "Continue exploring it as a pointer to a single value \[\[\]y/n\[\]\]: "
52    return "$type_description$prompt"
53}
54
55proc field_values { args } {
56    set result ""
57    foreach field $args {
58        set result "$result\[ \]*$field \[\.\]\[\.\] \[\(\]Value of type .*\[\)\]\[\r\n\]+"
59    }
60    return $result
61}
62
63proc field_choices { args } {
64    set result ""
65    set field_num 0
66    foreach field $args {
67        set result "$result$field\[ \]+=\[ \]+<Enter $field_num to explore this field of type .*"
68        incr field_num
69    }
70    return $result
71}
72
73proc scalar_value { value_name value } {
74    return "$value_name = $value\[r\n\]+"
75}
76
77set SS_fields [field_values {a = 10} {d = 100[.].*}]
78
79if ![runto_main] {
80   return -1
81}
82
83gdb_breakpoint [gdb_get_line_number "Break here."]
84gdb_continue_to_breakpoint "Break here" ".*Break here.*"
85
86#########################
87# Value exploration tests
88#########################
89
90gdb_test "explore i" "[scalar_description {i} {int}].*i = .*"
91gdb_test "explore ss" "[compound_description {ss} {struct/class} $SS].*$SS_fields"
92gdb_test "explore *ss_ptr" "[compound_description {\*ss_ptr} {struct/class} $SS].*$SS_fields"
93gdb_test "explore ss_t" "[typedef_description {ss_t} {SS} $SS].*[compound_description {ss_t} {struct/class} $SS].*$SS_fields"
94
95gdb_test_multiple "explore ss_ptr" "" {
96    -re "[pointer_description {ss_ptr} $SS].*" {
97        pass "explore ss_ptr"
98        gdb_test_multiple "y" "explore_as_single_value_pointer" {
99            -re "$SS_fields.*$gdb_prompt" {
100                pass "explore ss_ptr as single value pointer"
101            }
102        }
103    }
104}
105
106gdb_test_multiple "explore darray_ref" "" {
107    -re "[pointer_description {darray_ref} {double}].*" {
108        pass "explore darray_ref"
109        gdb_test_multiple "n" "no_to_explore_as_pointer" {
110            -re "Continue exploring it as a pointer to an array \[\[\]y/n\[\]\]: " {
111                pass "no_to_explore_as_pointer"
112                gdb_test_multiple "y" "explore_as_array" {
113                    -re ".*Enter the index of the element you want to explore in 'darray_ref':.*"  {
114                        pass "explore_as_array"
115                        gdb_test_multiple "2" "explore_as_array_index_2" {
116                            -re ".*'darray_ref\\\[2\\\]' is a scalar value of type 'double'\..*darray_ref\\\[2\\\] = 0.*" {
117                                pass "explore_as_array_index_2"
118                                gdb_test_multiple "\0" "end explore_as_array_index_2" {
119                                    -re ".*Returning to parent value.*Enter the index of the element you want to explore in 'darray_ref':.*" {
120                                        pass "end explore_as_array_index_2"
121                                        gdb_test_multiple "\0" "end explore_as_array" {
122                                            -re "\[\n\r\]+$gdb_prompt" {
123                                                pass "end explore_as_array"
124                                            }
125                                        }
126                                    }
127                                }
128                            }
129                        }
130                    }
131                }
132            }
133        }
134    }
135}
136
137gdb_test_multiple "explore su" "" {
138    -re "[compound_description {su} {union} {union SimpleUnion}].*[field_choices {i} {c} {f} {d}].*$enter_field_number_prompt" {
139        pass "explore su"
140        gdb_test_multiple "3" "explore su.d" {
141            -re "[scalar_description {su.d} {double}].*[scalar_value {su.d} {100[.].*}].*$return_to_parent_prompt" {
142                pass "explore su.d"
143                gdb_test_multiple " " "end su.d exploration" {
144                    -re ".*[compound_description {su} {union} {union SimpleUnion}].*[field_choices {i} {c} {f} {d}].*$enter_field_number_prompt" {
145                        pass "end su.d exploration"
146                        gdb_test_multiple "\0" "end su exploration" {
147                            -re "$gdb_prompt" {
148                                pass "end su exploration"
149                            }
150                        }
151                    }
152                }
153            }
154        }
155    }
156}
157
158gdb_test_multiple "explore cs" "" {
159    -re "[compound_description {cs} {struct/class} {struct ComplexStruct}].*[field_choices {s} {u} {sa}].*$enter_field_number_prompt" {
160        pass "explore cs"
161        gdb_test_multiple "0" "explore cs.s" {
162            -re "[compound_description {cs.s} {struct/class} {struct SimpleStruct}].*[field_values {a = 10} {d = 100[.].*}].*$return_to_parent_prompt" {
163                pass "explore cs.s"
164                gdb_test_multiple " " "end cs.s exploration" {
165                    -re ".*$enter_field_number_prompt" {
166                        pass "end cs.s exploration"
167                    }
168                }
169            }
170        }
171        gdb_test_multiple "1" "explore cs.u" {
172            -re "[compound_description {cs.u} {union} {union SimpleUnion}].*.*[field_choices {i} {c} {f} {d}].*$enter_field_number_prompt" {
173                pass "explore cs.u"
174                gdb_test_multiple " " "end cs.u exploration" {
175                    -re ".*$enter_field_number_prompt" {
176                        pass "end cs.u exploration"
177                    }
178                }
179            }
180        }
181        gdb_test_multiple "\0" "explore cs.u" {
182            -re "$gdb_prompt" {
183                pass "end cs exploration"
184            }
185        }
186    }
187}
188
189gdb_test_multiple "explore cu" "" {
190    -re "[compound_description {cu} {union} {union ComplexUnion}].*[field_choices {s} {sa}].*$enter_field_number_prompt" {
191        pass "explore cu"
192        gdb_test_multiple "1" "explore cu.sa" {
193            -re ".*[array_description {cu.sa} $SS].*$array_index_prompt" {
194                pass "explore cu.sa"
195                gdb_test_multiple "0" "explore cu.sa\[0\]" {
196                    -re "[compound_description {\(cu.sa\)\[0\]} {struct/class} {struct SimpleStruct}].*[field_values {a = 0} {d = 100[.].*}].*$return_to_parent_prompt" {
197                        pass "explore cu.sa\[0\]"
198                        gdb_test_multiple "\0" "end cu.sa\[0\] exploration" {
199                            -re "[array_description {cu.sa} $SS]$array_index_prompt" {
200                                pass "end cu.sa\[0\] exploration"
201                            }
202                        }
203                    }
204                }
205                gdb_test_multiple "\0" "end cu.sa exploration" {
206                    -re ".*$enter_field_number_prompt" {
207                        pass "end cu.sa exploration"
208                        gdb_test_multiple "\0" "end cu exploration" {
209                            -re "$gdb_prompt" {
210                                pass "end cu exploration"
211                            }
212                        }
213                    }
214                }
215            }
216        }
217    }
218}
219
220########################
221# Type exploration tests
222########################
223
224proc scalar_type_decsription {type} {
225    return "'$type' is a scalar type\."
226}
227
228proc child_scalar_type_description {path type} {
229    return "$path is of a scalar type '$type'\."
230}
231
232proc compound_type_description { type_name type_desc } {
233    return "'$type_name' is a $type_desc with the following fields:"
234}
235
236proc child_compound_type_description { path type_name type_desc } {
237    return "$path is a $type_desc of type '$type_name' with the following fields:"
238}
239
240proc child_array_type_description { path target_type_name } {
241    return "$path is an array of '$target_type_name'\."
242}
243
244proc typedef_type_description { type_name target_name } {
245    return "The type '$type_name' is a typedef of type '$target_name'\."
246}
247
248set SS_fields_types [field_choices {a} {d}]
249set SU_fields_types [field_choices {i} {c} {f} {d}]
250set CS_fields_types [field_choices {s} {u} {sa}]
251set CU_fields_types [field_choices {s} {sa}]
252
253set CS_field_0 "field 's' of 'struct ComplexStruct'"
254set CS_field_1 "field 'u' of 'struct ComplexStruct'"
255set CS_field_2 "field 'sa' of 'struct ComplexStruct'"
256set CS_field_2_array_element "an array element of $CS_field_2"
257
258set CU_field_0 "field 's' of 'union ComplexUnion'"
259set CU_field_1 "field 'sa' of 'union ComplexUnion'"
260set CU_field_1_array_element "an array element of $CU_field_1"
261
262gdb_test "explore int" ".*[scalar_type_decsription {int}].*"
263
264gdb_test_multiple "explore struct SimpleStruct" "" {
265    -re ".*[compound_type_description $SS {struct/class}].*$SS_fields_types.*" {
266        pass "explore struct SimpleStruct"
267        gdb_test_multiple "0" "explore type struct SimpleStruct feild 0" {
268            -re ".*[child_scalar_type_description {field 'a' of 'struct SimpleStruct'} {int}].*" {
269                pass "explore type struct SimpleStruct feild 0"
270                gdb_test_multiple "\0" "return to struct SimpleStruct from field 0" {
271                    -re ".*[compound_type_description $SS {struct/class}].*$SS_fields_types.*" {
272                        pass "return to struct SimpleStruct from field 0"
273                    }
274                }
275            }
276        }
277        gdb_test_multiple "1" "explore type struct SimpleStruct feild 1" {
278            -re ".*[child_scalar_type_description {field 'd' of 'struct SimpleStruct'} {double}].*" {
279                pass "explore type struct SimpleStruct feild 1"
280                gdb_test_multiple "\0" "return to struct SimpleStruct from field 1" {
281                    -re ".*[compound_type_description $SS {struct/class}].*$SS_fields_types.*" {
282                        pass "return to struct SimpleStruct from field 1"
283                    }
284                }
285            }
286        }
287        gdb_test_multiple "\0" "return to GDB prompt from struct SimpleStruct" {
288            -re "$gdb_prompt" {
289                pass "return to GDB prompt from struct SimpleStruct"
290            }
291        }
292    }
293}
294
295gdb_test_multiple "explore union SimpleUnion" "" {
296  -re ".*[compound_type_description $SU {union}].*$SU_fields_types.*" {
297      pass "explore union SimpleUnion"
298        gdb_test_multiple "0" "explore type union SimpleUnion feild 0" {
299            -re ".*[child_scalar_type_description {field 'i' of 'union SimpleUnion'} {int}].*" {
300                pass "explore type union SimpleUnion feild 0"
301                gdb_test_multiple "\0" "return to union SimpleUnion from field 0" {
302                    -re ".*[compound_type_description $SU {union}].*$SU_fields_types.*" {
303                        pass "return to union SimpleUnion from field 0"
304                    }
305                }
306            }
307        }
308        gdb_test_multiple "1" "explore type union SimpleUnion feild 1" {
309            -re ".*[child_scalar_type_description {field 'c' of 'union SimpleUnion'} {char}].*" {
310                pass "explore type union SimpleUnion feild 1"
311                gdb_test_multiple "\0" "return to union SimpleUnion from field 1" {
312                    -re ".*[compound_type_description $SU {union}].*$SU_fields_types.*" {
313                        pass "return to union SimpleUnion from field 1"
314                    }
315                }
316            }
317        }
318        gdb_test_multiple "2" "explore type union SimpleUnion feild 2" {
319            -re ".*[child_scalar_type_description {field 'f' of 'union SimpleUnion'} {float}].*" {
320                pass "explore type union SimpleUnion feild 2"
321                gdb_test_multiple "\0" "return to union SimpleUnion from field 2" {
322                    -re ".*[compound_type_description $SU {union}].*$SU_fields_types.*" {
323                        pass "return to union SimpleUnion from field 2"
324                    }
325                }
326            }
327        }
328        gdb_test_multiple "3" "explore type union SimpleUnion feild 3" {
329            -re ".*[child_scalar_type_description {field 'd' of 'union SimpleUnion'} {double}].*" {
330                pass "explore type union SimpleUnion feild 3"
331                gdb_test_multiple "\0" "return to union SimpleUnion from field 3" {
332                    -re ".*[compound_type_description $SU {union}].*$SU_fields_types.*" {
333                        pass "return to union SimpleUnion from field 3"
334                    }
335                }
336            }
337        }
338        gdb_test_multiple "\0" "return to GDB prompt from union SimpleUnion" {
339            -re "$gdb_prompt" {
340                pass "return to GDB prompt from union SimpleUnion"
341            }
342        }
343  }
344}
345
346gdb_test_multiple "explore SS" "" {
347    -re ".*[typedef_type_description {SS} $SS].*[compound_type_description {SS} {struct/class}].*$SS_fields_types.*" {
348        pass "explore SS"
349        gdb_test_multiple "0" "explore type SS feild 0" {
350            -re ".*[child_scalar_type_description {field 'a' of 'SS'} {int}].*" {
351                pass "explore type SS feild 0"
352                gdb_test_multiple "\0" "return to SS from field 0" {
353                    -re ".*[compound_type_description {SS} {struct/class}].*$SS_fields_types.*" {
354                        pass "return to SS from field 0"
355                    }
356                }
357            }
358        }
359        gdb_test_multiple "1" "explore type SS feild 1" {
360            -re ".*[child_scalar_type_description {field 'd' of 'SS'} {double}].*" {
361                pass "explore type SS feild 1"
362                gdb_test_multiple "\0" "return to struct SimpleStruct from field 1" {
363                    -re ".*[compound_type_description {SS} {struct/class}].*$SS_fields_types.*" {
364                        pass "return to SS field 1"
365                    }
366                }
367            }
368        }
369        gdb_test_multiple "\0" "return to GDB prompt from SS" {
370            -re "$gdb_prompt" {
371                pass "return to GDB prompt from SS"
372            }
373        }
374    }
375}
376
377gdb_test_multiple "explore type struct ComplexStruct" "" {
378    -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
379        pass "explore type struct ComplexStruct"
380        gdb_test_multiple "0" "explore type struct ComplexStruct field 0" {
381            -re ".*[child_compound_type_description $CS_field_0 $SS {struct/class}].*$SS_fields_types.*" {
382                pass "explore type struct ComplexStruct field 0"
383                gdb_test_multiple "\0" "return to ComplexStruct from field 0" {
384                    -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
385                        pass "return to ComplexStruct from field 0"
386                    }
387                }
388            }
389        }
390        gdb_test_multiple "1" "explore type struct ComplexStruct field 1" {
391            -re ".*[child_compound_type_description $CS_field_1 $SU {union}].*$SU_fields_types.*" {
392                pass "explore type struct ComplexStruct field 1"
393                gdb_test_multiple "\0" "return to ComplexStruct from field 1" {
394                    -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
395                        pass "return to ComplexStruct from field 1"
396                    }
397                }
398            }
399        }
400        gdb_test_multiple "2" "explore type struct ComplexStruct field 2" {
401            -re ".*[child_array_type_description $CS_field_2 {SS}].*" {
402                pass "explore type struct ComplexStruct field 2"
403                gdb_test_multiple "\0" "return to ComplexStruct from field 2" {
404                    -re ".*[compound_type_description $CS {struct/class}].*$CS_fields_types.*" {
405                        pass "return to ComplexStruct from field 2"
406                    }
407                }
408            }
409        }
410        gdb_test_multiple "\0" "return to GDB prompt from ComplexStruct type exploration" {
411            -re "$gdb_prompt" {
412                pass "return to GDB prompt from ComplexStruct type exploration"
413            }
414        }
415    }
416}
417
418gdb_test_multiple "explore type union ComplexUnion" "" {
419    -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
420        pass "explore type union ComplexUnion"
421        gdb_test_multiple "0" "explore type union ComplexStruct field 0" {
422            -re ".*[child_compound_type_description $CU_field_0 $SS {struct/class}].*$SS_fields_types.*" {
423                pass "explore type union ComplexUnion field 0"
424                gdb_test_multiple "\0" "return to ComplexUnion from field 0" {
425                    -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
426                        pass "return to ComplexUnion from field 0"
427                    }
428                }
429            }
430        }
431        gdb_test_multiple "1" "explore type union ComplexUnion field 1" {
432            -re ".*[child_array_type_description $CU_field_1 $SS].*" {
433                pass "explore type union ComplexUnion field 1"
434                gdb_test_multiple "\0" "return to ComplexUnion array" {
435                    -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
436                        pass "return to ComplexUnion from field 1"
437                    }
438                }
439            }
440        }
441        gdb_test_multiple "\0" "return to GDB prompt from ComplexUnion type exploration" {
442            -re "$gdb_prompt" {
443                pass "return to GDB prompt from ComplexUnion type exploration"
444            }
445        }
446    }
447}
448
449gdb_test_multiple "explore type cu" "" {
450    -re "'cu' is of type 'union ComplexUnion'.*[compound_type_description $CU {union}].*$CU_fields_types.*" {
451        pass "explore type union ComplexUnion"
452        gdb_test_multiple "0" "explore type union ComplexStruct field 0" {
453            -re ".*[child_compound_type_description $CU_field_0 $SS {struct/class}].*$SS_fields_types.*" {
454                pass "explore type union ComplexUnion field 0"
455                gdb_test_multiple "\0" "return to ComplexUnion from field 0" {
456                    -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
457                        pass "return to ComplexUnion from field 0"
458                    }
459                }
460            }
461        }
462        gdb_test_multiple "1" "explore type union ComplexUnion field 1" {
463            -re ".*[child_array_type_description $CU_field_1 $SS].*" {
464                pass "explore type union ComplexUnion field 1"
465                gdb_test_multiple "\0" "return to ComplexUnion array" {
466                    -re ".*[compound_type_description $CU {union}].*$CU_fields_types.*" {
467                        pass "return to ComplexUnion from field 1"
468                    }
469                }
470            }
471        }
472        gdb_test_multiple "\0" "return to GDB prompt from ComplexUnion type exploration" {
473            -re "$gdb_prompt" {
474                pass "return to GDB prompt from ComplexUnion type exploration"
475            }
476        }
477    }
478}
479