Add 'exec'

This commit is contained in:
Christoffer Lerno
2023-09-30 23:15:33 +02:00
committed by Christoffer Lerno
parent b2c7b713f2
commit 2b9276b495
13 changed files with 243 additions and 220 deletions

View File

@@ -3,6 +3,8 @@
## 0.5.0 Change List
### Changes / improvements
- 'exec' directive to run scripts at compile time.
- Project key descriptions in --list command.
- Added `init-lib` to simplify library creation.
- Local `const` work like namespaced global `const`.
- Added `$$atomic_fetch_*` builtins.

View File

@@ -0,0 +1,3 @@
module pwd;
fn int getnum() => 3;

View File

@@ -355,6 +355,7 @@ typedef struct BuildOptions_
const char *llvm_out;
const char *asm_out;
const char *obj_out;
const char *script_dir;
RelocModel reloc_model;
X86VectorCapability x86_vector_capability;
X86CpuSet x86_cpu_set;
@@ -429,6 +430,7 @@ typedef struct
const char *object_file_dir;
const char *ir_file_dir;
const char *asm_file_dir;
const char *script_dir;
bool run_after_compile;
bool generate_benchmark_runner;
bool generate_test_runner;
@@ -470,6 +472,7 @@ typedef struct
const char *testfn;
const char *cc;
const char *cflags;
const char **exec;
const char **csource_dirs;
const char **csources;
const char **feature_list;

View File

@@ -25,6 +25,12 @@ static const char *wincrt_linking[3] = {
[WIN_CRT_STATIC] = "static",
};
static const char *trust_level[3] = {
[TRUST_NONE] = "none",
[TRUST_INCLUDE] = "include",
[TRUST_FULL] = "full",
};
static const char *optsizes[3] = {
[SIZE_OPTIMIZATION_NONE] = "none",
[SIZE_OPTIMIZATION_SMALL] = "small",

View File

@@ -96,13 +96,12 @@ static void usage(void)
OUTPUT(" -O5 - Unsafe, highest optimization, fast maths, single module, emit debug info.");
OUTPUT(" -Os - Unsafe, high optimization, small code, single module, no debug info.");
OUTPUT(" -Oz - Unsafe, high optimization, tiny code, single module, no debug info.");
OUTPUT(" -t1 - Trust level 1 - don't allow $include nor $exec (default).");
OUTPUT(" -t2 - Trust level 2 - allow $include but not $exec / exec directives.");
OUTPUT(" -t3 - Trust level 3 - full trust, allow both include and exec.");
OUTPUT(" -D <name> - Add feature flag <name>.");
OUTPUT(" -U <name> - Remove feature flag <name>.");
OUTPUT(" --trust=<option> - Trust level: none (default), include ($include allowed), full ($exec / exec allowed).");
OUTPUT(" --build-dir <dir> - Override build output directory.");
OUTPUT(" --obj-out <dir> - Override object file output directory.");
OUTPUT(" --script-dir <dir> - Override the base directory for $exec.");
OUTPUT(" --llvm-out <dir> - Override llvm output directory for '--emit-llvm'.");
OUTPUT(" --emit-llvm - Emit LLVM IR as a .ll file per module.");
OUTPUT(" --asm-out <dir> - Override asm output directory for '--emit-asm'.");
@@ -887,6 +886,11 @@ static void parse_option(BuildOptions *options)
options->win.sdk = check_dir(next_arg());
return;
}
if ((argopt = match_argopt("trust")))
{
options->trust_level = (TrustLevel) parse_multi_option(argopt, 3, trust_level);
return;
}
if ((argopt = match_argopt("wincrt")))
{
options->win.crt_linking = (WinCrtLinking)parse_multi_option(argopt, 3, wincrt_linking);
@@ -916,6 +920,12 @@ static void parse_option(BuildOptions *options)
options->obj_out = next_arg();
return;
}
if (match_longopt("script-dir"))
{
if (at_end() || next_is_opt()) error_exit("error: --script-dir needs a directory.");
options->script_dir = next_arg();
return;
}
if (match_longopt("llvm-out"))
{
if (at_end() || next_is_opt()) error_exit("error: --llvm-out needs a directory.");
@@ -1044,6 +1054,7 @@ BuildOptions parse_arguments(int argc, const char *argv[])
.single_module = SINGLE_MODULE_NOT_SET,
.files = NULL,
.build_dir = NULL,
.script_dir = NULL,
};
for (int i = DIAG_NONE; i < DIAG_WARNING_TYPE; i++)

View File

@@ -312,6 +312,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
target->object_file_dir = options->obj_out ? options->obj_out : target->build_dir;
target->ir_file_dir = options->llvm_out ? options->llvm_out : target->build_dir;
target->asm_file_dir = options->asm_out ? options->asm_out : target->build_dir;
target->script_dir = options->script_dir ? options->script_dir : target->script_dir;
}
else
{
@@ -319,6 +320,8 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
target->object_file_dir = options->obj_out ? options->obj_out : file_append_path(target->build_dir, "tmp");
target->ir_file_dir = options->llvm_out ? options->llvm_out : file_append_path(target->build_dir, "llvm_ir");
target->asm_file_dir = options->asm_out ? options->asm_out : file_append_path(target->build_dir, "asm");
target->script_dir = options->script_dir ? options->script_dir : target->script_dir;
if (!target->script_dir) target->script_dir = "scripts";
}
switch (options->compile_option)
{

View File

@@ -6,211 +6,116 @@
#include "build_internal.h"
#define MAX_SYMTAB_SIZE (1024 * 1024)
const char *project_default_keys[] = {
"authors",
"benchfn",
"c-sources",
"cc",
"cflags",
"cpu",
"debug-info",
"dependencies",
"dependency-search-paths",
"features",
"fp-math",
"langrev",
"linked-libraries",
"linker-search-paths",
"link-args",
"link-libc",
"macossdk",
"memory-env",
"no-entry",
"opt",
"optlevel",
"optsize",
"output",
"panicfn",
"reloc",
"safe",
"single-module",
"soft-float",
"sources",
"strip-unused",
"symtab",
"system-linker",
"target",
"targets",
"testfn",
"trap-on-wrap",
"use-stdlib",
"version",
"warnings",
"wincrt",
"winsdk",
"x86cpu",
"x86vec",
"x86-stack-struct-return",
const char *project_default_keys[][2] = {
{"authors", "Authors, optionally with email."},
{"benchfn", "Override the benchmark function."},
{"c-sources", "Set the C sources to be compiled."},
{"cc", "Set C compiler (defaults to 'cc')."},
{"cflags", "C compiler flags."},
{"cpu", "CPU name, used for optimizations in the compiler backend."},
{"debug-info", "Debug level: none, line-tables, full."},
{"dependencies", "C3 library dependencies for all targets."},
{"dependency-search-paths", "The C3 library search paths."},
{"exec", "Scripts run for all targets.."},
{"features", "Features enabled for all targets."},
{"fp-math", "Set math behaviour: `strict`, `relaxed` or `fast`."},
{"langrev", "Version of the C3 language used."},
{"linked-libraries", "Libraries linked by the linker for all targets."},
{"linker-search-paths", "Linker search paths."},
{"link-args", "Linker arguments for all targets."},
{"link-libc", "Link libc (default: true)."},
{"macossdk", "Set the directory for the MacOS SDK for cross compilation."},
{"memory-env", "Set the memory environment: normal, small, tiny, none."},
{"no-entry", "Do not generate (or require) a main function."},
{"opt", "Link libc (default: true)."},
{"optlevel", "Code optimization level: none, less, more, max."},
{"optsize", "Code size optimization: none, small, tiny."},
{"output", "Output location, relative to project file."},
{"panicfn", "Override the panic function."},
{"reloc", "Relocation model: none, pic, PIC, pie, PIE."},
{"safe", "Set safety (contracts, runtime bounds checking, null pointer checks etc) on or off."},
{"script-dir", "The directory where 'exec' is run."},
{"single-module", "Compile all modules together, enables more inlining."},
{"soft-float", "Output soft-float functions."},
{"sources", "Paths to project sources for all targets."},
{"strip-unused", "Strip unused code and globals from the output. (default: true)"},
{"symtab", "Sets the preferred symtab size."},
{"system-linker", "Use the system linker (default: no for cross compilation, yes otherwise)."},
{"target", "Compile for a particular architecture + OS target."},
{"targets", "Set of targets for the project."},
{"testfn", "Override the test function."},
{"trap-on-wrap", "Make signed and unsigned integer overflow generate a panic rather than wrapping."},
{"use-stdlib", "Include the standard library (default: true)."},
{"version", "Version using semantic versioning."},
{"warnings", "Warnings used for all targets."},
{"wincrt", "Windows CRT linking: none, static, dynamic (default)."},
{"winsdk", "Set the path to Windows system library files for cross compilation."},
{"x86cpu", "Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native."},
{"x86vec", "Set max type of vector use: none, mmx, sse, avx, avx512, native."},
{"x86-stack-struct-return", "Return structs on the stack for x86."},
};
const int project_default_keys_count = ELEMENTLEN(project_default_keys);
const char *project_default_descriptions[] = {
"Authors, optionally with email.",
"Override the benchmark function name.",
"Override C sources to be compiled.",
"Specify the C compiler.",
"Add flags for the C compiler.",
"CPU name, used for optimizations in the compiler backend.",
"Add debug info.",
"Add dependencies for all targets.",
"Override dependencies for all targets.",
"features",
"fp-math",
"Language version of C3.",
"The external libraries to link for all targets.",
"The path used to search for external libraries.",
"Extra arguments to the linker for all targets.",
"Link libc other default libraries (default: yes).",
"Set the directory for the MacOS SDK for cross compilation.",
"Set the memory environment: normal, small, tiny, none.",
"Do not generate (or require) a main function.",
"opt",
"Code optimization level: none, less, more, max.",
"Code size optimization: none, small, tiny.",
"Output location, relative to project file.",
"Override the panic function name.",
"Relocation model: none, pic, PIC, pie, PIE.",
"Turn safety (contracts, runtime bounds checking, null pointer checks etc) on or off.",
"Compile all modules together, enables more inlining.",
"soft-float",
"Sources compiled for all targets.",
"Strip unused code and globals from the output. (default: yes)",
"Sets the preferred symtab size.",
"Use the system linker (default: no for cross compilation, yes otherwise).",
"Compile for a particular architecture + OS target.",
"Set of targets for the project.",
"Override the test function name.",
"trap-on-wrap",
"Use this directory as the C3 standard library path.",
"Version using semantic versioning.",
"Warnings used for all targets.",
"Windows CRT linking: none, static, dynamic (default).",
"Set the directory for Windows system library files for cross compilation.",
"Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native.",
"Set max type of vector use: none, mmx, sse, avx, avx512, native.",
"x86-stack-struct-return",
};
const char* project_target_keys[] = {
"benchfn",
"c-sources-add",
"c-sources-override",
"cc",
"cflags-add",
"cflags-override",
"cpu",
"debug-info",
"dependencies-add",
"dependencies-override",
"dependency-search-paths-add",
"dependency-search-paths-override",
"features",
"fp-math",
"langrev",
"linked-libraries-add",
"linked-libraries-override",
"linker-search-paths-add",
"linker-search-paths-override",
"link-args-add",
"link-args-override",
"link-libc",
"macossdk",
"memory-env",
"no-entry",
"opt",
"optlevel",
"optsize",
"output"
"panicfn",
"reloc",
"safe",
"single-module",
"soft-float",
"sources-add",
"sources-override",
"strip-unused",
"symtab",
"system-linker",
"target",
"testfn",
"trap-on-wrap",
"type",
"use-stdlib",
"version",
"warnings",
"wincrt",
"winsdk",
"x86cpu",
"x86vec",
"x86-stack-struct-return",
const char* project_target_keys[][2] = {
{"benchfn", "Override the benchmark function."},
{"c-sources-add", "Additional C sources to be compiled for the target."},
{"c-sources-override", "C sources to be compiled, overriding global settings."},
{"cc", "Set C compiler (defaults to 'cc')."},
{"cflags-add", "Additional C compiler flags for the target."},
{"cflags-override", "C compiler flags for the target, overriding global settings."},
{"cpu", "CPU name, used for optimizations in the compiler backend."},
{"debug-info", "Debug level: none, line-tables, full."},
{"dependencies-add", "Additional C3 library dependencies for the target."},
{"dependencies-override", "C3 library dependencies for this target, overriding global settings."},
{"dependency-search-paths-add", "Additional C3 library search paths for the target."},
{"dependency-search-paths-override", "C3 library search paths for this target, overriding global settings."},
{"exec-add", "Additional scripts to run for the target."},
{"exec-override", "Scripts to run for this target, overriding global settings."},
{"features", "Features enabled for all targets."},
{"fp-math", "Set math behaviour: `strict`, `relaxed` or `fast`."},
{"langrev", "Version of the C3 language used."},
{"linked-libraries-add", "Additional libraries linked by the linker for the target."},
{"linked-libraries-override", "Libraries linked by the linker for this target, overriding global settings."},
{"linker-search-paths-add", "Additional linker search paths for the target."},
{"linker-search-paths-override", "Linker search paths for this target, overriding global settings."},
{"link-args-add", "Additional linker arguments for the target."},
{"link-args-override", "Linker arguments for this target, overriding global settings."},
{"link-libc", "Link libc (default: true)."},
{"macossdk", "Set the directory for the MacOS SDK for cross compilation."},
{"memory-env", "Set the memory environment: normal, small, tiny, none."},
{"no-entry", "Do not generate (or require) a main function."},
{"opt", "Link libc (default: true)."},
{"optlevel", "Code optimization level: none, less, more, max."},
{"optsize", "Code size optimization: none, small, tiny."},
{"output", "Output location, relative to project file."},
{"panicfn", "Override the panic function."},
{"reloc", "Relocation model: none, pic, PIC, pie, PIE."},
{"safe", "Set safety (contracts, runtime bounds checking, null pointer checks etc) on or off."},
{"script-dir", "The directory where 'exec' is run."},
{"single-module", "Compile all modules together, enables more inlining."},
{"soft-float", "Output soft-float functions."},
{"sources-add", "Additional paths to project sources for the target."},
{"sources-override", "Paths to project sources for this target, overriding global settings."},
{"strip-unused", "Strip unused code and globals from the output. (default: true)"},
{"symtab", "Sets the preferred symtab size."},
{"system-linker", "Use the system linker (default: no for cross compilation, yes otherwise)."},
{"target", "Compile for a particular architecture + OS target."},
{"testfn", "Override the test function."},
{"trap-on-wrap", "Make signed and unsigned integer overflow generate a panic rather than wrapping."},
{"type", "Type of output, one of 'executable', 'static-lib', 'dynamic-lib', 'benchmark', 'test', 'object-files'." },
{"use-stdlib", "Include the standard library (default: true)."},
{"version", "Version using semantic versioning."},
{"warnings", "Warnings used for all targets."},
{"wincrt", "Windows CRT linking: none, static, dynamic (default)."},
{"winsdk", "Set the path to Windows system library files for cross compilation."},
{"x86cpu", "Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native."},
{"x86vec", "Set max type of vector use: none, mmx, sse, avx, avx512, native."},
{"x86-stack-struct-return", "Return structs on the stack for x86."},
};
const int project_target_keys_count = ELEMENTLEN(project_target_keys);
const char* project_target_descriptions[] = {
"Override the benchmark function name.",
"Add C sources to be compiled.",
"Override C sources to be compiled.",
"Specify the C compiler.",
"Add flags for the C compiler.",
"Override flags for the C compiler.",
"CPU name, used for optimizations in the compiler backend.",
"Add debug info.",
"Add dependencies for this target.",
"Override dependencies for this target.",
"Add directories where C3 library files may be found",
"Override directories where C3 library files may be found",
"features",
"FP math behaviour: strict, relaxed, fast.",
"Language version of C3.",
"Additional libraries to be linked.",
"Override libraries to be linked.",
"Add search paths for the linker.",
"Override search paths for the linker.",
"Add arguments for the linker.",
"Override arguments for the linker.",
"Link libc other default libraries (default: yes).",
"Set the directory for the MacOS SDK for cross compilation.",
"Set the memory environment: normal, small, tiny, none.",
"Do not generate (or require) a main function.",
"opt",
"Code optimization level: none, less, more, max.",
"Code size optimization: none, small, tiny.",
"Override the panic function name.",
"Relocation model: none, pic, PIC, pie, PIE.",
"Turn safety (contracts, runtime bounds checking, null pointer checks etc) on or off.",
"Compile all modules together, enables more inlining.",
"soft-float",
"Add sources for the target.",
"Override sources for the target.",
"Strip unused code and globals from the output. (default: yes)",
"Sets the preferred symtab size.",
"Use the system linker (default: no for cross compilation, yes otherwise).",
"Compile for a particular architecture + OS target.",
"Override the test function name.",
"trap-on-wrap",
"Executable or library.",
"Use this directory as the C3 standard library path.",
"Version using semantic versioning.",
"Warnings used for this target.",
"Windows CRT linking: none, static, dynamic (default).",
"Set the directory for Windows system library files for cross compilation.",
"Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native.",
"Set max type of vector use: none, mmx, sse, avx, avx512, native.",
"x86-stack-struct-return",
};
const char *get_valid_string(JSONObject *table, const char *key, const char *category, bool mandatory)
{
JSONObject *value = json_obj_get(table, key);
@@ -303,7 +208,7 @@ static const char **get_valid_array(JSONObject *table, const char *key, const ch
return values;
}
static void check_json_keys(const char** valid_keys, size_t key_count, JSONObject *json, const char *type)
static void check_json_keys(const char* valid_keys[][2], size_t key_count, JSONObject *json, const char *type)
{
static bool failed_shown = false;
bool failed = false;
@@ -312,7 +217,7 @@ static void check_json_keys(const char** valid_keys, size_t key_count, JSONObjec
const char *key = json->keys[i];
for (size_t j = 0; j < key_count; j++)
{
if (strcmp(key, valid_keys[j]) == 0) goto OK;
if (strcmp(key, valid_keys[j][0]) == 0) goto OK;
}
eprintf("WARNING: Unknown parameter '%s' in '%s'.\n", key, type);
failed = true;
@@ -360,6 +265,30 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
const char *cc = get_valid_string(json, "cc", type, false);
if (cc) target->cc = cc;
const char *script_dir = get_valid_string(json, "script-dir", type, false);
if (script_dir) target->script_dir = script_dir;
// Exec
const char **exec = get_valid_array(json, is_default ? "exec" : "exec-override" , type, false);
const char **exec_add = is_default ? NULL : get_valid_array(json, "exec-add" , type, false);
if (exec && exec_add)
{
error_exit("'%s' is combining both 'exec-add' and 'exec-override', only one may be used.", type);
}
if (exec_add && !target->exec)
{
target->exec = exec_add;
exec_add = NULL;
}
if (exec) target->exec = exec;
if (exec_add)
{
assert(target->exec);
FOREACH_BEGIN(const char *exec_command, exec_add)
vec_add(target->exec, exec_command);
FOREACH_END();
}
// CFlags
const char *cflags = get_valid_string(json, is_default ? "cflags" : "cflags-override" , type, false);
const char *cflags_add = is_default ? NULL : get_valid_string(json, "cflags-add" , type, false);

View File

@@ -202,7 +202,7 @@ void create_library(BuildOptions *build_options)
chdir_or_fail(build_options, build_options->project_name);
create_file_or_fail(build_options, "LICENSE", NULL);
create_file_or_fail(build_options, "README.md", LIB_README, build_options->project_name);
mkdir_or_fail(build_options, "run");
mkdir_or_fail(build_options, "scripts");
scratch_buffer_clear();
scratch_buffer_printf("%s.c3i", build_options->project_name);
const char *interface_file = scratch_buffer_copy();
@@ -260,7 +260,7 @@ void create_project(BuildOptions *build_options)
mkdir_or_fail(build_options, "docs");
mkdir_or_fail(build_options, "lib");
mkdir_or_fail(build_options, "resources");
mkdir_or_fail(build_options, "run");
mkdir_or_fail(build_options, "scripts");
mkdir_or_fail(build_options, "src");
chdir_or_fail(build_options, "src");

View File

@@ -736,18 +736,16 @@ void print_syntax(BuildOptions *options)
int width;
puts("Project properties");
puts("------------------");
width = find_padding_length(project_default_keys, project_default_keys_count);
for (int i = 0; i < project_default_keys_count; i++)
{
printf("%2d %-*s%s\n", i + 1, width, project_default_keys[i], project_default_descriptions[i]);
printf("%2d %-*s%s\n", i + 1, 35, project_default_keys[i][0], project_default_keys[i][1]);
}
puts("");
puts("Target properties");
puts("-----------------");
width = find_padding_length(project_target_keys, project_target_keys_count);
for (int i = 0; i < project_target_keys_count; i++)
{
printf("%2d %-*s%s\n", i + 1, width, project_target_keys[i], project_target_descriptions[i]);
printf("%2d %-*s%s\n", i + 1, 35, project_target_keys[i][0], project_target_keys[i][1]);
}
puts("");
}
@@ -827,6 +825,39 @@ static int jump_buffer_size()
UNREACHABLE
}
static void execute_scripts(void)
{
if (!vec_size(active_target.exec)) return;
if (active_target.trust_level < TRUST_FULL)
{
error_exit("This target has 'exec' directives, to run it trust level must be set to '--trust=full'.");
}
char *old_path = NULL;
if (active_target.script_dir)
{
old_path = getcwd(NULL, 0);
if (!dir_change(active_target.script_dir))
{
free(old_path);
error_exit("Failed to open script dir '%s'", active_target.script_dir);
}
}
FOREACH_BEGIN(const char *exec, active_target.exec)
StringSlice execs = slice_from_string(exec);
StringSlice call = slice_next_token(&execs, ' ');
if (call.len < 3 || call.ptr[call.len - 3] != '.' || call.ptr[call.len - 2] != 'c' || call.ptr[call.len - 2] != '3')
{
(void)execute_cmd(exec);
continue;
}
scratch_buffer_clear();
scratch_buffer_append_len(call.ptr, call.len);
(void)compile_and_invoke(scratch_buffer_to_string(), execs.len ? execs.ptr : "");
FOREACH_END();
dir_change(old_path);
free(old_path);
}
void compile()
{
symtab_init(active_target.symtab_size);
@@ -836,6 +867,7 @@ void compile()
static const char* c_suffix_list[3] = { ".c" };
active_target.csources = target_expand_source_names(active_target.csource_dirs, c_suffix_list, 1, false);
}
execute_scripts();
global_context.main = NULL;
global_context.string_type = NULL;
asm_target.initialized = false;
@@ -876,6 +908,11 @@ void compile()
compiler_init_time = bench_mark();
if (!vec_size(active_target.sources) && !active_target.read_stdin) error_exit("No files to compile.");
if (active_target.exec)
{
}
if (active_target.lex_only)
{
compiler_lex();
@@ -1004,15 +1041,24 @@ File *compile_and_invoke(const char *file, const char *args)
scratch_buffer_clear();
scratch_buffer_append(compiler_path);
#if (_MSC_VER)
const char *output = "__c3_exec.exe";
const char *output = "__c3exec__.exe";
#else
const char *output = "__c3_exec";
const char *output = "__c3exec__";
#endif
scratch_buffer_printf(" compile %s -o %s", file, output);
scratch_buffer_append(" compile");
StringSlice slice = slice_from_string(file);
while (slice.len > 0)
{
StringSlice file_name = slice_next_token(&slice, ';');
if (!file_name.len) continue;
scratch_buffer_append_char(' ');
scratch_buffer_append_len(file_name.ptr, file_name.len);
}
scratch_buffer_printf(" -o %s", output);
const char *out;
if (!execute_cmd_failable(scratch_buffer_to_string(), &out))
{
error_exit("Failed to compile script %s.", file);
error_exit("Failed to compile script '%s'.", file);
}
DEBUG_LOG("EXEC OUT: %s", out);
scratch_buffer_clear();
@@ -1024,7 +1070,7 @@ File *compile_and_invoke(const char *file, const char *args)
scratch_buffer_append(args);
if (!execute_cmd_failable(scratch_buffer_to_string(), &out))
{
error_exit("Error invoking script %s with arguments %s.", file, args);
error_exit("Error invoking script '%s' with arguments %s.", file, args);
}
return source_file_text_load(file, out);
}

View File

@@ -45,11 +45,9 @@ typedef uint16_t SectionId;
#define CLOBBER_FLAG_ELEMENTS 4
#define MAX_CLOBBER_FLAGS (64 * CLOBBER_FLAG_ELEMENTS)
extern const char *project_default_keys[];
extern const char *project_default_descriptions[];
extern const char *project_default_keys[][2];
extern const int project_default_keys_count;
extern const char* project_target_keys[];
extern const char* project_target_descriptions[];
extern const char* project_target_keys[][2];
extern const int project_target_keys_count;
typedef struct Ast_ Ast;

View File

@@ -163,7 +163,7 @@ static Decl **sema_load_include(CompilationUnit *unit, Decl *decl)
{
if (active_target.trust_level < TRUST_INCLUDE)
{
SEMA_ERROR(decl, "'$include' not permitted, trust level must be set to '-t2' or '-t3' to permit it.");
SEMA_ERROR(decl, "'$include' not permitted, trust level must be set to '--trust=include' or '--trust=full' to permit it.");
return NULL;
}
SemaContext context;
@@ -192,7 +192,7 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl)
{
if (active_target.trust_level < TRUST_FULL)
{
SEMA_ERROR(decl, "'$exec' not permitted, trust level must be set to '-t3' to permit it.");
SEMA_ERROR(decl, "'$exec' not permitted, trust level must be set to '--trust=full' to permit it.");
return NULL;
}
SemaContext context;
@@ -266,6 +266,18 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl)
UNREACHABLE
FOREACH_END();
File *file;
// TODO fix Win32
char *old_path = NULL;
if (active_target.script_dir)
{
old_path = getcwd(NULL, 0);
if (!dir_change(active_target.script_dir))
{
free(old_path);
SEMA_ERROR(decl, "Failed to open script dir '%s'", active_target.script_dir);
return NULL;
}
}
if (c3_script)
{
file = compile_and_invoke(file_str, scratch_buffer_copy());
@@ -275,6 +287,16 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl)
const char *output = execute_cmd(scratch_buffer_to_string());
file = source_file_text_load(scratch_buffer_to_string(), output);
}
if (old_path)
{
success = dir_change(old_path);
free(old_path);
if (!success)
{
SEMA_ERROR(decl, "Failed to open run dir '%s'", active_target.script_dir);
return NULL;
}
}
if (global_context.includes_used++ > MAX_INCLUDES)
{
SEMA_ERROR(decl, "This $include would cause the maximum number of includes (%d) to be exceeded.", MAX_INCLUDES);

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.665"
#define COMPILER_VERSION "0.4.666"