From 287fce6402100c40317233de6b4f749f2b79b0a5 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 23 Aug 2017 16:23:30 -0400 Subject: expand-response-params: Pull out of cc-wrapper No hashes were changed --- pkgs/build-support/cc-wrapper/default.nix | 16 ++--- .../cc-wrapper/expand-response-params.c | 84 ---------------------- .../expand-response-params/default.nix | 13 ++++ .../expand-response-params.c | 84 ++++++++++++++++++++++ 4 files changed, 101 insertions(+), 96 deletions(-) delete mode 100644 pkgs/build-support/cc-wrapper/expand-response-params.c create mode 100644 pkgs/build-support/expand-response-params/default.nix create mode 100644 pkgs/build-support/expand-response-params/expand-response-params.c (limited to 'pkgs/build-support') diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 525cb07ac32..d5ae64c9c5f 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -74,18 +74,10 @@ let else if stdenv.lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" else null; - expand-response-params = if buildPackages.stdenv.cc or null != null && buildPackages.stdenv.cc != "/dev/null" - then buildPackages.stdenv.mkDerivation { - name = "expand-response-params"; - src = ./expand-response-params.c; - buildCommand = '' - # Work around "stdenv-darwin-boot-2 is not allowed to refer to path /nix/store/...-expand-response-params.c" - cp "$src" expand-response-params.c - "$CC" -std=c99 -O3 -o "$out" expand-response-params.c - strip -S $out - ${optionalString hostPlatform.isLinux "patchelf --shrink-rpath $out"} - ''; - } else ""; + expand-response-params = + if buildPackages.stdenv.cc or null != null && buildPackages.stdenv.cc != "/dev/null" + then import ../expand-response-params { inherit (buildPackages) stdenv; } + else ""; in diff --git a/pkgs/build-support/cc-wrapper/expand-response-params.c b/pkgs/build-support/cc-wrapper/expand-response-params.c deleted file mode 100644 index 05b9c62b1e8..00000000000 --- a/pkgs/build-support/cc-wrapper/expand-response-params.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { char *data; size_t len, cap; } String; - -void resize(String *s, size_t len) { - s->len = len; - if (s->cap < s->len) { - s->cap = s->len * 2; - s->data = (char *)realloc(s->data, s->cap); - assert(s->data); - } -} - -void append(String *s, const char *data, size_t len) { - resize(s, s->len + len); - memcpy(s->data + s->len - len, data, len); -} - -typedef enum { space = 0, other = 1, backslash = 2, apostrophe = 3, quotation_mark = 4 } CharClass; -typedef enum { outside, unq, unq_esc, sq, sq_esc, dq, dq_esc } State; - -// current State -> CharClass -> next State -const State transitions[][5] = { - [outside] = {outside, unq, unq_esc, sq, dq}, - [unq] = {outside, unq, unq_esc, sq, dq}, - [unq_esc] = {unq, unq, unq, unq, unq}, - [sq] = {sq, sq, sq_esc, unq, sq}, - [sq_esc] = {sq, sq, sq, sq, sq}, - [dq] = {dq, dq, dq_esc, dq, unq}, - [dq_esc] = {dq, dq, dq, dq, dq}, -}; - -CharClass charClass(int c) { - return c == '\\' ? backslash : c == '\'' ? apostrophe : c == '"' ? quotation_mark : - isspace(c) ? space : other; -} - -// expandArg writes NULL-terminated expansions of `arg', a NULL-terminated -// string, to stdout. If arg does not begin with `@' or does not refer to a -// file, it is written as is. Otherwise the contents of the file are -// recursively expanded. On unexpected EOF in malformed response files an -// incomplete final argument is written, even if it is empty, to parse like GCC. -void expandArg(String *arg) { - FILE *f; - if (arg->data[0] != '@' || !(f = fopen(&arg->data[1], "r"))) { - fwrite(arg->data, 1, arg->len, stdout); - return; - } - - resize(arg, 0); - State cur = outside; - int c; - do { - c = fgetc(f); - State next = transitions[cur][charClass(c)]; - if ((cur == unq && next == outside) || (cur != outside && c == EOF)) { - append(arg, "", 1); - expandArg(arg); - resize(arg, 0); - } else if (cur == unq_esc || cur == sq_esc || cur == dq_esc || - (cur == outside ? next == unq : cur == next)) { - char s = c; - append(arg, &s, 1); - } - cur = next; - } while (c != EOF); - - fclose(f); -} - -int main(int argc, char **argv) { - String arg = { 0 }; - while (*++argv) { - resize(&arg, 0); - append(&arg, *argv, strlen(*argv) + 1); - expandArg(&arg); - } - free(arg.data); - return EXIT_SUCCESS; -} diff --git a/pkgs/build-support/expand-response-params/default.nix b/pkgs/build-support/expand-response-params/default.nix new file mode 100644 index 00000000000..7afbb727fc3 --- /dev/null +++ b/pkgs/build-support/expand-response-params/default.nix @@ -0,0 +1,13 @@ +{ stdenv }: + +stdenv.mkDerivation { + name = "expand-response-params"; + src = ./expand-response-params.c; + buildCommand = '' + # Work around "stdenv-darwin-boot-2 is not allowed to refer to path /nix/store/...-expand-response-params.c" + cp "$src" expand-response-params.c + "$CC" -std=c99 -O3 -o "$out" expand-response-params.c + strip -S $out + ${stdenv.lib.optionalString stdenv.hostPlatform.isLinux "patchelf --shrink-rpath $out"} + ''; +} diff --git a/pkgs/build-support/expand-response-params/expand-response-params.c b/pkgs/build-support/expand-response-params/expand-response-params.c new file mode 100644 index 00000000000..05b9c62b1e8 --- /dev/null +++ b/pkgs/build-support/expand-response-params/expand-response-params.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include + +typedef struct { char *data; size_t len, cap; } String; + +void resize(String *s, size_t len) { + s->len = len; + if (s->cap < s->len) { + s->cap = s->len * 2; + s->data = (char *)realloc(s->data, s->cap); + assert(s->data); + } +} + +void append(String *s, const char *data, size_t len) { + resize(s, s->len + len); + memcpy(s->data + s->len - len, data, len); +} + +typedef enum { space = 0, other = 1, backslash = 2, apostrophe = 3, quotation_mark = 4 } CharClass; +typedef enum { outside, unq, unq_esc, sq, sq_esc, dq, dq_esc } State; + +// current State -> CharClass -> next State +const State transitions[][5] = { + [outside] = {outside, unq, unq_esc, sq, dq}, + [unq] = {outside, unq, unq_esc, sq, dq}, + [unq_esc] = {unq, unq, unq, unq, unq}, + [sq] = {sq, sq, sq_esc, unq, sq}, + [sq_esc] = {sq, sq, sq, sq, sq}, + [dq] = {dq, dq, dq_esc, dq, unq}, + [dq_esc] = {dq, dq, dq, dq, dq}, +}; + +CharClass charClass(int c) { + return c == '\\' ? backslash : c == '\'' ? apostrophe : c == '"' ? quotation_mark : + isspace(c) ? space : other; +} + +// expandArg writes NULL-terminated expansions of `arg', a NULL-terminated +// string, to stdout. If arg does not begin with `@' or does not refer to a +// file, it is written as is. Otherwise the contents of the file are +// recursively expanded. On unexpected EOF in malformed response files an +// incomplete final argument is written, even if it is empty, to parse like GCC. +void expandArg(String *arg) { + FILE *f; + if (arg->data[0] != '@' || !(f = fopen(&arg->data[1], "r"))) { + fwrite(arg->data, 1, arg->len, stdout); + return; + } + + resize(arg, 0); + State cur = outside; + int c; + do { + c = fgetc(f); + State next = transitions[cur][charClass(c)]; + if ((cur == unq && next == outside) || (cur != outside && c == EOF)) { + append(arg, "", 1); + expandArg(arg); + resize(arg, 0); + } else if (cur == unq_esc || cur == sq_esc || cur == dq_esc || + (cur == outside ? next == unq : cur == next)) { + char s = c; + append(arg, &s, 1); + } + cur = next; + } while (c != EOF); + + fclose(f); +} + +int main(int argc, char **argv) { + String arg = { 0 }; + while (*++argv) { + resize(&arg, 0); + append(&arg, *argv, strlen(*argv) + 1); + expandArg(&arg); + } + free(arg.data); + return EXIT_SUCCESS; +} -- cgit 1.4.1