diff --git a/apps/file_manager/commands.cpp b/apps/file_manager/commands.cpp index 6a659d7..2ae0af4 100644 --- a/apps/file_manager/commands.cpp +++ b/apps/file_manager/commands.cpp @@ -270,16 +270,14 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe } if (error == ES_ERROR_INCORRECT_NODE_TYPE) { - EsDirectoryChild *buffer; - ptrdiff_t childCount = EsDirectoryEnumerateChildren(STRING(source), &buffer); + uintptr_t childCount; + EsDirectoryChild *buffer = EsDirectoryEnumerateChildren(STRING(source), &childCount, &error); - if (ES_CHECK_ERROR(childCount)) { - error = (EsError) childCount; - } else { + if (error == ES_SUCCESS) { error = EsPathCreate(STRING(destination), ES_NODE_DIRECTORY, false); if (error == ES_SUCCESS) { - for (intptr_t i = 0; i < childCount && error == ES_SUCCESS; i++) { + for (uintptr_t i = 0; i < childCount && error == ES_SUCCESS; i++) { String childSourcePath = StringAllocateAndFormat("%s%z%s", STRFMT(source), PathHasTrailingSlash(source) ? "" : "/", buffer[i].nameBytes, buffer[i].name); error = CommandPasteFile(childSourcePath, destination, copyBuffer, task, nullptr); diff --git a/apps/file_manager/folder.cpp b/apps/file_manager/folder.cpp index e2ae00c..93021e3 100644 --- a/apps/file_manager/folder.cpp +++ b/apps/file_manager/folder.cpp @@ -74,19 +74,18 @@ EsError FSDirEnumerate(Folder *folder) { folder->readOnly = volume.flags & ES_VOLUME_READ_ONLY; } - EsDirectoryChild *buffer = nullptr; - ptrdiff_t _entryCount = EsDirectoryEnumerateChildren(STRING(folder->path), &buffer); + uintptr_t _entryCount; + EsError error; + EsDirectoryChild *buffer = EsDirectoryEnumerateChildren(STRING(folder->path), &_entryCount, &error); - if (!ES_CHECK_ERROR(_entryCount)) { - for (intptr_t i = 0; i < _entryCount; i++) { + if (error == ES_SUCCESS) { + for (uintptr_t i = 0; i < _entryCount; i++) { FolderAddEntry(folder, buffer[i].name, buffer[i].nameBytes, &buffer[i]); } - - _entryCount = ES_SUCCESS; } EsHeapFree(buffer); - return (EsError) _entryCount; + return error; } void FSDirGetTotalSize(Folder *folder) { diff --git a/apps/file_manager/ui.cpp b/apps/file_manager/ui.cpp index cd327e8..f6f04d9 100644 --- a/apps/file_manager/ui.cpp +++ b/apps/file_manager/ui.cpp @@ -56,6 +56,7 @@ bool InstanceLoadFolder(Instance *instance, String path /* takes ownership */, i EsMutexAcquire(&folder->modifyEntriesMutex); if (!folder->doneInitialEnumeration) { + // TODO Reporting errors. folder->itemHandler->enumerate(folder); if (folder->containerHandler->getTotalSize) { diff --git a/apps/script_console.cpp b/apps/script_console.cpp index 9701cb7..dafa599 100644 --- a/apps/script_console.cpp +++ b/apps/script_console.cpp @@ -297,11 +297,10 @@ int ExternalFileCopy(ExecutionContext *context, Value *returnValue) { int External_DirectoryInternalStartIteration(ExecutionContext *context, Value *returnValue) { STACK_POP_STRING(entryText, entryBytes); EsHeapFree(directoryIterationBuffer); - directoryIterationBuffer = nullptr; - ptrdiff_t count = EsDirectoryEnumerateChildren(entryText, entryBytes, &directoryIterationBuffer); - returnValue->i = count >= 0 ? 1 : 0; + EsError error; + directoryIterationBuffer = EsDirectoryEnumerateChildren(entryText, entryBytes, &directoryIterationBufferCount, &error); + returnValue->i = error == ES_SUCCESS ? 1 : 0; directoryIterationBufferPosition = 0; - directoryIterationBufferCount = count >= 0 ? count : 0; return 2; } diff --git a/desktop/api_tests.cpp b/desktop/api_tests.cpp index 5c3aaff..e4aa627 100644 --- a/desktop/api_tests.cpp +++ b/desktop/api_tests.cpp @@ -543,15 +543,16 @@ struct { const int testVariable = 3; bool DirectoryEnumerateChildrenRecursive(const char *path, size_t pathBytes) { - EsDirectoryChild *buffer; - ptrdiff_t count = EsDirectoryEnumerateChildren(path, pathBytes, &buffer); + size_t count; + EsError error; + EsDirectoryChild *buffer = EsDirectoryEnumerateChildren(path, pathBytes, &count, &error); - if (count < 0) { - EsPrint("Error %i enumerating at path \"%s\".\n", (EsError) count, pathBytes, path); + if (error != ES_SUCCESS) { + EsPrint("Error %i enumerating at path \"%s\".\n", error, pathBytes, path); return false; } - for (intptr_t i = 0; i < count; i++) { + for (uintptr_t i = 0; i < count; i++) { char *childPath = (char *) EsHeapAllocate(pathBytes + 1 + buffer[i].nameBytes, false); size_t childPathBytes = EsStringFormat(childPath, ES_STRING_FORMAT_ENOUGH_SPACE, "%s/%s", pathBytes, path, buffer[i].nameBytes, buffer[i].name); diff --git a/desktop/files.cpp b/desktop/files.cpp index 0d49cd0..1bd6f5d 100644 --- a/desktop/files.cpp +++ b/desktop/files.cpp @@ -98,45 +98,55 @@ EsError EsFileControl(EsHandle file, uint32_t flags) { return EsSyscall(ES_SYSCALL_FILE_CONTROL, file, flags, 0, 0); } -ptrdiff_t EsDirectoryEnumerateChildrenFromHandle(EsHandle directory, EsDirectoryChild *buffer, size_t size) { +ptrdiff_t DirectoryEnumerateChildrenFromHandle(EsHandle directory, EsDirectoryChild *buffer, size_t size) { if (!size) return 0; return EsSyscall(ES_SYSCALL_DIRECTORY_ENUMERATE, directory, (uintptr_t) buffer, size, 0); } -ptrdiff_t EsDirectoryEnumerateChildren(const char *path, ptrdiff_t pathBytes, EsDirectoryChild **buffer) { - *buffer = nullptr; +EsDirectoryChild *EsDirectoryEnumerateChildren(const char *path, ptrdiff_t pathBytes, size_t *countOut, EsError *errorOut) { + *countOut = 0; + *errorOut = ES_ERROR_UNKNOWN; + if (pathBytes == -1) pathBytes = EsCStringLength(path); _EsNodeInformation node; EsError error = NodeOpen(path, pathBytes, ES_NODE_FAIL_IF_NOT_FOUND | ES_NODE_DIRECTORY, &node); - if (error != ES_SUCCESS) return error; + + if (error != ES_SUCCESS) { + *errorOut = error; + return nullptr; + } if (node.directoryChildren == ES_DIRECTORY_CHILDREN_UNKNOWN) { - node.directoryChildren = 4194304 / sizeof(EsDirectoryChild); // TODO Grow the buffer until all entries fit. + // TODO Grow the buffer until all entries fit. + node.directoryChildren = 4194304 / sizeof(EsDirectoryChild); } if (node.directoryChildren == 0) { // Empty directory. - *buffer = nullptr; - return 0; + *errorOut = ES_SUCCESS; + return nullptr; } - *buffer = (EsDirectoryChild *) EsHeapAllocate(sizeof(EsDirectoryChild) * node.directoryChildren, true); - ptrdiff_t result; + EsDirectoryChild *buffer = (EsDirectoryChild *) EsHeapAllocate(sizeof(EsDirectoryChild) * node.directoryChildren, true); - if (*buffer) { - result = EsDirectoryEnumerateChildrenFromHandle(node.handle, *buffer, node.directoryChildren); + if (buffer) { + ptrdiff_t result = DirectoryEnumerateChildrenFromHandle(node.handle, buffer, node.directoryChildren); if (ES_CHECK_ERROR(result)) { - EsHeapFree(*buffer); - *buffer = nullptr; + EsHeapFree(buffer); + buffer = nullptr; + *errorOut = result; + } else { + *errorOut = ES_SUCCESS; + *countOut = result; } } else { - result = ES_ERROR_INSUFFICIENT_RESOURCES; + *errorOut = ES_ERROR_INSUFFICIENT_RESOURCES; } EsHandleClose(node.handle); - return result; + return buffer; } EsFileInformation EsFileOpen(const char *path, ptrdiff_t pathLength, uint32_t flags) { diff --git a/desktop/os.header b/desktop/os.header index 465d010..7297d90 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -2019,7 +2019,7 @@ function void EsINIZeroTerminate(EsINIState *s); function const void *EsBundleFind(const EsBundle *bundle, STRING name, size_t *byteCount = ES_NULL) @out(byteCount) @fixed_buffer_out(return, byteCount*); // Pass null as the bundle to use the current application's bundle. -function ptrdiff_t EsDirectoryEnumerateChildren(STRING path, EsDirectoryChild **buffer) @out(buffer) @heap_array_out(buffer*, return); // Free buffer with EsHeapFree. Returns number of children. +function EsDirectoryChild *EsDirectoryEnumerateChildren(STRING path, size_t *count, EsError *error = ES_NULL) @out(count) @out(error) @heap_array_out(return, count*); function void *EsFileReadAll(STRING filePath, size_t *fileSize, EsError *error = ES_NULL) @out(fileSize) @out(error) @heap_buffer_out(return, fileSize*); // Free with EsHeapFree. function void *EsFileReadAllFromHandle(EsHandle handle, size_t *fileSize, EsError *error = ES_NULL) @out(fileSize) @out(error) @heap_buffer_out(return, fileSize*); // Free with EsHeapFree. diff --git a/util/build_core.c b/util/build_core.c index a8bd90a..37ec643 100644 --- a/util/build_core.c +++ b/util/build_core.c @@ -412,11 +412,13 @@ void CreateImportNode(const char *path, ImportNode *node) { #ifdef OS_ESSENCE size_t path2Bytes; char *path2 = EsPOSIXConvertPath(path, &path2Bytes, true); - EsDirectoryChild *children; - ptrdiff_t childCount = EsDirectoryEnumerateChildren(path2, path2Bytes, &children); + EsError error; + uintptr_t childCount; + EsDirectoryChild *children = EsDirectoryEnumerateChildren(path2, path2Bytes, &childCount, &error); + EsAssert(error == ES_SUCCESS); EsHeapFree(path2, 0, NULL); - for (intptr_t i = 0; i < childCount; i++) { + for (uintptr_t i = 0; i < childCount; i++) { snprintf(pathBuffer, sizeof(pathBuffer), "%s/%.*s", path, (int) children[i].nameBytes, children[i].name); ImportNode child = {}; diff --git a/util/header_generator.c b/util/header_generator.c index 6fff8c2..5499425 100644 --- a/util/header_generator.c +++ b/util/header_generator.c @@ -1269,6 +1269,7 @@ bool ScriptWriteBasicType(const char *type) { void OutputScript(Entry *root) { // TODO Return values. // TODO Structs, enums, etc. + // TODO matrix_shared int skippedFunctions = 0, totalFunctions = 0; @@ -1302,7 +1303,6 @@ void OutputScript(Entry *root) { for (int i = 0; i < arrlen(entry->annotations); i++) { if ((0 == strcmp(entry->annotations[i].name, "out") - || 0 == strcmp(entry->annotations[i].name, "heap_array_out") || 0 == strcmp(entry->annotations[i].name, "buffer_out")) && 0 == strcmp(entry->annotations[i].children[0].name, argument->name)) { goto skipArgument;