{ "strip-prefix": { "doc": [ "Returns list of artifact maps (each map contains a single artifact)" , "with the given prefix being stripped from their path." ] , "vars": ["artifacts", "paths", "prefix"] , "vars_doc": { "artifacts": ["A single map containing all artifacts."] , "paths": ["List of (unprefixed) artifacts paths to consider."] , "prefix": ["Prefix to strip from the artifact's path."] } , "expression": { "type": "foreach" , "var": "path" , "range": {"type": "var", "name": "paths"} , "body": { "type": "singleton_map" , "key": {"type": "var", "name": "path"} , "value": { "type": "lookup" , "key": { "type": "join" , "separator": "/" , "$1": [ {"type": "var", "name": "prefix"} , {"type": "var", "name": "path"} ] } , "map": {"type": "var", "name": "artifacts"} } } } } , "expand_exec_tool": { "doc": [ "Binary that expands specified env variables in argv and runs exec(2)." , "The syntax for accessing variable \"VAR\" is \"$(VAR)\"." , "Usage: expand_exec [VARS...] -- ARGV" , "" , "Requires a working C compiler for host from \"defaults\"." ] , "vars": ["CC", "ENV", "defaults-transition"] , "imports": { "compiler-cc": ["CC", "compiler-cc"] , "default-ENV": ["CC", "default-ENV"] , "default-PATH": ["CC", "default-PATH"] , "default-TOOLCHAIN": ["CC", "default-TOOLCHAIN"] , "default-NON_SYSTEM_TOOLS": ["CC", "default-NON_SYSTEM_TOOLS"] } , "expression": { "type": "let*" , "bindings": [ ["TOOLCHAIN_DIR", "toolchain"] , ["TOOLCHAIN", {"type": "CALL_EXPRESSION", "name": "default-TOOLCHAIN"}] , [ "TOOLCHAIN" , { "type": "to_subdir" , "subdir": {"type": "var", "name": "TOOLCHAIN_DIR"} , "$1": {"type": "var", "name": "TOOLCHAIN"} } ] , [ "NON_SYSTEM_TOOLS" , {"type": "CALL_EXPRESSION", "name": "default-NON_SYSTEM_TOOLS"} ] , ["CC", {"type": "CALL_EXPRESSION", "name": "compiler-cc"}] , [ "ENV" , { "type": "map_union" , "$1": [ {"type": "CALL_EXPRESSION", "name": "default-ENV"} , {"type": "var", "name": "ENV", "default": {"type": "empty_map"}} ] } ] , [ "ENV_PATH" , { "type": "lookup" , "map": {"type": "var", "name": "ENV"} , "key": "PATH" } ] , [ "ENV" , { "type": "map_union" , "$1": [ {"type": "var", "name": "ENV"} , { "type": "singleton_map" , "key": "PATH" , "value": { "type": "join" , "separator": ":" , "$1": { "type": "++" , "$1": [ {"type": "CALL_EXPRESSION", "name": "default-PATH"} , { "type": "if" , "cond": {"type": "var", "name": "ENV_PATH"} , "then": [{"type": "var", "name": "ENV_PATH"}] } ] } } } ] } ] , [ "expand_exec.c" , { "type": "singleton_map" , "key": "expand_exec.c" , "value": { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": [ "#include " , "#include " , "#include " , "" , "/* usage: ./expand_exec [VARS...] -- ARGS... */" , "int main(int argc, const char *argv[]) {" , " char** outv;" , " const char** varv;" , " int i, j, varc, sep = 0, retval = 0;" , " for (i = 1; i < argc; ++i) if (strcmp(argv[i], \"--\") == 0) { sep=i; break; }" , " varc = sep-1;" , " argc -= sep+1;" , " if (sep == 0 || argc < 1) return 1; /* error: missing sep or args */" , " varv = &argv[1];" , " argv = &argv[sep+1];" , " outv = (char**)calloc((size_t)(argc+1), sizeof(char*));" , " for (i = 0; i < argc; ++i) { /* iterate ARGS */" , " const char* arg = argv[i];" , " size_t arg_pos = 0, arg_len = strlen(arg);" , " size_t out_pos = 0, out_len = arg_len;" , " size_t str_pos = 0, str_len = 0;" , " char* out = (char*)calloc((size_t)(out_len+1), sizeof(char));" , " for (; arg_pos < arg_len; ++arg_pos) {" , " if (strncmp(&arg[arg_pos], \"$(\", 2) == 0) {" , " const char* start = &arg[arg_pos+2];" , " const char* end = strchr(start, ')');" , " if (end == NULL) {" , " retval = 2; /* error: unterminated $(VAR) expression */" , " free(out);" , " goto cleanup;" , " }" , " for (j = 0; j < varc; ++j) { /* lookup VAR */" , " const char* var = varv[j];" , " size_t len_var = strlen(var);" , " if ((size_t)(end - start) != len_var) continue;" , " if (strncmp(&arg[arg_pos+2], var, len_var) == 0) {" , " size_t val_len, out_len_new;" , " const char* val = getenv(var);" , " if (val == NULL) val = \"\";" , " val_len = strlen(val);" , " out_len_new = out_pos + str_len + val_len;" , " if (out_len_new > out_len) {" , " out = (char*)realloc(out, out_len_new+1);" , " out_len = out_len_new;" , " }" , " strncat(out, &arg[str_pos], str_len); /* concat preceding substr */" , " strncat(out, val, val_len); /* concat variable value */" , " arg_pos += len_var + 2;" , " out_pos += str_len + val_len;" , " str_pos = arg_pos + 1;" , " str_len = 0;" , " break;" , " }" , " }" , " if (j != varc) continue; /* success */" , " }" , " ++str_len;" , " }" , " if (str_len > 0) {" , " if (out_pos + str_len > out_len) {" , " out = (char*)realloc(out, out_pos + str_len + 1);" , " }" , " strncat(out, &arg[str_pos], str_len);" , " }" , " outv[i] = out;" , " }" , " execvp(outv[0], outv);" , " retval = 3; /* error: exec failed */" , "cleanup:" , " for (i = 0; i < argc; ++i) if (outv[i] != NULL) free(outv[i]);" , " free(outv);" , " return retval;" , "}" ] } } } ] ] , "body": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "var", "name": "expand_exec.c"} ] } , "cmd": [{"type": "var", "name": "CC"}, "expand_exec.c", "-o", "expand_exec"] , "outs": ["expand_exec"] , "env": {"type": "var", "name": "ENV"} } } } }