diff --git a/ports/gcc/port.script b/ports/gcc/port.script index 62d4ddf..e72850a 100644 --- a/ports/gcc/port.script +++ b/ports/gcc/port.script @@ -56,14 +56,11 @@ void Start() { } // Create folders. - assert PathCreateDirectory("bin"); - assert PathCreateDirectory("root"); - assert PathCreateDirectory("root/Essence"); - assert PathCreateDirectory("root/Applications"); - assert PathCreateDirectory("root/Applications/POSIX"); - assert PathCreateDirectory("root/Applications/POSIX/bin"); - assert PathCreateDirectory("root/Applications/POSIX/include"); - assert PathCreateDirectory("root/Applications/POSIX/lib"); + assert PathCreateLeadingDirectories("bin"); + assert PathCreateLeadingDirectories("root/Essence"); + assert PathCreateLeadingDirectories("root/Applications/POSIX/bin"); + assert PathCreateLeadingDirectories("root/Applications/POSIX/include"); + assert PathCreateLeadingDirectories("root/Applications/POSIX/lib"); // Load the persistent variables. assert PersistRead("bin/build_gcc_state.dat"); diff --git a/ports/harfbuzz/build.script b/ports/harfbuzz/build.script index 9ec2b8f..10ea6ce 100644 --- a/ports/harfbuzz/build.script +++ b/ports/harfbuzz/build.script @@ -25,7 +25,7 @@ void Start() { "find . -type f -exec %sed% -i 's/#include <%headers[i]%.h>/#include /g' {} \\;"); } - assert PathCreateDirectory("root/Applications/POSIX/include/harfbuzz"); + assert PathCreateLeadingDirectories("root/Applications/POSIX/include/harfbuzz"); assert SystemShellExecute("cp -p bin/harfbuzz/src/*.h root/Applications/POSIX/include/harfbuzz"); } diff --git a/ports/musl/build.script b/ports/musl/build.script index e98359e..431dac6 100644 --- a/ports/musl/build.script +++ b/ports/musl/build.script @@ -37,11 +37,8 @@ void Start() { } if install { - assert PathCreateDirectory("root"); - assert PathCreateDirectory("root/Applications"); - assert PathCreateDirectory("root/Applications/POSIX"); - assert PathCreateDirectory("root/Applications/POSIX/lib"); - assert PathCreateDirectory("root/Applications/POSIX/include"); + assert PathCreateLeadingDirectories("root/Applications/POSIX/lib"); + assert PathCreateLeadingDirectories("root/Applications/POSIX/include"); assert FileCopy("ports/musl/libc.a", "root/Applications/POSIX/lib/libc.a"); assert FileCopy("ports/musl/empty.a", "root/Applications/POSIX/lib/libm.a"); diff --git a/util/get_source.script b/util/get_source.script index ccd9d8e..8b64728 100644 --- a/util/get_source.script +++ b/util/get_source.script @@ -6,8 +6,7 @@ void Get(str url, str directoryName, str checksum) { assert url != ""; assert directoryName != ""; - assert PathCreateDirectory("bin"); - assert PathCreateDirectory("bin/cache"); + assert PathCreateLeadingDirectories("bin/cache"); assert PathDeleteRecursively("bin/source"); str url2 = ""; diff --git a/util/script.c b/util/script.c index 976fca1..b2305fe 100644 --- a/util/script.c +++ b/util/script.c @@ -357,6 +357,7 @@ char baseModuleSource[] = { "bool PathExists(str x) #extcall;" "bool PathCreateDirectory(str x) #extcall;" // TODO Replace the return value with a enum. + "bool PathCreateLeadingDirectories(str x) #extcall;" "bool PathDelete(str x) #extcall;" // TODO Replace the return value with a enum. "bool PathDeleteRecursively(str x) #extcall;" "bool PathMove(str source, str destination) #extcall;" @@ -397,6 +398,7 @@ int ExternalSystemGetProcessorCount(ExecutionContext *context, Value *returnValu int ExternalSystemGetEnvironmentVariable(ExecutionContext *context, Value *returnValue); int ExternalSystemSetEnvironmentVariable(ExecutionContext *context, Value *returnValue); int ExternalPathCreateDirectory(ExecutionContext *context, Value *returnValue); +int ExternalPathCreateLeadingDirectories(ExecutionContext *context, Value *returnValue); int ExternalPathDelete(ExecutionContext *context, Value *returnValue); int ExternalPathDeleteRecursively(ExecutionContext *context, Value *returnValue); int ExternalPathExists(ExecutionContext *context, Value *returnValue); @@ -424,6 +426,7 @@ ExternalFunction externalFunctions[] = { { .cName = "SystemSetEnvironmentVariable", .callback = ExternalSystemSetEnvironmentVariable }, { .cName = "PathExists", .callback = ExternalPathExists }, { .cName = "PathCreateDirectory", .callback = ExternalPathCreateDirectory }, + { .cName = "PathCreateLeadingDirectories", .callback = ExternalPathCreateLeadingDirectories }, { .cName = "PathDelete", .callback = ExternalPathDelete }, { .cName = "PathDeleteRecursively", .callback = ExternalPathDeleteRecursively }, { .cName = "PathMove", .callback = ExternalPathMove }, @@ -4050,6 +4053,39 @@ int ExternalPathCreateDirectory(ExecutionContext *context, Value *returnValue) { return 2; } +int ExternalPathCreateLeadingDirectories(ExecutionContext *context, Value *returnValue) { + (void) returnValue; + if (context->stackPointer < 1) return -1; + uint64_t index = context->stack[--context->stackPointer].i; + if (!context->stackIsManaged[context->stackPointer]) return -1; + if (context->heapEntriesAllocated <= index) return -1; + HeapEntry *entry = &context->heap[index]; + returnValue->i = 0; + if (entry->type == T_EOF) return 2; + if (entry->type != T_STR) return -1; + char *temporary = malloc(entry->bytes + 1); + if (!temporary) return 2; + memcpy(temporary, entry->text, entry->bytes); + temporary[entry->bytes] = 0; + returnValue->i = 1; +#ifdef _WIN32 +#pragma message ("ExternalPathCreateLeadingDirectories unimplemented") + returnValue->i = 0; +#else + for (uintptr_t i = 1; i < entry->bytes; i++) { + if (temporary[i] == '/') { + temporary[i] = 0; + mkdir(temporary, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + temporary[i] = '/'; + } + } + + if (mkdir(temporary, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) returnValue->i = errno == EEXIST; +#endif + free(temporary); + return 2; +} + int ExternalPathDelete(ExecutionContext *context, Value *returnValue) { (void) returnValue; if (context->stackPointer < 1) return -1;