+2020-09-14  Simon Marchi  <simon.marchi@polymtl.ca>
+
+       * xml-support.h (xml_fetch_another): Change type to be a
+       function_view.
+       (xml_process_xincludes): Remove baton parameter.
+       (xml_fetch_content_from_file): Change baton parameter to
+       dirname.
+       * xml-support.c (struct xinclude_parsing_data)
+       <xinclude_parsing_data>: Remove baton parameter.
+       <fetcher_baton>: Remove.
+       (xinclude_start_include): Adjust.
+       (xml_process_xincludes): Adjust.
+       (xml_fetch_content_from_file): Replace baton parameter with
+       dirname.
+       * xml-syscall.c (syscall_parse_xml): Remove baton parameter.
+       (xml_init_syscalls_info): Use a lambda.
+       * xml-tdesc.c (tdesc_parse_xml): Remove baton parameter.
+       (file_read_description_xml): Use a lambda.
+       (fetch_available_features_from_target): Change baton parameter
+       to target_ops.
+       (target_read_description_xml): Use a lambda.
+       (target_fetch_description_xml): Use a lambda.
+       (string_read_description_xml): Update.
+
 2020-09-14  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * gdbtypes.h (TYPE_ENDIANITY_NOT_DEFAULT): Remove, replace all
 
 struct xinclude_parsing_data
 {
   xinclude_parsing_data (std::string &output_,
-                        xml_fetch_another fetcher_, void *fetcher_baton_,
+                        xml_fetch_another fetcher_,
                         int include_depth_)
     : output (output_),
       skip_depth (0),
       include_depth (include_depth_),
-      fetcher (fetcher_),
-      fetcher_baton (fetcher_baton_)
+      fetcher (fetcher_)
   {}
 
   /* Where the output goes.  */
   /* A function to call to obtain additional features, and its
      baton.  */
   xml_fetch_another fetcher;
-  void *fetcher_baton;
 };
 
 static void
     gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
                   MAX_XINCLUDE_DEPTH);
 
-  gdb::optional<gdb::char_vector> text
-    = data->fetcher (href, data->fetcher_baton);
+  gdb::optional<gdb::char_vector> text = data->fetcher (href);
   if (!text)
     gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
 
   if (!xml_process_xincludes (data->output, parser->name (),
                              text->data (), data->fetcher,
-                             data->fetcher_baton,
                              data->include_depth + 1))
     gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
 
 bool
 xml_process_xincludes (std::string &result,
                       const char *name, const char *text,
-                      xml_fetch_another fetcher, void *fetcher_baton,
-                      int depth)
+                      xml_fetch_another fetcher, int depth)
 {
-  xinclude_parsing_data data (result, fetcher, fetcher_baton, depth);
+  xinclude_parsing_data data (result, fetcher, depth);
 
   gdb_xml_parser parser (name, xinclude_elements, &data);
   parser.set_is_xinclude (true);
 }
 
 gdb::optional<gdb::char_vector>
-xml_fetch_content_from_file (const char *filename, void *baton)
+xml_fetch_content_from_file (const char *filename, const char *dirname)
 {
-  const char *dirname = (const char *) baton;
   gdb_file_up file;
 
-  if (dirname && *dirname)
+  if (dirname != nullptr && *dirname != '\0')
     {
       char *fullname = concat (dirname, "/", filename, (char *) NULL);
 
 
 #include "gdbsupport/xml-utils.h"
 #include "gdbsupport/byte-vector.h"
 #include "gdbsupport/gdb_optional.h"
+#include "gdbsupport/function-view.h"
 
 struct gdb_xml_parser;
 struct gdb_xml_element;
 
 /* Callback to fetch a new XML file, based on the provided HREF.  */
 
-typedef gdb::optional<gdb::char_vector> (*xml_fetch_another) (const char *href,
-                                                             void *baton);
+using xml_fetch_another = gdb::function_view<gdb::optional<gdb::char_vector>
+                                            (const char * /* href */)>;
 
 /* Append the expansion of TEXT after processing <xi:include> tags in
-   RESULT.  FETCHER will be called (with FETCHER_BATON) to retrieve
-   any new files.  DEPTH should be zero on the initial call.
+   RESULT.  FETCHER will be called to retrieve any new files.  DEPTH
+   should be zero on the initial call.
 
    On failure, this function uses NAME in a warning and returns false.
    It may throw an exception, but does not for XML parsing
 
 bool xml_process_xincludes (std::string &result,
                            const char *name, const char *text,
-                           xml_fetch_another fetcher, void *fetcher_baton,
-                           int depth);
+                           xml_fetch_another fetcher, int depth);
 
 /* Simplified XML parser infrastructure.  */
 
    and warn.  */
 
 extern gdb::optional<gdb::char_vector> xml_fetch_content_from_file
-    (const char *filename, void *baton);
+    (const char *filename, const char *dirname);
 
 #endif
 
 };
 
 static struct syscalls_info *
-syscall_parse_xml (const char *document, xml_fetch_another fetcher,
-                   void *fetcher_baton)
+syscall_parse_xml (const char *document, xml_fetch_another fetcher)
 {
   struct syscall_parsing_data data;
   syscalls_info_up sysinfo (new syscalls_info ());
   if (!full_file)
     return NULL;
 
-  return syscall_parse_xml (full_file->data (),
-                           xml_fetch_content_from_file,
-                           (void *) ldirname (filename).c_str ());
+  const std::string dirname = ldirname (filename);
+  auto fetch_another = [&dirname] (const char *name)
+    {
+      return xml_fetch_content_from_file (name, dirname.c_str ());
+    };
+
+  return syscall_parse_xml (full_file->data (), fetch_another);
 }
 
 /* Initializes the syscalls_info structure according to the
 
 /* Parse DOCUMENT into a target description and return it.  */
 
 static struct target_desc *
-tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
-                void *fetcher_baton)
+tdesc_parse_xml (const char *document, xml_fetch_another fetcher)
 {
   struct tdesc_parsing_data data;
 
 
   if (!xml_process_xincludes (expanded_text,
                              _("target description"),
-                             document, fetcher, fetcher_baton, 0))
+                             document, fetcher, 0))
     {
       warning (_("Could not load XML target description; ignoring"));
       return NULL;
       return NULL;
     }
 
-  return tdesc_parse_xml (tdesc_str->data (), xml_fetch_content_from_file,
-                         (void *) ldirname (filename).c_str ());
+  const std::string dirname = ldirname (filename);
+  auto fetch_another = [&dirname] (const char *name)
+    {
+      return xml_fetch_content_from_file (name, dirname.c_str ());
+    };
+
+  return tdesc_parse_xml (tdesc_str->data (), fetch_another);
 }
 
 /* Read a string representation of available features from the target,
    for <xi:include>.  */
 
 static gdb::optional<gdb::char_vector>
-fetch_available_features_from_target (const char *name, void *baton_)
+fetch_available_features_from_target (const char *name, target_ops *ops)
 {
-  struct target_ops *ops = (struct target_ops *) baton_;
-
   /* Read this object as a string.  This ensures that a NUL
      terminator is added.  */
   return target_read_stralloc (ops,
   if (!tdesc_str)
     return NULL;
 
-  return tdesc_parse_xml (tdesc_str->data (),
-                         fetch_available_features_from_target,
-                         ops);
+  auto fetch_another = [ops] (const char *name)
+    {
+      return fetch_available_features_from_target (name, ops);
+    };
+
+  return tdesc_parse_xml (tdesc_str->data (), fetch_another);
 }
 
 /* Fetches an XML target description using OPS,  processing
   if (!tdesc_str)
     return {};
 
+  auto fetch_another = [ops] (const char *name)
+    {
+      return fetch_available_features_from_target (name, ops);
+    };
   std::string output;
   if (!xml_process_xincludes (output,
                              _("target description"),
-                             tdesc_str->data (),
-                             fetch_available_features_from_target, ops, 0))
+                             tdesc_str->data (), fetch_another, 0))
     {
       warning (_("Could not load XML target description; ignoring"));
       return {};
 const struct target_desc *
 string_read_description_xml (const char *xml)
 {
-  return tdesc_parse_xml (xml, [] (const char *href, void *baton)
+  return tdesc_parse_xml (xml, [] (const char *href)
     {
       error (_("xincludes are unsupported with this method"));
       return gdb::optional<gdb::char_vector> ();
-    }, nullptr);
+    });
 }