From 4520d610e0616ddfcea6fdc4a0d306d1a5eb48eb Mon Sep 17 00:00:00 2001 From: ff <_ff@tuta.io> Date: Sun, 17 Dec 2017 13:50:39 +0100 Subject: [PATCH] Make build.sh work evan with no arguments When called without arguments, build.sh should have invoked clang with some arguments, but failed because word splitting was turned off, so it tried to invoke them all as a single command. Fix it by setting IFS=' ' before invoking clang. --- Devember/log17.txt | 40 ++++++++++++++++++++++++++++++++++++++++ build.sh | 9 ++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 Devember/log17.txt diff --git a/Devember/log17.txt b/Devember/log17.txt new file mode 100644 index 0000000..8c2568b --- /dev/null +++ b/Devember/log17.txt @@ -0,0 +1,40 @@ +I am finding designing minish-eval properly to be hard. + +The command substitution feature makes the task inherently recursive, +so I could decide to use a recursive function. +This function returns a file descriptor. +The function iterates the strings in argv, building an array. +When it finds an open parenthesis, it calls itself recursively, +thus beginning to build a new array. +Using getdelim() with ␀, +it reads from the return value and adds the strings to the array. +After there is no more to read, it continues iterating on argv. +When it finds a close parenthesis, it open a pipe and fork()s: +the child dup2()s its output to the writing end of the pipe, +adds NULL to the array, and calls execv(); +the parent deletes the array and its contents +and returns the reading end of the pipe. +It seems sensible to avoid a deep copy of the strings in argv, +and simply have the array element point to them, +but those cannot be free()d and the ones returned by getdelim() do. +We would need some way to keep track of what to free(). + +Another approach is to avoid a recursive function, +but have a child of minish-eval execv() into minish-eval itself. +minish-eval iterates the strings in argv, building an array. +When it finds an open parenthesis, +it searches for the matching close parenthesis, +open a pipe and fork()s: +the child dup2()s its output to the writing end of the pipe, +copies what is inside the parentheses into another array, +adds NULL to it, and calls execv(); +the parent reads from the pipe using getdelim() with ␀, +adding the strings to the array. +After there is no more to read, it continues iterating on argv. +The array that stores the command to be substituted +does not need to be deleted, because it is created by the child. + +Enough for today. + +Suggested reading: +https://en.wikipedia.org/wiki/Copy-on-write diff --git a/build.sh b/build.sh index 72ebf3d..7136953 100755 --- a/build.sh +++ b/build.sh @@ -4,21 +4,24 @@ readonly CLANG="clang -DNDEBUG -ferror-limit=1 -flto \ -fvisibility=hidden -march=native -O3 -s -static -std=c11 -Werror \ -Weverything -Wno-disabled-macro-expansion -Wno-reserved-id-macro" -readonly SED_SCRIPT='s_[ \t]*#include[ \t]*"\(.*\)".*_src/\1_' +readonly NEWLINE=' +' + +readonly SED_SCRIPT='s_[ \t]*#include[ \t]*"\(.*\)".*_src/\1_p' is_not_newer_than() { [ ! -f "$1" ] || [ -z "$(find "$1" -newer "$2")" ] } mkdir -p bin/ -IFS=' -' for SOURCE in src/*.c; do OBJECT="${SOURCE%.c}" OBJECT="bin${OBJECT#src}" + IFS="$NEWLINE" for DEP in "$SOURCE" $(sed -n "$SED_SCRIPT" "$SOURCE"); do if is_not_newer_than "$OBJECT" "$DEP"; then if [ $# -eq 0 ]; then + IFS=' ' $CLANG -o "$OBJECT" "$SOURCE" & else "$@" -o "$OBJECT" "$SOURCE" & -- 2.11.4.GIT