xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.python/py-parameter.exp (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1# Copyright (C) 2010-2023 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
16# This file is part of the GDB testsuite.
17# It tests gdb.parameter and gdb.Parameter.
18
19load_lib gdb-python.exp
20
21# Start with a fresh gdb.
22clean_restart
23
24# Skip all tests if Python scripting is not enabled.
25if { [skip_python_tests] } { continue }
26
27proc py_param_test_maybe_no_output { command pattern args } {
28    if [string length $pattern] {
29	gdb_test $command $pattern $args
30    } else {
31	gdb_test_no_output $command $args
32    }
33}
34
35proc_with_prefix test_directories { } {
36    # We use "." here instead of ":" so that this works on win32 too.
37    if { [is_remote host] } {
38	# Don't match $srcdir/$subdir because proc gdb_reinitialize_dir
39	# doesn't set search directories on remote host.
40	set directories ".*\\\$cdir.\\\$cwd"
41    } else {
42	set escaped_directory [string_to_regexp "$::srcdir/$::subdir"]
43	set directories "$escaped_directory.\\\$cdir.\\\$cwd"
44    }
45    gdb_test "python print (gdb.parameter ('directories'))" $directories
46}
47
48proc_with_prefix test_data_directory { } {
49    clean_restart
50
51    # Check we can correctly read the data-directory parameter.  First,
52    # grab the value as read directly from the GDB CLI.
53    set dd ""
54    gdb_test_multiple "show data-directory" \
55	"find the initial data-directory value" {
56	    -re -wrap "GDB's data directory is \"(\[^\r\n\]+)\"\\." {
57		set dd $expect_out(1,string)
58		pass $gdb_test_name
59	    }
60	}
61
62    # Now print the data-directory from Python.
63    gdb_test "python print (gdb.parameter ('data-directory'))" $dd
64
65    # Next change the data-directory to a relative path.  Internally GDB
66    # will resolve this to an absolute path, which Python should then see.
67    #
68    # GDB is currently running in '...../build/gdb/testsuite/' and the
69    # test output is being written to:
70    #   ...../build/gdb/testsuite/outputs/gdb.python/py-parameter/
71    #
72    # So create the relative path './outputs/gdb.python/py-parameter/' and
73    # set the data-directory to that, we should then see the absolute path.
74
75    set abs_path_to_output_dir [standard_output_file ""]
76    set abs_path_to_cwd $::objdir
77    set rel_path_to_output_dir \
78	[file join "." [string replace ${abs_path_to_output_dir} 0 \
79			    [string length ${abs_path_to_cwd}] ""]]
80    gdb_test_no_output "set data-directory ${rel_path_to_output_dir}"
81
82    gdb_test "python print (gdb.parameter ('data-directory'))" \
83	${abs_path_to_output_dir} \
84	"python sees absolute version of data-directory path"
85
86    # While we're here, check we see the correct path at GDB's CLI.
87    gdb_test "show data-directory" \
88	"GDB's data directory is \"${abs_path_to_output_dir}\"\\." \
89	"check modified data-directory at the CLI"
90
91    # Now lets set the data-directory back to what it was initially.
92    gdb_test_no_output "set data-directory ${dd}" \
93	"set data-directory back to its original value"
94
95    # And check we see the restored value at CLI and from Python.
96    gdb_test "show data-directory" \
97	"GDB's data directory is \"${dd}\"\\." \
98	"check original data-directory was restored at the CLI"
99
100    gdb_test "python print (gdb.parameter ('data-directory'))" ${dd} \
101	"python sees restored data-directory value"
102}
103
104# Test a simple boolean parameter.
105proc_with_prefix test_boolean_parameter { } {
106    clean_restart
107
108    gdb_test_multiline "Simple gdb booleanparameter" \
109	"python" "" \
110	"class TestParam (gdb.Parameter):" "" \
111	"   \"\"\"When enabled, test param does something useful. When disabled, does nothing.\"\"\"" "" \
112	"   show_doc = \"Show the state of the boolean test-param\"" ""\
113	"   set_doc = \"Set the state of the boolean test-param\"" "" \
114	"   def get_show_string (self, pvalue):" ""\
115	"      return \"The state of the Test Parameter is \" + pvalue" ""\
116	"   def get_set_string (self):" ""\
117	"      val = \"on\"" ""\
118	"      if (self.value == False):" ""\
119	"         val = \"off\"" ""\
120	"      return \"Test Parameter has been set to \" + val" ""\
121	"   def __init__ (self, name):" "" \
122	"      super (TestParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)" "" \
123	"      self.value = True" "" \
124	"test_param = TestParam ('print test-param')" ""\
125	"end"
126
127    gdb_test "python print (test_param.value)" "True" \
128	"test boolean parameter value is True"
129    gdb_test "show print test-param" \
130	"The state of the Test Parameter is on.*" "show parameter on"
131    gdb_test "set print test-param off" \
132	"Test Parameter has been set to off" "turn off parameter"
133    gdb_test "show print test-param" \
134	"The state of the Test Parameter is off.*" "show parameter off"
135    gdb_test "python print (test_param.value)" "False" \
136	"test boolean parameter value is False"
137    gdb_test_no_output "python gdb.set_parameter('print test-param', True)" \
138	"set boolean parameter using set_parameter"
139    gdb_test "python print(gdb.parameter('print test-param'))" "True" \
140	"get boolean parameter using gdb.parameter"
141    gdb_test "help show print test-param" \
142	[multi_line \
143	     "Show the state of the boolean test-param" \
144	     "When enabled, test param does something useful\\. When disabled, does nothing\\."] \
145	"test show help"
146    gdb_test "help set print test-param" \
147	"Set the state of the boolean test-param.*" "test set help"
148    gdb_test "help set print" \
149	"set print test-param -- Set the state of the boolean test-param.*" \
150	"test general help"
151}
152
153# Test an enum parameter.
154proc_with_prefix test_enum_parameter { } {
155    clean_restart
156
157    gdb_test_multiline "enum gdb parameter" \
158	"python" "" \
159	"class TestEnumParam (gdb.Parameter):" "" \
160	"   \"\"\"When set, test param does something useful. When disabled, does nothing.\"\"\"" "" \
161	"   show_doc = \"Show the state of the enum\"" ""\
162	"   set_doc = \"Set the state of the enum\"" "" \
163	"   def get_show_string (self, pvalue):" ""\
164	"      return \"The state of the enum is \" + pvalue" ""\
165	"   def get_set_string (self):" ""\
166	"      return \"The state of the enum has been set to \" + self.value" ""\
167	"   def __init__ (self, name):" "" \
168	"      super (TestEnumParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_ENUM, \[\"one\", \"two\"\])" "" \
169	"      self.value = \"one\"" "" \
170	"test_enum_param = TestEnumParam ('print test-enum-param')" ""\
171	"end"
172
173    gdb_test "python print (test_enum_param.value)" "one" \
174	"test enum parameter value is one"
175    gdb_test "show print test-enum-param" \
176	"The state of the enum is one.*" \
177	"show parameter is initial value"
178    gdb_test "set print test-enum-param two" \
179	"The state of the enum has been set to two" "set enum to two"
180    gdb_test "show print test-enum-param" \
181	"The state of the enum is two.*" "show parameter is new value"
182    gdb_test "python print (test_enum_param.value)" "two" \
183	"test enum parameter value is two"
184    gdb_test "set print test-enum-param three" \
185	"Undefined item: \"three\".*" "set invalid enum parameter"
186}
187
188# Test a file parameter.
189proc_with_prefix test_file_parameter { } {
190    clean_restart
191
192    gdb_test_multiline "file gdb parameter" \
193	"python" "" \
194	"class TestFileParam (gdb.Parameter):" "" \
195	"   \"\"\"When set, test param does something useful. When disabled, does nothing.\"\"\"" "" \
196	"   show_doc = \"Show the name of the file\"" ""\
197	"   set_doc = \"Set the name of the file\"" "" \
198	"   def get_show_string (self, pvalue):" ""\
199	"      return \"The name of the file is \" + pvalue" ""\
200	"   def get_set_string (self):" ""\
201	"      return \"The name of the file has been changed to \" + self.value" ""\
202	"   def __init__ (self, name):" "" \
203	"      super (TestFileParam, self).__init__ (name, gdb.COMMAND_FILES, gdb.PARAM_FILENAME)" "" \
204	"      self.value = \"foo.txt\"" "" \
205	"test_file_param = TestFileParam ('test-file-param')" ""\
206	"end"
207
208    gdb_test "python print (test_file_param.value)" "foo.txt" \
209	"test file parameter value"
210    gdb_test "show test-file-param" \
211	"The name of the file is foo.txt.*" "show initial file value"
212    gdb_test "set test-file-param bar.txt" \
213	"The name of the file has been changed to bar.txt" \
214	"set new file parameter"
215    gdb_test "show test-file-param" \
216	"The name of the file is bar.txt.*" "show new file value"
217    gdb_test "python print (test_file_param.value)" \
218	"bar.txt" "test new file parameter value"
219    gdb_test "set test-file-param" "Argument required.*"
220}
221
222# Test a parameter that is not documented.
223proc_with_prefix test_undocumented_parameter { } {
224    clean_restart
225
226    gdb_test_multiline "Simple gdb booleanparameter" \
227	"python" "" \
228	"class TestUndocParam (gdb.Parameter):" "" \
229	"   def get_show_string (self, pvalue):" ""\
230	"      return \"The state of the Test Parameter is \" + pvalue" ""\
231	"   def get_set_string (self):" ""\
232	"      val = \"on\"" ""\
233	"      if (self.value == False):" ""\
234	"         val = \"off\"" ""\
235	"      return \"Test Parameter has been set to \" + val" ""\
236	"   def __init__ (self, name):" "" \
237	"      super (TestUndocParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)" "" \
238	"      self.value = True" "" \
239	"test_undoc_param = TestUndocParam ('print test-undoc-param')" ""\
240	"end"
241
242    gdb_test "show print test-undoc-param" \
243	"The state of the Test Parameter is on.*" "show parameter on"
244    gdb_test "set print test-undoc-param off" \
245	"Test Parameter has been set to off" "turn off parameter"
246    gdb_test "show print test-undoc-param" \
247	"The state of the Test Parameter is off.*" "show parameter off"
248    gdb_test "python print (test_undoc_param.value)" \
249	"False" "test undocumented parameter value is False"
250    gdb_test "help show print test-undoc-param" \
251	[multi_line \
252	     "Show the current value of 'print test-undoc-param'\\." \
253	     "This command is not documented.*"] \
254	"test show help"
255    gdb_test "help set print test-undoc-param" \
256	"This command is not documented.*" "test set help"
257    gdb_test "help set print" \
258	"set print test-undoc-param -- Set the current value of 'print test-undoc-param'\\..*" \
259	"test general help"
260}
261
262# Test a parameter that is not documented in any way..
263proc_with_prefix test_really_undocumented_parameter { } {
264    clean_restart
265
266    gdb_test_multiline "Simple gdb booleanparameter" \
267	"python" "" \
268	"class TestNodocParam (gdb.Parameter):" "" \
269	"   def __init__ (self, name):" "" \
270	"      super (TestNodocParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)" "" \
271	"      self.value = True" "" \
272	"test_nodoc_param = TestNodocParam ('print test-nodoc-param')" ""\
273	"end"
274
275    gdb_test "show print test-nodoc-param" \
276	"The current value of 'print test-nodoc-param' is \"on\"\\." \
277	"show parameter on"
278    gdb_test_no_output "set print test-nodoc-param off" \
279	"turn off parameter"
280    gdb_test "show print test-nodoc-param" \
281	"The current value of 'print test-nodoc-param' is \"off\"\\." \
282	"show parameter off"
283    gdb_test "python print (test_nodoc_param.value)" \
284	"False" "test really undocumented parameter value is False"
285    gdb_test "help show print test-nodoc-param" \
286	[multi_line \
287	     "Show the current value of 'print test-nodoc-param'\\." \
288	     "This command is not documented.*"] \
289	"test show help"
290    gdb_test "help set print test-nodoc-param" \
291	"This command is not documented.*" "test set help"
292    gdb_test "help set print" \
293	"set print test-nodoc-param -- Set the current value of 'print test-nodoc-param'\\..*" \
294	"test general help"
295}
296
297# Test deprecated API. Do not use in your own implementations.
298proc_with_prefix test_deprecated_api_parameter { } {
299    clean_restart
300
301    gdb_test_multiline "Simple gdb booleanparameter" \
302	"python" "" \
303	"class TestParam (gdb.Parameter):" "" \
304	"   \"\"\"When enabled, test param does something useful. When disabled, does nothing.\"\"\"" "" \
305	"   show_doc = \"State of the Test Parameter\"" ""\
306	"   set_doc = \"Set the state of the Test Parameter\"" "" \
307	"   def __init__ (self, name):" "" \
308	"      super (TestParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)" "" \
309	"      self.value = True" "" \
310	"test_param = TestParam ('print test-param')" ""\
311	"end"
312
313    gdb_test "python print (test_param.value)" "True" \
314	"test deprecated API parameter value is True"
315    gdb_test "show print test-param" \
316	"The current value of 'print test-param' is \"on\"\\." \
317	"show parameter on"
318    gdb_test_no_output "set print test-param off" "turn off parameter"
319    gdb_test "show print test-param" \
320	"The current value of 'print test-param' is \"off\"\\." \
321	"show parameter off"
322    gdb_test "python print (test_param.value)" "False" \
323	"test deprecated API parameter value is False"
324    gdb_test "help show print test-param" \
325	[multi_line \
326	     "State of the Test Parameter" \
327	     "When enabled, test param does something useful\\. When disabled, does nothing\\."] \
328	"test show help"
329    gdb_test "help set print test-param" \
330	"Set the state of the Test Parameter.*" "test set help"
331    gdb_test "help set print" \
332	"set print test-param -- Set the state of the Test Parameter.*" \
333	"test general help"
334}
335
336proc_with_prefix test_gdb_parameter { } {
337    foreach_with_prefix param {
338	"listsize"
339	"print elements"
340	"max-completions"
341    } {
342	clean_restart
343
344	set param_range_error ".*gdb.error: integer -1 out of range.*"
345	switch -- $param {
346	    "listsize" {
347		set param_get_zero None
348		set param_get_minus_one -1
349		set param_get_none None
350		set param_get_unlimited None
351		set param_set_minus_one ""
352	    }
353	    "print elements" {
354		set param_get_zero None
355		set param_get_minus_one None
356		set param_get_none None
357		set param_get_unlimited None
358		set param_set_minus_one $param_range_error
359	    }
360	    "max-completions" {
361		set param_get_zero 0
362		set param_get_minus_one -1
363		set param_get_none -1
364		set param_get_unlimited -1
365		set param_set_minus_one ""
366	    }
367	    default {
368		error "invalid param: $param"
369	    }
370	}
371
372	gdb_test_no_output "python gdb.set_parameter('$param', 1)" \
373	    "test set to 1"
374
375	gdb_test "python print(gdb.parameter('$param'))" \
376	    1 "test value of 1"
377
378	gdb_test_no_output "python gdb.set_parameter('$param', 0)" \
379	    "test set to 0"
380
381	gdb_test "python print(gdb.parameter('$param'))" \
382	    $param_get_zero "test value of 0"
383
384	py_param_test_maybe_no_output \
385	    "python gdb.set_parameter('$param', -1)" \
386	    $param_set_minus_one "test set to -1"
387
388	gdb_test "python print(gdb.parameter('$param'))" \
389	    $param_get_minus_one "test value of -1"
390
391	gdb_test_no_output "python gdb.set_parameter('$param', None)" \
392	    "test set to None"
393
394	gdb_test "python print(gdb.parameter('$param'))" \
395	    $param_get_none "test value of None"
396
397	gdb_test_no_output "python gdb.set_parameter('$param', 'unlimited')" \
398	    "test set to 'unlimited'"
399
400	gdb_test "python print(gdb.parameter('$param'))" \
401	    $param_get_unlimited "test value of 'unlimited'"
402    }
403
404    clean_restart
405
406    # This caused a gdb crash.
407    gdb_test "python print(gdb.parameter('endian'))" "auto" \
408	"print endian parameter"
409}
410
411proc_with_prefix test_integer_parameter { } {
412    foreach_with_prefix kind {
413	PARAM_UINTEGER
414	PARAM_INTEGER
415	PARAM_ZINTEGER
416	PARAM_ZUINTEGER
417	PARAM_ZUINTEGER_UNLIMITED
418    } {
419	clean_restart
420
421	gdb_test_multiline "create parameter" \
422	    "python" "" \
423	    "class TestNodocParam (gdb.Parameter):" "" \
424	    "   def __init__ (self, name):" "" \
425	    "      super (TestNodocParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.$kind)" "" \
426	    "      self.value = 0" "" \
427	    "test_param_$kind = TestNodocParam ('test-$kind')" "" \
428	    "end"
429
430	set param_range_error "RuntimeError: Range exceeded.*"
431	set param_integer_error "RuntimeError: The value must be integer.*"
432	switch -- $kind {
433	    PARAM_UINTEGER {
434		set param_get_zero None
435		set param_get_minus_one None
436		set param_get_minus_five 1
437		set param_get_none None
438		set param_set_minus_one $param_range_error
439		set param_set_minus_five $param_range_error
440		set param_set_none ""
441	    }
442	    PARAM_INTEGER {
443		set param_get_zero None
444		set param_get_minus_one -1
445		set param_get_minus_five -5
446		set param_get_none None
447		set param_set_minus_one -1
448		set param_set_minus_five -5
449		set param_set_none ""
450	    }
451	    PARAM_ZINTEGER {
452		set param_get_zero 0
453		set param_get_minus_one -1
454		set param_get_minus_five -5
455		set param_get_none 5
456		set param_set_minus_one ""
457		set param_set_minus_five ""
458		set param_set_none $param_integer_error
459	    }
460	    PARAM_ZUINTEGER {
461		set param_get_zero 0
462		set param_get_minus_one 0
463		set param_get_minus_five 1
464		set param_get_none 5
465		set param_set_minus_one $param_range_error
466		set param_set_minus_five $param_range_error
467		set param_set_none $param_integer_error
468	    }
469	    PARAM_ZUINTEGER_UNLIMITED {
470		set param_get_zero 0
471		set param_get_minus_one -1
472		set param_get_minus_five 1
473		set param_get_none -1
474		set param_set_minus_one ""
475		set param_set_minus_five $param_range_error
476		set param_set_none ""
477	    }
478	    default {
479		error "invalid kind: $kind"
480	    }
481	}
482
483	gdb_test "python print(test_param_$kind.value)" \
484	    $param_get_zero "test default value"
485
486	gdb_test "python print(gdb.parameter('test-$kind'))" \
487	    $param_get_zero "test default value via gdb.parameter"
488
489	py_param_test_maybe_no_output "python test_param_$kind.value = -1" \
490	    $param_set_minus_one "test set to -1"
491
492	gdb_test "python print(test_param_$kind.value)" \
493	    $param_get_minus_one "test value of -1"
494
495	gdb_test "python print(gdb.parameter('test-$kind'))" \
496	    $param_get_minus_one "test value of -1 via gdb.parameter"
497
498	gdb_test_no_output "python test_param_$kind.value = 1" "test set to 1"
499
500	gdb_test "python print(test_param_$kind.value)" 1 "test value of 1"
501
502	gdb_test "python print(gdb.parameter('test-$kind'))" \
503	    1 "test value of 1 via gdb.parameter"
504
505	py_param_test_maybe_no_output "python test_param_$kind.value = -5" \
506	    $param_set_minus_five "test set to -5"
507
508	gdb_test "python print(gdb.parameter('test-$kind'))" \
509	    $param_get_minus_five "test value of -5 via gdb.parameter"
510
511	gdb_test_no_output "python test_param_$kind.value = 5" "test set to 5"
512
513	gdb_test "python print(gdb.parameter('test-$kind'))" \
514	    5 "test value of 5 via gdb.parameter"
515
516	py_param_test_maybe_no_output "python test_param_$kind.value = None" \
517	    $param_set_none "test set to None"
518
519	gdb_test "python print(test_param_$kind.value)" \
520	    $param_get_none "test value of None"
521
522	gdb_test "python print(gdb.parameter('test-$kind'))" \
523	    $param_get_none "test value of None via gdb.parameter"
524
525	gdb_test_no_output "python test_param_$kind.value = 0" \
526	    "test set to 0"
527
528	gdb_test "python print(gdb.parameter('test-$kind'))" \
529	    $param_get_zero "test value of 0 via gdb.parameter"
530    }
531}
532
533proc_with_prefix test_throwing_parameter { } {
534    clean_restart
535
536    gdb_test_multiline "Throwing gdb parameter" \
537	"python" "" \
538	"class TestThrowParam (gdb.Parameter):" "" \
539	"   def __init__ (self, name):" "" \
540	"      super (TestThrowParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_STRING)" "" \
541	"      self.value = True" "" \
542	"   def get_set_string (self):" "" \
543	"      raise gdb.GdbError('Ordinary gdb error')" "" \
544	"test_throw_param = TestThrowParam ('print test-throw-param')" ""\
545	"end"
546
547    gdb_test "set print test-throw-param whoops" \
548	"Ordinary gdb error" \
549	"gdb.GdbError does not show Python stack"
550}
551
552proc_with_prefix test_language {} {
553    gdb_test "python print(gdb.parameter('language'))" "auto" \
554	"print language parameter"
555    gdb_test "python print(gdb.current_language())" "c" \
556	"print current language"
557    gdb_test_no_output "set lang rust"
558    gdb_test "python print(gdb.parameter('language'))" "rust" \
559	"print language parameter for rust"
560    gdb_test "python print(gdb.current_language())" "rust" \
561	"print current language for rust"
562    gdb_test_no_output "set lang auto"
563}
564
565test_directories
566test_data_directory
567test_boolean_parameter
568test_enum_parameter
569test_file_parameter
570test_undocumented_parameter
571test_really_undocumented_parameter
572test_deprecated_api_parameter
573test_gdb_parameter
574test_integer_parameter
575test_throwing_parameter
576test_language
577
578rename py_param_test_maybe_no_output ""
579