public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
From: tromey@sourceware.org
To: archer-commits@sourceware.org
Subject: [SCM]  archer-tromey-python: gdb
Date: Thu, 06 Nov 2008 19:58:00 -0000	[thread overview]
Message-ID: <20081106195819.20482.qmail@sourceware.org> (raw)

The branch, archer-tromey-python has been updated
       via  95bc4ef80d85b793a2cc50d39db64f2e7abd8551 (commit)
      from  e066d5afc0238f478df70c2b2f0c52d58959eb4d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 95bc4ef80d85b793a2cc50d39db64f2e7abd8551
Author: Tom Tromey <tromey@redhat.com>
Date:   Thu Nov 6 12:57:17 2008 -0700

    gdb
    	* varobj.c (struct varobj) <constructor>: New field.
    	(varobj_set_display_format): Update.
    	(varobj_get_display_hint): Likewise.
    	(varobj_get_num_children): Likewise.
    	(varobj_list_children): Likewise.
    	(install_new_value): Destroy old pretty-printer.
    	(install_visualizer): Update.  Recompute children when visualizer
    	is removed.
    	(install_default_visualizer): Don't instantiate printer.  Add
    	'type' argument.
    	(new_variable): Initialize new field.
    	(free_variable): Destroy new field.
    	(instantiate_pretty_printer): New function.
    	(varobj_set_visualizer): Don't instantiate printer.
    	* python/python-internal.h (objfpy_get_mi_printers,
    	objfpy_get_cli_printers): Remove.
    	(objfpy_get_printers): Declare.
    	(gdbpy_instantiate_printer): Declare.
    	* python/python.c (find_pretty_printer): Remove is_mi and dictp
    	arguments.
    	(_initialize_python): Initialize pretty_printers, not
    	cli_pretty_printers and mi_pretty_printers.
    	<_format_children>: Update.  Conditionally call 'children'.
    	(apply_pretty_printer): Update.  Instantiate printer.
    	(apply_val_pretty_printer): Update.  Instantiate printer.
    	(pretty_print_one_value): Rename func argument to printer.  Remove
    	value argument.  Update.
    	(gdbpy_instantiate_printer): New function.
    	(apply_varobj_pretty_printer): Update.
    	(gdbpy_get_varobj_pretty_printer): Update.
    	* python/python-objfile.c (objfile_object): Remove mi_printers,
    	cli_printers; add printers.
    	(objfpy_dealloc): Update.
    	(objfpy_new): Update.
    	(objfpy_get_printers): Rename from objfpy_get_mi_printers.
    	Update.
    	(objfpy_set_printers): Rename from objfpy_set_mi_printers.
    	Update.
    	(objfpy_get_cli_printers): Remove.
    	(objfpy_set_cli_printers): Remove.
    	(objfile_to_objfile_object): Update.
    	(objfile_getset): Update.
    gdb/doc
    	* gdb.texinfo (Pretty Printing): Update.
    	(GDB/MI Variable Objects): Likewise.
    gdb/testsuite
    	* gdb.python/python-mi.exp: Update.
    	* gdb.python/python-prettyprint.py: Move to purely class-based
    	printers.

-----------------------------------------------------------------------

Summary of changes:
 gdb/ChangeLog                                  |   45 +++++
 gdb/doc/ChangeLog                              |    5 +
 gdb/doc/gdb.texinfo                            |   92 ++++------
 gdb/python/python-internal.h                   |    4 +-
 gdb/python/python-objfile.c                    |   88 ++--------
 gdb/python/python.c                            |  221 +++++++++++++-----------
 gdb/testsuite/ChangeLog                        |    6 +
 gdb/testsuite/gdb.python/python-mi.exp         |    4 +-
 gdb/testsuite/gdb.python/python-prettyprint.py |   76 +++++----
 gdb/varobj.c                                   |  150 +++++++++-------
 10 files changed, 360 insertions(+), 331 deletions(-)

First 500 lines of diff:
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5533820..9333dcf 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,48 @@
+2008-11-06  Tom Tromey  <tromey@redhat.com>
+
+	* varobj.c (struct varobj) <constructor>: New field.
+	(varobj_set_display_format): Update.
+	(varobj_get_display_hint): Likewise.
+	(varobj_get_num_children): Likewise.
+	(varobj_list_children): Likewise.
+	(install_new_value): Destroy old pretty-printer.
+	(install_visualizer): Update.  Recompute children when visualizer
+	is removed.
+	(install_default_visualizer): Don't instantiate printer.  Add
+	'type' argument.
+	(new_variable): Initialize new field.
+	(free_variable): Destroy new field.
+	(instantiate_pretty_printer): New function.
+	(varobj_set_visualizer): Don't instantiate printer.
+	* python/python-internal.h (objfpy_get_mi_printers,
+	objfpy_get_cli_printers): Remove.
+	(objfpy_get_printers): Declare.
+	(gdbpy_instantiate_printer): Declare.
+	* python/python.c (find_pretty_printer): Remove is_mi and dictp
+	arguments.
+	(_initialize_python): Initialize pretty_printers, not
+	cli_pretty_printers and mi_pretty_printers.
+	<_format_children>: Update.  Conditionally call 'children'.
+	(apply_pretty_printer): Update.  Instantiate printer.
+	(apply_val_pretty_printer): Update.  Instantiate printer.
+	(pretty_print_one_value): Rename func argument to printer.  Remove
+	value argument.  Update.
+	(gdbpy_instantiate_printer): New function.
+	(apply_varobj_pretty_printer): Update.
+	(gdbpy_get_varobj_pretty_printer): Update.
+	* python/python-objfile.c (objfile_object): Remove mi_printers,
+	cli_printers; add printers.
+	(objfpy_dealloc): Update.
+	(objfpy_new): Update.
+	(objfpy_get_printers): Rename from objfpy_get_mi_printers.
+	Update.
+	(objfpy_set_printers): Rename from objfpy_set_mi_printers.
+	Update.
+	(objfpy_get_cli_printers): Remove.
+	(objfpy_set_cli_printers): Remove.
+	(objfile_to_objfile_object): Update.
+	(objfile_getset): Update.
+
 2008-11-03  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
 	* python/python.c (find_pretty_printer): Fix gcc-4.3.1 warnings.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 26c9ed2..9d45150 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2008-11-06  Tom Tromey  <tromey@redhat.com>
+
+	* gdb.texinfo (Pretty Printing): Update.
+	(GDB/MI Variable Objects): Likewise.
+
 2008-10-27  Tom Tromey  <tromey@redhat.com>
 
 	* gdb.texinfo (Pretty Printing): Reword list of predefined display
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 787a438..071c912 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17951,24 +17951,31 @@ using Python code.  This mechanism works for both MI and the CLI.
 A pretty-printer is an object that implements a specific interface.
 There is no predefined base class for pretty-printers.
 
-@defop Operation {pretty printer} children (self, val)
-This method is used by both the MI and CLI code.  When printing a
-value, @value{GDBN} will call this method to display the children of
-@var{val}, an instance of @code{gdb.Value}.
+@defop Operation {pretty printer} __init__ (self, val)
+When printing a value, @value{GDBN} constructs an instance of the
+pretty-printer.  @var{val} is the value to be printed, an instance of
+@code{gdb.Value}.
+@end defop
+
+@defop Operation {pretty printer} children (self)
+When printing a value, @value{GDBN} will call this method to compute
+the children of the value passed to the object's constructor.
 
 This method must return an object conforming to the Python iterator
 protocol.  Each element returned by the iterator must be a tuple
 holding two elements.  The first element is the ``name'' of the child;
 the second element is the child's value.  The value can be any Python
 object which is convertible to a @value{GDBN} value.
-@end defop
 
-@defop Operation {pretty printer} display_hint (self, val)
-This method is only used by the MI printer.
+This method is optional.  If it does not exist, @value{GDBN} will act
+as though the value has no children.
+@end defop
 
-This method must return a string.  It will be supplied to the MI
-consumer as a @samp{displayhint} attribute of the variable being
-printed.
+@defop Operation {pretty printer} display_hint (self)
+This method must return a string.  The CLI may use this to change the
+formatting of children of a value.  The result will also be supplied
+to an MI consumer as a @samp{displayhint} attribute of the variable
+being printed.
 
 Some display hints are predefined by @value{GDBN}:
 
@@ -17980,10 +17987,9 @@ alternate between keys and values.
 @end table
 @end defop
 
-@defop Operation {pretty printer} to_string (self, val)
-This method is used by both the MI and CLI code.  When printing a
-value, @value{GDBN} will call this method to display the string
-representation of @var{val}, an instance of @code{gdb.Value}.
+@defop Operation {pretty printer} to_string (self)
+@value{GDBN} will call this method to display the string
+representation of the value passed to the object's constructor.
 
 When printing from the CLI, if the @code{to_string} method exists,
 then @value{GDBN} will prepend its result to the values returned by
@@ -17992,13 +17998,15 @@ then @value{GDBN} will prepend its result to the values returned by
 This method must return a string.
 @end defop
 
-@subsubsection Selecting CLI Pretty-Printers
+@subsubsection Selecting Pretty-Printers
 
-The Python dictionary @code{gdb.cli_pretty_printers} maps regular
-expressions (strings) onto pretty-printers.  A pretty-printer is
-either a function or an object.
+The Python dictionary @code{gdb.pretty_printers} maps regular
+expressions (strings) onto constructors.  A constructor, in this
+context, is a function which takes a single @code{gdb.Value} argument
+and returns a a pretty-printer conforming to the interface definition
+above.
 
-When printing a value, @value{GDBN} first computes the values'
+When printing a value, @value{GDBN} first computes the value's
 canonical type by following typedefs, following a reference type to
 its referenced type, and removing qualifiers, such as @code{const} or
 @code{volatile}.  The name of this type is then compared to each
@@ -18006,46 +18014,23 @@ regular expression.  If a regular expression matches, then the
 corresponding pretty-printer is invoked with a @code{gdb.Value}
 representing the value to be printed.
 
-If the pretty-printer is a function, the function is called directly.
-
-If the pretty-printer is an object, the object's methods are called as
-described above.
-
-If the pretty-printer returns a string, it is printed.  If it returns any
-Python value that is convertible to a @code{gdb.Value}, then that
-value is passed to the regular @value{GDBN} type-printing code.
-
 The order in which the regular expressions are tried is not specified.
 
-Here is an example showing how a @code{std::string} might be printed:
-
-@smallexample
-def printstdstring(val):
-    return val['_M_dataplus']['_M_p']
-
-gdb.cli_pretty_printers['^std::basic_string<char.*>$'] = printstdstring
-@end smallexample
-
-Here is an example of the same printer, using a class:
+Here is an example showing how a @code{std::string} printer might be
+written:
 
 @smallexample
 class StdStringPrinter:
-    def to_string(self, val):
-        return val['_M_dataplus']['_M_p']
-
-gdb.cli_pretty_printers['^std::basic_string<char.*>$'] = StdStringPrinter()
-@end smallexample
+    "Print a std::string"
 
-@subsubsection Selecting MI Pretty-Printers
+    def __init__(self, val):
+        self.val = val
 
-MI pretty-printers are selected using a dictionary named
-@code{gdb.mi_pretty_printers}.  A key in this dictionary should be a
-regular expression in string form.  A value in this dictionary should
-be a constructor which takes no arguments and which returns a new
-object of the form described above.
+    def to_string(self):
+        return self.val['_M_dataplus']['_M_p']
 
-@value{GDBN} will consult @code{gdb.mi_pretty_printers} whenever a new
-MI variable object is created.
+gdb.pretty_printers['^std::basic_string<char.*>$'] = StdStringPrinter
+@end smallexample
 
 @node Threads In Python
 @subsubsection Threads In Python
@@ -21821,9 +21806,8 @@ The pre-defined function @code{gdb.get_default_visualizer} may be used
 to select a visualizer according to the type of the varobj.  This is
 called when a varobj is created, and so ordinarily is not needed.
 
-@code{gdb.get_default_visualizer} looks in a global dictionary named
-@code{gdb.mi_pretty_printers}.  This works analogously to
-@code{gdb.cli_pretty_printers}.
+@code{gdb.get_default_visualizer} looks in the global dictionary named
+@code{gdb.pretty_printers}.
 
 This feature is only available if Python support is enabled.
 
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 6dff805..672a2fe 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -75,8 +75,7 @@ PyObject *gdb_owned_value_to_value_object (struct value *v);
 PyObject *type_to_type_object (struct type *);
 PyObject *objfile_to_objfile_object (struct objfile *);
 
-PyObject *objfpy_get_mi_printers (PyObject *, void *);
-PyObject *objfpy_get_cli_printers (PyObject *, void *);
+PyObject *objfpy_get_printers (PyObject *, void *);
 
 struct block *block_object_to_block (PyObject *obj);
 struct symbol *symbol_object_to_symbol (PyObject *obj);
@@ -130,6 +129,7 @@ int gdbpy_is_string (PyObject *obj);
 char *apply_varobj_pretty_printer (PyObject *print_obj, struct value *value,
 				   struct value **replacement);
 PyObject *gdbpy_get_varobj_pretty_printer (struct type *type);
+PyObject *gdbpy_instantiate_printer (PyObject *cons, struct value *value);
 
 extern PyObject *gdbpy_children_cst;
 extern PyObject *gdbpy_to_string_cst;
diff --git a/gdb/python/python-objfile.c b/gdb/python/python-objfile.c
index 6b5a7c3..0a942c8 100644
--- a/gdb/python/python-objfile.c
+++ b/gdb/python/python-objfile.c
@@ -29,9 +29,8 @@ typedef struct
   /* The corresponding objfile.  */
   struct objfile *objfile;
 
-  /* The pretty-printer dictionaries.  */
-  PyObject *mi_printers;
-  PyObject *cli_printers;
+  /* The pretty-printer dictionary.  */
+  PyObject *printers;
 } objfile_object;
 
 static PyTypeObject objfile_object_type;
@@ -55,8 +54,7 @@ static void
 objfpy_dealloc (PyObject *o)
 {
   objfile_object *self = (objfile_object *) o;
-  Py_XDECREF (self->mi_printers);
-  Py_XDECREF (self->cli_printers);
+  Py_XDECREF (self->printers);
   self->ob_type->tp_free ((PyObject *) self);
 }
 
@@ -67,17 +65,9 @@ objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
   if (self)
     {
       self->objfile = NULL;
-      /* Initialize in case of early return.  */
-      self->cli_printers = NULL;
 
-      self->mi_printers = PyDict_New ();
-      if (!self->mi_printers)
-	{
-	  Py_DECREF (self);
-	  return NULL;
-	}
-      self->cli_printers = PyDict_New ();
-      if (!self->cli_printers)
+      self->printers = PyDict_New ();
+      if (!self->printers)
 	{
 	  Py_DECREF (self);
 	  return NULL;
@@ -87,67 +77,34 @@ objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
 }
 
 PyObject *
-objfpy_get_mi_printers (PyObject *o, void *ignore)
-{
-  objfile_object *self = (objfile_object *) o;
-  Py_INCREF (self->mi_printers);
-  return self->mi_printers;
-}
-
-static int
-objfpy_set_mi_printers (PyObject *o, PyObject *value, void *ignore)
-{
-  objfile_object *self = (objfile_object *) o;
-  if (! value)
-    {
-      PyErr_SetString (PyExc_TypeError,
-		       "cannot delete the mi_pretty_printers attribute");
-      return -1;
-    }
-
-  if (! PyDict_Check (value))
-    {
-      PyErr_SetString (PyExc_TypeError,
-		       "the mi_pretty_printers attribute must be a dictionary");
-      return -1;
-    }
-
-  Py_XDECREF (self->mi_printers);
-  Py_INCREF (value);
-  self->mi_printers = value;
-
-  return 0;
-}
-
-PyObject *
-objfpy_get_cli_printers (PyObject *o, void *ignore)
+objfpy_get_printers (PyObject *o, void *ignore)
 {
   objfile_object *self = (objfile_object *) o;
-  Py_INCREF (self->cli_printers);
-  return self->cli_printers;
+  Py_INCREF (self->printers);
+  return self->printers;
 }
 
 static int
-objfpy_set_cli_printers (PyObject *o, PyObject *value, void *ignore)
+objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
 {
   objfile_object *self = (objfile_object *) o;
   if (! value)
     {
       PyErr_SetString (PyExc_TypeError,
-		       "cannot delete the cli_pretty_printers attribute");
+		       "cannot delete the pretty_printers attribute");
       return -1;
     }
 
   if (! PyDict_Check (value))
     {
       PyErr_SetString (PyExc_TypeError,
-		       "the cli_pretty_printers attribute must be a dictionary");
+		       "the pretty_printers attribute must be a dictionary");
       return -1;
     }
 
-  Py_XDECREF (self->cli_printers);
+  Py_XDECREF (self->printers);
   Py_INCREF (value);
-  self->cli_printers = value;
+  self->printers = value;
 
   return 0;
 }
@@ -181,18 +138,9 @@ objfile_to_objfile_object (struct objfile *objfile)
 	  PyObject *dict;
 
 	  object->objfile = objfile;
-	  /* Initialize in case of early return.  */
-	  object->cli_printers = NULL;
-
-	  object->mi_printers = PyDict_New ();
-	  if (!object->mi_printers)
-	    {
-	      Py_DECREF (object);
-	      return NULL;
-	    }
 
-	  object->cli_printers = PyDict_New ();
-	  if (!object->cli_printers)
+	  object->printers = PyDict_New ();
+	  if (!object->printers)
 	    {
 	      Py_DECREF (object);
 	      return NULL;
@@ -223,10 +171,8 @@ gdbpy_initialize_objfile (void)
 
 static PyGetSetDef objfile_getset[] =
 {
-  { "mi_pretty_printers", objfpy_get_mi_printers, objfpy_set_mi_printers,
-    "MI pretty printers", NULL },
-  { "cli_pretty_printers", objfpy_get_cli_printers, objfpy_set_cli_printers,
-    "CLI pretty printers", NULL },
+  { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
+    "Pretty printers", NULL },
   { NULL }
 };
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 5f6a269..d6cea7e 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -676,17 +676,14 @@ search_pp_dictionary (PyObject *dict, char *type_name)
   return found;
 }
 
-/* Find the pretty-printing function for TYPE.  If no pretty-printer
-   exists, return NULL.  If one exists, return a borrowed reference.
-   If a printer is found, *DICTP is set to a reference to the
-   dictionary object; it must be derefed by the caller.  DICT_NAME is
-   the name of the dictionary to search for types.  */
+/* Find the pretty-printing constructor function for TYPE.  If no
+   pretty-printer exists, return NULL.  If one exists, return a new
+   reference.  */
 static PyObject *
-find_pretty_printer (struct type *type, PyObject **dictp, int is_mi)
+find_pretty_printer (struct type *type)
 {
   PyObject *dict, *found = NULL;
   char *type_name = NULL;
-  char *dict_name;
   struct objfile *obj;
   volatile struct gdb_exception except;
 
@@ -710,11 +707,7 @@ find_pretty_printer (struct type *type, PyObject **dictp, int is_mi)
     if (!objf)
       continue;
 
-    if (is_mi)
-      dict = objfpy_get_mi_printers (objf, NULL);
-    else
-      dict = objfpy_get_cli_printers (objf, NULL);
-
+    dict = objfpy_get_printers (objf, NULL);
     found = search_pp_dictionary (dict, type_name);
     if (found)
       goto done;
@@ -723,11 +716,10 @@ find_pretty_printer (struct type *type, PyObject **dictp, int is_mi)
   }
 
   /* Fetch the global pretty printer dictionary.  */
-  dict_name = is_mi ? "mi_pretty_printers" : "cli_pretty_printers";
   dict = NULL;
-  if (! PyObject_HasAttrString (gdb_module, dict_name))
+  if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))
     goto done;
-  dict = PyObject_GetAttrString (gdb_module, dict_name);
+  dict = PyObject_GetAttrString (gdb_module, "pretty_printers");
   if (! dict)
     goto done;
   if (! PyDict_Check (dict) || ! PyDict_Size (dict))
@@ -739,57 +731,44 @@ find_pretty_printer (struct type *type, PyObject **dictp, int is_mi)
   xfree (type_name);
 
   if (found)
-    *dictp = dict;
-  else
-    Py_XDECREF (dict);
+    Py_INCREF (found);
+  Py_XDECREF (dict);
 
   return found;
 }
 
-/* Pretty-print a single value, VALUE, using the printer function
-   FUNC.  If the function returns a string, an xmalloc()d copy is
-   returned.  Otherwise, if the function returns a value, a *OUT_VALUE
-   is set to the value, and NULL is returned.  On error, *OUT_VALUE is
-   set to NULL and NULL is returned.  If CHILDREN is true, we may also
-   try to call an object's "children" method and format the output
+/* Pretty-print a single value, via the printer object PRINTER.  If
+   the function returns a string, an xmalloc()d copy is returned.
+   Otherwise, if the function returns a value, a *OUT_VALUE is set to
+   the value, and NULL is returned.  On error, *OUT_VALUE is set to
+   NULL and NULL is returned.  If CHILDREN is true, we may also try to
+   call an object's "children" method and format the output
    accordingly.  */
 static char *
-pretty_print_one_value (PyObject *func, struct value *value,
-			struct value **out_value, int children)
+pretty_print_one_value (PyObject *printer, struct value **out_value,
+			int children)
 {
   char *output = NULL;
   volatile struct gdb_exception except;
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      PyObject *val_obj, *result;
-
-      /* FIXME: memory management here.  Why are values so
-	 funny?  */
-      value = value_copy (value);
-
-      val_obj = value_to_value_object (value);
+      PyObject *result;
 
-      /* The function might be an MI-style class, or it might be an
-	 ordinary function.  If CHILDREN is true, the existence of
-	 either the to_string or children methods means to call
-	 _format_children.  Otherwise, if we have to_string, call it.
-	 As a last resort, call the object as a function.  */
+      /* If CHILDREN is true, call _format_children.  Otherwise, just
+	 try to call the object's to_string method.  */
       if (children


hooks/post-receive
--
Repository for Project Archer.


             reply	other threads:[~2008-11-06 19:58 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-06 19:58 tromey [this message]
  -- strict thread matches above, loose matches on Subject: below --
2009-04-07 20:28 tromey
2009-03-24 17:27 tromey
2009-02-05 19:56 tromey
2008-12-17 23:10 tromey
2008-12-15 22:38 tromey
2008-12-13  0:37 tromey
2008-12-12 23:54 tromey
2008-12-10 15:28 tromey
2008-12-09  0:33 tromey
2008-12-02 21:29 tromey
2008-12-01 19:10 tromey
2008-11-25 21:17 tromey
2008-11-21 18:25 tromey
2008-11-18 18:52 tromey
2008-11-18 15:54 tromey
2008-11-17 15:45 tromey
2008-11-16 22:18 tromey
2008-11-16 16:56 tromey
2008-11-12  1:54 tromey
2008-11-10 14:15 tromey
2008-11-06 21:11 tromey
2008-10-23 22:27 tromey
2008-10-23 21:28 tromey
2008-10-22 18:18 tromey
2008-10-21 18:32 tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081106195819.20482.qmail@sourceware.org \
    --to=tromey@sourceware.org \
    --cc=archer-commits@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).