Change return type of find_and_open_script
authorTom Tromey <tom@tromey.com>
Thu, 27 Apr 2017 03:49:55 +0000 (21:49 -0600)
committerTom Tromey <tom@tromey.com>
Thu, 3 Aug 2017 13:58:53 +0000 (07:58 -0600)
This changes find_and_open_script to return a
gdb::optional<open_script>, where open_script is a new type
encapsulating the two return values.  The new type helps avoid
cleanups in the callers.

ChangeLog
2017-08-03  Tom Tromey  <tom@tromey.com>

* cli/cli-cmds.c (find_and_open_script): Change return type.
Remove "streamp" and "full_path" parameters.
(source_script_with_search): Update.
* auto-load.c (source_script_file): Update.
* cli/cli-cmds.h (find_and_open_script): Change type.
(open_script): New struct.

gdb/ChangeLog
gdb/auto-load.c
gdb/cli/cli-cmds.c
gdb/cli/cli-cmds.h

index 17a818cc6b34e9f50165b1af778172d1fb29cb57..80b9c2bbfc00048474ef08dd55dcaa88852ba88b 100644 (file)
@@ -1,3 +1,12 @@
+2017-08-03  Tom Tromey  <tom@tromey.com>
+
+       * cli/cli-cmds.c (find_and_open_script): Change return type.
+       Remove "streamp" and "full_path" parameters.
+       (source_script_with_search): Update.
+       * auto-load.c (source_script_file): Update.
+       * cli/cli-cmds.h (find_and_open_script): Change type.
+       (open_script): New struct.
+
 2017-08-03  Tom Tromey  <tom@tromey.com>
 
        * xml-support.c (xml_fetch_content_from_file): Update.
index 292f2ae88e9b46b8a230daeabcbf10b71a9cc04d..9f1f13f926d820d8a54a66cc2aca8e44c3774e21 100644 (file)
@@ -928,10 +928,7 @@ source_script_file (struct auto_load_pspace_info *pspace_info,
                    const char *section_name, unsigned int offset,
                    const char *file)
 {
-  FILE *stream;
-  char *full_path;
-  int opened, in_hash_table;
-  struct cleanup *cleanups;
+  int in_hash_table;
   objfile_script_sourcer_func *sourcer;
 
   /* Skip this script if support is not compiled in.  */
@@ -953,27 +950,22 @@ source_script_file (struct auto_load_pspace_info *pspace_info,
       return;
     }
 
-  opened = find_and_open_script (file, 1 /*search_path*/,
-                                &stream, &full_path);
+  gdb::optional<open_script> opened = find_and_open_script (file,
+                                                           1 /*search_path*/);
 
-  cleanups = make_cleanup (null_cleanup, NULL);
   if (opened)
     {
-      make_cleanup_fclose (stream);
-      make_cleanup (xfree, full_path);
-
-      if (!file_is_auto_load_safe (full_path,
+      if (!file_is_auto_load_safe (opened->full_path.get (),
                                   _("auto-load: Loading %s script "
                                     "\"%s\" from section \"%s\" of "
                                     "objfile \"%s\".\n"),
-                                  ext_lang_name (language), full_path,
+                                  ext_lang_name (language),
+                                  opened->full_path.get (),
                                   section_name, objfile_name (objfile)))
-       opened = 0;
+       opened.reset ();
     }
   else
     {
-      full_path = NULL;
-
       /* If one script isn't found it's not uncommon for more to not be
         found either.  We don't want to print a message for each script,
         too much noise.  Instead, we print the warning once and tell the
@@ -986,14 +978,16 @@ source_script_file (struct auto_load_pspace_info *pspace_info,
                                            section_name, offset);
     }
 
-  in_hash_table = maybe_add_script_file (pspace_info, opened, file, full_path,
+  in_hash_table = maybe_add_script_file (pspace_info, bool (opened), file,
+                                        (opened
+                                         ? opened->full_path.get ()
+                                         : NULL),
                                         language);
 
   /* If this file is not currently loaded, load it.  */
   if (opened && !in_hash_table)
-    sourcer (language, objfile, stream, full_path);
-
-  do_cleanups (cleanups);
+    sourcer (language, objfile, opened->stream.get (),
+            opened->full_path.get ());
 }
 
 /* Subroutine of source_section_scripts to simplify it.
index 8f0376e5f03d566588a7693e3dcc9858d137ddc3..465053241019494982e619ed84c47bfbb3b46f2b 100644 (file)
@@ -506,22 +506,21 @@ show_script_ext_mode (struct ui_file *file, int from_tty,
 
 /* Try to open SCRIPT_FILE.
    If successful, the full path name is stored in *FULL_PATHP,
-   the stream is stored in *STREAMP, and return 1.
-   The caller is responsible for freeing *FULL_PATHP.
-   If not successful, return 0; errno is set for the last file
+   and the stream is returned.
+   If not successful, return NULL; errno is set for the last file
    we tried to open.
 
    If SEARCH_PATH is non-zero, and the file isn't found in cwd,
    search for it in the source search path.  */
 
-int
-find_and_open_script (const char *script_file, int search_path,
-                     FILE **streamp, char **full_pathp)
+gdb::optional<open_script>
+find_and_open_script (const char *script_file, int search_path)
 {
   char *file;
   int fd;
   struct cleanup *old_cleanups;
   int search_flags = OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH;
+  gdb::optional<open_script> opened;
 
   file = tilde_expand (script_file);
   old_cleanups = make_cleanup (xfree, file);
@@ -531,32 +530,33 @@ find_and_open_script (const char *script_file, int search_path,
 
   /* Search for and open 'file' on the search path used for source
      files.  Put the full location in *FULL_PATHP.  */
+  char *temp_path;
   fd = openp (source_path, search_flags,
-             file, O_RDONLY, full_pathp);
+             file, O_RDONLY, &temp_path);
+  gdb::unique_xmalloc_ptr<char> full_path (temp_path);
 
   if (fd == -1)
     {
       int save_errno = errno;
       do_cleanups (old_cleanups);
       errno = save_errno;
-      return 0;
+      return opened;
     }
 
   do_cleanups (old_cleanups);
 
-  *streamp = fdopen (fd, FOPEN_RT);
-  if (*streamp == NULL)
+  FILE *result = fdopen (fd, FOPEN_RT);
+  if (result == NULL)
     {
       int save_errno = errno;
 
       close (fd);
-      if (full_pathp)
-       xfree (*full_pathp);
       errno = save_errno;
-      return 0;
     }
+  else
+    opened.emplace (gdb_file_up (result), std::move (full_path));
 
-  return 1;
+  return opened;
 }
 
 /* Load script FILE, which has already been opened as STREAM.
@@ -607,14 +607,12 @@ source_script_from_stream (FILE *stream, const char *file,
 static void
 source_script_with_search (const char *file, int from_tty, int search_path)
 {
-  FILE *stream;
-  char *full_path;
-  struct cleanup *old_cleanups;
 
   if (file == NULL || *file == 0)
     error (_("source command requires file name of file to source."));
 
-  if (!find_and_open_script (file, search_path, &stream, &full_path))
+  gdb::optional<open_script> opened = find_and_open_script (file, search_path);
+  if (!opened)
     {
       /* The script wasn't found, or was otherwise inaccessible.
          If the source command was invoked interactively, throw an
@@ -629,15 +627,13 @@ source_script_with_search (const char *file, int from_tty, int search_path)
        }
     }
 
-  old_cleanups = make_cleanup (xfree, full_path);
-  make_cleanup_fclose (stream);
   /* The python support reopens the file, so we need to pass full_path here
      in case the file was found on the search path.  It's useful to do this
      anyway so that error messages show the actual file used.  But only do
      this if we (may have) used search_path, as printing the full path in
      errors for the non-search case can be more noise than signal.  */
-  source_script_from_stream (stream, file, search_path ? full_path : file);
-  do_cleanups (old_cleanups);
+  source_script_from_stream (opened->stream.get (), file,
+                            search_path ? opened->full_path.get () : file);
 }
 
 /* Wrapper around source_script_with_search to export it to main.c
index 7ff1fca0b544cbcc34d9616a19ff271e586feb18..1122a97b3493b42a581ecf0c52987841ebed2c64 100644 (file)
@@ -17,6 +17,9 @@
 #if !defined (CLI_CMDS_H)
 #define CLI_CMDS_H 1
 
+#include "common/filestuff.h"
+#include "common/gdb_optional.h"
+
 /* Chain containing all defined commands.  */
 
 extern struct cmd_list_element *cmdlist;
@@ -117,8 +120,22 @@ extern void source_script (const char *, int);
 
 /* Exported to objfiles.c.  */
 
-extern int find_and_open_script (const char *file, int search_path,
-                                FILE **streamp, char **full_path);
+/* The script that was opened.  */
+struct open_script
+{
+  gdb_file_up stream;
+  gdb::unique_xmalloc_ptr<char> full_path;
+
+  open_script (gdb_file_up &&stream_,
+              gdb::unique_xmalloc_ptr<char> &&full_path_)
+    : stream (std::move (stream_)),
+      full_path (std::move (full_path_))
+  {
+  }
+};
+
+extern gdb::optional<open_script>
+    find_and_open_script (const char *file, int search_path);
 
 /* Command tracing state.  */