From a0f082f210cdcf33ce0cbbf6655c7e127f3f3f5e Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 24 Dec 2022 19:28:32 +0100 Subject: Error codes --- source/kit/file.c | 118 +++++++++++++++++++++++++++------------------- source/kit/file.h | 13 ++++- source/kit/input_buffer.c | 6 +-- source/kit/status.h | 11 ++++- 4 files changed, 94 insertions(+), 54 deletions(-) diff --git a/source/kit/file.c b/source/kit/file.c index d69bf76..0760258 100644 --- a/source/kit/file.c +++ b/source/kit/file.c @@ -24,7 +24,7 @@ static int is_delim(char const c) { kit_string_t kit_path_norm(kit_str_t const path, kit_allocator_t const alloc) { - str_t parent = SZ(".."); + str_t const parent = SZ(".."); string_t norm; DA_INIT(norm, path.size, alloc); @@ -189,6 +189,9 @@ kit_str_t kit_path_take(kit_str_t const path, ptrdiff_t const count) { #if defined(_WIN32) && !defined(__CYGWIN__) static void win32_prepare_path_(WCHAR *const buf, kit_str_t const path) { + assert(path.size == 0 || path.values != NULL); + assert(path.size + 5 < PATH_BUF_SIZE); + memset(buf, 0, PATH_BUF_SIZE); buf[0] = L'\\'; buf[1] = L'\\'; @@ -208,6 +211,9 @@ static void win32_prepare_path_(WCHAR *const buf, #else static void unix_prepare_path_(char *const buf, kit_str_t const path) { + assert(path.size == 0 || path.values != NULL); + assert(path.size + 1 < PATH_BUF_SIZE); + memset(buf, 0, PATH_BUF_SIZE); if (path.size > 0 && path.size + 1 < PATH_BUF_SIZE) memcpy(buf, path.values, path.size); @@ -220,13 +226,11 @@ static void unix_prepare_path_(char *const buf, kit_status_t kit_file_create_folder(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) - if (CreateDirectoryW(buf, NULL)) - return KIT_OK; + return CreateDirectoryW(buf, NULL) ? KIT_OK + : KIT_ERROR_MKDIR_FAILED; #else - if (mkdir(buf, 0755) == 0) - return KIT_OK; + return mkdir(buf, 0755) == 0 ? KIT_OK : KIT_ERROR_MKDIR_FAILED; #endif - return KIT_ERROR; } kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { @@ -234,7 +238,7 @@ kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { str_t const part = kit_path_take(path, i); int const type = kit_path_type(part); if (type == KIT_PATH_FILE) - return KIT_ERROR; + return KIT_ERROR_FILE_ALREADY_EXISTS; if (type == KIT_PATH_NONE) { kit_status_t const s = kit_file_create_folder(part); if (s != KIT_OK) @@ -250,25 +254,19 @@ kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { kit_status_t kit_file_remove(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) - if (DeleteFileW(buf)) - return KIT_OK; + return DeleteFileW(buf) ? KIT_OK : KIT_ERROR_UNLINK_FAILED; #else - if (unlink(buf) == 0) - return KIT_OK; + return unlink(buf) == 0 ? KIT_OK : KIT_ERROR_UNLINK_FAILED; #endif - return KIT_ERROR; } kit_status_t kit_file_remove_folder(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) - if (RemoveDirectoryW(buf)) - return KIT_OK; + return RemoveDirectoryW(buf) ? KIT_OK : KIT_ERROR_RMDIR_FAILED; #else - if (rmdir(buf) == 0) - return KIT_OK; + return rmdir(buf) == 0 ? KIT_OK : KIT_ERROR_RMDIR_FAILED; #endif - return KIT_ERROR; } kit_status_t kit_file_remove_recursive(kit_str_t const path, @@ -280,9 +278,13 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, case KIT_PATH_FOLDER: { kit_path_list_t list = kit_file_enum_folder(path, alloc); - for (ptrdiff_t i = 0; i < list.size; i++) { - str_t const s = { .size = list.values[i].size, - .values = list.values[i].values }; + if (list.status != KIT_OK) { + kit_path_list_destroy(list); + return list.status; + } + for (ptrdiff_t i = 0; i < list.files.size; i++) { + str_t const s = { .size = list.files.values[i].size, + .values = list.files.values[i].values }; kit_file_remove_recursive(s, alloc); } kit_path_list_destroy(list); @@ -292,7 +294,7 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, default:; } - return KIT_ERROR; + return KIT_ERROR_FILE_DO_NOT_EXISTS; } kit_path_type_t kit_path_type(kit_str_t const path) { @@ -316,8 +318,12 @@ kit_path_type_t kit_path_type(kit_str_t const path) { return KIT_PATH_NONE; } -ptrdiff_t kit_file_size(kit_str_t const path) { +kit_file_size_result_t kit_file_size(kit_str_t const path) { + kit_file_size_result_t result; + memset(&result, 0, sizeof result); + PREPARE_PATH_BUF_; + #if defined(_WIN32) && !defined(__CYGWIN__) HFILE f = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -325,26 +331,36 @@ ptrdiff_t kit_file_size(kit_str_t const path) { DWORD high; DWORD low = GetFileSize(f, &high); CloseHandle(f); - return (ptrdiff_t) ((((uint64_t) high) << 32) | (uint64_t) low); + + result.status = KIT_OK; + result.size = (((uint64_t) high) << 32) | (uint64_t) low; + return result; } #else struct stat info; - if (stat(buf, &info) == 0) - return info.st_size; + if (stat(buf, &info) == 0) { + result.status = KIT_OK; + result.size = (uint64_t) info.st_size; + return result; + } #endif - return KIT_FILE_SIZE_ERROR; + + result.status = KIT_ERROR_FILE_DO_NOT_EXISTS; + return result; } kit_path_list_t kit_file_enum_folder(kit_str_t const path, kit_allocator_t const alloc) { PREPARE_PATH_BUF_; - kit_path_list_t list; - DA_INIT(list, 0, alloc); + kit_path_list_t result = { .status = KIT_OK }; + DA_INIT(result.files, 0, alloc); #if defined(_WIN32) && !defined(__CYGWIN__) - if (path.size + 7 >= PATH_BUF_SIZE) - return list; + if (path.size + 7 >= PATH_BUF_SIZE) { + result.status = KIT_ERROR_PATH_TOO_LONG; + return result; + } buf[path.size + 4] = '\\'; buf[path.size + 5] = '*'; @@ -353,24 +369,27 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, HANDLE find = FindFirstFileW(buf, &data); if (find == INVALID_HANDLE_VALUE) - return list; + return result; do { ptrdiff_t const n = list.size; DA_RESIZE(list, n + 1); - if (list.size != n + 1) + if (result.files.size != n + 1) { + result.status = KIT_ERROR_BAD_ALLOC; break; + } ptrdiff_t size = 0; while (size < MAX_PATH && data.cFileName[size] != L'\0') size++; - DA_INIT(list.values[n], size, alloc); - if (list.values[n].size != size) { - DA_RESIZE(list, n); + DA_INIT(result.files.values[n], size, alloc); + if (result.files.values[n].size != size) { + DA_RESIZE(result.files, n); + result.status = KIT_ERROR_BAD_ALLOC; break; } for (ptrdiff_t i = 0; i < size; i++) - list.values[n].values[i] = data.cFileName[i]; + result.files.values[n].values[i] = data.cFileName[i]; } while (FindNextFileW(find, &data) != 0); FindClose(find); @@ -378,7 +397,7 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, DIR *directory = opendir(buf); if (directory == NULL) - return list; + return result; for (;;) { struct dirent *entry = readdir(directory); @@ -389,30 +408,33 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, if (entry->d_name[0] == '.') continue; - ptrdiff_t const n = list.size; - DA_RESIZE(list, n + 1); - if (list.size != n + 1) + ptrdiff_t const n = result.files.size; + DA_RESIZE(result.files, n + 1); + if (result.files.size != n + 1) { + result.status = KIT_ERROR_BAD_ALLOC; break; + } ptrdiff_t const size = (ptrdiff_t) strlen(entry->d_name); - DA_INIT(list.values[n], size, alloc); - if (list.values[n].size != size) { - DA_RESIZE(list, n); + DA_INIT(result.files.values[n], size, alloc); + if (result.files.values[n].size != size) { + DA_RESIZE(result.files, n); + result.status = KIT_ERROR_BAD_ALLOC; break; } if (size > 0) - memcpy(list.values[n].values, entry->d_name, size); + memcpy(result.files.values[n].values, entry->d_name, size); } closedir(directory); #endif - return list; + return result; } void kit_path_list_destroy(kit_path_list_t list) { - for (ptrdiff_t i = 0; i < list.size; i++) - DA_DESTROY(list.values[i]); - DA_DESTROY(list); + for (ptrdiff_t i = 0; i < list.files.size; i++) + DA_DESTROY(list.files.values[i]); + DA_DESTROY(list.files); } diff --git a/source/kit/file.h b/source/kit/file.h index e85a076..32661df 100644 --- a/source/kit/file.h +++ b/source/kit/file.h @@ -49,9 +49,17 @@ kit_status_t kit_file_remove_recursive(kit_str_t path, kit_path_type_t kit_path_type(kit_str_t path); -ptrdiff_t kit_file_size(kit_str_t path); +typedef struct { + kit_status_t status; + uint64_t size; +} kit_file_size_result_t; -typedef KIT_DA(kit_string_t) kit_path_list_t; +kit_file_size_result_t kit_file_size(kit_str_t path); + +typedef struct { + kit_status_t status; + KIT_DA(kit_string_t) files; +} kit_path_list_t; kit_path_list_t kit_file_enum_folder(kit_str_t path, kit_allocator_t alloc); @@ -71,6 +79,7 @@ void kit_path_list_destroy(kit_path_list_t list); # define file_remove_folder kit_file_remove_folder # define file_remove_recursive kit_file_remove_recursive # define path_type kit_path_type +# define file_size_result_t kit_file_size_result_t # define file_size kit_file_size # define path_type_t kit_path_type_t # define path_list_t kit_path_list_t diff --git a/source/kit/input_buffer.c b/source/kit/input_buffer.c index 208d0de..b9f280b 100644 --- a/source/kit/input_buffer.c +++ b/source/kit/input_buffer.c @@ -91,7 +91,7 @@ kit_ib_handle_t kit_ib_wrap(kit_is_handle_t upstream, DA_INIT(buf.data, 0, alloc); buf.internal = buf_init(upstream, alloc); if (buf.internal == NULL) - buf.status = KIT_ERROR; + buf.status = KIT_ERROR_BAD_ALLOC; return buf; } @@ -105,7 +105,7 @@ kit_ib_handle_t kit_ib_read(kit_ib_handle_t buf, ptrdiff_t size) { buf_adjust(buf.internal, buf.offset + size); DA_INIT(next.data, size, buf_alloc(buf.internal)); if (next.data.size != size) - next.status = KIT_ERROR; + next.status = KIT_ERROR_BAD_ALLOC; kit_out_str_t destination = { .size = next.data.size, .values = next.data.values }; ptrdiff_t n = buf_read(buf.internal, buf.offset, destination); @@ -113,7 +113,7 @@ kit_ib_handle_t kit_ib_read(kit_ib_handle_t buf, ptrdiff_t size) { next.internal = buf.internal; DA_RESIZE(next.data, n); if (next.data.size != n) - next.status = KIT_ERROR; + next.status = KIT_ERROR_BAD_ALLOC; } return next; } diff --git a/source/kit/status.h b/source/kit/status.h index c898e36..62e15d3 100644 --- a/source/kit/status.h +++ b/source/kit/status.h @@ -5,7 +5,16 @@ extern "C" { #endif -enum { KIT_OK, KIT_ERROR }; +enum { + KIT_OK, + KIT_ERROR_BAD_ALLOC, + KIT_ERROR_MKDIR_FAILED, + KIT_ERROR_RMDIR_FAILED, + KIT_ERROR_UNLINK_FAILED, + KIT_ERROR_FILE_ALREADY_EXISTS, + KIT_ERROR_FILE_DO_NOT_EXISTS, + KIT_ERROR_PATH_TOO_LONG +}; typedef int kit_status_t; -- cgit v1.2.3