bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/4] builtins: extract file content executor function


From: Matheus Afonso Martins Moreira
Subject: [PATCH 1/4] builtins: extract file content executor function
Date: Thu, 2 May 2024 19:22:30 -0300

Extract into a dedicated helper function the code which loads
the contents of a file and executes it in the current shell.
This separates this useful functionality from the path resolution
mechanism used by the source builtin, allowing new functionality
to be built upon it.

Signed-off-by: Matheus Afonso Martins Moreira <matheus@matheusmoreira.com>
---
 builtins/common.c   | 64 +++++++++++++++++++++++++++++++++++++++++++++
 builtins/common.h   |  1 +
 builtins/source.def | 62 +++----------------------------------------
 3 files changed, 68 insertions(+), 59 deletions(-)

diff --git a/builtins/common.c b/builtins/common.c
index 19b00c4d..6ef59e6c 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -1129,3 +1129,67 @@ set_expand_once (nval, uwp)
   return oa;
 }
 #endif
+
+/* If this . script is supplied arguments, we save the dollar vars and
+   replace them with the script arguments for the duration of the script's
+   execution.  If the script does not change the dollar vars, we restore
+   what we saved.  If the dollar vars are changed in the script, and we are
+   not executing a shell function, we leave the new values alone and free
+   the saved values. */
+static void
+maybe_pop_dollar_vars ()
+{
+  if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
+    dispose_saved_dollar_vars ();
+  else
+    pop_dollar_vars ();
+  if (debugging_mode)
+    pop_args ();       /* restore BASH_ARGC and BASH_ARGV */
+  set_dollar_vars_unchanged ();
+  invalidate_cached_quoted_dollar_at ();       /* just invalidate to be safe */
+}
+
+/* Read and execute commands from the file passed as argument.  Guess what.
+   This cannot be done in a subshell, since things like variable assignments
+   take place in there.  So, I open the file, place it into a large string,
+   close the file, and then execute the string. */
+int
+execute_file_contents (list, filename, framename)
+     WORD_LIST *list;
+     const char *filename, *framename;
+{
+  int result;
+  char *debug_trap;
+  begin_unwind_frame (framename);
+  add_unwind_protect (xfree, filename);
+
+  if (list->next)
+    {
+      push_dollar_vars ();
+      add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
+      if (debugging_mode || shell_compatibility_level <= 44)
+       init_bash_argv ();      /* Initialize BASH_ARGV and BASH_ARGC */
+      remember_args (list->next, 1);
+      if (debugging_mode)
+       push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
+    }
+  set_dollar_vars_unchanged ();
+
+  /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
+     is set.  XXX - should sourced files inherit the RETURN trap?  Functions
+     don't. */
+  debug_trap = TRAP_STRING (DEBUG_TRAP);
+  if (debug_trap && function_trace_mode == 0)
+    {
+      debug_trap = savestring (debug_trap);
+      add_unwind_protect (xfree, debug_trap);
+      add_unwind_protect (maybe_set_debug_trap, debug_trap);
+      restore_default_signal (DEBUG_TRAP);
+    }
+
+  result = source_file (filename, (list && list->next));
+
+  run_unwind_frame (framename);
+
+  return (result);
+}
diff --git a/builtins/common.h b/builtins/common.h
index a170f8fc..ab5fcfaf 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -227,6 +227,7 @@ extern int maybe_execute_file PARAMS((const char *, int));
 extern int force_execute_file PARAMS((const char *, int));
 extern int source_file PARAMS((const char *, int));
 extern int fc_execute_file PARAMS((const char *));
+extern int execute_file_contents PARAMS((WORD_LIST *, const char *, const char 
*));
 
 /* variables from common.c */
 extern sh_builtin_func_t *this_shell_builtin;
diff --git a/builtins/source.def b/builtins/source.def
index 5b2f994d..b1567aab 100644
--- a/builtins/source.def
+++ b/builtins/source.def
@@ -80,8 +80,6 @@ $END
 extern int errno;
 #endif /* !errno */
 
-static void maybe_pop_dollar_vars PARAMS((void));
-
 /* If non-zero, `.' uses $PATH to look up the script to be sourced. */
 int source_uses_path = 1;
 
@@ -89,35 +87,12 @@ int source_uses_path = 1;
    is not found in the $PATH. */
 int source_searches_cwd = 1;
 
-/* If this . script is supplied arguments, we save the dollar vars and
-   replace them with the script arguments for the duration of the script's
-   execution.  If the script does not change the dollar vars, we restore
-   what we saved.  If the dollar vars are changed in the script, and we are
-   not executing a shell function, we leave the new values alone and free
-   the saved values. */
-static void
-maybe_pop_dollar_vars ()
-{
-  if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
-    dispose_saved_dollar_vars ();
-  else
-    pop_dollar_vars ();
-  if (debugging_mode)
-    pop_args ();       /* restore BASH_ARGC and BASH_ARGV */
-  set_dollar_vars_unchanged ();
-  invalidate_cached_quoted_dollar_at ();       /* just invalidate to be safe */
-}
-
-/* Read and execute commands from the file passed as argument.  Guess what.
-   This cannot be done in a subshell, since things like variable assignments
-   take place in there.  So, I open the file, place it into a large string,
-   close the file, and then execute the string. */
+/* Read and execute commands from the file passed as argument. */
 int
 source_builtin (list)
      WORD_LIST *list;
 {
-  int result;
-  char *filename, *debug_trap, *x;
+  char *filename, *x;
 
   if (no_options (list))
     return (EX_USAGE);
@@ -165,36 +140,5 @@ source_builtin (list)
        filename = savestring (list->word->word);
     }
 
-  begin_unwind_frame ("source");
-  add_unwind_protect (xfree, filename);
-
-  if (list->next)
-    {
-      push_dollar_vars ();
-      add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL);
-      if (debugging_mode || shell_compatibility_level <= 44)
-       init_bash_argv ();      /* Initialize BASH_ARGV and BASH_ARGC */
-      remember_args (list->next, 1);
-      if (debugging_mode)
-       push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */
-    }
-  set_dollar_vars_unchanged ();
-
-  /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded)
-     is set.  XXX - should sourced files inherit the RETURN trap?  Functions
-     don't. */
-  debug_trap = TRAP_STRING (DEBUG_TRAP);
-  if (debug_trap && function_trace_mode == 0)
-    {
-      debug_trap = savestring (debug_trap);
-      add_unwind_protect (xfree, debug_trap);
-      add_unwind_protect (maybe_set_debug_trap, debug_trap);
-      restore_default_signal (DEBUG_TRAP);
-    }
-
-  result = source_file (filename, (list && list->next));
-
-  run_unwind_frame ("source");
-
-  return (result);
+  return execute_file_contents (list, filename, "source");
 }
-- 
2.44.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]