1 2

[PATCH] Implement xtrace option & PS4 expansion

Details
Message ID
<20190228154709.4732-1-sir@cmpwn.com>
DKIM signature
permerror
Download raw message
Patch: +26 -0
---
 include/mrsh/entry.h |  6 ++++++
 shell/entry.c        |  8 ++++++++
 shell/task/command.c | 12 ++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/include/mrsh/entry.h b/include/mrsh/entry.h
index 4101907..1c9cb6d 100644
--- a/include/mrsh/entry.h
+++ b/include/mrsh/entry.h
@@ -16,6 +16,12 @@ char *mrsh_get_ps1(struct mrsh_state *state, int next_history_id);
  */
 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.
diff --git a/shell/entry.c b/shell/entry.c
index b302911..e3c0aa3 100644
--- a/shell/entry.c
+++ b/shell/entry.c
@@ -41,6 +41,14 @@ char *mrsh_get_ps2(struct mrsh_state *state) {
 	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], '=');
diff --git a/shell/task/command.c b/shell/task/command.c
index 46d3d08..2327db5 100644
--- a/shell/task/command.c
+++ b/shell/task/command.c
@@ -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 @@ static int task_command_poll(struct task *task, struct context *ctx) {
 		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) {
-- 
-- 
2.20.1
Details
Message ID
<obovd0gNrqCENwc8RNsj76e0g9TMhBOeSLnEOgo0gCVSjiR4tC3gpMtiyMk3l_hXFV0BjVjpHqC1193WbTbVVoOSYrutZ-cMdhgs2S8Yvk0=@emersion.fr>
In-Reply-To
<20190228154709.4732-1-sir@cmpwn.com> (view parent)
DKIM signature
permerror
Download raw message
To git.sr.ht:~emersion/mrsh
   6579356..722ddc1  master -> master

Thanks!