From: Tom de Vries Date: Thu, 11 Dec 2025 21:31:49 +0000 (+0100) Subject: [gdb/testsuite] Add tclint-plugin.py X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9d59ebad7573f20a7236354183b4e0e1eab7d5f;p=thirdparty%2Fbinutils-gdb.git [gdb/testsuite] Add tclint-plugin.py Tclint v0.6.2 adds the possibility to specify a dynamic plugin using: ... $ tclint --commands tclint-plugin.py ... Update the pre-commit tclint version to v0.6.2, and add a plugin gdb/testsuite/tclint-plugin.py. The new plugin informs tclint about procs like proc_with_prefix which have a script-type parameter, making tclint check the body of proc foo: ... proc_with_prefix foo {} { ... } ... Declaring proc_with_prefix a builtin command makes tclint issue a redefined-builtin for the definition of proc_with_prefix. Fix this by adding "tclint-disable redefined-builtin" at the start of each file containing such procs. The plugin is not complete. Most entries were found by grepping for something like "proc.*body". The hope is that eventually we get to a situation where we can drop the plugin and instead annotate like this [1]: ... # tclint-args: name: any, arguments: any, body: script proc proc_with_prefix { name arguments body } { ... } ... One fix in the testsuite, in test-case gdb.python/py-missing-objfile.exp. [1] https://github.com/nmoroze/tclint/issues/121#issuecomment-3319368338 --- diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a78659cd173..62af6f5d2f9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -105,9 +105,9 @@ repos: pass_filenames: true stages: [pre-commit] - repo: https://github.com/nmoroze/tclint - rev: v0.6.1 + rev: v0.6.2 hooks: - id: tclint - args: [--config, gdb/tclint.toml] + args: [--config, gdb/tclint.toml, --commands, gdb/testsuite/tclint-plugin.py] types_or: [file] files: '^gdb/testsuite/.*\.(exp|tcl)$' diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.exp b/gdb/testsuite/gdb.python/py-missing-objfile.exp index 2f54f618cf0..f36c59713c3 100644 --- a/gdb/testsuite/gdb.python/py-missing-objfile.exp +++ b/gdb/testsuite/gdb.python/py-missing-objfile.exp @@ -190,8 +190,8 @@ with_test_prefix "no objfiles available" { # The following tests assume that the build-ids of binfile and libfile can be # found in the core file. -require {expr $expect_build_id_in_core_file_binfile} -require {expr $expect_build_id_in_core_file_libfile} +require {expr {$expect_build_id_in_core_file_binfile}} +require {expr {$expect_build_id_in_core_file_libfile}} with_test_prefix "all objfiles available" { # Another sanity check that GDB can find the files via the diff --git a/gdb/testsuite/lib/ada.exp b/gdb/testsuite/lib/ada.exp index c6d1c463b2b..57b547b9af1 100644 --- a/gdb/testsuite/lib/ada.exp +++ b/gdb/testsuite/lib/ada.exp @@ -13,6 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# tclint-disable redefined-builtin + # A wrapper for foreach_with_prefix that applies suitable # -fgnat-encodings arguments to a command line. SCENARIO_ARG is the # name of a loop variable that will hold the scenario currently being diff --git a/gdb/testsuite/lib/cache.exp b/gdb/testsuite/lib/cache.exp index f5780721e0f..68d86073250 100644 --- a/gdb/testsuite/lib/cache.exp +++ b/gdb/testsuite/lib/cache.exp @@ -13,6 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# tclint-disable redefined-builtin # The in-memory cache. array set gdb_data_cache {} diff --git a/gdb/testsuite/lib/completion-support.exp b/gdb/testsuite/lib/completion-support.exp index 8ddf53d6243..d13e6cffc51 100644 --- a/gdb/testsuite/lib/completion-support.exp +++ b/gdb/testsuite/lib/completion-support.exp @@ -18,6 +18,8 @@ # Any variable or procedure in the namespace whose name starts with # "_" is private to the module. Do not use these. +# tclint-disable redefined-builtin + namespace eval completion { variable bell_re "\\\x07" diff --git a/gdb/testsuite/lib/debuginfod-support.exp b/gdb/testsuite/lib/debuginfod-support.exp index ad6963e7af4..04033a0e47f 100644 --- a/gdb/testsuite/lib/debuginfod-support.exp +++ b/gdb/testsuite/lib/debuginfod-support.exp @@ -15,6 +15,8 @@ # Helper functions to make it easier to write debuginfod tests. +# tclint-disable redefined-builtin + # Return true if the debuginfod tests should be run, otherwise, return # false. proc allow_debuginfod_tests {} { diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 708bbd448de..a6a31916204 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -13,6 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# tclint-disable redefined-builtin + # Return true if the target supports DWARF-2 and uses gas. # For now pick a sampling of likely targets. proc dwarf2_support {} { diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp index e81f35ace79..175451dc262 100644 --- a/gdb/testsuite/lib/gdb-utils.exp +++ b/gdb/testsuite/lib/gdb-utils.exp @@ -15,6 +15,8 @@ # Utility procedures, shared between test suite domains. +# tclint-disable redefined-builtin + # A helper procedure to retrieve commands to send to GDB before a program # is started. diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 8dc03231a10..f7d9b61fec0 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -15,6 +15,8 @@ # This file was written by Fred Fish. (fnf@cygnus.com) +# tclint-disable redefined-builtin + package require Tcl 8.6.2 # Generic gdb subroutines that should work for any target. If these diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index b64c5862f26..607512b7ee2 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -19,6 +19,8 @@ load_lib gdb-utils.exp +# tclint-disable redefined-builtin + # The variable mi_gdb_prompt is a regexp which matches the gdb mi prompt. # Set it if it is not already set. global mi_gdb_prompt diff --git a/gdb/testsuite/lib/rocm.exp b/gdb/testsuite/lib/rocm.exp index d3f201ccf2d..67f05709cc2 100644 --- a/gdb/testsuite/lib/rocm.exp +++ b/gdb/testsuite/lib/rocm.exp @@ -15,6 +15,8 @@ # # Support library for testing ROCm (AMD GPU) GDB features. +# tclint-disable redefined-builtin + # ROCM_PATH is used by hipcc as well. if {[info exists ::env(ROCM_PATH)]} { set rocm_path $::env(ROCM_PATH) diff --git a/gdb/testsuite/lib/tuiterm.exp b/gdb/testsuite/lib/tuiterm.exp index 68fd6777b7c..86e52b9a788 100644 --- a/gdb/testsuite/lib/tuiterm.exp +++ b/gdb/testsuite/lib/tuiterm.exp @@ -15,6 +15,8 @@ # An ANSI terminal emulator for expect. +# tclint-disable redefined-builtin + namespace eval Term { # Size of the terminal. variable _rows diff --git a/gdb/testsuite/tclint-plugin.py b/gdb/testsuite/tclint-plugin.py new file mode 100644 index 00000000000..24a813a497c --- /dev/null +++ b/gdb/testsuite/tclint-plugin.py @@ -0,0 +1,199 @@ +from tclint.commands.checks import ( + CommandArgError, +) +from tclint.commands.schema import commands_schema + + +def _script_args(name, n, script_args, args, parser): + if len(args) != n: + raise CommandArgError( + f"wrong # of args to {name}: got {len(args)}, expected {n}" + ) + + res = [] + arg_n = 0 + for arg in args: + if arg_n in script_args: + res.append(parser.parse_script(arg)) + else: + res.append(arg) + arg_n += 1 + return res + + +def _script_last_arg(name, n, args, parser): + return _script_args(name, n, [n - 1], args, parser) + + +def _cond_wrap(args, parser): + return _script_last_arg("cond_wrap", 3, args, parser) + + +def _foreach_gnat_encoding(args, parser): + return _script_last_arg("foreach_gnat_encoding", 4, args, parser) + + +def _foreach_location_functions(args, parser): + return _script_args("foreach_location_functions", 4, [2, 3], args, parser) + + +def _foreach_location_labels(args, parser): + return _script_args("foreach_location_labels", 5, [3, 4], args, parser) + + +def _foreach_mi_ui_mode(args, parser): + return _script_last_arg("foreach_mi_ui_mode", 2, args, parser) + + +def _foreach_with_prefix(args, parser): + return _script_last_arg("foreach_with_prefix", 3, args, parser) + + +def _gdb_caching_proc(args, parser): + return _script_last_arg("gdb_caching_proc", 3, args, parser) + + +def _proc_with_prefix(args, parser): + return _script_last_arg("proc_with_prefix", 3, args, parser) + + +def _require(args, parser): + res = [] + for arg in args: + res.append(parser.parse_script(arg)) + return res + + +def _save_vars(args, parser): + return _script_last_arg("save_vars", 2, args, parser) + + +def _save_target_board_info(args, parser): + return _script_last_arg("save_target_board_info", 2, args, parser) + + +def _with_debuginfod_env(args, parser): + return _script_last_arg("with_debuginfod_env", 2, args, parser) + + +def _with_shared_gdb(args, parser): + return _script_last_arg("with_shared_gdb", 1, args, parser) + + +def _with_test_prefix(args, parser): + return _script_last_arg("with_test_prefix", 2, args, parser) + + +def _with_cwd(args, parser): + return _script_last_arg("with_cwd", 2, args, parser) + + +def _with_gdb_cwd(args, parser): + return _script_last_arg("with_gdb_cwd", 2, args, parser) + + +def _with_gdb_prompt(args, parser): + return _script_last_arg("with_gdb_prompt", 2, args, parser) + + +def _with_target_charset(args, parser): + return _script_last_arg("with_target_charset", 2, args, parser) + + +def _with_max_value_size(args, parser): + return _script_last_arg("with_max_value_size", 2, args, parser) + + +def _with_spawn_id(args, parser): + return _script_last_arg("with_spawn_id", 2, args, parser) + + +def _with_timeout_factor(args, parser): + return _script_last_arg("with_timeout_factor", 2, args, parser) + + +def _with_read1_timeout_factor(args, parser): + return _script_last_arg("with_read1_timeout_factor", 2, args, parser) + + +def _with_multilib_flags_filtered(args, parser): + return _script_last_arg("with_multilib_flags_filtered", 2, args, parser) + + +def _with_PIE_multilib_flags_filtered(args, parser): + return _script_last_arg("with_PIE_multilib_flags_filtered", 1, args, parser) + + +def _with_set(args, parser): + return _script_last_arg("with_set", 3, args, parser) + + +def _with_complaints(args, parser): + return _script_last_arg("with_complaints", 2, args, parser) + + +def _with_override(args, parser): + return _script_last_arg("with_override", 3, args, parser) + + +def _with_ansi_styling_terminal(args, parser): + return _script_last_arg("with_ansi_styling_terminal", 1, args, parser) + + +def _with_lock(args, parser): + return _script_last_arg("with_lock", 2, args, parser) + + +def _with_rocm_gpu_lock(args, parser): + return _script_last_arg("with_rocm_gpu_lock", 1, args, parser) + + +def _ns_term_log_cur(args, parser): + return _script_last_arg("Term::log_cur", 2, args, parser) + + +def _ns_term_with_term(args, parser): + return _script_last_arg("Term::with_term", 2, args, parser) + + +def _ns_term_with_tuiterm(args, parser): + return _script_last_arg("Term::with_tuiterm", 3, args, parser) + + +commands = commands_schema( + { + "cond_wrap": _cond_wrap, + "foreach_gnat_encoding": _foreach_gnat_encoding, + "foreach_location_functions": _foreach_location_functions, + "foreach_location_labels": _foreach_location_labels, + "foreach_mi_ui_mode": _foreach_mi_ui_mode, + "foreach_with_prefix": _foreach_with_prefix, + "gdb_caching_proc": _gdb_caching_proc, + "proc_with_prefix": _proc_with_prefix, + "require": _require, + "save_vars": _save_vars, + "save_target_board_info": _save_target_board_info, + "with_debuginfod_env": _with_debuginfod_env, + "with_shared_gdb": _with_shared_gdb, + "with_test_prefix": _with_test_prefix, + "with_cwd": _with_cwd, + "with_gdb_cwd": _with_gdb_cwd, + "with_gdb_prompt": _with_gdb_prompt, + "with_target_charset": _with_target_charset, + "with_max_value_size": _with_max_value_size, + "with_spawn_id": _with_spawn_id, + "with_timeout_factor": _with_timeout_factor, + "with_read1_timeout_factor": _with_read1_timeout_factor, + "with_multilib_flags_filtered": _with_multilib_flags_filtered, + "with_PIE_multilib_flags_filtered": _with_PIE_multilib_flags_filtered, + "with_set": _with_set, + "with_complaints": _with_complaints, + "with_override": _with_override, + "with_ansi_styling_terminal": _with_ansi_styling_terminal, + "with_lock": _with_lock, + "with_rocm_gpu_lock": _with_rocm_gpu_lock, + "Term::_log_cur": _ns_term_log_cur, + "Term::with_term": _ns_term_with_term, + "Term::with_tuiterm": _ns_term_with_tuiterm, + } +)