Subject: It is annoying to have to type 'print foo' before each .gdbinit command.
From: Alan Mackenzie <[email-masked]>
To: [email-masked]
Date: Sun, 12 Feb 2023 13:01:57 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello, Emacs.

In a GDB session, whilst debugging Emacs, it is common to want to print,
for example, the current value of Lisp variable foo.  At the moment, one
has to type

    p foo
    xpr

..  This need, continually to type p (or print) is irritating.  It should
be possible simply to type

    xpr foo

..  The same applies to many other commands in .gdbinit.

The following patch fixes this irritation.  It allows a user to type xpr
foo, yet also preserves the old version with no arguments, which can be
handy, sometimes.

I propose this patch be applied to the master branch.

diff --git a/etc/DEBUG b/etc/DEBUG
index c4f0852abb3..5fa60af2806 100644
--- a/etc/DEBUG
+++ b/etc/DEBUG
@@ -288,9 +288,10 @@ and where you interact with GDB.
 ** Examining Lisp object values.
 
 When you have a live process to debug, and it has not encountered a
-fatal error, you can use the GDB command 'pr'.  First print the value
-in the ordinary way, with the 'p' command.  Then type 'pr' with no
-arguments.  This calls a subroutine which uses the Lisp printer.
+fatal error, you can use the GDB command 'pr'.  Just type pr, giving
+the object as the argument.  (The older method of first printing with
+the 'p' command followed by pr without arguments still works.)  This
+calls a subroutine which uses the Lisp printer.
 
 You can also use 'pp value' to print the emacs value directly.
 
@@ -319,8 +320,7 @@ If you can't use 'pr' command, for whatever reason, you can use the
 'xpr' command to print out the data type and value of the last data
 value, For example:
 
-    p it->object
-    xpr
+    xpr it->object
 
 You may also analyze data values using lower-level commands.  Use the
 'xtype' command to print out the data type of the last data value.
@@ -328,10 +328,10 @@ Once you know the data type, use the command that corresponds to that
 type.  Here are these commands:
 
     xint xptr xwindow xmarker xoverlay xmiscfree xintfwd xboolfwd xobjfwd
-    xbufobjfwd xkbobjfwd xbuflocal xbuffer xsymbol xstring xvector xframe
-    xwinconfig xcompiled xcons xcar xcdr xsubr xprocess xfloat xscrollbar
-    xchartable xsubchartable xboolvector xhashtable xlist xcoding
-    xcharset xfontset xfont
+    xbufobjfwd xkbobjfwd xbuflocal xbuffer xsymbol xsymwithpos xstring
+    xvector xframe xwinconfig xcompiled xcons xcar xcdr xsubr xprocess
+    xfloat xscrollbar xchartable xsubchartable xboolvector xhashtable
+    xlist xcoding xcharset xfontset xfont
 
 Each one of them applies to a certain type or class of types.
 (Some of these types are not visible in Lisp, because they exist only
@@ -357,15 +357,13 @@ called frame.  First, use these commands:
 
 Then Emacs hits the breakpoint:
 
-  (gdb) p frame
-  $1 = 139854428
-  (gdb) xpr
+  (gdb) xpr frame
   Lisp_Vectorlike
   PVEC_FRAME
-  $2 = (struct frame *) 0x8560258
+  $1 = (struct frame *) 0x8560258
   "emacs@localhost"
   (gdb) p *$
-  $3 = {
+  $2 = {
     size = 1073742931,
     next = 0x85dfe58,
     name = 140615219,
@@ -391,22 +389,19 @@ evaluate expressions like "p XVECTOR (this_command_keys)".
 When this information isn't available, you can use the xvector command in GDB
 to get the same result.  Here is how:
 
-  (gdb) p this_command_keys
-  $1 = 1078005760
-  (gdb) xvector
-  $2 = (struct Lisp_Vector *) 0x411000
+  (gdb) xvector this_command_keys
+  $1 = (struct Lisp_Vector *) 0x411000
   0
   (gdb) p $->contents[this_command_key_count]
-  $3 = 1077872640
+  $2 = 1077872640
   (gdb) p &$
-  $4 = (int *) 0x411008
+  $3 = (int *) 0x411008
 
 Here's a related example of macros and the GDB 'define' command.
 There are many Lisp vectors such as 'recent_keys', which contains the
 last 300 keystrokes.  We can print this Lisp vector
 
-  p recent_keys
-  pr
+  pr recent_keys
 
 But this may be inconvenient, since 'recent_keys' is much more verbose
 than 'C-h l'.  We might want to print only the last 10 elements of
@@ -447,8 +442,7 @@ backtrace, and look for stack frames that call Ffuncall.  Select them
 one by one in GDB, by typing "up N", where N is the appropriate number
 of frames to go up, and in each frame that calls Ffuncall type this:
 
-   p *args
-   pr
+   pr *args
 
 This will print the name of the Lisp function called by that level
 of function calling.
@@ -456,15 +450,13 @@ of function calling.
 By printing the remaining elements of args, you can see the argument
 values.  Here's how to print the first argument:
 
-   p args[1]
-   pr
+   pr args[1]
 
 If you do not have a live process, you can use xtype and the other
 x...  commands such as xsymbol to get such information, albeit less
 conveniently.  For example:
 
-   p *args
-   xtype
+   xtype *args
 
 and, assuming that "xtype" says that args[0] is a symbol:
 
diff --git a/src/.gdbinit b/src/.gdbinit
index c96c2b597bd..65ef9a5684e 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -91,10 +91,15 @@ end
 # from calling OutputDebugString, which causes GDB to display each
 # character twice (yuk!).
 define pr
-  pp $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  pp $d
 end
 document pr
-Print the emacs s-expression which is $.
+Print the emacs s-expression which is $arg0 or $.
 Works only when an inferior emacs is executing.
 end
 
@@ -656,15 +661,20 @@ Takes one argument, a pointer to a glyph_matrix structure.
 end
 
 define xtype
-  xgettype $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgettype $d
   output $type
   echo \n
   if $type == Lisp_Vectorlike
-    xvectype
+    xvectype $d
   end
 end
 document xtype
-Print the type of $, assuming it is an Emacs Lisp value.
+Print the type of $arg0 or $, assuming it is an Emacs Lisp value.
 If the first type printed is Lisp_Vectorlike,
 a second line gives the more precise type.
 end
@@ -684,12 +694,17 @@ Takes one argument, a pointer to an object.
 end
 
 define xvectype
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   pvectype $ptr
 end
 document xvectype
 Print the subtype of vectorlike object.
-This command assumes that $ is a Lisp_Object.
+This command assumes that $arg0 or $ is a Lisp_Object.
 end
 
 define pvecsize
@@ -709,104 +724,159 @@ Takes one argument, a pointer to an object.
 end
 
 define xvecsize
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   pvecsize $ptr
 end
 document xvecsize
-Print the size of $
-This command assumes that $ is a Lisp_Object.
+Print the size of $arg0 or $.
+This command assumes that $arg0 or $ is a Lisp_Object.
 end
 
 define xint
-  xgetint $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetint $d
   print $int
 end
 document xint
-Print $ as an Emacs Lisp integer.  This gets the sign right.
+Print $arg0 or $ as an Emacs Lisp integer.  This gets the sign right.
 end
 
 define xptr
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (void *) $ptr
 end
 document xptr
-Print the pointer portion of an Emacs Lisp value in $.
+Print the pointer portion of an Emacs Lisp value in $arg0 or $.
 end
 
 define xmarker
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Marker *) $ptr
 end
 document xmarker
-Print $ as a marker pointer.
+Print $arg0 or $ as a marker pointer.
 This command assumes that $ is an Emacs Lisp marker value.
 end
 
 define xoverlay
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Overlay *) $ptr
 end
 document xoverlay
-Print $ as a overlay pointer.
-This command assumes that $ is an Emacs Lisp overlay value.
+Print $arg0 or $ as a overlay pointer.
+This command assumes that $arg0 or $ is an Emacs Lisp overlay value.
 end
 
 define xsymwithpos
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Symbol_With_Pos *) $ptr
 end
 document xsymwithpos
-Print $ as a symbol with position.
-This command assumes that $ is an Emacs Lisp symbol with position value.
+Print $arg0 or $ as a symbol with position.
+This command assumes that $arg0 or $ is an Emacs Lisp symbol with position value.
 end
 
 define xsymbol
-  set $sym = $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  set $sym = $d
   xgetsym $sym
   print (struct Lisp_Symbol *) $ptr
   xprintsym $sym
   echo \n
 end
 document xsymbol
-Print the name and address of the symbol $.
-This command assumes that $ is an Emacs Lisp symbol value.
+Print the name and address of the symbol $arg0 or $.
+This command assumes that $arg0 or $ is an Emacs Lisp symbol value.
 end
 
 define xstring
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_String *) $ptr
   xprintstr $
   echo \n
 end
 document xstring
-Print the contents and address of the string $.
-This command assumes that $ is an Emacs Lisp string value.
+Print the contents and address of the string $arg0 or $.
+This command assumes that $arg0 or $ is an Emacs Lisp string value.
 end
 
 define xvector
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Vector *) $ptr
   output ($->header.size > 50) ? 0 : ($->contents[0])@($->header.size & ~ARRAY_MARK_FLAG)
 echo \n
 end
 document xvector
-Print the contents and address of the vector $.
-This command assumes that $ is an Emacs Lisp vector value.
+Print the contents and address of the vector $arg0 or $.
+This command assumes that $arg0 or $ is an Emacs Lisp vector value.
 end
 
 define xprocess
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Process *) $ptr
-  output *$
+  output *$d
   echo \n
 end
 document xprocess
-Print the address of the struct Lisp_process to which $ points.
-This command assumes that $ is a Lisp_Object.
+Print the address of the struct Lisp_process to which $arg0 or $ points.
+This command assumes that $arg0 or $ is a Lisp_Object.
 end
 
 define xframe
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct frame *) $ptr
   xgetptr $->name
   set $ptr = (struct Lisp_String *) $ptr
@@ -814,53 +884,78 @@ define xframe
   echo \n
 end
 document xframe
-Print $ as a frame pointer.
-This command assumes $ is an Emacs Lisp frame value.
+Print $arg0 or $ as a frame pointer.
+This command assumes $arg0 or $ is an Emacs Lisp frame value.
 end
 
 define xcompiled
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Vector *) $ptr
   output ($->contents[0])@($->header.size & 0xff)
   echo \n
 end
 document xcompiled
-Print $ as a compiled function pointer.
-This command assumes that $ is an Emacs Lisp compiled value.
+Print $arg0 or $ as a compiled function pointer.
+This command assumes that $arg0 or $ is an Emacs Lisp compiled value.
 end
 
 define xwindow
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct window *) $ptr
   set $window = (struct window *) $ptr
   printf "%dx%d+%d+%d\n", $window->total_cols, $window->total_lines, $window->left_col, $window->top_line
 end
 document xwindow
-Print $ as a window pointer, assuming it is an Emacs Lisp window value.
+Print $arg0 or $ as a window pointer, assuming it is an Emacs Lisp window value.
 Print the window's position as "WIDTHxHEIGHT+LEFT+TOP".
 end
 
 define xwinconfig
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct save_window_data *) $ptr
 end
 document xwinconfig
-Print $ as a window configuration pointer.
-This command assumes that $ is an Emacs Lisp window configuration value.
+Print $arg0 or $ as a window configuration pointer.
+This command assumes that $arg0 or $ is an Emacs Lisp window configuration value.
 end
 
 define xsubr
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Subr *) $ptr
   output *$
   echo \n
 end
 document xsubr
-Print the address of the subr which the Lisp_Object $ points to.
+Print the address of the subr which the Lisp_Object $arg0 or $ points to.
 end
 
 define xchartable
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Char_Table *) $ptr
   printf "Purpose: "
   xprintsym $->purpose
@@ -868,65 +963,90 @@ define xchartable
   echo \n
 end
 document xchartable
-Print the address of the char-table $, and its purpose.
-This command assumes that $ is an Emacs Lisp char-table value.
+Print the address of the char-table $arg0 or $, and its purpose.
+This command assumes that $arg0 or $ is an Emacs Lisp char-table value.
 end
 
 define xsubchartable
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Sub_Char_Table *) $ptr
   set $subchartab = (struct Lisp_Sub_Char_Table *) $ptr
   printf "Depth: %d, Min char: %d (0x%x)\n", $subchartab->depth, $subchartab->min_char, $subchartab->min_char
 end
 document xsubchartable
-Print the address of the sub-char-table $, its depth and min-char.
-This command assumes that $ is an Emacs Lisp sub-char-table value.
+Print the address of the sub-char-table $arg0 or $, its depth and min-char.
+This command assumes that $arg0 or $ is an Emacs Lisp sub-char-table value.
 end
 
 define xboolvector
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Bool_Vector *) $ptr
   output ($->size > 256) ? 0 : ($->data[0])@(($->size + BOOL_VECTOR_BITS_PER_CHAR - 1)/ BOOL_VECTOR_BITS_PER_CHAR)
   echo \n
 end
 document xboolvector
-Print the contents and address of the bool-vector $.
-This command assumes that $ is an Emacs Lisp bool-vector value.
+Print the contents and address of the bool-vector $arg0 or $.
+This command assumes that $arg0 or $ is an Emacs Lisp bool-vector value.
 end
 
 define xbuffer
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct buffer *) $ptr
   xgetptr $->name_
   output $ptr ? (char *) ((struct Lisp_String *) $ptr)->u.s.data : "DEAD"
   echo \n
 end
 document xbuffer
-Set $ as a buffer pointer and the name of the buffer.
-This command assumes $ is an Emacs Lisp buffer value.
+Set $arg0 or $ as a buffer pointer and the name of the buffer.
+This command assumes $arg0 or $ is an Emacs Lisp buffer value.
 end
 
 define xhashtable
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Hash_Table *) $ptr
 end
 document xhashtable
-Set $ as a hash table pointer.
-This command assumes that $ is an Emacs Lisp hash table value.
+Set $arg0 or $ as a hash table pointer.
+This command assumes that $arg0 or $ is an Emacs Lisp hash table value.
 end
 
 define xcons
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct Lisp_Cons *) $ptr
   output/x *$
   echo \n
 end
 document xcons
-Print the contents of $ as an Emacs Lisp cons.
+Print the contents of $arg0 or $ as an Emacs Lisp cons.
 end
 
 define nextcons
-  p $.u.cdr
+  p $.u.s.u.cdr
   xcons
 end
 document nextcons
@@ -935,25 +1055,40 @@ This command assumes that the last thing you printed was a cons cell contents
 (type struct Lisp_Cons) or a pointer to one.
 end
 define xcar
-  xgetptr $
-  xgettype $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
+  xgettype $d
   print/x ($type == Lisp_Cons ? ((struct Lisp_Cons *) $ptr)->u.s.car : 0)
 end
 document xcar
-Assume that $ is an Emacs Lisp pair and print its car.
+Assume that $arg0 or $ is an Emacs Lisp pair and print its car.
 end
 
 define xcdr
-  xgetptr $
-  xgettype $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
+  xgettype $d
   print/x ($type == Lisp_Cons ? ((struct Lisp_Cons *) $ptr)->u.s.u.cdr : 0)
 end
 document xcdr
-Assume that $ is an Emacs Lisp pair and print its cdr.
+Assume that $arg0 or $ is an Emacs Lisp pair and print its cdr.
 end
 
 define xlist
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   set $cons = (struct Lisp_Cons *) $ptr
   xgetptr Qnil
   set $nil = $ptr
@@ -974,97 +1109,112 @@ define xlist
   end
 end
 document xlist
-Print $ assuming it is a list.
+Print $arg0 or $ assuming it is a list.
 end
 
 define xfloat
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print ((struct Lisp_Float *) $ptr)->u.data
 end
 document xfloat
-Print $ assuming it is a lisp floating-point number.
+Print $arg0 or $ assuming it is a lisp floating-point number.
 end
 
 define xscrollbar
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   print (struct scrollbar *) $ptr
-output *$
+output *$d
 echo \n
 end
 document xscrollbar
-Print $ as a scrollbar pointer.
+Print $arg0 or $ as a scrollbar pointer.
 end
 
 define xpr
-  xtype
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xtype $d
   if $type == Lisp_Int0 || $type == Lisp_Int1
-    xint
+    xint $d
   end
   if $type == Lisp_Symbol
-    xsymbol
+    xsymbol $d
   end
   if $type == Lisp_String
-    xstring
+    xstring $d
   end
   if $type == Lisp_Cons
-    xcons
+    xcons $d
   end
   if $type == Lisp_Float
-    xfloat
+    xfloat $d
   end
   if $type == Lisp_Vectorlike
     set $size = ((struct Lisp_Vector *) $ptr)->header.size
     if ($size & PSEUDOVECTOR_FLAG)
       set $vec = (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
       if $vec == PVEC_NORMAL_VECTOR
-	xvector
+	xvector $d
       end
       if $vec == PVEC_MARKER
-        xmarker
+        xmarker $d
       end
       if $vec == PVEC_OVERLAY
-        xoverlay
+        xoverlay $d
       end
       if $vec == PVEC_SYMBOL_WITH_POS
-        xsymwithpos
+        xsymwithpos $d
       end
       if $vec == PVEC_PROCESS
-	xprocess
+	xprocess $d
       end
       if $vec == PVEC_FRAME
-	xframe
+	xframe $d
       end
       if $vec == PVEC_COMPILED
-	xcompiled
+	xcompiled $d
       end
       if $vec == PVEC_WINDOW
-	xwindow
+	xwindow $d
       end
       if $vec == PVEC_WINDOW_CONFIGURATION
-	xwinconfig
+	xwinconfig $d
       end
       if $vec == PVEC_SUBR
-	xsubr
+	xsubr $d
       end
       if $vec == PVEC_CHAR_TABLE
-	xchartable
+	xchartable $d
       end
       if $vec == PVEC_BOOL_VECTOR
-	xboolvector
+	xboolvector $d
       end
       if $vec == PVEC_BUFFER
-	xbuffer
+	xbuffer $d
       end
       if $vec == PVEC_HASH_TABLE
-	xhashtable
+	xhashtable $d
       end
     else
-      xvector
+      xvector $d
     end
   end
 end
 document xpr
-Print $ as a lisp object of any type.
+Print $arg0 or $ as a lisp object of any type.
 end
 
 define xprintstr
@@ -1118,7 +1268,12 @@ document xcharset
 end
 
 define xfontset
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   set $tbl = (struct Lisp_Char_Table *) $ptr
   print $tbl
   xgetint $tbl->extras[0]
@@ -1141,7 +1296,12 @@ define xfontset
 end
 
 define xfont
-  xgetptr $
+  if $argc > 0
+    set $d = $arg0
+  else
+    set $d = $
+  end
+  xgetptr $d
   set $size = (((struct Lisp_Vector *) $ptr)->header.size & 0x1FF)
   if $size == FONT_SPEC_MAX
     print (struct font_spec *) $ptr
@@ -1154,7 +1314,7 @@ define xfont
   end
 end
 document xfont
-Print $ assuming it is a list font (font-spec, font-entity, or font-object).
+Print $arg0 or $ assuming it is a list font (font-spec, font-entity, or font-object).
 end
 
 define xbacktrace

-- 
Alan Mackenzie (Nuremberg, Germany).