Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC 1/5] [pre-commit] Add indent-exp
@ 2026-09-04  9:38 Tom de Vries
  2026-09-04  9:38 ` [RFC 2/5] [gdb/testsuite] Make lib/gdb.exp emacs indent compatible Tom de Vries
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Tom de Vries @ 2026-09-04  9:38 UTC (permalink / raw)
  To: gdb-patches

There's a long-term goal to start using tclfmt [1] to format .exp and .tcl
files.

A less impactful approach is to have consistent indentation.

Add a hook indent-exp that uses emacs indent-region.

It uses a new script ./gdb/contrib/emacs-indent.sh which we demonstrate here
using the largest .exp file (12433 lines):
...
$ time ./gdb/contrib/emacs-indent.sh tcl-mode gdb/testsuite/lib/gdb.exp

real	0m1.041s
user	0m0.998s
sys	0m0.045s
...

The first change is here where we replace 7 spaces with a tab:
...
 proc load_lib { file } {
     array set known_global {}
     foreach varname [info globals] {
-       set known_globals($varname) 1
+	set known_globals($varname) 1
     }
...

Less desirable changes are when emacs messes with indentation inside strings:
...
 	    for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
-		if (dyn->d_tag == DT_DEBUG)
-		    r_debug = (struct r_debug *) dyn->d_un.d_ptr;
+	    if (dyn->d_tag == DT_DEBUG)
+	    r_debug = (struct r_debug *) dyn->d_un.d_ptr;
...

The script is fast enough when checking a few files in a new commit, but very
slow when checking all files:
...
$ pre-commit run indent-exp --hook-stage manual --all-files -v
indent-exp..............................................................Failed
- hook id: indent-exp
- duration: 89.18s
- files were modified by this hook
...

It's using the manual stage, both because it's slow and because users need to
provide the emacs dependency.

I tried to make ./gdb/contrib/emacs-indent.sh generic enough to be also usable
for other modes, for instance sh-mode for shell scripts.

The script has a kludge to stop emacs from changing this:
...
    # Try this command:
    #     foo \
    #         arg1 \
    #         arg2
...
into:
...
    # Try this command:
    #     foo \
        #         arg1 \
        #         arg2
...
by adding a '#' after the trailing backslash:
...
    # Try this command:
    #     foo \#
    #         arg1 \#
    #         arg2
...

There might be a way to address this using some emacs customization instead.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=33724
---
 .pre-commit-config.yaml     |  9 +++-
 gdb/contrib/emacs-indent.sh | 85 +++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100755 gdb/contrib/emacs-indent.sh

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0b4285e6c82..096887ef86f 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -100,7 +100,7 @@ repos:
     hooks:
       - id: tclint
         args: [--trust-plugins]
-        files: '^gdb/testsuite/.*\.(exp|tcl)$'
+        files: &gdb_exp_tcl_files '^gdb/testsuite/.*\.(exp|tcl)$'
 
   # Yaml hooks.
   - repo: https://github.com/adrienverge/yamllint.git
@@ -169,6 +169,13 @@ repos:
         args: [--config-check]
         additional_dependencies: ["pyyaml"]
         files: *pre_commit_config_file
+      - id: &id7 indent-exp
+        name: *id7
+        language: unsupported_script
+        entry: gdb/contrib/emacs-indent.sh
+        args: [tcl-mode]
+        files: *gdb_exp_tcl_files
+        stages: [manual]
 
 # Local Variables:
 # indent-tabs-mode: nil
diff --git a/gdb/contrib/emacs-indent.sh b/gdb/contrib/emacs-indent.sh
new file mode 100755
index 00000000000..71411103aed
--- /dev/null
+++ b/gdb/contrib/emacs-indent.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+mode="$1"
+shift
+
+if [ "$mode" = "" ]; then
+    echo "Missing mode argument"
+    exit 1
+fi
+
+if [ $# -eq 0 ]; then
+    echo "No files"
+    exit 1
+fi
+
+if ! emacs --version > /dev/null; then
+    echo "Please install emacs"
+    exit 1
+fi
+
+files=()
+for f in "$@"; do
+    case "$mode" in
+	tcl-mode)
+	    case "$f" in
+		# Imported.
+		gdb/testsuite/lib/ton.tcl)
+		    continue
+		    ;;
+	    esac
+	    ;;
+    esac
+
+    files=("${files[@]}" "$f")
+done
+
+if [ ${#files[@]} -eq 0 ]; then
+    exit
+fi
+
+tmp=""
+
+cleanup()
+{
+    if [ "$tmp" != "" ]; then
+	rm -f "$tmp"
+    fi
+}
+
+# Schedule cleanup.
+trap cleanup EXIT
+
+# Get temporary file.
+tmp=$(mktemp) || exit 1
+
+if [ "$mode" = "tcl-mode" ]; then
+    # Kludge: Hide backslashes at end of comment from emacs tcl-mode, by
+    # appending '#'.
+    sed \
+	-i \
+	's%^\([ \t]*#.*\)\\$%\1\\#%' \
+	"${files[@]}" \
+	|| exit 1
+fi
+
+script="
+(dolist
+ (f command-line-args-left)
+ (with-current-buffer
+  (find-file-noselect f)
+  ($mode)
+  (indent-region (point-min) (point-max))
+  (save-buffer)
+  (kill-buffer)))"
+
+if ! emacs \
+     -batch \
+     --eval="$script" \
+     "${files[@]}" \
+     > "$tmp" \
+     2>&1; then
+    # Output is verbose, only show on error.
+    cat "$tmp"
+    exit 1
+fi

base-commit: 5f20ce97686ac7ee28cba3f0af0a237a1e878148
-- 
2.51.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-04  9:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-04  9:38 [RFC 1/5] [pre-commit] Add indent-exp Tom de Vries
2026-09-04  9:38 ` [RFC 2/5] [gdb/testsuite] Make lib/gdb.exp emacs indent compatible Tom de Vries
2026-09-04  9:38 ` [RFC 3/5] [gdb/testsuite] Update regexp in string_to_regexp Tom de Vries
2026-09-04  9:38 ` [RFC 4/5] [gdb/testsuite] Reformat lib/gdb.exp Tom de Vries
2026-09-04  9:38 ` [RFC 5/5] [gdb/testsuite] Reformat gdb.ada Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox