722ddc179547d932a72097371f5bc31128c5a21e — Drew DeVault 2 months ago 01d94fc
Implement xtrace option & PS4 expansion
3 files changed, 26 insertions(+), 0 deletions(-)

M include/mrsh/entry.h
M shell/entry.c
M shell/task/command.c
M include/mrsh/entry.h => include/mrsh/entry.h +6 -0
@@ 17,6 17,12 @@ char *mrsh_get_ps2(struct mrsh_state *state);
  
  /**
+  * Expands $PS4 or returns the POSIX-specified default of "+ ". The caller must
+  * free the return value.
+  */
+ char *mrsh_get_ps4(struct mrsh_state *state);
+ 
+ /**
   * Copies variables from the environment and sets up internal variables like
   * IFS, PPID, PWD, etc.
   */

M shell/entry.c => shell/entry.c +8 -0
@@ 46,6 46,14 @@ return strdup("> ");
  }
  
+ char *mrsh_get_ps4(struct mrsh_state *state) {
+ 	const char *ps4 = mrsh_env_get(state, "PS4", NULL);
+ 	if (ps4 != NULL) {
+ 		return expand_ps(state, ps4);
+ 	}
+ 	return strdup("+ ");
+ }
+ 
  bool mrsh_populate_env(struct mrsh_state *state, char **environ) {
  	for (size_t i = 0; environ[i] != NULL; ++i) {
  		char *eql = strchr(environ[i], '=');

M shell/task/command.c => shell/task/command.c +12 -0
@@ 1,5 1,6 @@ #include <assert.h>
  #include <mrsh/builtin.h>
+ #include <mrsh/entry.h>
  #include <stdlib.h>
  #include "shell/task_command.h"
  #include "shell/task.h"


@@ 57,6 58,17 @@ get_args(&tc->args, sc, ctx);
  		const char *argv_0 = (char *)tc->args.data[0];
  
+ 		if ((ctx->state->options & MRSH_OPT_XTRACE)) {
+ 			char *ps4 = mrsh_get_ps4(ctx->state);
+ 			fprintf(stderr, "%s", ps4);
+ 			for (size_t i = 0; i < tc->args.len - 1; ++i) {
+ 				fprintf(stderr, "%s%s", i != 0 ? " " : "",
+ 						(char *)tc->args.data[i]);
+ 			}
+ 			fprintf(stderr, "\n");
+ 			free(ps4);
+ 		}
+ 
  		enum task_command_type type;
  		tc->fn_def = mrsh_hashtable_get(&ctx->state->functions, argv_0);
  		if (tc->fn_def != NULL) {