Allow "project.json5" to be used.

This commit is contained in:
Christoffer Lerno
2024-08-25 00:19:08 +02:00
parent 1ed3eab010
commit a870881fff
7 changed files with 106 additions and 95 deletions

View File

@@ -193,10 +193,10 @@ fn Backtrace! resolve_backtrace(void* addr, Win32_HANDLE process, Allocator allo
ZString zname = (ZString)&name;
if (!symGetLineFromAddr64(process, (Win32_ULONG64)addr - 1, &offset, &line))
{
backtrace.init((uptr)addr, .function = zname.str_view(), .object_file = module_name.str_view(), .allocator = allocator);
backtrace.init((uptr)addr, zname.str_view(), module_name.str_view(), .allocator = allocator);
return backtrace;
}
String filename = ((ZString)line.fileName).str_view();
backtrace.init((uptr)addr, .function = zname.str_view(), .object_file = module_name.str_view(), .file = filename, .line = line.lineNumber, .allocator = allocator);
backtrace.init((uptr)addr, zname.str_view(), module_name.str_view(), .file = filename, .line = line.lineNumber, .allocator = allocator);
return backtrace;
}

View File

@@ -108,8 +108,8 @@ static const char *sanitize_modes[4] = {
[SANITIZE_THREAD] = "thread",
};
Project *project_load(void);
BuildTarget *project_select_target(Project *project, const char *optional_target);
Project *project_load(const char **filename_ref);
BuildTarget *project_select_target(const char *filename, Project *project, const char *optional_target);
void update_feature_flags(const char ***flags, const char ***removed_flag, const char *arg, bool add);
const char *get_string(const char *file, const char *category, JSONObject *table, const char *key,

View File

@@ -486,8 +486,9 @@ void init_build_target(BuildTarget *target, BuildOptions *options)
// Locate the project.json
file_find_top_dir();
// Parse it
Project *project = project_load();
*target = *project_select_target(project, options->target_select);
const char *filename;
Project *project = project_load(&filename);
*target = *project_select_target(filename, project, options->target_select);
update_build_target_from_options(target, options);
if (target->build_dir && !file_exists(target->build_dir))

View File

@@ -139,10 +139,11 @@ const int project_deprecated_target_keys_count = ELEMENTLEN(project_deprecated_t
#define MAX_SYMTAB_SIZE (1024 * 1024)
#define GET_SETTING(type__, key__, strings__, comment__) \
(type__)get_valid_string_setting(PROJECT_JSON, target_name, json, key__, strings__, 0, ELEMENTLEN(strings__), comment__)
(type__)get_valid_string_setting(filename, target_name, json, key__, strings__, 0, ELEMENTLEN(strings__), comment__)
// Json -> target / default target
static void load_into_build_target(JSONObject *json, const char *target_name, BuildTarget *target)
static void load_into_build_target(const char *filename, JSONObject *json, const char *target_name,
BuildTarget *target)
{
if (target_name)
{
@@ -154,53 +155,53 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
}
// The default c compiler name
target->cc = get_string(PROJECT_JSON, target_name, json, "cc", target->cc);
target->cc = get_string(filename, target_name, json, "cc", target->cc);
// Where to find and execute the scripts
target->script_dir = get_string(PROJECT_JSON, target_name, json, "script-dir", target->script_dir);
target->script_dir = get_string(filename, target_name, json, "script-dir", target->script_dir);
// The output directory
target->output_dir = get_string(PROJECT_JSON, target_name, json,"output", target->output_dir);
target->output_dir = get_string(filename, target_name, json, "output", target->output_dir);
// "Before compilation" execution
get_list_append_strings(PROJECT_JSON, target_name, json, &target->exec, "exec", "exec-override", "exec-add");
get_list_append_strings(filename, target_name, json, &target->exec, "exec", "exec-override", "exec-add");
// CFlags
target->cflags = get_cflags(PROJECT_JSON, target_name, json, target->cflags);
target->cflags = get_cflags(filename, target_name, json, target->cflags);
// C source dirs.
get_list_append_strings(PROJECT_JSON, target_name, json, &target->csource_dirs, "c-sources", "c-sources-override", "c-sources-add");
get_list_append_strings(filename, target_name, json, &target->csource_dirs, "c-sources", "c-sources-override", "c-sources-add");
// C include dirs.
get_list_append_strings(PROJECT_JSON, target_name, json, &target->cinclude_dirs, "c-include-dirs", "c-include-dirs-override", "c-include-dirs-add");
get_list_append_strings(filename, target_name, json, &target->cinclude_dirs, "c-include-dirs", "c-include-dirs-override", "c-include-dirs-add");
// Sources
get_list_append_strings(PROJECT_JSON, target_name, json, &target->source_dirs, "sources", "sources-override", "sources-add");
get_list_append_strings(filename, target_name, json, &target->source_dirs, "sources", "sources-override", "sources-add");
// Test sources
get_list_append_strings(PROJECT_JSON, target_name, json, &target->test_source_dirs, "test-sources", "test-sources-override", "test-sources-add");
get_list_append_strings(filename, target_name, json, &target->test_source_dirs, "test-sources", "test-sources-override", "test-sources-add");
// Linked-libraries - libraries to add at link time
get_list_append_strings(PROJECT_JSON, target_name, json, &target->linker_libs, "linked-libraries", "linked-libraries-override", "linked-libraries-add");
get_list_append_strings(filename, target_name, json, &target->linker_libs, "linked-libraries", "linked-libraries-override", "linked-libraries-add");
// linker-search-paths libs dir - libraries to add at link time
get_list_append_strings(PROJECT_JSON, target_name, json, &target->linker_libdirs, "linker-search-paths", "linker-search-paths-override", "linker-search-paths-add");
get_list_append_strings(filename, target_name, json, &target->linker_libdirs, "linker-search-paths", "linker-search-paths-override", "linker-search-paths-add");
// link-args - link args to add at link time
get_list_append_strings(PROJECT_JSON, target_name, json, &target->link_args, "link-args", "link-args-override", "link-args-add");
get_list_append_strings(filename, target_name, json, &target->link_args, "link-args", "link-args-override", "link-args-add");
// dependency-search-paths - path to search for libraries
get_list_append_strings(PROJECT_JSON, target_name, json, &target->libdirs, "dependency-search-paths", "dependency-search-paths-override", "dependency-search-paths-add");
get_list_append_strings(filename, target_name, json, &target->libdirs, "dependency-search-paths", "dependency-search-paths-override", "dependency-search-paths-add");
// Dependencies
get_list_append_strings(PROJECT_JSON, target_name, json, &target->libs, "dependencies", "dependencies-override", "dependencies-add");
get_list_append_strings(filename, target_name, json, &target->libs, "dependencies", "dependencies-override", "dependencies-add");
FOREACH(const char *, name, target->libs)
{
if (!str_is_valid_lowercase_name(name))
{
char *name_copy = strdup(name);
str_ellide_in_place(name_copy, 32);
error_exit("Error reading %s: invalid library target '%s'.", PROJECT_JSON, name_copy);
error_exit("Error reading %s: invalid library target '%s'.", filename, name_copy);
}
}
@@ -234,17 +235,17 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
if (opt != OPT_SETTING_NOT_SET) target->optsetting = opt;
// Safety level
target->feature.safe_mode = (SafetyLevel)get_valid_bool(PROJECT_JSON, target_name, json, "safe", target->feature.safe_mode);
target->feature.safe_mode = (SafetyLevel)get_valid_bool(filename, target_name, json, "safe", target->feature.safe_mode);
// Backtrace
target->show_backtrace = (ShowBacktrace) get_valid_bool(PROJECT_JSON, target_name, json, "show-backtrace", target->show_backtrace);
target->show_backtrace = (ShowBacktrace) get_valid_bool(filename, target_name, json, "show-backtrace", target->show_backtrace);
// Panic level
target->feature.panic_level = (PanicLevel)get_valid_bool(PROJECT_JSON, target_name, json, "panic-msg",
target->feature.panic_level);
target->feature.panic_level = (PanicLevel)get_valid_bool(filename, target_name, json, "panic-msg",
target->feature.panic_level);
// Single module
target->single_module = (SingleModule) get_valid_bool(PROJECT_JSON, target_name, json, "single-module", target->single_module);
target->single_module = (SingleModule) get_valid_bool(filename, target_name, json, "single-module", target->single_module);
// Memory environment for memory constrained environments.
MemoryEnvironment env = GET_SETTING(MemoryEnvironment, "memory-env", memory_environment, "one of 'normal', 'small', 'tiny' or 'none'.");
@@ -256,21 +257,21 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
{
if (symtab_size < 1024)
{
error_exit("Error reading %s: %s symtab was less than 1024.", PROJECT_JSON, target_name);
error_exit("Error reading %s: %s symtab was less than 1024.", filename, target_name);
}
if (symtab_size > MAX_SYMTAB_SIZE)
{
error_exit("Error reading %s: %s symtab may not exceed %d.", PROJECT_JSON, target_name, MAX_SYMTAB_SIZE);
error_exit("Error reading %s: %s symtab may not exceed %d.", filename, target_name, MAX_SYMTAB_SIZE);
}
target->symtab_size = (uint32_t)symtab_size;
}
// Target
const char *arch_os_string = get_optional_string(PROJECT_JSON, target_name, json, "target");
const char *arch_os_string = get_optional_string(filename, target_name, json, "target");
if (arch_os_string)
{
ArchOsTarget arch_os = arch_os_target_from_string(arch_os_string);
if (arch_os == ARCH_OS_TARGET_DEFAULT) error_exit("Error reading %s: %s target was not valid.", PROJECT_JSON, target_name);
if (arch_os == ARCH_OS_TARGET_DEFAULT) error_exit("Error reading %s: %s target was not valid.", filename, target_name);
target->arch_os_target = arch_os;
}
@@ -295,7 +296,7 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
}
// Cpu
target->cpu = get_string(PROJECT_JSON, target_name, json, "cpu", target->cpu);
target->cpu = get_string(filename, target_name, json, "cpu", target->cpu);
// WinCRT
WinCrtLinking wincrt = GET_SETTING(WinCrtLinking, "wincrt", wincrt_linking, "'none', 'static-debug', 'staticdebug, 'dynamic-debug' or 'dynamic'.");
@@ -305,7 +306,7 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
FpOpt fpmath = GET_SETTING(FpOpt, "fp-math", fp_math, "`strict`, `relaxed` or `fast`.");
if (fpmath > -1) target->feature.fp_math = fpmath;
const char **features = get_optional_string_array(PROJECT_JSON, target_name, json, "features");
const char **features = get_optional_string_array(filename, target_name, json, "features");
if (features)
{
FOREACH(const char *, feature, features)
@@ -331,49 +332,49 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
if (riscv_float != RISCVFLOAT_DEFAULT) target->feature.riscv_float_capability = riscv_float;
// winsdk
target->win.sdk = get_string(PROJECT_JSON, target_name, json, "winsdk", target->win.sdk);
target->win.sdk = get_string(filename, target_name, json, "winsdk", target->win.sdk);
// windef
target->win.def = get_string(PROJECT_JSON, target_name, json, "windef", target->win.def);
target->win.def = get_string(filename, target_name, json, "windef", target->win.def);
// macossdk
target->macos.sysroot = get_string(PROJECT_JSON, target_name, json, "macossdk", target->macos.sysroot);
target->macos.sysroot = get_string(filename, target_name, json, "macossdk", target->macos.sysroot);
// macos-min-version
target->macos.min_version = get_string(PROJECT_JSON, target_name, json, "macos-min-version", target->macos.min_version);
target->macos.min_version = get_string(filename, target_name, json, "macos-min-version", target->macos.min_version);
// macos-sdk-version
target->macos.sdk_version = get_string(PROJECT_JSON, target_name, json, "macos-sdk-version", target->macos.sdk_version);
target->macos.sdk_version = get_string(filename, target_name, json, "macos-sdk-version", target->macos.sdk_version);
// Linux crt
target->linuxpaths.crt = get_string(PROJECT_JSON, target_name, json, "linux-crt", target->linuxpaths.crt);
target->linuxpaths.crt = get_string(filename, target_name, json, "linux-crt", target->linuxpaths.crt);
// Linux crtbegin
target->linuxpaths.crtbegin = get_string(PROJECT_JSON, target_name, json, "linux-crtbegin", target->linuxpaths.crtbegin);
target->linuxpaths.crtbegin = get_string(filename, target_name, json, "linux-crtbegin", target->linuxpaths.crtbegin);
// version
target->version = get_string(PROJECT_JSON, target_name, json, "version", target->version);
target->version = get_string(filename, target_name, json, "version", target->version);
// langrev
target->langrev = get_string(PROJECT_JSON, target_name, json, "langrev", target->langrev);
target->langrev = get_string(filename, target_name, json, "langrev", target->langrev);
// panicfn
target->panicfn = get_string(PROJECT_JSON, target_name, json, "panicfn", target->panicfn);
target->panicfn = get_string(filename, target_name, json, "panicfn", target->panicfn);
// testfn
target->testfn = get_string(PROJECT_JSON, target_name, json, "testfn", target->testfn);
target->testfn = get_string(filename, target_name, json, "testfn", target->testfn);
// testfn
target->benchfn = get_string(PROJECT_JSON, target_name, json, "benchfn", target->benchfn);
target->benchfn = get_string(filename, target_name, json, "benchfn", target->benchfn);
// link-libc
target->link_libc = (LinkLibc) get_valid_bool(PROJECT_JSON, target_name, json, "link-libc", target->link_libc);
target->link_libc = (LinkLibc) get_valid_bool(filename, target_name, json, "link-libc", target->link_libc);
// strip-unused
target->strip_unused = (StripUnused) get_valid_bool(PROJECT_JSON, target_name, json, "strip-unused", target->strip_unused);
target->strip_unused = (StripUnused) get_valid_bool(filename, target_name, json, "strip-unused", target->strip_unused);
// linker
const char *linker_selection = get_optional_string(PROJECT_JSON, target_name, json, "linker");
const char *linker_selection = get_optional_string(filename, target_name, json, "linker");
if (linker_selection)
{
if (str_eq("cc", linker_selection))
@@ -394,33 +395,34 @@ static void load_into_build_target(JSONObject *json, const char *target_name, Bu
}
// no-entry
target->no_entry = get_valid_bool(PROJECT_JSON, target_name, json, "no-entry", target->no_entry);
target->no_entry = get_valid_bool(filename, target_name, json, "no-entry", target->no_entry);
// use-stdlib
target->use_stdlib = (UseStdlib) get_valid_bool(PROJECT_JSON, target_name, json, "use-stdlib", target->use_stdlib);
target->use_stdlib = (UseStdlib) get_valid_bool(filename, target_name, json, "use-stdlib", target->use_stdlib);
// emit-stdlib
target->emit_stdlib = (EmitStdlib) get_valid_bool(PROJECT_JSON, target_name, json, "emit-stdlib", target->emit_stdlib);
target->emit_stdlib = (EmitStdlib) get_valid_bool(filename, target_name, json, "emit-stdlib", target->emit_stdlib);
// single-module
target->single_module = (SingleModule) get_valid_bool(PROJECT_JSON, target_name, json, "single-module", target->single_module);
target->single_module = (SingleModule) get_valid_bool(filename, target_name, json, "single-module", target->single_module);
// Trap on wrap
target->feature.trap_on_wrap = get_valid_bool(PROJECT_JSON, target_name, json, "trap-on-wrap", target->feature.trap_on_wrap);
target->feature.trap_on_wrap = get_valid_bool(filename, target_name, json, "trap-on-wrap", target->feature.trap_on_wrap);
// Use the fact that they correspond to 0, 1, -1
target->feature.x86_struct_return = get_valid_bool(PROJECT_JSON, target_name, json, "x86-stack-struct-return",
target->feature.x86_struct_return = get_valid_bool(filename, target_name, json, "x86-stack-struct-return",
target->feature.x86_struct_return);
// Soft float
target->feature.soft_float = get_valid_bool(PROJECT_JSON, target_name, json, "soft-float", target->feature.soft_float);
target->feature.soft_float = get_valid_bool(filename, target_name, json, "soft-float", target->feature.soft_float);
// Win64 simd feature switch
target->feature.pass_win64_simd_as_arrays = get_valid_bool(PROJECT_JSON, target_name, json, "win64-simd-array",
target->feature.pass_win64_simd_as_arrays = get_valid_bool(filename, target_name, json, "win64-simd-array",
target->feature.pass_win64_simd_as_arrays);
}
static void project_add_target(Project *project, BuildTarget *default_target, JSONObject *json, const char *name, const char *type, TargetType target_type)
static void project_add_target(const char *filename, Project *project, BuildTarget *default_target, JSONObject *json,
const char *name, const char *type, TargetType target_type)
{
assert(json->type == J_OBJECT);
BuildTarget *target = CALLOCS(BuildTarget);
@@ -433,19 +435,19 @@ static void project_add_target(Project *project, BuildTarget *default_target, J
if (other_target == target) continue;
if (strcmp(other_target->name, target->name) == 0)
{
error_exit("More %s contained more than one target with the name %s. Please make all target names unique.", PROJECT_JSON, target->name);
error_exit("More %s contained more than one target with the name %s. Please make all target names unique.", filename, target->name);
}
}
type = str_printf("%s %s", type, target->name);
load_into_build_target(json, type, target);
load_into_build_target(filename, json, type, target);
}
static void project_add_targets(Project *project, JSONObject *project_data)
static void project_add_targets(const char *filename, Project *project, JSONObject *project_data)
{
assert(project_data->type == J_OBJECT);
BuildTarget default_target = default_build_target;
load_into_build_target(project_data, NULL, &default_target);
load_into_build_target(filename, project_data, NULL, &default_target);
JSONObject *targets_json = json_obj_get(project_data, "targets");
if (!targets_json)
{
@@ -463,9 +465,9 @@ static void project_add_targets(Project *project, JSONObject *project_data)
{
error_exit("Invalid data in target '%s'", key);
}
int type = get_valid_string_setting(PROJECT_JSON, NULL, object, "type", targets, 0, ELEMENTLEN(targets), "a target type like 'executable' or 'static-lib'");
int type = get_valid_string_setting(filename, NULL, object, "type", targets, 0, ELEMENTLEN(targets), "a target type like 'executable' or 'static-lib'");
if (type < 0) error_exit("Target %s did not contain 'type' key.", key);
project_add_target(project, &default_target, object, key, target_desc[type], type);
project_add_target(filename, project, &default_target, object, key, target_desc[type], type);
}
}
@@ -493,11 +495,11 @@ static BuildTarget *project_select_default_target(Project *project)
* @param optional_target the selected target, may be NULL.
* @return the target if one is provided, otherwise the default target.
*/
BuildTarget *project_select_target(Project *project, const char *optional_target)
BuildTarget *project_select_target(const char *filename, Project *project, const char *optional_target)
{
if (!vec_size(project->targets))
{
error_exit("No targets could be found in %s. Please define at least one target, for example an 'executable' and try again.", PROJECT_JSON);
error_exit("No targets could be found in %s. Please define at least one target, for example an 'executable' and try again.", filename);
}
if (!optional_target)
{
@@ -507,25 +509,26 @@ BuildTarget *project_select_target(Project *project, const char *optional_target
{
if (str_eq(target->name, optional_target)) return target;
}
error_exit("No build target named '%s' was found in %s. Was it misspelled?", optional_target, PROJECT_JSON);
error_exit("No build target named '%s' was found in %s. Was it misspelled?", optional_target, filename);
}
Project *project_load(void)
Project *project_load(const char **filename_ref)
{
Project *project = CALLOCS(Project);
size_t size;
char *read = file_read_all(PROJECT_JSON, &size);
const char *filename = *filename_ref = file_exists(PROJECT_JSON5) ? PROJECT_JSON5 : PROJECT_JSON;
char *read = file_read_all(filename, &size);
JsonParser parser;
json_init_string(&parser, read, &malloc_arena);
JSONObject *json = json_parse(&parser);
if (parser.error_message)
{
error_exit("Error on line %d reading '%s':'%s'", parser.line, PROJECT_JSON, parser.error_message);
error_exit("Error on line %d reading '%s':'%s'", parser.line, filename, parser.error_message);
}
if (!json || json->type != J_OBJECT)
{
error_exit("Expected a map of targets in '%s'.", PROJECT_JSON);
error_exit("Expected a map of targets in '%s'.", filename);
}
project_add_targets(project, json);
project_add_targets(filename, project, json);
return project;
}

View File

@@ -1,20 +1,23 @@
#include "build_internal.h"
#define PRINTFN(string, ...) fprintf(stdout, string "\n", ##__VA_ARGS__) // NOLINT
#define PRINTF(string, ...) fprintf(stdout, string, ##__VA_ARGS__) // NOLINT
static JSONObject *read_project()
static JSONObject *read_project(const char **file_used)
{
size_t size;
char *read = file_read_all(PROJECT_JSON, &size);
const char *project_filename = file_exists(PROJECT_JSON5) ? PROJECT_JSON5 : PROJECT_JSON;
*file_used = project_filename;
char *read = file_read_all(project_filename, &size);
JsonParser parser;
json_init_string(&parser, read, &malloc_arena);
JSONObject *json = json_parse(&parser);
if (parser.error_message)
{
error_exit("Error on line %d reading '%s':'%s'", parser.line, PROJECT_JSON, parser.error_message);
error_exit("Error on line %d reading '%s':'%s'", parser.line, project_filename, parser.error_message);
}
if (!json || json->type != J_OBJECT)
{
error_exit("Expected a map of project information in '%s'.", PROJECT_JSON);
error_exit("Expected a map of project information in '%s'.", project_filename);
}
return json;
}
@@ -94,74 +97,74 @@ const char *debug_levels[] = {
#define VIEW_MANDATORY_STRING_ARRAY(header, key) \
do { \
const char** arr = get_string_array(PROJECT_JSON, NULL, project_json, key, true);\
const char** arr = get_string_array(filename, NULL, project_json, key, true);\
print_vec(header, arr, false);\
} while(0)
#define VIEW_STRING_ARRAY(header, key) \
do { \
const char** arr = get_optional_string_array(PROJECT_JSON, NULL, project_json, key);\
const char** arr = get_optional_string_array(filename, NULL, project_json, key);\
print_vec(header, arr, true);\
} while(0)
#define VIEW_MANDATORY_STRING(header, key) \
do { \
const char* str = get_mandatory_string(PROJECT_JSON, NULL, project_json, key);\
const char* str = get_mandatory_string(filename, NULL, project_json, key);\
print_opt_str(header, str);\
} while(0)
#define VIEW_STRING(header, key) \
do { \
const char* str = get_optional_string(PROJECT_JSON, NULL, project_json, key);\
const char* str = get_optional_string(filename, NULL, project_json, key);\
print_opt_str(header, str);\
} while(0)
#define VIEW_SETTING(header, key, expected_arr) \
do { \
int setting = get_valid_string_setting(PROJECT_JSON, NULL, project_json, key, expected_arr, 0, ELEMENTLEN(expected_arr), generate_expected(expected_arr, ELEMENTLEN(expected_arr)));\
int setting = get_valid_string_setting(filename, NULL, project_json, key, expected_arr, 0, ELEMENTLEN(expected_arr), generate_expected(expected_arr, ELEMENTLEN(expected_arr)));\
print_opt_setting(header, setting, expected_arr);\
} while(0)
#define VIEW_BOOL(header, key) \
do {\
int val = get_valid_bool(PROJECT_JSON, NULL, project_json, key, -1);\
int val = get_valid_bool(filename, NULL, project_json, key, -1);\
print_opt_bool(header, val);\
} while(0)
#define VIEW_INTEGER(header, key) \
do {\
long v = get_valid_integer(project_json, key, PROJECT_JSON, false);\
long v = get_valid_integer(project_json, key, filename, false);\
print_opt_int(header, v);\
} while(0);
#define TARGET_VIEW_STRING_ARRAY(header, key) \
do {\
const char** arr = get_optional_string_array(PROJECT_JSON, name, target, key);\
const char** arr = get_optional_string_array(filename, name, target, key);\
print_vec("\t" header, arr, true);\
} while(0)
#define TARGET_VIEW_MANDATORY_STRING(header, key) \
do { \
const char* str = get_mandatory_string(PROJECT_JSON, name, target, key);\
const char* str = get_mandatory_string(filename, name, target, key);\
print_opt_str("\t" header, str);\
} while(0)
#define TARGET_VIEW_STRING(header, key) \
do { \
const char* str = get_optional_string(PROJECT_JSON, name, target, key);\
const char* str = get_optional_string(filename, name, target, key);\
print_opt_str("\t" header, str);\
} while(0)
#define TARGET_VIEW_SETTING(header, key, expected_arr) \
do { \
int setting = get_valid_string_setting(PROJECT_JSON, name, target, key, expected_arr, 0, ELEMENTLEN(expected_arr), generate_expected(expected_arr, ELEMENTLEN(expected_arr)));\
int setting = get_valid_string_setting(filename, name, target, key, expected_arr, 0, ELEMENTLEN(expected_arr), generate_expected(expected_arr, ELEMENTLEN(expected_arr)));\
print_opt_setting("\t" header, setting, expected_arr);\
} while(0)
#define TARGET_VIEW_BOOL(header, key) \
do {\
int val = get_valid_bool(PROJECT_JSON, name, target, key, -1);\
int val = get_valid_bool(filename, name, target, key, -1);\
print_opt_bool("\t" header, val);\
} while(0)
@@ -171,7 +174,7 @@ do {\
print_opt_int("\t" header, v);\
} while(0);
static void view_target(const char *name, JSONObject *target)
static void view_target(const char *filename, const char *name, JSONObject *target)
{
/* General target information */
PRINTFN("- %s", name);
@@ -238,7 +241,8 @@ static void view_target(const char *name, JSONObject *target)
void add_target_project(BuildOptions *build_options)
{
JSONObject *project_json = read_project();
const char *filename;
JSONObject *project_json = read_project(&filename);
JSONObject *targets_json = json_obj_get(project_json, "targets");
for (unsigned i = 0; i < targets_json->member_len; i++)
@@ -270,14 +274,15 @@ void add_target_project(BuildOptions *build_options)
targets_json->keys[index] = build_options->project_options.target_name;
targets_json->member_len++;
FILE *file = fopen(PROJECT_JSON, "w");
FILE *file = fopen(filename, "w");
print_json_to_file(project_json, file);
fclose(file);
}
void view_project(BuildOptions *build_options)
{
JSONObject *project_json = read_project();
const char *filename;
JSONObject *project_json = read_project(&filename);
/* General information */
VIEW_MANDATORY_STRING_ARRAY("Authors", "authors");
@@ -351,6 +356,6 @@ void view_project(BuildOptions *build_options)
{
error_exit("Invalid data in target '%s'", key);
}
view_target(key, object);
view_target(filename, key, object);
}
}

View File

@@ -22,6 +22,7 @@
#define MAX_ARRAY_SIZE INT64_MAX
#define MAX_SOURCE_LOCATION_LEN 255
#define PROJECT_JSON "project.json"
#define PROJECT_JSON5 "project.json5"
#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( _WIN64 )
#define PLATFORM_WINDOWS 1

View File

@@ -421,12 +421,13 @@ void file_find_top_dir()
while (1)
{
struct stat info;
int err = stat(PROJECT_JSON, &info);
const char *filename = file_exists(PROJECT_JSON5) ? PROJECT_JSON5 : PROJECT_JSON;
int err = stat(filename, &info);
// Error and the it's not a "missing file"?
if (err && errno != ENOENT)
{
error_exit("Can't open %s: %s.", PROJECT_JSON, strerror(errno));
error_exit("Can't open %s: %s.", filename, strerror(errno));
}
// Everything worked and it's a regular file? We're done!