From 14ccb4d7a1525685c9e2b88ab166c2ad85e7c4fe Mon Sep 17 00:00:00 2001 From: deliciouslytyped <47436522+deliciouslytyped@users.noreply.github.com> Date: Mon, 2 Aug 2021 20:07:57 +0200 Subject: [PATCH] Add a new func_trace builtin In which I cannibalize func_error and func_strip into a new func_trace builtin used as `$(trace ...)`. This is used similar to tracing function in functional programming languages: they both print (like `$(info ...)`) and return their argument. A test run during development looked like: ``` $ nix-shell -I nixpkgs=channel:nixos-unstable -p gdb '((enableDebugging remake).overrideAttrs (o: { patches = [ ./trace.patch ]; NIX_CFLAGS_COMPILE="-O0"; }))' git \ --run 'env -i SHELL=bash TERM=screen $(which gdb) $(which remake) -q -ex "b func_call" -ex "directory /remake/src" -ex "dis" -ex "r -X < <(echo -e \"expand \\\$(trace somestring)\\nq\")" -ex "q"' /nix/store/wvr3sj436yjla36i0fgrwpi6cpbx5rax-gdb-10.2/bin/gdb: warning: Couldn't determine a path for the index cache directory. Reading symbols from /nix/store/a68rnl52gqg2kfsk0bi9jxz1pbjfqr1s-remake-4.3+dbg-1.5/bin/remake... Breakpoint 1 at 0x418c24: file src/function.c, line 2428. Source directories searched: /remake/src:$cdir:$cwd Starting program: /nix/store/a68rnl52gqg2kfsk0bi9jxz1pbjfqr1s-remake-4.3+dbg-1.5/bin/remake -X < <(echo -e "expand \$(trace somestring)\nq") Reading makefiles... hello Updating makefiles... Updating goal targets... File 'all' does not exist. Must remake target 'all'. Successfully remade target file 'all'. <- (/tmp/tmp.h4PduA6Uid/Makefile:12) all remake<0> expand $(trace somestring) somestring somestring remake<1> q remake: That's all, folks... [Inferior 1 (process 30082) exited with code 0115] ``` --- src/function.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/function.c b/src/function.c index 6a578ada4..f5fb2476f 100644 --- a/src/function.c +++ b/src/function.c @@ -1088,6 +1088,43 @@ func_error (char *o, char **argv, const char *funcname) return o; } +/* + Print its argument and return it. +*/ +static char * +func_trace (char *o, char **argv, const char *funcname) +{ + char **argvp; + char *msg, *p; + size_t len; + + /* The arguments will be broken on commas. Rather than create yet + another special case where function arguments aren't broken up, + just create a format string that puts them back together. */ + for (len=0, argvp=argv; *argvp != 0; ++argvp) + len += strlen (*argvp) + 2; + + p = msg = alloca (len + 1); + msg[0] = '\0'; + + for (argvp=argv; argvp[1] != 0; ++argvp) + { + strcpy (p, *argvp); + p += strlen (*argvp); + *(p++) = ','; + *(p++) = ' '; + } + strcpy (p, *argvp); + + outputs (0, msg); + outputs (0, "\n"); + + o = variable_buffer_output (o, msg, len); // Not sure if len is correct + + /* The warning function expands to the empty string. */ + return o; +} + /* chop argv[0] into words, and sort them. @@ -2203,6 +2240,7 @@ static struct function_table_entry function_table_init[] = FT_ENTRY ("info", 0, 1, 1, func_error), FT_ENTRY ("error", 0, 1, 1, func_error), FT_ENTRY ("warning", 0, 1, 1, func_error), + FT_ENTRY ("trace", 0, 1, 1, func_trace), FT_ENTRY ("if", 2, 3, 0, func_if), FT_ENTRY ("or", 1, 0, 0, func_or), FT_ENTRY ("and", 1, 0, 0, func_and),