24 Commits

Author SHA1 Message Date
wash 87270b686c build: re-organise assembly build files 2026-05-03 17:05:48 +01:00
wash f4469c9eb0 fx.cmdline: convert to new assembly build system 2026-05-03 16:49:33 +01:00
wash 44fed67d43 fx.term: convert to new assembly build system 2026-05-03 16:49:23 +01:00
wash 0c53974ac9 fx.serial: convert to new assembly build system 2026-05-03 16:48:42 +01:00
wash 3f7ad3ab08 fx.compression: convert to new assembly build system 2026-05-03 16:29:23 +01:00
wash cefb548824 fx.io: convert to assembly build system 2026-05-03 14:51:11 +01:00
wash 55ba15b1fa fx: fix darwin compilation 2026-05-03 14:51:01 +01:00
wash 90d180d839 meta: update clang-format config 2026-05-03 14:50:50 +01:00
wash a0283da135 build: fix namespace build macro 2026-05-03 14:47:59 +01:00
wash 7b42a023e4 runtime: add assembly system to collect and export type definitions 2026-05-03 13:11:22 +01:00
wash 7d78d7d314 meta: update clang-format config 2026-05-03 13:10:36 +01:00
wash 4f40bfd9a0 fx.collections: move string to fx 2026-05-02 21:07:00 +01:00
wash a339b6e01a build: use dots instead of hyphens in library names 2026-05-02 21:03:46 +01:00
wash 604ddfcebf build: build fx and fx.collections assemblies 2026-05-02 21:02:10 +01:00
wash c78ea4bfa6 fx.collections: update header directories 2026-05-02 21:01:51 +01:00
wash b951577f48 fx: update header directories 2026-05-02 21:01:17 +01:00
wash 5d1b2aabbb build: update template for building assemblies 2026-05-02 21:00:59 +01:00
wash a65eb5c161 meta: rename compress module to fx.compression namespace 2026-05-02 14:38:31 +01:00
wash 9b8c0f8763 meta: rename ds module to fx.collections namespace 2026-05-02 14:38:11 +01:00
wash c04c2e8f12 meta: rename serial module to fx.serial namespace 2026-05-02 14:37:56 +01:00
wash b8cf2b379b meta: rename term module to fx.term namespace 2026-05-02 14:37:43 +01:00
wash 274a48a845 meta: rename io module to fx.io namespace 2026-05-02 14:37:29 +01:00
wash 47feee7b1a meta: rename cmd module to fx.cmdline namespace 2026-05-02 14:37:15 +01:00
wash 7db5fefe25 meta: rename core module to fx namespace 2026-05-02 14:36:59 +01:00
192 changed files with 4635 additions and 2245 deletions
+6 -64
View File
@@ -1,64 +1,6 @@
BasedOnStyle: WebKit BasedOnStyle: WebKit
IndentWidth: 8 IndentWidth: 8
--- ---
Language: C
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: OnePerLine
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 999999999
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- FX_API
ForEachMacros:
- fx_btree_foreach
- fx_queue_foreach
MacroBlockBegin: "FX_TYPE_.*_BEGIN"
MacroBlockEnd: "FX_TYPE_.*_END"
---
Language: ObjC Language: ObjC
DerivePointerAlignment: false DerivePointerAlignment: false
PointerAlignment: Right PointerAlignment: Right
@@ -85,7 +27,7 @@ AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false BinPackArguments: false
BinPackParameters: true BinPackParameters: false
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both BitFieldColonSpacing: Both
BreakBeforeBraces: Linux BreakBeforeBraces: Linux
@@ -114,8 +56,8 @@ AttributeMacros:
ForEachMacros: ForEachMacros:
- fx_btree_foreach - fx_btree_foreach
- fx_queue_foreach - fx_queue_foreach
MacroBlockBegin: "FX_TYPE_.*_BEGIN" MacroBlockBegin: "FX_(TYPE|ASSEMBLY)_.*_BEGIN"
MacroBlockEnd: "FX_TYPE_.*_END" MacroBlockEnd: "FX_(TYPE|ASSEMBLY)_.*_END"
--- ---
Language: Cpp Language: Cpp
DerivePointerAlignment: false DerivePointerAlignment: false
@@ -143,7 +85,7 @@ AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false BinPackArguments: false
BinPackParameters: OnePerLine BinPackParameters: false
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both BitFieldColonSpacing: Both
BreakBeforeBraces: Linux BreakBeforeBraces: Linux
@@ -172,5 +114,5 @@ AttributeMacros:
ForEachMacros: ForEachMacros:
- fx_btree_foreach - fx_btree_foreach
- fx_queue_foreach - fx_queue_foreach
MacroBlockBegin: "FX_TYPE_.*_BEGIN" MacroBlockBegin: "FX_(TYPE|ASSEMBLY).*_BEGIN"
MacroBlockEnd: "FX_TYPE_.*_END" MacroBlockEnd: "FX_(TYPE|ASSEMBLY).*_END"
+15 -47
View File
@@ -9,8 +9,16 @@ set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if (NOT DEFINED fx_modules) file(GLOB _all_assemblies assemblies/*
set(fx_modules core ds serial term cmd io compress) LIST_DIRECTORIES TRUE)
foreach (assembly_path ${_all_assemblies})
get_filename_component(assembly_name ${assembly_path} NAME)
set(fx_all_assemblies ${fx_all_assemblies} ${assembly_name})
endforeach (assembly_path)
if (NOT DEFINED fx_assemblies)
set(fx_assemblies ${fx_all_assemblies})
endif () endif ()
if (NOT DEFINED fx_enable_floating_point) if (NOT DEFINED fx_enable_floating_point)
@@ -32,50 +40,10 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
foreach (module ${fx_modules}) include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Templates.cmake)
add_subdirectory(${module})
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module})
message(STATUS "Building unit tests for module ${module}")
if (fx_enable_tests AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c) foreach (assembly ${fx_assemblies})
add_executable(fx-${module}-units add_subdirectory(assemblies/${assembly})
test/${module}/${module}-units.c endforeach (assembly)
misc/AllTests.c
misc/CuTest.c
misc/CuTest.h)
target_link_libraries(fx-${module}-units fx-${module})
target_include_directories(fx-${module}-units PRIVATE misc/)
set_target_properties(fx-${module}-units PROPERTIES FOLDER "Tests/${module}")
endif ()
file(GLOB test_sources test/${module}/*.c) add_executable(dynamic-test test/dynamic-test.c)
list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c")
if (fx_enable_tests)
foreach (test_file ${test_sources})
get_filename_component(test_name ${test_file} NAME_WE)
add_executable(fx-${module}-${test_name} ${test_file})
set_target_properties(fx-${module}-${test_name} PROPERTIES FOLDER "Tests/${module}")
target_link_libraries(fx-${module}-${test_name} fx-${module})
endforeach (test_file)
endif ()
endif ()
endforeach (module)
if (fx_enable_tests)
file(GLOB test_sources test/*.c)
list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/units.c")
foreach (test_file ${test_sources})
get_filename_component(test_name ${test_file} NAME_WE)
add_executable(fx-${test_name} ${test_file})
set_target_properties(fx-${test_name} PROPERTIES FOLDER "Tests")
foreach (module ${fx_modules})
target_link_libraries(fx-${test_name} fx-${module})
endforeach (module)
endforeach (test_file)
endif ()
+7
View File
@@ -0,0 +1,7 @@
add_fx_assembly(
NAME fx.cmdline
NAMESPACES fx.cmdline
DEPENDENCIES
fx.runtime
fx.collections
fx.term)
+7
View File
@@ -0,0 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.cmdline");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
+4
View File
@@ -0,0 +1,4 @@
add_fx_assembly(
NAME fx.collections
NAMESPACES fx.collections
DEPENDENCIES fx.runtime)
+14
View File
@@ -0,0 +1,14 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.collections");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "array", fx_array);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "bitbuffer", fx_bitbuffer);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "bitmap", fx_bitmap);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "dict", fx_dict);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "hashmap", fx_hashmap);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "list", fx_list);
FX_ASSEMBLY_EXPORT_TYPE("fx.collections", "tree", fx_tree);
FX_ASSEMBLY_END()
+4
View File
@@ -0,0 +1,4 @@
add_fx_assembly(
NAME fx.compression
NAMESPACES fx.compression
DEPENDENCIES fx.runtime)
+7
View File
@@ -0,0 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.compression");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
+4
View File
@@ -0,0 +1,4 @@
add_fx_assembly(
NAME fx.io
NAMESPACES fx.io
DEPENDENCIES fx.runtime)
+7
View File
@@ -0,0 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.io");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
+3
View File
@@ -0,0 +1,3 @@
add_fx_assembly(
NAME fx.runtime
NAMESPACES fx fx.reflection)
+12
View File
@@ -0,0 +1,12 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.runtime");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_EXPORT_TYPE("fx", "stream", fx_stream);
FX_ASSEMBLY_EXPORT_TYPE("fx", "string", fx_string);
FX_ASSEMBLY_EXPORT_TYPE("fx", "stringstream", fx_stringstream);
FX_ASSEMBLY_EXPORT_TYPE("fx", "iterator", fx_iterator);
FX_ASSEMBLY_EXPORT_TYPE("fx.reflection", "assembly", fx_assembly);
FX_ASSEMBLY_END()
+4
View File
@@ -0,0 +1,4 @@
add_fx_assembly(
NAME fx.serial
NAMESPACES fx.serial
DEPENDENCIES fx.runtime fx.collections)
+7
View File
@@ -0,0 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.serial");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
+4
View File
@@ -0,0 +1,4 @@
add_fx_assembly(
NAME fx.term
NAMESPACES fx.term
DEPENDENCIES fx.runtime fx.collections)
+7
View File
@@ -0,0 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.term");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
+64 -77
View File
@@ -1,109 +1,96 @@
function(add_fx_module) function(add_fx_assembly)
set(options) set(options)
set(one_value_args NAME) set(one_value_args NAME)
set(multi_value_args set(multi_value_args
NAMESPACES
DEPENDENCIES DEPENDENCIES
SUBDIRS LIBS)
EXTRA_SOURCES
LIBS
INCLUDE_DIRS
DEFINES)
cmake_parse_arguments(PARSE_ARGV 0 arg cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}" "${options}"
"${one_value_args}" "${one_value_args}"
"${multi_value_args}") "${multi_value_args}")
set(module_name ${arg_NAME}) set(assembly_name ${arg_NAME})
string(REPLACE "." "/" assembly_path ${assembly_name})
set(assembly_target_name ${assembly_name})
string(REPLACE "." "_" assembly_token ${assembly_name})
string(TOUPPER ${assembly_token} assembly_token)
file(GLOB sources *.c *.h) set(assembly_include_paths "")
set(assembly_sources ${CMAKE_CURRENT_SOURCE_DIR}/assembly.c)
foreach (dir ${arg_SUBDIRS}) foreach (dir ${arg_NAMESPACES})
file(GLOB dir_sources ${dir}/*.c ${dir}/*.h) add_subdirectory(../../${dir} ../../namespaces/${dir})
set(sources ${sources} ${dir_sources}) set(assembly_sources ${assembly_sources} ${namespace_sources})
set(assembly_include_paths ${assembly_include_paths} ${namespace_include_paths})
endforeach (dir) endforeach (dir)
file(GLOB sys_sources sys/${fx_system_name}/*.c sys/${fx_system_name}/*.h) message(STATUS "Building assembly ${assembly_name}")
set(root_header include/fx/${module_name}.h) add_library(${assembly_target_name} SHARED
file(GLOB headers include/fx/${module_name}/*.h) ${assembly_sources})
string(REPLACE "-" "_" module_preproc_token ${module_name}) target_include_directories(${assembly_target_name} PUBLIC ${assembly_include_paths})
string(TOUPPER ${module_preproc_token} module_preproc_token)
set(module_preproc_token FX_${module_preproc_token})
message(STATUS "Building module ${module_name} (shared)") target_compile_definitions(${assembly_target_name} PUBLIC
add_library(fx-${module_name} SHARED
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
message(STATUS "Building module ${module_name} (static)")
add_library(fx-${module_name}-s STATIC
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
target_include_directories(fx-${module_name} PUBLIC include/)
target_include_directories(fx-${module_name}-s PUBLIC include/)
target_compile_definitions(fx-${module_name} PUBLIC
${module_preproc_token}
FX_EXPORT=1 FX_EXPORT=1
FX_ENABLE_FLOATING_POINT=${fx_enable_floating_point}) FX_ENABLE_FLOATING_POINT=${fx_enable_floating_point})
target_compile_definitions(fx-${module_name}-s PUBLIC
${module_preproc_token}
FX_EXPORT=1
FX_STATIC=1
FX_ENABLE_FLOATING_POINT=${fx_enable_floating_point})
set_target_properties(fx-${module_name} set_target_properties(${assembly_target_name}
PROPERTIES POSITION_INDEPENDENT_CODE ON) PROPERTIES POSITION_INDEPENDENT_CODE ON)
foreach (dep ${arg_DEPENDENCIES}) target_link_libraries(${assembly_target_name} ${internal_libs} ${arg_DEPENDENCIES})
target_link_libraries(fx-${module_name} fx-${dep}) target_include_directories(${assembly_target_name} PRIVATE ${internal_include_dirs})
target_link_libraries(fx-${module_name}-s fx-${dep}-s)
endforeach (dep)
foreach (lib ${arg_LIBS})
target_link_libraries(fx-${module_name} ${lib})
target_link_libraries(fx-${module_name}-s ${lib})
endforeach (lib)
foreach (dir ${arg_INCLUDE_DIRS})
target_include_directories(fx-${module_name} PRIVATE
${dir})
target_include_directories(fx-${module_name}-s PRIVATE
${dir})
endforeach (dir)
foreach (def ${arg_DEFINES}) foreach (def ${arg_DEFINES})
target_compile_definitions(fx-${module_name} PRIVATE target_compile_definitions(${assembly_target_name} PRIVATE ${def})
${def})
target_compile_definitions(fx-${module_name}-s PRIVATE
${def})
endforeach (def) endforeach (def)
set_target_properties(fx-${module_name} PROPERTIES set_target_properties(${assembly_target_name} PROPERTIES
FOLDER "Shared/${module_name}") FOLDER "${assembly_name}")
set_target_properties(fx-${module_name}-s PROPERTIES
FOLDER "Static/${module_name}")
TEST_BIG_ENDIAN(IS_BIG_ENDIAN) TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN) if(IS_BIG_ENDIAN)
target_compile_definitions(fx-${module_name} PRIVATE target_compile_definitions(${assembly_target_name} PRIVATE
BIG_ENDIAN)
target_compile_definitions(fx-${module_name}-s PRIVATE
BIG_ENDIAN) BIG_ENDIAN)
else() else()
target_compile_definitions(fx-${module_name} PRIVATE target_compile_definitions(${assembly_target_name} PRIVATE
LITTLE_ENDIAN)
target_compile_definitions(fx-${module_name}-s PRIVATE
LITTLE_ENDIAN) LITTLE_ENDIAN)
endif() endif()
install(TARGETS fx-${module_name} fx-${module_name}-s) install(TARGETS ${assembly_target_name})
install(FILES ${root_header} DESTINATION include/fx) install(FILES ${headers} DESTINATION include/${assembly_path})
install(FILES ${headers} DESTINATION include/fx/${module_name}) endfunction(add_fx_assembly)
endfunction(add_fx_module)
macro(export_fx_namespace_details ns_name)
set(namespace_name ${ns_name})
string(REPLACE "." "/" namespace_path ${namespace_name})
set(namespace_target_name ${namespace_name})
set(namespace_include_paths ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
file(GLOB base_namespace_sources
*.c *.h
${CMAKE_CURRENT_SOURCE_DIR}/include/${namespace_path}/*.h)
foreach (dir ${source_dirs})
file(GLOB dir_sources ${dir}/*.c ${dir}/*.h)
set(dir_namespace_sources ${dir_namespace_sources} ${dir_sources})
endforeach (dir)
file(GLOB sys_sources
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/*.h)
file(GLOB headers include/${namespace_path}/*.h)
set(namespace_sources
${namespace_sources}
${base_namespace_sources}
${dir_namespace_sources}
${sys_sources}
${headers}
PARENT_SCOPE)
set(internal_libs ${internal_libs} PARENT_SCOPE)
set(internal_include_dirs ${internal_include_dirs} PARENT_SCOPE)
set(internal_defines ${internal_defines} PARENT_SCOPE)
endmacro(export_fx_namespace_details)
-3
View File
@@ -1,3 +0,0 @@
include(../cmake/Templates.cmake)
add_fx_module(NAME cmd DEPENDENCIES core ds term)
-19
View File
@@ -1,19 +0,0 @@
include(../cmake/Templates.cmake)
find_package(ZSTD)
if (ZSTD_FOUND)
set(libs ${libs} ${ZSTD_LIBRARY})
set(include_dirs ${include_dirs} ${ZSTD_INCLUDE_DIR})
set(function_sources ${function_sources} ${CMAKE_CURRENT_SOURCE_DIR}/function/zstd.c)
set(defines ${defines} FX_COMPRESSOR_SUPPORTED_ZSTD)
message(STATUS "Enabling ZSTD support in fx-compress")
endif ()
add_fx_module(
NAME compress
DEPENDENCIES core
EXTRA_SOURCES ${function_sources}
DEFINES ${defines}
LIBS ${libs}
INCLUDE_DIRS ${include_dirs})
View File
-5
View File
@@ -1,5 +0,0 @@
include(../cmake/Templates.cmake)
add_fx_module(
NAME core
SUBDIRS hash)
View File
-418
View File
@@ -1,418 +0,0 @@
#ifndef FX_CORE_ERROR_H_
#define FX_CORE_ERROR_H_
#include <fx/core/misc.h>
#include <fx/core/status.h>
#include <stdarg.h>
#include <stdbool.h>
#define FX_ERROR_TEMPLATE_PARAMETER_MAX 4
#define FX_ERROR_MSG_ID_INVALID ((unsigned long)-1)
#define FX_CATCH(err, expr) ((err = (expr)) != NULL)
#define fx_result_is_error(result) ((result) != NULL)
#define fx_result_is_success(result) ((result) == NULL)
#define FX_RESULT_SUCCESS ((fx_result)NULL)
#define FX_RESULT_ERR(err_name) \
fx_error_with_code(fx_error_vendor_get_builtin(), FX_ERR_##err_name)
#define FX_RESULT_ERR_WITH_STRING(err_name, ...) \
fx_error_with_string( \
fx_error_vendor_get_builtin(), FX_ERR_##err_name, __VA_ARGS__)
#define FX_RESULT_STATUS(code) \
((code) == FX_SUCCESS \
? FX_RESULT_SUCCESS \
: (fx_error_with_code(fx_error_vendor_get_builtin(), code)))
#define FX_RESULT_STATUS_WITH_STRING(code, ...) \
((code) == FX_SUCCESS \
? FX_RESULT_SUCCESS \
: (fx_error_with_string( \
fx_error_vendor_get_builtin(), code, __VA_ARGS__)))
#define FX_ERRORS_BUILTIN (fx_error_vendor_get_builtin())
#define FX_ERRORS_ERRNO (fx_error_vendor_get_errno())
#define FX_ERROR_PARAM(name, value) \
(fx_error_template_parameter) \
{ \
.param_name = (name), .param_value = (uintptr_t)(value), \
}
#define FX_ERROR_TEMPLATE_PARAM(name, type, format) \
(fx_error_template_parameter_definition) \
{ \
.param_name = (name), .param_type = (type), \
.param_format = (format), \
}
#define FX_ERROR_DEFINITION(code, name, msg) \
[code] = (fx_error_definition) \
{ \
.err_name = (name), .err_message = (msg), \
}
#define FX_ERROR_DEFINITION_TEMPLATE(code, name, msg, ...) \
[code] = (fx_error_definition) \
{ \
.err_name = (name), .err_message = (msg), \
.err_params = __VA_ARGS__, \
}
#define FX_ERROR_MSG(id, content) \
[id] = (fx_error_msg) \
{ \
.msg_message = (content), \
}
#define FX_ERROR_MSG_TEMPLATE(id, content, ...) \
[id] = (fx_error_msg) \
{ \
.msg_message = (content), .msg_params = __VA_ARGS__, \
}
#define z__fx_error_create_status(status_code) \
(z__fx_error_create( \
fx_error_vendor_get_builtin(), status_code, NULL, NULL, 0, \
NULL, NULL))
/* Error creation macros */
#define fx_error_with_code(vendor, code) \
(z__fx_error_create( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, NULL))
#define fx_error_caused_by_error(vendor, code, cause_error) \
(z__fx_error_create( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, NULL))
#define fx_error_caused_by_status(vendor, code, cause_status) \
(z__fx_error_create( \
vendor, code, z__fx_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, NULL))
#define fx_error_caused_by_code(vendor, code, cause_vendor, cause_code) \
(z__fx_error_create( \
vendor, code, fx_error_with_code(cause_vendor, cause_code), \
__FILE__, __LINE__, __FUNCTION__, NULL))
#define fx_error_with_string(vendor, code, ...) \
(z__fx_error_create( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#define fx_error_with_string_caused_by_error(vendor, code, cause_error, ...) \
(z__fx_error_create( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
__VA_ARGS__))
#define fx_error_with_string_caused_by_status(vendor, code, cause_status, ...) \
(z__fx_error_create( \
vendor, code, z__fx_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#define fx_error_with_msg(vendor, code, msg_id) \
(z__fx_error_create_msg( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, msg_id, \
(fx_error_template_parameter[]) {{}}))
#define fx_error_with_msg_caused_by_error(vendor, code, cause_error, msg_id) \
(z__fx_error_create_msg( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
msg_id, (fx_error_template_parameter[]) {{}}))
#define fx_error_with_msg_caused_by_status(vendor, code, cause_status, msg_id) \
(z__fx_error_create_msg( \
vendor, code, z__fx_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, msg_id, \
(fx_error_template_parameter[]) {{}}))
#define fx_error_with_msg_template(vendor, code, msg_id, ...) \
(z__fx_error_create_msg( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, msg_id, \
(fx_error_template_parameter[]) {__VA_ARGS__, {}}))
#define fx_error_with_msg_template_caused_by_error( \
vendor, code, cause_error, msg_id, ...) \
(z__fx_error_create_msg( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
msg_id, (fx_error_template_parameter[]) {__VA_ARGS__, {}}))
#define fx_error_with_msg_template_caused_by_status( \
vendor, code, cause_status, msg_id, ...) \
(z__fx_error_create_msg( \
vendor, code, z__fx_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, msg_id, \
(fx_error_template_parameter[]) {__VA_ARGS__, {}}))
#define fx_error_with_template(vendor, code, ...) \
(z__fx_error_create_template( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, \
(fx_error_template_parameter[]) {__VA_ARGS__, {}}))
#define fx_error_with_template_caused_by_error(vendor, code, cause_error, ...) \
(z__fx_error_create_template( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
(fx_error_template_parameter[]) {__VA_ARGS__, {}}))
#define fx_error_with_template_caused_by_status(vendor, code, cause_status, ...) \
(z__fx_error_create_template( \
vendor, code, z__fx_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, \
(fx_error_template_parameter[]) {__VA_ARGS__, {}}))
/* Error propagation macros */
#define fx_result_propagate(err) \
(z__fx_error_propagate(err, __FILE__, __LINE__, __FUNCTION__))
#define fx_error_caused_by(err, caused_by) (z__fx_error_caused_by(err, caused_by))
#define fx_error_caused_by_fx_status(err, status) \
(z__fx_error_caused_by_fx_status(err, status))
#define fx_error_replace(err, caused_by) \
(z__fx_error_propagate(err, __FILE__, __LINE__, __FUNCTION__))
/* Error throw macros */
#define z__fx_throw(err) (z__fx_error_throw(err, NULL, 0, NULL))
#define fx_throw(err) (z__fx_error_throw(err, __FILE__, __LINE__, __FUNCTION__))
#define fx_throw_status(status) \
(z__fx_error_throw( \
z__fx_error_create( \
fx_error_vendor_get_builtin(), status, NULL, NULL, 0, \
NULL, NULL), \
__FILE__, __LINE__, __FUNCTION__))
#define fx_throw_status_string(status, ...) \
(z__fx_error_throw( \
z__fx_error_create( \
fx_error_vendor_get_builtin(), status, NULL, NULL, 0, \
NULL, __VA_ARGS__), \
__FILE__, __LINE__, __FUNCTION__))
#define fx_throw_error_code(vendor, code) \
z__fx_throw(fx_error_with_code(vendor, code))
#define fx_throw_error_caused_by_error(vendor, code, cause) \
z__fx_throw(fx_error_caused_by_error(vendor, code, cause))
#define fx_throw_error_caused_by_status(vendor, code, cause) \
z__fx_throw(fx_error_caused_by_status(vendor, code, cause))
#define fx_throw_error_with_string(vendor, code, ...) \
z__fx_throw(fx_error_with_string(vendor, code, __VA_ARGS__))
#define fx_throw_error_with_string_caused_by_error(vendor, code, cause, ...) \
z__fx_throw(fx_error_with_string_caused_by_error( \
vendor, code, cause, __VA_ARGS__))
#define fx_throw_error_with_string_caused_by_status(vendor, code, cause, ...) \
z__fx_throw(fx_error_with_string_caused_by_status( \
vendor, code, cause, __VA_ARGS__))
#define fx_throw_error_with_msg(vendor, code, msg_id) \
z__fx_throw(fx_error_with_msg(vendor, code, msg_id))
#define fx_throw_error_with_msg_caused_by_error(vendor, code, cause, msg_id) \
z__fx_throw(fx_error_with_msg_caused_by_error(vendor, code, cause, msg_id))
#define fx_throw_error_with_msg_caused_by_status(vendor, code, cause, msg_id) \
z__fx_throw(fx_error_with_msg_caused_by_status(vendor, code, cause, msg_id))
#define fx_throw_error_with_msg_template(vendor, code, msg_id, ...) \
z__fx_throw(fx_error_with_msg_template(vendor, code, msg_id, __VA_ARGS__))
#define fx_throw_error_with_msg_template_caused_by_error( \
vendor, code, cause, msg_id, ...) \
z__fx_throw(fx_error_with_msg_template_caused_by_error( \
vendor, code, cause, msg_id, __VA_ARGS__))
#define fx_throw_error_with_msg_template_caused_by_status( \
vendor, code, cause, msg_id, ...) \
z__fx_throw(fx_error_with_msg_template_caused_by_status( \
vendor, code, cause, msg_id, __VA_ARGS__))
#define fx_throw_error_with_template(vendor, code, ...) \
z__fx_throw(fx_error_with_template(vendor, code, __VA_ARGS__))
#define fx_throw_error_with_template_caused_by_error(vendor, code, cause, ...) \
z__fx_throw(fx_error_with_template_caused_by_error( \
vendor, code, cause, __VA_ARGS__))
#define fx_throw_error_with_template_caused_by_status(vendor, code, cause, ...) \
z__fx_throw(fx_error_with_template_caused_by_status( \
vendor, code, cause, __VA_ARGS__))
#define FX_ERR_MSG(s) \
{ \
.msg_type = FX_ERROR_MESSAGE_ERROR, \
.msg_content = (s), \
}
#define FX_ERR_MSG_WARN(s) \
{ \
.msg_type = FX_ERROR_MESSAGE_WARN, \
.msg_content = (s), \
}
#define FX_ERR_MSG_INFO(s) \
{ \
.msg_type = FX_ERROR_MESSAGE_INFO, \
.msg_content = (s), \
}
#define FX_ERR_MSG_END(s) \
{ \
.msg_type = FX_ERROR_MESSAGE_NONE, \
.msg_content = NULL, \
}
typedef enum fx_error_submsg_type {
FX_ERROR_SUBMSG_NONE = 0,
FX_ERROR_SUBMSG_ERROR,
FX_ERROR_SUBMSG_WARNING,
FX_ERROR_SUBMSG_INFO,
} fx_error_submsg_type;
typedef enum fx_error_report_flags {
FX_ERROR_REPORT_NONE = 0,
FX_ERROR_REPORT_STATUS = 0x01u,
FX_ERROR_REPORT_DESCRIPTION = 0x02u,
FX_ERROR_REPORT_SUBMSG = 0x04u,
FX_ERROR_REPORT_STACK_TRACE = 0x08u,
FX_ERROR_REPORT_CAUSE = 0x10u,
FX_ERROR_REPORT_MINIMAL = FX_ERROR_REPORT_STATUS | FX_ERROR_REPORT_DESCRIPTION,
FX_ERROR_REPORT_DEFAULT = FX_ERROR_REPORT_MINIMAL | FX_ERROR_REPORT_SUBMSG
| FX_ERROR_REPORT_CAUSE,
FX_ERROR_REPORT_ALL = FX_ERROR_REPORT_DEFAULT | FX_ERROR_REPORT_STACK_TRACE,
} fx_error_report_flags;
typedef enum fx_error_template_parameter_type {
FX_ERROR_TEMPLATE_PARAM_NONE = 0,
FX_ERROR_TEMPLATE_PARAM_STRING,
FX_ERROR_TEMPLATE_PARAM_CHAR,
FX_ERROR_TEMPLATE_PARAM_INT,
FX_ERROR_TEMPLATE_PARAM_UINT,
FX_ERROR_TEMPLATE_PARAM_LONG,
FX_ERROR_TEMPLATE_PARAM_ULONG,
FX_ERROR_TEMPLATE_PARAM_LONGLONG,
FX_ERROR_TEMPLATE_PARAM_ULONGLONG,
FX_ERROR_TEMPLATE_PARAM_SIZE_T,
FX_ERROR_TEMPLATE_PARAM_INTPTR,
FX_ERROR_TEMPLATE_PARAM_UINTPTR,
FX_ERROR_TEMPLATE_PARAM_PTR,
} fx_error_template_parameter_type;
typedef struct fx_error_template_parameter_definition {
const char *param_name;
fx_error_template_parameter_type param_type;
const char *param_format;
} fx_error_template_parameter_definition;
typedef struct fx_error_template_parameter {
const char *param_name;
uintptr_t param_value;
const struct fx_error_template_parameter_definition *__param_def;
} fx_error_template_parameter;
struct fx_error_vendor;
typedef struct fx_error fx_error;
typedef struct fx_error *fx_result;
typedef struct fx_error_submsg fx_error_submsg;
typedef struct fx_error_stack_frame fx_error_stack_frame;
typedef long fx_error_status_code;
typedef unsigned long fx_error_msg_id;
typedef struct fx_error_definition {
const char *err_name;
const char *err_message;
const fx_error_template_parameter_definition err_params[FX_ERROR_TEMPLATE_PARAMETER_MAX];
} fx_error_definition;
typedef struct fx_error_msg {
const char *msg_message;
const fx_error_template_parameter_definition msg_params[FX_ERROR_TEMPLATE_PARAMETER_MAX];
} fx_error_msg;
typedef const fx_error_definition *(*fx_error_status_code_get_definition)(
const struct fx_error_vendor *, fx_error_status_code);
typedef const fx_error_msg *(*fx_error_msg_get_definition)(
const struct fx_error_vendor *, fx_error_msg_id);
typedef void (*fx_error_report_function)(
const struct fx_error *, fx_error_report_flags);
typedef struct fx_error_vendor {
const char *v_name;
fx_error_status_code_get_definition v_status_get_definition;
fx_error_msg_get_definition v_msg_get_definition;
const fx_error_definition *v_error_definitions;
size_t v_error_definitions_length;
const fx_error_msg *v_msg;
size_t v_msg_length;
} fx_error_vendor;
FX_API fx_error *z__fx_error_create_template(
const fx_error_vendor *, fx_error_status_code, fx_error *, const char *,
unsigned int, const char *, const fx_error_template_parameter[]);
FX_API fx_error *z__fx_error_create_string(
const fx_error_vendor *, fx_error_status_code, fx_error *, const char *,
unsigned int, const char *, const char *, va_list);
FX_API fx_error *z__fx_error_create_msg(
const fx_error_vendor *, fx_error_status_code, fx_error *, const char *,
unsigned int, const char *, fx_error_msg_id,
const fx_error_template_parameter[]);
FX_API fx_error *z__fx_error_propagate(
fx_error *, const char *, unsigned int, const char *);
FX_API fx_error *z__fx_error_caused_by(fx_error *, fx_error *);
FX_API fx_error *z__fx_error_caused_by_fx_status(fx_error *, fx_status);
FX_API void z__fx_error_throw(fx_error *, const char *, unsigned int, const char *);
FX_API bool fx_result_is(
fx_result result, const fx_error_vendor *vendor, fx_error_status_code code);
FX_API const fx_error_vendor *fx_error_vendor_get_builtin(void);
FX_API const fx_error_vendor *fx_error_vendor_get_errno(void);
FX_API const fx_error_definition *fx_error_vendor_get_error_definition(
const fx_error_vendor *vendor, fx_error_status_code code);
FX_API const char *fx_error_vendor_get_status_code_name(
const fx_error_vendor *vendor, fx_error_status_code code);
FX_API const char *fx_error_vendor_get_status_code_description(
const fx_error_vendor *vendor, fx_error_status_code code);
FX_API const fx_error_msg *fx_error_vendor_get_msg(
const fx_error_vendor *vendor, fx_error_msg_id msg_id);
static inline fx_error *z__fx_error_create(
const fx_error_vendor *v, fx_error_status_code c, fx_error *c2,
const char *f0, unsigned int l, const char *f1, const char *d, ...)
{
va_list arg;
va_start(arg, d);
fx_error *err = z__fx_error_create_string(v, c, c2, f0, l, f1, d, arg);
va_end(arg);
return err;
}
FX_API enum fx_status fx_error_add_submsg_string(
fx_error *error, fx_error_submsg_type type, const char *msg, ...);
FX_API enum fx_status z__fx_error_add_submsg_template(
fx_error *error, fx_error_submsg_type type, fx_error_msg_id msg_id,
fx_error_template_parameter param[]);
#define fx_error_add_submsg(error, type, msg_id) \
(z__fx_error_add_submsg_template( \
error, type, msg_id, (fx_error_template_parameter[]) {{}}))
#define fx_error_add_submsg_template(error, type, msg_id, ...) \
(z__fx_error_add_submsg_template( \
error, type, msg_id, \
(fx_error_template_parameter[]) {__VA_ARGS__, {}}))
FX_API void fx_error_discard(fx_error *error);
FX_API fx_error_status_code fx_error_get_status_code(const fx_error *error);
FX_API const fx_error_vendor *fx_error_get_vendor(const fx_error *error);
FX_API const fx_error_definition *fx_error_get_definition(const fx_error *error);
FX_API const fx_error_template_parameter *fx_error_get_template_parameter(
const fx_error *error, const char *param_name);
FX_API const fx_error_template_parameter *fx_error_get_template_parameters(
const fx_error *error);
FX_API const char *fx_error_get_description(const fx_error *error);
FX_API const fx_error_msg *fx_error_get_msg(const fx_error *error);
FX_API const fx_error_submsg *fx_error_get_first_submsg(const fx_error *error);
FX_API const fx_error_submsg *fx_error_get_next_submsg(
const fx_error *error, const fx_error_submsg *msg);
FX_API const fx_error_stack_frame *fx_error_get_first_stack_frame(
const fx_error *error);
FX_API const fx_error_stack_frame *fx_error_get_next_stack_frame(
const fx_error *error, const fx_error_stack_frame *frame);
FX_API const fx_error *fx_error_get_caused_by(const fx_error *error);
FX_API fx_error_submsg_type fx_error_submsg_get_type(const fx_error_submsg *msg);
FX_API const char *fx_error_submsg_get_content(const fx_error_submsg *msg);
FX_API const fx_error_msg *fx_error_submsg_get_msg(const fx_error_submsg *msg);
FX_API const fx_error_template_parameter *fx_error_submsg_get_template_parameters(
const fx_error_submsg *msg);
FX_API const char *fx_error_stack_frame_get_filepath(
const fx_error_stack_frame *frame);
FX_API unsigned int fx_error_stack_frame_get_line_number(
const fx_error_stack_frame *frame);
FX_API const char *fx_error_stack_frame_get_function_name(
const fx_error_stack_frame *frame);
FX_API const fx_error_template_parameter_definition *fx_error_definition_get_template_parameter(
const fx_error_definition *error_def, const char *param_name);
FX_API const char *fx_error_msg_get_content(const fx_error_msg *msg);
FX_API const fx_error_template_parameter_definition *fx_error_msg_get_template_parameter(
const fx_error_msg *msg, const char *param_name);
FX_API void fx_set_error_report_function(
fx_error_report_function func, fx_error_report_flags flags);
#endif
-3
View File
@@ -1,3 +0,0 @@
include(../cmake/Templates.cmake)
add_fx_module(NAME ds DEPENDENCIES core)
View File
+1
View File
@@ -0,0 +1 @@
export_fx_namespace_details(fx.cmdline)
+20 -8
View File
@@ -1,7 +1,7 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -54,7 +54,8 @@ fx_status fx_command_arg_set_name(struct fx_command_arg *arg, const char *name)
} }
fx_status fx_command_arg_set_description( fx_status fx_command_arg_set_description(
struct fx_command_arg *arg, const char *description) struct fx_command_arg *arg,
const char *description)
{ {
char *desc = fx_strdup(description); char *desc = fx_strdup(description);
if (!desc) { if (!desc) {
@@ -71,14 +72,16 @@ fx_status fx_command_arg_set_description(
} }
fx_status fx_command_arg_set_nr_values( fx_status fx_command_arg_set_nr_values(
struct fx_command_arg *arg, enum fx_command_arg_value_count nr_values) struct fx_command_arg *arg,
enum fx_command_arg_value_count nr_values)
{ {
arg->arg_nr_values = nr_values; arg->arg_nr_values = nr_values;
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_arg_set_allowed_values( fx_status fx_command_arg_set_allowed_values(
struct fx_command_arg *arg, const char **allowed_values) struct fx_command_arg *arg,
const char **allowed_values)
{ {
size_t count; size_t count;
for (count = 0; allowed_values[count]; count++) for (count = 0; allowed_values[count]; count++)
@@ -102,7 +105,10 @@ fx_status fx_command_arg_set_allowed_values(
return FX_SUCCESS; return FX_SUCCESS;
} }
void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_string *out) void z__fx_get_arg_usage_string(
struct fx_command_arg *arg,
bool colour,
fx_string *out)
{ {
bool optional = false, multi = false; bool optional = false, multi = false;
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
@@ -126,10 +132,14 @@ void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_stri
if (optional) { if (optional) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, colour ? F_GREEN "[[%s]" : "[[%s]", arg->arg_name); out,
colour ? F_GREEN "[[%s]" : "[[%s]",
arg->arg_name);
} else { } else {
fx_string_append_cstrf( fx_string_append_cstrf(
out, colour ? F_GREEN "<%s>" : "<%s>", arg->arg_name); out,
colour ? F_GREEN "<%s>" : "<%s>",
arg->arg_name);
} }
for (int i = 1; i < arg->arg_nr_values; i++) { for (int i = 1; i < arg->arg_nr_values; i++) {
@@ -167,7 +177,9 @@ void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, " " F_GREEN "%s" F_RESET, arg->arg_allowed_values[i]); out,
" " F_GREEN "%s" F_RESET,
arg->arg_allowed_values[i]);
} }
fx_string_append_cstr(out, "]"); fx_string_append_cstr(out, "]");
+133 -53
View File
@@ -1,8 +1,8 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <fx/term/print.h> #include <fx/term/print.h>
#include <fx/term/tty.h> #include <fx/term/tty.h>
#include <stdarg.h> #include <stdarg.h>
@@ -11,14 +11,28 @@
#include <string.h> #include <string.h>
FX_BST_DEFINE_SIMPLE_INSERT( FX_BST_DEFINE_SIMPLE_INSERT(
struct fx_arglist_option, opt_node, opt_id, put_arglist_option) struct fx_arglist_option,
opt_node,
opt_id,
put_arglist_option)
FX_BST_DEFINE_SIMPLE_GET( FX_BST_DEFINE_SIMPLE_GET(
struct fx_arglist_option, unsigned int, opt_node, opt_id, get_arglist_option) struct fx_arglist_option,
unsigned int,
opt_node,
opt_id,
get_arglist_option)
FX_BST_DEFINE_SIMPLE_INSERT( FX_BST_DEFINE_SIMPLE_INSERT(
struct fx_arglist_value, val_node, val_id, put_arglist_value) struct fx_arglist_value,
val_node,
val_id,
put_arglist_value)
FX_BST_DEFINE_SIMPLE_GET( FX_BST_DEFINE_SIMPLE_GET(
struct fx_arglist_value, unsigned int, val_node, val_id, get_arglist_value) struct fx_arglist_value,
unsigned int,
val_node,
val_id,
get_arglist_value)
struct argv_parser { struct argv_parser {
struct fx_command *cmd; struct fx_command *cmd;
@@ -62,7 +76,9 @@ struct fx_arglist *fx_arglist_create(void)
return out; return out;
} }
static void move_to_subcommand(struct argv_parser *parser, struct fx_command *cmd) static void move_to_subcommand(
struct argv_parser *parser,
struct fx_command *cmd)
{ {
parser->cmd = cmd; parser->cmd = cmd;
parser->arglist->list_command = cmd; parser->arglist->list_command = cmd;
@@ -86,10 +102,13 @@ static fx_status set_opt(struct fx_arglist *args, struct fx_command_option *opt)
} }
static fx_status put_arg( static fx_status put_arg(
struct fx_arglist *args, struct fx_command_arg *arg, const char *value) struct fx_arglist *args,
struct fx_command_arg *arg,
const char *value)
{ {
struct fx_arglist_option *arglist_opt struct fx_arglist_option *arglist_opt = get_arglist_option(
= get_arglist_option(&args->list_options, FX_COMMAND_INVALID_ID); &args->list_options,
FX_COMMAND_INVALID_ID);
if (!arglist_opt) { if (!arglist_opt) {
arglist_opt = malloc(sizeof *arglist_opt); arglist_opt = malloc(sizeof *arglist_opt);
@@ -134,8 +153,10 @@ static fx_status put_arg(
} }
static fx_status put_opt_arg( static fx_status put_opt_arg(
struct fx_arglist_option *arglist_opt, struct fx_command_option *opt, struct fx_arglist_option *arglist_opt,
struct fx_command_arg *arg, const char *value) struct fx_command_option *opt,
struct fx_command_arg *arg,
const char *value)
{ {
if (arg->arg_allowed_values) { if (arg->arg_allowed_values) {
@@ -202,14 +223,18 @@ static fx_status check_required_args(struct argv_parser *parser)
} }
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, FX_COMMAND_INVALID_ID, arg->arg_id, parser->arglist,
FX_COMMAND_INVALID_ID,
arg->arg_id,
parser->nr_values_cur_arg); parser->nr_values_cur_arg);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
if (parser->nr_values_cur_arg != arg->arg_nr_values) { if (parser->nr_values_cur_arg != arg->arg_nr_values) {
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, FX_COMMAND_INVALID_ID, arg->arg_id, parser->arglist,
FX_COMMAND_INVALID_ID,
arg->arg_id,
parser->nr_values_cur_arg); parser->nr_values_cur_arg);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -225,8 +250,9 @@ static fx_status parse_arg(struct argv_parser *parser)
break; break;
} }
struct fx_command *subcmd struct fx_command *subcmd = fx_command_get_subcommand_with_name(
= fx_command_get_subcommand_with_name(parser->cmd, value); parser->cmd,
value);
if (subcmd) { if (subcmd) {
move_to_subcommand(parser, subcmd); move_to_subcommand(parser, subcmd);
parser->arglist->list_argv_last_command parser->arglist->list_argv_last_command
@@ -236,10 +262,14 @@ static fx_status parse_arg(struct argv_parser *parser)
} }
struct fx_command_arg *arg = fx_unbox( struct fx_command_arg *arg = fx_unbox(
struct fx_command_arg, parser->arg_it, arg_entry); struct fx_command_arg,
parser->arg_it,
arg_entry);
if (!arg) { if (!arg) {
fx_arglist_report_unexpected_arg(parser->arglist, value); fx_arglist_report_unexpected_arg(
parser->arglist,
value);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -249,8 +279,10 @@ static fx_status parse_arg(struct argv_parser *parser)
if (status == FX_ERR_INVALID_ARGUMENT) { if (status == FX_ERR_INVALID_ARGUMENT) {
fx_arglist_report_invalid_arg_value( fx_arglist_report_invalid_arg_value(
parser->arglist, FX_COMMAND_INVALID_ID, parser->arglist,
arg->arg_id, value); FX_COMMAND_INVALID_ID,
arg->arg_id,
value);
} }
if (FX_ERR(status)) { if (FX_ERR(status)) {
@@ -306,7 +338,8 @@ static fx_status parse_short_opt(struct argv_parser *parser)
opt = fx_command_get_option_with_short_name(parser->cmd, flag); opt = fx_command_get_option_with_short_name(parser->cmd, flag);
if (!opt) { if (!opt) {
subcmd = fx_command_get_subcommand_with_short_name( subcmd = fx_command_get_subcommand_with_short_name(
parser->cmd, flag); parser->cmd,
flag);
} }
if (subcmd) { if (subcmd) {
@@ -319,10 +352,13 @@ static fx_status parse_short_opt(struct argv_parser *parser)
if (!opt) { if (!opt) {
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
parser->cmd, NULL, parser->arglist); parser->cmd,
NULL,
parser->arglist);
fx_err("unrecognised argument '" F_YELLOW "-%c" F_RESET fx_err("unrecognised argument '" F_YELLOW "-%c" F_RESET
"'\n\n", "'\n\n",
flag, fx_string_get_cstr(usage)); flag,
fx_string_get_cstr(usage));
fx_i("usage: %s", fx_string_get_cstr(usage)); fx_i("usage: %s", fx_string_get_cstr(usage));
fx_i("for more information, use '" F_YELLOW fx_i("for more information, use '" F_YELLOW
"--help" F_RESET "'\n"); "--help" F_RESET "'\n");
@@ -382,8 +418,10 @@ static fx_status parse_short_opt(struct argv_parser *parser)
if (status == FX_ERR_INVALID_ARGUMENT) { if (status == FX_ERR_INVALID_ARGUMENT) {
fx_arglist_report_invalid_arg_value( fx_arglist_report_invalid_arg_value(
parser->arglist, FX_COMMAND_INVALID_ID, parser->arglist,
arg->arg_id, value); FX_COMMAND_INVALID_ID,
arg->arg_id,
value);
} }
if (FX_ERR(status)) { if (FX_ERR(status)) {
@@ -408,7 +446,9 @@ static fx_status parse_short_opt(struct argv_parser *parser)
} }
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -420,7 +460,9 @@ static fx_status parse_short_opt(struct argv_parser *parser)
if (!value) { if (!value) {
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -443,16 +485,20 @@ static fx_status parse_long_opt(struct argv_parser *parser)
opt = fx_command_get_option_with_long_name(parser->cmd, opt_name); opt = fx_command_get_option_with_long_name(parser->cmd, opt_name);
if (!opt) { if (!opt) {
subcmd = fx_command_get_subcommand_with_long_name( subcmd = fx_command_get_subcommand_with_long_name(
parser->cmd, opt_name); parser->cmd,
opt_name);
} }
if (!opt && !subcmd) { if (!opt && !subcmd) {
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
parser->cmd, NULL, parser->arglist); parser->cmd,
NULL,
parser->arglist);
fx_err("unrecognised argument '" F_YELLOW "--%s" F_RESET fx_err("unrecognised argument '" F_YELLOW "--%s" F_RESET
"'\n\nusage: %s\n\nfor more information, use '" F_YELLOW "'\n\nusage: %s\n\nfor more information, use '" F_YELLOW
"--help" F_RESET "'\n", "--help" F_RESET "'\n",
opt_name, fx_string_get_cstr(usage)); opt_name,
fx_string_get_cstr(usage));
fx_string_unref(usage); fx_string_unref(usage);
return FX_ERR_NO_ENTRY; return FX_ERR_NO_ENTRY;
@@ -504,8 +550,10 @@ static fx_status parse_long_opt(struct argv_parser *parser)
if (status == FX_ERR_INVALID_ARGUMENT) { if (status == FX_ERR_INVALID_ARGUMENT) {
fx_arglist_report_invalid_arg_value( fx_arglist_report_invalid_arg_value(
parser->arglist, FX_COMMAND_INVALID_ID, parser->arglist,
arg->arg_id, value); FX_COMMAND_INVALID_ID,
arg->arg_id,
value);
} }
if (FX_ERR(status)) { if (FX_ERR(status)) {
@@ -533,7 +581,9 @@ static fx_status parse_long_opt(struct argv_parser *parser)
} }
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -546,7 +596,9 @@ static fx_status parse_long_opt(struct argv_parser *parser)
if (!value) { if (!value) {
fx_arglist_report_missing_args( fx_arglist_report_missing_args(
parser->arglist, opt->opt_id, arg->arg_id, parser->arglist,
opt->opt_id,
arg->arg_id,
nr_args_cur_opt); nr_args_cur_opt);
return FX_ERR_BAD_FORMAT; return FX_ERR_BAD_FORMAT;
} }
@@ -580,7 +632,9 @@ static bool should_show_help(struct fx_command *cmd, struct fx_arglist *args)
} }
fx_status fx_arglist_parse( fx_status fx_arglist_parse(
struct fx_arglist *args, struct fx_command **cmd, int argc, struct fx_arglist *args,
struct fx_command **cmd,
int argc,
const char **argv) const char **argv)
{ {
struct argv_parser parser = { struct argv_parser parser = {
@@ -665,7 +719,9 @@ void fx_arglist_destroy(struct fx_arglist *args)
args_it = fx_bst_first(&opt->opt_values); args_it = fx_bst_first(&opt->opt_values);
while (args_it) { while (args_it) {
struct fx_arglist_value *val = fx_unbox( struct fx_arglist_value *val = fx_unbox(
struct fx_arglist_value, args_it, val_node); struct fx_arglist_value,
args_it,
val_node);
args_next = fx_bst_next(args_it); args_next = fx_bst_next(args_it);
if (val) { if (val) {
@@ -686,8 +742,11 @@ void fx_arglist_destroy(struct fx_arglist *args)
} }
fx_status fx_arglist_get_string( fx_status fx_arglist_get_string(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, const char **out) unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
const char **out)
{ {
fx_arglist_iterator it = {0}; fx_arglist_iterator it = {0};
fx_arglist_iterator_begin(args, opt_id, arg_id, &it); fx_arglist_iterator_begin(args, opt_id, arg_id, &it);
@@ -710,8 +769,11 @@ fx_status fx_arglist_get_string(
} }
fx_status fx_arglist_get_int( fx_status fx_arglist_get_int(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, long long *out) unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
long long *out)
{ {
fx_arglist_iterator it = {0}; fx_arglist_iterator it = {0};
fx_arglist_iterator_begin(args, opt_id, arg_id, &it); fx_arglist_iterator_begin(args, opt_id, arg_id, &it);
@@ -734,8 +796,11 @@ fx_status fx_arglist_get_int(
} }
fx_status fx_arglist_get_uint( fx_status fx_arglist_get_uint(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, unsigned long long *out) unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
unsigned long long *out)
{ {
fx_arglist_iterator it = {0}; fx_arglist_iterator it = {0};
fx_arglist_iterator_begin(args, opt_id, arg_id, &it); fx_arglist_iterator_begin(args, opt_id, arg_id, &it);
@@ -758,7 +823,9 @@ fx_status fx_arglist_get_uint(
} }
fx_status fx_arglist_get_option( fx_status fx_arglist_get_option(
const fx_arglist *args, unsigned int opt_id, unsigned int index, const fx_arglist *args,
unsigned int opt_id,
unsigned int index,
fx_arglist_option **out) fx_arglist_option **out)
{ {
struct fx_bst_node *node = fx_bst_first(&args->list_options); struct fx_bst_node *node = fx_bst_first(&args->list_options);
@@ -785,7 +852,9 @@ fx_status fx_arglist_get_option(
} }
size_t fx_arglist_get_count( size_t fx_arglist_get_count(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id) const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id)
{ {
size_t count = 0; size_t count = 0;
fx_arglist_iterator it; fx_arglist_iterator it;
@@ -799,12 +868,15 @@ size_t fx_arglist_get_count(
} }
fx_status fx_arglist_option_get_value( fx_status fx_arglist_option_get_value(
const fx_arglist_option *opt, unsigned int arg_id, unsigned int index, const fx_arglist_option *opt,
unsigned int arg_id,
unsigned int index,
fx_arglist_value **out) fx_arglist_value **out)
{ {
struct fx_bst_node *node = fx_bst_first(&opt->opt_values); struct fx_bst_node *node = fx_bst_first(&opt->opt_values);
while (node) { while (node) {
fx_arglist_value *cur = fx_unbox(fx_arglist_value, node, val_node); fx_arglist_value *cur
= fx_unbox(fx_arglist_value, node, val_node);
if (cur->val_id != arg_id) { if (cur->val_id != arg_id) {
node = fx_bst_next(node); node = fx_bst_next(node);
@@ -825,7 +897,8 @@ fx_status fx_arglist_option_get_value(
/************************ arglist iterator functions **************************/ /************************ arglist iterator functions **************************/
static struct fx_arglist_option *advance_to_next_opt(struct fx_arglist_iterator *it) static struct fx_arglist_option *advance_to_next_opt(
struct fx_arglist_iterator *it)
{ {
struct fx_arglist_option *opt; struct fx_arglist_option *opt;
@@ -846,7 +919,8 @@ static struct fx_arglist_option *advance_to_next_opt(struct fx_arglist_iterator
return NULL; return NULL;
} }
static struct fx_arglist_value *advance_to_next_arg(struct fx_arglist_iterator *it) static struct fx_arglist_value *advance_to_next_arg(
struct fx_arglist_iterator *it)
{ {
struct fx_arglist_value *val; struct fx_arglist_value *val;
@@ -868,8 +942,10 @@ static struct fx_arglist_value *advance_to_next_arg(struct fx_arglist_iterator *
} }
int fx_arglist_iterator_begin( int fx_arglist_iterator_begin(
const struct fx_arglist *args, unsigned int opt_filter, const struct fx_arglist *args,
unsigned int arg_filter, struct fx_arglist_iterator *it) unsigned int opt_filter,
unsigned int arg_filter,
struct fx_arglist_iterator *it)
{ {
memset(it, 0x0, sizeof *it); memset(it, 0x0, sizeof *it);
@@ -909,7 +985,9 @@ int fx_arglist_iterator_begin(
} }
val = fx_unbox( val = fx_unbox(
struct fx_arglist_value, it->_arg_it, val_node); struct fx_arglist_value,
it->_arg_it,
val_node);
if (!val if (!val
|| (arg_filter != val->val_id || (arg_filter != val->val_id
&& arg_filter != FX_COMMAND_INVALID_ID)) { && arg_filter != FX_COMMAND_INVALID_ID)) {
@@ -994,7 +1072,8 @@ static struct fx_arglist_option *advance_to_next_opt2(
} }
int fx_arglist_option_iterator_begin( int fx_arglist_option_iterator_begin(
const struct fx_arglist *args, unsigned int opt_filter, const struct fx_arglist *args,
unsigned int opt_filter,
struct fx_arglist_option_iterator *it) struct fx_arglist_option_iterator *it)
{ {
memset(it, 0x0, sizeof *it); memset(it, 0x0, sizeof *it);
@@ -1047,7 +1126,8 @@ bool fx_arglist_option_iterator_next(struct fx_arglist_option_iterator *it)
return true; return true;
} }
bool fx_arglist_option_iterator_is_valid(const struct fx_arglist_option_iterator *it) bool fx_arglist_option_iterator_is_valid(
const struct fx_arglist_option_iterator *it)
{ {
return it->opt_id != FX_COMMAND_INVALID_ID || it->opt != NULL; return it->opt_id != FX_COMMAND_INVALID_ID || it->opt != NULL;
} }
+136 -58
View File
@@ -1,8 +1,8 @@
#include "command.h" #include "command.h"
#include <fx/bst.h>
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/core/bst.h> #include <fx/string.h>
#include <fx/ds/string.h>
#include <fx/term/print.h> #include <fx/term/print.h>
#include <fx/term/tty.h> #include <fx/term/tty.h>
#include <stdio.h> #include <stdio.h>
@@ -13,7 +13,12 @@
static struct fx_bst command_list = {0}; static struct fx_bst command_list = {0};
FX_BST_DEFINE_SIMPLE_GET(struct fx_command, unsigned int, c_node, c_id, get_command) FX_BST_DEFINE_SIMPLE_GET(
struct fx_command,
unsigned int,
c_node,
c_id,
get_command)
FX_BST_DEFINE_SIMPLE_INSERT(struct fx_command, c_node, c_id, put_command) FX_BST_DEFINE_SIMPLE_INSERT(struct fx_command, c_node, c_id, put_command)
enum item_type { enum item_type {
@@ -26,7 +31,8 @@ static void command_list_cleanup(void)
{ {
struct fx_bst_node *node = fx_bst_first(&command_list); struct fx_bst_node *node = fx_bst_first(&command_list);
while (node) { while (node) {
struct fx_command *cmd = fx_unbox(struct fx_command, node, c_node); struct fx_command *cmd
= fx_unbox(struct fx_command, node, c_node);
if (!cmd) { if (!cmd) {
break; break;
} }
@@ -57,8 +63,10 @@ static void command_usage_destroy(struct fx_command_usage *usage)
{ {
struct fx_queue_entry *entry = fx_queue_first(&usage->u_parts); struct fx_queue_entry *entry = fx_queue_first(&usage->u_parts);
while (entry) { while (entry) {
struct fx_command_usage_entry *arg struct fx_command_usage_entry *arg = fx_unbox(
= fx_unbox(struct fx_command_usage_entry, entry, e_entry); struct fx_command_usage_entry,
entry,
e_entry);
if (!arg) { if (!arg) {
continue; continue;
} }
@@ -216,7 +224,9 @@ fx_status fx_command_set_flags(struct fx_command *cmd, fx_command_flags flags)
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_set_description(struct fx_command *cmd, const char *description) fx_status fx_command_set_description(
struct fx_command *cmd,
const char *description)
{ {
char *desc = fx_strdup(description); char *desc = fx_strdup(description);
if (!desc) { if (!desc) {
@@ -233,7 +243,8 @@ fx_status fx_command_set_description(struct fx_command *cmd, const char *descrip
} }
fx_status fx_command_set_callback( fx_status fx_command_set_callback(
struct fx_command *cmd, fx_command_callback callback) struct fx_command *cmd,
fx_command_callback callback)
{ {
cmd->c_callback = callback; cmd->c_callback = callback;
return FX_SUCCESS; return FX_SUCCESS;
@@ -284,7 +295,8 @@ struct fx_command_usage *fx_command_add_usage(struct fx_command *cmd)
} }
const struct fx_command_option *fx_command_get_option( const struct fx_command_option *fx_command_get_option(
const struct fx_command *cmd, int id) const struct fx_command *cmd,
int id)
{ {
struct fx_queue_entry *cur = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *cur = fx_queue_first(&cmd->c_opt);
while (cur) { while (cur) {
@@ -302,7 +314,8 @@ const struct fx_command_option *fx_command_get_option(
} }
fx_status fx_command_usage_add_option( fx_status fx_command_usage_add_option(
struct fx_command_usage *usage, struct fx_command_option *opt) struct fx_command_usage *usage,
struct fx_command_option *opt)
{ {
struct fx_command_usage_entry *u_opt = malloc(sizeof *u_opt); struct fx_command_usage_entry *u_opt = malloc(sizeof *u_opt);
if (!u_opt) { if (!u_opt) {
@@ -319,7 +332,8 @@ fx_status fx_command_usage_add_option(
} }
fx_status fx_command_usage_add_arg( fx_status fx_command_usage_add_arg(
struct fx_command_usage *usage, struct fx_command_arg *arg) struct fx_command_usage *usage,
struct fx_command_arg *arg)
{ {
struct fx_command_usage_entry *u_arg = malloc(sizeof *u_arg); struct fx_command_usage_entry *u_arg = malloc(sizeof *u_arg);
if (!u_arg) { if (!u_arg) {
@@ -335,7 +349,9 @@ fx_status fx_command_usage_add_arg(
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_usage_add_command(fx_command_usage *usage, unsigned int cmd_id) fx_status fx_command_usage_add_command(
fx_command_usage *usage,
unsigned int cmd_id)
{ {
struct fx_command_usage_entry *u_cmd = malloc(sizeof *u_cmd); struct fx_command_usage_entry *u_cmd = malloc(sizeof *u_cmd);
if (!u_cmd) { if (!u_cmd) {
@@ -392,7 +408,9 @@ static void prepend_command_name(struct fx_command *cmd, fx_string *out)
} }
static void get_qualified_command_name( static void get_qualified_command_name(
struct fx_command *cmd, const struct fx_arglist *args, fx_string *out) struct fx_command *cmd,
const struct fx_arglist *args,
fx_string *out)
{ {
for (unsigned int i = 0; i <= args->list_argv_last_command; i++) { for (unsigned int i = 0; i <= args->list_argv_last_command; i++) {
if (i > 0) { if (i > 0) {
@@ -414,8 +432,10 @@ static void get_qualified_command_name(
} }
static void get_usage_string( static void get_usage_string(
struct fx_command *cmd, struct fx_arglist *args, struct fx_command *cmd,
struct fx_command_usage *usage, fx_string *out) struct fx_arglist *args,
struct fx_command_usage *usage,
fx_string *out)
{ {
get_qualified_command_name(cmd, args, out); get_qualified_command_name(cmd, args, out);
@@ -424,7 +444,9 @@ static void get_usage_string(
struct fx_queue_entry *q_entry = fx_queue_first(&usage->u_parts); struct fx_queue_entry *q_entry = fx_queue_first(&usage->u_parts);
while (q_entry) { while (q_entry) {
struct fx_command_usage_entry *entry = fx_unbox( struct fx_command_usage_entry *entry = fx_unbox(
struct fx_command_usage_entry, q_entry, e_entry); struct fx_command_usage_entry,
q_entry,
e_entry);
if (!entry) { if (!entry) {
break; break;
@@ -436,7 +458,10 @@ static void get_usage_string(
switch (entry->e_type) { switch (entry->e_type) {
case CMD_USAGE_ARG: case CMD_USAGE_ARG:
if (entry->e_arg) { if (entry->e_arg) {
z__fx_get_arg_usage_string(entry->e_arg, false, out); z__fx_get_arg_usage_string(
entry->e_arg,
false,
out);
} else { } else {
fx_string_append_cstr(out, "[[ARGS]"); fx_string_append_cstr(out, "[[ARGS]");
} }
@@ -444,7 +469,9 @@ static void get_usage_string(
case CMD_USAGE_OPT: case CMD_USAGE_OPT:
if (entry->e_opt) { if (entry->e_opt) {
z__fx_get_option_usage_string( z__fx_get_option_usage_string(
entry->e_opt, CMD_STR_DIRECT_USAGE, out); entry->e_opt,
CMD_STR_DIRECT_USAGE,
out);
} else { } else {
fx_string_append_cstr(out, "[[OPTIONS]"); fx_string_append_cstr(out, "[[OPTIONS]");
} }
@@ -473,7 +500,8 @@ static void get_usage_string(
} }
fx_string *z__fx_command_default_usage_string( fx_string *z__fx_command_default_usage_string(
struct fx_command *cmd, struct fx_command_option *with_opt, struct fx_command *cmd,
struct fx_command_option *with_opt,
const struct fx_arglist *args) const struct fx_arglist *args)
{ {
fx_string *str = fx_string_create(); fx_string *str = fx_string_create();
@@ -481,7 +509,10 @@ fx_string *z__fx_command_default_usage_string(
if (with_opt) { if (with_opt) {
fx_string_append_cstr(str, " "); fx_string_append_cstr(str, " ");
z__fx_get_option_usage_string(with_opt, CMD_STR_DIRECT_USAGE, str); z__fx_get_option_usage_string(
with_opt,
CMD_STR_DIRECT_USAGE,
str);
} else if (!fx_queue_empty(&cmd->c_opt)) { } else if (!fx_queue_empty(&cmd->c_opt)) {
fx_string_append_cstr(str, " [OPTIONS]"); fx_string_append_cstr(str, " [OPTIONS]");
} }
@@ -519,7 +550,9 @@ static void get_command_string(struct fx_command *cmd, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, F_GREEN "-%c" F_RESET, cmd->c_short_name); out,
F_GREEN "-%c" F_RESET,
cmd->c_short_name);
r++; r++;
} }
@@ -529,7 +562,9 @@ static void get_command_string(struct fx_command *cmd, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, F_GREEN "--%s" F_RESET, cmd->c_long_name); out,
F_GREEN "--%s" F_RESET,
cmd->c_long_name);
r++; r++;
} }
} }
@@ -544,7 +579,8 @@ static void get_command_description(struct fx_command *cmd, fx_string *out)
* 2) the length of the description string exceeds the remaining line length * 2) the length of the description string exceeds the remaining line length
* (once the usage string has been printed. * (once the usage string has been printed.
* or, * or,
* 3) the length of the description string is more than three terminal lines. * 3) the length of the description string is more than three terminal
* lines.
*/ */
#define description_on_separate_line(opt_len, desc_len) \ #define description_on_separate_line(opt_len, desc_len) \
((opt_len >= newline_threshold \ ((opt_len >= newline_threshold \
@@ -578,12 +614,14 @@ static void print_options_list(struct fx_command *cmd)
z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str); z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str);
z__fx_get_option_description(opt, desc_str); z__fx_get_option_description(opt, desc_str);
size_t opt_len = fx_string_get_size( size_t opt_len
opt_str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) opt_str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4; + 4;
size_t desc_len = fx_string_get_size( size_t desc_len = fx_string_get_size(
desc_str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD); desc_str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD);
if (description_on_separate_line(opt_len, desc_len)) { if (description_on_separate_line(opt_len, desc_len)) {
goto skip; goto skip;
@@ -616,12 +654,14 @@ static void print_options_list(struct fx_command *cmd)
z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str); z__fx_get_option_usage_string(opt, CMD_STR_COLOUR, opt_str);
z__fx_get_option_description(opt, desc_str); z__fx_get_option_description(opt, desc_str);
size_t opt_len = fx_string_get_size( size_t opt_len
opt_str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) opt_str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4; + 4;
size_t desc_len = fx_string_get_size( size_t desc_len = fx_string_get_size(
desc_str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD); desc_str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD);
bool new_paragraph bool new_paragraph
= description_on_separate_line(opt_len, desc_len); = description_on_separate_line(opt_len, desc_len);
@@ -650,7 +690,10 @@ static void print_options_list(struct fx_command *cmd)
len++; len++;
} }
fx_print_paragraph(fx_string_get_cstr(desc_str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(desc_str),
OUTPUT_STREAM,
&format);
if (new_paragraph) { if (new_paragraph) {
fx_tty_putc(OUTPUT_STREAM, 0, '\n'); fx_tty_putc(OUTPUT_STREAM, 0, '\n');
@@ -678,8 +721,10 @@ static void print_args_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
z__fx_get_arg_usage_string(arg, true, str); z__fx_get_arg_usage_string(arg, true, str);
size_t len = fx_string_get_size( size_t len
str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD) = fx_string_get_size(
str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4; + 4;
if (len > desc_margin) { if (len > desc_margin) {
@@ -705,9 +750,10 @@ static void print_args_list(struct fx_command *cmd)
fx_tty_puts(OUTPUT_STREAM, 0, " "); fx_tty_puts(OUTPUT_STREAM, 0, " ");
fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str)); fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str));
unsigned int len = fx_string_get_size( unsigned int len
str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4; + 4;
while (len < format.p_left_margin) { while (len < format.p_left_margin) {
fx_tty_putc(OUTPUT_STREAM, 0, ' '); fx_tty_putc(OUTPUT_STREAM, 0, ' ');
@@ -717,7 +763,10 @@ static void print_args_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
z__fx_get_arg_description(arg, str); z__fx_get_arg_description(arg, str);
fx_print_paragraph(fx_string_get_cstr(str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(str),
OUTPUT_STREAM,
&format);
entry = fx_queue_next(entry); entry = fx_queue_next(entry);
} }
@@ -738,8 +787,10 @@ static void print_commands_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
get_command_string(sub, str); get_command_string(sub, str);
size_t len = fx_string_get_size( size_t len
str, FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD) = fx_string_get_size(
str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4; + 4;
if (len > desc_margin) { if (len > desc_margin) {
@@ -765,9 +816,10 @@ static void print_commands_list(struct fx_command *cmd)
fx_tty_puts(OUTPUT_STREAM, 0, " "); fx_tty_puts(OUTPUT_STREAM, 0, " ");
fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str)); fx_tty_puts(OUTPUT_STREAM, 0, fx_string_get_cstr(str));
unsigned int len = fx_string_get_size( unsigned int len
str, FX_STRLEN_IGNORE_ESC = fx_string_get_size(
| FX_STRLEN_IGNORE_MOD) str,
FX_STRLEN_IGNORE_ESC | FX_STRLEN_IGNORE_MOD)
+ 4; + 4;
while (len < format.p_left_margin) { while (len < format.p_left_margin) {
fx_tty_putc(OUTPUT_STREAM, 0, ' '); fx_tty_putc(OUTPUT_STREAM, 0, ' ');
@@ -777,7 +829,10 @@ static void print_commands_list(struct fx_command *cmd)
fx_string_clear(str); fx_string_clear(str);
get_command_description(sub, str); get_command_description(sub, str);
fx_print_paragraph(fx_string_get_cstr(str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(str),
OUTPUT_STREAM,
&format);
entry = fx_queue_next(entry); entry = fx_queue_next(entry);
} }
@@ -786,7 +841,8 @@ static void print_commands_list(struct fx_command *cmd)
} }
struct fx_command *fx_command_get_subcommand_with_name( struct fx_command *fx_command_get_subcommand_with_name(
struct fx_command *cmd, const char *name) struct fx_command *cmd,
const char *name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands);
while (entry) { while (entry) {
@@ -808,7 +864,8 @@ struct fx_command *fx_command_get_subcommand_with_name(
} }
struct fx_command *fx_command_get_subcommand_with_long_name( struct fx_command *fx_command_get_subcommand_with_long_name(
struct fx_command *cmd, const char *long_name) struct fx_command *cmd,
const char *long_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands);
while (entry) { while (entry) {
@@ -830,7 +887,8 @@ struct fx_command *fx_command_get_subcommand_with_long_name(
} }
struct fx_command *fx_command_get_subcommand_with_short_name( struct fx_command *fx_command_get_subcommand_with_short_name(
struct fx_command *cmd, char short_name) struct fx_command *cmd,
char short_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_subcommands);
while (entry) { while (entry) {
@@ -852,7 +910,8 @@ struct fx_command *fx_command_get_subcommand_with_short_name(
} }
struct fx_command_option *fx_command_get_option_with_long_name( struct fx_command_option *fx_command_get_option_with_long_name(
struct fx_command *cmd, const char *long_name) struct fx_command *cmd,
const char *long_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt);
while (entry) { while (entry) {
@@ -874,7 +933,8 @@ struct fx_command_option *fx_command_get_option_with_long_name(
} }
struct fx_command_option *fx_command_get_option_with_short_name( struct fx_command_option *fx_command_get_option_with_short_name(
struct fx_command *cmd, char short_name) struct fx_command *cmd,
char short_name)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt);
while (entry) { while (entry) {
@@ -896,7 +956,8 @@ struct fx_command_option *fx_command_get_option_with_short_name(
} }
struct fx_command_option *fx_command_get_option_with_id( struct fx_command_option *fx_command_get_option_with_id(
struct fx_command *cmd, unsigned int id) struct fx_command *cmd,
unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_opt);
while (entry) { while (entry) {
@@ -914,7 +975,8 @@ struct fx_command_option *fx_command_get_option_with_id(
} }
struct fx_command_arg *fx_command_get_arg_with_id( struct fx_command_arg *fx_command_get_arg_with_id(
struct fx_command *cmd, unsigned int id) struct fx_command *cmd,
unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&cmd->c_arg); struct fx_queue_entry *entry = fx_queue_first(&cmd->c_arg);
while (entry) { while (entry) {
@@ -941,7 +1003,10 @@ static void print_usage(struct fx_command *cmd, struct fx_arglist *args)
if (fx_queue_empty(&cmd->c_usage)) { if (fx_queue_empty(&cmd->c_usage)) {
fx_string *usage fx_string *usage
= z__fx_command_default_usage_string(cmd, NULL, args); = z__fx_command_default_usage_string(cmd, NULL, args);
fx_print_paragraph(fx_string_get_cstr(usage), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(usage),
OUTPUT_STREAM,
&format);
fx_string_unref(usage); fx_string_unref(usage);
return; return;
} }
@@ -954,7 +1019,10 @@ static void print_usage(struct fx_command *cmd, struct fx_arglist *args)
fx_string_clear(str); fx_string_clear(str);
get_usage_string(cmd, args, usage, str); get_usage_string(cmd, args, usage, str);
fx_print_paragraph(fx_string_get_cstr(str), OUTPUT_STREAM, &format); fx_print_paragraph(
fx_string_get_cstr(str),
OUTPUT_STREAM,
&format);
entry = fx_queue_next(entry); entry = fx_queue_next(entry);
} }
@@ -968,7 +1036,10 @@ static void print_help(struct fx_command *cmd, struct fx_arglist *args)
if (!cmd->c_parent) { if (!cmd->c_parent) {
fx_tty_printf( fx_tty_printf(
OUTPUT_STREAM, 0, F_GREEN "%s" F_RESET "\n", cmd->c_name); OUTPUT_STREAM,
0,
F_GREEN "%s" F_RESET "\n",
cmd->c_name);
} }
if (cmd->c_description) { if (cmd->c_description) {
@@ -999,9 +1070,13 @@ static int execute_command(struct fx_command *cmd, struct fx_arglist *args)
} }
size_t nr_items = fx_arglist_get_count( size_t nr_items = fx_arglist_get_count(
args, FX_COMMAND_INVALID_ID, FX_COMMAND_INVALID_ID); args,
FX_COMMAND_INVALID_ID,
FX_COMMAND_INVALID_ID);
size_t nr_help = fx_arglist_get_count( size_t nr_help = fx_arglist_get_count(
args, FX_COMMAND_OPTION_HELP, FX_COMMAND_INVALID_ID); args,
FX_COMMAND_OPTION_HELP,
FX_COMMAND_INVALID_ID);
if ((cmd->c_flags & FX_COMMAND_SHOW_HELP_BY_DEFAULT) && nr_items == 0) { if ((cmd->c_flags & FX_COMMAND_SHOW_HELP_BY_DEFAULT) && nr_items == 0) {
print_help(cmd, args); print_help(cmd, args);
@@ -1020,7 +1095,9 @@ static int execute_command(struct fx_command *cmd, struct fx_arglist *args)
return -1; return -1;
} }
static fx_status add_subcommand(struct fx_command *parent, struct fx_command *child) static fx_status add_subcommand(
struct fx_command *parent,
struct fx_command *child)
{ {
fx_queue_push_back(&parent->c_subcommands, &child->c_entry); fx_queue_push_back(&parent->c_subcommands, &child->c_entry);
child->c_parent = parent; child->c_parent = parent;
@@ -1032,7 +1109,8 @@ static int resolve_command_parents(struct fx_bst *commands)
{ {
struct fx_bst_node *node = fx_bst_first(commands); struct fx_bst_node *node = fx_bst_first(commands);
while (node) { while (node) {
struct fx_command *cmd = fx_unbox(struct fx_command, node, c_node); struct fx_command *cmd
= fx_unbox(struct fx_command, node, c_node);
if (cmd->c_parent_id == FX_COMMAND_INVALID_ID) { if (cmd->c_parent_id == FX_COMMAND_INVALID_ID) {
goto skip; goto skip;
+35 -17
View File
@@ -1,10 +1,10 @@
#ifndef _FX_COMMAND_H_ #ifndef _FX_COMMAND_H_
#define _FX_COMMAND_H_ #define _FX_COMMAND_H_
#include <fx/bst.h>
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/core/bst.h> #include <fx/queue.h>
#include <fx/core/queue.h> #include <fx/string.h>
#include <fx/ds/string.h>
#define F_RED "[bright_red]" #define F_RED "[bright_red]"
#define F_GREEN "[bright_green]" #define F_GREEN "[bright_green]"
@@ -105,23 +105,31 @@ struct fx_arglist {
}; };
FX_API struct fx_command *fx_command_get_subcommand_with_name( FX_API struct fx_command *fx_command_get_subcommand_with_name(
struct fx_command *cmd, const char *name); struct fx_command *cmd,
const char *name);
FX_API struct fx_command *fx_command_get_subcommand_with_long_name( FX_API struct fx_command *fx_command_get_subcommand_with_long_name(
struct fx_command *cmd, const char *long_name); struct fx_command *cmd,
const char *long_name);
FX_API struct fx_command *fx_command_get_subcommand_with_short_name( FX_API struct fx_command *fx_command_get_subcommand_with_short_name(
struct fx_command *cmd, char short_name); struct fx_command *cmd,
char short_name);
FX_API struct fx_command_option *fx_command_get_option_with_long_name( FX_API struct fx_command_option *fx_command_get_option_with_long_name(
struct fx_command *cmd, const char *long_name); struct fx_command *cmd,
const char *long_name);
FX_API struct fx_command_option *fx_command_get_option_with_short_name( FX_API struct fx_command_option *fx_command_get_option_with_short_name(
struct fx_command *cmd, char short_name); struct fx_command *cmd,
char short_name);
FX_API struct fx_command_option *fx_command_get_option_with_id( FX_API struct fx_command_option *fx_command_get_option_with_id(
struct fx_command *cmd, unsigned int id); struct fx_command *cmd,
unsigned int id);
FX_API struct fx_command_arg *fx_command_get_arg_with_id( FX_API struct fx_command_arg *fx_command_get_arg_with_id(
struct fx_command *cmd, unsigned int id); struct fx_command *cmd,
unsigned int id);
FX_API struct fx_command_arg *fx_command_option_get_arg_with_id( FX_API struct fx_command_arg *fx_command_option_get_arg_with_id(
struct fx_command_option *opt, unsigned int id); struct fx_command_option *opt,
unsigned int id);
FX_API struct fx_command_option *fx_command_option_create(void); FX_API struct fx_command_option *fx_command_option_create(void);
FX_API void fx_command_option_destroy(struct fx_command_option *opt); FX_API void fx_command_option_destroy(struct fx_command_option *opt);
@@ -131,21 +139,31 @@ FX_API void fx_command_arg_destroy(struct fx_command_arg *arg);
FX_API struct fx_arglist *fx_arglist_create(void); FX_API struct fx_arglist *fx_arglist_create(void);
FX_API fx_status fx_arglist_parse( FX_API fx_status fx_arglist_parse(
struct fx_arglist *args, struct fx_command **cmd, int argc, struct fx_arglist *args,
struct fx_command **cmd,
int argc,
const char **argv); const char **argv);
FX_API void fx_arglist_destroy(struct fx_arglist *args); FX_API void fx_arglist_destroy(struct fx_arglist *args);
FX_API fx_string *z__fx_command_default_usage_string( FX_API fx_string *z__fx_command_default_usage_string(
struct fx_command *cmd, struct fx_command_option *with_opt, struct fx_command *cmd,
struct fx_command_option *with_opt,
const struct fx_arglist *args); const struct fx_arglist *args);
FX_API void z__fx_get_arg_usage_string( FX_API void z__fx_get_arg_usage_string(
struct fx_command_arg *arg, bool colour, fx_string *out); struct fx_command_arg *arg,
FX_API void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out); bool colour,
fx_string *out);
FX_API void z__fx_get_arg_description(
struct fx_command_arg *arg,
fx_string *out);
FX_API void z__fx_get_option_usage_string( FX_API void z__fx_get_option_usage_string(
struct fx_command_option *opt, enum cmd_string_flags flags, fx_string *out); struct fx_command_option *opt,
enum cmd_string_flags flags,
fx_string *out);
FX_API void z__fx_get_option_description( FX_API void z__fx_get_option_description(
struct fx_command_option *opt, fx_string *out); struct fx_command_option *opt,
fx_string *out);
#endif #endif
@@ -1,27 +1,34 @@
#ifndef FX_CMD_H_ #ifndef FX_CMD_H_
#define FX_CMD_H_ #define FX_CMD_H_
#include <fx/core/bst.h> #include <fx/bst.h>
#include <fx/core/init.h> #include <fx/collections/array.h>
#include <fx/core/iterator.h> #include <fx/init.h>
#include <fx/core/queue.h> #include <fx/iterator.h>
#include <fx/ds/array.h> #include <fx/queue.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#define fx_arglist_foreach(it, q) \ #define fx_arglist_foreach(it, q) \
for (int z__fx_unique_name() = fx_arglist_iterator_begin( \ for (int z__fx_unique_name() = fx_arglist_iterator_begin( \
q, FX_COMMAND_INVALID_ID, FX_COMMAND_INVALID_ID, (it)); \ q, \
fx_arglist_iterator_is_valid(it); fx_arglist_iterator_next(it)) FX_COMMAND_INVALID_ID, \
FX_COMMAND_INVALID_ID, \
(it)); \
fx_arglist_iterator_is_valid(it); \
fx_arglist_iterator_next(it))
#define fx_arglist_foreach_filtered(it, q, opt_id, arg_id) \ #define fx_arglist_foreach_filtered(it, q, opt_id, arg_id) \
for (int z__fx_unique_name() \ for (int z__fx_unique_name() \
= fx_arglist_iterator_begin(q, opt_id, arg_id, (it)); \ = fx_arglist_iterator_begin(q, opt_id, arg_id, (it)); \
fx_arglist_iterator_is_valid(it); fx_arglist_iterator_next(it)) fx_arglist_iterator_is_valid(it); \
fx_arglist_iterator_next(it))
#define fx_arglist_option_foreach(it, q) \ #define fx_arglist_option_foreach(it, q) \
for (int z__fx_unique_name() \ for (int z__fx_unique_name() = fx_arglist_option_iterator_begin( \
= fx_arglist_option_iterator_begin(q, FX_COMMAND_INVALID_ID, (it)); \ q, \
FX_COMMAND_INVALID_ID, \
(it)); \
fx_arglist_option_iterator_is_valid(it); \ fx_arglist_option_iterator_is_valid(it); \
fx_arglist_option_iterator_next(it)) fx_arglist_option_iterator_next(it))
@@ -34,7 +41,9 @@
#define FX_COMMAND(id, parent_id) \ #define FX_COMMAND(id, parent_id) \
static fx_command *command_##id = NULL; \ static fx_command *command_##id = NULL; \
static void __init_##id( \ static void __init_##id( \
fx_command *, fx_command_option *, fx_command_arg *, \ fx_command *, \
fx_command_option *, \
fx_command_arg *, \
fx_command_usage *); \ fx_command_usage *); \
FX_INIT(init_##id) \ FX_INIT(init_##id) \
{ \ { \
@@ -46,8 +55,10 @@
fx_command_register(command_##id); \ fx_command_register(command_##id); \
} \ } \
static void __init_##id( \ static void __init_##id( \
fx_command *this_cmd, fx_command_option *this_opt, \ fx_command *this_cmd, \
fx_command_arg *this_arg, fx_command_usage *this_usage) fx_command_option *this_opt, \
fx_command_arg *this_arg, \
fx_command_usage *this_usage)
#define FX_COMMAND_NAME(name) fx_command_set_name(this_cmd, (name)) #define FX_COMMAND_NAME(name) fx_command_set_name(this_cmd, (name))
#define FX_COMMAND_LONG_NAME(name) fx_command_set_long_name(this_cmd, (name)) #define FX_COMMAND_LONG_NAME(name) fx_command_set_long_name(this_cmd, (name))
@@ -69,9 +80,12 @@
#define FX_COMMAND_HELP_OPTION() \ #define FX_COMMAND_HELP_OPTION() \
do { \ do { \
fx_command_option *opt \ fx_command_option *opt = fx_command_add_option( \
= fx_command_add_option(this_cmd, FX_COMMAND_OPTION_HELP); \ this_cmd, \
fx_command_option_set_description(opt, "Show this help message"); \ FX_COMMAND_OPTION_HELP); \
fx_command_option_set_description( \
opt, \
"Show this help message"); \
fx_command_option_set_short_name(opt, 'h'); \ fx_command_option_set_short_name(opt, 'h'); \
fx_command_option_set_long_name(opt, "help"); \ fx_command_option_set_long_name(opt, "help"); \
} while (0) } while (0)
@@ -109,7 +123,8 @@
fx_command_arg_set_allowed_values(this_arg, allowed_values) fx_command_arg_set_allowed_values(this_arg, allowed_values)
#define FX_COMMAND_USAGE() \ #define FX_COMMAND_USAGE() \
fx_command_usage *z__fx_unique_name() = fx_command_add_usage(this_cmd); \ fx_command_usage *z__fx_unique_name() \
= fx_command_add_usage(this_cmd); \
this_usage = z__fx_unique_name(); \ this_usage = z__fx_unique_name(); \
if (this_usage) if (this_usage)
@@ -197,90 +212,137 @@ typedef struct fx_arglist fx_arglist;
typedef struct fx_arglist_option fx_arglist_option; typedef struct fx_arglist_option fx_arglist_option;
typedef int (*fx_command_callback)( typedef int (*fx_command_callback)(
const fx_command *, const fx_arglist *, const fx_array *); const fx_command *,
const fx_arglist *,
const fx_array *);
FX_API fx_command *fx_command_create(unsigned int id); FX_API fx_command *fx_command_create(unsigned int id);
FX_API void fx_command_destroy(fx_command *cmd); FX_API void fx_command_destroy(fx_command *cmd);
FX_API fx_status fx_command_register(fx_command *cmd); FX_API fx_status fx_command_register(fx_command *cmd);
FX_API int fx_command_dispatch(unsigned int cmd_id, int argc, const char **argv); FX_API int fx_command_dispatch(
unsigned int cmd_id,
int argc,
const char **argv);
FX_API fx_status fx_command_set_name(fx_command *cmd, const char *name); FX_API fx_status fx_command_set_name(fx_command *cmd, const char *name);
FX_API fx_status fx_command_set_long_name(fx_command *cmd, const char *name); FX_API fx_status fx_command_set_long_name(fx_command *cmd, const char *name);
FX_API fx_status fx_command_set_short_name(fx_command *cmd, char name); FX_API fx_status fx_command_set_short_name(fx_command *cmd, char name);
FX_API fx_status fx_command_set_flags(fx_command *cmd, fx_command_flags flags); FX_API fx_status fx_command_set_flags(fx_command *cmd, fx_command_flags flags);
FX_API fx_status fx_command_set_description(fx_command *cmd, const char *description); FX_API fx_status fx_command_set_description(
fx_command *cmd,
const char *description);
FX_API fx_status fx_command_set_callback( FX_API fx_status fx_command_set_callback(
fx_command *cmd, fx_command_callback callback); fx_command *cmd,
fx_command_callback callback);
FX_API fx_status fx_command_set_parent(fx_command *cmd, unsigned int parent_id); FX_API fx_status fx_command_set_parent(fx_command *cmd, unsigned int parent_id);
FX_API fx_command_option *fx_command_add_option(fx_command *cmd, int id); FX_API fx_command_option *fx_command_add_option(fx_command *cmd, int id);
FX_API fx_command_arg *fx_command_add_arg(fx_command *cmd, int id); FX_API fx_command_arg *fx_command_add_arg(fx_command *cmd, int id);
FX_API fx_command_usage *fx_command_add_usage(fx_command *cmd); FX_API fx_command_usage *fx_command_add_usage(fx_command *cmd);
FX_API const fx_command_option *fx_command_get_option(const fx_command *cmd, int id); FX_API const fx_command_option *fx_command_get_option(
const fx_command *cmd,
int id);
FX_API const char *fx_command_option_get_long_name(const fx_command_option *opt); FX_API const char *fx_command_option_get_long_name(
const fx_command_option *opt);
FX_API char fx_command_option_get_short_name(const fx_command_option *opt); FX_API char fx_command_option_get_short_name(const fx_command_option *opt);
FX_API const char *fx_command_option_get_description(fx_command_option *opt); FX_API const char *fx_command_option_get_description(fx_command_option *opt);
FX_API fx_status fx_command_option_set_long_name( FX_API fx_status fx_command_option_set_long_name(
fx_command_option *opt, const char *name); fx_command_option *opt,
FX_API fx_status fx_command_option_set_short_name(fx_command_option *opt, char name); const char *name);
FX_API fx_status fx_command_option_set_short_name(
fx_command_option *opt,
char name);
FX_API fx_status fx_command_option_set_description( FX_API fx_status fx_command_option_set_description(
fx_command_option *opt, const char *description); fx_command_option *opt,
FX_API fx_command_arg *fx_command_option_add_arg(fx_command_option *opt, int id); const char *description);
FX_API fx_command_arg *fx_command_option_add_arg(
fx_command_option *opt,
int id);
FX_API fx_status fx_command_arg_set_name(fx_command_arg *arg, const char *name); FX_API fx_status fx_command_arg_set_name(fx_command_arg *arg, const char *name);
FX_API fx_status fx_command_arg_set_description( FX_API fx_status fx_command_arg_set_description(
fx_command_arg *arg, const char *description); fx_command_arg *arg,
const char *description);
FX_API fx_status fx_command_arg_set_nr_values( FX_API fx_status fx_command_arg_set_nr_values(
fx_command_arg *arg, fx_command_arg_value_count nr_values); fx_command_arg *arg,
fx_command_arg_value_count nr_values);
FX_API fx_status fx_command_arg_set_allowed_values( FX_API fx_status fx_command_arg_set_allowed_values(
fx_command_arg *arg, const char **allowed_values); fx_command_arg *arg,
const char **allowed_values);
FX_API fx_status fx_command_usage_add_option( FX_API fx_status fx_command_usage_add_option(
fx_command_usage *usage, fx_command_option *opt); fx_command_usage *usage,
fx_command_option *opt);
FX_API fx_status fx_command_usage_add_arg( FX_API fx_status fx_command_usage_add_arg(
fx_command_usage *usage, fx_command_arg *opt); fx_command_usage *usage,
fx_command_arg *opt);
FX_API fx_status fx_command_usage_add_command( FX_API fx_status fx_command_usage_add_command(
fx_command_usage *usage, unsigned int cmd_id); fx_command_usage *usage,
unsigned int cmd_id);
FX_API fx_status fx_arglist_get_string( FX_API fx_status fx_arglist_get_string(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, const char **out); unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
const char **out);
FX_API fx_status fx_arglist_get_int( FX_API fx_status fx_arglist_get_int(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, long long *out); unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
long long *out);
FX_API fx_status fx_arglist_get_uint( FX_API fx_status fx_arglist_get_uint(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int index, unsigned long long *out); unsigned int opt_id,
unsigned int arg_id,
unsigned int index,
unsigned long long *out);
FX_API fx_status fx_arglist_get_option( FX_API fx_status fx_arglist_get_option(
const fx_arglist *args, unsigned int opt_id, unsigned int index, const fx_arglist *args,
unsigned int opt_id,
unsigned int index,
fx_arglist_option **out); fx_arglist_option **out);
FX_API size_t fx_arglist_get_count( FX_API size_t fx_arglist_get_count(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id); const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id);
FX_API fx_status fx_arglist_report_missing_option( FX_API fx_status fx_arglist_report_missing_option(
const fx_arglist *args, unsigned int opt_id); const fx_arglist *args,
unsigned int opt_id);
FX_API fx_status fx_arglist_report_unexpected_arg( FX_API fx_status fx_arglist_report_unexpected_arg(
const fx_arglist *args, const char *value); const fx_arglist *args,
const char *value);
FX_API fx_status fx_arglist_report_invalid_arg_value( FX_API fx_status fx_arglist_report_invalid_arg_value(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
const char *value); const char *value);
FX_API fx_status fx_arglist_report_missing_args( FX_API fx_status fx_arglist_report_missing_args(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
size_t nr_supplied); size_t nr_supplied);
FX_API fx_status fx_arglist_option_get_value( FX_API fx_status fx_arglist_option_get_value(
const fx_arglist_option *opt, unsigned int arg_id, unsigned int index, const fx_arglist_option *opt,
unsigned int arg_id,
unsigned int index,
fx_arglist_value **out); fx_arglist_value **out);
FX_API int fx_arglist_iterator_begin( FX_API int fx_arglist_iterator_begin(
const fx_arglist *args, unsigned int opt_filter, unsigned int arg_filter, const fx_arglist *args,
unsigned int opt_filter,
unsigned int arg_filter,
fx_arglist_iterator *it); fx_arglist_iterator *it);
FX_API bool fx_arglist_iterator_next(fx_arglist_iterator *it); FX_API bool fx_arglist_iterator_next(fx_arglist_iterator *it);
FX_API bool fx_arglist_iterator_is_valid(const fx_arglist_iterator *it); FX_API bool fx_arglist_iterator_is_valid(const fx_arglist_iterator *it);
FX_API int fx_arglist_option_iterator_begin( FX_API int fx_arglist_option_iterator_begin(
const fx_arglist *args, unsigned int opt_filter, const fx_arglist *args,
unsigned int opt_filter,
fx_arglist_option_iterator *it); fx_arglist_option_iterator *it);
FX_API bool fx_arglist_option_iterator_next(fx_arglist_option_iterator *it); FX_API bool fx_arglist_option_iterator_next(fx_arglist_option_iterator *it);
FX_API bool fx_arglist_option_iterator_is_valid( FX_API bool fx_arglist_option_iterator_is_valid(
+27 -12
View File
@@ -1,7 +1,7 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <fx/cmd.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -58,7 +58,8 @@ const char *fx_command_option_get_description(struct fx_command_option *opt)
} }
fx_status fx_command_option_set_long_name( fx_status fx_command_option_set_long_name(
struct fx_command_option *opt, const char *name) struct fx_command_option *opt,
const char *name)
{ {
char *n = fx_strdup(name); char *n = fx_strdup(name);
if (!n) { if (!n) {
@@ -74,14 +75,17 @@ fx_status fx_command_option_set_long_name(
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_option_set_short_name(struct fx_command_option *opt, char name) fx_status fx_command_option_set_short_name(
struct fx_command_option *opt,
char name)
{ {
opt->opt_short_name = name; opt->opt_short_name = name;
return FX_SUCCESS; return FX_SUCCESS;
} }
fx_status fx_command_option_set_description( fx_status fx_command_option_set_description(
struct fx_command_option *opt, const char *description) struct fx_command_option *opt,
const char *description)
{ {
char *desc = fx_strdup(description); char *desc = fx_strdup(description);
if (!desc) { if (!desc) {
@@ -97,7 +101,9 @@ fx_status fx_command_option_set_description(
return FX_SUCCESS; return FX_SUCCESS;
} }
struct fx_command_arg *fx_command_option_add_arg(struct fx_command_option *opt, int id) struct fx_command_arg *fx_command_option_add_arg(
struct fx_command_option *opt,
int id)
{ {
struct fx_command_arg *arg = malloc(sizeof *arg); struct fx_command_arg *arg = malloc(sizeof *arg);
if (!arg) { if (!arg) {
@@ -139,7 +145,9 @@ void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out)
if (nr_args > 1) { if (nr_args > 1) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, "values for `%s`:", arg->arg_name); out,
"values for `%s`:",
arg->arg_name);
} else { } else {
fx_string_append_cstr(out, "values:"); fx_string_append_cstr(out, "values:");
} }
@@ -150,7 +158,8 @@ void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out)
} }
fx_string_append_cstrf( fx_string_append_cstrf(
out, " " F_GREEN "%s" F_RESET, out,
" " F_GREEN "%s" F_RESET,
arg->arg_allowed_values[i]); arg->arg_allowed_values[i]);
} }
@@ -165,7 +174,9 @@ void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out)
} }
void z__fx_get_option_usage_string( void z__fx_get_option_usage_string(
struct fx_command_option *opt, enum cmd_string_flags flags, fx_string *out) struct fx_command_option *opt,
enum cmd_string_flags flags,
fx_string *out)
{ {
if (flags & CMD_STR_DIRECT_USAGE) { if (flags & CMD_STR_DIRECT_USAGE) {
fx_string_append_cstr(out, "{"); fx_string_append_cstr(out, "{");
@@ -174,19 +185,22 @@ void z__fx_get_option_usage_string(
if (opt->opt_short_name) { if (opt->opt_short_name) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, out,
(flags & CMD_STR_COLOUR) ? F_GREEN "-%c" F_RESET : "-%c", (flags & CMD_STR_COLOUR) ? F_GREEN "-%c" F_RESET
: "-%c",
opt->opt_short_name); opt->opt_short_name);
} }
if (opt->opt_short_name && opt->opt_long_name) { if (opt->opt_short_name && opt->opt_long_name) {
fx_string_append_cstr( fx_string_append_cstr(
out, (flags & CMD_STR_DIRECT_USAGE) ? "|" : ", "); out,
(flags & CMD_STR_DIRECT_USAGE) ? "|" : ", ");
} }
if (opt->opt_long_name) { if (opt->opt_long_name) {
fx_string_append_cstrf( fx_string_append_cstrf(
out, out,
(flags & CMD_STR_COLOUR) ? F_GREEN "--%s" F_RESET : "--%s", (flags & CMD_STR_COLOUR) ? F_GREEN "--%s" F_RESET
: "--%s",
opt->opt_long_name); opt->opt_long_name);
} }
@@ -254,7 +268,8 @@ void z__fx_get_option_usage_string(
} }
struct fx_command_arg *fx_command_option_get_arg_with_id( struct fx_command_arg *fx_command_option_get_arg_with_id(
struct fx_command_option *opt, unsigned int id) struct fx_command_option *opt,
unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args); struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args);
+55 -24
View File
@@ -1,13 +1,14 @@
#include "command.h" #include "command.h"
#include <assert.h> #include <assert.h>
#include <fx/core/stringstream.h> #include <fx/string.h>
#include <fx/ds/string.h> #include <fx/stringstream.h>
#include <fx/term/print.h> #include <fx/term/print.h>
#include <stdio.h> #include <stdio.h>
enum fx_status fx_arglist_report_missing_option( enum fx_status fx_arglist_report_missing_option(
const fx_arglist *args, unsigned int opt_id) const fx_arglist *args,
unsigned int opt_id)
{ {
struct fx_command_option *opt = NULL; struct fx_command_option *opt = NULL;
@@ -35,7 +36,10 @@ enum fx_status fx_arglist_report_missing_option(
if (opt_names == 2) { if (opt_names == 2) {
fx_stream_write_fmt( fx_stream_write_fmt(
opt_name, NULL, "-%c / --%s", opt->opt_short_name, opt_name,
NULL,
"-%c / --%s",
opt->opt_short_name,
opt->opt_long_name); opt->opt_long_name);
} else if (opt->opt_short_name) { } else if (opt->opt_short_name) {
fx_stream_write_fmt(opt_name, NULL, "-%c", opt->opt_short_name); fx_stream_write_fmt(opt_name, NULL, "-%c", opt->opt_short_name);
@@ -55,10 +59,13 @@ enum fx_status fx_arglist_report_missing_option(
} }
enum fx_status fx_arglist_report_unexpected_arg( enum fx_status fx_arglist_report_unexpected_arg(
const fx_arglist *args, const char *value) const fx_arglist *args,
const char *value)
{ {
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
args->list_command, NULL, args); args->list_command,
NULL,
args);
fx_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value); fx_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value);
fx_i("usage: %s", fx_string_get_cstr(usage)); fx_i("usage: %s", fx_string_get_cstr(usage));
@@ -68,7 +75,9 @@ enum fx_status fx_arglist_report_unexpected_arg(
} }
enum fx_status fx_arglist_report_invalid_arg_value( enum fx_status fx_arglist_report_invalid_arg_value(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
const char *value) const char *value)
{ {
struct fx_command_option *opt = NULL; struct fx_command_option *opt = NULL;
@@ -80,11 +89,15 @@ enum fx_status fx_arglist_report_invalid_arg_value(
if (arg_id != FX_COMMAND_INVALID_ID) { if (arg_id != FX_COMMAND_INVALID_ID) {
arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id) arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id)
: fx_command_get_arg_with_id(args->list_command, arg_id); : fx_command_get_arg_with_id(
args->list_command,
arg_id);
} }
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
args->list_command, opt, args); args->list_command,
opt,
args);
fx_string *opt_string = fx_string_create(); fx_string *opt_string = fx_string_create();
if (opt) { if (opt) {
@@ -95,15 +108,18 @@ enum fx_status fx_arglist_report_invalid_arg_value(
fx_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW fx_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW
"%s" F_RESET "'.", "%s" F_RESET "'.",
value, fx_string_get_cstr(opt_string)); value,
fx_string_get_cstr(opt_string));
if (opt) { if (opt) {
fx_i("'" F_YELLOW "%s" F_RESET fx_i("'" F_YELLOW "%s" F_RESET
"' accepts the following values for '" F_YELLOW "%s" F_RESET "' accepts the following values for '" F_YELLOW
"':", "%s" F_RESET "':",
fx_string_get_cstr(opt_string), arg->arg_name); fx_string_get_cstr(opt_string),
arg->arg_name);
} else { } else {
fx_i("'" F_YELLOW "%s" F_RESET "' accepts the following values:", fx_i("'" F_YELLOW "%s" F_RESET
"' accepts the following values:",
fx_string_get_cstr(opt_string)); fx_string_get_cstr(opt_string));
} }
@@ -124,7 +140,9 @@ enum fx_status fx_arglist_report_invalid_arg_value(
} }
enum fx_status fx_arglist_report_missing_args( enum fx_status fx_arglist_report_missing_args(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const fx_arglist *args,
unsigned int opt_id,
unsigned int arg_id,
size_t args_supplied) size_t args_supplied)
{ {
struct fx_command_option *opt = NULL; struct fx_command_option *opt = NULL;
@@ -137,12 +155,16 @@ enum fx_status fx_arglist_report_missing_args(
if (arg_id != FX_COMMAND_INVALID_ID) { if (arg_id != FX_COMMAND_INVALID_ID) {
arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id) arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id)
: fx_command_get_arg_with_id(args->list_command, arg_id); : fx_command_get_arg_with_id(
args->list_command,
arg_id);
assert(arg); assert(arg);
} }
fx_string *usage = z__fx_command_default_usage_string( fx_string *usage = z__fx_command_default_usage_string(
args->list_command, opt, args); args->list_command,
opt,
args);
fx_string *opt_string = fx_string_create(); fx_string *opt_string = fx_string_create();
if (opt) { if (opt) {
@@ -154,16 +176,19 @@ enum fx_status fx_arglist_report_missing_args(
char supplied_arg_str[64]; char supplied_arg_str[64];
if (args_supplied == 0) { if (args_supplied == 0) {
snprintf( snprintf(
supplied_arg_str, sizeof supplied_arg_str, supplied_arg_str,
sizeof supplied_arg_str,
F_RED_BOLD "none" F_RESET " were provided"); F_RED_BOLD "none" F_RESET " were provided");
} else if (args_supplied == 1) { } else if (args_supplied == 1) {
snprintf( snprintf(
supplied_arg_str, sizeof supplied_arg_str, supplied_arg_str,
sizeof supplied_arg_str,
"only " F_YELLOW_BOLD "%zu" F_RESET " was provided", "only " F_YELLOW_BOLD "%zu" F_RESET " was provided",
args_supplied); args_supplied);
} else { } else {
snprintf( snprintf(
supplied_arg_str, sizeof supplied_arg_str, supplied_arg_str,
sizeof supplied_arg_str,
"only " F_YELLOW_BOLD "%zu" F_RESET " were provided", "only " F_YELLOW_BOLD "%zu" F_RESET " were provided",
args_supplied); args_supplied);
} }
@@ -172,19 +197,25 @@ enum fx_status fx_arglist_report_missing_args(
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
case FX_ARG_1_OR_MORE_VALUES: case FX_ARG_1_OR_MORE_VALUES:
snprintf( snprintf(
required_arg_count, sizeof required_arg_count, required_arg_count,
sizeof required_arg_count,
"one or more"); "one or more");
break; break;
default: default:
snprintf( snprintf(
required_arg_count, sizeof required_arg_count, "%d", required_arg_count,
sizeof required_arg_count,
"%d",
arg->arg_nr_values); arg->arg_nr_values);
} }
fx_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD fx_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD
"%s" F_RESET " `" F_YELLOW "%s" F_RESET "` value%s, but %s.", "%s" F_RESET " `" F_YELLOW "%s" F_RESET "` value%s, but %s.",
fx_string_get_cstr(opt_string), required_arg_count, arg->arg_name, fx_string_get_cstr(opt_string),
(arg->arg_nr_values == 1) ? "" : "s", supplied_arg_str); required_arg_count,
arg->arg_name,
(arg->arg_nr_values == 1) ? "" : "s",
supplied_arg_str);
fx_i("usage: %s", fx_string_get_cstr(usage)); fx_i("usage: %s", fx_string_get_cstr(usage));
fx_i("for more information, use '" F_YELLOW "--help" F_RESET "'"); fx_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
+1
View File
@@ -0,0 +1 @@
export_fx_namespace_details(fx.collections)
+4 -4
View File
@@ -1,7 +1,7 @@
#include <fx/core/iterator.h> #include <fx/collections/array.h>
#include <fx/core/stream.h> #include <fx/iterator.h>
#include <fx/ds/array.h> #include <fx/stream.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -1,4 +1,4 @@
#include <fx/ds/bitbuffer.h> #include <fx/collections/bitbuffer.h>
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
+45 -15
View File
@@ -1,6 +1,6 @@
#include <fx/core/bitop.h> #include <fx/bitop.h>
#include <fx/core/stream.h> #include <fx/collections/bitmap.h>
#include <fx/ds/bitmap.h> #include <fx/stream.h>
#include <string.h> #include <string.h>
#define BITS_PER_WORD (8 * sizeof(bitmap_word_t)) #define BITS_PER_WORD (8 * sizeof(bitmap_word_t))
@@ -36,11 +36,17 @@ static void bitmap_clear_bit(struct fx_bitmap_p *map, size_t bit)
map->map_words[index] &= ~mask; map->map_words[index] &= ~mask;
} }
static void bitmap_set_range(struct fx_bitmap_p *map, size_t first_bit, size_t nbits) static void bitmap_set_range(
struct fx_bitmap_p *map,
size_t first_bit,
size_t nbits)
{ {
} }
static void bitmap_clear_range(struct fx_bitmap_p *map, size_t first_bit, size_t nbits) static void bitmap_clear_range(
struct fx_bitmap_p *map,
size_t first_bit,
size_t nbits)
{ {
} }
@@ -216,13 +222,21 @@ void fx_bitmap_clear_bit(fx_bitmap *map, size_t bit)
void fx_bitmap_set_range(fx_bitmap *map, size_t first_bit, size_t nbits) void fx_bitmap_set_range(fx_bitmap *map, size_t first_bit, size_t nbits)
{ {
FX_CLASS_DISPATCH_STATIC_V( FX_CLASS_DISPATCH_STATIC_V(
FX_TYPE_BITMAP, bitmap_set_range, map, first_bit, nbits); FX_TYPE_BITMAP,
bitmap_set_range,
map,
first_bit,
nbits);
} }
void fx_bitmap_clear_range(fx_bitmap *map, size_t first_bit, size_t nbits) void fx_bitmap_clear_range(fx_bitmap *map, size_t first_bit, size_t nbits)
{ {
FX_CLASS_DISPATCH_STATIC_V( FX_CLASS_DISPATCH_STATIC_V(
FX_TYPE_BITMAP, bitmap_clear_range, map, first_bit, nbits); FX_TYPE_BITMAP,
bitmap_clear_range,
map,
first_bit,
nbits);
} }
void fx_bitmap_set_all(fx_bitmap *map) void fx_bitmap_set_all(fx_bitmap *map)
@@ -247,7 +261,10 @@ size_t fx_bitmap_count_set_bits(const fx_bitmap *map)
size_t fx_bitmap_count_clear_bits(const fx_bitmap *map) size_t fx_bitmap_count_clear_bits(const fx_bitmap *map)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BITMAP, bitmap_count_clear_bits, map); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_BITMAP,
bitmap_count_clear_bits,
map);
} }
size_t fx_bitmap_highest_set_bit(const fx_bitmap *map) size_t fx_bitmap_highest_set_bit(const fx_bitmap *map)
@@ -257,7 +274,10 @@ size_t fx_bitmap_highest_set_bit(const fx_bitmap *map)
size_t fx_bitmap_highest_clear_bit(const fx_bitmap *map) size_t fx_bitmap_highest_clear_bit(const fx_bitmap *map)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BITMAP, bitmap_highest_clear_bit, map); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_BITMAP,
bitmap_highest_clear_bit,
map);
} }
size_t fx_bitmap_lowest_set_bit(const fx_bitmap *map) size_t fx_bitmap_lowest_set_bit(const fx_bitmap *map)
@@ -267,7 +287,10 @@ size_t fx_bitmap_lowest_set_bit(const fx_bitmap *map)
size_t fx_bitmap_lowest_clear_bit(const fx_bitmap *map) size_t fx_bitmap_lowest_clear_bit(const fx_bitmap *map)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BITMAP, bitmap_lowest_clear_bit, map); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_BITMAP,
bitmap_lowest_clear_bit,
map);
} }
/*** PUBLIC ALIAS FUNCTIONS ***************************************************/ /*** PUBLIC ALIAS FUNCTIONS ***************************************************/
@@ -285,7 +308,8 @@ static void bitmap_fini(fx_object *obj, void *priv)
static void bitmap_to_string(const fx_object *obj, fx_stream *out) static void bitmap_to_string(const fx_object *obj, fx_stream *out)
{ {
const struct fx_bitmap_p *map = fx_object_get_private(obj, FX_TYPE_BITMAP); const struct fx_bitmap_p *map
= fx_object_get_private(obj, FX_TYPE_BITMAP);
unsigned char *bytes = (unsigned char *)map->map_words; unsigned char *bytes = (unsigned char *)map->map_words;
size_t nr_bytes = map->map_nr_words * sizeof(bitmap_word_t); size_t nr_bytes = map->map_nr_words * sizeof(bitmap_word_t);
@@ -294,10 +318,16 @@ static void bitmap_to_string(const fx_object *obj, fx_stream *out)
for (size_t i = 0; i < nr_bytes - 1; i++) { for (size_t i = 0; i < nr_bytes - 1; i++) {
c = bytes[i]; c = bytes[i];
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, "%c%c%c%c%c%c%c%c", c & 0x80 ? '1' : '0', out,
c & 0x40 ? '1' : '0', c & 0x20 ? '1' : '0', NULL,
c & 0x10 ? '1' : '0', c & 0x08 ? '1' : '0', "%c%c%c%c%c%c%c%c",
c & 0x04 ? '1' : '0', c & 0x02 ? '1' : '0', c & 0x80 ? '1' : '0',
c & 0x40 ? '1' : '0',
c & 0x20 ? '1' : '0',
c & 0x10 ? '1' : '0',
c & 0x08 ? '1' : '0',
c & 0x04 ? '1' : '0',
c & 0x02 ? '1' : '0',
c & 0x01 ? '1' : '0'); c & 0x01 ? '1' : '0');
} }
+53 -14
View File
@@ -1,5 +1,5 @@
#include <fx/core/iterator.h> #include <fx/collections/buffer.h>
#include <fx/ds/buffer.h> #include <fx/iterator.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -21,7 +21,8 @@ static fx_status resize_buffer(struct fx_buffer_p *buffer, size_t new_capacity)
{ {
if (buffer->buf_cap < new_capacity) { if (buffer->buf_cap < new_capacity) {
void *new_data = realloc( void *new_data = realloc(
buffer->buf_data, new_capacity * buffer->buf_itemsz); buffer->buf_data,
new_capacity * buffer->buf_itemsz);
if (!new_data) { if (!new_data) {
return FX_ERR_NO_MEMORY; return FX_ERR_NO_MEMORY;
} }
@@ -29,7 +30,8 @@ static fx_status resize_buffer(struct fx_buffer_p *buffer, size_t new_capacity)
buffer->buf_data = new_data; buffer->buf_data = new_data;
} else { } else {
void *new_data = realloc( void *new_data = realloc(
buffer->buf_data, new_capacity * buffer->buf_itemsz); buffer->buf_data,
new_capacity * buffer->buf_itemsz);
if (!new_data) { if (!new_data) {
return FX_ERR_NO_MEMORY; return FX_ERR_NO_MEMORY;
} }
@@ -78,7 +80,10 @@ static enum fx_status buffer_resize(struct fx_buffer_p *buf, size_t length)
} }
static enum fx_status buffer_insert( static enum fx_status buffer_insert(
struct fx_buffer_p *buffer, const void *p, size_t count, size_t at) struct fx_buffer_p *buffer,
const void *p,
size_t count,
size_t at)
{ {
if (at == FX_NPOS) { if (at == FX_NPOS) {
at = buffer->buf_len; at = buffer->buf_len;
@@ -110,7 +115,10 @@ static enum fx_status buffer_insert(
return FX_SUCCESS; return FX_SUCCESS;
} }
static enum fx_status buffer_remove(struct fx_buffer_p *buffer, size_t at, size_t count) static enum fx_status buffer_remove(
struct fx_buffer_p *buffer,
size_t at,
size_t count)
{ {
if (at >= buffer->buf_len) { if (at >= buffer->buf_len) {
return FX_ERR_OUT_OF_BOUNDS; return FX_ERR_OUT_OF_BOUNDS;
@@ -162,7 +170,9 @@ static enum fx_status buffer_clear(struct fx_buffer_p *buffer)
} }
static enum fx_status buffer_push_back( static enum fx_status buffer_push_back(
struct fx_buffer_p *buf, size_t count, void **p) struct fx_buffer_p *buf,
size_t count,
void **p)
{ {
enum fx_status status = FX_SUCCESS; enum fx_status status = FX_SUCCESS;
@@ -181,7 +191,9 @@ static enum fx_status buffer_push_back(
} }
static enum fx_status buffer_push_front( static enum fx_status buffer_push_front(
struct fx_buffer_p *buf, size_t count, void **p) struct fx_buffer_p *buf,
size_t count,
void **p)
{ {
enum fx_status status = FX_SUCCESS; enum fx_status status = FX_SUCCESS;
@@ -286,7 +298,10 @@ fx_buffer *fx_buffer_create_from_bytes(const void *buf, size_t len)
return buffer; return buffer;
} }
fx_buffer *fx_buffer_create_from_array(const void *buf, size_t item_sz, size_t len) fx_buffer *fx_buffer_create_from_array(
const void *buf,
size_t item_sz,
size_t len)
{ {
fx_buffer *buffer = fx_object_create(FX_TYPE_BUFFER); fx_buffer *buffer = fx_object_create(FX_TYPE_BUFFER);
if (!buffer) { if (!buffer) {
@@ -325,14 +340,28 @@ enum fx_status fx_buffer_resize(fx_buffer *buf, size_t length)
} }
enum fx_status fx_buffer_insert( enum fx_status fx_buffer_insert(
fx_buffer *buffer, const void *p, size_t count, size_t at) fx_buffer *buffer,
const void *p,
size_t count,
size_t at)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_BUFFER, buffer_insert, buffer, p, count, at); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_BUFFER,
buffer_insert,
buffer,
p,
count,
at);
} }
enum fx_status fx_buffer_remove(fx_buffer *buffer, size_t at, size_t count) enum fx_status fx_buffer_remove(fx_buffer *buffer, size_t at, size_t count)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_BUFFER, buffer_remove, buffer, at, count); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_BUFFER,
buffer_remove,
buffer,
at,
count);
} }
void *fx_buffer_ptr(const fx_buffer *buffer) void *fx_buffer_ptr(const fx_buffer *buffer)
@@ -362,12 +391,22 @@ enum fx_status fx_buffer_clear(fx_buffer *buffer)
enum fx_status fx_buffer_push_back(fx_buffer *buf, size_t count, void **p) enum fx_status fx_buffer_push_back(fx_buffer *buf, size_t count, void **p)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_BUFFER, buffer_push_back, buf, count, p); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_BUFFER,
buffer_push_back,
buf,
count,
p);
} }
enum fx_status fx_buffer_push_front(fx_buffer *buf, size_t count, void **p) enum fx_status fx_buffer_push_front(fx_buffer *buf, size_t count, void **p)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_BUFFER, buffer_push_front, buf, count, p); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_BUFFER,
buffer_push_front,
buf,
count,
p);
} }
enum fx_status fx_buffer_pop_back(fx_buffer *buf, size_t count) enum fx_status fx_buffer_pop_back(fx_buffer *buf, size_t count)
+58 -19
View File
@@ -1,6 +1,6 @@
#include <fx/core/stream.h> #include <fx/collections/datetime.h>
#include <fx/ds/datetime.h> #include <fx/stream.h>
#include <fx/ds/string.h> #include <fx/string.h>
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
@@ -89,7 +89,8 @@ static bool is_zone_valid(const struct fx_datetime_p *dt)
return false; return false;
} }
if (!(dt->dt_zone_offset_minute >= 0 && dt->dt_zone_offset_minute <= 59)) { if (!(dt->dt_zone_offset_minute >= 0
&& dt->dt_zone_offset_minute <= 59)) {
return false; return false;
} }
@@ -309,12 +310,18 @@ fail:
return NULL; return NULL;
} }
static enum fx_status encode_rfc3339(const struct fx_datetime_p *dt, fx_stream *out) static enum fx_status encode_rfc3339(
const struct fx_datetime_p *dt,
fx_stream *out)
{ {
if (dt->dt_has_date) { if (dt->dt_has_date) {
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, "%04ld-%02ld-%02ld", dt->dt_year, out,
dt->dt_month, dt->dt_day); NULL,
"%04ld-%02ld-%02ld",
dt->dt_year,
dt->dt_month,
dt->dt_day);
} }
if (dt->dt_has_date && dt->dt_has_time) { if (dt->dt_has_date && dt->dt_has_time) {
@@ -323,7 +330,11 @@ static enum fx_status encode_rfc3339(const struct fx_datetime_p *dt, fx_stream *
if (dt->dt_has_time) { if (dt->dt_has_time) {
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, "%02ld:%02ld:%02ld", dt->dt_hour, dt->dt_min, out,
NULL,
"%02ld:%02ld:%02ld",
dt->dt_hour,
dt->dt_min,
dt->dt_sec); dt->dt_sec);
if (dt->dt_msec > 0) { if (dt->dt_msec > 0) {
@@ -336,7 +347,9 @@ static enum fx_status encode_rfc3339(const struct fx_datetime_p *dt, fx_stream *
fx_stream_write_char(out, 'Z'); fx_stream_write_char(out, 'Z');
} else { } else {
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, "%c%02ld:%02ld", out,
NULL,
"%c%02ld:%02ld",
dt->dt_zone_offset_negative ? '-' : '+', dt->dt_zone_offset_negative ? '-' : '+',
dt->dt_zone_offset_hour, dt->dt_zone_offset_hour,
dt->dt_zone_offset_minute); dt->dt_zone_offset_minute);
@@ -348,7 +361,9 @@ static enum fx_status encode_rfc3339(const struct fx_datetime_p *dt, fx_stream *
} }
static void datetime_to_string( static void datetime_to_string(
const struct fx_datetime_p *dt, fx_datetime_format format, fx_stream *dest) const struct fx_datetime_p *dt,
fx_datetime_format format,
fx_stream *dest)
{ {
switch (format) { switch (format) {
case FX_DATETIME_FORMAT_RFC3339: case FX_DATETIME_FORMAT_RFC3339:
@@ -453,10 +468,16 @@ fx_datetime *fx_datetime_parse(enum fx_datetime_format format, const char *s)
} }
void fx_datetime_to_string( void fx_datetime_to_string(
const fx_datetime *dt, fx_datetime_format format, fx_stream *dest) const fx_datetime *dt,
fx_datetime_format format,
fx_stream *dest)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DATETIME, datetime_to_string, dt, format, dest); FX_TYPE_DATETIME,
datetime_to_string,
dt,
format,
dest);
} }
bool fx_datetime_is_localtime(const fx_datetime *dt) bool fx_datetime_is_localtime(const fx_datetime *dt)
@@ -512,17 +533,25 @@ long fx_datetime_subsecond(const fx_datetime *dt)
bool fx_datetime_zone_offset_is_negative(const fx_datetime *dt) bool fx_datetime_zone_offset_is_negative(const fx_datetime *dt)
{ {
FX_CLASS_DISPATCH_STATIC_0( FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DATETIME, datetime_zone_offset_is_negative, dt); FX_TYPE_DATETIME,
datetime_zone_offset_is_negative,
dt);
} }
long fx_datetime_zone_offset_hour(const fx_datetime *dt) long fx_datetime_zone_offset_hour(const fx_datetime *dt)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DATETIME, datetime_zone_offset_hour, dt); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DATETIME,
datetime_zone_offset_hour,
dt);
} }
long fx_datetime_zone_offset_minute(const fx_datetime *dt) long fx_datetime_zone_offset_minute(const fx_datetime *dt)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DATETIME, datetime_zone_offset_minute, dt); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DATETIME,
datetime_zone_offset_minute,
dt);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
@@ -543,8 +572,12 @@ static void _datetime_to_string(const fx_object *obj, fx_stream *out)
if (dt->dt_has_date) { if (dt->dt_has_date) {
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, "%04ld-%02ld-%02ld", dt->dt_year, out,
dt->dt_month, dt->dt_day); NULL,
"%04ld-%02ld-%02ld",
dt->dt_year,
dt->dt_month,
dt->dt_day);
} }
if (dt->dt_has_date && dt->dt_has_time) { if (dt->dt_has_date && dt->dt_has_time) {
@@ -553,7 +586,11 @@ static void _datetime_to_string(const fx_object *obj, fx_stream *out)
if (dt->dt_has_time) { if (dt->dt_has_time) {
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, "%02ld:%02ld:%02ld", dt->dt_hour, dt->dt_min, out,
NULL,
"%02ld:%02ld:%02ld",
dt->dt_hour,
dt->dt_min,
dt->dt_sec); dt->dt_sec);
if (dt->dt_msec > 0) { if (dt->dt_msec > 0) {
@@ -562,7 +599,9 @@ static void _datetime_to_string(const fx_object *obj, fx_stream *out)
if (!dt->dt_localtime) { if (!dt->dt_localtime) {
fx_stream_write_fmt( fx_stream_write_fmt(
out, NULL, " %c%02ld:%02ld", out,
NULL,
" %c%02ld:%02ld",
dt->dt_zone_offset_negative ? '-' : '+', dt->dt_zone_offset_negative ? '-' : '+',
dt->dt_zone_offset_hour, dt->dt_zone_offset_hour,
dt->dt_zone_offset_minute); dt->dt_zone_offset_minute);
+4 -4
View File
@@ -1,7 +1,7 @@
#include <fx/core/status.h> #include <fx/collections/dict.h>
#include <fx/core/stream.h> #include <fx/status.h>
#include <fx/ds/dict.h> #include <fx/stream.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
+92 -41
View File
@@ -1,7 +1,7 @@
#include <fx/core/misc.h> #include <fx/collections/hashmap.h>
#include <fx/core/status.h> #include <fx/misc.h>
#include <fx/ds/hashmap.h> #include <fx/status.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
@@ -42,9 +42,16 @@ struct fx_hashmap_iterator_p {
/*** PRIVATE FUNCTIONS ********************************************************/ /*** PRIVATE FUNCTIONS ********************************************************/
static FX_BST_DEFINE_SIMPLE_GET( static FX_BST_DEFINE_SIMPLE_GET(
struct fx_hashmap_bucket, uint64_t, bk_node, bk_hash, get_bucket); struct fx_hashmap_bucket,
uint64_t,
bk_node,
bk_hash,
get_bucket);
static FX_BST_DEFINE_SIMPLE_INSERT( static FX_BST_DEFINE_SIMPLE_INSERT(
struct fx_hashmap_bucket, bk_node, bk_hash, put_bucket); struct fx_hashmap_bucket,
bk_node,
bk_hash,
put_bucket);
static uint64_t hash_data(const void *p, size_t size) static uint64_t hash_data(const void *p, size_t size)
{ {
@@ -69,7 +76,8 @@ static uint64_t hash_key(const struct fx_hashmap_key *key)
} }
static bool compare_key( static bool compare_key(
const struct fx_hashmap_key *a, const struct fx_hashmap_key *b) const struct fx_hashmap_key *a,
const struct fx_hashmap_key *b)
{ {
const void *a_data = NULL, *fx_data = NULL; const void *a_data = NULL, *fx_data = NULL;
size_t a_len = 0, fx_len = 0; size_t a_len = 0, fx_len = 0;
@@ -99,8 +107,10 @@ static bool compare_key(
} }
static bool get_next_node( static bool get_next_node(
struct fx_bst_node *cur_node, struct fx_queue_entry *cur_entry, struct fx_bst_node *cur_node,
struct fx_bst_node **out_next_node, struct fx_queue_entry **out_next_entry) struct fx_queue_entry *cur_entry,
struct fx_bst_node **out_next_node,
struct fx_queue_entry **out_next_entry)
{ {
struct fx_hashmap_bucket *cur_bucket struct fx_hashmap_bucket *cur_bucket
= fx_unbox(struct fx_hashmap_bucket, cur_node, bk_node); = fx_unbox(struct fx_hashmap_bucket, cur_node, bk_node);
@@ -122,8 +132,10 @@ static bool get_next_node(
return false; return false;
} }
struct fx_hashmap_bucket *next_bucket struct fx_hashmap_bucket *next_bucket = fx_unbox(
= fx_unbox(struct fx_hashmap_bucket, next_node, bk_node); struct fx_hashmap_bucket,
next_node,
bk_node);
if (!next_bucket) { if (!next_bucket) {
return false; return false;
} }
@@ -169,11 +181,13 @@ static struct fx_hashmap_bucket_item *create_bucket_item(void)
} }
static fx_status hashmap_put( static fx_status hashmap_put(
struct fx_hashmap_p *hashmap, const fx_hashmap_key *key, struct fx_hashmap_p *hashmap,
const fx_hashmap_key *key,
const fx_hashmap_value *value) const fx_hashmap_value *value)
{ {
uint64_t hash = hash_key(key); uint64_t hash = hash_key(key);
struct fx_hashmap_bucket *bucket = get_bucket(&hashmap->h_buckets, hash); struct fx_hashmap_bucket *bucket
= get_bucket(&hashmap->h_buckets, hash);
if (!bucket) { if (!bucket) {
bucket = create_bucket(); bucket = create_bucket();
@@ -187,8 +201,10 @@ static fx_status hashmap_put(
struct fx_queue_entry *entry = fx_queue_first(&bucket->bk_items); struct fx_queue_entry *entry = fx_queue_first(&bucket->bk_items);
while (entry) { while (entry) {
struct fx_hashmap_bucket_item *item struct fx_hashmap_bucket_item *item = fx_unbox(
= fx_unbox(struct fx_hashmap_bucket_item, entry, bi_entry); struct fx_hashmap_bucket_item,
entry,
bi_entry);
if (compare_key(&item->bi_key, key)) { if (compare_key(&item->bi_key, key)) {
memcpy(&item->bi_value, value, sizeof *value); memcpy(&item->bi_value, value, sizeof *value);
@@ -213,19 +229,23 @@ static fx_status hashmap_put(
} }
static const struct fx_hashmap_value *hashmap_get( static const struct fx_hashmap_value *hashmap_get(
const struct fx_hashmap_p *hashmap, const struct fx_hashmap_key *key) const struct fx_hashmap_p *hashmap,
const struct fx_hashmap_key *key)
{ {
uint64_t hash = hash_key(key); uint64_t hash = hash_key(key);
struct fx_hashmap_bucket *bucket = get_bucket(&hashmap->h_buckets, hash); struct fx_hashmap_bucket *bucket
= get_bucket(&hashmap->h_buckets, hash);
if (!bucket) { if (!bucket) {
return NULL; return NULL;
} }
struct fx_queue_entry *entry = fx_queue_first(&bucket->bk_items); struct fx_queue_entry *entry = fx_queue_first(&bucket->bk_items);
while (entry) { while (entry) {
struct fx_hashmap_bucket_item *item struct fx_hashmap_bucket_item *item = fx_unbox(
= fx_unbox(struct fx_hashmap_bucket_item, entry, bi_entry); struct fx_hashmap_bucket_item,
entry,
bi_entry);
if (compare_key(&item->bi_key, key)) { if (compare_key(&item->bi_key, key)) {
return &item->bi_value; return &item->bi_value;
@@ -238,18 +258,22 @@ static const struct fx_hashmap_value *hashmap_get(
} }
static bool hashmap_has_key( static bool hashmap_has_key(
const struct fx_hashmap_p *hashmap, const fx_hashmap_key *key) const struct fx_hashmap_p *hashmap,
const fx_hashmap_key *key)
{ {
uint64_t hash = hash_key(key); uint64_t hash = hash_key(key);
struct fx_hashmap_bucket *bucket = get_bucket(&hashmap->h_buckets, hash); struct fx_hashmap_bucket *bucket
= get_bucket(&hashmap->h_buckets, hash);
if (!bucket) { if (!bucket) {
return false; return false;
} }
struct fx_queue_entry *entry = fx_queue_first(&bucket->bk_items); struct fx_queue_entry *entry = fx_queue_first(&bucket->bk_items);
while (entry) { while (entry) {
struct fx_hashmap_bucket_item *item struct fx_hashmap_bucket_item *item = fx_unbox(
= fx_unbox(struct fx_hashmap_bucket_item, entry, bi_entry); struct fx_hashmap_bucket_item,
entry,
bi_entry);
if (compare_key(&item->bi_key, key)) { if (compare_key(&item->bi_key, key)) {
return true; return true;
@@ -276,8 +300,10 @@ static bool hashmap_is_empty(const struct fx_hashmap_p *hashmap)
} }
fx_queue_entry *first_entry = fx_queue_first(&first_bucket->bk_items); fx_queue_entry *first_entry = fx_queue_first(&first_bucket->bk_items);
struct fx_hashmap_bucket_item *first_item struct fx_hashmap_bucket_item *first_item = fx_unbox(
= fx_unbox(struct fx_hashmap_bucket_item, first_entry, bi_entry); struct fx_hashmap_bucket_item,
first_entry,
bi_entry);
if (!first_item) { if (!first_item) {
return true; return true;
} }
@@ -286,7 +312,8 @@ static bool hashmap_is_empty(const struct fx_hashmap_p *hashmap)
} }
static fx_status delete_item( static fx_status delete_item(
struct fx_hashmap_p *hashmap, struct fx_hashmap_bucket *bucket, struct fx_hashmap_p *hashmap,
struct fx_hashmap_bucket *bucket,
struct fx_hashmap_bucket_item *item) struct fx_hashmap_bucket_item *item)
{ {
fx_queue_delete(&bucket->bk_items, &item->bi_entry); fx_queue_delete(&bucket->bk_items, &item->bi_entry);
@@ -313,7 +340,8 @@ static fx_status delete_item(
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_hashmap *fx_hashmap_create( fx_hashmap *fx_hashmap_create(
fx_hashmap_key_destructor key_dtor, fx_hashmap_value_destructor value_dtor) fx_hashmap_key_destructor key_dtor,
fx_hashmap_value_destructor value_dtor)
{ {
fx_hashmap *hashmap = fx_object_create(FX_TYPE_HASHMAP); fx_hashmap *hashmap = fx_object_create(FX_TYPE_HASHMAP);
if (!hashmap) { if (!hashmap) {
@@ -330,9 +358,11 @@ fx_hashmap *fx_hashmap_create_with_items(const fx_hashmap_item *items)
return NULL; return NULL;
} }
struct fx_hashmap_p *p = fx_object_get_private(hashmap, FX_TYPE_HASHMAP); struct fx_hashmap_p *p
= fx_object_get_private(hashmap, FX_TYPE_HASHMAP);
for (size_t i = 0; items[i].key.key_data && items[i].key.key_size; i++) { for (size_t i = 0; items[i].key.key_data && items[i].key.key_size;
i++) {
hashmap_put(p, &items[i].key, &items[i].value); hashmap_put(p, &items[i].key, &items[i].value);
} }
@@ -340,20 +370,32 @@ fx_hashmap *fx_hashmap_create_with_items(const fx_hashmap_item *items)
} }
fx_status fx_hashmap_put( fx_status fx_hashmap_put(
fx_hashmap *hashmap, const fx_hashmap_key *key, const fx_hashmap_value *value) fx_hashmap *hashmap,
const fx_hashmap_key *key,
const fx_hashmap_value *value)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_HASHMAP, hashmap_put, hashmap, key, value); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_HASHMAP,
hashmap_put,
hashmap,
key,
value);
} }
const struct fx_hashmap_value *fx_hashmap_get( const struct fx_hashmap_value *fx_hashmap_get(
const fx_hashmap *hashmap, const struct fx_hashmap_key *key) const fx_hashmap *hashmap,
const struct fx_hashmap_key *key)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_HASHMAP, hashmap_get, hashmap, key); FX_CLASS_DISPATCH_STATIC(FX_TYPE_HASHMAP, hashmap_get, hashmap, key);
} }
bool fx_hashmap_has_key(const fx_hashmap *hashmap, const fx_hashmap_key *key) bool fx_hashmap_has_key(const fx_hashmap *hashmap, const fx_hashmap_key *key)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_HASHMAP, hashmap_has_key, hashmap, key); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_HASHMAP,
hashmap_has_key,
hashmap,
key);
} }
size_t fx_hashmap_get_size(const fx_hashmap *hashmap) size_t fx_hashmap_get_size(const fx_hashmap *hashmap)
@@ -368,7 +410,8 @@ bool fx_hashmap_is_empty(const fx_hashmap *hashmap)
fx_iterator *fx_hashmap_begin(fx_hashmap *hashmap) fx_iterator *fx_hashmap_begin(fx_hashmap *hashmap)
{ {
fx_hashmap_iterator *it_obj = fx_object_create(FX_TYPE_HASHMAP_ITERATOR); fx_hashmap_iterator *it_obj
= fx_object_create(FX_TYPE_HASHMAP_ITERATOR);
struct fx_hashmap_iterator_p *it struct fx_hashmap_iterator_p *it
= fx_object_get_private(it_obj, FX_TYPE_HASHMAP_ITERATOR); = fx_object_get_private(it_obj, FX_TYPE_HASHMAP_ITERATOR);
@@ -391,9 +434,12 @@ fx_iterator *fx_hashmap_begin(fx_hashmap *hashmap)
return it_obj; return it_obj;
} }
struct fx_queue_entry *first_entry = fx_queue_first(&first_bucket->bk_items); struct fx_queue_entry *first_entry
struct fx_hashmap_bucket_item *first_item = fx_queue_first(&first_bucket->bk_items);
= fx_unbox(struct fx_hashmap_bucket_item, first_entry, bi_entry); struct fx_hashmap_bucket_item *first_item = fx_unbox(
struct fx_hashmap_bucket_item,
first_entry,
bi_entry);
if (!first_item) { if (!first_item) {
memset(&it->item, 0x0, sizeof it->item); memset(&it->item, 0x0, sizeof it->item);
fx_iterator_set_status(it_obj, FX_ERR_NO_DATA); fx_iterator_set_status(it_obj, FX_ERR_NO_DATA);
@@ -435,8 +481,11 @@ static void hashmap_fini(fx_object *obj, void *priv)
struct fx_queue_entry *entry = fx_queue_first(&b->bk_items); struct fx_queue_entry *entry = fx_queue_first(&b->bk_items);
while (entry) { while (entry) {
struct fx_hashmap_bucket_item *item = fx_unbox( struct fx_hashmap_bucket_item *item = fx_unbox(
struct fx_hashmap_bucket_item, entry, bi_entry); struct fx_hashmap_bucket_item,
struct fx_queue_entry *next_entry = fx_queue_next(entry); entry,
bi_entry);
struct fx_queue_entry *next_entry
= fx_queue_next(entry);
fx_queue_delete(&b->bk_items, entry); fx_queue_delete(&b->bk_items, entry);
if (map->h_key_dtor) { if (map->h_key_dtor) {
@@ -444,7 +493,8 @@ static void hashmap_fini(fx_object *obj, void *priv)
} }
if (map->h_value_dtor) { if (map->h_value_dtor) {
map->h_value_dtor((void *)item->bi_value.value_data); map->h_value_dtor(
(void *)item->bi_value.value_data);
} }
free(item); free(item);
@@ -524,7 +574,8 @@ static enum fx_status iterator_erase(fx_iterator *obj)
if (next_item) { if (next_item) {
memcpy(&it->item.key, &next_item->bi_key, sizeof it->item.key); memcpy(&it->item.key, &next_item->bi_key, sizeof it->item.key);
memcpy(&it->item.value, &next_item->bi_value, memcpy(&it->item.value,
&next_item->bi_value,
sizeof it->item.value); sizeof it->item.value);
it->_cbn = next_node; it->_cbn = next_node;
@@ -9,10 +9,10 @@
#ifndef FX_DS_ARRAY_H_ #ifndef FX_DS_ARRAY_H_
#define FX_DS_ARRAY_H_ #define FX_DS_ARRAY_H_
#include <fx/core/iterator.h> #include <fx/iterator.h>
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/status.h> #include <fx/status.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -51,11 +51,13 @@ FX_TYPE_DEFAULT_CONSTRUCTOR(fx_array, FX_TYPE_ARRAY);
* @return A pointer to the new fx_array, or NULL if an error occurred. * @return A pointer to the new fx_array, or NULL if an error occurred.
*/ */
FX_API fx_array *fx_array_create_with_values( FX_API fx_array *fx_array_create_with_values(
fx_object *const *values, size_t nr_values); fx_object *const *values,
size_t nr_values);
/** /**
* Remove all object references from an fx_array, resetting the size of the array to zero. * Remove all object references from an fx_array, resetting the size of the
* The reference counts of all objects in the array will be decremented. * array to zero. The reference counts of all objects in the array will be
* decremented.
* *
* @param array The fx_array to clear. * @param array The fx_array to clear.
*/ */
@@ -116,11 +118,12 @@ FX_API fx_status fx_array_remove(fx_array *array, size_t at);
/** /**
* Removes the object at the beginning of an fx_array. The reference count * Removes the object at the beginning of an fx_array. The reference count
* of the removed object will be decremented. The remaining objects will be moved * of the removed object will be decremented. The remaining objects will be
* to fill the empty space created by the object's removal. * moved to fill the empty space created by the object's removal.
* *
* @param array The fx_array to remove the object from. * @param array The fx_array to remove the object from.
* @return FX_SUCCESS if the object was removed, or a status code describing any error that occurred. * @return FX_SUCCESS if the object was removed, or a status code describing any
* error that occurred.
*/ */
FX_API fx_status fx_array_remove_front(fx_array *array); FX_API fx_status fx_array_remove_front(fx_array *array);
@@ -129,7 +132,8 @@ FX_API fx_status fx_array_remove_front(fx_array *array);
* of the removed object will be decremented. * of the removed object will be decremented.
* *
* @param array The fx_array to remove the object from. * @param array The fx_array to remove the object from.
* @return FX_SUCCESS if the object was removed, or a status code describing any error that occurred. * @return FX_SUCCESS if the object was removed, or a status code describing any
* error that occurred.
*/ */
FX_API fx_status fx_array_remove_back(fx_array *array); FX_API fx_status fx_array_remove_back(fx_array *array);
@@ -162,8 +166,8 @@ FX_API fx_object *fx_array_pop(fx_array *array, size_t at);
FX_API fx_object *fx_array_pop_front(fx_array *array); FX_API fx_object *fx_array_pop_front(fx_array *array);
/** /**
* Removes the object at the end of an fx_array, and returns a pointer to it. The * Removes the object at the end of an fx_array, and returns a pointer to it.
* reference count of the removed object will NOT be decremented. The caller * The reference count of the removed object will NOT be decremented. The caller
* becomes the owner of the array's reference to the object. * becomes the owner of the array's reference to the object.
* *
* @param array The fx_array to remove the object from. * @param array The fx_array to remove the object from.
@@ -1,7 +1,7 @@
#ifndef FX_DS_BITBUFFER_H_ #ifndef FX_DS_BITBUFFER_H_
#define FX_DS_BITBUFFER_H_ #define FX_DS_BITBUFFER_H_
#include <fx/core/macros.h> #include <fx/macros.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -13,12 +13,18 @@ FX_TYPE_CLASS_DECLARATION_END(fx_bitbuffer);
FX_API fx_status fx_bitbuffer_put_bit(fx_bitbuffer *buf, int bit); FX_API fx_status fx_bitbuffer_put_bit(fx_bitbuffer *buf, int bit);
FX_API fx_status fx_bitbuffer_put_bool(fx_bitbuffer *buf, bool b); FX_API fx_status fx_bitbuffer_put_bool(fx_bitbuffer *buf, bool b);
FX_API fx_status fx_bitbuffer_put_int( FX_API fx_status
fx_bitbuffer *buf, uint64_t v, unsigned int nr_bits); fx_bitbuffer_put_int(fx_bitbuffer *buf, uint64_t v, unsigned int nr_bits);
FX_API fx_status fx_bitbuffer_put_bytes( FX_API fx_status fx_bitbuffer_put_bytes(
fx_bitbuffer *buf, const void *p, size_t len, size_t bits_per_byte); fx_bitbuffer *buf,
const void *p,
size_t len,
size_t bits_per_byte);
FX_API fx_status fx_bitbuffer_put_string( FX_API fx_status fx_bitbuffer_put_string(
fx_bitbuffer *buf, const char *p, size_t len, size_t bits_per_char); fx_bitbuffer *buf,
const char *p,
size_t len,
size_t bits_per_char);
FX_DECLS_END; FX_DECLS_END;
@@ -1,8 +1,8 @@
#ifndef FX_DS_BITMAP_H_ #ifndef FX_DS_BITMAP_H_
#define FX_DS_BITMAP_H_ #define FX_DS_BITMAP_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <stdbool.h> #include <stdbool.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -21,7 +21,10 @@ FX_API fx_bitmap *fx_bitmap_create(size_t nr_bits);
FX_API void fx_bitmap_set_bit(fx_bitmap *map, size_t bit); FX_API void fx_bitmap_set_bit(fx_bitmap *map, size_t bit);
FX_API void fx_bitmap_clear_bit(fx_bitmap *map, size_t bit); FX_API void fx_bitmap_clear_bit(fx_bitmap *map, size_t bit);
FX_API void fx_bitmap_set_range(fx_bitmap *map, size_t first_bit, size_t nbits); FX_API void fx_bitmap_set_range(fx_bitmap *map, size_t first_bit, size_t nbits);
FX_API void fx_bitmap_clear_range(fx_bitmap *map, size_t first_bit, size_t nbits); FX_API void fx_bitmap_clear_range(
fx_bitmap *map,
size_t first_bit,
size_t nbits);
FX_API void fx_bitmap_set_all(fx_bitmap *map); FX_API void fx_bitmap_set_all(fx_bitmap *map);
FX_API void fx_bitmap_clear_all(fx_bitmap *map); FX_API void fx_bitmap_clear_all(fx_bitmap *map);
@@ -1,7 +1,7 @@
#ifndef FX_DS_BUFFER_H_ #ifndef FX_DS_BUFFER_H_
#define FX_DS_BUFFER_H_ #define FX_DS_BUFFER_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <stddef.h> #include <stddef.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -18,16 +18,19 @@ FX_API fx_type fx_buffer_get_type(void);
FX_API fx_buffer *fx_buffer_create(size_t item_sz); FX_API fx_buffer *fx_buffer_create(size_t item_sz);
FX_API fx_buffer *fx_buffer_create_from_bytes(const void *p, size_t len); FX_API fx_buffer *fx_buffer_create_from_bytes(const void *p, size_t len);
FX_API fx_buffer *fx_buffer_create_from_array( FX_API fx_buffer *fx_buffer_create_from_array(
const void *p, size_t item_sz, size_t len); const void *p,
size_t item_sz,
size_t len);
FX_API void *fx_buffer_steal(fx_buffer *buf); FX_API void *fx_buffer_steal(fx_buffer *buf);
FX_API fx_status fx_buffer_reserve(fx_buffer *buf, size_t capacity); FX_API fx_status fx_buffer_reserve(fx_buffer *buf, size_t capacity);
FX_API fx_status fx_buffer_resize(fx_buffer *buf, size_t length); FX_API fx_status fx_buffer_resize(fx_buffer *buf, size_t length);
FX_API fx_status fx_buffer_append(fx_buffer *dest, const void *p, size_t count); FX_API fx_status fx_buffer_append(fx_buffer *dest, const void *p, size_t count);
FX_API fx_status fx_buffer_prepend(fx_buffer *dest, const void *p, size_t count); FX_API fx_status
FX_API fx_status fx_buffer_insert( fx_buffer_prepend(fx_buffer *dest, const void *p, size_t count);
fx_buffer *dest, const void *p, size_t count, size_t at); FX_API fx_status
fx_buffer_insert(fx_buffer *dest, const void *p, size_t count, size_t at);
FX_API fx_status fx_buffer_remove(fx_buffer *dest, size_t at, size_t count); FX_API fx_status fx_buffer_remove(fx_buffer *dest, size_t at, size_t count);
FX_API fx_status fx_buffer_clear(fx_buffer *buf); FX_API fx_status fx_buffer_clear(fx_buffer *buf);
@@ -1,9 +1,9 @@
#ifndef FX_DS_DATETIME_H_ #ifndef FX_DS_DATETIME_H_
#define FX_DS_DATETIME_H_ #define FX_DS_DATETIME_H_
#include <fx/core/macros.h>
#include <fx/core/status.h>
#include <ctype.h> #include <ctype.h>
#include <fx/macros.h>
#include <fx/status.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -24,7 +24,8 @@ FX_TYPE_DEFAULT_CONSTRUCTOR(fx_datetime, FX_TYPE_DATETIME);
FX_API fx_datetime *fx_datetime_parse(fx_datetime_format format, const char *s); FX_API fx_datetime *fx_datetime_parse(fx_datetime_format format, const char *s);
FX_API void fx_datetime_to_string( FX_API void fx_datetime_to_string(
const fx_datetime *dt, fx_datetime_format format, const fx_datetime *dt,
fx_datetime_format format,
FX_TYPE_FWDREF(fx_stream) * dest); FX_TYPE_FWDREF(fx_stream) * dest);
FX_API bool fx_datetime_is_localtime(const fx_datetime *dt); FX_API bool fx_datetime_is_localtime(const fx_datetime *dt);
@@ -1,12 +1,12 @@
#ifndef FX_DS_DICT_H_ #ifndef FX_DS_DICT_H_
#define FX_DS_DICT_H_ #define FX_DS_DICT_H_
#include <fx/core/bst.h> #include <fx/bst.h>
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/queue.h> #include <fx/queue.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <fx/ds/string.h> #include <fx/string.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -29,7 +29,8 @@ FX_TYPE_CLASS_DECLARATION_END(fx_dict_iterator)
#define fx_dict_foreach(it, dict) \ #define fx_dict_foreach(it, dict) \
for (int z__fx_unique_name() = fx_dict_iterator_begin(dict, it); \ for (int z__fx_unique_name() = fx_dict_iterator_begin(dict, it); \
(it)->key != NULL; fx_dict_iterator_next(it)) (it)->key != NULL; \
fx_dict_iterator_next(it))
typedef struct fx_dict_item { typedef struct fx_dict_item {
const fx_string *key; const fx_string *key;
@@ -46,7 +47,8 @@ FX_API fx_dict *fx_dict_create_with_items(const fx_dict_item *items);
#endif #endif
FX_API fx_status fx_dict_put(fx_dict *dict, const char *key, fx_object *value); FX_API fx_status fx_dict_put(fx_dict *dict, const char *key, fx_object *value);
FX_API fx_status fx_dict_put_sk(fx_dict *dict, const fx_string *key, fx_object *value); FX_API fx_status
fx_dict_put_sk(fx_dict *dict, const fx_string *key, fx_object *value);
FX_API fx_object *fx_dict_at(const fx_dict *dict, const char *key); FX_API fx_object *fx_dict_at(const fx_dict *dict, const char *key);
FX_API fx_object *fx_dict_at_sk(const fx_dict *dict, const fx_string *key); FX_API fx_object *fx_dict_at_sk(const fx_dict *dict, const fx_string *key);
FX_API fx_object *fx_dict_get(fx_dict *dict, const char *key); FX_API fx_object *fx_dict_get(fx_dict *dict, const char *key);
@@ -1,11 +1,11 @@
#ifndef FX_DS_HASHMAP_H_ #ifndef FX_DS_HASHMAP_H_
#define FX_DS_HASHMAP_H_ #define FX_DS_HASHMAP_H_
#include <fx/core/bst.h> #include <fx/bst.h>
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/queue.h> #include <fx/queue.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <stddef.h> #include <stddef.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -34,7 +34,8 @@ FX_TYPE_CLASS_DECLARATION_END(fx_hashmap_iterator)
#define fx_hashmap_foreach(it, hashmap) \ #define fx_hashmap_foreach(it, hashmap) \
for (int z__fx_unique_name() = fx_hashmap_iterator_begin(hashmap, it); \ for (int z__fx_unique_name() = fx_hashmap_iterator_begin(hashmap, it); \
(it)->key != NULL; fx_hashmap_iterator_next(it)) (it)->key != NULL; \
fx_hashmap_iterator_next(it))
typedef void (*fx_hashmap_key_destructor)(void *); typedef void (*fx_hashmap_key_destructor)(void *);
typedef void (*fx_hashmap_value_destructor)(void *); typedef void (*fx_hashmap_value_destructor)(void *);
@@ -63,15 +64,21 @@ FX_API fx_type fx_hashmap_get_type(void);
FX_API fx_type fx_hashmap_iterator_get_type(void); FX_API fx_type fx_hashmap_iterator_get_type(void);
FX_API fx_hashmap *fx_hashmap_create( FX_API fx_hashmap *fx_hashmap_create(
fx_hashmap_key_destructor key_dtor, fx_hashmap_value_destructor value_dtor); fx_hashmap_key_destructor key_dtor,
fx_hashmap_value_destructor value_dtor);
FX_API fx_hashmap *fx_hashmap_create_with_items(const fx_hashmap_item *items); FX_API fx_hashmap *fx_hashmap_create_with_items(const fx_hashmap_item *items);
FX_API fx_status fx_hashmap_put( FX_API fx_status fx_hashmap_put(
fx_hashmap *hashmap, const fx_hashmap_key *key, const fx_hashmap_value *value); fx_hashmap *hashmap,
const fx_hashmap_key *key,
const fx_hashmap_value *value);
FX_API const fx_hashmap_value *fx_hashmap_get( FX_API const fx_hashmap_value *fx_hashmap_get(
const fx_hashmap *hashmap, const fx_hashmap_key *key); const fx_hashmap *hashmap,
const fx_hashmap_key *key);
FX_API bool fx_hashmap_has_key(const fx_hashmap *hashmap, const fx_hashmap_key *key); FX_API bool fx_hashmap_has_key(
const fx_hashmap *hashmap,
const fx_hashmap_key *key);
FX_API size_t fx_hashmap_get_size(const fx_hashmap *hashmap); FX_API size_t fx_hashmap_get_size(const fx_hashmap *hashmap);
FX_API bool fx_hashmap_is_empty(const fx_hashmap *hashmap); FX_API bool fx_hashmap_is_empty(const fx_hashmap *hashmap);
@@ -1,9 +1,9 @@
#ifndef FX_DS_LIST_H_ #ifndef FX_DS_LIST_H_
#define FX_DS_LIST_H_ #define FX_DS_LIST_H_
#include <fx/core/iterator.h> #include <fx/iterator.h>
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/status.h> #include <fx/status.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -39,9 +39,13 @@ FX_API fx_list_entry *fx_list_prev(const fx_list_entry *entry);
FX_API size_t fx_list_length(const fx_list *q); FX_API size_t fx_list_length(const fx_list *q);
FX_API fx_list_entry *fx_list_insert_before( FX_API fx_list_entry *fx_list_insert_before(
fx_list *q, void *ptr, fx_list_entry *before); fx_list *q,
void *ptr,
fx_list_entry *before);
FX_API fx_list_entry *fx_list_insert_after( FX_API fx_list_entry *fx_list_insert_after(
fx_list *q, void *ptr, fx_list_entry *after); fx_list *q,
void *ptr,
fx_list_entry *after);
FX_API fx_list_entry *fx_list_push_front(fx_list *q, void *ptr); FX_API fx_list_entry *fx_list_push_front(fx_list *q, void *ptr);
FX_API fx_list_entry *fx_list_push_back(fx_list *q, void *ptr); FX_API fx_list_entry *fx_list_push_back(fx_list *q, void *ptr);
@@ -1,7 +1,7 @@
#ifndef FX_DS_NUMBER_H #ifndef FX_DS_NUMBER_H
#define FX_DS_NUMBER_H #define FX_DS_NUMBER_H
#include <fx/core/macros.h> #include <fx/macros.h>
#include <stdbool.h> #include <stdbool.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -133,7 +133,9 @@ static inline fx_number *fx_number_create_size_t(size_t value)
FX_API fx_number_type fx_number_get_number_type(const fx_number *number); FX_API fx_number_type fx_number_get_number_type(const fx_number *number);
FX_API int fx_number_get_value( FX_API int fx_number_get_value(
const fx_number *number, fx_number_type type, void *value_ptr); const fx_number *number,
fx_number_type type,
void *value_ptr);
static inline int8_t fx_number_get_int8(const fx_number *number) static inline int8_t fx_number_get_int8(const fx_number *number)
{ {
@@ -1,10 +1,10 @@
#ifndef FX_DS_TREE_H_ #ifndef FX_DS_TREE_H_
#define FX_DS_TREE_H_ #define FX_DS_TREE_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/queue.h> #include <fx/queue.h>
#include <fx/ds/string.h> #include <fx/string.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -50,7 +50,8 @@ FX_API fx_iterator *fx_tree_node_begin(fx_tree_node *node);
FX_API const fx_iterator *fx_tree_node_cbegin(const fx_tree_node *node); FX_API const fx_iterator *fx_tree_node_cbegin(const fx_tree_node *node);
FX_API fx_iterator *fx_tree_node_begin_recursive(fx_tree_node *node); FX_API fx_iterator *fx_tree_node_begin_recursive(fx_tree_node *node);
FX_API const fx_iterator *fx_tree_node_cbegin_recursive(const fx_tree_node *node); FX_API const fx_iterator *fx_tree_node_cbegin_recursive(
const fx_tree_node *node);
FX_DECLS_END; FX_DECLS_END;
@@ -1,9 +1,9 @@
#ifndef FX_DS_UUID_H_ #ifndef FX_DS_UUID_H_
#define FX_DS_UUID_H_ #define FX_DS_UUID_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <fx/ds/string.h> #include <fx/string.h>
#define FX_UUID_NBYTES 16 #define FX_UUID_NBYTES 16
#define FX_UUID_STRING_MAX 37 #define FX_UUID_STRING_MAX 37
@@ -29,19 +29,34 @@ FX_API fx_type fx_uuid_get_type(void);
FX_TYPE_DEFAULT_CONSTRUCTOR(fx_uuid, FX_TYPE_UUID); FX_TYPE_DEFAULT_CONSTRUCTOR(fx_uuid, FX_TYPE_UUID);
FX_API fx_uuid *fx_uuid_create_from_bytes( FX_API fx_uuid *fx_uuid_create_from_bytes(
unsigned char u00, unsigned char u01, unsigned char u02, unsigned char u00,
unsigned char u03, unsigned char u04, unsigned char u05, unsigned char u01,
unsigned char u06, unsigned char u07, unsigned char u08, unsigned char u02,
unsigned char u09, unsigned char u10, unsigned char u11, unsigned char u12, unsigned char u03,
unsigned char u13, unsigned char u14, unsigned char u15); unsigned char u04,
FX_API fx_uuid *fx_uuid_create_from_bytev(const unsigned char bytes[FX_UUID_NBYTES]); unsigned char u05,
unsigned char u06,
unsigned char u07,
unsigned char u08,
unsigned char u09,
unsigned char u10,
unsigned char u11,
unsigned char u12,
unsigned char u13,
unsigned char u14,
unsigned char u15);
FX_API fx_uuid *fx_uuid_create_from_bytev(
const unsigned char bytes[FX_UUID_NBYTES]);
FX_API fx_uuid *fx_uuid_create_from_uuid_bytes(const fx_uuid_bytes *bytes); FX_API fx_uuid *fx_uuid_create_from_uuid_bytes(const fx_uuid_bytes *bytes);
FX_API fx_uuid *fx_uuid_create_from_string(const fx_string *string); FX_API fx_uuid *fx_uuid_create_from_string(const fx_string *string);
FX_API fx_uuid *fx_uuid_create_from_cstr(const char *s); FX_API fx_uuid *fx_uuid_create_from_cstr(const char *s);
FX_API fx_status fx_uuid_to_cstr(const fx_uuid *uuid, char out[FX_UUID_STRING_MAX]); FX_API fx_status fx_uuid_to_cstr(
const fx_uuid *uuid,
char out[FX_UUID_STRING_MAX]);
FX_API void fx_uuid_get_bytes( FX_API void fx_uuid_get_bytes(
const fx_uuid *uuid, unsigned char bytes[FX_UUID_NBYTES]); const fx_uuid *uuid,
unsigned char bytes[FX_UUID_NBYTES]);
FX_API void fx_uuid_get_uuid_bytes(const fx_uuid *uuid, fx_uuid_bytes *bytes); FX_API void fx_uuid_get_uuid_bytes(const fx_uuid *uuid, fx_uuid_bytes *bytes);
FX_API fx_uuid_bytes *fx_uuid_ptr(fx_uuid *uuid); FX_API fx_uuid_bytes *fx_uuid_ptr(fx_uuid *uuid);
+30 -10
View File
@@ -1,6 +1,6 @@
#include <fx/core/iterator.h> #include <fx/collections/list.h>
#include <fx/core/queue.h> #include <fx/iterator.h>
#include <fx/ds/list.h> #include <fx/queue.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -109,7 +109,9 @@ static struct fx_list_entry *make_entry(void *item)
} }
static struct fx_list_entry *list_insert_before( static struct fx_list_entry *list_insert_before(
struct fx_list_p *q, void *ptr, struct fx_list_entry *before) struct fx_list_p *q,
void *ptr,
struct fx_list_entry *before)
{ {
struct fx_list_entry *entry = make_entry(ptr); struct fx_list_entry *entry = make_entry(ptr);
if (!entry) { if (!entry) {
@@ -122,7 +124,9 @@ static struct fx_list_entry *list_insert_before(
} }
static struct fx_list_entry *list_insert_after( static struct fx_list_entry *list_insert_after(
struct fx_list_p *q, void *ptr, struct fx_list_entry *after) struct fx_list_p *q,
void *ptr,
struct fx_list_entry *after)
{ {
struct fx_list_entry *entry = make_entry(ptr); struct fx_list_entry *entry = make_entry(ptr);
if (!entry) { if (!entry) {
@@ -226,7 +230,9 @@ static fx_status list_delete_item(struct fx_list_p *q, void *ptr)
return FX_SUCCESS; return FX_SUCCESS;
} }
static fx_status list_delete_entry(struct fx_list_p *q, struct fx_list_entry *entry) static fx_status list_delete_entry(
struct fx_list_p *q,
struct fx_list_entry *entry)
{ {
fx_queue_delete(&q->l_queue, &entry->e_entry); fx_queue_delete(&q->l_queue, &entry->e_entry);
q->l_len--; q->l_len--;
@@ -314,15 +320,29 @@ size_t fx_list_length(const fx_list *q)
} }
struct fx_list_entry *fx_list_insert_before( struct fx_list_entry *fx_list_insert_before(
fx_list *q, void *ptr, struct fx_list_entry *before) fx_list *q,
void *ptr,
struct fx_list_entry *before)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_LIST, list_insert_before, q, ptr, before); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_LIST,
list_insert_before,
q,
ptr,
before);
} }
struct fx_list_entry *fx_list_insert_after( struct fx_list_entry *fx_list_insert_after(
fx_list *q, void *ptr, struct fx_list_entry *after) fx_list *q,
void *ptr,
struct fx_list_entry *after)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_LIST, list_insert_after, q, ptr, after); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_LIST,
list_insert_after,
q,
ptr,
after);
} }
struct fx_list_entry *fx_list_push_front(fx_list *q, void *ptr) struct fx_list_entry *fx_list_push_front(fx_list *q, void *ptr)
+2 -2
View File
@@ -1,5 +1,5 @@
#include <fx/core/stream.h> #include <fx/collections/number.h>
#include <fx/ds/number.h> #include <fx/stream.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
+17 -7
View File
@@ -1,4 +1,4 @@
#include <fx/ds/tree.h> #include <fx/collections/tree.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -33,7 +33,9 @@ static void tree_set_root(struct fx_tree_p *tree, struct fx_tree_node *node)
} }
static const struct fx_tree_node *next_node( static const struct fx_tree_node *next_node(
const struct fx_tree_node *node, bool recursive, int *depth_diff) const struct fx_tree_node *node,
bool recursive,
int *depth_diff)
{ {
if (!node) { if (!node) {
return NULL; return NULL;
@@ -101,7 +103,8 @@ static void remove_node(struct fx_tree_node *node)
} }
static void reparent_children( static void reparent_children(
struct fx_tree_node *old_parent, struct fx_tree_node *new_parent) struct fx_tree_node *old_parent,
struct fx_tree_node *new_parent)
{ {
struct fx_tree_node *last = NODE_FIRST_CHILD(new_parent); struct fx_tree_node *last = NODE_FIRST_CHILD(new_parent);
while (last && NODE_NEXT_SIBLING(last)) { while (last && NODE_NEXT_SIBLING(last)) {
@@ -132,7 +135,9 @@ void fx_tree_set_root(fx_tree *tree, struct fx_tree_node *node)
FX_CLASS_DISPATCH_STATIC(FX_TYPE_TREE, tree_set_root, tree, node); FX_CLASS_DISPATCH_STATIC(FX_TYPE_TREE, tree_set_root, tree, node);
} }
void fx_tree_node_add_child(struct fx_tree_node *parent, struct fx_tree_node *child) void fx_tree_node_add_child(
struct fx_tree_node *parent,
struct fx_tree_node *child)
{ {
if (NODE_PARENT(child)) { if (NODE_PARENT(child)) {
return; return;
@@ -152,7 +157,9 @@ void fx_tree_node_add_child(struct fx_tree_node *parent, struct fx_tree_node *ch
NODE_NEXT_SIBLING(cur) = child; NODE_NEXT_SIBLING(cur) = child;
} }
void fx_tree_node_add_sibling(struct fx_tree_node *node, struct fx_tree_node *to_add) void fx_tree_node_add_sibling(
struct fx_tree_node *node,
struct fx_tree_node *to_add)
{ {
if (NODE_PARENT(to_add) || !NODE_PARENT(node)) { if (NODE_PARENT(to_add) || !NODE_PARENT(node)) {
return; return;
@@ -161,7 +168,9 @@ void fx_tree_node_add_sibling(struct fx_tree_node *node, struct fx_tree_node *to
fx_tree_node_add_child(NODE_PARENT(node), to_add); fx_tree_node_add_child(NODE_PARENT(node), to_add);
} }
struct fx_tree_node *fx_tree_node_get_child(struct fx_tree_node *node, size_t at) struct fx_tree_node *fx_tree_node_get_child(
struct fx_tree_node *node,
size_t at)
{ {
size_t i = 0; size_t i = 0;
struct fx_tree_node *cur = NODE_FIRST_CHILD(node); struct fx_tree_node *cur = NODE_FIRST_CHILD(node);
@@ -233,7 +242,8 @@ fx_iterator *fx_tree_node_begin_recursive(struct fx_tree_node *node)
return it_obj; return it_obj;
} }
const fx_iterator *fx_tree_node_cbegin_recursive(const struct fx_tree_node *node) const fx_iterator *fx_tree_node_cbegin_recursive(
const struct fx_tree_node *node)
{ {
return fx_tree_node_begin_recursive((struct fx_tree_node *)node); return fx_tree_node_begin_recursive((struct fx_tree_node *)node);
} }
+3 -3
View File
@@ -1,7 +1,7 @@
#include <ctype.h> #include <ctype.h>
#include <fx/core/stringstream.h> #include <fx/collections/uuid.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <fx/ds/uuid.h> #include <fx/stringstream.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
+20
View File
@@ -0,0 +1,20 @@
include(../cmake/Templates.cmake)
find_package(ZSTD)
if (ZSTD_FOUND)
set(internal_libs ${libs} ${ZSTD_LIBRARY})
set(internal_include_dirs ${include_dirs} ${ZSTD_INCLUDE_DIR})
set(internal_defines ${defines} FX_COMPRESSOR_SUPPORTED_ZSTD)
set(namespace_sources ${namespace_sources} ${CMAKE_CURRENT_SOURCE_DIR}/function/zstd.c)
message(STATUS "Enabling ZSTD support in fx.compression")
endif ()
#add_fx_module(
# NAME compress
# DEPENDENCIES core
# EXTRA_SOURCES ${function_sources}
# DEFINES ${defines}
# LIBS ${libs}
# INCLUDE_DIRS ${include_dirs})
export_fx_namespace_details(fx.compression)
@@ -1,6 +1,6 @@
#include <assert.h> #include <assert.h>
#include <fx/compress/compressor.h> #include <fx/compression/compressor.h>
#include <fx/core/ringbuffer.h> #include <fx/ringbuffer.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -36,16 +36,21 @@ struct compressor_data {
/*** PRIVATE FUNCTIONS ********************************************************/ /*** PRIVATE FUNCTIONS ********************************************************/
static enum fx_status compressor_get_data( static enum fx_status compressor_get_data(
fx_compressor *compressor, struct compressor_data *out) fx_compressor *compressor,
struct compressor_data *out)
{ {
out->c_obj = compressor; out->c_obj = compressor;
return fx_object_get_data( return fx_object_get_data(
compressor, FX_TYPE_COMPRESSOR, NULL, (void **)&out->c_data, compressor,
FX_TYPE_COMPRESSOR,
NULL,
(void **)&out->c_data,
(void **)&out->c_ops); (void **)&out->c_ops);
} }
static enum fx_status compressor_get_mode( static enum fx_status compressor_get_mode(
struct compressor_data *p, enum fx_compressor_mode *out) struct compressor_data *p,
enum fx_compressor_mode *out)
{ {
if (out) { if (out) {
*out = p->c_data->c_mode; *out = p->c_data->c_mode;
@@ -55,7 +60,8 @@ static enum fx_status compressor_get_mode(
} }
static enum fx_status compressor_set_mode( static enum fx_status compressor_set_mode(
struct compressor_data *p, enum fx_compressor_mode mode) struct compressor_data *p,
enum fx_compressor_mode mode)
{ {
if (!p->c_ops->c_set_mode) { if (!p->c_ops->c_set_mode) {
return FX_ERR_NOT_SUPPORTED; return FX_ERR_NOT_SUPPORTED;
@@ -65,7 +71,9 @@ static enum fx_status compressor_set_mode(
} }
static enum fx_status compressor_set_buffer( static enum fx_status compressor_set_buffer(
struct compressor_data *p, fx_ringbuffer *inbuf, fx_ringbuffer *outbuf) struct compressor_data *p,
fx_ringbuffer *inbuf,
fx_ringbuffer *outbuf)
{ {
p->c_data->c_in = inbuf; p->c_data->c_in = inbuf;
p->c_data->c_out = outbuf; p->c_data->c_out = outbuf;
@@ -154,14 +162,18 @@ static bool compressor_eof(const struct compressor_data *p)
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
enum fx_status fx_compressor_get_buffer_size( enum fx_status fx_compressor_get_buffer_size(
fx_type type, fx_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size) fx_type type,
fx_compressor_mode mode,
size_t *inbuf_size,
size_t *outbuf_size)
{ {
fx_class *c = fx_class_get(type); fx_class *c = fx_class_get(type);
if (!c) { if (!c) {
return FX_ERR_INVALID_ARGUMENT; return FX_ERR_INVALID_ARGUMENT;
} }
fx_compressor_class *ops = fx_class_get_interface(c, FX_TYPE_COMPRESSOR); fx_compressor_class *ops
= fx_class_get_interface(c, FX_TYPE_COMPRESSOR);
if (!ops) { if (!ops) {
return FX_ERR_INVALID_ARGUMENT; return FX_ERR_INVALID_ARGUMENT;
} }
@@ -174,22 +186,32 @@ enum fx_status fx_compressor_get_buffer_size(
} }
enum fx_status fx_compressor_get_mode( enum fx_status fx_compressor_get_mode(
const fx_compressor *compressor, enum fx_compressor_mode *out) const fx_compressor *compressor,
enum fx_compressor_mode *out)
{ {
COMPRESSOR_DISPATCH_STATIC( COMPRESSOR_DISPATCH_STATIC(
compressor_get_mode, (fx_compressor *)compressor, out); compressor_get_mode,
(fx_compressor *)compressor,
out);
} }
enum fx_status fx_compressor_set_mode( enum fx_status fx_compressor_set_mode(
fx_compressor *compressor, enum fx_compressor_mode mode) fx_compressor *compressor,
enum fx_compressor_mode mode)
{ {
COMPRESSOR_DISPATCH_STATIC(compressor_set_mode, compressor, mode); COMPRESSOR_DISPATCH_STATIC(compressor_set_mode, compressor, mode);
} }
enum fx_status fx_compressor_set_buffer( enum fx_status fx_compressor_set_buffer(
fx_compressor *compressor, fx_ringbuffer *inbuf, fx_ringbuffer *outbuf) fx_compressor *compressor,
fx_ringbuffer *inbuf,
fx_ringbuffer *outbuf)
{ {
COMPRESSOR_DISPATCH_STATIC(compressor_set_buffer, compressor, inbuf, outbuf); COMPRESSOR_DISPATCH_STATIC(
compressor_set_buffer,
compressor,
inbuf,
outbuf);
} }
enum fx_status fx_compressor_step(fx_compressor *compressor) enum fx_status fx_compressor_step(fx_compressor *compressor)
@@ -209,7 +231,9 @@ enum fx_status fx_compressor_reset(fx_compressor *compressor)
bool fx_compressor_eof(const fx_compressor *compressor) bool fx_compressor_eof(const fx_compressor *compressor)
{ {
COMPRESSOR_DISPATCH_STATIC_0(compressor_eof, (fx_compressor *)compressor); COMPRESSOR_DISPATCH_STATIC_0(
compressor_eof,
(fx_compressor *)compressor);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
+182 -57
View File
@@ -1,5 +1,5 @@
#include <fx/compress/compressor.h> #include <fx/compression/compressor.h>
#include <fx/compress/cstream.h> #include <fx/compression/cstream.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -17,8 +17,8 @@ struct fx_cstream_p {
* *
* the input buffer holds data that will be provided to the * the input buffer holds data that will be provided to the
* (de)compression function. in compression mode, this data is provided * (de)compression function. in compression mode, this data is provided
* by the code using the cstream (via fx_cstream_write). in decompression * by the code using the cstream (via fx_cstream_write). in
* mode, this data is read from s_endpoint. * decompression mode, this data is read from s_endpoint.
* *
* the output buffer holds data produced by the (de)compression * the output buffer holds data produced by the (de)compression
* function. in compression mode, this data will be written to * function. in compression mode, this data will be written to
@@ -27,7 +27,8 @@ struct fx_cstream_p {
* *
* heavy usage of cstream's compressed sections facility can result * heavy usage of cstream's compressed sections facility can result
* in the input buffer holding uncompressed data while the stream is in * in the input buffer holding uncompressed data while the stream is in
* decompression mode. this is handled by the uncompressed read code path. * decompression mode. this is handled by the uncompressed read code
* path.
*/ */
fx_ringbuffer *s_in, *s_out; fx_ringbuffer *s_in, *s_out;
fx_compressor_mode s_mode; fx_compressor_mode s_mode;
@@ -78,13 +79,23 @@ struct fx_cstream_p {
/*** PRIVATE FUNCTIONS ********************************************************/ /*** PRIVATE FUNCTIONS ********************************************************/
static enum fx_status read_cursor( static enum fx_status read_cursor(
struct fx_cstream_p *stream, void *buf, size_t count, size_t *out_nr_read) struct fx_cstream_p *stream,
void *buf,
size_t count,
size_t *out_nr_read)
{ {
return fx_stream_read_bytes(stream->s_endpoint, buf, count, out_nr_read); return fx_stream_read_bytes(
stream->s_endpoint,
buf,
count,
out_nr_read);
} }
static enum fx_status read_uncompressed( static enum fx_status read_uncompressed(
struct fx_cstream_p *stream, void *buf, size_t count, size_t *out_nr_read) struct fx_cstream_p *stream,
void *buf,
size_t count,
size_t *out_nr_read)
{ {
size_t remaining = count; size_t remaining = count;
unsigned char *dest = buf; unsigned char *dest = buf;
@@ -101,7 +112,9 @@ static enum fx_status read_uncompressed(
const void *data; const void *data;
size_t available; size_t available;
status = fx_ringbuffer_open_read_buffer( status = fx_ringbuffer_open_read_buffer(
stream->s_in, &data, &available); stream->s_in,
&data,
&available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
@@ -128,7 +141,10 @@ static enum fx_status read_uncompressed(
} }
status = fx_stream_read_bytes( status = fx_stream_read_bytes(
stream->s_endpoint, dest, remaining, &nr_read_from_endpoint); stream->s_endpoint,
dest,
remaining,
&nr_read_from_endpoint);
stream->s_tx_bytes_uncompressed += nr_read_from_endpoint; stream->s_tx_bytes_uncompressed += nr_read_from_endpoint;
stream->s_tx_bytes += nr_read_from_endpoint; stream->s_tx_bytes += nr_read_from_endpoint;
@@ -150,14 +166,19 @@ static enum fx_status refill_input_buffer(struct fx_cstream_p *stream)
void *data; void *data;
size_t capacity; size_t capacity;
status = fx_ringbuffer_open_write_buffer( status = fx_ringbuffer_open_write_buffer(
stream->s_in, &data, &capacity); stream->s_in,
&data,
&capacity);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
size_t r = 0; size_t r = 0;
status = fx_stream_read_bytes( status = fx_stream_read_bytes(
stream->s_endpoint, data, capacity, &r); stream->s_endpoint,
data,
capacity,
&r);
fx_ringbuffer_close_write_buffer(stream->s_in, &data, r); fx_ringbuffer_close_write_buffer(stream->s_in, &data, r);
nr_read += r; nr_read += r;
@@ -196,9 +217,11 @@ static enum fx_status refill_output_buffer(struct fx_cstream_p *stream)
return status; return status;
} }
size_t bytes_before = fx_ringbuffer_available_data_remaining(stream->s_in); size_t bytes_before
= fx_ringbuffer_available_data_remaining(stream->s_in);
status = fx_compressor_step(stream->s_compressor); status = fx_compressor_step(stream->s_compressor);
size_t bytes_after = fx_ringbuffer_available_data_remaining(stream->s_in); size_t bytes_after
= fx_ringbuffer_available_data_remaining(stream->s_in);
stream->s_tx_bytes_compressed += (bytes_before - bytes_after); stream->s_tx_bytes_compressed += (bytes_before - bytes_after);
stream->s_tx_bytes += (bytes_before - bytes_after); stream->s_tx_bytes += (bytes_before - bytes_after);
@@ -207,7 +230,10 @@ static enum fx_status refill_output_buffer(struct fx_cstream_p *stream)
} }
static enum fx_status cstream_read( static enum fx_status cstream_read(
struct fx_cstream_p *stream, void *buf, size_t count, size_t *out_nr_read) struct fx_cstream_p *stream,
void *buf,
size_t count,
size_t *out_nr_read)
{ {
if (stream->s_mode != FX_COMPRESSOR_MODE_DECOMPRESS) { if (stream->s_mode != FX_COMPRESSOR_MODE_DECOMPRESS) {
return FX_ERR_BAD_STATE; return FX_ERR_BAD_STATE;
@@ -238,7 +264,9 @@ static enum fx_status cstream_read(
const void *data; const void *data;
size_t available; size_t available;
status = fx_ringbuffer_open_read_buffer( status = fx_ringbuffer_open_read_buffer(
stream->s_out, &data, &available); stream->s_out,
&data,
&available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
@@ -267,13 +295,23 @@ static enum fx_status cstream_read(
} }
static enum fx_status write_cursor( static enum fx_status write_cursor(
struct fx_cstream_p *stream, const void *buf, size_t count, size_t *nr_written) struct fx_cstream_p *stream,
const void *buf,
size_t count,
size_t *nr_written)
{ {
return fx_stream_write_bytes(stream->s_endpoint, buf, count, nr_written); return fx_stream_write_bytes(
stream->s_endpoint,
buf,
count,
nr_written);
} }
static enum fx_status write_uncompressed( static enum fx_status write_uncompressed(
struct fx_cstream_p *stream, const void *buf, size_t count, size_t *nr_written) struct fx_cstream_p *stream,
const void *buf,
size_t count,
size_t *nr_written)
{ {
size_t w = 0; size_t w = 0;
enum fx_status status enum fx_status status
@@ -307,14 +345,19 @@ static enum fx_status flush_output_buffer(struct fx_cstream_p *stream)
const void *data; const void *data;
size_t capacity; size_t capacity;
status = fx_ringbuffer_open_read_buffer( status = fx_ringbuffer_open_read_buffer(
stream->s_out, &data, &capacity); stream->s_out,
&data,
&capacity);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
size_t w = 0; size_t w = 0;
status = fx_stream_write_bytes( status = fx_stream_write_bytes(
stream->s_endpoint, data, capacity, &w); stream->s_endpoint,
data,
capacity,
&w);
fx_ringbuffer_close_read_buffer(stream->s_out, &data, w); fx_ringbuffer_close_read_buffer(stream->s_out, &data, w);
nr_written += w; nr_written += w;
@@ -338,7 +381,9 @@ static enum fx_status flush_output_buffer(struct fx_cstream_p *stream)
} }
static enum fx_status cstream_write( static enum fx_status cstream_write(
struct fx_cstream_p *stream, const void *buf, size_t count, struct fx_cstream_p *stream,
const void *buf,
size_t count,
size_t *out_nr_written) size_t *out_nr_written)
{ {
if (stream->s_mode != FX_COMPRESSOR_MODE_COMPRESS) { if (stream->s_mode != FX_COMPRESSOR_MODE_COMPRESS) {
@@ -374,7 +419,9 @@ static enum fx_status cstream_write(
void *data; void *data;
size_t available; size_t available;
status = fx_ringbuffer_open_write_buffer( status = fx_ringbuffer_open_write_buffer(
stream->s_in, &data, &available); stream->s_in,
&data,
&available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
@@ -403,7 +450,9 @@ static enum fx_status cstream_write(
} }
static enum fx_status skip_uncompressed( static enum fx_status skip_uncompressed(
struct fx_cstream_p *stream, size_t count, size_t *out_nr_skipped) struct fx_cstream_p *stream,
size_t count,
size_t *out_nr_skipped)
{ {
size_t remaining = count; size_t remaining = count;
size_t nr_read_from_buf = 0; size_t nr_read_from_buf = 0;
@@ -419,7 +468,9 @@ static enum fx_status skip_uncompressed(
const void *data; const void *data;
size_t available; size_t available;
status = fx_ringbuffer_open_read_buffer( status = fx_ringbuffer_open_read_buffer(
stream->s_in, &data, &available); stream->s_in,
&data,
&available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
@@ -447,7 +498,10 @@ static enum fx_status skip_uncompressed(
size_t cursor = fx_stream_cursor(stream->s_endpoint); size_t cursor = fx_stream_cursor(stream->s_endpoint);
status = fx_stream_seek(stream->s_endpoint, remaining, FX_STREAM_SEEK_CURRENT); status = fx_stream_seek(
stream->s_endpoint,
remaining,
FX_STREAM_SEEK_CURRENT);
nr_read_from_endpoint = fx_stream_cursor(stream->s_endpoint) - cursor; nr_read_from_endpoint = fx_stream_cursor(stream->s_endpoint) - cursor;
stream->s_tx_bytes_uncompressed += nr_read_from_endpoint; stream->s_tx_bytes_uncompressed += nr_read_from_endpoint;
stream->s_tx_bytes += nr_read_from_endpoint; stream->s_tx_bytes += nr_read_from_endpoint;
@@ -460,7 +514,9 @@ static enum fx_status skip_uncompressed(
} }
static enum fx_status cstream_skip( static enum fx_status cstream_skip(
struct fx_cstream_p *stream, size_t count, size_t *out_nr_skipped) struct fx_cstream_p *stream,
size_t count,
size_t *out_nr_skipped)
{ {
if (stream->s_mode != FX_COMPRESSOR_MODE_DECOMPRESS) { if (stream->s_mode != FX_COMPRESSOR_MODE_DECOMPRESS) {
return FX_ERR_BAD_STATE; return FX_ERR_BAD_STATE;
@@ -499,7 +555,9 @@ static enum fx_status cstream_skip(
const void *data; const void *data;
size_t available; size_t available;
status = fx_ringbuffer_open_read_buffer( status = fx_ringbuffer_open_read_buffer(
stream->s_out, &data, &available); stream->s_out,
&data,
&available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
@@ -554,7 +612,8 @@ static enum fx_status cstream_reset(struct fx_cstream_p *stream)
} }
static enum fx_status cstream_begin_compressed_section( static enum fx_status cstream_begin_compressed_section(
struct fx_cstream_p *stream, size_t *tx_uncompressed_bytes) struct fx_cstream_p *stream,
size_t *tx_uncompressed_bytes)
{ {
if (stream->s_flags & CSTREAM_CURSOR_MOVED) { if (stream->s_flags & CSTREAM_CURSOR_MOVED) {
return FX_ERR_BAD_STATE; return FX_ERR_BAD_STATE;
@@ -578,7 +637,8 @@ static enum fx_status cstream_begin_compressed_section(
} }
static enum fx_status cstream_end_compressed_section( static enum fx_status cstream_end_compressed_section(
struct fx_cstream_p *stream, size_t *tx_compressed_bytes, struct fx_cstream_p *stream,
size_t *tx_compressed_bytes,
size_t *tx_uncompressed_bytes) size_t *tx_uncompressed_bytes)
{ {
if (stream->s_flags & CSTREAM_CURSOR_MOVED) { if (stream->s_flags & CSTREAM_CURSOR_MOVED) {
@@ -646,28 +706,33 @@ static bool cstream_in_compressed_section(const struct fx_cstream_p *stream)
return stream->s_compression_depth > 0; return stream->s_compression_depth > 0;
} }
static enum fx_status cstream_tx_bytes(const struct fx_cstream_p *stream, size_t *out) static enum fx_status cstream_tx_bytes(
const struct fx_cstream_p *stream,
size_t *out)
{ {
*out = stream->s_tx_bytes; *out = stream->s_tx_bytes;
return FX_SUCCESS; return FX_SUCCESS;
} }
static enum fx_status cstream_tx_bytes_compressed( static enum fx_status cstream_tx_bytes_compressed(
const struct fx_cstream_p *stream, size_t *out) const struct fx_cstream_p *stream,
size_t *out)
{ {
*out = stream->s_tx_bytes_compressed; *out = stream->s_tx_bytes_compressed;
return FX_SUCCESS; return FX_SUCCESS;
} }
static enum fx_status cstream_tx_bytes_uncompressed( static enum fx_status cstream_tx_bytes_uncompressed(
const struct fx_cstream_p *stream, size_t *out) const struct fx_cstream_p *stream,
size_t *out)
{ {
*out = stream->s_tx_bytes_uncompressed; *out = stream->s_tx_bytes_uncompressed;
return FX_SUCCESS; return FX_SUCCESS;
} }
static enum fx_status cstream_set_cursor_position( static enum fx_status cstream_set_cursor_position(
struct fx_cstream_p *stream, size_t pos) struct fx_cstream_p *stream,
size_t pos)
{ {
if (stream->s_compression_depth > 0) { if (stream->s_compression_depth > 0) {
return FX_ERR_BAD_STATE; return FX_ERR_BAD_STATE;
@@ -691,14 +756,17 @@ static enum fx_status cstream_set_cursor_position(
return FX_SUCCESS; return FX_SUCCESS;
} }
static enum fx_status cstream_restore_cursor_position(struct fx_cstream_p *stream) static enum fx_status cstream_restore_cursor_position(
struct fx_cstream_p *stream)
{ {
if (!(stream->s_flags & CSTREAM_CURSOR_MOVED)) { if (!(stream->s_flags & CSTREAM_CURSOR_MOVED)) {
return FX_ERR_BAD_STATE; return FX_ERR_BAD_STATE;
} }
enum fx_status status = fx_stream_seek( enum fx_status status = fx_stream_seek(
stream->s_endpoint, stream->s_cursor, FX_STREAM_SEEK_START); stream->s_endpoint,
stream->s_cursor,
FX_STREAM_SEEK_START);
stream->s_cursor = 0; stream->s_cursor = 0;
if (!FX_OK(status)) { if (!FX_OK(status)) {
@@ -713,12 +781,17 @@ static enum fx_status cstream_restore_cursor_position(struct fx_cstream_p *strea
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
enum fx_status fx_cstream_open( enum fx_status fx_cstream_open(
fx_stream *endpoint, fx_type compressor_type, fx_compressor_mode mode, fx_stream *endpoint,
fx_type compressor_type,
fx_compressor_mode mode,
fx_cstream **out) fx_cstream **out)
{ {
size_t inbuf_size = 0, outbuf_size = 0; size_t inbuf_size = 0, outbuf_size = 0;
enum fx_status status = fx_compressor_get_buffer_size( enum fx_status status = fx_compressor_get_buffer_size(
compressor_type, mode, &inbuf_size, &outbuf_size); compressor_type,
mode,
&inbuf_size,
&outbuf_size);
if (!FX_OK(status)) { if (!FX_OK(status)) {
return status; return status;
} }
@@ -764,23 +837,46 @@ enum fx_status fx_cstream_open(
} }
enum fx_status fx_cstream_read( enum fx_status fx_cstream_read(
fx_cstream *stream, void *buf, size_t count, size_t *out_nr_read) fx_cstream *stream,
void *buf,
size_t count,
size_t *out_nr_read)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_read, stream, buf, count, out_nr_read); FX_TYPE_CSTREAM,
cstream_read,
stream,
buf,
count,
out_nr_read);
} }
enum fx_status fx_cstream_write( enum fx_status fx_cstream_write(
fx_cstream *stream, const void *buf, size_t count, size_t *out_nr_written) fx_cstream *stream,
const void *buf,
size_t count,
size_t *out_nr_written)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_write, stream, buf, count, out_nr_written); FX_TYPE_CSTREAM,
cstream_write,
stream,
buf,
count,
out_nr_written);
} }
enum fx_status fx_cstream_skip(fx_cstream *stream, size_t count, size_t *out_nr_skipped) enum fx_status fx_cstream_skip(
fx_cstream *stream,
size_t count,
size_t *out_nr_skipped)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_skip, stream, count, out_nr_skipped); FX_TYPE_CSTREAM,
cstream_skip,
stream,
count,
out_nr_skipped);
} }
enum fx_status fx_cstream_reset(fx_cstream *stream) enum fx_status fx_cstream_reset(fx_cstream *stream)
@@ -789,54 +885,83 @@ enum fx_status fx_cstream_reset(fx_cstream *stream)
} }
enum fx_status fx_cstream_begin_compressed_section( enum fx_status fx_cstream_begin_compressed_section(
fx_cstream *stream, size_t *tx_uncompressed_bytes) fx_cstream *stream,
size_t *tx_uncompressed_bytes)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_begin_compressed_section, stream, FX_TYPE_CSTREAM,
cstream_begin_compressed_section,
stream,
tx_uncompressed_bytes); tx_uncompressed_bytes);
} }
enum fx_status fx_cstream_end_compressed_section( enum fx_status fx_cstream_end_compressed_section(
fx_cstream *stream, size_t *tx_compressed_bytes, size_t *tx_uncompressed_bytes) fx_cstream *stream,
size_t *tx_compressed_bytes,
size_t *tx_uncompressed_bytes)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_end_compressed_section, stream, FX_TYPE_CSTREAM,
tx_compressed_bytes, tx_uncompressed_bytes); cstream_end_compressed_section,
stream,
tx_compressed_bytes,
tx_uncompressed_bytes);
} }
bool fx_cstream_in_compressed_section(const fx_cstream *stream) bool fx_cstream_in_compressed_section(const fx_cstream *stream)
{ {
FX_CLASS_DISPATCH_STATIC_0( FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_CSTREAM, cstream_in_compressed_section, stream); FX_TYPE_CSTREAM,
cstream_in_compressed_section,
stream);
} }
enum fx_status fx_cstream_tx_bytes(const fx_cstream *stream, size_t *out) enum fx_status fx_cstream_tx_bytes(const fx_cstream *stream, size_t *out)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_CSTREAM, cstream_tx_bytes, stream, out); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM,
cstream_tx_bytes,
stream,
out);
} }
enum fx_status fx_cstream_tx_bytes_compressed(const fx_cstream *stream, size_t *out) enum fx_status fx_cstream_tx_bytes_compressed(
const fx_cstream *stream,
size_t *out)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_tx_bytes_compressed, stream, out); FX_TYPE_CSTREAM,
cstream_tx_bytes_compressed,
stream,
out);
} }
enum fx_status fx_cstream_tx_bytes_uncompressed(const fx_cstream *stream, size_t *out) enum fx_status fx_cstream_tx_bytes_uncompressed(
const fx_cstream *stream,
size_t *out)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_tx_bytes_uncompressed, stream, out); FX_TYPE_CSTREAM,
cstream_tx_bytes_uncompressed,
stream,
out);
} }
enum fx_status fx_cstream_set_cursor_position(fx_cstream *stream, size_t pos) enum fx_status fx_cstream_set_cursor_position(fx_cstream *stream, size_t pos)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_CSTREAM, cstream_set_cursor_position, stream, pos); FX_TYPE_CSTREAM,
cstream_set_cursor_position,
stream,
pos);
} }
enum fx_status fx_cstream_restore_cursor_position(fx_cstream *stream) enum fx_status fx_cstream_restore_cursor_position(fx_cstream *stream)
{ {
FX_CLASS_DISPATCH_STATIC_0( FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_CSTREAM, cstream_restore_cursor_position, stream); FX_TYPE_CSTREAM,
cstream_restore_cursor_position,
stream);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
@@ -1,5 +1,5 @@
#include <fx/compress/zstd.h> #include <fx/compression/zstd.h>
#include <fx/core/ringbuffer.h> #include <fx/ringbuffer.h>
#include <zstd.h> #include <zstd.h>
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
@@ -14,7 +14,9 @@ struct fx_zstd_compressor_p {
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_status fx_zstd_compressor_get_buffer_size( fx_status fx_zstd_compressor_get_buffer_size(
fx_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size) fx_compressor_mode mode,
size_t *inbuf_size,
size_t *outbuf_size)
{ {
switch (mode) { switch (mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case FX_COMPRESSOR_MODE_COMPRESS:
@@ -40,7 +42,8 @@ static void zstd_compressor_init(fx_object *obj, void *priv)
static void zstd_compressor_fini(fx_object *obj, void *priv) static void zstd_compressor_fini(fx_object *obj, void *priv)
{ {
fx_compressor_data *c = fx_object_get_protected(obj, FX_TYPE_COMPRESSOR); fx_compressor_data *c
= fx_object_get_protected(obj, FX_TYPE_COMPRESSOR);
struct fx_zstd_compressor_p *ctx = priv; struct fx_zstd_compressor_p *ctx = priv;
switch (c->c_mode) { switch (c->c_mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case FX_COMPRESSOR_MODE_COMPRESS:
@@ -109,13 +112,18 @@ static enum fx_status compress(fx_compressor *compressor)
const void *in_buf = NULL; const void *in_buf = NULL;
void *out_buf = NULL; void *out_buf = NULL;
status = fx_ringbuffer_open_read_buffer(in, &in_buf, &in_available); status = fx_ringbuffer_open_read_buffer(
in,
&in_buf,
&in_available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
status = fx_ringbuffer_open_write_buffer( status = fx_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity); out,
&out_buf,
&out_capacity);
if (!FX_OK(status)) { if (!FX_OK(status)) {
fx_ringbuffer_close_read_buffer(in, &in_buf, 0); fx_ringbuffer_close_read_buffer(in, &in_buf, 0);
break; break;
@@ -135,7 +143,10 @@ static enum fx_status compress(fx_compressor *compressor)
do { do {
size_t ret = ZSTD_compressStream2( size_t ret = ZSTD_compressStream2(
ctx->zstd_c, &z_out, &z_in, ZSTD_e_continue); ctx->zstd_c,
&z_out,
&z_in,
ZSTD_e_continue);
if (ZSTD_isError(ret)) { if (ZSTD_isError(ret)) {
status = FX_ERR_COMPRESSION_FAILURE; status = FX_ERR_COMPRESSION_FAILURE;
break; break;
@@ -178,7 +189,9 @@ static enum fx_status compress_end(fx_compressor *compressor)
void *out_buf = NULL; void *out_buf = NULL;
size_t out_capacity = 0; size_t out_capacity = 0;
status = fx_ringbuffer_open_write_buffer( status = fx_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity); out,
&out_buf,
&out_capacity);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
@@ -192,7 +205,10 @@ static enum fx_status compress_end(fx_compressor *compressor)
do { do {
size_t ret = ZSTD_compressStream2( size_t ret = ZSTD_compressStream2(
ctx->zstd_c, &z_out, &z_in, ZSTD_e_end); ctx->zstd_c,
&z_out,
&z_in,
ZSTD_e_end);
if (ZSTD_isError(ret)) { if (ZSTD_isError(ret)) {
status = FX_ERR_COMPRESSION_FAILURE; status = FX_ERR_COMPRESSION_FAILURE;
finished = true; finished = true;
@@ -240,13 +256,18 @@ static enum fx_status decompress(fx_compressor *compressor)
const void *in_buf = NULL; const void *in_buf = NULL;
void *out_buf = NULL; void *out_buf = NULL;
status = fx_ringbuffer_open_read_buffer(in, &in_buf, &in_available); status = fx_ringbuffer_open_read_buffer(
in,
&in_buf,
&in_available);
if (!FX_OK(status)) { if (!FX_OK(status)) {
break; break;
} }
status = fx_ringbuffer_open_write_buffer( status = fx_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity); out,
&out_buf,
&out_capacity);
if (!FX_OK(status)) { if (!FX_OK(status)) {
fx_ringbuffer_close_read_buffer(in, &in_buf, 0); fx_ringbuffer_close_read_buffer(in, &in_buf, 0);
break; break;
@@ -266,7 +287,9 @@ static enum fx_status decompress(fx_compressor *compressor)
do { do {
size_t ret = ZSTD_decompressStream( size_t ret = ZSTD_decompressStream(
ctx->zstd_d, &z_out, &z_in); ctx->zstd_d,
&z_out,
&z_in);
if (ZSTD_isError(ret)) { if (ZSTD_isError(ret)) {
status = FX_ERR_COMPRESSION_FAILURE; status = FX_ERR_COMPRESSION_FAILURE;
break; break;
@@ -292,7 +315,9 @@ static enum fx_status decompress(fx_compressor *compressor)
return status; return status;
} }
static enum fx_status set_mode(fx_compressor *compressor, fx_compressor_mode mode) static enum fx_status set_mode(
fx_compressor *compressor,
fx_compressor_mode mode)
{ {
struct fx_zstd_compressor_p *ctx struct fx_zstd_compressor_p *ctx
= fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR); = fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR);
@@ -1,10 +1,10 @@
#ifndef FX_COMPRESS_COMPRESSOR_H_ #ifndef FX_COMPRESS_COMPRESSOR_H_
#define FX_COMPRESS_COMPRESSOR_H_ #define FX_COMPRESS_COMPRESSOR_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/ringbuffer.h> #include <fx/ringbuffer.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <stdbool.h> #include <stdbool.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -48,15 +48,21 @@ FX_API fx_status fx_compressor_create(
#endif #endif
FX_API fx_status fx_compressor_get_buffer_size( FX_API fx_status fx_compressor_get_buffer_size(
fx_type type, fx_compressor_mode mode, size_t *inbuf_size, fx_type type,
fx_compressor_mode mode,
size_t *inbuf_size,
size_t *outbuf_size); size_t *outbuf_size);
FX_API fx_status fx_compressor_get_mode( FX_API fx_status fx_compressor_get_mode(
const fx_compressor *compressor, fx_compressor_mode *out); const fx_compressor *compressor,
fx_compressor_mode *out);
FX_API fx_status fx_compressor_set_mode( FX_API fx_status fx_compressor_set_mode(
fx_compressor *compressor, fx_compressor_mode mode); fx_compressor *compressor,
fx_compressor_mode mode);
FX_API fx_status fx_compressor_set_buffer( FX_API fx_status fx_compressor_set_buffer(
fx_compressor *compressor, fx_ringbuffer *inbuf, fx_ringbuffer *outbuf); fx_compressor *compressor,
fx_ringbuffer *inbuf,
fx_ringbuffer *outbuf);
FX_API fx_status fx_compressor_step(fx_compressor *compressor); FX_API fx_status fx_compressor_step(fx_compressor *compressor);
FX_API fx_status fx_compressor_end(fx_compressor *compressor); FX_API fx_status fx_compressor_end(fx_compressor *compressor);
FX_API fx_status fx_compressor_reset(fx_compressor *compressor); FX_API fx_status fx_compressor_reset(fx_compressor *compressor);
@@ -1,8 +1,8 @@
#ifndef FX_COMPRESS_CSTREAM_H_ #ifndef FX_COMPRESS_CSTREAM_H_
#define FX_COMPRESS_CSTREAM_H_ #define FX_COMPRESS_CSTREAM_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/stream.h> #include <fx/stream.h>
#include <stdbool.h> #include <stdbool.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -19,28 +19,37 @@ FX_TYPE_CLASS_DECLARATION_END(fx_cstream)
FX_API fx_type fx_cstream_get_type(void); FX_API fx_type fx_cstream_get_type(void);
FX_API fx_status fx_cstream_open( FX_API fx_status fx_cstream_open(
fx_stream *endpoint, fx_type compressor_type, enum fx_compressor_mode mode, fx_stream *endpoint,
fx_type compressor_type,
enum fx_compressor_mode mode,
fx_cstream **out); fx_cstream **out);
FX_API fx_status fx_cstream_read( FX_API fx_status
fx_cstream *stream, void *buf, size_t count, size_t *nr_read); fx_cstream_read(fx_cstream *stream, void *buf, size_t count, size_t *nr_read);
FX_API fx_status fx_cstream_write( FX_API fx_status fx_cstream_write(
fx_cstream *stream, const void *buf, size_t count, size_t *nr_written); fx_cstream *stream,
FX_API fx_status fx_cstream_skip( const void *buf,
fx_cstream *stream, size_t count, size_t *nr_skipped); size_t count,
size_t *nr_written);
FX_API fx_status
fx_cstream_skip(fx_cstream *stream, size_t count, size_t *nr_skipped);
FX_API fx_status fx_cstream_reset(fx_cstream *stream); FX_API fx_status fx_cstream_reset(fx_cstream *stream);
FX_API fx_status fx_cstream_begin_compressed_section( FX_API fx_status fx_cstream_begin_compressed_section(
fx_cstream *stream, size_t *tx_uncompressed_bytes); fx_cstream *stream,
size_t *tx_uncompressed_bytes);
FX_API fx_status fx_cstream_end_compressed_section( FX_API fx_status fx_cstream_end_compressed_section(
fx_cstream *stream, size_t *tx_compressed_bytes, fx_cstream *stream,
size_t *tx_compressed_bytes,
size_t *tx_uncompressed_bytes); size_t *tx_uncompressed_bytes);
FX_API bool fx_cstream_in_compressed_section(const fx_cstream *stream); FX_API bool fx_cstream_in_compressed_section(const fx_cstream *stream);
FX_API fx_status fx_cstream_tx_bytes(const fx_cstream *stream, size_t *out); FX_API fx_status fx_cstream_tx_bytes(const fx_cstream *stream, size_t *out);
FX_API fx_status fx_cstream_tx_bytes_compressed( FX_API fx_status fx_cstream_tx_bytes_compressed(
const fx_cstream *stream, size_t *out); const fx_cstream *stream,
size_t *out);
FX_API fx_status fx_cstream_tx_bytes_uncompressed( FX_API fx_status fx_cstream_tx_bytes_uncompressed(
const fx_cstream *stream, size_t *out); const fx_cstream *stream,
size_t *out);
FX_API fx_status fx_cstream_set_cursor_position(fx_cstream *stream, size_t pos); FX_API fx_status fx_cstream_set_cursor_position(fx_cstream *stream, size_t pos);
FX_API fx_status fx_cstream_restore_cursor_position(fx_cstream *stream); FX_API fx_status fx_cstream_restore_cursor_position(fx_cstream *stream);
@@ -1,10 +1,10 @@
#ifndef FX_COMPRESS_ZSTD_H_ #ifndef FX_COMPRESS_ZSTD_H_
#define FX_COMPRESS_ZSTD_H_ #define FX_COMPRESS_ZSTD_H_
#include <fx/compress/compressor.h> #include <fx/compression/compressor.h>
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <stdbool.h> #include <stdbool.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -19,7 +19,9 @@ FX_TYPE_CLASS_DECLARATION_END(fx_compressor)
FX_API fx_type fx_zstd_compressor_get_type(void); FX_API fx_type fx_zstd_compressor_get_type(void);
FX_API fx_status fx_zstd_compressor_get_buffer_size( FX_API fx_status fx_zstd_compressor_get_buffer_size(
fx_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size); fx_compressor_mode mode,
size_t *inbuf_size,
size_t *outbuf_size);
FX_TYPE_DEFAULT_CONSTRUCTOR(fx_zstd_compressor, FX_TYPE_ZSTD_COMPRESSOR); FX_TYPE_DEFAULT_CONSTRUCTOR(fx_zstd_compressor, FX_TYPE_ZSTD_COMPRESSOR);
+1
View File
@@ -0,0 +1 @@
export_fx_namespace_details(fx.io)
@@ -1,12 +1,12 @@
#ifndef FX_IO_DIRECTORY_H_ #ifndef FX_IO_DIRECTORY_H_
#define FX_IO_DIRECTORY_H_ #define FX_IO_DIRECTORY_H_
#include <fx/core/error.h> #include <fx/error.h>
#include <fx/core/iterator.h>
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <fx/io/file.h> #include <fx/io/file.h>
#include <fx/io/path.h> #include <fx/io/path.h>
#include <fx/iterator.h>
#include <fx/macros.h>
#include <fx/misc.h>
#define FX_DIRECTORY_ROOT ((fx_directory *)NULL) #define FX_DIRECTORY_ROOT ((fx_directory *)NULL)
@@ -49,7 +49,9 @@ FX_API fx_type fx_directory_get_type(void);
FX_API fx_type fx_directory_iterator_get_type(void); FX_API fx_type fx_directory_iterator_get_type(void);
FX_API fx_result fx_directory_open( FX_API fx_result fx_directory_open(
fx_directory *root, const fx_path *path, fx_directory_open_flags flags, fx_directory *root,
const fx_path *path,
fx_directory_open_flags flags,
fx_directory **out); fx_directory **out);
FX_API fx_result fx_directory_open_temp(fx_directory **out); FX_API fx_result fx_directory_open_temp(fx_directory **out);
FX_API const fx_path *fx_directory_get_path(const fx_directory *dir); FX_API const fx_path *fx_directory_get_path(const fx_directory *dir);
@@ -58,17 +60,26 @@ FX_API const char *fx_directory_get_path_cstr(const fx_directory *dir);
FX_API const char *fx_directory_get_rel_path_cstr(const fx_directory *dir); FX_API const char *fx_directory_get_rel_path_cstr(const fx_directory *dir);
FX_API fx_result fx_directory_delete(fx_directory *dir); FX_API fx_result fx_directory_delete(fx_directory *dir);
FX_API bool fx_directory_path_exists(const fx_directory *root, const fx_path *path); FX_API bool fx_directory_path_exists(
FX_API bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path); const fx_directory *root,
const fx_path *path);
FX_API bool fx_directory_path_is_file(
const fx_directory *root,
const fx_path *path);
FX_API bool fx_directory_path_is_directory( FX_API bool fx_directory_path_is_directory(
const fx_directory *root, const fx_path *path); const fx_directory *root,
const fx_path *path);
FX_API fx_result fx_directory_path_stat( FX_API fx_result fx_directory_path_stat(
const fx_directory *root, const fx_path *path, struct fx_file_info *out); const fx_directory *root,
const fx_path *path,
struct fx_file_info *out);
FX_API fx_result fx_directory_path_unlink( FX_API fx_result fx_directory_path_unlink(
const fx_directory *root, const fx_path *path); const fx_directory *root,
const fx_path *path);
FX_API fx_iterator *fx_directory_begin( FX_API fx_iterator *fx_directory_begin(
fx_directory *dir, fx_directory_iterator_flags flags); fx_directory *dir,
fx_directory_iterator_flags flags);
FX_DECLS_END; FX_DECLS_END;
@@ -1,10 +1,10 @@
#ifndef FX_IO_FILE_H_ #ifndef FX_IO_FILE_H_
#define FX_IO_FILE_H_ #define FX_IO_FILE_H_
#include <fx/core/error.h> #include <fx/error.h>
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/stream.h> #include <fx/stream.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -54,25 +54,35 @@ typedef struct fx_file_info {
FX_API fx_type fx_file_get_type(void); FX_API fx_type fx_file_get_type(void);
FX_API fx_result fx_file_open( FX_API fx_result fx_file_open(
FX_TYPE_FWDREF(fx_directory) * root, const FX_TYPE_FWDREF(fx_path) * path, FX_TYPE_FWDREF(fx_directory) * root,
fx_file_mode mode, fx_file **out); const FX_TYPE_FWDREF(fx_path) * path,
fx_file_mode mode,
fx_file **out);
FX_API fx_result fx_file_open_temp(fx_file_mode mode, fx_file **out); FX_API fx_result fx_file_open_temp(fx_file_mode mode, fx_file **out);
FX_API fx_result fx_file_open_shadow( FX_API fx_result
fx_file *original, fx_file_mode mode, fx_file **out); fx_file_open_shadow(fx_file *original, fx_file_mode mode, fx_file **out);
FX_API fx_status fx_file_stat(fx_file *file, fx_file_info *out); FX_API fx_status fx_file_stat(fx_file *file, fx_file_info *out);
FX_API fx_status fx_file_size(fx_file *file, size_t *out_len); FX_API fx_status fx_file_size(fx_file *file, size_t *out_len);
FX_API fx_status fx_file_cursor(fx_file *file, size_t *out_pos); FX_API fx_status fx_file_cursor(fx_file *file, size_t *out_pos);
FX_API fx_status fx_file_resize(fx_file *file, size_t len); FX_API fx_status fx_file_resize(fx_file *file, size_t len);
FX_API fx_status fx_file_seek(fx_file *file, long long offset, fx_seek_basis basis); FX_API fx_status
fx_file_seek(fx_file *file, long long offset, fx_seek_basis basis);
FX_API const FX_TYPE_FWDREF(fx_path) * fx_file_path(const fx_file *file); FX_API const FX_TYPE_FWDREF(fx_path) * fx_file_path(const fx_file *file);
FX_API fx_status fx_file_swap_shadow(fx_file *main_file, fx_file *shadow_file); FX_API fx_status fx_file_swap_shadow(fx_file *main_file, fx_file *shadow_file);
FX_API fx_status fx_file_read( FX_API fx_status fx_file_read(
fx_file *file, size_t offset, size_t len, void *buf, size_t *nr_read); fx_file *file,
size_t offset,
size_t len,
void *buf,
size_t *nr_read);
FX_API fx_status fx_file_write( FX_API fx_status fx_file_write(
fx_file *file, size_t offset, size_t len, const void *buf, fx_file *file,
size_t offset,
size_t len,
const void *buf,
size_t *nr_written); size_t *nr_written);
FX_DECLS_END; FX_DECLS_END;
@@ -1,10 +1,10 @@
#ifndef FX_IO_PATH_H_ #ifndef FX_IO_PATH_H_
#define FX_IO_PATH_H_ #define FX_IO_PATH_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <fx/ds/string.h> #include <fx/string.h>
#include <stddef.h> #include <stddef.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -43,8 +43,11 @@ FX_API fx_status fx_path_stat(const fx_path *path, struct fx_file_info *out);
FX_API fx_status fx_path_unlink(const fx_path *path); FX_API fx_status fx_path_unlink(const fx_path *path);
FX_API enum fx_status fx_path_get_directory( FX_API enum fx_status fx_path_get_directory(
const fx_path *path, fx_path **out_dir_path); const fx_path *path,
FX_API enum fx_status fx_path_get_filename(const fx_path *path, fx_string *out_name); fx_path **out_dir_path);
FX_API enum fx_status fx_path_get_filename(
const fx_path *path,
fx_string *out_name);
FX_API const char *fx_path_ptr(const fx_path *path); FX_API const char *fx_path_ptr(const fx_path *path);
FX_API size_t fx_path_length(const fx_path *path); FX_API size_t fx_path_length(const fx_path *path);
@@ -1,12 +1,12 @@
#include "misc.h" #include "misc.h"
#include "posix.h" #include "posix.h"
#include <fx/core/error.h>
#include <fx/ds/string.h>
#include <fx/io/directory.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <fts.h> #include <fts.h>
#include <fx/error.h>
#include <fx/io/directory.h>
#include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -58,11 +58,14 @@ static const char *directory_get_rel_path_cstr(const struct fx_directory_p *dir)
return fx_path_ptr(dir->d_path_rel); return fx_path_ptr(dir->d_path_rel);
} }
static fx_result directory_delete(fx_directory *dir, struct fx_directory_p *dir_p) static fx_result directory_delete(
fx_directory *dir,
struct fx_directory_p *dir_p)
{ {
enum fx_status status = FX_SUCCESS; enum fx_status status = FX_SUCCESS;
fx_iterator *it = fx_directory_begin(dir, FX_DIRECTORY_ITERATE_PARENT_LAST); fx_iterator *it
= fx_directory_begin(dir, FX_DIRECTORY_ITERATE_PARENT_LAST);
while (FX_OK(fx_iterator_get_status(it))) { while (FX_OK(fx_iterator_get_status(it))) {
fx_iterator_erase(it); fx_iterator_erase(it);
} }
@@ -81,7 +84,8 @@ static fx_result directory_delete(fx_directory *dir, struct fx_directory_p *dir_
} }
static bool directory_path_exists( static bool directory_path_exists(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -100,7 +104,8 @@ static bool directory_path_exists(
} }
static bool directory_path_is_file( static bool directory_path_is_file(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -119,7 +124,8 @@ static bool directory_path_is_file(
} }
static bool directory_path_is_directory( static bool directory_path_is_directory(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -138,7 +144,8 @@ static bool directory_path_is_directory(
} }
static fx_result directory_path_stat( static fx_result directory_path_stat(
const struct fx_directory_p *root, const fx_path *path, const struct fx_directory_p *root,
const fx_path *path,
struct fx_file_info *out) struct fx_file_info *out)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
@@ -158,7 +165,8 @@ static fx_result directory_path_stat(
} }
static fx_result directory_path_unlink( static fx_result directory_path_unlink(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -192,11 +200,15 @@ static fx_result create_directory(struct fx_directory_p *root, const char *path)
} }
return fx_result_from_errno_with_subfilepath( return fx_result_from_errno_with_subfilepath(
errno, path, directory_get_rel_path_cstr(root), FX_ERR_IO_FAILURE); errno,
path,
directory_get_rel_path_cstr(root),
FX_ERR_IO_FAILURE);
} }
static fx_result create_directory_hierarchy( static fx_result create_directory_hierarchy(
struct fx_directory_p *root, const char *path) struct fx_directory_p *root,
const char *path)
{ {
int root_fd = root ? root->d_fd : AT_FDCWD; int root_fd = root ? root->d_fd : AT_FDCWD;
@@ -216,7 +228,9 @@ static fx_result create_directory_hierarchy(
int err = mkdirat(root_fd, path_buf, 0755); int err = mkdirat(root_fd, path_buf, 0755);
if (err != 0 && errno != EEXIST) { if (err != 0 && errno != EEXIST) {
result = fx_result_from_errno_with_subfilepath( result = fx_result_from_errno_with_subfilepath(
errno, path_buf, directory_get_rel_path_cstr(root), errno,
path_buf,
directory_get_rel_path_cstr(root),
FX_ERR_IO_FAILURE); FX_ERR_IO_FAILURE);
break; break;
} }
@@ -227,7 +241,9 @@ static fx_result create_directory_hierarchy(
int err = mkdirat(root_fd, path_buf, 0755); int err = mkdirat(root_fd, path_buf, 0755);
if (err != 0 && errno != EEXIST) { if (err != 0 && errno != EEXIST) {
result = fx_result_from_errno_with_subfilepath( result = fx_result_from_errno_with_subfilepath(
errno, path_buf, directory_get_rel_path_cstr(root), errno,
path_buf,
directory_get_rel_path_cstr(root),
FX_ERR_IO_FAILURE); FX_ERR_IO_FAILURE);
} }
@@ -236,8 +252,10 @@ static fx_result create_directory_hierarchy(
} }
static fx_result directory_open( static fx_result directory_open(
struct fx_directory_p *root, const fx_path *path, struct fx_directory_p *root,
fx_directory_open_flags flags, fx_directory **out) const fx_path *path,
fx_directory_open_flags flags,
fx_directory **out)
{ {
enum fx_status status = FX_SUCCESS; enum fx_status status = FX_SUCCESS;
@@ -254,7 +272,9 @@ static fx_result directory_open(
if ((flags & FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE) if ((flags & FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE)
== FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE) { == FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE) {
result = create_directory_hierarchy(root, path_cstr); result = create_directory_hierarchy(root, path_cstr);
} else if ((flags & FX_DIRECTORY_OPEN_CREATE) == FX_DIRECTORY_OPEN_CREATE) { } else if (
(flags & FX_DIRECTORY_OPEN_CREATE)
== FX_DIRECTORY_OPEN_CREATE) {
result = create_directory(root, path_cstr); result = create_directory(root, path_cstr);
} }
@@ -271,7 +291,8 @@ static fx_result directory_open(
fx_directory *dir = fx_object_create(FX_TYPE_DIRECTORY); fx_directory *dir = fx_object_create(FX_TYPE_DIRECTORY);
fx_path *cwd = NULL; fx_path *cwd = NULL;
struct fx_directory_p *p = fx_object_get_private(dir, FX_TYPE_DIRECTORY); struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
if (!root) { if (!root) {
cwd = fx_path_create_cwd(); cwd = fx_path_create_cwd();
@@ -307,11 +328,18 @@ static fx_result directory_open(
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_result fx_directory_open( fx_result fx_directory_open(
fx_directory *root, const fx_path *path, fx_directory_open_flags flags, fx_directory *root,
const fx_path *path,
fx_directory_open_flags flags,
fx_directory **out) fx_directory **out)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_open, root, path, flags, out); FX_TYPE_DIRECTORY,
directory_open,
root,
path,
flags,
out);
} }
fx_result fx_directory_open_temp(fx_directory **out) fx_result fx_directory_open_temp(fx_directory **out)
@@ -326,7 +354,10 @@ fx_result fx_directory_open_temp(fx_directory **out)
fx_directory *dir = NULL; fx_directory *dir = NULL;
fx_result status = fx_directory_open( fx_result status = fx_directory_open(
FX_DIRECTORY_ROOT, rpath, FX_DIRECTORY_OPEN_CREATE, &dir); FX_DIRECTORY_ROOT,
rpath,
FX_DIRECTORY_OPEN_CREATE,
&dir);
struct fx_directory_p *p struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY); = fx_object_get_private(dir, FX_TYPE_DIRECTORY);
@@ -353,23 +384,32 @@ const fx_path *fx_directory_get_path(const fx_directory *dir)
const fx_path *fx_directory_get_rel_path(const fx_directory *dir) const fx_path *fx_directory_get_rel_path(const fx_directory *dir)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DIRECTORY, directory_get_rel_path, dir); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DIRECTORY,
directory_get_rel_path,
dir);
} }
const char *fx_directory_get_path_cstr(const fx_directory *dir) const char *fx_directory_get_path_cstr(const fx_directory *dir)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DIRECTORY, directory_get_path_cstr, dir); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DIRECTORY,
directory_get_path_cstr,
dir);
} }
const char *fx_directory_get_rel_path_cstr(const fx_directory *dir) const char *fx_directory_get_rel_path_cstr(const fx_directory *dir)
{ {
FX_CLASS_DISPATCH_STATIC_0( FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DIRECTORY, directory_get_rel_path_cstr, dir); FX_TYPE_DIRECTORY,
directory_get_rel_path_cstr,
dir);
} }
fx_result fx_directory_delete(fx_directory *dir) fx_result fx_directory_delete(fx_directory *dir)
{ {
struct fx_directory_p *p = fx_object_get_private(dir, FX_TYPE_DIRECTORY); struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
p->d_flags |= DIRECTORY_DELETE_ON_CLOSE; p->d_flags |= DIRECTORY_DELETE_ON_CLOSE;
/* TODO allow object release functions to return a fx_result value */ /* TODO allow object release functions to return a fx_result value */
fx_directory_unref(dir); fx_directory_unref(dir);
@@ -378,31 +418,55 @@ fx_result fx_directory_delete(fx_directory *dir)
bool fx_directory_path_exists(const fx_directory *root, const fx_path *path) bool fx_directory_path_exists(const fx_directory *root, const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_DIRECTORY, directory_path_exists, root, path); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY,
directory_path_exists,
root,
path);
} }
bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path) bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_is_file, root, path); FX_TYPE_DIRECTORY,
directory_path_is_file,
root,
path);
} }
bool fx_directory_path_is_directory(const fx_directory *root, const fx_path *path) bool fx_directory_path_is_directory(
const fx_directory *root,
const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_is_directory, root, path); FX_TYPE_DIRECTORY,
directory_path_is_directory,
root,
path);
} }
fx_result fx_directory_path_stat( fx_result fx_directory_path_stat(
const fx_directory *root, const fx_path *path, struct fx_file_info *out) const fx_directory *root,
const fx_path *path,
struct fx_file_info *out)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_stat, root, path, out); FX_TYPE_DIRECTORY,
directory_path_stat,
root,
path,
out);
} }
fx_result fx_directory_path_unlink(const fx_directory *root, const fx_path *path) fx_result fx_directory_path_unlink(
const fx_directory *root,
const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_DIRECTORY, directory_path_unlink, root, path); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY,
directory_path_unlink,
root,
path);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
@@ -487,7 +551,8 @@ static void iterator_fini(fx_object *obj, void *priv)
} }
fx_iterator *fx_directory_begin( fx_iterator *fx_directory_begin(
fx_directory *directory, enum fx_directory_iterator_flags flags) fx_directory *directory,
enum fx_directory_iterator_flags flags)
{ {
fx_iterator *it_obj = fx_object_create(FX_TYPE_DIRECTORY_ITERATOR); fx_iterator *it_obj = fx_object_create(FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it struct fx_directory_iterator_p *it
@@ -556,7 +621,9 @@ static fx_iterator *iterator_begin(fx_object *obj)
static const fx_iterator *iterator_cbegin(const fx_object *obj) static const fx_iterator *iterator_cbegin(const fx_object *obj)
{ {
return fx_directory_begin((fx_object *)obj, FX_DIRECTORY_ITERATE_PARENT_FIRST); return fx_directory_begin(
(fx_object *)obj,
FX_DIRECTORY_ITERATE_PARENT_FIRST);
} }
static enum fx_status iterator_move_next(const fx_iterator *obj) static enum fx_status iterator_move_next(const fx_iterator *obj)
@@ -612,7 +679,8 @@ static enum fx_status iterator_erase(fx_iterator *obj)
{ {
struct fx_directory_iterator_p *it struct fx_directory_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR); = fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR);
fx_result result = fx_directory_path_unlink(it->root, it->entry.filepath); fx_result result
= fx_directory_path_unlink(it->root, it->entry.filepath);
if (fx_result_is_error(result)) { if (fx_result_is_error(result)) {
enum fx_status status = fx_error_get_status_code(result); enum fx_status status = fx_error_get_status_code(result);
fx_error_discard(result); fx_error_discard(result);
+100 -29
View File
@@ -1,13 +1,13 @@
#include "misc.h" #include "misc.h"
#include "posix.h" #include "posix.h"
#include <fx/core/random.h> #include <errno.h>
#include <fx/ds/string.h> #include <fcntl.h>
#include <fx/io/directory.h> #include <fx/io/directory.h>
#include <fx/io/file.h> #include <fx/io/file.h>
#include <fx/io/path.h> #include <fx/io/path.h>
#include <errno.h> #include <fx/random.h>
#include <fcntl.h> #include <fx/string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -20,7 +20,10 @@ static enum fx_status stream_close(fx_stream *);
static enum fx_status stream_getc(fx_stream *, int *); static enum fx_status stream_getc(fx_stream *, int *);
static enum fx_status stream_read(fx_stream *, void *, size_t, size_t *); static enum fx_status stream_read(fx_stream *, void *, size_t, size_t *);
static enum fx_status stream_write(fx_stream *, const void *, size_t, size_t *); static enum fx_status stream_write(fx_stream *, const void *, size_t, size_t *);
static enum fx_status stream_seek(fx_stream *, long long, fx_stream_seek_origin); static enum fx_status stream_seek(
fx_stream *,
long long,
fx_stream_seek_origin);
static enum fx_status stream_tell(const fx_stream *, size_t *); static enum fx_status stream_tell(const fx_stream *, size_t *);
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
@@ -63,7 +66,9 @@ static unsigned int fx_mode_to_unix_mode(enum fx_file_mode mode)
} }
static fx_result file_open_shadow( static fx_result file_open_shadow(
struct fx_file_p *original, enum fx_file_mode mode, fx_file **out) struct fx_file_p *original,
enum fx_file_mode mode,
fx_file **out)
{ {
mode |= FX_FILE_SHADOW | FX_FILE_DELETE_ON_CLOSE | FX_FILE_CREATE; mode |= FX_FILE_SHADOW | FX_FILE_DELETE_ON_CLOSE | FX_FILE_CREATE;
@@ -75,7 +80,8 @@ static fx_result file_open_shadow(
fx_string_prepend_cstr(filename, ".~"); fx_string_prepend_cstr(filename, ".~");
fx_path *shadow_filename = fx_path_create_from_cstr(fx_string_get_cstr(filename)); fx_path *shadow_filename
= fx_path_create_from_cstr(fx_string_get_cstr(filename));
fx_string_unref(filename); fx_string_unref(filename);
const fx_path *parts[] = { const fx_path *parts[] = {
@@ -94,7 +100,10 @@ static fx_result file_open_shadow(
fx_file *shadow_file; fx_file *shadow_file;
fx_result status = fx_file_open( fx_result status = fx_file_open(
FX_DIRECTORY_ROOT, shadow_filepath, mode, &shadow_file); FX_DIRECTORY_ROOT,
shadow_filepath,
mode,
&shadow_file);
fx_path_unref(shadow_filepath); fx_path_unref(shadow_filepath);
if (fx_result_is_error(status)) { if (fx_result_is_error(status)) {
@@ -110,7 +119,9 @@ static const fx_path *file_path(const struct fx_file_p *file)
return file->path; return file->path;
} }
static enum fx_status file_stat(struct fx_file_p *file, struct fx_file_info *out) static enum fx_status file_stat(
struct fx_file_p *file,
struct fx_file_info *out)
{ {
struct stat st; struct stat st;
int err = fstat(file->fd, &st); int err = fstat(file->fd, &st);
@@ -167,7 +178,9 @@ static enum fx_status file_resize(struct fx_file_p *file, size_t len)
} }
static enum fx_status file_seek( static enum fx_status file_seek(
struct fx_file_p *file, long long offset, enum fx_seek_basis basis) struct fx_file_p *file,
long long offset,
enum fx_seek_basis basis)
{ {
int whence; int whence;
switch (basis) { switch (basis) {
@@ -193,7 +206,8 @@ static enum fx_status file_seek(
} }
static enum fx_status file_swap_shadow( static enum fx_status file_swap_shadow(
struct fx_file_p *main_file, struct fx_file_p *shadow_file) struct fx_file_p *main_file,
struct fx_file_p *shadow_file)
{ {
if (main_file->mode & FX_FILE_SHADOW) { if (main_file->mode & FX_FILE_SHADOW) {
return FX_ERR_NOT_SUPPORTED; return FX_ERR_NOT_SUPPORTED;
@@ -235,7 +249,9 @@ static enum fx_status file_swap_shadow(
int err; int err;
err = rename(fx_path_ptr(main_file->path), fx_path_ptr(tmp_path)); err = rename(fx_path_ptr(main_file->path), fx_path_ptr(tmp_path));
err = rename(fx_path_ptr(shadow_file->path), fx_path_ptr(main_file->path)); err = rename(
fx_path_ptr(shadow_file->path),
fx_path_ptr(main_file->path));
err = rename(fx_path_ptr(tmp_path), fx_path_ptr(shadow_file->path)); err = rename(fx_path_ptr(tmp_path), fx_path_ptr(shadow_file->path));
fx_path_unref(tmp_path); fx_path_unref(tmp_path);
@@ -248,7 +264,11 @@ static enum fx_status file_swap_shadow(
} }
static enum fx_status file_read( static enum fx_status file_read(
struct fx_file_p *file, size_t offset, size_t len, void *buf, size_t *nr_read) struct fx_file_p *file,
size_t offset,
size_t len,
void *buf,
size_t *nr_read)
{ {
if (offset != FX_OFFSET_CURRENT) { if (offset != FX_OFFSET_CURRENT) {
lseek(file->fd, offset, SEEK_SET); lseek(file->fd, offset, SEEK_SET);
@@ -267,7 +287,10 @@ static enum fx_status file_read(
} }
static enum fx_status file_write( static enum fx_status file_write(
struct fx_file_p *file, size_t offset, size_t len, const void *buf, struct fx_file_p *file,
size_t offset,
size_t len,
const void *buf,
size_t *nr_written) size_t *nr_written)
{ {
if (offset != FX_OFFSET_CURRENT) { if (offset != FX_OFFSET_CURRENT) {
@@ -314,7 +337,10 @@ static enum fx_status stream_getc(fx_stream *stream, int *out)
} }
static enum fx_status stream_read( static enum fx_status stream_read(
fx_stream *stream, void *buf, size_t max, size_t *nr_read) fx_stream *stream,
void *buf,
size_t max,
size_t *nr_read)
{ {
struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE); struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE);
@@ -325,7 +351,10 @@ static enum fx_status stream_read(
} }
static enum fx_status stream_write( static enum fx_status stream_write(
fx_stream *stream, const void *buf, size_t count, size_t *nr_written) fx_stream *stream,
const void *buf,
size_t count,
size_t *nr_written)
{ {
struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE); struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE);
@@ -336,7 +365,9 @@ static enum fx_status stream_write(
} }
static enum fx_status stream_seek( static enum fx_status stream_seek(
fx_stream *stream, long long offset, fx_stream_seek_origin origin) fx_stream *stream,
long long offset,
fx_stream_seek_origin origin)
{ {
fx_seek_basis basis; fx_seek_basis basis;
switch (origin) { switch (origin) {
@@ -360,7 +391,8 @@ static enum fx_status stream_seek(
static enum fx_status stream_tell(const fx_stream *stream, size_t *pos) static enum fx_status stream_tell(const fx_stream *stream, size_t *pos)
{ {
const struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE); const struct fx_file_p *file
= fx_object_get_private(stream, FX_TYPE_FILE);
off_t v = lseek(file->fd, 0, SEEK_CUR); off_t v = lseek(file->fd, 0, SEEK_CUR);
if (v == (off_t)-1) { if (v == (off_t)-1) {
return fx_status_from_errno(errno, FX_ERR_IO_FAILURE); return fx_status_from_errno(errno, FX_ERR_IO_FAILURE);
@@ -373,7 +405,10 @@ static enum fx_status stream_tell(const fx_stream *stream, size_t *pos)
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_result fx_file_open( fx_result fx_file_open(
fx_directory *root, const fx_path *path, enum fx_file_mode mode, fx_file **out) fx_directory *root,
const fx_path *path,
enum fx_file_mode mode,
fx_file **out)
{ {
const fx_path *file_path = path; const fx_path *file_path = path;
unsigned int flags = fx_mode_to_unix_mode(mode); unsigned int flags = fx_mode_to_unix_mode(mode);
@@ -456,7 +491,10 @@ fx_result fx_file_open_temp(enum fx_file_mode mode, fx_file **out)
fx_path *rpath = fx_path_create_from_cstr(path); fx_path *rpath = fx_path_create_from_cstr(path);
fx_result status = fx_file_open( fx_result status = fx_file_open(
FX_DIRECTORY_ROOT, rpath, mode | FX_FILE_CREATE_ONLY, out); FX_DIRECTORY_ROOT,
rpath,
mode | FX_FILE_CREATE_ONLY,
out);
if (fx_error_get_status_code(status) == FX_ERR_NAME_EXISTS) { if (fx_error_get_status_code(status) == FX_ERR_NAME_EXISTS) {
fx_path_unref(rpath); fx_path_unref(rpath);
@@ -470,9 +508,17 @@ fx_result fx_file_open_temp(enum fx_file_mode mode, fx_file **out)
} }
} }
fx_result fx_file_open_shadow(fx_file *original, enum fx_file_mode mode, fx_file **out) fx_result fx_file_open_shadow(
fx_file *original,
enum fx_file_mode mode,
fx_file **out)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_open_shadow, original, mode, out); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_FILE,
file_open_shadow,
original,
mode,
out);
} }
const fx_path *fx_file_path(const fx_file *file) const fx_path *fx_file_path(const fx_file *file)
@@ -500,30 +546,55 @@ enum fx_status fx_file_resize(fx_file *file, size_t len)
FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_resize, file, len); FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_resize, file, len);
} }
enum fx_status fx_file_seek(fx_file *file, long long offset, enum fx_seek_basis basis) enum fx_status fx_file_seek(
fx_file *file,
long long offset,
enum fx_seek_basis basis)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_seek, file, offset, basis); FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_seek, file, offset, basis);
} }
enum fx_status fx_file_swap_shadow(fx_file *main_file, fx_file *shadow_file) enum fx_status fx_file_swap_shadow(fx_file *main_file, fx_file *shadow_file)
{ {
struct fx_file_p *main_p = fx_object_get_private(main_file, FX_TYPE_FILE); struct fx_file_p *main_p
struct fx_file_p *shadow_p = fx_object_get_private(main_file, FX_TYPE_FILE); = fx_object_get_private(main_file, FX_TYPE_FILE);
struct fx_file_p *shadow_p
= fx_object_get_private(main_file, FX_TYPE_FILE);
return file_swap_shadow(main_p, shadow_p); return file_swap_shadow(main_p, shadow_p);
} }
enum fx_status fx_file_read( enum fx_status fx_file_read(
fx_file *file, size_t offset, size_t len, void *buf, size_t *nr_read) fx_file *file,
size_t offset,
size_t len,
void *buf,
size_t *nr_read)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_FILE, file_read, file, offset, len, buf, nr_read); FX_TYPE_FILE,
file_read,
file,
offset,
len,
buf,
nr_read);
} }
enum fx_status fx_file_write( enum fx_status fx_file_write(
fx_file *file, size_t offset, size_t len, const void *buf, size_t *nr_written) fx_file *file,
size_t offset,
size_t len,
const void *buf,
size_t *nr_written)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_FILE, file_write, file, offset, len, buf, nr_written); FX_TYPE_FILE,
file_write,
file,
offset,
len,
buf,
nr_written);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
@@ -1,6 +1,6 @@
#include "misc.h" #include "misc.h"
#include <fx/core/random.h> #include <fx/random.h>
void z__fx_io_generate_tmp_filename(char *out, size_t len) void z__fx_io_generate_tmp_filename(char *out, size_t len)
{ {
@@ -1,11 +1,11 @@
#include "posix.h" #include "posix.h"
#include <fx/ds/string.h>
#include <fx/io/file.h>
#include <fx/io/path.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <fx/io/file.h>
#include <fx/io/path.h>
#include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -45,7 +45,9 @@ static const char *path_ptr(const struct fx_path_p *path)
return fx_string_get_cstr(path->p_pathstr); return fx_string_get_cstr(path->p_pathstr);
} }
static enum fx_status path_stat(const struct fx_path_p *path, struct fx_file_info *out) static enum fx_status path_stat(
const struct fx_path_p *path,
struct fx_file_info *out)
{ {
struct stat st; struct stat st;
int err = stat(path_ptr(path), &st); int err = stat(path_ptr(path), &st);
@@ -110,11 +112,13 @@ static void append_path(struct fx_path_p *dest, const struct fx_path_p *src)
static enum fx_status path_unlink(const struct fx_path_p *path) static enum fx_status path_unlink(const struct fx_path_p *path)
{ {
int err = remove(fx_string_get_cstr(path->p_pathstr)); int err = remove(fx_string_get_cstr(path->p_pathstr));
return err == 0 ? FX_SUCCESS : fx_status_from_errno(errno, FX_ERR_IO_FAILURE); return err == 0 ? FX_SUCCESS
: fx_status_from_errno(errno, FX_ERR_IO_FAILURE);
} }
static enum fx_status path_get_directory( static enum fx_status path_get_directory(
const struct fx_path_p *path, fx_path **out_dir_path) const struct fx_path_p *path,
fx_path **out_dir_path)
{ {
fx_string *path_str = path->p_pathstr; fx_string *path_str = path->p_pathstr;
long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL); long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL);
@@ -130,7 +134,8 @@ static enum fx_status path_get_directory(
size_t dir_path_len = (size_t)(sep - path_cstr); size_t dir_path_len = (size_t)(sep - path_cstr);
fx_string *dir_path_s = fx_string_get_substr(path_str, 0, dir_path_len); fx_string *dir_path_s = fx_string_get_substr(path_str, 0, dir_path_len);
fx_path *dir_path = fx_path_create_from_cstr(fx_string_get_cstr(dir_path_s)); fx_path *dir_path
= fx_path_create_from_cstr(fx_string_get_cstr(dir_path_s));
fx_string_unref(dir_path_s); fx_string_unref(dir_path_s);
*out_dir_path = dir_path; *out_dir_path = dir_path;
@@ -139,7 +144,8 @@ static enum fx_status path_get_directory(
} }
static enum fx_status path_get_filename( static enum fx_status path_get_filename(
const struct fx_path_p *path, fx_string *out_name) const struct fx_path_p *path,
fx_string *out_name)
{ {
fx_string *path_str = path->p_pathstr; fx_string *path_str = path->p_pathstr;
long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL); long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL);
@@ -278,7 +284,8 @@ fx_path *fx_path_join(const fx_path *paths[], size_t nr_paths)
return NULL; return NULL;
} }
struct fx_path_p *result_p = fx_object_get_private(result, FX_TYPE_PATH); struct fx_path_p *result_p
= fx_object_get_private(result, FX_TYPE_PATH);
for (size_t i = 0; i < nr_paths; i++) { for (size_t i = 0; i < nr_paths; i++) {
if (paths[i]) { if (paths[i]) {
@@ -336,14 +343,24 @@ enum fx_status fx_path_unlink(const fx_path *path)
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_PATH, path_unlink, path); FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_PATH, path_unlink, path);
} }
enum fx_status fx_path_get_directory(const fx_path *path, fx_path **out_dir_path) enum fx_status fx_path_get_directory(
const fx_path *path,
fx_path **out_dir_path)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_PATH, path_get_directory, path, out_dir_path); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_PATH,
path_get_directory,
path,
out_dir_path);
} }
enum fx_status fx_path_get_filename(const fx_path *path, fx_string *out_name) enum fx_status fx_path_get_filename(const fx_path *path, fx_string *out_name)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_PATH, path_get_filename, path, out_name); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_PATH,
path_get_filename,
path,
out_name);
} }
const char *fx_path_ptr(const fx_path *path) const char *fx_path_ptr(const fx_path *path)
@@ -1,7 +1,7 @@
#include <fx/core/error.h>
#include <fx/core/status.h>
#include <fx/io/file.h>
#include <errno.h> #include <errno.h>
#include <fx/error.h>
#include <fx/io/file.h>
#include <fx/status.h>
#include <sys/stat.h> #include <sys/stat.h>
enum fx_status fx_status_from_errno(int error, enum fx_status default_value) enum fx_status fx_status_from_errno(int error, enum fx_status default_value)
@@ -35,40 +35,53 @@ enum fx_status fx_status_from_errno(int error, enum fx_status default_value)
} }
fx_result fx_result_from_errno_with_filepath( fx_result fx_result_from_errno_with_filepath(
int error, const char *path, enum fx_status default_value) int error,
const char *path,
enum fx_status default_value)
{ {
switch (error) { switch (error) {
case 0: case 0:
return FX_RESULT_SUCCESS; return FX_RESULT_SUCCESS;
case ENOENT: case ENOENT:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NO_ENTRY, "Path @i{%s} does not exist", path); FX_ERR_NO_ENTRY,
"Path @i{%s} does not exist",
path);
case ENOTDIR: case ENOTDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NOT_DIRECTORY, "Path @i{%s} is not a directory", FX_ERR_NOT_DIRECTORY,
"Path @i{%s} is not a directory",
path); path);
case EISDIR: case EISDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_IS_DIRECTORY, "Path @i{%s} is a directory", path); FX_ERR_IS_DIRECTORY,
"Path @i{%s} is a directory",
path);
case EPERM: case EPERM:
case EACCES: case EACCES:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_PERMISSION_DENIED, FX_ERR_PERMISSION_DENIED,
"Permission denied while accessing path @i{%s}", path); "Permission denied while accessing path @i{%s}",
path);
default: default:
return FX_RESULT_STATUS(fx_status_from_errno(error, default_value)); return FX_RESULT_STATUS(
fx_status_from_errno(error, default_value));
} }
return FX_RESULT_SUCCESS; return FX_RESULT_SUCCESS;
} }
fx_result fx_result_from_errno_with_subfilepath( fx_result fx_result_from_errno_with_subfilepath(
int error, const char *path, const char *dir_path, int error,
const char *path,
const char *dir_path,
enum fx_status default_value) enum fx_status default_value)
{ {
if (!dir_path) { if (!dir_path) {
return fx_result_propagate(fx_result_from_errno_with_filepath( return fx_result_propagate(fx_result_from_errno_with_filepath(
error, path, default_value)); error,
path,
default_value));
} }
switch (error) { switch (error) {
@@ -77,17 +90,20 @@ fx_result fx_result_from_errno_with_subfilepath(
case ENOENT: case ENOENT:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NO_ENTRY, FX_ERR_NO_ENTRY,
"Path @i{%s} in directory @i{%s} does not exist", path, "Path @i{%s} in directory @i{%s} does not exist",
path,
dir_path); dir_path);
case ENOTDIR: case ENOTDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NOT_DIRECTORY, FX_ERR_NOT_DIRECTORY,
"Path @i{%s} in directory @i{%s} is not a directory", "Path @i{%s} in directory @i{%s} is not a directory",
path, dir_path); path,
dir_path);
case EISDIR: case EISDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_IS_DIRECTORY, FX_ERR_IS_DIRECTORY,
"Path @i{%s} in directory @i{%s} is a directory", path, "Path @i{%s} in directory @i{%s} is a directory",
path,
dir_path); dir_path);
case EPERM: case EPERM:
case EACCES: case EACCES:
@@ -95,15 +111,19 @@ fx_result fx_result_from_errno_with_subfilepath(
FX_ERR_PERMISSION_DENIED, FX_ERR_PERMISSION_DENIED,
"Permission denied while accessing path @i{%s} in " "Permission denied while accessing path @i{%s} in "
"directory @i{%s}", "directory @i{%s}",
path, dir_path); path,
dir_path);
default: default:
return FX_RESULT_STATUS(fx_status_from_errno(error, default_value)); return FX_RESULT_STATUS(
fx_status_from_errno(error, default_value));
} }
return FX_RESULT_SUCCESS; return FX_RESULT_SUCCESS;
} }
enum fx_status fx_file_info_from_stat(const struct stat *st, struct fx_file_info *out) enum fx_status fx_file_info_from_stat(
const struct stat *st,
struct fx_file_info *out)
{ {
out->length = st->st_size; out->length = st->st_size;
+26
View File
@@ -0,0 +1,26 @@
#ifndef _IO_DARWIN_POSIX_H_
#define _IO_DARWIN_POSIX_H_
#include <fx/error.h>
#include <fx/status.h>
struct stat;
struct fx_file_info;
extern enum fx_status fx_status_from_errno(
int error,
enum fx_status default_value);
extern fx_result fx_result_from_errno_with_filepath(
int error,
const char *path,
enum fx_status default_value);
extern fx_result fx_result_from_errno_with_subfilepath(
int error,
const char *path,
const char *dir_path,
enum fx_status default_value);
extern enum fx_status fx_file_info_from_stat(
const struct stat *in,
struct fx_file_info *out);
#endif
@@ -6,9 +6,9 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <fts.h> #include <fts.h>
#include <fx/core/error.h> #include <fx/error.h>
#include <fx/ds/string.h>
#include <fx/io/directory.h> #include <fx/io/directory.h>
#include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -60,7 +60,9 @@ static const char *directory_get_rel_path_cstr(const struct fx_directory_p *dir)
return fx_path_ptr(dir->d_path_rel); return fx_path_ptr(dir->d_path_rel);
} }
static fx_result directory_delete(fx_directory *dir, struct fx_directory_p *dir_p) static fx_result directory_delete(
fx_directory *dir,
struct fx_directory_p *dir_p)
{ {
enum fx_status status = FX_SUCCESS; enum fx_status status = FX_SUCCESS;
@@ -84,7 +86,8 @@ static fx_result directory_delete(fx_directory *dir, struct fx_directory_p *dir_
} }
static bool directory_path_exists( static bool directory_path_exists(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -103,7 +106,8 @@ static bool directory_path_exists(
} }
static bool directory_path_is_file( static bool directory_path_is_file(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -122,7 +126,8 @@ static bool directory_path_is_file(
} }
static bool directory_path_is_directory( static bool directory_path_is_directory(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -141,7 +146,8 @@ static bool directory_path_is_directory(
} }
static fx_result directory_path_stat( static fx_result directory_path_stat(
const struct fx_directory_p *root, const fx_path *path, const struct fx_directory_p *root,
const fx_path *path,
struct fx_file_info *out) struct fx_file_info *out)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
@@ -161,7 +167,8 @@ static fx_result directory_path_stat(
} }
static fx_result directory_path_unlink( static fx_result directory_path_unlink(
const struct fx_directory_p *root, const fx_path *path) const struct fx_directory_p *root,
const fx_path *path)
{ {
const fx_path *parts[] = { const fx_path *parts[] = {
root ? root->d_path_abs : NULL, root ? root->d_path_abs : NULL,
@@ -195,11 +202,15 @@ static fx_result create_directory(struct fx_directory_p *root, const char *path)
} }
return fx_result_from_errno_with_subfilepath( return fx_result_from_errno_with_subfilepath(
errno, path, directory_get_rel_path_cstr(root), FX_ERR_IO_FAILURE); errno,
path,
directory_get_rel_path_cstr(root),
FX_ERR_IO_FAILURE);
} }
static fx_result create_directory_hierarchy( static fx_result create_directory_hierarchy(
struct fx_directory_p *root, const char *path) struct fx_directory_p *root,
const char *path)
{ {
int root_fd = root ? root->d_fd : AT_FDCWD; int root_fd = root ? root->d_fd : AT_FDCWD;
@@ -219,7 +230,9 @@ static fx_result create_directory_hierarchy(
int err = mkdirat(root_fd, path_buf, 0755); int err = mkdirat(root_fd, path_buf, 0755);
if (err != 0 && errno != EEXIST) { if (err != 0 && errno != EEXIST) {
result = fx_result_from_errno_with_subfilepath( result = fx_result_from_errno_with_subfilepath(
errno, path_buf, directory_get_rel_path_cstr(root), errno,
path_buf,
directory_get_rel_path_cstr(root),
FX_ERR_IO_FAILURE); FX_ERR_IO_FAILURE);
break; break;
} }
@@ -230,7 +243,9 @@ static fx_result create_directory_hierarchy(
int err = mkdirat(root_fd, path_buf, 0755); int err = mkdirat(root_fd, path_buf, 0755);
if (err != 0 && errno != EEXIST) { if (err != 0 && errno != EEXIST) {
result = fx_result_from_errno_with_subfilepath( result = fx_result_from_errno_with_subfilepath(
errno, path_buf, directory_get_rel_path_cstr(root), errno,
path_buf,
directory_get_rel_path_cstr(root),
FX_ERR_IO_FAILURE); FX_ERR_IO_FAILURE);
} }
@@ -239,8 +254,10 @@ static fx_result create_directory_hierarchy(
} }
static fx_result directory_open( static fx_result directory_open(
struct fx_directory_p *root, const fx_path *path, struct fx_directory_p *root,
fx_directory_open_flags flags, fx_directory **out) const fx_path *path,
fx_directory_open_flags flags,
fx_directory **out)
{ {
enum fx_status status = FX_SUCCESS; enum fx_status status = FX_SUCCESS;
@@ -257,7 +274,9 @@ static fx_result directory_open(
if ((flags & FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE) if ((flags & FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE)
== FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE) { == FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE) {
result = create_directory_hierarchy(root, path_cstr); result = create_directory_hierarchy(root, path_cstr);
} else if ((flags & FX_DIRECTORY_OPEN_CREATE) == FX_DIRECTORY_OPEN_CREATE) { } else if (
(flags & FX_DIRECTORY_OPEN_CREATE)
== FX_DIRECTORY_OPEN_CREATE) {
result = create_directory(root, path_cstr); result = create_directory(root, path_cstr);
} }
@@ -274,7 +293,8 @@ static fx_result directory_open(
fx_directory *dir = fx_object_create(FX_TYPE_DIRECTORY); fx_directory *dir = fx_object_create(FX_TYPE_DIRECTORY);
fx_path *cwd = NULL; fx_path *cwd = NULL;
struct fx_directory_p *p = fx_object_get_private(dir, FX_TYPE_DIRECTORY); struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
if (!root) { if (!root) {
cwd = fx_path_create_cwd(); cwd = fx_path_create_cwd();
@@ -310,11 +330,18 @@ static fx_result directory_open(
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_result fx_directory_open( fx_result fx_directory_open(
fx_directory *root, const fx_path *path, fx_directory_open_flags flags, fx_directory *root,
const fx_path *path,
fx_directory_open_flags flags,
fx_directory **out) fx_directory **out)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_open, root, path, flags, out); FX_TYPE_DIRECTORY,
directory_open,
root,
path,
flags,
out);
} }
fx_result fx_directory_open_temp(fx_directory **out) fx_result fx_directory_open_temp(fx_directory **out)
@@ -329,7 +356,10 @@ fx_result fx_directory_open_temp(fx_directory **out)
fx_directory *dir = NULL; fx_directory *dir = NULL;
fx_result status = fx_directory_open( fx_result status = fx_directory_open(
FX_DIRECTORY_ROOT, rpath, FX_DIRECTORY_OPEN_CREATE, &dir); FX_DIRECTORY_ROOT,
rpath,
FX_DIRECTORY_OPEN_CREATE,
&dir);
struct fx_directory_p *p struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY); = fx_object_get_private(dir, FX_TYPE_DIRECTORY);
@@ -356,23 +386,32 @@ const fx_path *fx_directory_get_path(const fx_directory *dir)
const fx_path *fx_directory_get_rel_path(const fx_directory *dir) const fx_path *fx_directory_get_rel_path(const fx_directory *dir)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DIRECTORY, directory_get_rel_path, dir); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DIRECTORY,
directory_get_rel_path,
dir);
} }
const char *fx_directory_get_path_cstr(const fx_directory *dir) const char *fx_directory_get_path_cstr(const fx_directory *dir)
{ {
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DIRECTORY, directory_get_path_cstr, dir); FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DIRECTORY,
directory_get_path_cstr,
dir);
} }
const char *fx_directory_get_rel_path_cstr(const fx_directory *dir) const char *fx_directory_get_rel_path_cstr(const fx_directory *dir)
{ {
FX_CLASS_DISPATCH_STATIC_0( FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_DIRECTORY, directory_get_rel_path_cstr, dir); FX_TYPE_DIRECTORY,
directory_get_rel_path_cstr,
dir);
} }
fx_result fx_directory_delete(fx_directory *dir) fx_result fx_directory_delete(fx_directory *dir)
{ {
struct fx_directory_p *p = fx_object_get_private(dir, FX_TYPE_DIRECTORY); struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
p->d_flags |= DIRECTORY_DELETE_ON_CLOSE; p->d_flags |= DIRECTORY_DELETE_ON_CLOSE;
/* TODO allow object release functions to return a fx_result value */ /* TODO allow object release functions to return a fx_result value */
fx_directory_unref(dir); fx_directory_unref(dir);
@@ -382,32 +421,54 @@ fx_result fx_directory_delete(fx_directory *dir)
bool fx_directory_path_exists(const fx_directory *root, const fx_path *path) bool fx_directory_path_exists(const fx_directory *root, const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_exists, root, path); FX_TYPE_DIRECTORY,
directory_path_exists,
root,
path);
} }
bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path) bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_is_file, root, path); FX_TYPE_DIRECTORY,
directory_path_is_file,
root,
path);
} }
bool fx_directory_path_is_directory(const fx_directory *root, const fx_path *path) bool fx_directory_path_is_directory(
const fx_directory *root,
const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_is_directory, root, path); FX_TYPE_DIRECTORY,
directory_path_is_directory,
root,
path);
} }
fx_result fx_directory_path_stat( fx_result fx_directory_path_stat(
const fx_directory *root, const fx_path *path, struct fx_file_info *out) const fx_directory *root,
const fx_path *path,
struct fx_file_info *out)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_stat, root, path, out); FX_TYPE_DIRECTORY,
directory_path_stat,
root,
path,
out);
} }
fx_result fx_directory_path_unlink(const fx_directory *root, const fx_path *path) fx_result fx_directory_path_unlink(
const fx_directory *root,
const fx_path *path)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY, directory_path_unlink, root, path); FX_TYPE_DIRECTORY,
directory_path_unlink,
root,
path);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
@@ -492,7 +553,8 @@ static void iterator_fini(fx_object *obj, void *priv)
} }
fx_iterator *fx_directory_begin( fx_iterator *fx_directory_begin(
fx_directory *directory, enum fx_directory_iterator_flags flags) fx_directory *directory,
enum fx_directory_iterator_flags flags)
{ {
fx_iterator *it_obj = fx_object_create(FX_TYPE_DIRECTORY_ITERATOR); fx_iterator *it_obj = fx_object_create(FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it struct fx_directory_iterator_p *it
@@ -562,7 +624,8 @@ static fx_iterator *iterator_begin(fx_object *obj)
static const fx_iterator *iterator_cbegin(const fx_object *obj) static const fx_iterator *iterator_cbegin(const fx_object *obj)
{ {
return fx_directory_begin( return fx_directory_begin(
(fx_object *)obj, FX_DIRECTORY_ITERATE_PARENT_FIRST); (fx_object *)obj,
FX_DIRECTORY_ITERATE_PARENT_FIRST);
} }
static enum fx_status iterator_move_next(const fx_iterator *obj) static enum fx_status iterator_move_next(const fx_iterator *obj)
@@ -618,7 +681,8 @@ static enum fx_status iterator_erase(fx_iterator *obj)
{ {
struct fx_directory_iterator_p *it struct fx_directory_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR); = fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR);
fx_result result = fx_directory_path_unlink(it->root, it->entry.filepath); fx_result result
= fx_directory_path_unlink(it->root, it->entry.filepath);
if (fx_result_is_error(result)) { if (fx_result_is_error(result)) {
enum fx_status status = fx_error_get_status_code(result); enum fx_status status = fx_error_get_status_code(result);
fx_error_discard(result); fx_error_discard(result);
+100 -29
View File
@@ -3,13 +3,13 @@
#include "misc.h" #include "misc.h"
#include "posix.h" #include "posix.h"
#include <fx/core/random.h> #include <errno.h>
#include <fx/ds/string.h> #include <fcntl.h>
#include <fx/io/directory.h> #include <fx/io/directory.h>
#include <fx/io/file.h> #include <fx/io/file.h>
#include <fx/io/path.h> #include <fx/io/path.h>
#include <errno.h> #include <fx/random.h>
#include <fcntl.h> #include <fx/string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -22,7 +22,10 @@ static enum fx_status stream_close(fx_stream *);
static enum fx_status stream_getc(fx_stream *, int *); static enum fx_status stream_getc(fx_stream *, int *);
static enum fx_status stream_read(fx_stream *, void *, size_t, size_t *); static enum fx_status stream_read(fx_stream *, void *, size_t, size_t *);
static enum fx_status stream_write(fx_stream *, const void *, size_t, size_t *); static enum fx_status stream_write(fx_stream *, const void *, size_t, size_t *);
static enum fx_status stream_seek(fx_stream *, long long, fx_stream_seek_origin); static enum fx_status stream_seek(
fx_stream *,
long long,
fx_stream_seek_origin);
static enum fx_status stream_tell(const fx_stream *, size_t *); static enum fx_status stream_tell(const fx_stream *, size_t *);
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
@@ -65,7 +68,9 @@ static unsigned int fx_mode_to_unix_mode(enum fx_file_mode mode)
} }
static fx_result file_open_shadow( static fx_result file_open_shadow(
struct fx_file_p *original, enum fx_file_mode mode, fx_file **out) struct fx_file_p *original,
enum fx_file_mode mode,
fx_file **out)
{ {
mode |= FX_FILE_SHADOW | FX_FILE_DELETE_ON_CLOSE | FX_FILE_CREATE; mode |= FX_FILE_SHADOW | FX_FILE_DELETE_ON_CLOSE | FX_FILE_CREATE;
@@ -77,7 +82,8 @@ static fx_result file_open_shadow(
fx_string_prepend_cstr(filename, ".~"); fx_string_prepend_cstr(filename, ".~");
fx_path *shadow_filename = fx_path_create_from_cstr(fx_string_get_cstr(filename)); fx_path *shadow_filename
= fx_path_create_from_cstr(fx_string_get_cstr(filename));
fx_string_unref(filename); fx_string_unref(filename);
const fx_path *parts[] = { const fx_path *parts[] = {
@@ -96,7 +102,10 @@ static fx_result file_open_shadow(
fx_file *shadow_file; fx_file *shadow_file;
fx_result status = fx_file_open( fx_result status = fx_file_open(
FX_DIRECTORY_ROOT, shadow_filepath, mode, &shadow_file); FX_DIRECTORY_ROOT,
shadow_filepath,
mode,
&shadow_file);
fx_path_unref(shadow_filepath); fx_path_unref(shadow_filepath);
if (fx_result_is_error(status)) { if (fx_result_is_error(status)) {
@@ -112,7 +121,9 @@ static const fx_path *file_path(const struct fx_file_p *file)
return file->path; return file->path;
} }
static enum fx_status file_stat(struct fx_file_p *file, struct fx_file_info *out) static enum fx_status file_stat(
struct fx_file_p *file,
struct fx_file_info *out)
{ {
struct stat st; struct stat st;
int err = fstat(file->fd, &st); int err = fstat(file->fd, &st);
@@ -169,7 +180,9 @@ static enum fx_status file_resize(struct fx_file_p *file, size_t len)
} }
static enum fx_status file_seek( static enum fx_status file_seek(
struct fx_file_p *file, long long offset, enum fx_seek_basis basis) struct fx_file_p *file,
long long offset,
enum fx_seek_basis basis)
{ {
int whence; int whence;
switch (basis) { switch (basis) {
@@ -195,7 +208,8 @@ static enum fx_status file_seek(
} }
static enum fx_status file_swap_shadow( static enum fx_status file_swap_shadow(
struct fx_file_p *main_file, struct fx_file_p *shadow_file) struct fx_file_p *main_file,
struct fx_file_p *shadow_file)
{ {
if (main_file->mode & FX_FILE_SHADOW) { if (main_file->mode & FX_FILE_SHADOW) {
return FX_ERR_NOT_SUPPORTED; return FX_ERR_NOT_SUPPORTED;
@@ -237,7 +251,9 @@ static enum fx_status file_swap_shadow(
int err; int err;
err = rename(fx_path_ptr(main_file->path), fx_path_ptr(tmp_path)); err = rename(fx_path_ptr(main_file->path), fx_path_ptr(tmp_path));
err = rename(fx_path_ptr(shadow_file->path), fx_path_ptr(main_file->path)); err = rename(
fx_path_ptr(shadow_file->path),
fx_path_ptr(main_file->path));
err = rename(fx_path_ptr(tmp_path), fx_path_ptr(shadow_file->path)); err = rename(fx_path_ptr(tmp_path), fx_path_ptr(shadow_file->path));
fx_path_unref(tmp_path); fx_path_unref(tmp_path);
@@ -250,7 +266,11 @@ static enum fx_status file_swap_shadow(
} }
static enum fx_status file_read( static enum fx_status file_read(
struct fx_file_p *file, size_t offset, size_t len, void *buf, size_t *nr_read) struct fx_file_p *file,
size_t offset,
size_t len,
void *buf,
size_t *nr_read)
{ {
if (offset != FX_OFFSET_CURRENT) { if (offset != FX_OFFSET_CURRENT) {
lseek(file->fd, offset, SEEK_SET); lseek(file->fd, offset, SEEK_SET);
@@ -269,7 +289,10 @@ static enum fx_status file_read(
} }
static enum fx_status file_write( static enum fx_status file_write(
struct fx_file_p *file, size_t offset, size_t len, const void *buf, struct fx_file_p *file,
size_t offset,
size_t len,
const void *buf,
size_t *nr_written) size_t *nr_written)
{ {
if (offset != FX_OFFSET_CURRENT) { if (offset != FX_OFFSET_CURRENT) {
@@ -316,7 +339,10 @@ static enum fx_status stream_getc(fx_stream *stream, int *out)
} }
static enum fx_status stream_read( static enum fx_status stream_read(
fx_stream *stream, void *buf, size_t max, size_t *nr_read) fx_stream *stream,
void *buf,
size_t max,
size_t *nr_read)
{ {
struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE); struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE);
@@ -327,7 +353,10 @@ static enum fx_status stream_read(
} }
static enum fx_status stream_write( static enum fx_status stream_write(
fx_stream *stream, const void *buf, size_t count, size_t *nr_written) fx_stream *stream,
const void *buf,
size_t count,
size_t *nr_written)
{ {
struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE); struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE);
@@ -338,7 +367,9 @@ static enum fx_status stream_write(
} }
static enum fx_status stream_seek( static enum fx_status stream_seek(
fx_stream *stream, long long offset, fx_stream_seek_origin origin) fx_stream *stream,
long long offset,
fx_stream_seek_origin origin)
{ {
fx_seek_basis basis; fx_seek_basis basis;
switch (origin) { switch (origin) {
@@ -362,7 +393,8 @@ static enum fx_status stream_seek(
static enum fx_status stream_tell(const fx_stream *stream, size_t *pos) static enum fx_status stream_tell(const fx_stream *stream, size_t *pos)
{ {
const struct fx_file_p *file = fx_object_get_private(stream, FX_TYPE_FILE); const struct fx_file_p *file
= fx_object_get_private(stream, FX_TYPE_FILE);
off_t v = lseek(file->fd, 0, SEEK_CUR); off_t v = lseek(file->fd, 0, SEEK_CUR);
if (v == (off_t)-1) { if (v == (off_t)-1) {
return fx_status_from_errno(errno, FX_ERR_IO_FAILURE); return fx_status_from_errno(errno, FX_ERR_IO_FAILURE);
@@ -375,7 +407,10 @@ static enum fx_status stream_tell(const fx_stream *stream, size_t *pos)
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_result fx_file_open( fx_result fx_file_open(
fx_directory *root, const fx_path *path, enum fx_file_mode mode, fx_file **out) fx_directory *root,
const fx_path *path,
enum fx_file_mode mode,
fx_file **out)
{ {
const fx_path *file_path = path; const fx_path *file_path = path;
unsigned int flags = fx_mode_to_unix_mode(mode); unsigned int flags = fx_mode_to_unix_mode(mode);
@@ -458,7 +493,10 @@ fx_result fx_file_open_temp(enum fx_file_mode mode, fx_file **out)
fx_path *rpath = fx_path_create_from_cstr(path); fx_path *rpath = fx_path_create_from_cstr(path);
fx_result status = fx_file_open( fx_result status = fx_file_open(
FX_DIRECTORY_ROOT, rpath, mode | FX_FILE_CREATE_ONLY, out); FX_DIRECTORY_ROOT,
rpath,
mode | FX_FILE_CREATE_ONLY,
out);
if (fx_error_get_status_code(status) == FX_ERR_NAME_EXISTS) { if (fx_error_get_status_code(status) == FX_ERR_NAME_EXISTS) {
fx_path_unref(rpath); fx_path_unref(rpath);
@@ -472,9 +510,17 @@ fx_result fx_file_open_temp(enum fx_file_mode mode, fx_file **out)
} }
} }
fx_result fx_file_open_shadow(fx_file *original, enum fx_file_mode mode, fx_file **out) fx_result fx_file_open_shadow(
fx_file *original,
enum fx_file_mode mode,
fx_file **out)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_open_shadow, original, mode, out); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_FILE,
file_open_shadow,
original,
mode,
out);
} }
const fx_path *fx_file_path(const fx_file *file) const fx_path *fx_file_path(const fx_file *file)
@@ -502,30 +548,55 @@ enum fx_status fx_file_resize(fx_file *file, size_t len)
FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_resize, file, len); FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_resize, file, len);
} }
enum fx_status fx_file_seek(fx_file *file, long long offset, enum fx_seek_basis basis) enum fx_status fx_file_seek(
fx_file *file,
long long offset,
enum fx_seek_basis basis)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_seek, file, offset, basis); FX_CLASS_DISPATCH_STATIC(FX_TYPE_FILE, file_seek, file, offset, basis);
} }
enum fx_status fx_file_swap_shadow(fx_file *main_file, fx_file *shadow_file) enum fx_status fx_file_swap_shadow(fx_file *main_file, fx_file *shadow_file)
{ {
struct fx_file_p *main_p = fx_object_get_private(main_file, FX_TYPE_FILE); struct fx_file_p *main_p
struct fx_file_p *shadow_p = fx_object_get_private(main_file, FX_TYPE_FILE); = fx_object_get_private(main_file, FX_TYPE_FILE);
struct fx_file_p *shadow_p
= fx_object_get_private(main_file, FX_TYPE_FILE);
return file_swap_shadow(main_p, shadow_p); return file_swap_shadow(main_p, shadow_p);
} }
enum fx_status fx_file_read( enum fx_status fx_file_read(
fx_file *file, size_t offset, size_t len, void *buf, size_t *nr_read) fx_file *file,
size_t offset,
size_t len,
void *buf,
size_t *nr_read)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_FILE, file_read, file, offset, len, buf, nr_read); FX_TYPE_FILE,
file_read,
file,
offset,
len,
buf,
nr_read);
} }
enum fx_status fx_file_write( enum fx_status fx_file_write(
fx_file *file, size_t offset, size_t len, const void *buf, size_t *nr_written) fx_file *file,
size_t offset,
size_t len,
const void *buf,
size_t *nr_written)
{ {
FX_CLASS_DISPATCH_STATIC( FX_CLASS_DISPATCH_STATIC(
FX_TYPE_FILE, file_write, file, offset, len, buf, nr_written); FX_TYPE_FILE,
file_write,
file,
offset,
len,
buf,
nr_written);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
@@ -1,6 +1,6 @@
#include "misc.h" #include "misc.h"
#include <fx/core/random.h> #include <fx/random.h>
void z__fx_io_generate_tmp_filename(char *out, size_t len) void z__fx_io_generate_tmp_filename(char *out, size_t len)
{ {
+29 -12
View File
@@ -1,11 +1,11 @@
#include "posix.h" #include "posix.h"
#include <fx/ds/string.h>
#include <fx/io/file.h>
#include <fx/io/path.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <fx/io/file.h>
#include <fx/io/path.h>
#include <fx/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -45,7 +45,9 @@ static const char *path_ptr(const struct fx_path_p *path)
return fx_string_get_cstr(path->p_pathstr); return fx_string_get_cstr(path->p_pathstr);
} }
static enum fx_status path_stat(const struct fx_path_p *path, struct fx_file_info *out) static enum fx_status path_stat(
const struct fx_path_p *path,
struct fx_file_info *out)
{ {
struct stat st; struct stat st;
int err = stat(path_ptr(path), &st); int err = stat(path_ptr(path), &st);
@@ -110,11 +112,13 @@ static void append_path(struct fx_path_p *dest, const struct fx_path_p *src)
static enum fx_status path_unlink(const struct fx_path_p *path) static enum fx_status path_unlink(const struct fx_path_p *path)
{ {
int err = remove(fx_string_get_cstr(path->p_pathstr)); int err = remove(fx_string_get_cstr(path->p_pathstr));
return err == 0 ? FX_SUCCESS : fx_status_from_errno(errno, FX_ERR_IO_FAILURE); return err == 0 ? FX_SUCCESS
: fx_status_from_errno(errno, FX_ERR_IO_FAILURE);
} }
static enum fx_status path_get_directory( static enum fx_status path_get_directory(
const struct fx_path_p *path, fx_path **out_dir_path) const struct fx_path_p *path,
fx_path **out_dir_path)
{ {
fx_string *path_str = path->p_pathstr; fx_string *path_str = path->p_pathstr;
long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL); long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL);
@@ -130,7 +134,8 @@ static enum fx_status path_get_directory(
size_t dir_path_len = (size_t)(sep - path_cstr); size_t dir_path_len = (size_t)(sep - path_cstr);
fx_string *dir_path_s = fx_string_get_substr(path_str, 0, dir_path_len); fx_string *dir_path_s = fx_string_get_substr(path_str, 0, dir_path_len);
fx_path *dir_path = fx_path_create_from_cstr(fx_string_get_cstr(dir_path_s)); fx_path *dir_path
= fx_path_create_from_cstr(fx_string_get_cstr(dir_path_s));
fx_string_unref(dir_path_s); fx_string_unref(dir_path_s);
*out_dir_path = dir_path; *out_dir_path = dir_path;
@@ -139,7 +144,8 @@ static enum fx_status path_get_directory(
} }
static enum fx_status path_get_filename( static enum fx_status path_get_filename(
const struct fx_path_p *path, fx_string *out_name) const struct fx_path_p *path,
fx_string *out_name)
{ {
fx_string *path_str = path->p_pathstr; fx_string *path_str = path->p_pathstr;
long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL); long len = fx_string_get_size(path_str, FX_STRLEN_NORMAL);
@@ -278,7 +284,8 @@ fx_path *fx_path_join(const fx_path *paths[], size_t nr_paths)
return NULL; return NULL;
} }
struct fx_path_p *result_p = fx_object_get_private(result, FX_TYPE_PATH); struct fx_path_p *result_p
= fx_object_get_private(result, FX_TYPE_PATH);
for (size_t i = 0; i < nr_paths; i++) { for (size_t i = 0; i < nr_paths; i++) {
if (paths[i]) { if (paths[i]) {
@@ -336,14 +343,24 @@ enum fx_status fx_path_unlink(const fx_path *path)
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_PATH, path_unlink, path); FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_PATH, path_unlink, path);
} }
enum fx_status fx_path_get_directory(const fx_path *path, fx_path **out_dir_path) enum fx_status fx_path_get_directory(
const fx_path *path,
fx_path **out_dir_path)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_PATH, path_get_directory, path, out_dir_path); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_PATH,
path_get_directory,
path,
out_dir_path);
} }
enum fx_status fx_path_get_filename(const fx_path *path, fx_string *out_name) enum fx_status fx_path_get_filename(const fx_path *path, fx_string *out_name)
{ {
FX_CLASS_DISPATCH_STATIC(FX_TYPE_PATH, path_get_filename, path, out_name); FX_CLASS_DISPATCH_STATIC(
FX_TYPE_PATH,
path_get_filename,
path,
out_name);
} }
const char *fx_path_ptr(const fx_path *path) const char *fx_path_ptr(const fx_path *path)
@@ -1,7 +1,7 @@
#include <fx/core/error.h>
#include <fx/core/status.h>
#include <fx/io/file.h>
#include <errno.h> #include <errno.h>
#include <fx/error.h>
#include <fx/io/file.h>
#include <fx/status.h>
#include <sys/stat.h> #include <sys/stat.h>
enum fx_status fx_status_from_errno(int error, enum fx_status default_value) enum fx_status fx_status_from_errno(int error, enum fx_status default_value)
@@ -35,40 +35,53 @@ enum fx_status fx_status_from_errno(int error, enum fx_status default_value)
} }
fx_result fx_result_from_errno_with_filepath( fx_result fx_result_from_errno_with_filepath(
int error, const char *path, enum fx_status default_value) int error,
const char *path,
enum fx_status default_value)
{ {
switch (error) { switch (error) {
case 0: case 0:
return FX_RESULT_SUCCESS; return FX_RESULT_SUCCESS;
case ENOENT: case ENOENT:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NO_ENTRY, "Path @i{%s} does not exist", path); FX_ERR_NO_ENTRY,
"Path @i{%s} does not exist",
path);
case ENOTDIR: case ENOTDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NOT_DIRECTORY, "Path @i{%s} is not a directory", FX_ERR_NOT_DIRECTORY,
"Path @i{%s} is not a directory",
path); path);
case EISDIR: case EISDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_IS_DIRECTORY, "Path @i{%s} is a directory", path); FX_ERR_IS_DIRECTORY,
"Path @i{%s} is a directory",
path);
case EPERM: case EPERM:
case EACCES: case EACCES:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_PERMISSION_DENIED, FX_ERR_PERMISSION_DENIED,
"Permission denied while accessing path @i{%s}", path); "Permission denied while accessing path @i{%s}",
path);
default: default:
return FX_RESULT_STATUS(fx_status_from_errno(error, default_value)); return FX_RESULT_STATUS(
fx_status_from_errno(error, default_value));
} }
return FX_RESULT_SUCCESS; return FX_RESULT_SUCCESS;
} }
fx_result fx_result_from_errno_with_subfilepath( fx_result fx_result_from_errno_with_subfilepath(
int error, const char *path, const char *dir_path, int error,
const char *path,
const char *dir_path,
enum fx_status default_value) enum fx_status default_value)
{ {
if (!dir_path) { if (!dir_path) {
return fx_result_propagate(fx_result_from_errno_with_filepath( return fx_result_propagate(fx_result_from_errno_with_filepath(
error, path, default_value)); error,
path,
default_value));
} }
switch (error) { switch (error) {
@@ -77,17 +90,20 @@ fx_result fx_result_from_errno_with_subfilepath(
case ENOENT: case ENOENT:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NO_ENTRY, FX_ERR_NO_ENTRY,
"Path @i{%s} in directory @i{%s} does not exist", path, "Path @i{%s} in directory @i{%s} does not exist",
path,
dir_path); dir_path);
case ENOTDIR: case ENOTDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_NOT_DIRECTORY, FX_ERR_NOT_DIRECTORY,
"Path @i{%s} in directory @i{%s} is not a directory", "Path @i{%s} in directory @i{%s} is not a directory",
path, dir_path); path,
dir_path);
case EISDIR: case EISDIR:
return FX_RESULT_STATUS_WITH_STRING( return FX_RESULT_STATUS_WITH_STRING(
FX_ERR_IS_DIRECTORY, FX_ERR_IS_DIRECTORY,
"Path @i{%s} in directory @i{%s} is a directory", path, "Path @i{%s} in directory @i{%s} is a directory",
path,
dir_path); dir_path);
case EPERM: case EPERM:
case EACCES: case EACCES:
@@ -95,15 +111,19 @@ fx_result fx_result_from_errno_with_subfilepath(
FX_ERR_PERMISSION_DENIED, FX_ERR_PERMISSION_DENIED,
"Permission denied while accessing path @i{%s} in " "Permission denied while accessing path @i{%s} in "
"directory @i{%s}", "directory @i{%s}",
path, dir_path); path,
dir_path);
default: default:
return FX_RESULT_STATUS(fx_status_from_errno(error, default_value)); return FX_RESULT_STATUS(
fx_status_from_errno(error, default_value));
} }
return FX_RESULT_SUCCESS; return FX_RESULT_SUCCESS;
} }
enum fx_status fx_file_info_from_stat(const struct stat *st, struct fx_file_info *out) enum fx_status fx_file_info_from_stat(
const struct stat *st,
struct fx_file_info *out)
{ {
out->length = st->st_size; out->length = st->st_size;
+26
View File
@@ -0,0 +1,26 @@
#ifndef _IO_DARWIN_POSIX_H_
#define _IO_DARWIN_POSIX_H_
#include <fx/error.h>
#include <fx/status.h>
struct stat;
struct fx_file_info;
extern enum fx_status fx_status_from_errno(
int error,
enum fx_status default_value);
extern fx_result fx_result_from_errno_with_filepath(
int error,
const char *path,
enum fx_status default_value);
extern fx_result fx_result_from_errno_with_subfilepath(
int error,
const char *path,
const char *dir_path,
enum fx_status default_value);
extern enum fx_status fx_file_info_from_stat(
const struct stat *in,
struct fx_file_info *out);
#endif
+1
View File
@@ -0,0 +1 @@
export_fx_namespace_details(fx.reflection)
+264
View File
@@ -0,0 +1,264 @@
#include <fx/bst.h>
#include <fx/hash.h>
#include <fx/macros.h>
#include <fx/queue.h>
#include <fx/reflection/assembly.h>
enum map_entry_type {
MAP_ENTRY_NONE = 0,
MAP_ENTRY_ITEM,
MAP_ENTRY_BUCKET,
};
struct map_entry {
enum map_entry_type e_type;
uint64_t e_hash;
union {
fx_queue_entry e_entry;
fx_bst_node e_node;
};
};
struct map_bucket {
struct map_entry b_entry;
fx_queue b_items;
};
struct map_item {
struct map_entry i_entry;
const char *i_name;
};
struct map {
fx_bst m_entries;
};
struct type {
struct map_item e_map_item;
fx_type e_type;
};
struct fx_assembly_p {
const char *a_name;
struct map a_types;
struct {
long v_major;
long v_minor;
long v_build;
long v_revision;
} a_version;
};
/*** PRIVATE FUNCTIONS ********************************************************/
FX_BST_DEFINE_SIMPLE_GET(
struct map_entry,
uint64_t,
e_node,
e_hash,
map_get_entry);
FX_BST_DEFINE_SIMPLE_INSERT(struct map_entry, e_node, e_hash, map_put_entry);
static struct map_bucket *map_item_convert_to_bucket(
struct map *map,
struct map_item *item)
{
struct map_bucket *bucket = malloc(sizeof *bucket);
memset(bucket, 0x0, sizeof *bucket);
bucket->b_entry.e_hash = item->i_entry.e_hash;
bucket->b_entry.e_type = MAP_ENTRY_BUCKET;
fx_bst_delete(&map->m_entries, &item->i_entry.e_node);
fx_queue_push_back(&bucket->b_items, &item->i_entry.e_entry);
map_put_entry(&map->m_entries, &bucket->b_entry);
return bucket;
}
static void map_put(struct map *map, const char *name, struct map_item *item)
{
uint64_t hash = fx_hash_cstr(name);
item->i_entry.e_type = MAP_ENTRY_ITEM;
item->i_entry.e_hash = hash;
item->i_name = name;
struct map_entry *entry = map_get_entry(&map->m_entries, hash);
if (!entry) {
map_put_entry(&map->m_entries, &item->i_entry);
return;
}
struct map_item *existing_item = NULL;
struct map_bucket *bucket = NULL;
switch (entry->e_type) {
case MAP_ENTRY_ITEM:
existing_item = (struct map_item *)entry;
bucket = map_item_convert_to_bucket(map, existing_item);
fx_queue_push_back(&bucket->b_items, &item->i_entry.e_entry);
break;
case MAP_ENTRY_BUCKET:
bucket = (struct map_bucket *)entry;
fx_queue_push_back(&bucket->b_items, &item->i_entry.e_entry);
break;
default:
break;
}
}
static void assembly_set_name(struct fx_assembly_p *asm, const char *name)
{
asm->a_name = name;
}
static void assembly_set_version(
struct fx_assembly_p *asm,
long major,
long minor,
long build,
long revision)
{
asm->a_version.v_major = major;
asm->a_version.v_minor = minor;
asm->a_version.v_build = build;
asm->a_version.v_revision = revision;
}
#include <stdio.h>
static void assembly_add_type(
struct fx_assembly_p *asm,
const char *full_name,
fx_type type_id)
{
struct type *type = malloc(sizeof *type);
memset(type, 0x0, sizeof *type);
map_put(&asm->a_types, full_name, &type->e_map_item);
}
static void map_item_dump(struct map_item *item)
{
struct type *type = (struct type *)item;
printf(" Type: %s\n", type->e_map_item.i_name);
}
static void assembly_dump(struct fx_assembly_p *asm)
{
printf("Loaded assembly:\n");
printf(" %s, Version=%ld.%ld.%ld.%ld\n",
asm->a_name,
asm->a_version.v_major,
asm->a_version.v_minor,
asm->a_version.v_build,
asm->a_version.v_revision);
fx_bst_node *cur_node = fx_bst_first(&asm->a_types.m_entries);
while (cur_node) {
struct map_entry *entry
= fx_unbox(struct map_entry, cur_node, e_node);
switch (entry->e_type) {
case MAP_ENTRY_ITEM: {
struct map_item *item = (struct map_item *)entry;
map_item_dump(item);
break;
}
case MAP_ENTRY_BUCKET: {
struct map_bucket *bucket = (struct map_bucket *)entry;
fx_queue_entry *cur_qentry
= fx_queue_first(&bucket->b_items);
while (cur_qentry) {
struct map_item *item = fx_unbox(
struct map_item,
cur_qentry,
i_entry.e_entry);
map_item_dump(item);
cur_qentry = fx_queue_next(cur_qentry);
}
}
default:
break;
}
cur_node = fx_bst_next(cur_node);
}
}
/*** PUBLIC FUNCTIONS *********************************************************/
void fx_assembly_set_name(fx_assembly *asm, const char *name)
{
FX_CLASS_DISPATCH_STATIC_V(
FX_REFLECTION_TYPE_ASSEMBLY,
assembly_set_name,
asm,
name);
}
void fx_assembly_set_version(
fx_assembly *asm,
long major,
long minor,
long build,
long revision)
{
FX_CLASS_DISPATCH_STATIC_V(
FX_REFLECTION_TYPE_ASSEMBLY,
assembly_set_version,
asm,
major,
minor,
build,
revision);
}
void fx_assembly_add_type(
fx_assembly *asm,
const char *full_name,
fx_type type_id)
{
FX_CLASS_DISPATCH_STATIC_V(
FX_REFLECTION_TYPE_ASSEMBLY,
assembly_add_type,
asm,
full_name,
type_id);
}
void fx_assembly_dump(const fx_assembly *asm)
{
FX_CLASS_DISPATCH_STATIC_0(
FX_REFLECTION_TYPE_ASSEMBLY,
assembly_dump,
asm);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void assembly_init(fx_object *obj, void *priv)
{
}
static void assembly_fini(fx_object *obj, void *priv)
{
}
/*** CLASS DEFINITION *********************************************************/
// ---- fx_string DEFINITION
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_assembly)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_assembly)
FX_TYPE_DEFINITION_BEGIN(fx_assembly)
FX_TYPE_ID(0xf6690c30, 0x6642, 0x42f0, 0xb79f, 0xe2baf3684b1b);
FX_TYPE_CLASS(fx_assembly_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_assembly_p);
FX_TYPE_INSTANCE_INIT(assembly_init);
FX_TYPE_INSTANCE_FINI(assembly_fini);
FX_TYPE_DEFINITION_END(fx_assembly)
@@ -0,0 +1,37 @@
#ifndef FX_REFLECTION_ASSEMBLY_H_
#define FX_REFLECTION_ASSEMBLY_H_
#include <fx/macros.h>
FX_DECLS_BEGIN;
#define FX_REFLECTION_TYPE_ASSEMBLY (fx_assembly_get_type())
FX_DECLARE_TYPE(fx_assembly);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_assembly)
FX_TYPE_CLASS_DECLARATION_END(fx_assembly)
FX_API fx_type fx_assembly_get_type();
FX_TYPE_DEFAULT_CONSTRUCTOR(fx_assembly, FX_REFLECTION_TYPE_ASSEMBLY);
FX_API void fx_assembly_set_name(fx_assembly *asm, const char *name);
FX_API void fx_assembly_set_version(
fx_assembly *asm,
long major,
long minor,
long build,
long revision);
FX_API void fx_assembly_add_type(
fx_assembly *asm,
const char *full_name,
fx_type type_id);
FX_API void fx_assembly_dump(const fx_assembly *asm);
FX_DECLS_END
;
#endif
+1
View File
@@ -0,0 +1 @@
export_fx_namespace_details(fx.serial)
View File
@@ -1,7 +1,7 @@
#ifndef FX_SERIAL_BITCODE_H_ #ifndef FX_SERIAL_BITCODE_H_
#define FX_SERIAL_BITCODE_H_ #define FX_SERIAL_BITCODE_H_
#include <fx/core/macros.h> #include <fx/macros.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -1,11 +1,11 @@
#ifndef FX_SERIAL_CTX_H_ #ifndef FX_SERIAL_CTX_H_
#define FX_SERIAL_CTX_H_ #define FX_SERIAL_CTX_H_
#include <fx/core/macros.h> #include <fx/macros.h>
#include <fx/core/misc.h> #include <fx/misc.h>
#include <fx/core/object.h> #include <fx/object.h>
#include <fx/core/status.h> #include <fx/status.h>
#include <fx/core/stream.h> #include <fx/stream.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -1,7 +1,7 @@
#ifndef FX_SERIAL_TOML_H_ #ifndef FX_SERIAL_TOML_H_
#define FX_SERIAL_TOML_H_ #define FX_SERIAL_TOML_H_
#include <fx/core/macros.h> #include <fx/macros.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
View File
View File
+21 -21
View File
@@ -1,14 +1,14 @@
#include <fx/core/error.h> #include <fx/collections/array.h>
#include <fx/core/status.h> #include <fx/collections/datetime.h>
#include <fx/core/stringstream.h> #include <fx/collections/dict.h>
#include <fx/ds/array.h> #include <fx/collections/hashmap.h>
#include <fx/ds/datetime.h> #include <fx/collections/number.h>
#include <fx/ds/dict.h> #include <fx/error.h>
#include <fx/ds/hashmap.h>
#include <fx/ds/number.h>
#include <fx/ds/string.h>
#include <fx/serial/ctx.h> #include <fx/serial/ctx.h>
#include <fx/serial/toml.h> #include <fx/serial/toml.h>
#include <fx/status.h>
#include <fx/string.h>
#include <fx/stringstream.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -1400,7 +1400,7 @@ static void read_newline(struct ctx *ctx)
} }
enqueue_token(ctx, TOK_NEWLINE); enqueue_token(ctx, TOK_NEWLINE);
ctx->ctx_result = FX_SUCCESS; ctx->ctx_result = FX_RESULT_SUCCESS;
} }
static void read_comment(struct ctx *ctx) static void read_comment(struct ctx *ctx)
@@ -1670,7 +1670,7 @@ static fx_result parse_timestamp(struct ctx *ctx, fx_object **result)
tok->tok_value.time = NULL; tok->tok_value.time = NULL;
*result = (dt); *result = (dt);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_string(struct ctx *ctx, fx_object **result) static fx_result parse_string(struct ctx *ctx, fx_object **result)
@@ -1682,7 +1682,7 @@ static fx_result parse_string(struct ctx *ctx, fx_object **result)
} }
*result = (str); *result = (str);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_int(struct ctx *ctx, fx_object **result) static fx_result parse_int(struct ctx *ctx, fx_object **result)
@@ -1708,7 +1708,7 @@ static fx_result parse_int(struct ctx *ctx, fx_object **result)
} }
*result = (val); *result = (val);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_float(struct ctx *ctx, fx_object **result) static fx_result parse_float(struct ctx *ctx, fx_object **result)
@@ -1734,7 +1734,7 @@ static fx_result parse_float(struct ctx *ctx, fx_object **result)
} }
*result = (val); *result = (val);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_bool(struct ctx *ctx, fx_object **result) static fx_result parse_bool(struct ctx *ctx, fx_object **result)
@@ -1746,7 +1746,7 @@ static fx_result parse_bool(struct ctx *ctx, fx_object **result)
} }
*result = (val); *result = (val);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_table_inline(struct ctx *ctx, fx_object **result) static fx_result parse_table_inline(struct ctx *ctx, fx_object **result)
@@ -1763,7 +1763,7 @@ static fx_result parse_table_inline(struct ctx *ctx, fx_object **result)
struct token *tok = peek_token(ctx); struct token *tok = peek_token(ctx);
if (tok && tok->tok_type == TOK_RIGHT_BRACE) { if (tok && tok->tok_type == TOK_RIGHT_BRACE) {
*result = (table); *result = (table);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
bool done = false; bool done = false;
@@ -1797,7 +1797,7 @@ static fx_result parse_table_inline(struct ctx *ctx, fx_object **result)
} }
*result = (table); *result = (table);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static void skip_newlines(struct ctx *ctx) static void skip_newlines(struct ctx *ctx)
@@ -1878,7 +1878,7 @@ static fx_result parse_array_inline(struct ctx *ctx, fx_object **result)
DISABLE_EXTENDED_LEXING(ctx); DISABLE_EXTENDED_LEXING(ctx);
*result = (array); *result = (array);
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_value(struct ctx *ctx, fx_object **result) static fx_result parse_value(struct ctx *ctx, fx_object **result)
@@ -2005,7 +2005,7 @@ static fx_result parse_key_value_pair(struct ctx *ctx, fx_dict *container)
ctx_set_object_flags(ctx, value, OBJECT_KV_END_DEFINED); ctx_set_object_flags(ctx, value, OBJECT_KV_END_DEFINED);
} }
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_table_header( static fx_result parse_table_header(
@@ -2101,7 +2101,7 @@ static fx_result parse_table_header(
advance_token(ctx); advance_token(ctx);
*new_container = new_table; *new_container = new_table;
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_array_header( static fx_result parse_array_header(
@@ -2183,7 +2183,7 @@ static fx_result parse_array_header(
advance_token(ctx); advance_token(ctx);
*new_container = new_table; *new_container = new_table;
return FX_SUCCESS; return FX_RESULT_SUCCESS;
} }
static fx_result parse_root(struct ctx *ctx, fx_dict **out) static fx_result parse_root(struct ctx *ctx, fx_dict **out)
View File
+1
View File
@@ -0,0 +1 @@
export_fx_namespace_details(fx.term)
+49 -23
View File
@@ -1,11 +1,13 @@
#include <fx/core/error.h> #include <fx/error.h>
#include <fx/core/stringstream.h> #include <fx/stringstream.h>
#include <fx/term/tty.h> #include <fx/term/tty.h>
#include <inttypes.h> #include <inttypes.h>
static void get_error_id( static void get_error_id(
const struct fx_error_vendor *vendor, const struct fx_error *error, const struct fx_error_vendor *vendor,
char *out, size_t max) const struct fx_error *error,
char *out,
size_t max)
{ {
const char *vendor_name = NULL; const char *vendor_name = NULL;
const char *error_name = NULL; const char *error_name = NULL;
@@ -38,7 +40,8 @@ static void get_error_id(
} }
static void print_template_parameter( static void print_template_parameter(
const struct fx_error_template_parameter *params, size_t nr_params, const struct fx_error_template_parameter *params,
size_t nr_params,
const char *param_name) const char *param_name)
{ {
const struct fx_error_template_parameter *param = NULL; const struct fx_error_template_parameter *param = NULL;
@@ -122,7 +125,8 @@ static void print_template_parameter(
} }
static void print_content( static void print_content(
const struct fx_error_template_parameter *params, size_t nr_params, const struct fx_error_template_parameter *params,
size_t nr_params,
const char *s) const char *s)
{ {
if (!s) { if (!s) {
@@ -214,13 +218,16 @@ static void print_content(
static void print_submsg(const struct fx_error *error) static void print_submsg(const struct fx_error *error)
{ {
const struct fx_error_definition *error_def = fx_error_get_definition(error); const struct fx_error_definition *error_def
= fx_error_get_definition(error);
const struct fx_error_submsg *submsg = fx_error_get_first_submsg(error); const struct fx_error_submsg *submsg = fx_error_get_first_submsg(error);
while (submsg) { while (submsg) {
enum fx_error_submsg_type type = fx_error_submsg_get_type(submsg); enum fx_error_submsg_type type
= fx_error_submsg_get_type(submsg);
const char *content = fx_error_submsg_get_content(submsg); const char *content = fx_error_submsg_get_content(submsg);
const struct fx_error_msg *msg = fx_error_submsg_get_msg(submsg); const struct fx_error_msg *msg
= fx_error_submsg_get_msg(submsg);
const struct fx_error_template_parameter *params const struct fx_error_template_parameter *params
= fx_error_submsg_get_template_parameters(submsg); = fx_error_submsg_get_template_parameters(submsg);
@@ -229,16 +236,21 @@ static void print_submsg(const struct fx_error *error)
switch (type) { switch (type) {
case FX_ERROR_SUBMSG_ERROR: case FX_ERROR_SUBMSG_ERROR:
fx_tty_printf( fx_tty_printf(
fx_stdtty_err, 0, "[bright_red,bold]>[reset] "); fx_stdtty_err,
0,
"[bright_red,bold]>[reset] ");
break; break;
case FX_ERROR_SUBMSG_WARNING: case FX_ERROR_SUBMSG_WARNING:
fx_tty_printf( fx_tty_printf(
fx_stdtty_err, 0, fx_stdtty_err,
0,
"[bright_yellow,bold]>[reset] "); "[bright_yellow,bold]>[reset] ");
break; break;
case FX_ERROR_SUBMSG_INFO: case FX_ERROR_SUBMSG_INFO:
fx_tty_printf( fx_tty_printf(
fx_stdtty_err, 0, "[bright_cyan,bold]>[reset] "); fx_stdtty_err,
0,
"[bright_cyan,bold]>[reset] ");
break; break;
default: default:
break; break;
@@ -246,11 +258,14 @@ static void print_submsg(const struct fx_error *error)
if (msg) { if (msg) {
print_content( print_content(
params, FX_ERROR_TEMPLATE_PARAMETER_MAX, params,
FX_ERROR_TEMPLATE_PARAMETER_MAX,
fx_error_msg_get_content(msg)); fx_error_msg_get_content(msg));
} else if (content) { } else if (content) {
print_content( print_content(
params, FX_ERROR_TEMPLATE_PARAMETER_MAX, content); params,
FX_ERROR_TEMPLATE_PARAMETER_MAX,
content);
} }
fx_tty_printf(fx_stdtty_err, 0, "\n"); fx_tty_printf(fx_stdtty_err, 0, "\n");
@@ -293,8 +308,11 @@ static void print_stack_trace(const struct fx_error *error)
file = get_short_filepath(file); file = get_short_filepath(file);
fx_tty_printf( fx_tty_printf(
fx_stdtty_err, 0, fx_stdtty_err,
" [dark_grey]at %s() (%s:%u)[reset]\n", func, file, 0,
" [dark_grey]at %s() (%s:%u)[reset]\n",
func,
file,
line); line);
frame = fx_error_get_next_stack_frame(error, frame); frame = fx_error_get_next_stack_frame(error, frame);
@@ -302,14 +320,17 @@ static void print_stack_trace(const struct fx_error *error)
} }
static void report_error( static void report_error(
const fx_error *error, fx_error_report_flags flags, bool caused_by) const fx_error *error,
fx_error_report_flags flags,
bool caused_by)
{ {
const fx_error_vendor *vendor = fx_error_get_vendor(error); const fx_error_vendor *vendor = fx_error_get_vendor(error);
char error_id[128]; char error_id[128];
get_error_id(vendor, error, error_id, sizeof error_id); get_error_id(vendor, error, error_id, sizeof error_id);
const struct fx_error_definition *error_def = fx_error_get_definition(error); const struct fx_error_definition *error_def
= fx_error_get_definition(error);
fx_error_status_code code = fx_error_get_status_code(error); fx_error_status_code code = fx_error_get_status_code(error);
const char *description = fx_error_get_description(error); const char *description = fx_error_get_description(error);
const struct fx_error_template_parameter *params const struct fx_error_template_parameter *params
@@ -317,12 +338,14 @@ static void report_error(
if (!description && vendor) { if (!description && vendor) {
description = fx_error_vendor_get_status_code_description( description = fx_error_vendor_get_status_code_description(
vendor, code); vendor,
code);
} }
if (caused_by) { if (caused_by) {
fx_tty_printf( fx_tty_printf(
fx_stdtty_err, 0, fx_stdtty_err,
0,
" [green]->[reset] caused by [bright_red,bold]ERROR "); " [green]->[reset] caused by [bright_red,bold]ERROR ");
} else { } else {
fx_tty_printf(fx_stdtty_err, 0, "[bright_red,bold]==> ERROR "); fx_tty_printf(fx_stdtty_err, 0, "[bright_red,bold]==> ERROR ");
@@ -339,12 +362,14 @@ static void report_error(
if (msg) { if (msg) {
fx_tty_printf(fx_stdtty_err, 0, ": "); fx_tty_printf(fx_stdtty_err, 0, ": ");
print_content( print_content(
params, FX_ERROR_TEMPLATE_PARAMETER_MAX, params,
FX_ERROR_TEMPLATE_PARAMETER_MAX,
fx_error_msg_get_content(msg)); fx_error_msg_get_content(msg));
} else if (description) { } else if (description) {
fx_tty_printf(fx_stdtty_err, 0, ": "); fx_tty_printf(fx_stdtty_err, 0, ": ");
print_content( print_content(
params, FX_ERROR_TEMPLATE_PARAMETER_MAX, params,
FX_ERROR_TEMPLATE_PARAMETER_MAX,
description); description);
} }
} }
@@ -366,7 +391,8 @@ static void report_error(
} }
void fx_enhanced_error_reporter( void fx_enhanced_error_reporter(
const struct fx_error *error, fx_error_report_flags flags) const struct fx_error *error,
fx_error_report_flags flags)
{ {
report_error(error, flags, false); report_error(error, flags, false);
} }

Some files were not shown because too many files have changed in this diff Show More