Compare commits

6 Commits

255 changed files with 13805 additions and 12900 deletions

View File

@@ -1,52 +1,56 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(fx C) project(bluelib C CXX)
include (TestBigEndian) include (TestBigEndian)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_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)
set(fx_modules core ds serial term cmd io compress) set(b_modules
core ds serial term cmd io compress
core-mm ds-mm)
set(fx_system_name ${CMAKE_SYSTEM_NAME}) set(b_system_name ${CMAKE_SYSTEM_NAME})
string(TOLOWER ${fx_system_name} fx_system_name) string(TOLOWER ${b_system_name} b_system_name)
message(STATUS "System name: ${fx_system_name}") message(STATUS "System name: ${b_system_name}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) 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}) foreach (module ${b_modules})
add_subdirectory(${module}) add_subdirectory(${module})
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module}) if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module})
message(STATUS "Building unit tests for module ${module}") message(STATUS "Building unit tests for module ${module}")
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c) if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c)
add_executable(fx-${module}-units add_executable(blue-${module}-units
test/${module}/${module}-units.c test/${module}/${module}-units.c
misc/AllTests.c misc/AllTests.c
misc/CuTest.c misc/CuTest.c
misc/CuTest.h) misc/CuTest.h)
target_link_libraries(fx-${module}-units fx-${module}) target_link_libraries(blue-${module}-units blue-${module})
target_include_directories(fx-${module}-units PRIVATE misc/) target_include_directories(blue-${module}-units PRIVATE misc/)
set_target_properties(fx-${module}-units PROPERTIES FOLDER "Tests/${module}") set_target_properties(blue-${module}-units PROPERTIES FOLDER "Tests/${module}")
endif () endif ()
file(GLOB test_sources test/${module}/*.c) file(GLOB test_sources test/${module}/*.c test/${module}/*.cpp)
list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c") list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/${module}/${module}-units.c")
foreach (test_file ${test_sources}) foreach (test_file ${test_sources})
get_filename_component(test_name ${test_file} NAME_WE) get_filename_component(test_name ${test_file} NAME_WE)
add_executable(fx-${module}-${test_name} ${test_file}) add_executable(blue-${module}-${test_name} ${test_file})
set_target_properties(fx-${module}-${test_name} PROPERTIES FOLDER "Tests/${module}") set_target_properties(blue-${module}-${test_name} PROPERTIES FOLDER "Tests/${module}")
target_link_libraries(fx-${module}-${test_name} fx-${module}) target_link_libraries(blue-${module}-${test_name} blue-${module})
endforeach (test_file) endforeach (test_file)
endif () endif ()
endforeach (module) endforeach (module)
@@ -56,11 +60,11 @@ list(REMOVE_ITEM test_sources "${CMAKE_CURRENT_SOURCE_DIR}/test/units.c")
foreach (test_file ${test_sources}) foreach (test_file ${test_sources})
get_filename_component(test_name ${test_file} NAME_WE) get_filename_component(test_name ${test_file} NAME_WE)
add_executable(fx-${test_name} ${test_file}) add_executable(blue-${test_name} ${test_file})
set_target_properties(fx-${test_name} PROPERTIES FOLDER "Tests") set_target_properties(blue-${test_name} PROPERTIES FOLDER "Tests")
foreach (module ${fx_modules}) foreach (module ${b_modules})
target_link_libraries(fx-${test_name} fx-${module}) target_link_libraries(blue-${test_name} blue-${module})
endforeach (module) endforeach (module)
endforeach (test_file) endforeach (test_file)

189
cmake/FindBluelib.cmake Normal file
View File

@@ -0,0 +1,189 @@
#[=======================================================================[.rst:
FindBluelib
------------
Find the Bluelib library and header directories
Imported Targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``Bluelib::Bluelib``
The Bluelib library, if found
Result Variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``Bluelib_FOUND``
true if the Bluelib C headers and libraries were found
``Bluelib_INCLUDE_DIR``
directories containing the Bluelib C headers.
``Bluelib_LIBRARY``
the C library to link against
Hints
^^^^^
The user may set the environment variable ``Bluelib_PREFIX`` to the root
directory of a Bluelib library installation.
#]=======================================================================]
set (Bluelib_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr/local/share
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${Bluelib_PREFIX}
$ENV{Bluelib_PREFIX})
if (Bluelib_STATIC)
set(_lib_suffix "-s")
endif ()
set(supported_components Core Ds Term Cmd Io Serial Compress)
set(components ${Bluelib_FIND_COMPONENTS})
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
if (NOT components)
set(components ${supported_components})
endif ()
set(required_vars)
foreach (component ${components})
if (NOT "${component}" IN_LIST supported_components)
message(FATAL_ERROR "'${component}' is not a valid Bluelib module.\nSupported modules: ${supported_components_string_list}")
endif ()
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if (NOT Bluelib_${component}_INCLUDE_DIR)
find_path(Bluelib_${component}_INCLUDE_DIR
NAMES blue/${header_name}.h ${Bluelib_FIND_ARGS}
PATH_SUFFIXES include
PATHS ${Bluelib_SEARCH_PATHS})
endif ()
if (NOT Bluelib_${component}_LIBRARY)
find_library(Bluelib_${component}_LIBRARY
NAMES blue-${lib_name} ${Bluelib_FIND_ARGS}
PATH_SUFFIXES lib
PATHS ${Bluelib_SEARCH_PATHS})
else ()
# on Windows, ensure paths are in canonical format (forward slahes):
file(TO_CMAKE_PATH "${Bluelib_${component}_LIBRARY}" Bluelib_${component}_LIBRARY)
endif()
list(APPEND required_vars Bluelib_${component}_INCLUDE_DIR Bluelib_${component}_LIBRARY)
endforeach (component)
unset(Bluelib_FIND_ARGS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Bluelib
REQUIRED_VARS ${required_vars})
if (Bluelib_FOUND)
set(created_targets)
foreach (component ${components})
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if(NOT TARGET Bluelib::${component})
add_library(Bluelib::${component} UNKNOWN IMPORTED)
set_target_properties(Bluelib::${component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Bluelib_${component}_INCLUDE_DIR}")
target_compile_definitions(Bluelib::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
if (Bluelib_STATIC)
target_compile_definitions(Bluelib::${component} INTERFACE BLUELIB_STATIC=1)
endif ()
set_target_properties(Bluelib::${component} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${Bluelib_${component}_LIBRARY}")
set(created_targets ${created_targets} ${component})
endif ()
endforeach (component)
foreach (component ${created_targets})
if ("${component}" STREQUAL "Ds")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Ds' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Ds INTERFACE Bluelib::Core)
endif ()
if ("${component}" STREQUAL "Term")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Term INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Serial")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Serial INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Cmd")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Term)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Cmd INTERFACE Bluelib::Core Bluelib::Ds Bluelib::Term)
endif ()
if ("${component}" STREQUAL "Io")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Io INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Compress")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Compress' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Compress INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
endforeach (component)
endif()

View File

@@ -1,189 +0,0 @@
#[=======================================================================[.rst:
FindFX
------------
Find the FX library and header directories
Imported Targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``FX::FX``
The FX library, if found
Result Variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``FX_FOUND``
true if the FX C headers and libraries were found
``FX_INCLUDE_DIR``
directories containing the FX C headers.
``FX_LIBRARY``
the C library to link against
Hints
^^^^^
The user may set the environment variable ``FX_PREFIX`` to the root
directory of a FX library installation.
#]=======================================================================]
set (FX_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr/local/share
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${FX_PREFIX}
$ENV{FX_PREFIX})
if (FX_STATIC)
set(_lib_suffix "-s")
endif ()
set(supported_components Core Ds Term Cmd Io Serial Compress)
set(components ${FX_FIND_COMPONENTS})
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
if (NOT components)
set(components ${supported_components})
endif ()
set(required_vars)
foreach (component ${components})
if (NOT "${component}" IN_LIST supported_components)
message(FATAL_ERROR "'${component}' is not a valid FX module.\nSupported modules: ${supported_components_string_list}")
endif ()
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if (NOT FX_${component}_INCLUDE_DIR)
find_path(FX_${component}_INCLUDE_DIR
NAMES fx/${header_name}.h ${FX_FIND_ARGS}
PATH_SUFFIXES include
PATHS ${FX_SEARCH_PATHS})
endif ()
if (NOT FX_${component}_LIBRARY)
find_library(FX_${component}_LIBRARY
NAMES fx-${lib_name} ${FX_FIND_ARGS}
PATH_SUFFIXES lib
PATHS ${FX_SEARCH_PATHS})
else ()
# on Windows, ensure paths are in canonical format (forward slahes):
file(TO_CMAKE_PATH "${FX_${component}_LIBRARY}" FX_${component}_LIBRARY)
endif()
list(APPEND required_vars FX_${component}_INCLUDE_DIR FX_${component}_LIBRARY)
endforeach (component)
unset(FX_FIND_ARGS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FX
REQUIRED_VARS ${required_vars})
if (FX_FOUND)
set(created_targets)
foreach (component ${components})
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if(NOT TARGET FX::${component})
add_library(FX::${component} UNKNOWN IMPORTED)
set_target_properties(FX::${component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FX_${component}_INCLUDE_DIR}")
target_compile_definitions(FX::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
if (FX_STATIC)
target_compile_definitions(FX::${component} INTERFACE FX_STATIC=1)
endif ()
set_target_properties(FX::${component} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${FX_${component}_LIBRARY}")
set(created_targets ${created_targets} ${component})
endif ()
endforeach (component)
foreach (component ${created_targets})
if ("${component}" STREQUAL "Ds")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Ds' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Ds INTERFACE FX::Core)
endif ()
if ("${component}" STREQUAL "Term")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Term' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Term' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Term INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Serial")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Serial' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Serial INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Cmd")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Term)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Cmd INTERFACE FX::Core FX::Ds FX::Term)
endif ()
if ("${component}" STREQUAL "Io")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Io' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Io' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Io INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Compress")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Compress' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Compress INTERFACE FX::Core FX::Ds)
endif ()
endforeach (component)
endif()

View File

@@ -1,4 +1,4 @@
function(add_fx_module) function(add_bluelib_module)
set(options) set(options)
set(one_value_args NAME) set(one_value_args NAME)
set(multi_value_args set(multi_value_args
@@ -22,86 +22,201 @@ function(add_fx_module)
set(sources ${sources} ${dir_sources}) set(sources ${sources} ${dir_sources})
endforeach (dir) endforeach (dir)
file(GLOB sys_sources sys/${fx_system_name}/*.c sys/${fx_system_name}/*.h) file(GLOB sys_sources sys/${b_system_name}/*.c sys/${b_system_name}/*.h)
set(root_header include/fx/${module_name}.h) set(root_header include/blue/${module_name}.h)
file(GLOB headers include/fx/${module_name}/*.h) file(GLOB headers include/blue/${module_name}/*.h)
string(REPLACE "-" "_" module_preproc_token ${module_name}) string(REPLACE "-" "_" module_preproc_token ${module_name})
string(TOUPPER ${module_preproc_token} module_preproc_token) string(TOUPPER ${module_preproc_token} module_preproc_token)
set(module_preproc_token FX_${module_preproc_token}) set(module_preproc_token BLUELIB_${module_preproc_token})
message(STATUS "Building module ${module_name} (shared)") message(STATUS "Building module ${module_name} (shared)")
add_library(fx-${module_name} SHARED add_library(blue-${module_name} SHARED
${sources} ${sources}
${sys_sources} ${sys_sources}
${root_header} ${root_header}
${headers} ${headers}
${arg_EXTRA_SOURCES}) ${arg_EXTRA_SOURCES})
message(STATUS "Building module ${module_name} (static)") message(STATUS "Building module ${module_name} (static)")
add_library(fx-${module_name}-s STATIC add_library(blue-${module_name}-s STATIC
${sources} ${sources}
${sys_sources} ${sys_sources}
${root_header} ${root_header}
${headers} ${headers}
${arg_EXTRA_SOURCES}) ${arg_EXTRA_SOURCES})
target_include_directories(fx-${module_name} PUBLIC include/) target_include_directories(blue-${module_name} PUBLIC include/)
target_include_directories(fx-${module_name}-s PUBLIC include/) target_include_directories(blue-${module_name}-s PUBLIC include/)
target_compile_definitions(fx-${module_name} PUBLIC target_compile_definitions(blue-${module_name} PUBLIC
${module_preproc_token} ${module_preproc_token}
FX_EXPORT=1) BLUELIB_EXPORT=1)
target_compile_definitions(fx-${module_name}-s PUBLIC target_compile_definitions(blue-${module_name}-s PUBLIC
${module_preproc_token} ${module_preproc_token}
FX_EXPORT=1 BLUELIB_EXPORT=1
FX_STATIC=1) BLUELIB_STATIC=1)
set_target_properties(fx-${module_name} set_target_properties(blue-${module_name}
PROPERTIES POSITION_INDEPENDENT_CODE ON) PROPERTIES POSITION_INDEPENDENT_CODE ON)
foreach (dep ${arg_DEPENDENCIES}) foreach (dep ${arg_DEPENDENCIES})
target_link_libraries(fx-${module_name} fx-${dep}) target_link_libraries(blue-${module_name} blue-${dep})
target_link_libraries(fx-${module_name}-s fx-${dep}-s) target_link_libraries(blue-${module_name}-s blue-${dep}-s)
endforeach (dep) endforeach (dep)
foreach (lib ${arg_LIBS}) foreach (lib ${arg_LIBS})
target_link_libraries(fx-${module_name} ${lib}) target_link_libraries(blue-${module_name} ${lib})
target_link_libraries(fx-${module_name}-s ${lib}) target_link_libraries(blue-${module_name}-s ${lib})
endforeach (lib) endforeach (lib)
foreach (dir ${arg_INCLUDE_DIRS}) foreach (dir ${arg_INCLUDE_DIRS})
target_include_directories(fx-${module_name} PRIVATE target_include_directories(blue-${module_name} PRIVATE
${dir}) ${dir})
target_include_directories(fx-${module_name}-s PRIVATE target_include_directories(blue-${module_name}-s PRIVATE
${dir}) ${dir})
endforeach (dir) endforeach (dir)
foreach (def ${arg_DEFINES}) foreach (def ${arg_DEFINES})
target_compile_definitions(fx-${module_name} PRIVATE target_compile_definitions(blue-${module_name} PRIVATE
${def}) ${def})
target_compile_definitions(fx-${module_name}-s PRIVATE target_compile_definitions(blue-${module_name}-s PRIVATE
${def}) ${def})
endforeach (def) endforeach (def)
set_target_properties(fx-${module_name} PROPERTIES set_target_properties(blue-${module_name} PROPERTIES
FOLDER "Shared/${module_name}") FOLDER "Shared/${module_name}")
set_target_properties(fx-${module_name}-s PROPERTIES set_target_properties(blue-${module_name}-s PROPERTIES
FOLDER "Static/${module_name}") 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(blue-${module_name} PRIVATE
BIG_ENDIAN) BIG_ENDIAN)
target_compile_definitions(fx-${module_name}-s PRIVATE target_compile_definitions(blue-${module_name}-s PRIVATE
BIG_ENDIAN) BIG_ENDIAN)
else() else()
target_compile_definitions(fx-${module_name} PRIVATE target_compile_definitions(blue-${module_name} PRIVATE
LITTLE_ENDIAN) LITTLE_ENDIAN)
target_compile_definitions(fx-${module_name}-s PRIVATE target_compile_definitions(blue-${module_name}-s PRIVATE
LITTLE_ENDIAN) LITTLE_ENDIAN)
endif() endif()
install(TARGETS fx-${module_name} fx-${module_name}-s) install(TARGETS blue-${module_name} blue-${module_name}-s)
install(FILES ${root_header} DESTINATION include/fx) install(FILES ${root_header} DESTINATION include/blue)
install(FILES ${headers} DESTINATION include/fx/${module_name}) install(FILES ${headers} DESTINATION include/blue/${module_name})
endfunction(add_fx_module) endfunction(add_bluelib_module)
function(add_bluelib_mm_module)
set(options)
set(one_value_args NAME)
set(multi_value_args
DEPENDENCIES
SUBDIRS
EXTRA_SOURCES
LIBS
INCLUDE_DIRS
DEFINES)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(short_module_name ${arg_NAME})
set(module_name ${arg_NAME}-mm)
file(GLOB sources
*.c *.h
*.cpp *.hpp)
foreach (dir ${arg_SUBDIRS})
file(GLOB dir_sources
${dir}/*.c ${dir}/*.h
${dir}/*.cpp ${dir}/*.hpp)
set(sources ${sources} ${dir_sources})
endforeach (dir)
file(GLOB sys_sources
sys/${b_system_name}/*.c sys/${b_system_name}/*.h
sys/${b_system_name}/*.cpp sys/${b_system_name}/*.hpp)
set(root_header include/blue/${short_module_name}.hpp)
file(GLOB headers include/blue/${short_module_name}/*.hpp)
string(REPLACE "-" "_" module_preproc_token ${short_module_name})
string(TOUPPER ${module_preproc_token} module_preproc_token)
set(module_preproc_token BLUELIB_${module_preproc_token})
message(STATUS "Building mm module ${short_module_name} (shared)")
add_library(blue-${module_name} SHARED
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
message(STATUS "Building mm module ${short_module_name} (static)")
add_library(blue-${module_name}-s STATIC
${sources}
${sys_sources}
${root_header}
${headers}
${arg_EXTRA_SOURCES})
target_include_directories(blue-${module_name} PUBLIC include/)
target_include_directories(blue-${module_name}-s PUBLIC include/)
target_compile_definitions(blue-${module_name} PUBLIC
${module_preproc_token}
BLUELIB_EXPORT=1)
target_compile_definitions(blue-${module_name}-s PUBLIC
${module_preproc_token}
BLUELIB_EXPORT=1
BLUELIB_STATIC=1)
set_target_properties(blue-${module_name}
PROPERTIES POSITION_INDEPENDENT_CODE ON)
foreach (dep ${arg_DEPENDENCIES})
target_link_libraries(blue-${module_name} blue-${dep})
target_link_libraries(blue-${module_name}-s blue-${dep}-s)
endforeach (dep)
foreach (lib ${arg_LIBS})
target_link_libraries(blue-${module_name} ${lib})
target_link_libraries(blue-${module_name}-s ${lib})
endforeach (lib)
foreach (dir ${arg_INCLUDE_DIRS})
target_include_directories(blue-${module_name} PRIVATE
${dir})
target_include_directories(blue-${module_name}-s PRIVATE
${dir})
endforeach (dir)
foreach (def ${arg_DEFINES})
target_compile_definitions(blue-${module_name} PRIVATE
${def})
target_compile_definitions(blue-${module_name}-s PRIVATE
${def})
endforeach (def)
set_target_properties(blue-${module_name} PROPERTIES
FOLDER "mm/Shared/${short_module_name}")
set_target_properties(blue-${module_name}-s PROPERTIES
FOLDER "mm/Static/${short_module_name}")
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
target_compile_definitions(blue-${module_name} PRIVATE
BIG_ENDIAN)
target_compile_definitions(blue-${module_name}-s PRIVATE
BIG_ENDIAN)
else()
target_compile_definitions(blue-${module_name} PRIVATE
LITTLE_ENDIAN)
target_compile_definitions(blue-${module_name}-s PRIVATE
LITTLE_ENDIAN)
endif()
install(TARGETS blue-${module_name} blue-${module_name}-s)
install(FILES ${root_header} DESTINATION include/blue)
install(FILES ${headers} DESTINATION include/blue/${short_module_name})
endfunction(add_bluelib_mm_module)

View File

@@ -1,3 +1,3 @@
include(../cmake/Templates.cmake) include(../cmake/Templates.cmake)
add_fx_module(NAME cmd DEPENDENCIES core ds term) add_bluelib_module(NAME cmd DEPENDENCIES core ds term)

View File

@@ -1,13 +1,13 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <blue/cmd.h>
#include <fx/ds/string.h> #include <blue/ds/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct fx_command_arg *fx_command_arg_create(void) struct b_command_arg *b_command_arg_create(void)
{ {
struct fx_command_arg *out = malloc(sizeof *out); struct b_command_arg *out = malloc(sizeof *out);
if (!out) { if (!out) {
return out; return out;
} }
@@ -16,7 +16,7 @@ struct fx_command_arg *fx_command_arg_create(void)
return out; return out;
} }
void fx_command_arg_destroy(struct fx_command_arg *arg) void b_command_arg_destroy(struct b_command_arg *arg)
{ {
if (arg->arg_name) { if (arg->arg_name) {
free(arg->arg_name); free(arg->arg_name);
@@ -37,11 +37,11 @@ void fx_command_arg_destroy(struct fx_command_arg *arg)
free(arg); free(arg);
} }
fx_status fx_command_arg_set_name(struct fx_command_arg *arg, const char *name) b_status b_command_arg_set_name(struct b_command_arg *arg, const char *name)
{ {
char *n = fx_strdup(name); char *n = b_strdup(name);
if (!n) { if (!n) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
if (arg->arg_name) { if (arg->arg_name) {
@@ -50,15 +50,15 @@ fx_status fx_command_arg_set_name(struct fx_command_arg *arg, const char *name)
} }
arg->arg_name = n; arg->arg_name = n;
return FX_SUCCESS; return B_SUCCESS;
} }
fx_status fx_command_arg_set_description( b_status b_command_arg_set_description(
struct fx_command_arg *arg, const char *description) struct b_command_arg *arg, const char *description)
{ {
char *desc = fx_strdup(description); char *desc = b_strdup(description);
if (!desc) { if (!desc) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
if (arg->arg_description) { if (arg->arg_description) {
@@ -67,18 +67,18 @@ fx_status fx_command_arg_set_description(
} }
arg->arg_description = desc; arg->arg_description = desc;
return FX_SUCCESS; return B_SUCCESS;
} }
fx_status fx_command_arg_set_nr_values( b_status b_command_arg_set_nr_values(
struct fx_command_arg *arg, enum fx_command_arg_value_count nr_values) struct b_command_arg *arg, enum b_command_arg_value_count nr_values)
{ {
arg->arg_nr_values = nr_values; arg->arg_nr_values = nr_values;
return FX_SUCCESS; return B_SUCCESS;
} }
fx_status fx_command_arg_set_allowed_values( b_status b_command_arg_set_allowed_values(
struct fx_command_arg *arg, const char **allowed_values) struct b_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++)
@@ -86,35 +86,35 @@ fx_status fx_command_arg_set_allowed_values(
char **values = calloc(count + 1, sizeof *values); char **values = calloc(count + 1, sizeof *values);
if (!values) { if (!values) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
values[i] = fx_strdup(allowed_values[i]); values[i] = b_strdup(allowed_values[i]);
if (!values[i]) { if (!values[i]) {
/* TODO also free strings in `values` */ /* TODO also free strings in `values` */
free(values); free(values);
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
} }
arg->arg_allowed_values = values; arg->arg_allowed_values = values;
return FX_SUCCESS; return B_SUCCESS;
} }
void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_string *out) void z__b_get_arg_usage_string(struct b_command_arg *arg, bool colour, b_string *out)
{ {
bool optional = false, multi = false; bool optional = false, multi = false;
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
case FX_ARG_0_OR_1_VALUES: case B_ARG_0_OR_1_VALUES:
optional = true; optional = true;
multi = false; multi = false;
break; break;
case FX_ARG_0_OR_MORE_VALUES: case B_ARG_0_OR_MORE_VALUES:
optional = true; optional = true;
multi = true; multi = true;
break; break;
case FX_ARG_1_OR_MORE_VALUES: case B_ARG_1_OR_MORE_VALUES:
optional = false; optional = false;
multi = true; multi = true;
break; break;
@@ -125,30 +125,30 @@ void z__fx_get_arg_usage_string(struct fx_command_arg *arg, bool colour, fx_stri
} }
if (optional) { if (optional) {
fx_string_append_cstrf( b_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( b_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++) {
fx_string_append_cstrf(out, " <%s>", arg->arg_name); b_string_append_cstrf(out, " <%s>", arg->arg_name);
} }
if (multi) { if (multi) {
fx_string_append_cstr(out, "..."); b_string_append_cstr(out, "...");
} }
if (colour) { if (colour) {
fx_string_append_cstr(out, F_RESET); b_string_append_cstr(out, F_RESET);
} }
} }
void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out) void z__b_get_arg_description(struct b_command_arg *arg, b_string *out)
{ {
if (arg->arg_description) { if (arg->arg_description) {
fx_string_append_cstr(out, arg->arg_description); b_string_append_cstr(out, arg->arg_description);
} }
if (!arg->arg_allowed_values) { if (!arg->arg_allowed_values) {
@@ -156,19 +156,19 @@ void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out)
} }
if (arg->arg_description) { if (arg->arg_description) {
fx_string_append_cstr(out, " "); b_string_append_cstr(out, " ");
} }
fx_string_append_cstr(out, "[[values:"); b_string_append_cstr(out, "[[values:");
for (size_t i = 0; arg->arg_allowed_values[i]; i++) { for (size_t i = 0; arg->arg_allowed_values[i]; i++) {
if (i > 0) { if (i > 0) {
fx_string_append_cstr(out, ","); b_string_append_cstr(out, ",");
} }
fx_string_append_cstrf( b_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, "]"); b_string_append_cstr(out, "]");
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
#ifndef _FX_COMMAND_H_ #ifndef _B_COMMAND_H_
#define _FX_COMMAND_H_ #define _B_COMMAND_H_
#include <fx/cmd.h> #include <blue/cmd.h>
#include <fx/core/bst.h> #include <blue/core/btree.h>
#include <fx/core/queue.h> #include <blue/core/queue.h>
#include <fx/ds/string.h> #include <blue/ds/string.h>
#define F_RED "[bright_red]" #define F_RED "[bright_red]"
#define F_GREEN "[bright_green]" #define F_GREEN "[bright_green]"
@@ -20,132 +20,132 @@ enum cmd_string_flags {
CMD_STR_DIRECT_USAGE = 0x02u, CMD_STR_DIRECT_USAGE = 0x02u,
}; };
enum fx_command_usage_entry_type { enum b_command_usage_entry_type {
CMD_USAGE_NONE = 0, CMD_USAGE_NONE = 0,
CMD_USAGE_ARG, CMD_USAGE_ARG,
CMD_USAGE_OPT, CMD_USAGE_OPT,
CMD_USAGE_COMMAND, CMD_USAGE_COMMAND,
}; };
struct fx_command { struct b_command {
unsigned int c_id; unsigned int b_id;
unsigned int c_parent_id; unsigned int b_parent_id;
struct fx_command *c_parent; struct b_command *b_parent;
enum fx_command_flags c_flags; enum b_command_flags b_flags;
char *c_name; char *b_name;
char *c_long_name; char *b_long_name;
char c_short_name; char b_short_name;
char *c_description; char *b_description;
struct fx_queue c_opt; struct b_queue b_opt;
struct fx_queue c_arg; struct b_queue b_arg;
struct fx_queue c_subcommands; struct b_queue b_subcommands;
struct fx_queue c_usage; struct b_queue b_usage;
fx_command_callback c_callback; b_command_callback b_callback;
struct fx_queue_entry c_entry; struct b_queue_entry b_entry;
struct fx_bst_node c_node; struct b_btree_node b_node;
}; };
struct fx_command_usage_entry { struct b_command_usage_entry {
struct fx_queue_entry e_entry; struct b_queue_entry e_entry;
enum fx_command_usage_entry_type e_type; enum b_command_usage_entry_type e_type;
union { union {
struct fx_command_option *e_opt; struct b_command_option *e_opt;
struct fx_command_arg *e_arg; struct b_command_arg *e_arg;
unsigned int e_cmd_id; unsigned int e_cmd_id;
}; };
}; };
struct fx_command_usage { struct b_command_usage {
fx_command_usage_flags u_flags; b_command_usage_flags u_flags;
struct fx_queue_entry u_entry; struct b_queue_entry u_entry;
struct fx_queue u_parts; struct b_queue u_parts;
}; };
struct fx_command_option { struct b_command_option {
unsigned int opt_id; unsigned int opt_id;
char *opt_long_name; char *opt_long_name;
char opt_short_name; char opt_short_name;
char *opt_description; char *opt_description;
// fx_command_arg_value_count arg_nr_values; // b_command_arg_value_count arg_nr_values;
// char **arg_allowed_values; // char **arg_allowed_values;
struct fx_queue opt_args; struct b_queue opt_args;
struct fx_queue_entry opt_entry; struct b_queue_entry opt_entry;
}; };
struct fx_command_arg { struct b_command_arg {
unsigned int arg_id; unsigned int arg_id;
char *arg_name; char *arg_name;
char *arg_description; char *arg_description;
fx_command_arg_value_count arg_nr_values; b_command_arg_value_count arg_nr_values;
char **arg_allowed_values; char **arg_allowed_values;
struct fx_queue_entry arg_entry; struct b_queue_entry arg_entry;
}; };
struct fx_arglist_option { struct b_arglist_option {
unsigned int opt_id; unsigned int opt_id;
struct fx_bst opt_values; struct b_btree opt_values;
struct fx_bst_node opt_node; struct b_btree_node opt_node;
}; };
struct fx_arglist { struct b_arglist {
size_t list_argc; size_t list_argc;
const char **list_argv; const char **list_argv;
unsigned int list_argv_last_command; unsigned int list_argv_last_command;
struct fx_command *list_command; struct b_command *list_command;
struct fx_bst list_options; struct b_btree list_options;
}; };
FX_API struct fx_command *fx_command_get_subcommand_with_name( BLUE_API struct b_command *b_command_get_subcommand_with_name(
struct fx_command *cmd, const char *name); struct b_command *cmd, const char *name);
FX_API struct fx_command *fx_command_get_subcommand_with_long_name( BLUE_API struct b_command *b_command_get_subcommand_with_long_name(
struct fx_command *cmd, const char *long_name); struct b_command *cmd, const char *long_name);
FX_API struct fx_command *fx_command_get_subcommand_with_short_name( BLUE_API struct b_command *b_command_get_subcommand_with_short_name(
struct fx_command *cmd, char short_name); struct b_command *cmd, char short_name);
FX_API struct fx_command_option *fx_command_get_option_with_long_name( BLUE_API struct b_command_option *b_command_get_option_with_long_name(
struct fx_command *cmd, const char *long_name); struct b_command *cmd, const char *long_name);
FX_API struct fx_command_option *fx_command_get_option_with_short_name( BLUE_API struct b_command_option *b_command_get_option_with_short_name(
struct fx_command *cmd, char short_name); struct b_command *cmd, char short_name);
FX_API struct fx_command_option *fx_command_get_option_with_id( BLUE_API struct b_command_option *b_command_get_option_with_id(
struct fx_command *cmd, unsigned int id); struct b_command *cmd, unsigned int id);
FX_API struct fx_command_arg *fx_command_get_arg_with_id( BLUE_API struct b_command_arg *b_command_get_arg_with_id(
struct fx_command *cmd, unsigned int id); struct b_command *cmd, unsigned int id);
FX_API struct fx_command_arg *fx_command_option_get_arg_with_id( BLUE_API struct b_command_arg *b_command_option_get_arg_with_id(
struct fx_command_option *opt, unsigned int id); struct b_command_option *opt, unsigned int id);
FX_API struct fx_command_option *fx_command_option_create(void); BLUE_API struct b_command_option *b_command_option_create(void);
FX_API void fx_command_option_destroy(struct fx_command_option *opt); BLUE_API void b_command_option_destroy(struct b_command_option *opt);
FX_API struct fx_command_arg *fx_command_arg_create(void); BLUE_API struct b_command_arg *b_command_arg_create(void);
FX_API void fx_command_arg_destroy(struct fx_command_arg *arg); BLUE_API void b_command_arg_destroy(struct b_command_arg *arg);
FX_API struct fx_arglist *fx_arglist_create(void); BLUE_API struct b_arglist *b_arglist_create(void);
FX_API fx_status fx_arglist_parse( BLUE_API b_status b_arglist_parse(
struct fx_arglist *args, struct fx_command **cmd, int argc, struct b_arglist *args, struct b_command **cmd, int argc,
const char **argv); const char **argv);
FX_API void fx_arglist_destroy(struct fx_arglist *args); BLUE_API void b_arglist_destroy(struct b_arglist *args);
FX_API fx_string *z__fx_command_default_usage_string( BLUE_API b_string *z__b_command_default_usage_string(
struct fx_command *cmd, struct fx_command_option *with_opt, struct b_command *cmd, struct b_command_option *with_opt,
const struct fx_arglist *args); const struct b_arglist *args);
FX_API void z__fx_get_arg_usage_string( BLUE_API void z__b_get_arg_usage_string(
struct fx_command_arg *arg, bool colour, fx_string *out); struct b_command_arg *arg, bool colour, b_string *out);
FX_API void z__fx_get_arg_description(struct fx_command_arg *arg, fx_string *out); BLUE_API void z__b_get_arg_description(struct b_command_arg *arg, b_string *out);
FX_API void z__fx_get_option_usage_string( BLUE_API void z__b_get_option_usage_string(
struct fx_command_option *opt, enum cmd_string_flags flags, fx_string *out); struct b_command_option *opt, enum cmd_string_flags flags, b_string *out);
FX_API void z__fx_get_option_description( BLUE_API void z__b_get_option_description(
struct fx_command_option *opt, fx_string *out); struct b_command_option *opt, b_string *out);
#endif #endif

289
cmd/include/blue/cmd.h Normal file
View File

@@ -0,0 +1,289 @@
#ifndef BLUE_CMD_H_
#define BLUE_CMD_H_
#include <blue/core/btree.h>
#include <blue/core/init.h>
#include <blue/core/iterator.h>
#include <blue/core/queue.h>
#include <blue/ds/array.h>
#include <stdbool.h>
#include <stdint.h>
#define b_arglist_foreach(it, q) \
for (int z__b_unique_name() = b_arglist_iterator_begin( \
q, B_COMMAND_INVALID_ID, B_COMMAND_INVALID_ID, (it)); \
b_arglist_iterator_is_valid(it); b_arglist_iterator_next(it))
#define b_arglist_foreach_filtered(it, q, opt_id, arg_id) \
for (int z__b_unique_name() \
= b_arglist_iterator_begin(q, opt_id, arg_id, (it)); \
b_arglist_iterator_is_valid(it); b_arglist_iterator_next(it))
#define b_arglist_option_foreach(it, q) \
for (int z__b_unique_name() \
= b_arglist_option_iterator_begin(q, B_COMMAND_INVALID_ID, (it)); \
b_arglist_option_iterator_is_valid(it); \
b_arglist_option_iterator_next(it))
#define b_arglist_option_foreach_filtered(it, q, opt_id) \
for (int z__b_unique_name() \
= b_arglist_option_iterator_begin(q, opt_id, (it)); \
b_arglist_option_iterator_is_valid(it); \
b_arglist_option_iterator_next(it))
#define B_COMMAND(id, parent_id) \
static b_command *command_##id = NULL; \
static void __init_##id( \
b_command *, b_command_option *, b_command_arg *, \
b_command_usage *); \
B_INIT(init_##id) \
{ \
command_##id = b_command_create(id); \
if ((parent_id) != B_COMMAND_INVALID_ID) { \
b_command_set_parent(command_##id, parent_id); \
} \
__init_##id(command_##id, NULL, NULL, NULL); \
b_command_register(command_##id); \
} \
static void __init_##id( \
b_command *this_cmd, b_command_option *this_opt, \
b_command_arg *this_arg, b_command_usage *this_usage)
#define B_COMMAND_NAME(name) b_command_set_name(this_cmd, (name))
#define B_COMMAND_LONG_NAME(name) b_command_set_long_name(this_cmd, (name))
#define B_COMMAND_SHORT_NAME(name) b_command_set_short_name(this_cmd, (name))
#define B_COMMAND_DESC(desc) b_command_set_description(this_cmd, (desc))
#define B_COMMAND_FLAGS(flags) b_command_set_flags(this_cmd, (flags))
#define B_COMMAND_FUNCTION(fn) b_command_set_callback(this_cmd, (fn))
#define B_COMMAND_OPTION(id) \
b_command_option *opt_##id = b_command_add_option(this_cmd, (id)); \
this_opt = opt_##id; \
if (this_opt)
#define B_COMMAND_OPTION_GEN(id) \
b_command_option *z__b_unique_name() \
= b_command_add_option(this_cmd, (id)); \
this_opt = z__b_unique_name(); \
if (this_opt)
#define B_COMMAND_HELP_OPTION() \
do { \
b_command_option *opt \
= b_command_add_option(this_cmd, B_COMMAND_OPTION_HELP); \
b_command_option_set_description(opt, "Show this help message"); \
b_command_option_set_short_name(opt, 'h'); \
b_command_option_set_long_name(opt, "help"); \
} while (0)
#define B_OPTION_LONG_NAME(name) \
b_command_option_set_long_name(this_opt, (name))
#define B_OPTION_SHORT_NAME(name) \
b_command_option_set_short_name(this_opt, (name))
#define B_OPTION_DESC(desc) b_command_option_set_description(this_opt, (desc))
#define B_OPTION_ARG(id) \
b_command_arg *arg_##id = b_command_option_add_arg(this_opt, (id)); \
this_arg = arg_##id; \
if (this_arg)
#define B_COMMAND_ARG(id) \
b_command_arg *arg_##id = b_command_add_arg(this_cmd, (id)); \
this_arg = arg_##id; \
if (this_arg)
#define B_ARG_NAME(name) b_command_arg_set_name(this_arg, (name))
#define B_ARG_DESC(desc) b_command_arg_set_description(this_arg, (desc))
#define B_ARG_NR_VALUES(nr_values) \
b_command_arg_set_nr_values(this_arg, (nr_values))
#define B_ARG_ALLOWED_VALUES(...) \
static const char *allowed_values[] = { \
__VA_ARGS__, \
NULL, \
}; \
b_command_arg_set_allowed_values(this_arg, allowed_values)
#define B_COMMAND_USAGE() \
b_command_usage *z__b_unique_name() = b_command_add_usage(this_cmd); \
this_usage = z__b_unique_name(); \
if (this_usage)
#define B_COMMAND_USAGE_COMMAND(cmd_id) \
b_command_usage_add_command(this_usage, cmd_id)
#define B_COMMAND_USAGE_COMMAND_PLACEHOLDER() \
b_command_usage_add_command(this_usage, B_COMMAND_INVALID_ID)
#define B_COMMAND_USAGE_OPT(opt_id) \
b_command_usage_add_option(this_usage, opt_##opt_id)
#define B_COMMAND_USAGE_OPT_PLACEHOLDER() \
b_command_usage_add_option(this_usage, NULL)
#define B_COMMAND_USAGE_ARG(opt_id) \
b_command_usage_add_arg(this_usage, arg_##opt_id)
#define B_COMMAND_USAGE_ARG_PLACEHOLDER() \
b_command_usage_add_arg(this_usage, NULL)
#define B_COMMAND_OPTION_HELP ((uintptr_t)0xF0000001)
#define B_COMMAND_INVALID_ID ((uintptr_t)0xFFFFFFFF)
typedef enum b_command_arg_value_count {
B_ARG_0_OR_1_VALUES = -1,
B_ARG_0_OR_MORE_VALUES = -2,
B_ARG_1_OR_MORE_VALUES = -3,
} b_command_arg_value_count;
typedef enum b_command_arg_type {
B_COMMAND_ARG_NONE = 0,
B_COMMAND_ARG_STRING,
B_COMMAND_ARG_SIGNED_INT,
B_COMMAND_ARG_UNSIGNED_INT,
B_COMMAND_ARG_INT = B_COMMAND_ARG_SIGNED_INT,
} b_command_arg_type;
typedef enum b_command_flags {
B_COMMAND_SHOW_HELP_BY_DEFAULT = 0x01u,
} b_command_flags;
typedef enum b_command_usage_flags {
B_COMMAND_USAGE_SHOW_OPTIONS = 0x01u,
} b_command_usage_flags;
typedef struct b_arglist_value {
unsigned int val_id;
b_command_arg_type val_type;
struct b_btree_node val_node;
union {
char *val_str;
long long val_int;
unsigned long long val_uint;
};
} b_arglist_value;
typedef struct b_arglist_iterator {
size_t i;
unsigned int opt_id;
struct b_arglist_value *value;
b_btree_node *_opt_it, *_arg_it;
unsigned int _opt_filter, _arg_filter;
} b_arglist_iterator;
typedef struct b_arglist_option_iterator {
size_t i;
unsigned int opt_id;
struct b_arglist_option *opt;
b_btree_node *_opt_it;
unsigned int _opt_filter;
} b_arglist_option_iterator;
typedef struct b_command b_command;
typedef struct b_command_option b_command_option;
typedef struct b_command_arg b_command_arg;
typedef struct b_command_usage b_command_usage;
typedef struct b_arglist b_arglist;
typedef struct b_arglist_option b_arglist_option;
typedef int (*b_command_callback)(
const b_command *, const b_arglist *, const b_array *);
BLUE_API b_command *b_command_create(unsigned int id);
BLUE_API void b_command_destroy(b_command *cmd);
BLUE_API b_status b_command_register(b_command *cmd);
BLUE_API int b_command_dispatch(unsigned int cmd_id, int argc, const char **argv);
BLUE_API b_status b_command_set_name(b_command *cmd, const char *name);
BLUE_API b_status b_command_set_long_name(b_command *cmd, const char *name);
BLUE_API b_status b_command_set_short_name(b_command *cmd, char name);
BLUE_API b_status b_command_set_flags(b_command *cmd, b_command_flags flags);
BLUE_API b_status b_command_set_description(b_command *cmd, const char *description);
BLUE_API b_status b_command_set_callback(
b_command *cmd, b_command_callback callback);
BLUE_API b_status b_command_set_parent(b_command *cmd, unsigned int parent_id);
BLUE_API b_command_option *b_command_add_option(b_command *cmd, int id);
BLUE_API b_command_arg *b_command_add_arg(b_command *cmd, int id);
BLUE_API b_command_usage *b_command_add_usage(b_command *cmd);
BLUE_API const b_command_option *b_command_get_option(const b_command *cmd, int id);
BLUE_API const char *b_command_option_get_long_name(const b_command_option *opt);
BLUE_API char b_command_option_get_short_name(const b_command_option *opt);
BLUE_API const char *b_command_option_get_description(b_command_option *opt);
BLUE_API b_status b_command_option_set_long_name(
b_command_option *opt, const char *name);
BLUE_API b_status b_command_option_set_short_name(b_command_option *opt, char name);
BLUE_API b_status b_command_option_set_description(
b_command_option *opt, const char *description);
BLUE_API b_command_arg *b_command_option_add_arg(b_command_option *opt, int id);
BLUE_API b_status b_command_arg_set_name(b_command_arg *arg, const char *name);
BLUE_API b_status b_command_arg_set_description(
b_command_arg *arg, const char *description);
BLUE_API b_status b_command_arg_set_nr_values(
b_command_arg *arg, b_command_arg_value_count nr_values);
BLUE_API b_status b_command_arg_set_allowed_values(
b_command_arg *arg, const char **allowed_values);
BLUE_API b_status b_command_usage_add_option(
b_command_usage *usage, b_command_option *opt);
BLUE_API b_status b_command_usage_add_arg(
b_command_usage *usage, b_command_arg *opt);
BLUE_API b_status b_command_usage_add_command(
b_command_usage *usage, unsigned int cmd_id);
BLUE_API b_status b_arglist_get_string(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, const char **out);
BLUE_API b_status b_arglist_get_int(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, long long *out);
BLUE_API b_status b_arglist_get_uint(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, unsigned long long *out);
BLUE_API b_status b_arglist_get_option(
const b_arglist *args, unsigned int opt_id, unsigned int index,
b_arglist_option **out);
BLUE_API size_t b_arglist_get_count(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id);
BLUE_API b_status b_arglist_report_missing_option(
const b_arglist *args, unsigned int opt_id);
BLUE_API b_status b_arglist_report_unexpected_arg(
const b_arglist *args, const char *value);
BLUE_API b_status b_arglist_report_invalid_arg_value(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
const char *value);
BLUE_API b_status b_arglist_report_missing_args(
const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
size_t nr_supplied);
BLUE_API b_status b_arglist_option_get_value(
const b_arglist_option *opt, unsigned int arg_id, unsigned int index,
b_arglist_value **out);
BLUE_API int b_arglist_iterator_begin(
const b_arglist *args, unsigned int opt_filter, unsigned int arg_filter,
b_arglist_iterator *it);
BLUE_API bool b_arglist_iterator_next(b_arglist_iterator *it);
BLUE_API bool b_arglist_iterator_is_valid(const b_arglist_iterator *it);
BLUE_API int b_arglist_option_iterator_begin(
const b_arglist *args, unsigned int opt_filter,
b_arglist_option_iterator *it);
BLUE_API bool b_arglist_option_iterator_next(b_arglist_option_iterator *it);
BLUE_API bool b_arglist_option_iterator_is_valid(
const b_arglist_option_iterator *it);
#endif

View File

@@ -1,289 +0,0 @@
#ifndef FX_CMD_H_
#define FX_CMD_H_
#include <fx/core/bst.h>
#include <fx/core/init.h>
#include <fx/core/iterator.h>
#include <fx/core/queue.h>
#include <fx/ds/array.h>
#include <stdbool.h>
#include <stdint.h>
#define fx_arglist_foreach(it, q) \
for (int z__fx_unique_name() = fx_arglist_iterator_begin( \
q, 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) \
for (int z__fx_unique_name() \
= fx_arglist_iterator_begin(q, opt_id, arg_id, (it)); \
fx_arglist_iterator_is_valid(it); fx_arglist_iterator_next(it))
#define fx_arglist_option_foreach(it, q) \
for (int z__fx_unique_name() \
= fx_arglist_option_iterator_begin(q, FX_COMMAND_INVALID_ID, (it)); \
fx_arglist_option_iterator_is_valid(it); \
fx_arglist_option_iterator_next(it))
#define fx_arglist_option_foreach_filtered(it, q, opt_id) \
for (int z__fx_unique_name() \
= fx_arglist_option_iterator_begin(q, opt_id, (it)); \
fx_arglist_option_iterator_is_valid(it); \
fx_arglist_option_iterator_next(it))
#define FX_COMMAND(id, parent_id) \
static fx_command *command_##id = NULL; \
static void __init_##id( \
fx_command *, fx_command_option *, fx_command_arg *, \
fx_command_usage *); \
FX_INIT(init_##id) \
{ \
command_##id = fx_command_create(id); \
if ((parent_id) != FX_COMMAND_INVALID_ID) { \
fx_command_set_parent(command_##id, parent_id); \
} \
__init_##id(command_##id, NULL, NULL, NULL); \
fx_command_register(command_##id); \
} \
static void __init_##id( \
fx_command *this_cmd, 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_LONG_NAME(name) fx_command_set_long_name(this_cmd, (name))
#define FX_COMMAND_SHORT_NAME(name) fx_command_set_short_name(this_cmd, (name))
#define FX_COMMAND_DESC(desc) fx_command_set_description(this_cmd, (desc))
#define FX_COMMAND_FLAGS(flags) fx_command_set_flags(this_cmd, (flags))
#define FX_COMMAND_FUNCTION(fn) fx_command_set_callback(this_cmd, (fn))
#define FX_COMMAND_OPTION(id) \
fx_command_option *opt_##id = fx_command_add_option(this_cmd, (id)); \
this_opt = opt_##id; \
if (this_opt)
#define FX_COMMAND_OPTION_GEN(id) \
fx_command_option *z__fx_unique_name() \
= fx_command_add_option(this_cmd, (id)); \
this_opt = z__fx_unique_name(); \
if (this_opt)
#define FX_COMMAND_HELP_OPTION() \
do { \
fx_command_option *opt \
= fx_command_add_option(this_cmd, 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_long_name(opt, "help"); \
} while (0)
#define FX_OPTION_LONG_NAME(name) \
fx_command_option_set_long_name(this_opt, (name))
#define FX_OPTION_SHORT_NAME(name) \
fx_command_option_set_short_name(this_opt, (name))
#define FX_OPTION_DESC(desc) fx_command_option_set_description(this_opt, (desc))
#define FX_OPTION_ARG(id) \
fx_command_arg *arg_##id = fx_command_option_add_arg(this_opt, (id)); \
this_arg = arg_##id; \
if (this_arg)
#define FX_COMMAND_ARG(id) \
fx_command_arg *arg_##id = fx_command_add_arg(this_cmd, (id)); \
this_arg = arg_##id; \
if (this_arg)
#define FX_ARG_NAME(name) fx_command_arg_set_name(this_arg, (name))
#define FX_ARG_DESC(desc) fx_command_arg_set_description(this_arg, (desc))
#define FX_ARG_NR_VALUES(nr_values) \
fx_command_arg_set_nr_values(this_arg, (nr_values))
#define FX_ARG_ALLOWED_VALUES(...) \
static const char *allowed_values[] = { \
__VA_ARGS__, \
NULL, \
}; \
fx_command_arg_set_allowed_values(this_arg, allowed_values)
#define FX_COMMAND_USAGE() \
fx_command_usage *z__fx_unique_name() = fx_command_add_usage(this_cmd); \
this_usage = z__fx_unique_name(); \
if (this_usage)
#define FX_COMMAND_USAGE_COMMAND(cmd_id) \
fx_command_usage_add_command(this_usage, cmd_id)
#define FX_COMMAND_USAGE_COMMAND_PLACEHOLDER() \
fx_command_usage_add_command(this_usage, FX_COMMAND_INVALID_ID)
#define FX_COMMAND_USAGE_OPT(opt_id) \
fx_command_usage_add_option(this_usage, opt_##opt_id)
#define FX_COMMAND_USAGE_OPT_PLACEHOLDER() \
fx_command_usage_add_option(this_usage, NULL)
#define FX_COMMAND_USAGE_ARG(opt_id) \
fx_command_usage_add_arg(this_usage, arg_##opt_id)
#define FX_COMMAND_USAGE_ARG_PLACEHOLDER() \
fx_command_usage_add_arg(this_usage, NULL)
#define FX_COMMAND_OPTION_HELP ((uintptr_t)0xF0000001)
#define FX_COMMAND_INVALID_ID ((uintptr_t)0xFFFFFFFF)
typedef enum fx_command_arg_value_count {
FX_ARG_0_OR_1_VALUES = -1,
FX_ARG_0_OR_MORE_VALUES = -2,
FX_ARG_1_OR_MORE_VALUES = -3,
} fx_command_arg_value_count;
typedef enum fx_command_arg_type {
FX_COMMAND_ARG_NONE = 0,
FX_COMMAND_ARG_STRING,
FX_COMMAND_ARG_SIGNED_INT,
FX_COMMAND_ARG_UNSIGNED_INT,
FX_COMMAND_ARG_INT = FX_COMMAND_ARG_SIGNED_INT,
} fx_command_arg_type;
typedef enum fx_command_flags {
FX_COMMAND_SHOW_HELP_BY_DEFAULT = 0x01u,
} fx_command_flags;
typedef enum fx_command_usage_flags {
FX_COMMAND_USAGE_SHOW_OPTIONS = 0x01u,
} fx_command_usage_flags;
typedef struct fx_arglist_value {
unsigned int val_id;
fx_command_arg_type val_type;
struct fx_bst_node val_node;
union {
char *val_str;
long long val_int;
unsigned long long val_uint;
};
} fx_arglist_value;
typedef struct fx_arglist_iterator {
size_t i;
unsigned int opt_id;
struct fx_arglist_value *value;
fx_bst_node *_opt_it, *_arg_it;
unsigned int _opt_filter, _arg_filter;
} fx_arglist_iterator;
typedef struct fx_arglist_option_iterator {
size_t i;
unsigned int opt_id;
struct fx_arglist_option *opt;
fx_bst_node *_opt_it;
unsigned int _opt_filter;
} fx_arglist_option_iterator;
typedef struct fx_command fx_command;
typedef struct fx_command_option fx_command_option;
typedef struct fx_command_arg fx_command_arg;
typedef struct fx_command_usage fx_command_usage;
typedef struct fx_arglist fx_arglist;
typedef struct fx_arglist_option fx_arglist_option;
typedef int (*fx_command_callback)(
const fx_command *, const fx_arglist *, const fx_array *);
FX_API fx_command *fx_command_create(unsigned int id);
FX_API void fx_command_destroy(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 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_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_description(fx_command *cmd, const char *description);
FX_API fx_status fx_command_set_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_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_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 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 const char *fx_command_option_get_description(fx_command_option *opt);
FX_API fx_status fx_command_option_set_long_name(
fx_command_option *opt, 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_command_option *opt, 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_description(
fx_command_arg *arg, const char *description);
FX_API fx_status fx_command_arg_set_nr_values(
fx_command_arg *arg, fx_command_arg_value_count nr_values);
FX_API fx_status fx_command_arg_set_allowed_values(
fx_command_arg *arg, const char **allowed_values);
FX_API fx_status fx_command_usage_add_option(
fx_command_usage *usage, fx_command_option *opt);
FX_API fx_status fx_command_usage_add_arg(
fx_command_usage *usage, fx_command_arg *opt);
FX_API fx_status fx_command_usage_add_command(
fx_command_usage *usage, unsigned int cmd_id);
FX_API fx_status fx_arglist_get_string(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, const char **out);
FX_API fx_status fx_arglist_get_int(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, long long *out);
FX_API fx_status fx_arglist_get_uint(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id,
unsigned int index, unsigned long long *out);
FX_API fx_status fx_arglist_get_option(
const fx_arglist *args, unsigned int opt_id, unsigned int index,
fx_arglist_option **out);
FX_API size_t fx_arglist_get_count(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id);
FX_API fx_status fx_arglist_report_missing_option(
const fx_arglist *args, unsigned int opt_id);
FX_API fx_status fx_arglist_report_unexpected_arg(
const fx_arglist *args, const char *value);
FX_API fx_status fx_arglist_report_invalid_arg_value(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id,
const char *value);
FX_API fx_status fx_arglist_report_missing_args(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id,
size_t nr_supplied);
FX_API fx_status fx_arglist_option_get_value(
const fx_arglist_option *opt, unsigned int arg_id, unsigned int index,
fx_arglist_value **out);
FX_API int fx_arglist_iterator_begin(
const fx_arglist *args, unsigned int opt_filter, unsigned int arg_filter,
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 int fx_arglist_option_iterator_begin(
const fx_arglist *args, unsigned int opt_filter,
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(
const fx_arglist_option_iterator *it);
#endif

View File

@@ -1,13 +1,13 @@
#include "command.h" #include "command.h"
#include <fx/cmd.h> #include <blue/cmd.h>
#include <fx/ds/string.h> #include <blue/ds/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct fx_command_option *fx_command_option_create(void) struct b_command_option *b_command_option_create(void)
{ {
struct fx_command_option *out = malloc(sizeof *out); struct b_command_option *out = malloc(sizeof *out);
if (!out) { if (!out) {
return out; return out;
} }
@@ -16,7 +16,7 @@ struct fx_command_option *fx_command_option_create(void)
return out; return out;
} }
void fx_command_option_destroy(struct fx_command_option *opt) void b_command_option_destroy(struct b_command_option *opt)
{ {
if (opt->opt_long_name) { if (opt->opt_long_name) {
free(opt->opt_long_name); free(opt->opt_long_name);
@@ -26,43 +26,43 @@ void fx_command_option_destroy(struct fx_command_option *opt)
free(opt->opt_description); free(opt->opt_description);
} }
struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args); struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) { while (entry) {
struct fx_command_arg *arg struct b_command_arg *arg
= fx_unbox(struct fx_command_arg, entry, arg_entry); = b_unbox(struct b_command_arg, entry, arg_entry);
struct fx_queue_entry *next = fx_queue_next(entry); struct b_queue_entry *next = b_queue_next(entry);
fx_queue_delete(&opt->opt_args, entry); b_queue_delete(&opt->opt_args, entry);
fx_command_arg_destroy(arg); b_command_arg_destroy(arg);
entry = next; entry = next;
} }
free(opt); free(opt);
} }
const char *fx_command_option_get_long_name(const struct fx_command_option *opt) const char *b_command_option_get_long_name(const struct b_command_option *opt)
{ {
return opt->opt_long_name; return opt->opt_long_name;
} }
char fx_command_option_get_short_name(const struct fx_command_option *opt) char b_command_option_get_short_name(const struct b_command_option *opt)
{ {
return opt->opt_short_name; return opt->opt_short_name;
} }
const char *fx_command_option_get_description(struct fx_command_option *opt) const char *b_command_option_get_description(struct b_command_option *opt)
{ {
return opt->opt_description; return opt->opt_description;
} }
fx_status fx_command_option_set_long_name( b_status b_command_option_set_long_name(
struct fx_command_option *opt, const char *name) struct b_command_option *opt, const char *name)
{ {
char *n = fx_strdup(name); char *n = b_strdup(name);
if (!n) { if (!n) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
if (opt->opt_long_name) { if (opt->opt_long_name) {
@@ -71,21 +71,21 @@ fx_status fx_command_option_set_long_name(
} }
opt->opt_long_name = n; opt->opt_long_name = n;
return FX_SUCCESS; return B_SUCCESS;
} }
fx_status fx_command_option_set_short_name(struct fx_command_option *opt, char name) b_status b_command_option_set_short_name(struct b_command_option *opt, char name)
{ {
opt->opt_short_name = name; opt->opt_short_name = name;
return FX_SUCCESS; return B_SUCCESS;
} }
fx_status fx_command_option_set_description( b_status b_command_option_set_description(
struct fx_command_option *opt, const char *description) struct b_command_option *opt, const char *description)
{ {
char *desc = fx_strdup(description); char *desc = b_strdup(description);
if (!desc) { if (!desc) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
if (opt->opt_description) { if (opt->opt_description) {
@@ -94,12 +94,12 @@ fx_status fx_command_option_set_description(
} }
opt->opt_description = desc; opt->opt_description = desc;
return FX_SUCCESS; return B_SUCCESS;
} }
struct fx_command_arg *fx_command_option_add_arg(struct fx_command_option *opt, int id) struct b_command_arg *b_command_option_add_arg(struct b_command_option *opt, int id)
{ {
struct fx_command_arg *arg = malloc(sizeof *arg); struct b_command_arg *arg = malloc(sizeof *arg);
if (!arg) { if (!arg) {
return NULL; return NULL;
} }
@@ -108,111 +108,111 @@ struct fx_command_arg *fx_command_option_add_arg(struct fx_command_option *opt,
arg->arg_id = id; arg->arg_id = id;
fx_queue_push_back(&opt->opt_args, &arg->arg_entry); b_queue_push_back(&opt->opt_args, &arg->arg_entry);
return arg; return arg;
} }
void z__fx_get_option_description(struct fx_command_option *opt, fx_string *out) void z__b_get_option_description(struct b_command_option *opt, b_string *out)
{ {
if (opt->opt_description) { if (opt->opt_description) {
fx_string_append_cstr(out, opt->opt_description); b_string_append_cstr(out, opt->opt_description);
} }
size_t nr_args = fx_queue_length(&opt->opt_args); size_t nr_args = b_queue_length(&opt->opt_args);
bool close_bracket = false; bool close_bracket = false;
size_t i = 0; size_t i = 0;
struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args); struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) { while (entry) {
struct fx_command_arg *arg struct b_command_arg *arg
= fx_unbox(struct fx_command_arg, entry, arg_entry); = b_unbox(struct b_command_arg, entry, arg_entry);
if (!arg || !arg->arg_allowed_values) { if (!arg || !arg->arg_allowed_values) {
goto skip; goto skip;
} }
if (i > 0) { if (i > 0) {
fx_string_append_cstr(out, "; "); b_string_append_cstr(out, "; ");
} else { } else {
fx_string_append_cstr(out, " [["); b_string_append_cstr(out, " [[");
close_bracket = true; close_bracket = true;
} }
if (nr_args > 1) { if (nr_args > 1) {
fx_string_append_cstrf( b_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:"); b_string_append_cstr(out, "values:");
} }
for (size_t i = 0; arg->arg_allowed_values[i]; i++) { for (size_t i = 0; arg->arg_allowed_values[i]; i++) {
if (i > 0) { if (i > 0) {
fx_string_append_cstr(out, ","); b_string_append_cstr(out, ",");
} }
fx_string_append_cstrf( b_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]);
} }
skip: skip:
i++; i++;
entry = fx_queue_next(entry); entry = b_queue_next(entry);
} }
if (close_bracket) { if (close_bracket) {
fx_string_append_cstr(out, "]"); b_string_append_cstr(out, "]");
} }
} }
void z__fx_get_option_usage_string( void z__b_get_option_usage_string(
struct fx_command_option *opt, enum cmd_string_flags flags, fx_string *out) struct b_command_option *opt, enum cmd_string_flags flags, b_string *out)
{ {
if (flags & CMD_STR_DIRECT_USAGE) { if (flags & CMD_STR_DIRECT_USAGE) {
fx_string_append_cstr(out, "{"); b_string_append_cstr(out, "{");
} }
if (opt->opt_short_name) { if (opt->opt_short_name) {
fx_string_append_cstrf( b_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( b_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( b_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);
} }
if (flags & CMD_STR_DIRECT_USAGE) { if (flags & CMD_STR_DIRECT_USAGE) {
fx_string_append_cstr(out, "}"); b_string_append_cstr(out, "}");
} }
struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args); struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) { while (entry) {
struct fx_command_arg *arg struct b_command_arg *arg
= fx_unbox(struct fx_command_arg, entry, arg_entry); = b_unbox(struct b_command_arg, entry, arg_entry);
if (!arg) { if (!arg) {
goto skip; goto skip;
} }
bool optional = false, multi = false; bool optional = false, multi = false;
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
case FX_ARG_0_OR_1_VALUES: case B_ARG_0_OR_1_VALUES:
optional = true; optional = true;
multi = false; multi = false;
break; break;
case FX_ARG_0_OR_MORE_VALUES: case B_ARG_0_OR_MORE_VALUES:
optional = true; optional = true;
multi = true; multi = true;
break; break;
case FX_ARG_1_OR_MORE_VALUES: case B_ARG_1_OR_MORE_VALUES:
optional = false; optional = false;
multi = true; multi = true;
break; break;
@@ -223,13 +223,13 @@ void z__fx_get_option_usage_string(
} }
if (optional) { if (optional) {
fx_string_append_cstrf( b_string_append_cstrf(
out, out,
(flags & CMD_STR_COLOUR) ? " " F_GREEN "[%s]" (flags & CMD_STR_COLOUR) ? " " F_GREEN "[%s]"
: " [%s]", : " [%s]",
arg->arg_name); arg->arg_name);
} else { } else {
fx_string_append_cstrf( b_string_append_cstrf(
out, out,
(flags & CMD_STR_COLOUR) ? " " F_GREEN "<%s>" (flags & CMD_STR_COLOUR) ? " " F_GREEN "<%s>"
: " <%s>", : " <%s>",
@@ -237,36 +237,36 @@ void z__fx_get_option_usage_string(
} }
for (int i = 1; i < arg->arg_nr_values; i++) { for (int i = 1; i < arg->arg_nr_values; i++) {
fx_string_append_cstrf(out, " <%s>", arg->arg_name); b_string_append_cstrf(out, " <%s>", arg->arg_name);
} }
if (multi) { if (multi) {
fx_string_append_cstr(out, "..."); b_string_append_cstr(out, "...");
} }
if (flags & CMD_STR_COLOUR) { if (flags & CMD_STR_COLOUR) {
fx_string_append_cstr(out, F_RESET); b_string_append_cstr(out, F_RESET);
} }
skip: skip:
entry = fx_queue_next(entry); entry = b_queue_next(entry);
} }
} }
struct fx_command_arg *fx_command_option_get_arg_with_id( struct b_command_arg *b_command_option_get_arg_with_id(
struct fx_command_option *opt, unsigned int id) struct b_command_option *opt, unsigned int id)
{ {
struct fx_queue_entry *entry = fx_queue_first(&opt->opt_args); struct b_queue_entry *entry = b_queue_first(&opt->opt_args);
while (entry) { while (entry) {
struct fx_command_arg *arg struct b_command_arg *arg
= fx_unbox(struct fx_command_arg, entry, arg_entry); = b_unbox(struct b_command_arg, entry, arg_entry);
if (arg->arg_id == id) { if (arg->arg_id == id) {
return arg; return arg;
} }
entry = fx_queue_next(entry); entry = b_queue_next(entry);
} }
return NULL; return NULL;

View File

@@ -1,28 +1,28 @@
#include "command.h" #include "command.h"
#include <assert.h> #include <assert.h>
#include <fx/core/stringstream.h> #include <blue/core/stringstream.h>
#include <fx/ds/string.h> #include <blue/ds/string.h>
#include <fx/term/print.h> #include <blue/term/print.h>
#include <stdio.h> #include <stdio.h>
enum fx_status fx_arglist_report_missing_option( enum b_status b_arglist_report_missing_option(
const fx_arglist *args, unsigned int opt_id) const b_arglist *args, unsigned int opt_id)
{ {
struct fx_command_option *opt = NULL; struct b_command_option *opt = NULL;
if (opt_id != FX_COMMAND_INVALID_ID) { if (opt_id != B_COMMAND_INVALID_ID) {
opt = fx_command_get_option_with_id(args->list_command, opt_id); opt = b_command_get_option_with_id(args->list_command, opt_id);
} }
if (!opt) { if (!opt) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
fx_string *opt_string = fx_string_create(); b_string *opt_string = b_string_create();
z__fx_get_option_usage_string(opt, 0, opt_string); z__b_get_option_usage_string(opt, 0, opt_string);
fx_stringstream *opt_name = fx_stringstream_create(); b_stringstream *opt_name = b_stringstream_create();
int opt_names = 0; int opt_names = 0;
if (opt->opt_short_name) { if (opt->opt_short_name) {
@@ -34,121 +34,121 @@ enum fx_status fx_arglist_report_missing_option(
} }
if (opt_names == 2) { if (opt_names == 2) {
fx_stream_write_fmt( b_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); b_stream_write_fmt(opt_name, NULL, "-%c", opt->opt_short_name);
} else if (opt->opt_long_name) { } else if (opt->opt_long_name) {
fx_stream_write_fmt(opt_name, NULL, "--%s", opt->opt_long_name); b_stream_write_fmt(opt_name, NULL, "--%s", opt->opt_long_name);
} }
fx_err("required option `" F_YELLOW "%s" F_RESET "` was not specified.", b_err("required option `" F_YELLOW "%s" F_RESET "` was not specified.",
fx_stringstream_ptr(opt_name)); b_stringstream_ptr(opt_name));
fx_i("usage: %s", fx_string_ptr(opt_string)); b_i("usage: %s", b_string_ptr(opt_string));
fx_i("for more information, use `" F_YELLOW "--help" F_RESET "`"); b_i("for more information, use `" F_YELLOW "--help" F_RESET "`");
fx_string_unref(opt_string); b_string_unref(opt_string);
fx_stringstream_unref(opt_name); b_stringstream_unref(opt_name);
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_arglist_report_unexpected_arg( enum b_status b_arglist_report_unexpected_arg(
const fx_arglist *args, const char *value) const b_arglist *args, const char *value)
{ {
fx_string *usage = z__fx_command_default_usage_string( b_string *usage = z__b_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); b_err("unexpected argument '" F_YELLOW "%s" F_RESET "' found.", value);
fx_i("usage: %s", fx_string_ptr(usage)); b_i("usage: %s", b_string_ptr(usage));
fx_i("for more information, use '" F_YELLOW "--help" F_RESET "'"); b_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_arglist_report_invalid_arg_value( enum b_status b_arglist_report_invalid_arg_value(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const b_arglist *args, unsigned int opt_id, unsigned int arg_id,
const char *value) const char *value)
{ {
struct fx_command_option *opt = NULL; struct b_command_option *opt = NULL;
struct fx_command_arg *arg = NULL; struct b_command_arg *arg = NULL;
if (opt_id != FX_COMMAND_INVALID_ID) { if (opt_id != B_COMMAND_INVALID_ID) {
opt = fx_command_get_option_with_id(args->list_command, opt_id); opt = b_command_get_option_with_id(args->list_command, opt_id);
} }
if (arg_id != FX_COMMAND_INVALID_ID) { if (arg_id != B_COMMAND_INVALID_ID) {
arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id) arg = opt ? b_command_option_get_arg_with_id(opt, arg_id)
: fx_command_get_arg_with_id(args->list_command, arg_id); : b_command_get_arg_with_id(args->list_command, arg_id);
} }
fx_string *usage = z__fx_command_default_usage_string( b_string *usage = z__b_command_default_usage_string(
args->list_command, opt, args); args->list_command, opt, args);
fx_string *opt_string = fx_string_create(); b_string *opt_string = b_string_create();
if (opt) { if (opt) {
z__fx_get_option_usage_string(opt, 0, opt_string); z__b_get_option_usage_string(opt, 0, opt_string);
} else { } else {
z__fx_get_arg_usage_string(arg, 0, opt_string); z__b_get_arg_usage_string(arg, 0, opt_string);
} }
fx_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW b_err("invalid value '" F_YELLOW "%s" F_RESET "' for '" F_YELLOW
"%s" F_RESET "'.", "%s" F_RESET "'.",
value, fx_string_ptr(opt_string)); value, b_string_ptr(opt_string));
if (opt) { if (opt) {
fx_i("'" F_YELLOW "%s" F_RESET b_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_ptr(opt_string), arg->arg_name); b_string_ptr(opt_string), arg->arg_name);
} else { } else {
fx_i("'" F_YELLOW "%s" F_RESET "' accepts the following values:", b_i("'" F_YELLOW "%s" F_RESET "' accepts the following values:",
fx_string_ptr(opt_string)); b_string_ptr(opt_string));
} }
for (int i = 0; arg->arg_allowed_values[i]; i++) { for (int i = 0; arg->arg_allowed_values[i]; i++) {
fx_printf( b_printf(
" * " F_GREEN "%s" F_RESET "\n", " * " F_GREEN "%s" F_RESET "\n",
arg->arg_allowed_values[i]); arg->arg_allowed_values[i]);
} }
fx_printf("\n"); b_printf("\n");
fx_i("usage: %s", fx_string_ptr(usage)); b_i("usage: %s", b_string_ptr(usage));
fx_i("for more information, use '" F_YELLOW "--help" F_RESET); b_i("for more information, use '" F_YELLOW "--help" F_RESET);
fx_string_unref(usage); b_string_unref(usage);
fx_string_unref(opt_string); b_string_unref(opt_string);
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_arglist_report_missing_args( enum b_status b_arglist_report_missing_args(
const fx_arglist *args, unsigned int opt_id, unsigned int arg_id, const b_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 b_command_option *opt = NULL;
struct fx_command_arg *arg = NULL; struct b_command_arg *arg = NULL;
if (opt_id != FX_COMMAND_INVALID_ID) { if (opt_id != B_COMMAND_INVALID_ID) {
opt = fx_command_get_option_with_id(args->list_command, opt_id); opt = b_command_get_option_with_id(args->list_command, opt_id);
assert(opt); assert(opt);
} }
if (arg_id != FX_COMMAND_INVALID_ID) { if (arg_id != B_COMMAND_INVALID_ID) {
arg = opt ? fx_command_option_get_arg_with_id(opt, arg_id) arg = opt ? b_command_option_get_arg_with_id(opt, arg_id)
: fx_command_get_arg_with_id(args->list_command, arg_id); : b_command_get_arg_with_id(args->list_command, arg_id);
assert(arg); assert(arg);
} }
fx_string *usage = z__fx_command_default_usage_string( b_string *usage = z__b_command_default_usage_string(
args->list_command, opt, args); args->list_command, opt, args);
fx_string *opt_string = fx_string_create(); b_string *opt_string = b_string_create();
if (opt) { if (opt) {
z__fx_get_option_usage_string(opt, 0, opt_string); z__b_get_option_usage_string(opt, 0, opt_string);
} else { } else {
z__fx_get_arg_usage_string(arg, 0, opt_string); z__b_get_arg_usage_string(arg, 0, opt_string);
} }
char supplied_arg_str[64]; char supplied_arg_str[64];
@@ -170,7 +170,7 @@ enum fx_status fx_arglist_report_missing_args(
char required_arg_count[64]; char required_arg_count[64];
switch (arg->arg_nr_values) { switch (arg->arg_nr_values) {
case FX_ARG_1_OR_MORE_VALUES: case B_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");
@@ -181,15 +181,15 @@ enum fx_status fx_arglist_report_missing_args(
arg->arg_nr_values); arg->arg_nr_values);
} }
fx_err("argument `" F_YELLOW "%s" F_RESET "` requires " F_GREEN_BOLD b_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_ptr(opt_string), required_arg_count, arg->arg_name, b_string_ptr(opt_string), required_arg_count, arg->arg_name,
(arg->arg_nr_values == 1) ? "" : "s", supplied_arg_str); (arg->arg_nr_values == 1) ? "" : "s", supplied_arg_str);
fx_i("usage: %s", fx_string_ptr(usage)); b_i("usage: %s", b_string_ptr(usage));
fx_i("for more information, use '" F_YELLOW "--help" F_RESET "'"); b_i("for more information, use '" F_YELLOW "--help" F_RESET "'");
fx_string_unref(usage); b_string_unref(usage);
fx_string_unref(opt_string); b_string_unref(opt_string);
return FX_SUCCESS; return B_SUCCESS;
} }

View File

@@ -6,11 +6,11 @@ if (ZSTD_FOUND)
set(libs ${libs} ${ZSTD_LIBRARY}) set(libs ${libs} ${ZSTD_LIBRARY})
set(include_dirs ${include_dirs} ${ZSTD_INCLUDE_DIR}) set(include_dirs ${include_dirs} ${ZSTD_INCLUDE_DIR})
set(function_sources ${function_sources} ${CMAKE_CURRENT_SOURCE_DIR}/function/zstd.c) set(function_sources ${function_sources} ${CMAKE_CURRENT_SOURCE_DIR}/function/zstd.c)
set(defines ${defines} FX_COMPRESSOR_SUPPORTED_ZSTD) set(defines ${defines} B_COMPRESSOR_SUPPORTED_ZSTD)
message(STATUS "Enabling ZSTD support in fx-compress") message(STATUS "Enabling ZSTD support in blue-compress")
endif () endif ()
add_fx_module( add_bluelib_module(
NAME compress NAME compress
DEPENDENCIES core DEPENDENCIES core
EXTRA_SOURCES ${function_sources} EXTRA_SOURCES ${function_sources}

View File

@@ -1,15 +1,15 @@
#include <assert.h> #include <assert.h>
#include <fx/compress/compressor.h> #include <blue/compress/compressor.h>
#include <fx/core/ringbuffer.h> #include <blue/core/ringbuffer.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define COMPRESSOR_DISPATCH_STATIC(func, compressor, ...) \ #define COMPRESSOR_DISPATCH_STATIC(func, compressor, ...) \
do { \ do { \
struct compressor_data _compressor; \ struct compressor_data _compressor; \
enum fx_status status \ enum b_status status \
= compressor_get_data(compressor, &_compressor); \ = compressor_get_data(compressor, &_compressor); \
if (!FX_OK(status)) { \ if (!B_OK(status)) { \
return status; \ return status; \
} \ } \
return func(&_compressor, __VA_ARGS__); \ return func(&_compressor, __VA_ARGS__); \
@@ -17,9 +17,9 @@
#define COMPRESSOR_DISPATCH_STATIC_0(func, compressor) \ #define COMPRESSOR_DISPATCH_STATIC_0(func, compressor) \
do { \ do { \
struct compressor_data _compressor; \ struct compressor_data _compressor; \
enum fx_status status \ enum b_status status \
= compressor_get_data(compressor, &_compressor); \ = compressor_get_data(compressor, &_compressor); \
if (!FX_OK(status)) { \ if (!B_OK(status)) { \
return status; \ return status; \
} \ } \
return func(&_compressor); \ return func(&_compressor); \
@@ -28,106 +28,106 @@
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
struct compressor_data { struct compressor_data {
fx_compressor *c_obj; b_compressor *c_obj;
fx_compressor_class *c_ops; b_compressor_class *c_ops;
fx_compressor_data *c_data; b_compressor_data *c_data;
}; };
/*** PRIVATE FUNCTIONS ********************************************************/ /*** PRIVATE FUNCTIONS ********************************************************/
static enum fx_status compressor_get_data( static enum b_status compressor_get_data(
fx_compressor *compressor, struct compressor_data *out) b_compressor *compressor, struct compressor_data *out)
{ {
out->c_obj = compressor; out->c_obj = compressor;
return fx_object_get_data( return b_object_get_data(
compressor, FX_TYPE_COMPRESSOR, NULL, (void **)&out->c_data, compressor, B_TYPE_COMPRESSOR, NULL, (void **)&out->c_data,
(void **)&out->c_ops); (void **)&out->c_ops);
} }
static enum fx_status compressor_get_mode( static enum b_status compressor_get_mode(
struct compressor_data *p, enum fx_compressor_mode *out) struct compressor_data *p, enum b_compressor_mode *out)
{ {
if (out) { if (out) {
*out = p->c_data->c_mode; *out = p->c_data->c_mode;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
static enum fx_status compressor_set_mode( static enum b_status compressor_set_mode(
struct compressor_data *p, enum fx_compressor_mode mode) struct compressor_data *p, enum b_compressor_mode mode)
{ {
if (!p->c_ops->c_set_mode) { if (!p->c_ops->c_set_mode) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
return p->c_ops->c_set_mode(p->c_obj, mode); return p->c_ops->c_set_mode(p->c_obj, mode);
} }
static enum fx_status compressor_set_buffer( static enum b_status compressor_set_buffer(
struct compressor_data *p, fx_ringbuffer *inbuf, fx_ringbuffer *outbuf) struct compressor_data *p, b_ringbuffer *inbuf, b_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;
return FX_SUCCESS; return B_SUCCESS;
} }
static enum fx_status compress(struct compressor_data *p) static enum b_status compress(struct compressor_data *p)
{ {
if (p->c_data->c_mode != FX_COMPRESSOR_MODE_COMPRESS) { if (p->c_data->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
if (!p->c_ops->c_compress) { if (!p->c_ops->c_compress) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
return p->c_ops->c_compress(p->c_obj); return p->c_ops->c_compress(p->c_obj);
} }
static enum fx_status decompress(struct compressor_data *p) static enum b_status decompress(struct compressor_data *p)
{ {
if (p->c_data->c_mode != FX_COMPRESSOR_MODE_DECOMPRESS) { if (p->c_data->c_mode != B_COMPRESSOR_MODE_DECOMPRESS) {
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
if (!p->c_ops->c_decompress) { if (!p->c_ops->c_decompress) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
return p->c_ops->c_decompress(p->c_obj); return p->c_ops->c_decompress(p->c_obj);
} }
static enum fx_status compressor_step(struct compressor_data *p) static enum b_status compressor_step(struct compressor_data *p)
{ {
switch (p->c_data->c_mode) { switch (p->c_data->c_mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case B_COMPRESSOR_MODE_COMPRESS:
return compress(p); return compress(p);
case FX_COMPRESSOR_MODE_DECOMPRESS: case B_COMPRESSOR_MODE_DECOMPRESS:
return decompress(p); return decompress(p);
default: default:
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
} }
static enum fx_status compressor_end(struct compressor_data *p) static enum b_status compressor_end(struct compressor_data *p)
{ {
if (p->c_data->c_mode != FX_COMPRESSOR_MODE_COMPRESS) { if (p->c_data->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
return FX_SUCCESS; return B_SUCCESS;
} }
if (!p->c_ops->c_compress_end) { if (!p->c_ops->c_compress_end) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
while (fx_ringbuffer_available_data_remaining(p->c_data->c_in)) { while (b_ringbuffer_available_data_remaining(p->c_data->c_in)) {
if (!fx_ringbuffer_write_capacity_remaining(p->c_data->c_out)) { if (!b_ringbuffer_write_capacity_remaining(p->c_data->c_out)) {
return FX_ERR_NO_SPACE; return B_ERR_NO_SPACE;
} }
enum fx_status status = compressor_step(p); enum b_status status = compressor_step(p);
if (!FX_OK(status)) { if (!B_OK(status)) {
return status; return status;
} }
} }
@@ -135,105 +135,105 @@ static enum fx_status compressor_end(struct compressor_data *p)
return p->c_ops->c_compress_end(p->c_obj); return p->c_ops->c_compress_end(p->c_obj);
} }
static enum fx_status compressor_reset(struct compressor_data *p) static enum b_status compressor_reset(struct compressor_data *p)
{ {
p->c_data->c_flags &= ~FX_COMPRESSOR_EOF; p->c_data->c_flags &= ~B_COMPRESSOR_EOF;
if (p->c_ops->c_reset) { if (p->c_ops->c_reset) {
return p->c_ops->c_reset(p->c_obj); return p->c_ops->c_reset(p->c_obj);
} }
return FX_SUCCESS; return B_SUCCESS;
} }
static bool compressor_eof(const struct compressor_data *p) static bool compressor_eof(const struct compressor_data *p)
{ {
return (p->c_data->c_flags & FX_COMPRESSOR_EOF) != 0; return (p->c_data->c_flags & B_COMPRESSOR_EOF) != 0;
} }
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
enum fx_status fx_compressor_get_buffer_size( enum b_status b_compressor_get_buffer_size(
fx_type type, fx_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size) b_type type, b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size)
{ {
fx_class *c = fx_class_get(type); b_class *c = b_class_get(type);
if (!c) { if (!c) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
fx_compressor_class *ops = fx_class_get_interface(c, FX_TYPE_COMPRESSOR); b_compressor_class *ops = b_class_get_interface(c, B_TYPE_COMPRESSOR);
if (!ops) { if (!ops) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
if (!ops->c_buffer_size) { if (!ops->c_buffer_size) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
return ops->c_buffer_size(mode, inbuf_size, outbuf_size); return ops->c_buffer_size(mode, inbuf_size, outbuf_size);
} }
enum fx_status fx_compressor_get_mode( enum b_status b_compressor_get_mode(
const fx_compressor *compressor, enum fx_compressor_mode *out) const b_compressor *compressor, enum b_compressor_mode *out)
{ {
COMPRESSOR_DISPATCH_STATIC( COMPRESSOR_DISPATCH_STATIC(
compressor_get_mode, (fx_compressor *)compressor, out); compressor_get_mode, (b_compressor *)compressor, out);
} }
enum fx_status fx_compressor_set_mode( enum b_status b_compressor_set_mode(
fx_compressor *compressor, enum fx_compressor_mode mode) b_compressor *compressor, enum b_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 b_status b_compressor_set_buffer(
fx_compressor *compressor, fx_ringbuffer *inbuf, fx_ringbuffer *outbuf) b_compressor *compressor, b_ringbuffer *inbuf, b_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 b_status b_compressor_step(b_compressor *compressor)
{ {
COMPRESSOR_DISPATCH_STATIC_0(compressor_step, compressor); COMPRESSOR_DISPATCH_STATIC_0(compressor_step, compressor);
} }
enum fx_status fx_compressor_end(fx_compressor *compressor) enum b_status b_compressor_end(b_compressor *compressor)
{ {
COMPRESSOR_DISPATCH_STATIC_0(compressor_end, compressor); COMPRESSOR_DISPATCH_STATIC_0(compressor_end, compressor);
} }
enum fx_status fx_compressor_reset(fx_compressor *compressor) enum b_status b_compressor_reset(b_compressor *compressor)
{ {
COMPRESSOR_DISPATCH_STATIC_0(compressor_reset, compressor); COMPRESSOR_DISPATCH_STATIC_0(compressor_reset, compressor);
} }
bool fx_compressor_eof(const fx_compressor *compressor) bool b_compressor_eof(const b_compressor *compressor)
{ {
COMPRESSOR_DISPATCH_STATIC_0(compressor_eof, (fx_compressor *)compressor); COMPRESSOR_DISPATCH_STATIC_0(compressor_eof, (b_compressor *)compressor);
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
static void compressor_init(fx_object *obj, void *priv) static void compressor_init(b_object *obj, void *priv)
{ {
} }
static void compressor_fini(fx_object *obj, void *priv) static void compressor_fini(b_object *obj, void *priv)
{ {
} }
/*** CLASS DEFINITION *********************************************************/ /*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_compressor) B_TYPE_CLASS_DEFINITION_BEGIN(b_compressor)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL; B_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_compressor) B_TYPE_CLASS_DEFINITION_END(b_compressor)
FX_TYPE_DEFINITION_BEGIN(fx_compressor) B_TYPE_DEFINITION_BEGIN(b_compressor)
FX_TYPE_ID(0x452ee0f9, 0xfe12, 0x48a1, 0xb596, 0xad5b7a3940e7); B_TYPE_ID(0x452ee0f9, 0xfe12, 0x48a1, 0xb596, 0xad5b7a3940e7);
FX_TYPE_CLASS(fx_compressor_class); B_TYPE_CLASS(b_compressor_class);
FX_TYPE_INSTANCE_PROTECTED(fx_compressor_data); B_TYPE_INSTANCE_PROTECTED(b_compressor_data);
FX_TYPE_INSTANCE_INIT(compressor_init); B_TYPE_INSTANCE_INIT(compressor_init);
FX_TYPE_INSTANCE_FINI(compressor_fini); B_TYPE_INSTANCE_FINI(compressor_fini);
FX_TYPE_DEFINITION_END(fx_compressor) B_TYPE_DEFINITION_END(b_compressor)

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
#include <fx/compress/zstd.h> #include <blue/compress/zstd.h>
#include <fx/core/ringbuffer.h> #include <blue/core/ringbuffer.h>
#include <zstd.h> #include <zstd.h>
/*** PRIVATE DATA *************************************************************/ /*** PRIVATE DATA *************************************************************/
struct fx_zstd_compressor_p { struct b_zstd_compressor_p {
union { union {
ZSTD_CCtx *zstd_c; ZSTD_CCtx *zstd_c;
ZSTD_DCtx *zstd_d; ZSTD_DCtx *zstd_d;
@@ -13,40 +13,40 @@ struct fx_zstd_compressor_p {
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS *********************************************************/
fx_status fx_zstd_compressor_get_buffer_size( b_status b_zstd_compressor_get_buffer_size(
fx_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size) b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size)
{ {
switch (mode) { switch (mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case B_COMPRESSOR_MODE_COMPRESS:
*inbuf_size = ZSTD_CStreamInSize(); *inbuf_size = ZSTD_CStreamInSize();
*outbuf_size = ZSTD_CStreamOutSize(); *outbuf_size = ZSTD_CStreamOutSize();
break; break;
case FX_COMPRESSOR_MODE_DECOMPRESS: case B_COMPRESSOR_MODE_DECOMPRESS:
*inbuf_size = ZSTD_DStreamInSize(); *inbuf_size = ZSTD_DStreamInSize();
*outbuf_size = ZSTD_DStreamOutSize(); *outbuf_size = ZSTD_DStreamOutSize();
break; break;
default: default:
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
/*** VIRTUAL FUNCTIONS ********************************************************/ /*** VIRTUAL FUNCTIONS ********************************************************/
static void zstd_compressor_init(fx_object *obj, void *priv) static void zstd_compressor_init(b_object *obj, void *priv)
{ {
} }
static void zstd_compressor_fini(fx_object *obj, void *priv) static void zstd_compressor_fini(b_object *obj, void *priv)
{ {
fx_compressor_data *c = fx_object_get_protected(obj, FX_TYPE_COMPRESSOR); b_compressor_data *c = b_object_get_protected(obj, B_TYPE_COMPRESSOR);
struct fx_zstd_compressor_p *ctx = priv; struct b_zstd_compressor_p *ctx = priv;
switch (c->c_mode) { switch (c->c_mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case B_COMPRESSOR_MODE_COMPRESS:
ZSTD_freeCCtx(ctx->zstd_c); ZSTD_freeCCtx(ctx->zstd_c);
break; break;
case FX_COMPRESSOR_MODE_DECOMPRESS: case B_COMPRESSOR_MODE_DECOMPRESS:
ZSTD_freeDCtx(ctx->zstd_d); ZSTD_freeDCtx(ctx->zstd_d);
break; break;
default: default:
@@ -54,52 +54,52 @@ static void zstd_compressor_fini(fx_object *obj, void *priv)
} }
} }
static enum fx_status reset(fx_compressor *compressor) static enum b_status reset(b_compressor *compressor)
{ {
struct fx_zstd_compressor_p *ctx struct b_zstd_compressor_p *ctx
= fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR); = b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
fx_compressor_data *data b_compressor_data *data
= fx_object_get_protected(compressor, FX_TYPE_COMPRESSOR); = b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) { if (!ctx || !data) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
switch (data->c_mode) { switch (data->c_mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case B_COMPRESSOR_MODE_COMPRESS:
ZSTD_CCtx_reset(ctx->zstd_c, ZSTD_reset_session_only); ZSTD_CCtx_reset(ctx->zstd_c, ZSTD_reset_session_only);
break; break;
case FX_COMPRESSOR_MODE_DECOMPRESS: case B_COMPRESSOR_MODE_DECOMPRESS:
ZSTD_DCtx_reset(ctx->zstd_d, ZSTD_reset_session_only); ZSTD_DCtx_reset(ctx->zstd_d, ZSTD_reset_session_only);
break; break;
default: default:
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
static enum fx_status compress(fx_compressor *compressor) static enum b_status compress(b_compressor *compressor)
{ {
enum fx_status status = FX_SUCCESS; enum b_status status = B_SUCCESS;
struct fx_zstd_compressor_p *ctx struct b_zstd_compressor_p *ctx
= fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR); = b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
fx_compressor_data *data b_compressor_data *data
= fx_object_get_protected(compressor, FX_TYPE_COMPRESSOR); = b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) { if (!ctx || !data) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
fx_ringbuffer *in = data->c_in; b_ringbuffer *in = data->c_in;
fx_ringbuffer *out = data->c_out; b_ringbuffer *out = data->c_out;
if (fx_ringbuffer_available_data_remaining(in) == 0) { if (b_ringbuffer_available_data_remaining(in) == 0) {
return FX_ERR_NO_DATA; return B_ERR_NO_DATA;
} }
if (fx_ringbuffer_write_capacity_remaining(out) == 0) { if (b_ringbuffer_write_capacity_remaining(out) == 0) {
return FX_ERR_NO_SPACE; return B_ERR_NO_SPACE;
} }
size_t nr_consumed = 0; size_t nr_consumed = 0;
@@ -109,15 +109,15 @@ 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 = b_ringbuffer_open_read_buffer(in, &in_buf, &in_available);
if (!FX_OK(status)) { if (!B_OK(status)) {
break; break;
} }
status = fx_ringbuffer_open_write_buffer( status = b_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity); out, &out_buf, &out_capacity);
if (!FX_OK(status)) { if (!B_OK(status)) {
fx_ringbuffer_close_read_buffer(in, &in_buf, 0); b_ringbuffer_close_read_buffer(in, &in_buf, 0);
break; break;
} }
@@ -137,49 +137,49 @@ static enum fx_status compress(fx_compressor *compressor)
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 = B_ERR_COMPRESSION_FAILURE;
break; break;
} }
} while (z_in.pos < z_in.size && z_out.pos < z_out.size); } while (z_in.pos < z_in.size && z_out.pos < z_out.size);
nr_consumed += z_in.pos; nr_consumed += z_in.pos;
fx_ringbuffer_close_read_buffer(in, &in_buf, z_in.pos); b_ringbuffer_close_read_buffer(in, &in_buf, z_in.pos);
fx_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos); b_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos);
} }
if ((status == FX_ERR_NO_SPACE || status == FX_ERR_NO_DATA) if ((status == B_ERR_NO_SPACE || status == B_ERR_NO_DATA)
&& nr_consumed > 0) { && nr_consumed > 0) {
status = FX_SUCCESS; status = B_SUCCESS;
} }
return status; return status;
} }
static enum fx_status compress_end(fx_compressor *compressor) static enum b_status compress_end(b_compressor *compressor)
{ {
enum fx_status status = FX_SUCCESS; enum b_status status = B_SUCCESS;
struct fx_zstd_compressor_p *ctx struct b_zstd_compressor_p *ctx
= fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR); = b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
fx_compressor_data *data b_compressor_data *data
= fx_object_get_protected(compressor, FX_TYPE_COMPRESSOR); = b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) { if (!ctx || !data) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
fx_ringbuffer *out = data->c_out; b_ringbuffer *out = data->c_out;
if (fx_ringbuffer_write_capacity_remaining(out) == 0) { if (b_ringbuffer_write_capacity_remaining(out) == 0) {
return FX_ERR_NO_SPACE; return B_ERR_NO_SPACE;
} }
bool finished = false; bool finished = false;
do { do {
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 = b_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity); out, &out_buf, &out_capacity);
if (!FX_OK(status)) { if (!B_OK(status)) {
break; break;
} }
@@ -194,61 +194,61 @@ static enum fx_status compress_end(fx_compressor *compressor)
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 = B_ERR_COMPRESSION_FAILURE;
finished = true; finished = true;
} }
if (ret == 0) { if (ret == 0) {
data->c_flags |= FX_COMPRESSOR_EOF; data->c_flags |= B_COMPRESSOR_EOF;
finished = true; finished = true;
} }
} while (!finished && z_out.pos < z_out.size); } while (!finished && z_out.pos < z_out.size);
fx_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos); b_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos);
} while (!finished); } while (!finished);
return status; return status;
} }
static enum fx_status decompress(fx_compressor *compressor) static enum b_status decompress(b_compressor *compressor)
{ {
enum fx_status status = FX_SUCCESS; enum b_status status = B_SUCCESS;
struct fx_zstd_compressor_p *ctx struct b_zstd_compressor_p *ctx
= fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR); = b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
fx_compressor_data *data b_compressor_data *data
= fx_object_get_protected(compressor, FX_TYPE_COMPRESSOR); = b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) { if (!ctx || !data) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
fx_ringbuffer *in = data->c_in; b_ringbuffer *in = data->c_in;
fx_ringbuffer *out = data->c_out; b_ringbuffer *out = data->c_out;
if (fx_ringbuffer_available_data_remaining(in) == 0) { if (b_ringbuffer_available_data_remaining(in) == 0) {
return FX_ERR_NO_DATA; return B_ERR_NO_DATA;
} }
if (fx_ringbuffer_write_capacity_remaining(out) == 0) { if (b_ringbuffer_write_capacity_remaining(out) == 0) {
return FX_ERR_NO_SPACE; return B_ERR_NO_SPACE;
} }
size_t nr_consumed = 0; size_t nr_consumed = 0;
while (!(data->c_flags & FX_COMPRESSOR_EOF)) { while (!(data->c_flags & B_COMPRESSOR_EOF)) {
size_t in_available = 0, out_capacity = 0; size_t in_available = 0, out_capacity = 0;
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 = b_ringbuffer_open_read_buffer(in, &in_buf, &in_available);
if (!FX_OK(status)) { if (!B_OK(status)) {
break; break;
} }
status = fx_ringbuffer_open_write_buffer( status = b_ringbuffer_open_write_buffer(
out, &out_buf, &out_capacity); out, &out_buf, &out_capacity);
if (!FX_OK(status)) { if (!B_OK(status)) {
fx_ringbuffer_close_read_buffer(in, &in_buf, 0); b_ringbuffer_close_read_buffer(in, &in_buf, 0);
break; break;
} }
@@ -268,50 +268,50 @@ static enum fx_status decompress(fx_compressor *compressor)
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 = B_ERR_COMPRESSION_FAILURE;
break; break;
} }
if (ret == 0) { if (ret == 0) {
data->c_flags |= FX_COMPRESSOR_EOF; data->c_flags |= B_COMPRESSOR_EOF;
break; break;
} }
} while (z_in.pos < z_in.size && z_out.pos < z_out.size); } while (z_in.pos < z_in.size && z_out.pos < z_out.size);
nr_consumed += z_in.pos; nr_consumed += z_in.pos;
fx_ringbuffer_close_read_buffer(in, &in_buf, z_in.pos); b_ringbuffer_close_read_buffer(in, &in_buf, z_in.pos);
fx_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos); b_ringbuffer_close_write_buffer(out, &out_buf, z_out.pos);
} }
if ((status == FX_ERR_NO_SPACE || status == FX_ERR_NO_DATA) if ((status == B_ERR_NO_SPACE || status == B_ERR_NO_DATA)
&& nr_consumed > 0) { && nr_consumed > 0) {
status = FX_SUCCESS; status = B_SUCCESS;
} }
return status; return status;
} }
static enum fx_status set_mode(fx_compressor *compressor, fx_compressor_mode mode) static enum b_status set_mode(b_compressor *compressor, b_compressor_mode mode)
{ {
struct fx_zstd_compressor_p *ctx struct b_zstd_compressor_p *ctx
= fx_object_get_private(compressor, FX_TYPE_ZSTD_COMPRESSOR); = b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
fx_compressor_data *data b_compressor_data *data
= fx_object_get_protected(compressor, FX_TYPE_COMPRESSOR); = b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
if (!ctx || !data) { if (!ctx || !data) {
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
if (mode == data->c_mode) { if (mode == data->c_mode) {
return FX_SUCCESS; return B_SUCCESS;
} }
switch (data->c_mode) { switch (data->c_mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case B_COMPRESSOR_MODE_COMPRESS:
ZSTD_freeCCtx(ctx->zstd_c); ZSTD_freeCCtx(ctx->zstd_c);
break; break;
case FX_COMPRESSOR_MODE_DECOMPRESS: case B_COMPRESSOR_MODE_DECOMPRESS:
ZSTD_freeDCtx(ctx->zstd_d); ZSTD_freeDCtx(ctx->zstd_d);
break; break;
default: default:
@@ -321,42 +321,42 @@ static enum fx_status set_mode(fx_compressor *compressor, fx_compressor_mode mod
data->c_mode = mode; data->c_mode = mode;
switch (data->c_mode) { switch (data->c_mode) {
case FX_COMPRESSOR_MODE_COMPRESS: case B_COMPRESSOR_MODE_COMPRESS:
ctx->zstd_c = ZSTD_createCCtx(); ctx->zstd_c = ZSTD_createCCtx();
break; break;
case FX_COMPRESSOR_MODE_DECOMPRESS: case B_COMPRESSOR_MODE_DECOMPRESS:
ctx->zstd_d = ZSTD_createDCtx(); ctx->zstd_d = ZSTD_createDCtx();
break; break;
default: default:
return FX_ERR_INVALID_ARGUMENT; return B_ERR_INVALID_ARGUMENT;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
/*** CLASS DEFINITION *********************************************************/ /*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_zstd_compressor) B_TYPE_CLASS_DEFINITION_BEGIN(b_zstd_compressor)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL; B_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_compressor, FX_TYPE_COMPRESSOR) B_TYPE_CLASS_INTERFACE_BEGIN(b_compressor, B_TYPE_COMPRESSOR)
FX_INTERFACE_ENTRY(c_buffer_size) B_INTERFACE_ENTRY(c_buffer_size)
= fx_zstd_compressor_get_buffer_size; = b_zstd_compressor_get_buffer_size;
FX_INTERFACE_ENTRY(c_compress) = compress; B_INTERFACE_ENTRY(c_compress) = compress;
FX_INTERFACE_ENTRY(c_compress_end) = compress_end; B_INTERFACE_ENTRY(c_compress_end) = compress_end;
FX_INTERFACE_ENTRY(c_decompress) = decompress; B_INTERFACE_ENTRY(c_decompress) = decompress;
FX_INTERFACE_ENTRY(c_reset) = reset; B_INTERFACE_ENTRY(c_reset) = reset;
FX_INTERFACE_ENTRY(c_set_mode) = set_mode; B_INTERFACE_ENTRY(c_set_mode) = set_mode;
FX_TYPE_CLASS_INTERFACE_END(fx_compressor, FX_TYPE_COMPRESSOR) B_TYPE_CLASS_INTERFACE_END(b_compressor, B_TYPE_COMPRESSOR)
FX_TYPE_CLASS_DEFINITION_END(fx_zstd_compressor) B_TYPE_CLASS_DEFINITION_END(b_zstd_compressor)
FX_TYPE_DEFINITION_BEGIN(fx_zstd_compressor) B_TYPE_DEFINITION_BEGIN(b_zstd_compressor)
FX_TYPE_ID(0x51d437fc, 0xe789, 0x4105, 0xbac7, 0xe6b3f45df198); B_TYPE_ID(0x51d437fc, 0xe789, 0x4105, 0xbac7, 0xe6b3f45df198);
FX_TYPE_EXTENDS(FX_TYPE_COMPRESSOR); B_TYPE_EXTENDS(B_TYPE_COMPRESSOR);
FX_TYPE_CLASS(fx_zstd_compressor_class); B_TYPE_CLASS(b_zstd_compressor_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_zstd_compressor_p); B_TYPE_INSTANCE_PRIVATE(struct b_zstd_compressor_p);
FX_TYPE_INSTANCE_INIT(zstd_compressor_init); B_TYPE_INSTANCE_INIT(zstd_compressor_init);
FX_TYPE_INSTANCE_FINI(zstd_compressor_fini); B_TYPE_INSTANCE_FINI(zstd_compressor_fini);
FX_TYPE_DEFINITION_END(fx_zstd_compressor) B_TYPE_DEFINITION_END(b_zstd_compressor)

View File

@@ -0,0 +1,67 @@
#ifndef BLUE_COMPRESS_COMPRESSOR_H_
#define BLUE_COMPRESS_COMPRESSOR_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/ringbuffer.h>
#include <blue/core/status.h>
#include <stdbool.h>
B_DECLS_BEGIN;
typedef enum b_compressor_mode {
B_COMPRESSOR_MODE_NONE = 0,
B_COMPRESSOR_MODE_COMPRESS,
B_COMPRESSOR_MODE_DECOMPRESS,
} b_compressor_mode;
typedef enum b_compressor_flags {
B_COMPRESSOR_EOF = 0x01u,
} b_compressor_flags;
#define B_TYPE_COMPRESSOR (b_compressor_get_type())
B_DECLARE_TYPE(b_compressor);
B_TYPE_CLASS_DECLARATION_BEGIN(b_compressor)
b_status (*c_buffer_size)(b_compressor_mode, size_t *, size_t *);
b_status (*c_set_mode)(b_compressor *, b_compressor_mode);
b_status (*c_compress)(b_compressor *);
b_status (*c_compress_end)(b_compressor *);
b_status (*c_decompress)(b_compressor *);
b_status (*c_reset)(b_compressor *);
B_TYPE_CLASS_DECLARATION_END(b_compressor)
typedef struct b_compressor_data {
b_compressor_flags c_flags;
b_compressor_mode c_mode;
b_ringbuffer *c_in, *c_out;
} b_compressor_data;
BLUE_API b_type b_compressor_get_type(void);
#if 0
BLUE_API b_status b_compressor_create(
const struct b_compression_function *func, enum b_compression_mode mode,
struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf,
b_compressor **out);
#endif
BLUE_API b_status b_compressor_get_buffer_size(
b_type type, b_compressor_mode mode, size_t *inbuf_size,
size_t *outbuf_size);
BLUE_API b_status b_compressor_get_mode(
const b_compressor *compressor, b_compressor_mode *out);
BLUE_API b_status b_compressor_set_mode(
b_compressor *compressor, b_compressor_mode mode);
BLUE_API b_status b_compressor_set_buffer(
b_compressor *compressor, b_ringbuffer *inbuf, b_ringbuffer *outbuf);
BLUE_API b_status b_compressor_step(b_compressor *compressor);
BLUE_API b_status b_compressor_end(b_compressor *compressor);
BLUE_API b_status b_compressor_reset(b_compressor *compressor);
BLUE_API bool b_compressor_eof(const b_compressor *compressor);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,50 @@
#ifndef BLUE_COMPRESS_CSTREAM_H_
#define BLUE_COMPRESS_CSTREAM_H_
#include <blue/core/macros.h>
#include <blue/core/stream.h>
#include <stdbool.h>
B_DECLS_BEGIN;
enum b_compressor_mode;
#define B_TYPE_CSTREAM (b_cstream_get_type())
B_DECLARE_TYPE(b_cstream);
B_TYPE_CLASS_DECLARATION_BEGIN(b_cstream)
B_TYPE_CLASS_DECLARATION_END(b_cstream)
BLUE_API b_type b_cstream_get_type(void);
BLUE_API b_status b_cstream_open(
b_stream *endpoint, b_type compressor_type, enum b_compressor_mode mode,
b_cstream **out);
BLUE_API b_status b_cstream_read(
b_cstream *stream, void *buf, size_t count, size_t *nr_read);
BLUE_API b_status b_cstream_write(
b_cstream *stream, const void *buf, size_t count, size_t *nr_written);
BLUE_API b_status b_cstream_skip(
b_cstream *stream, size_t count, size_t *nr_skipped);
BLUE_API b_status b_cstream_reset(b_cstream *stream);
BLUE_API b_status b_cstream_begin_compressed_section(
b_cstream *stream, size_t *tx_uncompressed_bytes);
BLUE_API b_status b_cstream_end_compressed_section(
b_cstream *stream, size_t *tx_compressed_bytes,
size_t *tx_uncompressed_bytes);
BLUE_API bool b_cstream_in_compressed_section(const b_cstream *stream);
BLUE_API b_status b_cstream_tx_bytes(const b_cstream *stream, size_t *out);
BLUE_API b_status b_cstream_tx_bytes_compressed(
const b_cstream *stream, size_t *out);
BLUE_API b_status b_cstream_tx_bytes_uncompressed(
const b_cstream *stream, size_t *out);
BLUE_API b_status b_cstream_set_cursor_position(b_cstream *stream, size_t pos);
BLUE_API b_status b_cstream_restore_cursor_position(b_cstream *stream);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,28 @@
#ifndef BLUE_COMPRESS_ZSTD_H_
#define BLUE_COMPRESS_ZSTD_H_
#include <blue/compress/compressor.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdbool.h>
B_DECLS_BEGIN;
#define B_TYPE_ZSTD_COMPRESSOR (b_zstd_compressor_get_type())
B_DECLARE_TYPE(b_zstd_compressor);
B_TYPE_CLASS_DECLARATION_BEGIN(b_zstd_compressor)
B_TYPE_CLASS_DECLARATION_END(b_compressor)
BLUE_API b_type b_zstd_compressor_get_type(void);
BLUE_API b_status b_zstd_compressor_get_buffer_size(
b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size);
B_TYPE_DEFAULT_CONSTRUCTOR(b_zstd_compressor, B_TYPE_ZSTD_COMPRESSOR);
B_DECLS_END;
#endif

View File

@@ -1,67 +0,0 @@
#ifndef FX_COMPRESS_COMPRESSOR_H_
#define FX_COMPRESS_COMPRESSOR_H_
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <fx/core/ringbuffer.h>
#include <fx/core/status.h>
#include <stdbool.h>
FX_DECLS_BEGIN;
typedef enum fx_compressor_mode {
FX_COMPRESSOR_MODE_NONE = 0,
FX_COMPRESSOR_MODE_COMPRESS,
FX_COMPRESSOR_MODE_DECOMPRESS,
} fx_compressor_mode;
typedef enum fx_compressor_flags {
FX_COMPRESSOR_EOF = 0x01u,
} fx_compressor_flags;
#define FX_TYPE_COMPRESSOR (fx_compressor_get_type())
FX_DECLARE_TYPE(fx_compressor);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_compressor)
fx_status (*c_buffer_size)(fx_compressor_mode, size_t *, size_t *);
fx_status (*c_set_mode)(fx_compressor *, fx_compressor_mode);
fx_status (*c_compress)(fx_compressor *);
fx_status (*c_compress_end)(fx_compressor *);
fx_status (*c_decompress)(fx_compressor *);
fx_status (*c_reset)(fx_compressor *);
FX_TYPE_CLASS_DECLARATION_END(fx_compressor)
typedef struct fx_compressor_data {
fx_compressor_flags c_flags;
fx_compressor_mode c_mode;
fx_ringbuffer *c_in, *c_out;
} fx_compressor_data;
FX_API fx_type fx_compressor_get_type(void);
#if 0
FX_API fx_status fx_compressor_create(
const struct fx_compression_function *func, enum fx_compression_mode mode,
struct fx_ringbuffer *inbuf, struct fx_ringbuffer *outbuf,
fx_compressor **out);
#endif
FX_API fx_status fx_compressor_get_buffer_size(
fx_type type, fx_compressor_mode mode, size_t *inbuf_size,
size_t *outbuf_size);
FX_API fx_status fx_compressor_get_mode(
const fx_compressor *compressor, fx_compressor_mode *out);
FX_API fx_status fx_compressor_set_mode(
fx_compressor *compressor, fx_compressor_mode mode);
FX_API fx_status fx_compressor_set_buffer(
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_end(fx_compressor *compressor);
FX_API fx_status fx_compressor_reset(fx_compressor *compressor);
FX_API bool fx_compressor_eof(const fx_compressor *compressor);
FX_DECLS_END;
#endif

View File

@@ -1,50 +0,0 @@
#ifndef FX_COMPRESS_CSTREAM_H_
#define FX_COMPRESS_CSTREAM_H_
#include <fx/core/macros.h>
#include <fx/core/stream.h>
#include <stdbool.h>
FX_DECLS_BEGIN;
enum fx_compressor_mode;
#define FX_TYPE_CSTREAM (fx_cstream_get_type())
FX_DECLARE_TYPE(fx_cstream);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_cstream)
FX_TYPE_CLASS_DECLARATION_END(fx_cstream)
FX_API fx_type fx_cstream_get_type(void);
FX_API fx_status fx_cstream_open(
fx_stream *endpoint, fx_type compressor_type, enum fx_compressor_mode mode,
fx_cstream **out);
FX_API fx_status fx_cstream_read(
fx_cstream *stream, void *buf, size_t count, size_t *nr_read);
FX_API fx_status fx_cstream_write(
fx_cstream *stream, const void *buf, 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_begin_compressed_section(
fx_cstream *stream, size_t *tx_uncompressed_bytes);
FX_API fx_status fx_cstream_end_compressed_section(
fx_cstream *stream, size_t *tx_compressed_bytes,
size_t *tx_uncompressed_bytes);
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_compressed(
const fx_cstream *stream, size_t *out);
FX_API fx_status fx_cstream_tx_bytes_uncompressed(
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_restore_cursor_position(fx_cstream *stream);
FX_DECLS_END;
#endif

View File

@@ -1,28 +0,0 @@
#ifndef FX_COMPRESS_ZSTD_H_
#define FX_COMPRESS_ZSTD_H_
#include <fx/compress/compressor.h>
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <fx/core/status.h>
#include <stdbool.h>
FX_DECLS_BEGIN;
#define FX_TYPE_ZSTD_COMPRESSOR (fx_zstd_compressor_get_type())
FX_DECLARE_TYPE(fx_zstd_compressor);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_zstd_compressor)
FX_TYPE_CLASS_DECLARATION_END(fx_compressor)
FX_API fx_type fx_zstd_compressor_get_type(void);
FX_API fx_status fx_zstd_compressor_get_buffer_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_DECLS_END;
#endif

6
core-mm/CMakeLists.txt Normal file
View File

@@ -0,0 +1,6 @@
include(../cmake/Templates.cmake)
add_bluelib_mm_module(
NAME core
DEPENDENCIES core
SUBDIRS hash)

1
core-mm/encoding.cpp Normal file
View File

@@ -0,0 +1 @@
#include <blue/core/encoding.hpp>

View File

@@ -0,0 +1,106 @@
#ifndef BLUE_CORE_ENCODING_HPP_
#define BLUE_CORE_ENCODING_HPP_
#include <blue/core/encoding.h>
#include <cstddef>
#include <cstdint>
namespace blue::core
{
class wchar
{
public:
static const int32_t INVALID = B_WCHAR_INVALID;
wchar();
wchar(std::int32_t v)
: val_(v)
{
}
static wchar decode(const char *s);
operator int32_t() const
{
return val_;
}
bool is_alpha(void) const
{
return b_wchar_is_alpha(val_);
}
bool is_number(void) const
{
return b_wchar_is_number(val_);
}
bool is_bin_digit(void) const
{
return b_wchar_is_bin_digit(val_);
}
bool is_oct_digit(void) const
{
return b_wchar_is_oct_digit(val_);
}
bool is_hex_digit(void) const
{
return b_wchar_is_hex_digit(val_);
}
bool is_space(void) const
{
return b_wchar_is_space(val_);
}
bool is_alnum(void) const
{
return b_wchar_is_alnum(val_);
}
bool is_punct(void) const
{
return b_wchar_is_punct(val_);
}
bool is_valid_utf8_scalar(void) const
{
return b_wchar_utf8_is_valid_scalar(val_);
}
unsigned int get_utf8_codepoint_size(void) const
{
return b_wchar_utf8_codepoint_size(val_);
}
unsigned int encode_utf8(char s[4]) const
{
return b_wchar_utf8_codepoint_encode(val_, s);
}
private:
int32_t val_ = B_WCHAR_INVALID;
};
class utf8
{
public:
static unsigned int decode_header(char c)
{
return b_wchar_utf8_header_decode(c);
}
static unsigned int get_codepoint_stride(const char *s)
{
return b_wchar_utf8_codepoint_stride(s);
}
static std::size_t get_codepoint_count(const char *s, std::size_t nr_bytes)
{
return b_wchar_utf8_codepoint_count(s, nr_bytes);
}
static std::size_t get_string_encoded_size(
const wchar *s, std::size_t nr_codepoints)
{
return b_wchar_utf8_string_encoded_size(
reinterpret_cast<const b_wchar *>(s), nr_codepoints);
}
private:
utf8() = delete;
~utf8() = delete;
};
}
#endif

View File

@@ -0,0 +1,13 @@
#ifndef BLUE_CORE_ITERATOR_HPP_
#define BLUE_CORE_ITERATOR_HPP_
#include <blue/core/object.hpp>
namespace blue::core
{
class iterator : public object
{
};
}
#endif

View File

@@ -0,0 +1,46 @@
#ifndef BLUE_CORE_MISC_HPP_
#define BLUE_CORE_MISC_HPP_
#define Z__B_ENUM_CLASS_BITWISE_OPS(enum_name) \
inline constexpr enum_name operator&(enum_name x, enum_name y) \
{ \
return static_cast<enum_name>( \
static_cast<int>(x) & static_cast<int>(y)); \
} \
\
inline constexpr enum_name operator|(enum_name x, enum_name y) \
{ \
return static_cast<enum_name>( \
static_cast<int>(x) | static_cast<int>(y)); \
} \
\
inline constexpr enum_name operator^(enum_name x, enum_name y) \
{ \
return static_cast<enum_name>( \
static_cast<int>(x) ^ static_cast<int>(y)); \
} \
\
inline constexpr enum_name operator~(enum_name x) \
{ \
return static_cast<enum_name>(~static_cast<int>(x)); \
} \
\
inline enum_name &operator&=(enum_name &x, enum_name y) \
{ \
x = x & y; \
return x; \
} \
\
inline enum_name &operator|=(enum_name &x, enum_name y) \
{ \
x = x | y; \
return x; \
} \
\
inline enum_name &operator^=(enum_name &x, enum_name y) \
{ \
x = x ^ y; \
return x; \
}
#endif

View File

@@ -0,0 +1,40 @@
#ifndef BLUE_CORE_OBJECT_HPP_
#define BLUE_CORE_OBJECT_HPP_
#include <blue/core/object.h>
namespace blue::core
{
class type;
class object
{
public:
static const size_t MAGIC = B_OBJECT_MAGIC;
object(object &) = delete;
object(object &&);
~object();
bool operator!()
{
return ptr_ == nullptr;
}
void to_string(void) const;
bool is_type(const type &type) const;
b_object *ptr(void)
{
return ptr_;
}
const b_object *ptr(void) const
{
return ptr_;
}
protected:
object() = default;
b_object *ptr_ = nullptr;
};
}
#endif

View File

@@ -0,0 +1,62 @@
#ifndef BLUE_CORE_STATUS_HPP_
#define BLUE_CORE_STATUS_HPP_
#include <blue/core/status.h>
namespace blue
{
class status
{
public:
#define __MM_STATUS_ENUM(name) name = B_ERR_##name
enum _status : int {
SUCCESS = B_SUCCESS,
__MM_STATUS_ENUM(NO_MEMORY),
__MM_STATUS_ENUM(OUT_OF_BOUNDS),
__MM_STATUS_ENUM(INVALID_ARGUMENT),
__MM_STATUS_ENUM(NAME_EXISTS),
__MM_STATUS_ENUM(NOT_SUPPORTED),
__MM_STATUS_ENUM(BAD_STATE),
__MM_STATUS_ENUM(NO_ENTRY),
__MM_STATUS_ENUM(NO_DATA),
__MM_STATUS_ENUM(NO_SPACE),
__MM_STATUS_ENUM(UNKNOWN_FUNCTION),
__MM_STATUS_ENUM(BAD_FORMAT),
__MM_STATUS_ENUM(IO_FAILURE),
__MM_STATUS_ENUM(IS_DIRECTORY),
__MM_STATUS_ENUM(NOT_DIRECTORY),
__MM_STATUS_ENUM(PERMISSION_DENIED),
__MM_STATUS_ENUM(BUSY),
__MM_STATUS_ENUM(COMPRESSION_FAILURE),
__MM_STATUS_ENUM(TYPE_REGISTRATION_FAILURE),
__MM_STATUS_ENUM(CLASS_INIT_FAILURE),
};
status() = default;
status(_status v)
: v_(static_cast<b_status>(v))
{
}
status(b_status v)
: v_(v)
{
}
bool operator!() const
{
return v_ != B_SUCCESS;
}
operator b_status() const
{
return v_;
}
const char *to_string(void);
const char *description(void);
private:
b_status v_ = B_SUCCESS;
};
}
#endif

View File

@@ -0,0 +1,135 @@
#ifndef BLUE_CORE_STREAM_HPP_
#define BLUE_CORE_STREAM_HPP_
#include <blue/core/encoding.hpp>
#include <blue/core/misc.hpp>
#include <blue/core/object.hpp>
#include <blue/core/status.hpp>
#include <blue/core/stream.h>
#include <blue/core/type.hpp>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <string>
namespace blue::core
{
class stream_buffer : public object
{
};
class stream : public object
{
public:
enum class mode : int {
READ = B_STREAM_READ,
WRITE = B_STREAM_WRITE,
BINARY = B_STREAM_BINARY,
__STATIC = Z__B_STREAM_STATIC,
};
enum class seek_origin : int {
START = B_STREAM_SEEK_START,
CURRENT = B_STREAM_SEEK_CURRENT,
END = B_STREAM_SEEK_END,
};
static type get_type(void);
static stream &in(void);
static stream &out(void);
static stream &err(void);
stream(stream &) = delete;
stream(std::FILE *fp);
status reserve(std::size_t len);
status seek(long long offset, seek_origin origin);
std::size_t cursor(void) const;
status push_indent(int indent);
status pop_indent(void);
status read_char(wchar &c);
status read_bytes(void *buf, std::size_t count, std::size_t &nr_read);
status read_bytes(void *buf, std::size_t count)
{
std::size_t tmp;
return read_bytes(buf, count, tmp);
}
status read_line(char *s, std::size_t max);
status read_line(std::string &out);
status read_line(stream &dest);
status read_all_bytes(void *p, std::size_t max, std::size_t &nr_read);
status read_all_bytes(
stream &dest, stream_buffer &buf, std::size_t &nr_read);
status read_all_bytes(void *p, std::size_t max)
{
std::size_t tmp;
return read_all_bytes(p, max);
}
status read_all_bytes(stream &dest, stream_buffer &buf)
{
std::size_t tmp;
return read_all_bytes(dest, buf);
}
status write_char(wchar c);
status write_string(const char *s, std::size_t &nr_written);
status write_string(const char *s)
{
std::size_t tmp;
return write_string(s, tmp);
}
status write_string(const std::string &s, std::size_t &nr_written)
{
return write_string(s.c_str(), nr_written);
}
status write_string(const std::string &s)
{
std::size_t tmp;
return write_string(s, tmp);
}
status write_bytes(
const void *buf, std::size_t count, std::size_t &nr_written);
status write_bytes(const void *buf, std::size_t count)
{
std::size_t tmp;
return write_bytes(buf, count, tmp);
}
status write_fmt(std::size_t &nr_written, const char *format, ...);
status write_vfmt(
std::size_t &nr_written, const char *format, std::va_list arg);
status write_fmt(const char *format, ...)
{
std::size_t tmp;
std::va_list arg;
va_start(arg, format);
status s = write_vfmt(tmp, format, arg);
va_end(arg);
return s;
}
status write_vfmt(const char *format, std::va_list arg)
{
std::size_t tmp;
return write_vfmt(tmp, format, arg);
}
protected:
stream() = default;
};
}
Z__B_ENUM_CLASS_BITWISE_OPS(blue::core::stream::mode)
#endif

View File

@@ -0,0 +1,23 @@
#ifndef BLUE_CORE_STRINGSTREAM_HPP_
#define BLUE_CORE_STRINGSTREAM_HPP_
#include <blue/core/stream.hpp>
namespace blue::core
{
class stringstream : public stream
{
public:
stringstream();
stringstream(char *buf, std::size_t max);
status reset();
status reset(char *buf, std::size_t max);
const char *get_ptr() const;
char *steal_ptr();
std::size_t get_length() const;
};
}
#endif

View File

@@ -0,0 +1,24 @@
#ifndef BLUE_CORE_TYPE_HPP_
#define BLUE_CORE_TYPE_HPP_
#include <blue/core/type.h>
namespace blue::core
{
class type
{
public:
type(b_type p)
{
ptr_ = p;
}
~type() = default;
type(type &) = default;
private:
const union b_type_id *ptr_;
};
}
#endif

1
core-mm/iterator.cpp Normal file
View File

@@ -0,0 +1 @@
#include <blue/core/iterator.hpp>

20
core-mm/object.cpp Normal file
View File

@@ -0,0 +1,20 @@
#include <blue/core/object.hpp>
namespace blue::core
{
object::object(object &&other)
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
object::~object()
{
if (ptr_) {
b_object_unref(ptr_);
ptr_ = nullptr;
}
}
}

169
core-mm/stream.cpp Normal file
View File

@@ -0,0 +1,169 @@
#include <blue/core/stream.h>
#include <blue/core/stream.hpp>
namespace blue::core
{
type stream::get_type(void)
{
return b_stream_get_type();
}
stream &stream::in(void)
{
static stream s;
s.ptr_ = b_stdin;
return s;
}
stream &stream::out(void)
{
static stream s;
s.ptr_ = b_stdout;
return s;
}
stream &stream::err(void)
{
static stream s;
s.ptr_ = b_stderr;
return s;
}
stream::stream(std::FILE *fp)
{
ptr_ = b_stream_open_fp(fp);
}
status stream::reserve(std::size_t len)
{
return b_stream_reserve(ptr_, len);
}
status stream::seek(long long offset, seek_origin origin)
{
return b_stream_seek(
ptr_, offset, static_cast<b_stream_seek_origin>(origin));
}
std::size_t stream::cursor(void) const
{
return b_stream_cursor(ptr_);
}
status stream::push_indent(int indent)
{
return b_stream_push_indent(ptr_, indent);
}
status stream::pop_indent(void)
{
return b_stream_pop_indent(ptr_);
}
status stream::read_char(wchar &c)
{
b_wchar tmp;
status s = b_stream_read_char(ptr_, &tmp);
c = tmp;
return s;
}
status stream::read_bytes(void *buf, std::size_t count, std::size_t &nr_read)
{
std::size_t r;
status s = b_stream_read_bytes(ptr_, buf, count, &r);
nr_read = r;
return s;
}
status stream::read_line(char *s, std::size_t max)
{
return b_stream_read_line(ptr_, s, max);
}
status stream::read_line(std::string &out)
{
while (1) {
wchar c = wchar::INVALID;
status s = read_char(c);
if (!s) {
return s;
}
if (c == '\n') {
break;
}
char str[5] = {0};
c.encode_utf8(str);
out.append(str);
}
return status::SUCCESS;
}
status stream::read_line(stream &dest)
{
return b_stream_read_line_s(ptr_, dest.ptr_);
}
status stream::read_all_bytes(void *p, std::size_t max, std::size_t &nr_read)
{
std::size_t tmp;
status s = b_stream_read_all_bytes(ptr_, p, max, &tmp);
nr_read = tmp;
return s;
}
status stream::read_all_bytes(stream &dest, stream_buffer &buf, std::size_t &nr_read)
{
std::size_t tmp;
status s = b_stream_read_all_bytes_s(ptr_, dest.ptr_, buf.ptr(), &tmp);
nr_read = tmp;
return s;
}
status stream::write_char(wchar c)
{
return b_stream_write_char(ptr_, c);
}
status stream::write_string(const char *str, std::size_t &nr_written)
{
std::size_t tmp;
status s = b_stream_write_string(ptr_, str, &tmp);
nr_written = tmp;
return s;
}
status stream::write_bytes(
const void *buf, std::size_t count, std::size_t &nr_written)
{
std::size_t tmp;
status s = b_stream_write_bytes(ptr_, buf, count, &tmp);
nr_written = tmp;
return s;
}
status stream::write_fmt(std::size_t &nr_written, const char *format, ...)
{
size_t tmp;
std::va_list arg;
va_start(arg, format);
status s = b_stream_write_vfmt(ptr_, &tmp, format, arg);
va_end(arg);
nr_written = tmp;
return s;
}
status stream::write_vfmt(std::size_t &nr_written, const char *format, va_list arg)
{
size_t tmp;
status s = b_stream_write_vfmt(ptr_, &tmp, format, arg);
nr_written = tmp;
return s;
}
}

42
core-mm/stringstream.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include <blue/core/stringstream.h>
#include <blue/core/stringstream.hpp>
namespace blue::core
{
stringstream::stringstream()
{
ptr_ = b_stringstream_create();
}
stringstream::stringstream(char *buf, std::size_t max)
{
ptr_ = b_stringstream_create_with_buffer(buf, max);
}
status stringstream::reset()
{
return b_stringstream_reset(ptr_);
}
status stringstream::reset(char *buf, std::size_t max)
{
return b_stringstream_reset_with_buffer(ptr_, buf, max);
}
const char *stringstream::get_ptr() const
{
return b_stringstream_ptr(ptr_);
}
char *stringstream::steal_ptr()
{
return b_stringstream_steal(ptr_);
}
std::size_t stringstream::get_length() const
{
return b_stringstream_get_length(ptr_);
}
}

1
core-mm/type.cpp Normal file
View File

@@ -0,0 +1 @@
#include <blue/core/type.hpp>

View File

@@ -1,5 +1,5 @@
include(../cmake/Templates.cmake) include(../cmake/Templates.cmake)
add_fx_module( add_bluelib_module(
NAME core NAME core
SUBDIRS hash) SUBDIRS hash)

View File

@@ -1,37 +1,37 @@
#include "printf.h" #include "printf.h"
#include <fx/core/bstr.h> #include <blue/core/bstr.h>
#include <fx/core/rope.h> #include <blue/core/rope.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define CHECK_FLAG(str, f) ((((str)->bstr_flags) & (f)) == (f)) #define CHECK_FLAG(str, f) ((((str)->bstr_flags) & (f)) == (f))
#define IS_DYNAMIC(p) (CHECK_FLAG(p, FX_BSTR_F_ALLOC)) #define IS_DYNAMIC(p) (CHECK_FLAG(p, B_BSTR_F_ALLOC))
/* number of bytes that bstr_buf is extended by when required */ /* number of bytes that bstr_buf is extended by when required */
#define CAPACITY_STEP 32 #define CAPACITY_STEP 32
void fx_bstr_begin(struct fx_bstr *str, char *buf, size_t max) void b_bstr_begin(struct b_bstr *str, char *buf, size_t max)
{ {
memset(str, 0x0, sizeof *str); memset(str, 0x0, sizeof *str);
str->bstr_magic = FX_BSTR_MAGIC; str->bstr_magic = B_BSTR_MAGIC;
str->bstr_buf = buf; str->bstr_buf = buf;
str->bstr_capacity = max; str->bstr_capacity = max;
str->bstr_len = 0; str->bstr_len = 0;
str->bstr_flags = FX_BSTR_F_NONE; str->bstr_flags = B_BSTR_F_NONE;
} }
void fx_bstr_begin_dynamic(struct fx_bstr *str) void b_bstr_begin_dynamic(struct b_bstr *str)
{ {
memset(str, 0x0, sizeof *str); memset(str, 0x0, sizeof *str);
str->bstr_magic = FX_BSTR_MAGIC; str->bstr_magic = B_BSTR_MAGIC;
str->bstr_buf = NULL; str->bstr_buf = NULL;
str->bstr_capacity = 0; str->bstr_capacity = 0;
str->bstr_len = 0; str->bstr_len = 0;
str->bstr_flags = FX_BSTR_F_ALLOC; str->bstr_flags = B_BSTR_F_ALLOC;
} }
static char *truncate_buffer(char *s, size_t len) static char *truncate_buffer(char *s, size_t len)
@@ -50,7 +50,7 @@ static char *truncate_buffer(char *s, size_t len)
return final; return final;
} }
char *fx_bstr_end(struct fx_bstr *str) char *b_bstr_end(struct b_bstr *str)
{ {
char *out = str->bstr_buf; char *out = str->bstr_buf;
size_t len = str->bstr_len; size_t len = str->bstr_len;
@@ -70,29 +70,29 @@ char *fx_bstr_end(struct fx_bstr *str)
return out; return out;
} }
enum fx_status fx_bstr_reserve(struct fx_bstr *strv, size_t len) enum b_status b_bstr_reserve(struct b_bstr *strv, size_t len)
{ {
if (!IS_DYNAMIC(strv)) { if (!IS_DYNAMIC(strv)) {
return FX_SUCCESS; return B_SUCCESS;
} }
if (strv->bstr_capacity > 0 && strv->bstr_capacity - 1 >= len) { if (strv->bstr_capacity > 0 && strv->bstr_capacity - 1 >= len) {
return FX_SUCCESS; return B_SUCCESS;
} }
char *new_buf = realloc(strv->bstr_buf, len + 1); char *new_buf = realloc(strv->bstr_buf, len + 1);
if (!new_buf) { if (!new_buf) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
strv->bstr_buf = new_buf; strv->bstr_buf = new_buf;
strv->bstr_capacity = len + 1; strv->bstr_capacity = len + 1;
strv->bstr_buf[strv->bstr_len] = '\0'; strv->bstr_buf[strv->bstr_len] = '\0';
return FX_SUCCESS; return B_SUCCESS;
} }
static int current_indent(struct fx_bstr *str) static int current_indent(struct b_bstr *str)
{ {
if (!str->bstr_istack || !str->bstr_istack_size) { if (!str->bstr_istack || !str->bstr_istack_size) {
return 0; return 0;
@@ -101,7 +101,7 @@ static int current_indent(struct fx_bstr *str)
return str->bstr_istack[str->bstr_istack_ptr]; return str->bstr_istack[str->bstr_istack_ptr];
} }
static void __formatter_putchar(struct fx_bstr *str, char c) static void __formatter_putchar(struct b_bstr *str, char c)
{ {
if (str->bstr_capacity > 0 && str->bstr_len < str->bstr_capacity - 1) { if (str->bstr_capacity > 0 && str->bstr_len < str->bstr_capacity - 1) {
str->bstr_buf[str->bstr_len++] = c; str->bstr_buf[str->bstr_len++] = c;
@@ -109,7 +109,7 @@ static void __formatter_putchar(struct fx_bstr *str, char c)
return; return;
} }
if (!CHECK_FLAG(str, FX_BSTR_F_ALLOC)) { if (!CHECK_FLAG(str, B_BSTR_F_ALLOC)) {
return; return;
} }
@@ -127,7 +127,7 @@ static void __formatter_putchar(struct fx_bstr *str, char c)
str->bstr_buf[str->bstr_len] = '\0'; str->bstr_buf[str->bstr_len] = '\0';
} }
static void formatter_putchar(struct fx_bstr *f, char c) static void formatter_putchar(struct b_bstr *f, char c)
{ {
if (f->bstr_add_indent && c != '\n') { if (f->bstr_add_indent && c != '\n') {
int indent = current_indent(f); int indent = current_indent(f);
@@ -148,12 +148,12 @@ static void formatter_putchar(struct fx_bstr *f, char c)
static void bstr_fctprintf(char c, void *arg) static void bstr_fctprintf(char c, void *arg)
{ {
struct fx_bstr *str = arg; struct b_bstr *str = arg;
formatter_putchar(str, c); formatter_putchar(str, c);
} }
static enum fx_status bstr_putcs( static enum b_status bstr_putcs(
struct fx_bstr *str, const char *s, size_t len, size_t *nr_written) struct b_bstr *str, const char *s, size_t len, size_t *nr_written)
{ {
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
formatter_putchar(str, s[i]); formatter_putchar(str, s[i]);
@@ -163,10 +163,10 @@ static enum fx_status bstr_putcs(
*nr_written = len; *nr_written = len;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
static enum fx_status bstr_puts(struct fx_bstr *str, const char *s, size_t *nr_written) static enum b_status bstr_puts(struct b_bstr *str, const char *s, size_t *nr_written)
{ {
size_t i; size_t i;
for (i = 0; s[i]; i++) { for (i = 0; s[i]; i++) {
@@ -177,10 +177,10 @@ static enum fx_status bstr_puts(struct fx_bstr *str, const char *s, size_t *nr_w
*nr_written = i; *nr_written = i;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_bstr_push_indent(struct fx_bstr *str, int indent) enum b_status b_bstr_push_indent(struct b_bstr *str, int indent)
{ {
if (!str->bstr_istack) { if (!str->bstr_istack) {
str->bstr_istack = calloc(4, sizeof(int)); str->bstr_istack = calloc(4, sizeof(int));
@@ -193,7 +193,7 @@ enum fx_status fx_bstr_push_indent(struct fx_bstr *str, int indent)
str->bstr_istack, str->bstr_istack,
(str->bstr_istack_size + 4) * sizeof(int)); (str->bstr_istack_size + 4) * sizeof(int));
if (!buf) { if (!buf) {
return FX_ERR_NO_MEMORY; return B_ERR_NO_MEMORY;
} }
str->bstr_istack = buf; str->bstr_istack = buf;
@@ -203,47 +203,47 @@ enum fx_status fx_bstr_push_indent(struct fx_bstr *str, int indent)
int cur_indent = str->bstr_istack[str->bstr_istack_ptr]; int cur_indent = str->bstr_istack[str->bstr_istack_ptr];
str->bstr_istack[++str->bstr_istack_ptr] = cur_indent + indent; str->bstr_istack[++str->bstr_istack_ptr] = cur_indent + indent;
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_bstr_pop_indent(struct fx_bstr *strv) enum b_status b_bstr_pop_indent(struct b_bstr *strv)
{ {
if (strv->bstr_istack_ptr > 0) { if (strv->bstr_istack_ptr > 0) {
strv->bstr_istack_ptr--; strv->bstr_istack_ptr--;
} }
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_bstr_write_char(struct fx_bstr *str, char c) enum b_status b_bstr_write_char(struct b_bstr *str, char c)
{ {
formatter_putchar(str, c); formatter_putchar(str, c);
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_bstr_write_chars( enum b_status b_bstr_write_chars(
struct fx_bstr *str, const char *s, size_t len, size_t *nr_written) struct b_bstr *str, const char *s, size_t len, size_t *nr_written)
{ {
return bstr_putcs(str, s, len, nr_written); return bstr_putcs(str, s, len, nr_written);
} }
enum fx_status fx_bstr_write_cstr(struct fx_bstr *str, const char *s, size_t *nr_written) enum b_status b_bstr_write_cstr(struct b_bstr *str, const char *s, size_t *nr_written)
{ {
return bstr_puts(str, s, nr_written); return bstr_puts(str, s, nr_written);
} }
enum fx_status fx_bstr_write_cstr_list( enum b_status b_bstr_write_cstr_list(
struct fx_bstr *str, const char **strs, size_t *nr_written) struct b_bstr *str, const char **strs, size_t *nr_written)
{ {
size_t w = 0; size_t w = 0;
enum fx_status status = FX_SUCCESS; enum b_status status = B_SUCCESS;
for (size_t i = 0; strs[i]; i++) { for (size_t i = 0; strs[i]; i++) {
size_t tmp = 0; size_t tmp = 0;
status = bstr_puts(str, strs[i], &tmp); status = bstr_puts(str, strs[i], &tmp);
w += tmp; w += tmp;
if (FX_ERR(status)) { if (B_ERR(status)) {
break; break;
} }
} }
@@ -255,10 +255,10 @@ enum fx_status fx_bstr_write_cstr_list(
return status; return status;
} }
enum fx_status fx_bstr_write_cstr_array( enum b_status b_bstr_write_cstr_array(
struct fx_bstr *str, const char **strs, size_t count, size_t *nr_written) struct b_bstr *str, const char **strs, size_t count, size_t *nr_written)
{ {
enum fx_status status = FX_SUCCESS; enum b_status status = B_SUCCESS;
size_t w = 0; size_t w = 0;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
@@ -270,7 +270,7 @@ enum fx_status fx_bstr_write_cstr_array(
status = bstr_puts(str, strs[i], &tmp); status = bstr_puts(str, strs[i], &tmp);
w += tmp; w += tmp;
if (FX_ERR(status)) { if (B_ERR(status)) {
break; break;
} }
} }
@@ -282,20 +282,20 @@ enum fx_status fx_bstr_write_cstr_array(
return status; return status;
} }
enum fx_status fx_bstr_add_many(struct fx_bstr *str, size_t *nr_written, ...) enum b_status b_bstr_add_many(struct b_bstr *str, size_t *nr_written, ...)
{ {
va_list arg; va_list arg;
va_start(arg, nr_written); va_start(arg, nr_written);
const char *s = NULL; const char *s = NULL;
size_t w = 0; size_t w = 0;
enum fx_status status = FX_SUCCESS; enum b_status status = B_SUCCESS;
while ((s = va_arg(arg, const char *))) { while ((s = va_arg(arg, const char *))) {
size_t tmp = 0; size_t tmp = 0;
status = bstr_puts(str, s, &tmp); status = bstr_puts(str, s, &tmp);
w += tmp; w += tmp;
if (FX_ERR(status)) { if (B_ERR(status)) {
break; break;
} }
} }
@@ -307,11 +307,11 @@ enum fx_status fx_bstr_add_many(struct fx_bstr *str, size_t *nr_written, ...)
return status; return status;
} }
enum fx_status fx_bstr_write_rope( enum b_status b_bstr_write_rope(
fx_bstr *strv, const struct fx_rope *rope, size_t *nr_written) b_bstr *strv, const struct b_rope *rope, size_t *nr_written)
{ {
size_t start = strv->bstr_len; size_t start = strv->bstr_len;
enum fx_status status = fx_rope_to_bstr(rope, strv); enum b_status status = b_rope_to_bstr(rope, strv);
size_t end = strv->bstr_len; size_t end = strv->bstr_len;
if (nr_written) { if (nr_written) {
@@ -321,55 +321,55 @@ enum fx_status fx_bstr_write_rope(
return status; return status;
} }
enum fx_status fx_bstr_write_fmt( enum b_status b_bstr_write_fmt(
struct fx_bstr *str, size_t *nr_written, const char *format, ...) struct b_bstr *str, size_t *nr_written, const char *format, ...)
{ {
va_list arg; va_list arg;
va_start(arg, format); va_start(arg, format);
enum fx_status result = fx_bstr_write_vfmt(str, nr_written, format, arg); enum b_status result = b_bstr_write_vfmt(str, nr_written, format, arg);
va_end(arg); va_end(arg);
return result; return result;
} }
enum fx_status fx_bstr_write_vfmt( enum b_status b_bstr_write_vfmt(
struct fx_bstr *str, size_t *nr_written, const char *format, va_list arg) struct b_bstr *str, size_t *nr_written, const char *format, va_list arg)
{ {
size_t start = str->bstr_len; size_t start = str->bstr_len;
z__fx_fctprintf(bstr_fctprintf, str, format, arg); z__b_fctprintf(bstr_fctprintf, str, format, arg);
size_t end = str->bstr_len; size_t end = str->bstr_len;
if (nr_written) { if (nr_written) {
*nr_written = end - start; *nr_written = end - start;
} }
/* TODO update z__fx_fctprintf to support propagating error codes */ /* TODO update z__b_fctprintf to support propagating error codes */
return FX_SUCCESS; return B_SUCCESS;
} }
char *fx_bstr_rope(const struct fx_rope *rope, size_t *nr_written) char *b_bstr_rope(const struct b_rope *rope, size_t *nr_written)
{ {
struct fx_bstr str; struct b_bstr str;
fx_bstr_begin_dynamic(&str); b_bstr_begin_dynamic(&str);
fx_bstr_write_rope(&str, rope, nr_written); b_bstr_write_rope(&str, rope, nr_written);
return fx_bstr_end(&str); return b_bstr_end(&str);
} }
char *fx_bstr_fmt(size_t *nr_written, const char *format, ...) char *b_bstr_fmt(size_t *nr_written, const char *format, ...)
{ {
va_list arg; va_list arg;
va_start(arg, format); va_start(arg, format);
char *s = fx_bstr_vfmt(nr_written, format, arg); char *s = b_bstr_vfmt(nr_written, format, arg);
va_end(arg); va_end(arg);
return s; return s;
} }
char *fx_bstr_vfmt(size_t *nr_written, const char *format, va_list arg) char *b_bstr_vfmt(size_t *nr_written, const char *format, va_list arg)
{ {
struct fx_bstr str; struct b_bstr str;
fx_bstr_begin_dynamic(&str); b_bstr_begin_dynamic(&str);
fx_bstr_write_vfmt(&str, nr_written, format, arg); b_bstr_write_vfmt(&str, nr_written, format, arg);
return fx_bstr_end(&str); return b_bstr_end(&str);
} }

View File

@@ -25,10 +25,10 @@
this file implements an extensible AVL binary tree data structure. this file implements an extensible AVL binary tree data structure.
the primary rule of an AVL binary tree is that for a given node N, the primary rule of an AVL binary tree is that for a given node N,
the heights of N's left and right substs can differ by at most 1. the heights of N's left and right subtrees can differ by at most 1.
the height of a subst is the length of the longest path between the height of a subtree is the length of the longest path between
the root of the subst and a leaf node, including the root node itself. the root of the subtree and a leaf node, including the root node itself.
the height of a leaf node is 1. the height of a leaf node is 1.
@@ -50,45 +50,45 @@
this file intentionally excludes any kind of search function implementation. this file intentionally excludes any kind of search function implementation.
it is up to the programmer to implement their own tree node type it is up to the programmer to implement their own tree node type
using fx_bst_node, and their own search function using fx_bst. using b_btree_node, and their own search function using b_btree.
this allows the programmer to define their own node types with complex this allows the programmer to define their own node types with complex
non-integer key types. bst.h contains a number of macros to help non-integer key types. btree.h contains a number of macros to help
define these functions. the macros do all the work, you just have to define these functions. the macros do all the work, you just have to
provide a comparator function. provide a comparator function.
*/ */
#include <fx/core/bst.h> #include <blue/core/btree.h>
#include <stddef.h> #include <stddef.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define IS_LEFT_CHILD(p, c) ((p) && (c) && ((p)->n_left == (c))) #define IS_LEFT_CHILD(p, c) ((p) && (c) && ((p)->b_left == (c)))
#define IS_RIGHT_CHILD(p, c) ((p) && (c) && ((p)->n_right == (c))) #define IS_RIGHT_CHILD(p, c) ((p) && (c) && ((p)->b_right == (c)))
#define HAS_LEFT_CHILD(x) ((x) && ((x)->n_left)) #define HAS_LEFT_CHILD(x) ((x) && ((x)->b_left))
#define HAS_RIGHT_CHILD(x) ((x) && ((x)->n_right)) #define HAS_RIGHT_CHILD(x) ((x) && ((x)->b_right))
#define HAS_NO_CHILDREN(x) ((x) && (!(x)->n_left) && (!(x)->n_right)) #define HAS_NO_CHILDREN(x) ((x) && (!(x)->b_left) && (!(x)->b_right))
#define HAS_ONE_CHILD(x) \ #define HAS_ONE_CHILD(x) \
((HAS_LEFT_CHILD(x) && !HAS_RIGHT_CHILD(x)) \ ((HAS_LEFT_CHILD(x) && !HAS_RIGHT_CHILD(x)) \
|| (!HAS_LEFT_CHILD(x) && HAS_RIGHT_CHILD(x))) || (!HAS_LEFT_CHILD(x) && HAS_RIGHT_CHILD(x)))
#define HAS_TWO_CHILDREN(x) (HAS_LEFT_CHILD(x) && HAS_RIGHT_CHILD(x)) #define HAS_TWO_CHILDREN(x) (HAS_LEFT_CHILD(x) && HAS_RIGHT_CHILD(x))
#define HEIGHT(x) ((x) ? (x)->n_height : 0) #define HEIGHT(x) ((x) ? (x)->b_height : 0)
struct fx_bst_iterator_p { struct b_btree_iterator_p {
size_t i, depth; size_t i, depth;
fx_bst_node *node; b_btree_node *node;
fx_bst *_b; b_btree *_b;
}; };
static inline void update_height(struct fx_bst_node *x) static inline void update_height(struct b_btree_node *x)
{ {
x->n_height = MAX(HEIGHT(x->n_left), HEIGHT((x->n_right))) + 1; x->b_height = MAX(HEIGHT(x->b_left), HEIGHT((x->b_right))) + 1;
} }
static inline int bf(struct fx_bst_node *x) static inline int bf(struct b_btree_node *x)
{ {
int bf = 0; int bf = 0;
@@ -96,18 +96,18 @@ static inline int bf(struct fx_bst_node *x)
return bf; return bf;
} }
if (x->n_right) { if (x->b_right) {
bf += x->n_right->n_height; bf += x->b_right->b_height;
} }
if (x->n_left) { if (x->b_left) {
bf -= x->n_left->n_height; bf -= x->b_left->b_height;
} }
return bf; return bf;
} }
/* perform a left rotation on a subst /* perform a left rotation on a subtree
if you have a tree like this: if you have a tree like this:
@@ -130,42 +130,42 @@ static inline int bf(struct fx_bst_node *x)
/ \ / \
. . . .
note that this function does NOT update fx_height for the rotated note that this function does NOT update b_height for the rotated
nodes. it is up to you to call update_height_to_root(). nodes. it is up to you to call update_height_to_root().
*/ */
static void rotate_left(struct fx_bst *tree, struct fx_bst_node *x) static void rotate_left(struct b_btree *tree, struct b_btree_node *x)
{ {
struct fx_bst_node *y = x->n_right; struct b_btree_node *y = x->b_right;
struct fx_bst_node *p = x->n_parent; struct b_btree_node *p = x->b_parent;
if (y->n_left) { if (y->b_left) {
y->n_left->n_parent = x; y->b_left->b_parent = x;
} }
x->n_right = y->n_left; x->b_right = y->b_left;
if (!p) { if (!p) {
tree->bst_root = y; tree->b_root = y;
} else if (x == p->n_left) { } else if (x == p->b_left) {
p->n_left = y; p->b_left = y;
} else { } else {
p->n_right = y; p->b_right = y;
} }
x->n_parent = y; x->b_parent = y;
y->n_left = x; y->b_left = x;
y->n_parent = p; y->b_parent = p;
} }
static void update_height_to_root(struct fx_bst_node *x) static void update_height_to_root(struct b_btree_node *x)
{ {
while (x) { while (x) {
update_height(x); update_height(x);
x = x->n_parent; x = x->b_parent;
} }
} }
/* perform a right rotation on a subst /* perform a right rotation on a subtree
if you have a tree like this: if you have a tree like this:
@@ -188,31 +188,31 @@ static void update_height_to_root(struct fx_bst_node *x)
/ \ / \
. . . .
note that this function does NOT update fx_height for the rotated note that this function does NOT update b_height for the rotated
nodes. it is up to you to call update_height_to_root(). nodes. it is up to you to call update_height_to_root().
*/ */
static void rotate_right(struct fx_bst *tree, struct fx_bst_node *y) static void rotate_right(struct b_btree *tree, struct b_btree_node *y)
{ {
struct fx_bst_node *x = y->n_left; struct b_btree_node *x = y->b_left;
struct fx_bst_node *p = y->n_parent; struct b_btree_node *p = y->b_parent;
if (x->n_right) { if (x->b_right) {
x->n_right->n_parent = y; x->b_right->b_parent = y;
} }
y->n_left = x->n_right; y->b_left = x->b_right;
if (!p) { if (!p) {
tree->bst_root = x; tree->b_root = x;
} else if (y == p->n_left) { } else if (y == p->b_left) {
p->n_left = x; p->b_left = x;
} else { } else {
p->n_right = x; p->b_right = x;
} }
y->n_parent = x; y->b_parent = x;
x->n_right = y; x->b_right = y;
x->n_parent = p; x->b_parent = p;
} }
/* for a given node Z, perform a right rotation on Z's right child, /* for a given node Z, perform a right rotation on Z's right child,
@@ -239,13 +239,13 @@ static void rotate_right(struct fx_bst *tree, struct fx_bst_node *y)
. . . . . . . .
note that, unlike rotate_left and rotate_right, this function note that, unlike rotate_left and rotate_right, this function
DOES update fx_height for the rotated nodes (since it needs to be DOES update b_height for the rotated nodes (since it needs to be
done in a certain order). done in a certain order).
*/ */
static void rotate_double_left(struct fx_bst *tree, struct fx_bst_node *z) static void rotate_double_left(struct b_btree *tree, struct b_btree_node *z)
{ {
struct fx_bst_node *x = z->n_right; struct b_btree_node *x = z->b_right;
struct fx_bst_node *y = x->n_left; struct b_btree_node *y = x->b_left;
rotate_right(tree, x); rotate_right(tree, x);
rotate_left(tree, z); rotate_left(tree, z);
@@ -255,7 +255,7 @@ static void rotate_double_left(struct fx_bst *tree, struct fx_bst_node *z)
while (y) { while (y) {
update_height(y); update_height(y);
y = y->n_parent; y = y->b_parent;
} }
} }
@@ -283,13 +283,13 @@ static void rotate_double_left(struct fx_bst *tree, struct fx_bst_node *z)
. . . . . . . .
note that, unlike rotate_left and rotate_right, this function note that, unlike rotate_left and rotate_right, this function
DOES update fx_height for the rotated nodes (since it needs to be DOES update b_height for the rotated nodes (since it needs to be
done in a certain order). done in a certain order).
*/ */
static void rotate_double_right(struct fx_bst *tree, struct fx_bst_node *z) static void rotate_double_right(struct b_btree *tree, struct b_btree_node *z)
{ {
struct fx_bst_node *x = z->n_left; struct b_btree_node *x = z->b_left;
struct fx_bst_node *y = x->n_right; struct b_btree_node *y = x->b_right;
rotate_left(tree, x); rotate_left(tree, x);
rotate_right(tree, z); rotate_right(tree, z);
@@ -299,25 +299,25 @@ static void rotate_double_right(struct fx_bst *tree, struct fx_bst_node *z)
while (y) { while (y) {
update_height(y); update_height(y);
y = y->n_parent; y = y->b_parent;
} }
} }
/* run after an insert operation. checks that the balance factor /* run after an insert operation. checks that the balance factor
of the local subst is within the range -1 <= BF <= 1. if it of the local subtree is within the range -1 <= BF <= 1. if it
is not, rotate the subst to restore balance. is not, rotate the subtree to restore balance.
note that at most one rotation should be required after a node note that at most one rotation should be required after a node
is inserted into the tree. is inserted into the tree.
this function depends on all nodes in the tree having this function depends on all nodes in the tree having
correct fx_height values. correct b_height values.
@param w the node that was just inserted into the tree @param w the node that was just inserted into the tree
*/ */
static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w) static void insert_fixup(struct b_btree *tree, struct b_btree_node *w)
{ {
struct fx_bst_node *z = NULL, *y = NULL, *x = NULL; struct b_btree_node *z = NULL, *y = NULL, *x = NULL;
z = w; z = w;
while (z) { while (z) {
@@ -344,19 +344,19 @@ static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w)
next_ancestor: next_ancestor:
x = y; x = y;
y = z; y = z;
z = z->n_parent; z = z->b_parent;
} }
} }
/* run after a delete operation. checks that the balance factor /* run after a delete operation. checks that the balance factor
of the local subst is within the range -1 <= BF <= 1. if it of the local subtree is within the range -1 <= BF <= 1. if it
is not, rotate the subst to restore balance. is not, rotate the subtree to restore balance.
note that, unlike insert_fixup, multiple rotations may be required note that, unlike insert_fixup, multiple rotations may be required
to restore balance after a node is deleted. to restore balance after a node is deleted.
this function depends on all nodes in the tree having this function depends on all nodes in the tree having
correct fx_height values. correct b_height values.
@param w one of the following: @param w one of the following:
- the parent of the node that was deleted if the node - the parent of the node that was deleted if the node
@@ -366,20 +366,20 @@ static void insert_fixup(struct fx_bst *tree, struct fx_bst_node *w)
- the node that replaced the node that was deleted, if - the node that replaced the node that was deleted, if
the node that was deleted had one child. the node that was deleted had one child.
*/ */
static void delete_fixup(struct fx_bst *tree, struct fx_bst_node *w) static void delete_fixup(struct b_btree *tree, struct b_btree_node *w)
{ {
struct fx_bst_node *z = w; struct b_btree_node *z = w;
while (z) { while (z) {
if (bf(z) > 1) { if (bf(z) > 1) {
if (bf(z->n_right) >= 0) { if (bf(z->b_right) >= 0) {
rotate_left(tree, z); rotate_left(tree, z);
update_height_to_root(z); update_height_to_root(z);
} else { } else {
rotate_double_left(tree, z); rotate_double_left(tree, z);
} }
} else if (bf(z) < -1) { } else if (bf(z) < -1) {
if (bf(z->n_left) <= 0) { if (bf(z->b_left) <= 0) {
rotate_right(tree, z); rotate_right(tree, z);
update_height_to_root(z); update_height_to_root(z);
} else { } else {
@@ -387,23 +387,23 @@ static void delete_fixup(struct fx_bst *tree, struct fx_bst_node *w)
} }
} }
z = z->n_parent; z = z->b_parent;
} }
} }
/* updates fx_height for all nodes between the inserted node and the root /* updates b_height for all nodes between the inserted node and the root
of the tree, and calls insert_fixup. of the tree, and calls insert_fixup.
@param node the node that was just inserted into the tree. @param node the node that was just inserted into the tree.
*/ */
void fx_bst_insert_fixup(struct fx_bst *tree, struct fx_bst_node *node) void b_btree_insert_fixup(struct b_btree *tree, struct b_btree_node *node)
{ {
node->n_height = 0; node->b_height = 0;
struct fx_bst_node *cur = node; struct b_btree_node *cur = node;
while (cur) { while (cur) {
update_height(cur); update_height(cur);
cur = cur->n_parent; cur = cur->b_parent;
} }
insert_fixup(tree, node); insert_fixup(tree, node);
@@ -414,28 +414,28 @@ void fx_bst_insert_fixup(struct fx_bst *tree, struct fx_bst_node *node)
this function assumes that `node` has no children, and therefore this function assumes that `node` has no children, and therefore
doesn't need to be replaced. doesn't need to be replaced.
updates fx_height for all nodes between `node` and the tree root. updates b_height for all nodes between `node` and the tree root.
@param node the node to delete. @param node the node to delete.
*/ */
static struct fx_bst_node *remove_node_with_no_children( static struct b_btree_node *remove_node_with_no_children(
struct fx_bst *tree, struct fx_bst_node *node) struct b_btree *tree, struct b_btree_node *node)
{ {
struct fx_bst_node *w = node->n_parent; struct b_btree_node *w = node->b_parent;
struct fx_bst_node *p = node->n_parent; struct b_btree_node *p = node->b_parent;
node->n_parent = NULL; node->b_parent = NULL;
if (!p) { if (!p) {
tree->bst_root = NULL; tree->b_root = NULL;
} else if (IS_LEFT_CHILD(p, node)) { } else if (IS_LEFT_CHILD(p, node)) {
p->n_left = NULL; p->b_left = NULL;
} else { } else {
p->n_right = NULL; p->b_right = NULL;
} }
while (p) { while (p) {
update_height(p); update_height(p);
p = p->n_parent; p = p->b_parent;
} }
return w; return w;
@@ -446,40 +446,40 @@ static struct fx_bst_node *remove_node_with_no_children(
this function assumes that `node` has one child. this function assumes that `node` has one child.
the child of `node` is inherited by `node`'s parent, and `node` is removed. the child of `node` is inherited by `node`'s parent, and `node` is removed.
updates fx_height for all nodes between the node that replaced updates b_height for all nodes between the node that replaced
`node` and the tree root. `node` and the tree root.
@param node the node to delete. @param node the node to delete.
*/ */
static struct fx_bst_node *replace_node_with_one_subst( static struct b_btree_node *replace_node_with_one_subtree(
struct fx_bst *tree, struct fx_bst_node *node) struct b_btree *tree, struct b_btree_node *node)
{ {
struct fx_bst_node *p = node->n_parent; struct b_btree_node *p = node->b_parent;
struct fx_bst_node *z = NULL; struct b_btree_node *z = NULL;
if (HAS_LEFT_CHILD(node)) { if (HAS_LEFT_CHILD(node)) {
z = node->n_left; z = node->b_left;
} else { } else {
z = node->n_right; z = node->b_right;
} }
struct fx_bst_node *w = z; struct b_btree_node *w = z;
if (!p) { if (!p) {
tree->bst_root = z; tree->b_root = z;
} else if (IS_LEFT_CHILD(p, node)) { } else if (IS_LEFT_CHILD(p, node)) {
p->n_left = z; p->b_left = z;
} else if (IS_RIGHT_CHILD(p, node)) { } else if (IS_RIGHT_CHILD(p, node)) {
p->n_right = z; p->b_right = z;
} }
z->n_parent = p; z->b_parent = p;
node->n_parent = NULL; node->b_parent = NULL;
node->n_left = node->n_right = NULL; node->b_left = node->b_right = NULL;
while (z) { while (z) {
update_height(z); update_height(z);
z = z->n_parent; z = z->b_parent;
} }
return w; return w;
@@ -495,100 +495,100 @@ static struct fx_bst_node *replace_node_with_one_subst(
if Y has a child (it will never have more than one), have Y's parent inherit if Y has a child (it will never have more than one), have Y's parent inherit
Y's child. Y's child.
updates fx_height for all nodes between the deepest node that was modified updates b_height for all nodes between the deepest node that was modified
and the tree root. and the tree root.
@param z the node to delete. @param z the node to delete.
*/ */
static struct fx_bst_node *replace_node_with_two_substs( static struct b_btree_node *replace_node_with_two_subtrees(
struct fx_bst *tree, struct fx_bst_node *z) struct b_btree *tree, struct b_btree_node *z)
{ {
/* x will replace z */ /* x will replace z */
struct fx_bst_node *x = z->n_left; struct b_btree_node *x = z->b_left;
while (x->n_right) { while (x->b_right) {
x = x->n_right; x = x->b_right;
} }
/* y is the node that will replace x (if x has a left child) */ /* y is the node that will replace x (if x has a left child) */
struct fx_bst_node *y = x->n_left; struct b_btree_node *y = x->b_left;
/* w is the starting point for the height update and fixup */ /* w is the starting point for the height update and fixup */
struct fx_bst_node *w = x; struct b_btree_node *w = x;
if (w->n_parent != z) { if (w->b_parent != z) {
w = w->n_parent; w = w->b_parent;
} }
if (y) { if (y) {
w = y; w = y;
} }
if (IS_LEFT_CHILD(x->n_parent, x)) { if (IS_LEFT_CHILD(x->b_parent, x)) {
x->n_parent->n_left = y; x->b_parent->b_left = y;
} else if (IS_RIGHT_CHILD(x->n_parent, x)) { } else if (IS_RIGHT_CHILD(x->b_parent, x)) {
x->n_parent->n_right = y; x->b_parent->b_right = y;
} }
if (y) { if (y) {
y->n_parent = x->n_parent; y->b_parent = x->b_parent;
} }
if (IS_LEFT_CHILD(z->n_parent, z)) { if (IS_LEFT_CHILD(z->b_parent, z)) {
z->n_parent->n_left = x; z->b_parent->b_left = x;
} else if (IS_RIGHT_CHILD(z->n_parent, z)) { } else if (IS_RIGHT_CHILD(z->b_parent, z)) {
z->n_parent->n_right = x; z->b_parent->b_right = x;
} }
x->n_parent = z->n_parent; x->b_parent = z->b_parent;
x->n_left = z->n_left; x->b_left = z->b_left;
x->n_right = z->n_right; x->b_right = z->b_right;
if (x->n_left) { if (x->b_left) {
x->n_left->n_parent = x; x->b_left->b_parent = x;
} }
if (x->n_right) { if (x->b_right) {
x->n_right->n_parent = x; x->b_right->b_parent = x;
} }
if (!x->n_parent) { if (!x->b_parent) {
tree->bst_root = x; tree->b_root = x;
} }
struct fx_bst_node *cur = w; struct b_btree_node *cur = w;
while (cur) { while (cur) {
update_height(cur); update_height(cur);
cur = cur->n_parent; cur = cur->b_parent;
} }
return w; return w;
} }
/* delete a node from the tree and re-balance it afterwards */ /* delete a node from the tree and re-balance it afterwards */
void fx_bst_delete(struct fx_bst *tree, struct fx_bst_node *node) void b_btree_delete(struct b_btree *tree, struct b_btree_node *node)
{ {
struct fx_bst_node *w = NULL; struct b_btree_node *w = NULL;
if (HAS_NO_CHILDREN(node)) { if (HAS_NO_CHILDREN(node)) {
w = remove_node_with_no_children(tree, node); w = remove_node_with_no_children(tree, node);
} else if (HAS_ONE_CHILD(node)) { } else if (HAS_ONE_CHILD(node)) {
w = replace_node_with_one_subst(tree, node); w = replace_node_with_one_subtree(tree, node);
} else if (HAS_TWO_CHILDREN(node)) { } else if (HAS_TWO_CHILDREN(node)) {
w = replace_node_with_two_substs(tree, node); w = replace_node_with_two_subtrees(tree, node);
} }
if (w) { if (w) {
delete_fixup(tree, w); delete_fixup(tree, w);
} }
node->n_left = node->n_right = node->n_parent = NULL; node->b_left = node->b_right = node->b_parent = NULL;
} }
static struct fx_bst_node *first_node(const struct fx_bst *tree, int *depth) static struct b_btree_node *first_node(const struct b_btree *tree, int *depth)
{ {
/* the first node in the tree is the node with the smallest key. /* the first node in the tree is the node with the smallest key.
we keep moving left until we can't go any further */ we keep moving left until we can't go any further */
struct fx_bst_node *cur = tree->bst_root; struct b_btree_node *cur = tree->b_root;
int d = 0; int d = 0;
if (!cur) { if (!cur) {
@@ -596,47 +596,47 @@ static struct fx_bst_node *first_node(const struct fx_bst *tree, int *depth)
return NULL; return NULL;
} }
while (cur->n_left) { while (cur->b_left) {
d++; d++;
cur = cur->n_left; cur = cur->b_left;
} }
*depth = d; *depth = d;
return cur; return cur;
} }
struct fx_bst_node *fx_bst_first(const struct fx_bst *tree) struct b_btree_node *b_btree_first(const struct b_btree *tree)
{ {
int d; int d;
return first_node(tree, &d); return first_node(tree, &d);
} }
static struct fx_bst_node *last_node(const struct fx_bst *tree, int *depth) static struct b_btree_node *last_node(const struct b_btree *tree, int *depth)
{ {
/* the first node in the tree is the node with the largest key. /* the first node in the tree is the node with the largest key.
we keep moving right until we can't go any further */ we keep moving right until we can't go any further */
struct fx_bst_node *cur = tree->bst_root; struct b_btree_node *cur = tree->b_root;
int d = 0; int d = 0;
if (!cur) { if (!cur) {
return NULL; return NULL;
} }
while (cur->n_right) { while (cur->b_right) {
d++; d++;
cur = cur->n_right; cur = cur->b_right;
} }
*depth = d; *depth = d;
return cur; return cur;
} }
fx_bst_node *fx_bst_last(const struct fx_bst *tree) b_btree_node *b_btree_last(const struct b_btree *tree)
{ {
int d; int d;
return last_node(tree, &d); return last_node(tree, &d);
} }
static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff) static b_btree_node *next_node(const struct b_btree_node *node, int *depth_diff)
{ {
if (!node) { if (!node) {
return NULL; return NULL;
@@ -648,18 +648,18 @@ static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff)
1. if `node` has a right sub-tree, every node in this sub-tree is 1. if `node` has a right sub-tree, every node in this sub-tree is
bigger than node. the in-order successor of `node` is the smallest bigger than node. the in-order successor of `node` is the smallest
node in this subst. node in this subtree.
2. if `node` has no right sub-tree, we've reached the largest node in 2. if `node` has no right sub-tree, we've reached the largest node in
the sub-tree rooted at `node`. we need to go back to our parent the sub-tree rooted at `node`. we need to go back to our parent
and continue the search elsewhere. and continue the search elsewhere.
*/ */
if (node->n_right) { if (node->b_right) {
/* case 1: step into `node`'s right sub-tree and keep going /* case 1: step into `node`'s right sub-tree and keep going
left to find the smallest node */ left to find the smallest node */
struct fx_bst_node *cur = node->n_right; struct b_btree_node *cur = node->b_right;
depth++; depth++;
while (cur->n_left) { while (cur->b_left) {
cur = cur->n_left; cur = cur->b_left;
depth++; depth++;
} }
@@ -671,16 +671,16 @@ static fx_bst_node *next_node(const struct fx_bst_node *node, int *depth_diff)
if we encounter a step where we are our parent's left child, if we encounter a step where we are our parent's left child,
we've found a parent with a value larger than us. this parent we've found a parent with a value larger than us. this parent
is the in-order successor of `node` */ is the in-order successor of `node` */
while (node->n_parent && node->n_parent->n_left != node) { while (node->b_parent && node->b_parent->b_left != node) {
node = node->n_parent; node = node->b_parent;
depth--; depth--;
} }
*depth_diff = depth - 1; *depth_diff = depth - 1;
return node->n_parent; return node->b_parent;
} }
static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff) static b_btree_node *prev_node(const struct b_btree_node *node, int *depth_diff)
{ {
if (!node) { if (!node) {
return NULL; return NULL;
@@ -692,18 +692,18 @@ static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff)
1. if `node` has a left sub-tree, every node in this sub-tree is 1. if `node` has a left sub-tree, every node in this sub-tree is
smaller than `node`. the in-order predecessor of `node` is the smaller than `node`. the in-order predecessor of `node` is the
largest node in this subst. largest node in this subtree.
2. if `node` has no left sub-tree, we've reached the smallest node in 2. if `node` has no left sub-tree, we've reached the smallest node in
the sub-tree rooted at `node`. we need to go back to our parent the sub-tree rooted at `node`. we need to go back to our parent
and continue the search elsewhere. and continue the search elsewhere.
*/ */
if (node->n_left) { if (node->b_left) {
/* case 1: step into `node`'s left sub-tree and keep going /* case 1: step into `node`'s left sub-tree and keep going
right to find the largest node */ right to find the largest node */
fx_bst_node *cur = node->n_left; b_btree_node *cur = node->b_left;
depth++; depth++;
while (cur->n_right) { while (cur->b_right) {
cur = cur->n_right; cur = cur->b_right;
depth++; depth++;
} }
@@ -715,65 +715,65 @@ static fx_bst_node *prev_node(const struct fx_bst_node *node, int *depth_diff)
if we encounter a step where we are our parent's right child, if we encounter a step where we are our parent's right child,
we've found a parent with a value smaller than us. this parent we've found a parent with a value smaller than us. this parent
is the in-order predecessor of `node`. */ is the in-order predecessor of `node`. */
while (node->n_parent && node->n_parent->n_right != node) { while (node->b_parent && node->b_parent->b_right != node) {
node = node->n_parent; node = node->b_parent;
depth--; depth--;
} }
*depth_diff = depth - 1; *depth_diff = depth - 1;
return node->n_parent; return node->b_parent;
} }
fx_bst_node *fx_bst_next(const struct fx_bst_node *node) b_btree_node *b_btree_next(const struct b_btree_node *node)
{ {
int d; int d;
return next_node(node, &d); return next_node(node, &d);
} }
fx_bst_node *fx_bst_prev(const struct fx_bst_node *node) b_btree_node *b_btree_prev(const struct b_btree_node *node)
{ {
int d; int d;
return prev_node(node, &d); return prev_node(node, &d);
} }
void fx_bst_move( void b_btree_move(
struct fx_bst *tree, struct fx_bst_node *dest, struct fx_bst_node *src) struct b_btree *tree, struct b_btree_node *dest, struct b_btree_node *src)
{ {
if (src->n_parent) { if (src->b_parent) {
if (src->n_parent->n_left == src) { if (src->b_parent->b_left == src) {
src->n_parent->n_left = dest; src->b_parent->b_left = dest;
} else { } else {
src->n_parent->n_right = dest; src->b_parent->b_right = dest;
} }
} }
if (src->n_left) { if (src->b_left) {
src->n_left->n_parent = dest; src->b_left->b_parent = dest;
} }
if (src->n_right) { if (src->b_right) {
src->n_right->n_parent = dest; src->b_right->b_parent = dest;
} }
if (tree->bst_root == src) { if (tree->b_root == src) {
tree->bst_root = dest; tree->b_root = dest;
} }
memmove(dest, src, sizeof *src); memmove(dest, src, sizeof *src);
} }
fx_iterator *fx_bst_begin(struct fx_bst *tree) b_iterator *b_btree_begin(struct b_btree *tree)
{ {
fx_iterator *it_obj = fx_object_create(FX_TYPE_BST_ITERATOR); b_iterator *it_obj = b_object_create(B_TYPE_BTREE_ITERATOR);
if (!it_obj) { if (!it_obj) {
return NULL; return NULL;
} }
struct fx_bst_iterator_p *it struct b_btree_iterator_p *it
= fx_object_get_private(it_obj, FX_TYPE_BST_ITERATOR); = b_object_get_private(it_obj, B_TYPE_BTREE_ITERATOR);
int depth = 0; int depth = 0;
it->_b = (struct fx_bst *)tree; it->_b = (struct b_btree *)tree;
it->i = 0; it->i = 0;
it->node = first_node(tree, &depth); it->node = first_node(tree, &depth);
it->depth = depth; it->depth = depth;
@@ -781,18 +781,18 @@ fx_iterator *fx_bst_begin(struct fx_bst *tree)
return it_obj; return it_obj;
} }
const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree) const b_iterator *b_btree_cbegin(const struct b_btree *tree)
{ {
fx_iterator *it_obj = fx_object_create(FX_TYPE_BST_ITERATOR); b_iterator *it_obj = b_object_create(B_TYPE_BTREE_ITERATOR);
if (!it_obj) { if (!it_obj) {
return NULL; return NULL;
} }
struct fx_bst_iterator_p *it struct b_btree_iterator_p *it
= fx_object_get_private(it_obj, FX_TYPE_BST_ITERATOR); = b_object_get_private(it_obj, B_TYPE_BTREE_ITERATOR);
int depth = 0; int depth = 0;
it->_b = (struct fx_bst *)tree; it->_b = (struct b_btree *)tree;
it->i = 0; it->i = 0;
it->node = first_node(tree, &depth); it->node = first_node(tree, &depth);
it->depth = depth; it->depth = depth;
@@ -800,13 +800,13 @@ const fx_iterator *fx_bst_cbegin(const struct fx_bst *tree)
return it_obj; return it_obj;
} }
static enum fx_status iterator_move_next(const fx_iterator *obj) static enum b_status iterator_move_next(const b_iterator *obj)
{ {
struct fx_bst_iterator_p *it struct b_btree_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR); = b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
int depth_diff = 0; int depth_diff = 0;
struct fx_bst_node *next = next_node(it->node, &depth_diff); struct b_btree_node *next = next_node(it->node, &depth_diff);
if (!next) { if (!next) {
it->node = NULL; it->node = NULL;
@@ -821,19 +821,19 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
return true; return true;
} }
static enum fx_status iterator_erase(fx_iterator *obj) static enum b_status iterator_erase(b_iterator *obj)
{ {
struct fx_bst_iterator_p *it struct b_btree_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR); = b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
if (!it->node) { if (!it->node) {
return FX_ERR_OUT_OF_BOUNDS; return B_ERR_OUT_OF_BOUNDS;
} }
int depth_diff = 0; int depth_diff = 0;
struct fx_bst_node *next = next_node(it->node, &depth_diff); struct b_btree_node *next = next_node(it->node, &depth_diff);
fx_bst_delete(it->_b, it->node); b_btree_delete(it->_b, it->node);
if (!next) { if (!next) {
it->node = NULL; it->node = NULL;
it->depth = 0; it->depth = 0;
@@ -841,51 +841,51 @@ static enum fx_status iterator_erase(fx_iterator *obj)
it->node = next; it->node = next;
it->depth = 0; it->depth = 0;
struct fx_bst_node *cur = next->n_parent; struct b_btree_node *cur = next->b_parent;
while (cur) { while (cur) {
it->depth++; it->depth++;
cur = cur->n_parent; cur = cur->b_parent;
} }
} }
return FX_SUCCESS; return B_SUCCESS;
} }
static fx_iterator_value iterator_get_value(fx_iterator *obj) static b_iterator_value iterator_get_value(b_iterator *obj)
{ {
struct fx_bst_iterator_p *it struct b_btree_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR); = b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
return FX_ITERATOR_VALUE_PTR(it->node); return B_ITERATOR_VALUE_PTR(it->node);
} }
static const fx_iterator_value iterator_get_cvalue(const fx_iterator *obj) static const b_iterator_value iterator_get_cvalue(const b_iterator *obj)
{ {
struct fx_bst_iterator_p *it struct b_btree_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_BST_ITERATOR); = b_object_get_private(obj, B_TYPE_BTREE_ITERATOR);
return FX_ITERATOR_VALUE_CPTR(it->node); return B_ITERATOR_VALUE_CPTR(it->node);
} }
/*** CLASS DEFINITION *********************************************************/ /*** CLASS DEFINITION *********************************************************/
// ---- fx_bst_iterator DEFINITION // ---- b_btree_iterator DEFINITION
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_bst_iterator) B_TYPE_CLASS_DEFINITION_BEGIN(b_btree_iterator)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL; B_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT) B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_iterator, FX_TYPE_ITERATOR) B_TYPE_CLASS_INTERFACE_BEGIN(b_iterator, B_TYPE_ITERATOR)
FX_INTERFACE_ENTRY(it_move_next) = iterator_move_next; B_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
FX_INTERFACE_ENTRY(it_erase) = iterator_erase; B_INTERFACE_ENTRY(it_erase) = iterator_erase;
FX_INTERFACE_ENTRY(it_get_value) = iterator_get_value; B_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
FX_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue; B_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
FX_TYPE_CLASS_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR) B_TYPE_CLASS_INTERFACE_END(b_iterator, B_TYPE_ITERATOR)
FX_TYPE_CLASS_DEFINITION_END(fx_bst_iterator) B_TYPE_CLASS_DEFINITION_END(b_btree_iterator)
FX_TYPE_DEFINITION_BEGIN(fx_bst_iterator) B_TYPE_DEFINITION_BEGIN(b_btree_iterator)
FX_TYPE_ID(0x432779d7, 0xc03a, 0x48ea, 0xae8f, 0x12c666c767ae); B_TYPE_ID(0x432779d7, 0xc03a, 0x48ea, 0xae8f, 0x12c666c767ae);
FX_TYPE_EXTENDS(FX_TYPE_ITERATOR); B_TYPE_EXTENDS(B_TYPE_ITERATOR);
FX_TYPE_CLASS(fx_bst_iterator_class); B_TYPE_CLASS(b_btree_iterator_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_bst_iterator_p); B_TYPE_INSTANCE_PRIVATE(struct b_btree_iterator_p);
FX_TYPE_DEFINITION_END(fx_bst_iterator) B_TYPE_DEFINITION_END(b_btree_iterator)

View File

@@ -3,13 +3,13 @@
#include "type.h" #include "type.h"
#include <assert.h> #include <assert.h>
#include <fx/core/class.h> #include <blue/core/class.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
void *fx_class_get(fx_type id) void *b_class_get(b_type id)
{ {
struct fx_type_registration *r = fx_type_get_registration(id); struct b_type_registration *r = b_type_get_registration(id);
if (!r) { if (!r) {
return NULL; return NULL;
} }
@@ -17,28 +17,28 @@ void *fx_class_get(fx_type id)
return r->r_class; return r->r_class;
} }
const char *fx_class_get_name(const struct _fx_class *c) const char *b_class_get_name(const struct _b_class *c)
{ {
if (!c) { if (!c) {
return NULL; return NULL;
} }
assert(c->c_magic == FX_CLASS_MAGIC); assert(c->c_magic == B_CLASS_MAGIC);
return c->c_type->r_info->t_name; return c->c_type->r_info->t_name;
} }
void *fx_class_get_interface(const struct _fx_class *c, const union fx_type *id) void *b_class_get_interface(const struct _b_class *c, const union b_type_id *id)
{ {
if (!c) { if (!c) {
return NULL; return NULL;
} }
assert(c->c_magic == FX_CLASS_MAGIC); assert(c->c_magic == B_CLASS_MAGIC);
const struct fx_type_registration *type_reg = c->c_type; const struct b_type_registration *type_reg = c->c_type;
struct fx_type_component *comp struct b_type_component *comp
= fx_type_get_component(&type_reg->r_components, id); = b_type_get_component(&type_reg->r_components, id);
if (!comp) { if (!comp) {
return NULL; return NULL;
@@ -47,33 +47,33 @@ void *fx_class_get_interface(const struct _fx_class *c, const union fx_type *id)
return (char *)c + comp->c_class_data_offset; return (char *)c + comp->c_class_data_offset;
} }
fx_result fx_class_instantiate( b_result b_class_instantiate(
struct fx_type_registration *type, struct _fx_class **out_class) struct b_type_registration *type, struct _b_class **out_class)
{ {
struct _fx_class *out = malloc(type->r_class_size); struct _b_class *out = malloc(type->r_class_size);
if (!out) { if (!out) {
return FX_RESULT_ERR(NO_MEMORY); return B_RESULT_ERR(NO_MEMORY);
} }
memset(out, 0x0, type->r_class_size); memset(out, 0x0, type->r_class_size);
out->c_magic = FX_CLASS_MAGIC; out->c_magic = B_CLASS_MAGIC;
out->c_type = type; out->c_type = type;
struct fx_queue_entry *entry = fx_queue_first(&type->r_class_hierarchy); struct b_queue_entry *entry = b_queue_first(&type->r_class_hierarchy);
while (entry) { while (entry) {
struct fx_type_component *comp struct b_type_component *comp
= fx_unbox(struct fx_type_component, entry, c_entry); = b_unbox(struct b_type_component, entry, c_entry);
const struct fx_type_info *class_info = comp->c_type->r_info; const struct b_type_info *class_info = comp->c_type->r_info;
void *class_data = (char *)out + comp->c_class_data_offset; void *class_data = (char *)out + comp->c_class_data_offset;
if (class_info->t_class_init) { if (class_info->t_class_init) {
class_info->t_class_init(out, class_data); class_info->t_class_init(out, class_data);
} }
entry = fx_queue_next(entry); entry = b_queue_next(entry);
} }
*out_class = out; *out_class = out;
return FX_RESULT_SUCCESS; return B_RESULT_SUCCESS;
} }

View File

@@ -1,18 +1,18 @@
#ifndef _CLASS_H_ #ifndef _CLASS_H_
#define _CLASS_H_ #define _CLASS_H_
#include <fx/core/error.h> #include <blue/core/error.h>
#include <fx/core/misc.h> #include <blue/core/misc.h>
#include <stdint.h> #include <stdint.h>
struct fx_type_registration; struct b_type_registration;
struct _fx_class { struct _b_class {
uint64_t c_magic; uint64_t c_magic;
const struct fx_type_registration *c_type; const struct b_type_registration *c_type;
}; };
extern fx_result fx_class_instantiate( extern b_result b_class_instantiate(
struct fx_type_registration *type, struct _fx_class **out); struct b_type_registration *type, struct _b_class **out);
#endif #endif

View File

@@ -1,12 +1,12 @@
#include <fx/core/encoding.h> #include <blue/core/encoding.h>
#include <wctype.h> #include <wctype.h>
bool fx_wchar_is_number(fx_wchar c) bool b_wchar_is_number(b_wchar c)
{ {
return iswnumber((wchar_t)c); return iswnumber((wchar_t)c);
} }
bool fx_wchar_is_alpha(fx_wchar c) bool b_wchar_is_alpha(b_wchar c)
{ {
if (c == 0) { if (c == 0) {
return false; return false;
@@ -1177,28 +1177,28 @@ bool fx_wchar_is_alpha(fx_wchar c)
} }
} }
bool fx_wchar_is_hex_digit(fx_wchar c) bool b_wchar_is_hex_digit(b_wchar c)
{ {
return isxdigit(c); return isxdigit(c);
} }
bool fx_wchar_is_space(fx_wchar c) bool b_wchar_is_space(b_wchar c)
{ {
return iswspace((wchar_t)c); return iswspace((wchar_t)c);
} }
bool fx_wchar_is_punct(fx_wchar c) bool b_wchar_is_punct(b_wchar c)
{ {
return iswpunct((wchar_t)c); return iswpunct((wchar_t)c);
} }
bool fx_wchar_utf8_is_valid_scalar(fx_wchar c) bool b_wchar_utf8_is_valid_scalar(b_wchar c)
{ {
return (((c) >= 0x0000 && (c) <= 0xD7FF) return (((c) >= 0x0000 && (c) <= 0xD7FF)
|| ((c) >= 0xE000 && (c) <= 0x10FFFF)); || ((c) >= 0xE000 && (c) <= 0x10FFFF));
} }
unsigned int fx_wchar_utf8_header_decode(char c) unsigned int b_wchar_utf8_header_decode(char c)
{ {
unsigned int len = 0; unsigned int len = 0;
@@ -1217,9 +1217,9 @@ unsigned int fx_wchar_utf8_header_decode(char c)
return len; return len;
} }
unsigned int fx_wchar_utf8_codepoint_size(fx_wchar c) unsigned int b_wchar_utf8_codepoint_size(b_wchar c)
{ {
if (!fx_wchar_utf8_is_valid_scalar(c)) { if (!b_wchar_utf8_is_valid_scalar(c)) {
return 0; return 0;
} }
@@ -1251,9 +1251,9 @@ static int32_t decode_utf8_trailer_byte(char c)
return c & 0x3F; return c & 0x3F;
} }
fx_wchar fx_wchar_utf8_codepoint_decode(const char *s) b_wchar b_wchar_utf8_codepoint_decode(const char *s)
{ {
fx_wchar result = 0; b_wchar result = 0;
int len = 0; int len = 0;
if (!(s[0] & 0x80)) { if (!(s[0] & 0x80)) {
@@ -1272,29 +1272,29 @@ fx_wchar fx_wchar_utf8_codepoint_decode(const char *s)
result = s[0] & 0x07; result = s[0] & 0x07;
result <<= 18; result <<= 18;
} else { } else {
return FX_WCHAR_INVALID; return B_WCHAR_INVALID;
} }
for (int i = 1; i < len; i++) { for (int i = 1; i < len; i++) {
int32_t c = decode_utf8_trailer_byte(s[i]); int32_t c = decode_utf8_trailer_byte(s[i]);
if (c == -1) { if (c == -1) {
return FX_WCHAR_INVALID; return B_WCHAR_INVALID;
} }
c <<= 6 * (len - i - 1); c <<= 6 * (len - i - 1);
result |= c; result |= c;
} }
if (!fx_wchar_utf8_is_valid_scalar(result)) { if (!b_wchar_utf8_is_valid_scalar(result)) {
return FX_WCHAR_INVALID; return B_WCHAR_INVALID;
} }
return result; return result;
} }
unsigned int fx_wchar_utf8_codepoint_encode(fx_wchar c, char s[4]) unsigned int b_wchar_utf8_codepoint_encode(b_wchar c, char s[4])
{ {
unsigned int len = fx_wchar_utf8_codepoint_size(c); unsigned int len = b_wchar_utf8_codepoint_size(c);
switch (len) { switch (len) {
case 1: case 1:
@@ -1322,7 +1322,7 @@ unsigned int fx_wchar_utf8_codepoint_encode(fx_wchar c, char s[4])
return len; return len;
} }
unsigned int fx_wchar_utf8_codepoint_stride(const char *s) unsigned int b_wchar_utf8_codepoint_stride(const char *s)
{ {
char c = *s; char c = *s;
@@ -1345,13 +1345,13 @@ unsigned int fx_wchar_utf8_codepoint_stride(const char *s)
return 0; return 0;
} }
size_t fx_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes) size_t b_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes)
{ {
size_t nr_codepoints = 0; size_t nr_codepoints = 0;
const char *end = s + nr_bytes; const char *end = s + nr_bytes;
while (*s && s < end) { while (*s && s < end) {
size_t stride = fx_wchar_utf8_codepoint_stride(s); size_t stride = b_wchar_utf8_codepoint_stride(s);
if (stride == 0) { if (stride == 0) {
/* invalid codepoint */ /* invalid codepoint */
return 0; return 0;
@@ -1364,11 +1364,11 @@ size_t fx_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes)
return nr_codepoints; return nr_codepoints;
} }
size_t fx_wchar_utf8_string_encoded_size(const fx_wchar *s, size_t nr_codepoints) size_t b_wchar_utf8_string_encoded_size(const b_wchar *s, size_t nr_codepoints)
{ {
size_t len = 0; size_t len = 0;
for (size_t i = 0; i < nr_codepoints; i++) { for (size_t i = 0; i < nr_codepoints; i++) {
size_t l = fx_wchar_utf8_codepoint_size(s[i]); size_t l = b_wchar_utf8_codepoint_size(s[i]);
if (l == 0) { if (l == 0) {
/* invalid codepoint */ /* invalid codepoint */
return 0; return 0;

View File

@@ -1,8 +1,8 @@
#include <fx/core/endian.h> #include <blue/core/endian.h>
fx_i16 fx_i16_htob(uint16_t v) b_i16 b_i16_htob(uint16_t v)
{ {
fx_i16 x; b_i16 x;
#ifdef BIG_ENDIAN #ifdef BIG_ENDIAN
x.i_uval = v; x.i_uval = v;
@@ -15,9 +15,9 @@ fx_i16 fx_i16_htob(uint16_t v)
return x; return x;
} }
fx_i16 fx_i16_htos(uint16_t v) b_i16 b_i16_htos(uint16_t v)
{ {
fx_i16 x; b_i16 x;
#ifdef LITTLE_ENDIAN #ifdef LITTLE_ENDIAN
x.i_uval = v; x.i_uval = v;
@@ -30,7 +30,7 @@ fx_i16 fx_i16_htos(uint16_t v)
return x; return x;
} }
uint16_t fx_i16_btoh(fx_i16 v) uint16_t b_i16_btoh(b_i16 v)
{ {
uint16_t x; uint16_t x;
@@ -45,7 +45,7 @@ uint16_t fx_i16_btoh(fx_i16 v)
return x; return x;
} }
uint16_t fx_i16_stoh(fx_i16 v) uint16_t b_i16_stoh(b_i16 v)
{ {
uint16_t x; uint16_t x;
@@ -60,9 +60,9 @@ uint16_t fx_i16_stoh(fx_i16 v)
return x; return x;
} }
fx_i32 fx_i32_htob(uint32_t v) b_i32 b_i32_htob(uint32_t v)
{ {
fx_i32 x; b_i32 x;
#ifdef BIG_ENDIAN #ifdef BIG_ENDIAN
x.i_uval = v; x.i_uval = v;
@@ -77,9 +77,9 @@ fx_i32 fx_i32_htob(uint32_t v)
return x; return x;
} }
fx_i32 fx_i32_htos(uint32_t v) b_i32 b_i32_htos(uint32_t v)
{ {
fx_i32 x; b_i32 x;
#ifdef LITTLE_ENDIAN #ifdef LITTLE_ENDIAN
x.i_uval = v; x.i_uval = v;
@@ -94,7 +94,7 @@ fx_i32 fx_i32_htos(uint32_t v)
return x; return x;
} }
uint32_t fx_i32_btoh(fx_i32 v) uint32_t b_i32_btoh(b_i32 v)
{ {
uint32_t x; uint32_t x;
@@ -111,7 +111,7 @@ uint32_t fx_i32_btoh(fx_i32 v)
return x; return x;
} }
uint32_t fx_i32_stoh(fx_i32 v) uint32_t b_i32_stoh(b_i32 v)
{ {
uint32_t x; uint32_t x;
@@ -128,9 +128,9 @@ uint32_t fx_i32_stoh(fx_i32 v)
return x; return x;
} }
fx_i64 fx_i64_htob(uint64_t v) b_i64 b_i64_htob(uint64_t v)
{ {
fx_i64 x; b_i64 x;
#ifdef BIG_ENDIAN #ifdef BIG_ENDIAN
x.i_uval = v; x.i_uval = v;
@@ -149,9 +149,9 @@ fx_i64 fx_i64_htob(uint64_t v)
return x; return x;
} }
fx_i64 fx_i64_htos(uint64_t v) b_i64 b_i64_htos(uint64_t v)
{ {
fx_i64 x; b_i64 x;
#ifdef LITTLE_ENDIAN #ifdef LITTLE_ENDIAN
x.i_uval = v; x.i_uval = v;
@@ -170,7 +170,7 @@ fx_i64 fx_i64_htos(uint64_t v)
return x; return x;
} }
uint64_t fx_i64_btoh(fx_i64 v) uint64_t b_i64_btoh(b_i64 v)
{ {
uint64_t x; uint64_t x;
@@ -191,7 +191,7 @@ uint64_t fx_i64_btoh(fx_i64 v)
return x; return x;
} }
uint64_t fx_i64_stoh(fx_i64 v) uint64_t b_i64_stoh(b_i64 v)
{ {
uint64_t x; uint64_t x;

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,37 @@
#ifndef _FX_ERROR_H_ #ifndef _BLUELIB_ERROR_H_
#define _FX_ERROR_H_ #define _BLUELIB_ERROR_H_
#include <fx/core/error.h> #include <blue/core/error.h>
#include <fx/core/queue.h> #include <blue/core/queue.h>
struct fx_error_stack_frame { struct b_error_stack_frame {
fx_queue_entry f_entry; b_queue_entry f_entry;
const char *f_file; const char *f_file;
unsigned int f_line_number; unsigned int f_line_number;
const char *f_function; const char *f_function;
}; };
struct fx_error_submsg { struct b_error_submsg {
fx_queue_entry msg_entry; b_queue_entry msg_entry;
fx_error_submsg_type msg_type; b_error_submsg_type msg_type;
char *msg_content; char *msg_content;
const struct fx_error_msg *msg_msg; const struct b_error_msg *msg_msg;
struct fx_error_template_parameter msg_params[FX_ERROR_TEMPLATE_PARAMETER_MAX]; struct b_error_template_parameter msg_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
}; };
struct fx_error { struct b_error {
const struct fx_error_vendor *err_vendor; const struct b_error_vendor *err_vendor;
fx_error_status_code err_code; b_error_status_code err_code;
const struct fx_error_definition *err_def; const struct b_error_definition *err_def;
const struct fx_error_msg *err_msg; const struct b_error_msg *err_msg;
char *err_description; char *err_description;
struct fx_error_template_parameter err_params[FX_ERROR_TEMPLATE_PARAMETER_MAX]; struct b_error_template_parameter err_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
struct fx_queue err_submsg; struct b_queue err_submsg;
struct fx_queue err_stack; struct b_queue err_stack;
fx_queue_entry err_entry; b_queue_entry err_entry;
struct fx_error *err_caused_by; struct b_error *err_caused_by;
}; };
#endif #endif

View File

@@ -1,7 +1,7 @@
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <fx/core/rope.h> #include <blue/core/rope.h>
#include <inttypes.h> #include <inttypes.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -10,46 +10,46 @@
#define FNV1_OFFSET_BASIS 0xcbf29ce484222325 #define FNV1_OFFSET_BASIS 0xcbf29ce484222325
#define FNV1_PRIME 0x100000001b3 #define FNV1_PRIME 0x100000001b3
extern struct fx_hash_function_ops z__fx_md4_ops; extern struct b_hash_function_ops z__b_md4_ops;
extern struct fx_hash_function_ops z__fx_md5_ops; extern struct b_hash_function_ops z__b_md5_ops;
extern struct fx_hash_function_ops z__fx_sha1_ops; extern struct b_hash_function_ops z__b_sha1_ops;
extern struct fx_hash_function_ops z__fx_sha2_224_ops; extern struct b_hash_function_ops z__b_sha2_224_ops;
extern struct fx_hash_function_ops z__fx_sha2_256_ops; extern struct b_hash_function_ops z__b_sha2_256_ops;
extern struct fx_hash_function_ops z__fx_sha2_384_ops; extern struct b_hash_function_ops z__b_sha2_384_ops;
extern struct fx_hash_function_ops z__fx_sha2_512_ops; extern struct b_hash_function_ops z__b_sha2_512_ops;
extern struct fx_hash_function_ops z__fx_sha3_224_ops; extern struct b_hash_function_ops z__b_sha3_224_ops;
extern struct fx_hash_function_ops z__fx_sha3_256_ops; extern struct b_hash_function_ops z__b_sha3_256_ops;
extern struct fx_hash_function_ops z__fx_sha3_384_ops; extern struct b_hash_function_ops z__b_sha3_384_ops;
extern struct fx_hash_function_ops z__fx_sha3_512_ops; extern struct b_hash_function_ops z__b_sha3_512_ops;
extern struct fx_hash_function_ops z__fx_shake128_ops; extern struct b_hash_function_ops z__b_shake128_ops;
extern struct fx_hash_function_ops z__fx_shake256_ops; extern struct b_hash_function_ops z__b_shake256_ops;
static const struct fx_hash_function_ops *hash_functions[] = { static const struct b_hash_function_ops *hash_functions[] = {
[FX_HASH_NONE] = NULL, [B_HASH_NONE] = NULL,
[FX_HASH_MD4] = &z__fx_md4_ops, [B_HASH_MD4] = &z__b_md4_ops,
[FX_HASH_MD5] = &z__fx_md5_ops, [B_HASH_MD5] = &z__b_md5_ops,
[FX_HASH_SHA1] = &z__fx_sha1_ops, [B_HASH_SHA1] = &z__b_sha1_ops,
[FX_HASH_SHA2_224] = &z__fx_sha2_224_ops, [B_HASH_SHA2_224] = &z__b_sha2_224_ops,
[FX_HASH_SHA2_256] = &z__fx_sha2_256_ops, [B_HASH_SHA2_256] = &z__b_sha2_256_ops,
[FX_HASH_SHA2_384] = &z__fx_sha2_384_ops, [B_HASH_SHA2_384] = &z__b_sha2_384_ops,
[FX_HASH_SHA2_512] = &z__fx_sha2_512_ops, [B_HASH_SHA2_512] = &z__b_sha2_512_ops,
[FX_HASH_SHA3_224] = &z__fx_sha3_224_ops, [B_HASH_SHA3_224] = &z__b_sha3_224_ops,
[FX_HASH_SHA3_256] = &z__fx_sha3_256_ops, [B_HASH_SHA3_256] = &z__b_sha3_256_ops,
[FX_HASH_SHA3_384] = &z__fx_sha3_384_ops, [B_HASH_SHA3_384] = &z__b_sha3_384_ops,
[FX_HASH_SHA3_512] = &z__fx_sha3_512_ops, [B_HASH_SHA3_512] = &z__b_sha3_512_ops,
[FX_HASH_SHAKE128] = &z__fx_shake128_ops, [B_HASH_SHAKE128] = &z__b_shake128_ops,
[FX_HASH_SHAKE256] = &z__fx_shake256_ops, [B_HASH_SHAKE256] = &z__b_shake256_ops,
}; };
static const size_t nr_hash_functions static const size_t nr_hash_functions
= sizeof hash_functions / sizeof hash_functions[0]; = sizeof hash_functions / sizeof hash_functions[0];
uint64_t fx_hash_cstr(const char *s) uint64_t b_hash_cstr(const char *s)
{ {
size_t x = 0; size_t x = 0;
return fx_hash_cstr_ex(s, &x); return b_hash_cstr_ex(s, &x);
} }
uint64_t fx_hash_cstr_ex(const char *s, size_t *len) uint64_t b_hash_cstr_ex(const char *s, size_t *len)
{ {
uint64_t hash = FNV1_OFFSET_BASIS; uint64_t hash = FNV1_OFFSET_BASIS;
size_t i = 0; size_t i = 0;
@@ -66,15 +66,15 @@ uint64_t fx_hash_cstr_ex(const char *s, size_t *len)
return hash; return hash;
} }
enum fx_status fx_hash_ctx_init(struct fx_hash_ctx *ctx, enum fx_hash_function func) enum b_status b_hash_ctx_init(struct b_hash_ctx *ctx, enum b_hash_function func)
{ {
if (func < 0 || func >= nr_hash_functions) { if (func < 0 || func >= nr_hash_functions) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
const struct fx_hash_function_ops *hash_function = hash_functions[func]; const struct b_hash_function_ops *hash_function = hash_functions[func];
if (!hash_function) { if (!hash_function) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
memset(ctx, 0x0, sizeof *ctx); memset(ctx, 0x0, sizeof *ctx);
@@ -86,13 +86,13 @@ enum fx_status fx_hash_ctx_init(struct fx_hash_ctx *ctx, enum fx_hash_function f
hash_function->hash_init(ctx); hash_function->hash_init(ctx);
} }
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_hash_ctx_reset(struct fx_hash_ctx *ctx) enum b_status b_hash_ctx_reset(struct b_hash_ctx *ctx)
{ {
if (ctx->ctx_func == FX_HASH_NONE || !ctx->ctx_ops) { if (ctx->ctx_func == B_HASH_NONE || !ctx->ctx_ops) {
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
memset(&ctx->ctx_state, 0x0, sizeof ctx->ctx_state); memset(&ctx->ctx_state, 0x0, sizeof ctx->ctx_state);
@@ -101,69 +101,69 @@ enum fx_status fx_hash_ctx_reset(struct fx_hash_ctx *ctx)
ctx->ctx_ops->hash_init(ctx); ctx->ctx_ops->hash_init(ctx);
} }
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_hash_ctx_update(struct fx_hash_ctx *ctx, const void *p, size_t len) enum b_status b_hash_ctx_update(struct b_hash_ctx *ctx, const void *p, size_t len)
{ {
if (!ctx->ctx_ops) { if (!ctx->ctx_ops) {
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
if (!ctx->ctx_ops->hash_update) { if (!ctx->ctx_ops->hash_update) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
ctx->ctx_ops->hash_update(ctx, p, len); ctx->ctx_ops->hash_update(ctx, p, len);
return FX_SUCCESS; return B_SUCCESS;
} }
static void update_rope(const fx_rope *rope, void *arg) static void update_rope(const b_rope *rope, void *arg)
{ {
struct fx_hash_ctx *ctx = arg; struct b_hash_ctx *ctx = arg;
unsigned int type = FX_ROPE_TYPE(rope->r_flags); unsigned int type = B_ROPE_TYPE(rope->r_flags);
char tmp[64]; char tmp[64];
size_t len = 0; size_t len = 0;
switch (type) { switch (type) {
case FX_ROPE_F_CHAR: case B_ROPE_F_CHAR:
fx_hash_ctx_update(ctx, &rope->r_v.v_char, sizeof rope->r_v.v_char); b_hash_ctx_update(ctx, &rope->r_v.v_char, sizeof rope->r_v.v_char);
break; break;
case FX_ROPE_F_CSTR: case B_ROPE_F_CSTR:
case FX_ROPE_F_CSTR_BORROWED: case B_ROPE_F_CSTR_BORROWED:
case FX_ROPE_F_CSTR_STATIC: case B_ROPE_F_CSTR_STATIC:
fx_hash_ctx_update( b_hash_ctx_update(
ctx, rope->r_v.v_cstr.s, strlen(rope->r_v.v_cstr.s)); ctx, rope->r_v.v_cstr.s, strlen(rope->r_v.v_cstr.s));
break; break;
case FX_ROPE_F_INT: case B_ROPE_F_INT:
len = snprintf(tmp, sizeof tmp, "%" PRIdPTR, rope->r_v.v_int); len = snprintf(tmp, sizeof tmp, "%" PRIdPTR, rope->r_v.v_int);
fx_hash_ctx_update(ctx, tmp, len); b_hash_ctx_update(ctx, tmp, len);
break; break;
case FX_ROPE_F_UINT: case B_ROPE_F_UINT:
len = snprintf(tmp, sizeof tmp, "%" PRIuPTR, rope->r_v.v_uint); len = snprintf(tmp, sizeof tmp, "%" PRIuPTR, rope->r_v.v_uint);
fx_hash_ctx_update(ctx, tmp, len); b_hash_ctx_update(ctx, tmp, len);
break; break;
default: default:
break; break;
} }
} }
enum fx_status fx_hash_ctx_update_rope( enum b_status b_hash_ctx_update_rope(
struct fx_hash_ctx *ctx, const struct fx_rope *rope) struct b_hash_ctx *ctx, const struct b_rope *rope)
{ {
fx_rope_iterate(rope, update_rope, ctx); b_rope_iterate(rope, update_rope, ctx);
return FX_SUCCESS; return B_SUCCESS;
} }
enum fx_status fx_hash_ctx_finish( enum b_status b_hash_ctx_finish(
struct fx_hash_ctx *ctx, void *out_digest, size_t out_max) struct b_hash_ctx *ctx, void *out_digest, size_t out_max)
{ {
if (!ctx->ctx_ops) { if (!ctx->ctx_ops) {
return FX_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
if (!ctx->ctx_ops->hash_finish) { if (!ctx->ctx_ops->hash_finish) {
return FX_ERR_NOT_SUPPORTED; return B_ERR_NOT_SUPPORTED;
} }
ctx->ctx_ops->hash_finish(ctx, out_digest, out_max); ctx->ctx_ops->hash_finish(ctx, out_digest, out_max);
@@ -174,5 +174,5 @@ enum fx_status fx_hash_ctx_finish(
ctx->ctx_ops->hash_init(ctx); ctx->ctx_ops->hash_init(ctx);
} }
return FX_SUCCESS; return B_SUCCESS;
} }

View File

@@ -3,12 +3,12 @@
#include <stddef.h> #include <stddef.h>
struct fx_hash_ctx; struct b_hash_ctx;
struct fx_hash_function_ops { struct b_hash_function_ops {
void (*hash_init)(struct fx_hash_ctx *); void (*hash_init)(struct b_hash_ctx *);
void (*hash_update)(struct fx_hash_ctx *, const void *, size_t); void (*hash_update)(struct b_hash_ctx *, const void *, size_t);
void (*hash_finish)(struct fx_hash_ctx *, void *, size_t); void (*hash_finish)(struct b_hash_ctx *, void *, size_t);
}; };
#endif #endif

View File

@@ -36,7 +36,7 @@
*/ */
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -88,7 +88,7 @@
* This processes one or more 64-byte data blocks, but does NOT update the bit * This processes one or more 64-byte data blocks, but does NOT update the bit
* counters. There are no alignment requirements. * counters. There are no alignment requirements.
*/ */
static const void *body(struct fx_hash_ctx *ctx, const void *data, unsigned long size) static const void *body(struct b_hash_ctx *ctx, const void *data, unsigned long size)
{ {
const unsigned char *ptr; const unsigned char *ptr;
uint32_t a, b, c, d; uint32_t a, b, c, d;
@@ -178,7 +178,7 @@ static const void *body(struct fx_hash_ctx *ctx, const void *data, unsigned long
return ptr; return ptr;
} }
void md4_init(struct fx_hash_ctx *ctx) void md4_init(struct b_hash_ctx *ctx)
{ {
ctx->ctx_state.md4.a = 0x67452301; ctx->ctx_state.md4.a = 0x67452301;
ctx->ctx_state.md4.b = 0xefcdab89; ctx->ctx_state.md4.b = 0xefcdab89;
@@ -189,7 +189,7 @@ void md4_init(struct fx_hash_ctx *ctx)
ctx->ctx_state.md4.hi = 0; ctx->ctx_state.md4.hi = 0;
} }
void md4_update(struct fx_hash_ctx *ctx, const void *data, unsigned long size) void md4_update(struct b_hash_ctx *ctx, const void *data, unsigned long size)
{ {
uint32_t saved_lo; uint32_t saved_lo;
unsigned long used, available; unsigned long used, available;
@@ -229,7 +229,7 @@ void md4_update(struct fx_hash_ctx *ctx, const void *data, unsigned long size)
(dst)[2] = (unsigned char)((src) >> 16); \ (dst)[2] = (unsigned char)((src) >> 16); \
(dst)[3] = (unsigned char)((src) >> 24); (dst)[3] = (unsigned char)((src) >> 24);
void md4_finish(struct fx_hash_ctx *ctx, void *out, size_t max) void md4_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char *result = out; unsigned char *result = out;
unsigned long used, available; unsigned long used, available;
@@ -261,7 +261,7 @@ void md4_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
OUT(&result[12], ctx->ctx_state.md4.d) OUT(&result[12], ctx->ctx_state.md4.d)
} }
struct fx_hash_function_ops z__fx_md4_ops = { struct b_hash_function_ops z__b_md4_ops = {
.hash_init = md4_init, .hash_init = md4_init,
.hash_update = md4_update, .hash_update = md4_update,
.hash_finish = md4_finish, .hash_finish = md4_finish,

View File

@@ -3,7 +3,7 @@
* and is in the public domain. */ * and is in the public domain. */
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <memory.h> #include <memory.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -19,7 +19,7 @@
#define STEP(f, a, b, c, d, x, t, s) \ #define STEP(f, a, b, c, d, x, t, s) \
(a += f(b, c, d) + x + t, a = ROTATE_LEFT(a, s), a += b) (a += f(b, c, d) + x + t, a = ROTATE_LEFT(a, s), a += b)
void md5_init(struct fx_hash_ctx *ctx) void md5_init(struct b_hash_ctx *ctx)
{ {
ctx->ctx_state.md5.a = 0x67452301; ctx->ctx_state.md5.a = 0x67452301;
ctx->ctx_state.md5.b = 0xefcdab89; ctx->ctx_state.md5.b = 0xefcdab89;
@@ -30,7 +30,7 @@ void md5_init(struct fx_hash_ctx *ctx)
ctx->ctx_state.md5.count[1] = 0; ctx->ctx_state.md5.count[1] = 0;
} }
uint8_t *md5_transform(struct fx_hash_ctx *ctx, const void *data, uintmax_t size) uint8_t *md5_transform(struct b_hash_ctx *ctx, const void *data, uintmax_t size)
{ {
uint8_t *ptr = (uint8_t *)data; uint8_t *ptr = (uint8_t *)data;
uint32_t a, b, c, d, aa, bb, cc, dd; uint32_t a, b, c, d, aa, bb, cc, dd;
@@ -140,7 +140,7 @@ uint8_t *md5_transform(struct fx_hash_ctx *ctx, const void *data, uintmax_t size
return ptr; return ptr;
} }
void md5_update(struct fx_hash_ctx *ctx, const void *buffer, size_t buffer_size) void md5_update(struct b_hash_ctx *ctx, const void *buffer, size_t buffer_size)
{ {
uint32_t saved_low = ctx->ctx_state.md5.count[0]; uint32_t saved_low = ctx->ctx_state.md5.count[0];
uint32_t used; uint32_t used;
@@ -178,7 +178,7 @@ void md5_update(struct fx_hash_ctx *ctx, const void *buffer, size_t buffer_size)
memcpy(ctx->ctx_state.md5.input, buffer, buffer_size); memcpy(ctx->ctx_state.md5.input, buffer, buffer_size);
} }
void md5_finish(struct fx_hash_ctx *ctx, void *out, size_t max) void md5_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
uint32_t used = ctx->ctx_state.md5.count[0] & 0x3f; uint32_t used = ctx->ctx_state.md5.count[0] & 0x3f;
ctx->ctx_state.md5.input[used++] = 0x80; ctx->ctx_state.md5.input[used++] = 0x80;
@@ -193,7 +193,7 @@ void md5_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
memset(&ctx->ctx_state.md5.input[used], 0, free - 8); memset(&ctx->ctx_state.md5.input[used], 0, free - 8);
unsigned char digest[FX_DIGEST_LENGTH_MD5]; unsigned char digest[B_DIGEST_LENGTH_MD5];
ctx->ctx_state.md5.count[0] <<= 3; ctx->ctx_state.md5.count[0] <<= 3;
ctx->ctx_state.md5.input[56] = (uint8_t)(ctx->ctx_state.md5.count[0]); ctx->ctx_state.md5.input[56] = (uint8_t)(ctx->ctx_state.md5.count[0]);
@@ -228,10 +228,10 @@ void md5_finish(struct fx_hash_ctx *ctx, void *out, size_t max)
digest[14] = (uint8_t)(ctx->ctx_state.md5.d >> 16); digest[14] = (uint8_t)(ctx->ctx_state.md5.d >> 16);
digest[15] = (uint8_t)(ctx->ctx_state.md5.d >> 24); digest[15] = (uint8_t)(ctx->ctx_state.md5.d >> 24);
memcpy(out, digest, fx_min(size_t, sizeof digest, max)); memcpy(out, digest, b_min(size_t, sizeof digest, max));
} }
struct fx_hash_function_ops z__fx_md5_ops = { struct b_hash_function_ops z__b_md5_ops = {
.hash_init = md5_init, .hash_init = md5_init,
.hash_update = md5_update, .hash_update = md5_update,
.hash_finish = md5_finish, .hash_finish = md5_finish,

View File

@@ -19,7 +19,7 @@ A million repetitions of "a"
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -187,7 +187,7 @@ void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
/* sha_init - Initialize new context */ /* sha_init - Initialize new context */
static void sha_init(struct fx_hash_ctx *context) static void sha_init(struct b_hash_ctx *context)
{ {
/* SHA1 initialization constants */ /* SHA1 initialization constants */
context->ctx_state.sha1.state[0] = 0x67452301; context->ctx_state.sha1.state[0] = 0x67452301;
@@ -200,7 +200,7 @@ static void sha_init(struct fx_hash_ctx *context)
/* Run your data through this. */ /* Run your data through this. */
static void sha_update(struct fx_hash_ctx *context, const void *p, size_t len) static void sha_update(struct b_hash_ctx *context, const void *p, size_t len)
{ {
const unsigned char *data = p; const unsigned char *data = p;
uint32_t i, j; uint32_t i, j;
@@ -226,7 +226,7 @@ static void sha_update(struct fx_hash_ctx *context, const void *p, size_t len)
/* Add padding and return the message digest. */ /* Add padding and return the message digest. */
static void sha_finish(struct fx_hash_ctx *context, void *out, size_t max) static void sha_finish(struct b_hash_ctx *context, void *out, size_t max)
{ {
unsigned i; unsigned i;
@@ -241,7 +241,7 @@ static void sha_finish(struct fx_hash_ctx *context, void *out, size_t max)
& 255); /* Endian independent */ & 255); /* Endian independent */
} }
char digest[FX_DIGEST_LENGTH_SHA1]; char digest[B_DIGEST_LENGTH_SHA1];
c = 0200; c = 0200;
sha_update(context, &c, 1); sha_update(context, &c, 1);
while ((context->ctx_state.sha1.count[0] & 504) != 448) { while ((context->ctx_state.sha1.count[0] & 504) != 448) {
@@ -255,12 +255,12 @@ static void sha_finish(struct fx_hash_ctx *context, void *out, size_t max)
& 255); & 255);
} }
memcpy(out, digest, fx_min(size_t, sizeof digest, max)); memcpy(out, digest, b_min(size_t, sizeof digest, max));
/* Wipe variables */ /* Wipe variables */
memset(&finalcount, '\0', sizeof(finalcount)); memset(&finalcount, '\0', sizeof(finalcount));
} }
struct fx_hash_function_ops z__fx_sha1_ops = { struct b_hash_function_ops z__b_sha1_ops = {
.hash_init = sha_init, .hash_init = sha_init,
.hash_update = sha_update, .hash_update = sha_update,
.hash_finish = sha_finish, .hash_finish = sha_finish,

View File

@@ -1,14 +1,14 @@
// SHA-224. Adapted from LibTomCrypt. This code is Public Domain // SHA-224. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <string.h> #include <string.h>
extern void z__fx_sha2_256_update( extern void z__b_sha2_256_update(
struct fx_hash_ctx *md, const void *src, size_t inlen); struct b_hash_ctx *md, const void *src, size_t inlen);
extern void z__fx_sha2_256_finish(struct fx_hash_ctx *md, void *out, size_t max); extern void z__b_sha2_256_finish(struct b_hash_ctx *md, void *out, size_t max);
static void sha_init(struct fx_hash_ctx *md) static void sha_init(struct b_hash_ctx *md)
{ {
md->ctx_state.sha2_256.curlen = 0; md->ctx_state.sha2_256.curlen = 0;
md->ctx_state.sha2_256.length = 0; md->ctx_state.sha2_256.length = 0;
@@ -22,20 +22,20 @@ static void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_256.state[7] = 0xbefa4fa4UL; md->ctx_state.sha2_256.state[7] = 0xbefa4fa4UL;
} }
static void sha_update(struct fx_hash_ctx *md, const void *in, size_t inlen) static void sha_update(struct b_hash_ctx *md, const void *in, size_t inlen)
{ {
z__fx_sha2_256_update(md, in, inlen); z__b_sha2_256_update(md, in, inlen);
} }
static void sha_finish(struct fx_hash_ctx *md, void *out, size_t max) static void sha_finish(struct b_hash_ctx *md, void *out, size_t max)
{ {
unsigned char res[FX_DIGEST_LENGTH_SHA2_256]; unsigned char res[B_DIGEST_LENGTH_SHA2_256];
z__fx_sha2_256_finish(md, res, max); z__b_sha2_256_finish(md, res, max);
/* truncate the digest to 224 bits */ /* truncate the digest to 224 bits */
memcpy(out, res, fx_min(size_t, max, FX_DIGEST_LENGTH_224)); memcpy(out, res, b_min(size_t, max, B_DIGEST_LENGTH_224));
} }
struct fx_hash_function_ops z__fx_sha2_224_ops = { struct b_hash_function_ops z__b_sha2_224_ops = {
.hash_init = sha_init, .hash_init = sha_init,
.hash_update = sha_update, .hash_update = sha_update,
.hash_finish = sha_finish, .hash_finish = sha_finish,

View File

@@ -1,7 +1,7 @@
// SHA-256. Adapted from LibTomCrypt. This code is Public Domain // SHA-256. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <string.h> #include <string.h>
static const uint32_t K[64] = { static const uint32_t K[64] = {
@@ -87,7 +87,7 @@ static void RND(
(*h) = *t0 + *t1; (*h) = *t0 + *t1;
} }
static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf) static void sha_compress(struct b_hash_ctx *md, const unsigned char *buf)
{ {
uint32_t S[8], W[64], t0, t1, t; uint32_t S[8], W[64], t0, t1, t;
@@ -127,7 +127,7 @@ static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
// Public interface // Public interface
static void sha_init(struct fx_hash_ctx *md) static void sha_init(struct b_hash_ctx *md)
{ {
md->ctx_state.sha2_256.curlen = 0; md->ctx_state.sha2_256.curlen = 0;
md->ctx_state.sha2_256.length = 0; md->ctx_state.sha2_256.length = 0;
@@ -141,7 +141,7 @@ static void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_256.state[7] = 0x5BE0CD19UL; md->ctx_state.sha2_256.state[7] = 0x5BE0CD19UL;
} }
void z__fx_sha2_256_update(struct fx_hash_ctx *md, const void *src, size_t inlen) void z__b_sha2_256_update(struct b_hash_ctx *md, const void *src, size_t inlen)
{ {
const uint32_t block_size = sizeof md->ctx_state.sha2_256.buf; const uint32_t block_size = sizeof md->ctx_state.sha2_256.buf;
const unsigned char *in = (const unsigned char *)(src); const unsigned char *in = (const unsigned char *)(src);
@@ -171,7 +171,7 @@ void z__fx_sha2_256_update(struct fx_hash_ctx *md, const void *src, size_t inlen
} }
} }
} }
void z__fx_sha2_256_finish(struct fx_hash_ctx *md, void *out, size_t max) void z__b_sha2_256_finish(struct b_hash_ctx *md, void *out, size_t max)
{ {
// Increase the length of the message // Increase the length of the message
md->ctx_state.sha2_256.length += md->ctx_state.sha2_256.curlen * 8; md->ctx_state.sha2_256.length += md->ctx_state.sha2_256.curlen * 8;
@@ -198,18 +198,18 @@ void z__fx_sha2_256_finish(struct fx_hash_ctx *md, void *out, size_t max)
store64(md->ctx_state.sha2_256.length, md->ctx_state.sha2_256.buf + 56); store64(md->ctx_state.sha2_256.length, md->ctx_state.sha2_256.buf + 56);
sha_compress(md, md->ctx_state.sha2_256.buf); sha_compress(md, md->ctx_state.sha2_256.buf);
unsigned char digest[FX_DIGEST_LENGTH_SHA2_256]; unsigned char digest[B_DIGEST_LENGTH_SHA2_256];
// Copy output // Copy output
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
store32(md->ctx_state.sha2_256.state[i], store32(md->ctx_state.sha2_256.state[i],
(unsigned char *)&digest[(4 * i)]); (unsigned char *)&digest[(4 * i)]);
memcpy(out, digest, fx_min(size_t, sizeof digest, max)); memcpy(out, digest, b_min(size_t, sizeof digest, max));
} }
struct fx_hash_function_ops z__fx_sha2_256_ops = { struct b_hash_function_ops z__b_sha2_256_ops = {
.hash_init = sha_init, .hash_init = sha_init,
.hash_update = z__fx_sha2_256_update, .hash_update = z__b_sha2_256_update,
.hash_finish = z__fx_sha2_256_finish, .hash_finish = z__b_sha2_256_finish,
}; };

View File

@@ -1,14 +1,14 @@
// SHA-384. Adapted from LibTomCrypt. This code is Public Domain // SHA-384. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <string.h> #include <string.h>
extern void z__fx_sha2_512_update( extern void z__b_sha2_512_update(
struct fx_hash_ctx *md, const void *src, size_t inlen); struct b_hash_ctx *md, const void *src, size_t inlen);
extern void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max); extern void z__b_sha2_512_finish(struct b_hash_ctx *md, void *out, size_t max);
void sha_init(struct fx_hash_ctx *md) void sha_init(struct b_hash_ctx *md)
{ {
md->ctx_state.sha2_512.curlen = 0; md->ctx_state.sha2_512.curlen = 0;
md->ctx_state.sha2_512.length = 0; md->ctx_state.sha2_512.length = 0;
@@ -22,20 +22,20 @@ void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_512.state[7] = 0x47b5481dbefa4fa4ULL; md->ctx_state.sha2_512.state[7] = 0x47b5481dbefa4fa4ULL;
} }
static void sha_update(struct fx_hash_ctx *md, const void *in, size_t inlen) static void sha_update(struct b_hash_ctx *md, const void *in, size_t inlen)
{ {
z__fx_sha2_512_update(md, in, inlen); z__b_sha2_512_update(md, in, inlen);
} }
static void sha_finish(struct fx_hash_ctx *md, void *out, size_t max) static void sha_finish(struct b_hash_ctx *md, void *out, size_t max)
{ {
unsigned char res[FX_DIGEST_LENGTH_SHA2_512]; unsigned char res[B_DIGEST_LENGTH_SHA2_512];
z__fx_sha2_512_finish(md, res, max); z__b_sha2_512_finish(md, res, max);
/* truncate the digest to 384 bits */ /* truncate the digest to 384 bits */
memcpy(out, res, fx_min(size_t, max, FX_DIGEST_LENGTH_384)); memcpy(out, res, b_min(size_t, max, B_DIGEST_LENGTH_384));
} }
struct fx_hash_function_ops z__fx_sha2_384_ops = { struct b_hash_function_ops z__b_sha2_384_ops = {
.hash_init = sha_init, .hash_init = sha_init,
.hash_update = sha_update, .hash_update = sha_update,
.hash_finish = sha_finish, .hash_finish = sha_finish,

View File

@@ -1,7 +1,7 @@
// SHA-512. Adapted from LibTomCrypt. This code is Public Domain // SHA-512. Adapted from LibTomCrypt. This code is Public Domain
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -96,7 +96,7 @@ static void RND(
*h = *t0 + *t1; *h = *t0 + *t1;
} }
static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf) static void sha_compress(struct b_hash_ctx *md, const unsigned char *buf)
{ {
uint64_t S[8], W[80], t0, t1; uint64_t S[8], W[80], t0, t1;
@@ -144,7 +144,7 @@ static void sha_compress(struct fx_hash_ctx *md, const unsigned char *buf)
// Public interface // Public interface
static void sha_init(struct fx_hash_ctx *md) static void sha_init(struct b_hash_ctx *md)
{ {
md->ctx_state.sha2_512.curlen = 0; md->ctx_state.sha2_512.curlen = 0;
md->ctx_state.sha2_512.length = 0; md->ctx_state.sha2_512.length = 0;
@@ -158,7 +158,7 @@ static void sha_init(struct fx_hash_ctx *md)
md->ctx_state.sha2_512.state[7] = 0x5be0cd19137e2179ULL; md->ctx_state.sha2_512.state[7] = 0x5be0cd19137e2179ULL;
} }
void z__fx_sha2_512_update(struct fx_hash_ctx *md, const void *src, size_t inlen) void z__b_sha2_512_update(struct b_hash_ctx *md, const void *src, size_t inlen)
{ {
const uint32_t block_size = sizeof md->ctx_state.sha2_512.block; const uint32_t block_size = sizeof md->ctx_state.sha2_512.block;
const unsigned char *in = (const unsigned char *)src; const unsigned char *in = (const unsigned char *)src;
@@ -189,7 +189,7 @@ void z__fx_sha2_512_update(struct fx_hash_ctx *md, const void *src, size_t inlen
} }
} }
void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max) void z__b_sha2_512_finish(struct b_hash_ctx *md, void *out, size_t max)
{ {
// Increase the length of the message // Increase the length of the message
md->ctx_state.sha2_512.length += md->ctx_state.sha2_512.curlen * 8ULL; md->ctx_state.sha2_512.length += md->ctx_state.sha2_512.curlen * 8ULL;
@@ -218,7 +218,7 @@ void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max)
store64(md->ctx_state.sha2_512.length, md->ctx_state.sha2_512.block + 120); store64(md->ctx_state.sha2_512.length, md->ctx_state.sha2_512.block + 120);
sha_compress(md, md->ctx_state.sha2_512.block); sha_compress(md, md->ctx_state.sha2_512.block);
unsigned char digest[FX_DIGEST_LENGTH_SHA2_512]; unsigned char digest[B_DIGEST_LENGTH_SHA2_512];
// Copy output // Copy output
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
@@ -226,11 +226,11 @@ void z__fx_sha2_512_finish(struct fx_hash_ctx *md, void *out, size_t max)
(unsigned char *)&digest[(8 * i)]); (unsigned char *)&digest[(8 * i)]);
} }
memcpy(out, digest, fx_min(size_t, sizeof digest, max)); memcpy(out, digest, b_min(size_t, sizeof digest, max));
} }
struct fx_hash_function_ops z__fx_sha2_512_ops = { struct b_hash_function_ops z__b_sha2_512_ops = {
.hash_init = sha_init, .hash_init = sha_init,
.hash_update = z__fx_sha2_512_update, .hash_update = z__b_sha2_512_update,
.hash_finish = z__fx_sha2_512_finish, .hash_finish = z__b_sha2_512_finish,
}; };

View File

@@ -30,8 +30,8 @@
#include "hash.h" #include "hash.h"
#include <fx/core/hash.h> #include <blue/core/hash.h>
#include <fx/core/misc.h> #include <blue/core/misc.h>
#include <string.h> #include <string.h>
#ifndef KECCAKF_ROUNDS #ifndef KECCAKF_ROUNDS
@@ -134,7 +134,7 @@ void sha3_keccakf(uint64_t st[25])
// Initialize the context for SHA3 // Initialize the context for SHA3
int sha3_init(struct fx_hash_ctx *c, int mdlen) int sha3_init(struct b_hash_ctx *c, int mdlen)
{ {
int i; int i;
@@ -149,7 +149,7 @@ int sha3_init(struct fx_hash_ctx *c, int mdlen)
// update state with more data // update state with more data
void sha3_update(struct fx_hash_ctx *c, const void *data, size_t len) void sha3_update(struct b_hash_ctx *c, const void *data, size_t len)
{ {
size_t i; size_t i;
int j; int j;
@@ -168,7 +168,7 @@ void sha3_update(struct fx_hash_ctx *c, const void *data, size_t len)
// finalize and output a hash // finalize and output a hash
int sha3_final(void *md, struct fx_hash_ctx *c) int sha3_final(void *md, struct b_hash_ctx *c)
{ {
int i; int i;
@@ -187,7 +187,7 @@ int sha3_final(void *md, struct fx_hash_ctx *c)
void *sha3(const void *in, size_t inlen, void *md, int mdlen) void *sha3(const void *in, size_t inlen, void *md, int mdlen)
{ {
struct fx_hash_ctx sha3; struct b_hash_ctx sha3;
sha3_init(&sha3, mdlen); sha3_init(&sha3, mdlen);
sha3_update(&sha3, in, inlen); sha3_update(&sha3, in, inlen);
@@ -198,7 +198,7 @@ void *sha3(const void *in, size_t inlen, void *md, int mdlen)
// SHAKE128 and SHAKE256 extensible-output functionality // SHAKE128 and SHAKE256 extensible-output functionality
void shake_xof(struct fx_hash_ctx *c) void shake_xof(struct b_hash_ctx *c)
{ {
c->ctx_state.sha3.st.b[c->ctx_state.sha3.pt] ^= 0x1F; c->ctx_state.sha3.st.b[c->ctx_state.sha3.pt] ^= 0x1F;
c->ctx_state.sha3.st.b[c->ctx_state.sha3.rsiz - 1] ^= 0x80; c->ctx_state.sha3.st.b[c->ctx_state.sha3.rsiz - 1] ^= 0x80;
@@ -206,7 +206,7 @@ void shake_xof(struct fx_hash_ctx *c)
c->ctx_state.sha3.pt = 0; c->ctx_state.sha3.pt = 0;
} }
void shake_out(struct fx_hash_ctx *c, void *out, size_t len) void shake_out(struct b_hash_ctx *c, void *out, size_t len)
{ {
size_t i; size_t i;
int j; int j;
@@ -222,111 +222,111 @@ void shake_out(struct fx_hash_ctx *c, void *out, size_t len)
c->ctx_state.sha3.pt = j; c->ctx_state.sha3.pt = j;
} }
static void sha3_224_init(struct fx_hash_ctx *ctx) static void sha3_224_init(struct b_hash_ctx *ctx)
{ {
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_224); sha3_init(ctx, B_DIGEST_LENGTH_SHA3_224);
} }
static void sha3_224_finish(struct fx_hash_ctx *ctx, void *out, size_t max) static void sha3_224_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char md[FX_DIGEST_LENGTH_SHA3_224]; unsigned char md[B_DIGEST_LENGTH_SHA3_224];
sha3_final(md, ctx); sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max)); memcpy(out, md, b_min(size_t, sizeof md, max));
} }
static void sha3_256_init(struct fx_hash_ctx *ctx) static void sha3_256_init(struct b_hash_ctx *ctx)
{ {
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_256); sha3_init(ctx, B_DIGEST_LENGTH_SHA3_256);
} }
static void sha3_256_finish(struct fx_hash_ctx *ctx, void *out, size_t max) static void sha3_256_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char md[FX_DIGEST_LENGTH_SHA3_256]; unsigned char md[B_DIGEST_LENGTH_SHA3_256];
sha3_final(md, ctx); sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max)); memcpy(out, md, b_min(size_t, sizeof md, max));
} }
static void sha3_384_init(struct fx_hash_ctx *ctx) static void sha3_384_init(struct b_hash_ctx *ctx)
{ {
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_384); sha3_init(ctx, B_DIGEST_LENGTH_SHA3_384);
} }
static void sha3_384_finish(struct fx_hash_ctx *ctx, void *out, size_t max) static void sha3_384_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char md[FX_DIGEST_LENGTH_SHA3_384]; unsigned char md[B_DIGEST_LENGTH_SHA3_384];
sha3_final(md, ctx); sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max)); memcpy(out, md, b_min(size_t, sizeof md, max));
} }
static void sha3_512_init(struct fx_hash_ctx *ctx) static void sha3_512_init(struct b_hash_ctx *ctx)
{ {
sha3_init(ctx, FX_DIGEST_LENGTH_SHA3_512); sha3_init(ctx, B_DIGEST_LENGTH_SHA3_512);
} }
static void sha3_512_finish(struct fx_hash_ctx *ctx, void *out, size_t max) static void sha3_512_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char md[FX_DIGEST_LENGTH_SHA3_512]; unsigned char md[B_DIGEST_LENGTH_SHA3_512];
sha3_final(md, ctx); sha3_final(md, ctx);
memcpy(out, md, fx_min(size_t, sizeof md, max)); memcpy(out, md, b_min(size_t, sizeof md, max));
} }
static void shake128_init(struct fx_hash_ctx *ctx) static void shake128_init(struct b_hash_ctx *ctx)
{ {
sha3_init(ctx, FX_DIGEST_LENGTH_SHAKE128); sha3_init(ctx, B_DIGEST_LENGTH_SHAKE128);
} }
static void shake128_finish(struct fx_hash_ctx *ctx, void *out, size_t max) static void shake128_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char md[FX_DIGEST_LENGTH_SHAKE128]; unsigned char md[B_DIGEST_LENGTH_SHAKE128];
shake_xof(ctx); shake_xof(ctx);
shake_out(ctx, md, sizeof md); shake_out(ctx, md, sizeof md);
memcpy(out, md, fx_min(size_t, sizeof md, max)); memcpy(out, md, b_min(size_t, sizeof md, max));
} }
static void shake256_init(struct fx_hash_ctx *ctx) static void shake256_init(struct b_hash_ctx *ctx)
{ {
sha3_init(ctx, FX_DIGEST_LENGTH_SHAKE256); sha3_init(ctx, B_DIGEST_LENGTH_SHAKE256);
} }
static void shake256_finish(struct fx_hash_ctx *ctx, void *out, size_t max) static void shake256_finish(struct b_hash_ctx *ctx, void *out, size_t max)
{ {
unsigned char md[FX_DIGEST_LENGTH_SHAKE256]; unsigned char md[B_DIGEST_LENGTH_SHAKE256];
shake_xof(ctx); shake_xof(ctx);
shake_out(ctx, md, sizeof md); shake_out(ctx, md, sizeof md);
memcpy(out, md, fx_min(size_t, sizeof md, max)); memcpy(out, md, b_min(size_t, sizeof md, max));
} }
struct fx_hash_function_ops z__fx_sha3_224_ops = { struct b_hash_function_ops z__b_sha3_224_ops = {
.hash_init = sha3_224_init, .hash_init = sha3_224_init,
.hash_update = sha3_update, .hash_update = sha3_update,
.hash_finish = sha3_224_finish, .hash_finish = sha3_224_finish,
}; };
struct fx_hash_function_ops z__fx_sha3_256_ops = { struct b_hash_function_ops z__b_sha3_256_ops = {
.hash_init = sha3_256_init, .hash_init = sha3_256_init,
.hash_update = sha3_update, .hash_update = sha3_update,
.hash_finish = sha3_256_finish, .hash_finish = sha3_256_finish,
}; };
struct fx_hash_function_ops z__fx_sha3_384_ops = { struct b_hash_function_ops z__b_sha3_384_ops = {
.hash_init = sha3_384_init, .hash_init = sha3_384_init,
.hash_update = sha3_update, .hash_update = sha3_update,
.hash_finish = sha3_384_finish, .hash_finish = sha3_384_finish,
}; };
struct fx_hash_function_ops z__fx_sha3_512_ops = { struct b_hash_function_ops z__b_sha3_512_ops = {
.hash_init = sha3_512_init, .hash_init = sha3_512_init,
.hash_update = sha3_update, .hash_update = sha3_update,
.hash_finish = sha3_512_finish, .hash_finish = sha3_512_finish,
}; };
struct fx_hash_function_ops z__fx_shake128_ops = { struct b_hash_function_ops z__b_shake128_ops = {
.hash_init = shake128_init, .hash_init = shake128_init,
.hash_update = sha3_update, .hash_update = sha3_update,
.hash_finish = shake128_finish, .hash_finish = shake128_finish,
}; };
struct fx_hash_function_ops z__fx_shake256_ops = { struct b_hash_function_ops z__b_shake256_ops = {
.hash_init = shake256_init, .hash_init = shake256_init,
.hash_update = sha3_update, .hash_update = sha3_update,
.hash_finish = shake256_finish, .hash_finish = shake256_finish,

View File

@@ -1,14 +1,14 @@
#ifndef FX_CORE_BITOP_H_ #ifndef BLUELIB_CORE_BITOP_H_
#define FX_CORE_BITOP_H_ #define BLUELIB_CORE_BITOP_H_
#include <fx/core/misc.h> #include <blue/core/misc.h>
FX_API int fx_popcountl(long v); BLUE_API int b_popcountl(long v);
FX_API int fx_ctzl(long v); BLUE_API int b_ctzl(long v);
FX_API int fx_clzl(long v); BLUE_API int b_clzl(long v);
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#define fx_cmpxchg(v, expected_val, new_val) \ #define b_cmpxchg(v, expected_val, new_val) \
__atomic_compare_exchange_n( \ __atomic_compare_exchange_n( \
v, expected_val, new_val, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED) v, expected_val, new_val, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
#elif defined(_MSC_VER) #elif defined(_MSC_VER)

View File

@@ -0,0 +1,71 @@
#ifndef BLUE_CORE_BSTR_H_
#define BLUE_CORE_BSTR_H_
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdarg.h>
#include <stddef.h>
#define B_BSTR_MAGIC 0x5005500550055005ULL
struct b_rope;
enum b_bstr_flags {
B_BSTR_F_NONE = 0x00u,
B_BSTR_F_ALLOC = 0x01u,
};
typedef struct b_bstr {
uint64_t bstr_magic;
enum b_bstr_flags bstr_flags;
char *bstr_buf;
/* total number of characters in bstr_buf, not including null terminator */
size_t bstr_len;
/* number of bytes allocated for bstr_buf (includes space for the null
* terminator) */
size_t bstr_capacity;
int *bstr_istack;
int bstr_add_indent;
size_t bstr_istack_ptr, bstr_istack_size;
} b_bstr;
BLUE_API void b_bstr_begin(b_bstr *strv, char *buf, size_t max);
BLUE_API void b_bstr_begin_dynamic(b_bstr *strv);
BLUE_API char *b_bstr_end(b_bstr *strv);
BLUE_API b_status b_bstr_reserve(b_bstr *strv, size_t len);
static inline size_t b_bstr_get_size(const b_bstr *str)
{
return str->bstr_len;
}
static inline size_t b_bstr_get_capacity(const b_bstr *str)
{
return str->bstr_capacity;
}
BLUE_API b_status b_bstr_push_indent(b_bstr *strv, int indent);
BLUE_API b_status b_bstr_pop_indent(b_bstr *strv);
BLUE_API b_status b_bstr_write_char(b_bstr *strv, char c);
BLUE_API b_status b_bstr_write_chars(
b_bstr *strv, const char *cs, size_t len, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr(
b_bstr *strv, const char *str, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr_list(
b_bstr *strv, const char **strs, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr_array(
b_bstr *strv, const char **strs, size_t count, size_t *nr_written);
BLUE_API b_status b_bstr_write_cstr_varg(b_bstr *strv, size_t *nr_written, ...);
BLUE_API b_status b_bstr_write_rope(
b_bstr *strv, const struct b_rope *rope, size_t *nr_written);
BLUE_API b_status b_bstr_write_fmt(
b_bstr *strv, size_t *nr_written, const char *format, ...);
BLUE_API b_status b_bstr_write_vfmt(
b_bstr *strv, size_t *nr_written, const char *format, va_list arg);
BLUE_API char *b_bstr_rope(const struct b_rope *rope, size_t *nr_written);
BLUE_API char *b_bstr_fmt(size_t *nr_written, const char *format, ...);
BLUE_API char *b_bstr_vfmt(size_t *nr_written, const char *format, va_list arg);
#endif

View File

@@ -0,0 +1,359 @@
#ifndef BLUELIB_CORE_BTREE_H_
#define BLUELIB_CORE_BTREE_H_
#include <blue/core/iterator.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
B_DECLS_BEGIN;
#define B_BTREE_INIT {0}
#define B_TYPE_BTREE_ITERATOR (b_btree_iterator_get_type())
B_DECLARE_TYPE(b_btree_iterator);
B_TYPE_CLASS_DECLARATION_BEGIN(b_btree_iterator)
B_TYPE_CLASS_DECLARATION_END(b_btree_iterator)
/* defines a simple node insertion function.
this function assumes that your nodes have simple integer keys that can be
compared with the usual operators.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
int key;
b_btree_node base;
}
You would use the following call to generate an insert function for a tree
with this node type:
BTREE_DEFINE_SIMPLE_INSERT(
struct my_tree_node,
base,
key,
my_tree_node_insert);
Which would emit a function defined like:
static void my_tree_node_insert(b_btree *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that
contains a b_btree_node member.
@param container_node_member the name of the b_btree_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
*/
#define B_BTREE_DEFINE_SIMPLE_INSERT( \
node_type, container_node_member, container_key_member, function_name) \
void function_name(b_btree *tree, node_type *node) \
{ \
if (!tree->b_root) { \
tree->b_root = &node->container_node_member; \
b_btree_insert_fixup(tree, &node->container_node_member); \
return; \
} \
\
b_btree_node *cur = tree->b_root; \
while (1) { \
node_type *cur_node = b_unbox( \
node_type, cur, container_node_member); \
b_btree_node *next = NULL; \
\
if (node->container_key_member \
>= cur_node->container_key_member) { \
next = b_btree_right(cur); \
\
if (!next) { \
b_btree_put_right( \
cur, \
&node->container_node_member); \
break; \
} \
} else if ( \
node->container_key_member \
< cur_node->container_key_member) { \
next = b_btree_left(cur); \
\
if (!next) { \
b_btree_put_left( \
cur, \
&node->container_node_member); \
break; \
} \
} \
\
cur = next; \
} \
\
b_btree_insert_fixup(tree, &node->container_node_member); \
}
/* defines a node insertion function.
this function should be used for trees with complex node keys that cannot be
directly compared. a comparator for your keys must be supplied.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
complex_key_t key;
b_btree_node base;
}
You would need to define a comparator function or macro with the following
signature:
int my_comparator(struct my_tree_node *a, struct my_tree_node *b);
Which implements the following:
return -1 if a < b
return 0 if a == b
return 1 if a > b
You would use the following call to generate an insert function for a tree
with this node type:
BTREE_DEFINE_INSERT(struct my_tree_node, base, key, my_tree_node_insert,
my_comparator);
Which would emit a function defined like:
static void my_tree_node_insert(b_btree *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that
contains a b_btree_node member.
@param container_node_member the name of the b_btree_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
@param comparator the name of a comparator function or functional-macro that
conforms to the requirements listed above.
*/
#define B_BTREE_DEFINE_INSERT( \
node_type, container_node_member, container_key_member, function_name, \
comparator) \
void function_name(b_btree *tree, node_type *node) \
{ \
if (!tree->b_root) { \
tree->b_root = &node->container_node_member; \
b_btree_insert_fixup(tree, &node->container_node_member); \
return; \
} \
\
b_btree_node *cur = tree->b_root; \
while (1) { \
node_type *cur_node = b_unbox( \
node_type, cur, container_node_member); \
b_btree_node *next = NULL; \
int cmp = comparator(node, cur_node); \
\
if (cmp >= 0) { \
next = b_btree_right(cur); \
\
if (!next) { \
b_btree_put_right( \
cur, \
&node->container_node_member); \
break; \
} \
} else if (cmp < 0) { \
next = b_btree_left(cur); \
\
if (!next) { \
b_btree_put_left( \
cur, \
&node->container_node_member); \
break; \
} \
} else { \
return; \
} \
\
cur = next; \
} \
\
b_btree_insert_fixup(tree, &node->container_node_member); \
}
/* defines a simple tree search function.
this function assumes that your nodes have simple integer keys that can be
compared with the usual operators.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
int key;
b_btree_node base;
}
You would use the following call to generate a search function for a tree
with this node type:
BTREE_DEFINE_SIMPLE_GET(struct my_tree_node, int, base, key,
my_tree_node_get);
Which would emit a function defined like:
static struct my_tree_node *my_tree_node_get(b_btree *tree, int key);
@param node_type your custom tree node type. usually a structure that
contains a b_btree_node member.
@param key_type the type name of the key embedded in your custom tree node
type. this type must be compatible with the builtin comparison operators.
@param container_node_member the name of the b_btree_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
*/
#define B_BTREE_DEFINE_SIMPLE_GET( \
node_type, key_type, container_node_member, container_key_member, \
function_name) \
node_type *function_name(const b_btree *tree, key_type key) \
{ \
b_btree_node *cur = tree->b_root; \
while (cur) { \
node_type *cur_node = b_unbox( \
node_type, cur, container_node_member); \
if (key > cur_node->container_key_member) { \
cur = b_btree_right(cur); \
} else if (key < cur_node->container_key_member) { \
cur = b_btree_left(cur); \
} else { \
return cur_node; \
} \
} \
\
return NULL; \
}
#define b_btree_foreach(it, btree) \
for (int z__b_unique_name() = b_btree_iterator_begin(btree, it); \
(it)->node != NULL; b_btree_iterator_next(it))
/* binary tree nodes. this *cannot* be used directly. you need to define a
custom node type that contains a member variable of type b_btree_node.
you would then use the supplied macros to define functions to manipulate your
custom binary tree.
*/
typedef struct b_btree_node {
struct b_btree_node *b_parent, *b_left, *b_right;
unsigned short b_height;
} b_btree_node;
/* binary tree. unlike b_btree_node, you can define variables of type b_btree.
*/
typedef struct b_btree {
b_btree_node *b_root;
} b_btree;
BLUE_API b_type b_btree_iterator_get_type(void);
/* re-balance a binary tree after an insertion operation.
NOTE that, if you define an insertion function using BTREE_DEFINE_INSERT or
similar, this function will automatically called for you.
@param tree the tree to re-balance.
@param node the node that was just inserted into the tree.
*/
BLUE_API void b_btree_insert_fixup(b_btree *tree, b_btree_node *node);
/* delete a node from a binary tree and re-balance the tree afterwards.
@param tree the tree to delete from
@param node the node to delete.
*/
BLUE_API void b_btree_delete(b_btree *tree, b_btree_node *node);
/* get the first node in a binary tree.
this will be the node with the smallest key (i.e. the node that is
furthest-left from the root)
*/
BLUE_API b_btree_node *b_btree_first(const b_btree *tree);
/* get the last node in a binary tree.
this will be the node with the largest key (i.e. the node that is
furthest-right from the root)
*/
BLUE_API b_btree_node *b_btree_last(const b_btree *tree);
/* for any binary tree node, this function returns the node with the
* next-largest key value */
BLUE_API b_btree_node *b_btree_next(const b_btree_node *node);
/* for any binary tree node, this function returns the node with the
* next-smallest key value */
BLUE_API b_btree_node *b_btree_prev(const b_btree_node *node);
/* return true if the btree is empty, false otherwise */
static inline bool b_btree_empty(const b_btree *tree)
{
return tree->b_root == NULL;
}
/* sets `child` as the immediate left-child of `parent` */
static inline void b_btree_put_left(b_btree_node *parent, b_btree_node *child)
{
parent->b_left = child;
child->b_parent = parent;
}
/* sets `child` as the immediate right-child of `parent` */
static inline void b_btree_put_right(b_btree_node *parent, b_btree_node *child)
{
parent->b_right = child;
child->b_parent = parent;
}
/* get the immediate left-child of `node` */
static inline b_btree_node *b_btree_left(b_btree_node *node)
{
return node->b_left;
}
/* get the immediate right-child of `node` */
static inline b_btree_node *b_btree_right(b_btree_node *node)
{
return node->b_right;
}
/* get the immediate parent of `node` */
static inline b_btree_node *b_btree_parent(b_btree_node *node)
{
return node->b_parent;
}
BLUE_API void b_btree_move(b_btree *tree, b_btree_node *dest, b_btree_node *src);
/* get the height of `node`.
the height of a node is defined as the length of the longest path
between the node and a leaf node.
this count includes the node itself, so the height of a leaf node will be 1.
*/
static inline unsigned short b_btree_height(b_btree_node *node)
{
return node->b_height;
}
BLUE_API b_iterator *b_btree_begin(b_btree *tree);
BLUE_API const b_iterator *b_btree_cbegin(const b_btree *tree);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,15 @@
#ifndef BLUE_OBJECT_CLASS_H_
#define BLUE_OBJECT_CLASS_H_
#include <blue/core/type.h>
#define B_CLASS_MAGIC 0xDEADFACEDCAFEBEDULL
#define B_CLASS(p) ((b_class *)(p))
typedef struct _b_class b_class;
BLUE_API void *b_class_get(b_type id);
BLUE_API const char *b_class_get_name(const b_class *c);
BLUE_API void *b_class_get_interface(const b_class *c, b_type id);
#endif

View File

@@ -0,0 +1,45 @@
#ifndef BLUE_CORE_ENCODING_H_
#define BLUE_CORE_ENCODING_H_
#include <blue/core/misc.h>
#include <stdbool.h>
#include <stdint.h>
B_DECLS_BEGIN;
#define B_WCHAR_INVALID ((b_wchar) - 1)
typedef int32_t b_wchar;
BLUE_API bool b_wchar_is_alpha(b_wchar c);
BLUE_API bool b_wchar_is_number(b_wchar c);
static inline bool b_wchar_is_bin_digit(b_wchar c)
{
return c >= '0' && c <= '1';
}
static inline bool b_wchar_is_oct_digit(b_wchar c)
{
return c >= '0' && c <= '7';
}
BLUE_API bool b_wchar_is_hex_digit(b_wchar c);
BLUE_API bool b_wchar_is_space(b_wchar c);
static inline bool b_wchar_is_alnum(b_wchar c)
{
return b_wchar_is_alpha(c) || b_wchar_is_number(c);
}
BLUE_API bool b_wchar_is_punct(b_wchar c);
BLUE_API bool b_wchar_utf8_is_valid_scalar(b_wchar c);
BLUE_API unsigned int b_wchar_utf8_header_decode(char c);
BLUE_API unsigned int b_wchar_utf8_codepoint_size(b_wchar c);
BLUE_API b_wchar b_wchar_utf8_codepoint_decode(const char *s);
BLUE_API unsigned int b_wchar_utf8_codepoint_encode(b_wchar c, char s[4]);
BLUE_API unsigned int b_wchar_utf8_codepoint_stride(const char *s);
BLUE_API size_t b_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes);
BLUE_API size_t b_wchar_utf8_string_encoded_size(
const b_wchar *s, size_t nr_codepoints);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,49 @@
#ifndef BLUELIB_CORE_ENDIAN_H_
#define BLUELIB_CORE_ENDIAN_H_
#include <blue/core/misc.h>
#include <stdint.h>
typedef struct {
union {
unsigned char i_bytes[sizeof(uint16_t)];
int16_t i_val;
uint16_t i_uval;
};
} b_i16;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint32_t)];
int32_t i_val;
uint32_t i_uval;
};
} b_i32;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint64_t)];
int64_t i_val;
uint64_t i_uval;
};
} b_i64;
BLUE_API b_i16 b_i16_htob(uint16_t v);
BLUE_API b_i16 b_i16_htos(uint16_t v);
BLUE_API uint16_t b_i16_btoh(b_i16 v);
BLUE_API uint16_t b_i16_stoh(b_i16 v);
BLUE_API b_i32 b_i32_htob(uint32_t v);
BLUE_API b_i32 b_i32_htos(uint32_t v);
BLUE_API uint32_t b_i32_btoh(b_i32 v);
BLUE_API uint32_t b_i32_stoh(b_i32 v);
BLUE_API b_i64 b_i64_htob(uint64_t v);
BLUE_API b_i64 b_i64_htos(uint64_t v);
BLUE_API uint64_t b_i64_btoh(b_i64 v);
BLUE_API uint64_t b_i64_stoh(b_i64 v);
#endif

View File

@@ -0,0 +1,418 @@
#ifndef BLUE_CORE_ERROR_H_
#define BLUE_CORE_ERROR_H_
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdarg.h>
#include <stdbool.h>
#define B_ERROR_TEMPLATE_PARAMETER_MAX 4
#define B_ERROR_MSG_ID_INVALID ((unsigned long)-1)
#define B_CATCH(err, expr) ((err = (expr)) != NULL)
#define b_result_is_error(result) ((result) != NULL)
#define b_result_is_success(result) ((result) == NULL)
#define B_RESULT_SUCCESS ((b_result)NULL)
#define B_RESULT_ERR(err_name) \
b_error_with_code(b_error_vendor_get_builtin(), B_ERR_##err_name)
#define B_RESULT_ERR_WITH_STRING(err_name, ...) \
b_error_with_string( \
b_error_vendor_get_builtin(), B_ERR_##err_name, __VA_ARGS__)
#define B_RESULT_STATUS(code) \
((code) == B_SUCCESS \
? B_RESULT_SUCCESS \
: (b_error_with_code(b_error_vendor_get_builtin(), code)))
#define B_RESULT_STATUS_WITH_STRING(code, ...) \
((code) == B_SUCCESS \
? B_RESULT_SUCCESS \
: (b_error_with_string( \
b_error_vendor_get_builtin(), code, __VA_ARGS__)))
#define B_ERRORS_BUILTIN (b_error_vendor_get_builtin())
#define B_ERRORS_ERRNO (b_error_vendor_get_errno())
#define B_ERROR_PARAM(name, value) \
(b_error_template_parameter) \
{ \
.param_name = (name), .param_value = (uintptr_t)(value), \
}
#define B_ERROR_TEMPLATE_PARAM(name, type, format) \
(b_error_template_parameter_definition) \
{ \
.param_name = (name), .param_type = (type), \
.param_format = (format), \
}
#define B_ERROR_DEFINITION(code, name, msg) \
[code] = (b_error_definition) \
{ \
.err_name = (name), .err_message = (msg), \
}
#define B_ERROR_DEFINITION_TEMPLATE(code, name, msg, ...) \
[code] = (b_error_definition) \
{ \
.err_name = (name), .err_message = (msg), \
.err_params = __VA_ARGS__, \
}
#define B_ERROR_MSG(id, content) \
[id] = (b_error_msg) \
{ \
.msg_message = (content), \
}
#define B_ERROR_MSG_TEMPLATE(id, content, ...) \
[id] = (b_error_msg) \
{ \
.msg_message = (content), .msg_params = __VA_ARGS__, \
}
#define z__b_error_create_status(status_code) \
(z__b_error_create( \
b_error_vendor_get_builtin(), status_code, NULL, NULL, 0, \
NULL, NULL))
/* Error creation macros */
#define b_error_with_code(vendor, code) \
(z__b_error_create( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_caused_by_error(vendor, code, cause_error) \
(z__b_error_create( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_caused_by_status(vendor, code, cause_status) \
(z__b_error_create( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_caused_by_code(vendor, code, cause_vendor, cause_code) \
(z__b_error_create( \
vendor, code, b_error_with_code(cause_vendor, cause_code), \
__FILE__, __LINE__, __FUNCTION__, NULL))
#define b_error_with_string(vendor, code, ...) \
(z__b_error_create( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#define b_error_with_string_caused_by_error(vendor, code, cause_error, ...) \
(z__b_error_create( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
__VA_ARGS__))
#define b_error_with_string_caused_by_status(vendor, code, cause_status, ...) \
(z__b_error_create( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#define b_error_with_msg(vendor, code, msg_id) \
(z__b_error_create_msg( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {{}}))
#define b_error_with_msg_caused_by_error(vendor, code, cause_error, msg_id) \
(z__b_error_create_msg( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
msg_id, (b_error_template_parameter[]) {{}}))
#define b_error_with_msg_caused_by_status(vendor, code, cause_status, msg_id) \
(z__b_error_create_msg( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {{}}))
#define b_error_with_msg_template(vendor, code, msg_id, ...) \
(z__b_error_create_msg( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_msg_template_caused_by_error( \
vendor, code, cause_error, msg_id, ...) \
(z__b_error_create_msg( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
msg_id, (b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_msg_template_caused_by_status( \
vendor, code, cause_status, msg_id, ...) \
(z__b_error_create_msg( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, msg_id, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_template(vendor, code, ...) \
(z__b_error_create_template( \
vendor, code, NULL, __FILE__, __LINE__, __FUNCTION__, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_template_caused_by_error(vendor, code, cause_error, ...) \
(z__b_error_create_template( \
vendor, code, cause_error, __FILE__, __LINE__, __FUNCTION__, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
#define b_error_with_template_caused_by_status(vendor, code, cause_status, ...) \
(z__b_error_create_template( \
vendor, code, z__b_error_create_status(cause_status), \
__FILE__, __LINE__, __FUNCTION__, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
/* Error propagation macros */
#define b_result_propagate(err) \
(z__b_error_propagate(err, __FILE__, __LINE__, __FUNCTION__))
#define b_error_caused_by(err, caused_by) (z__b_error_caused_by(err, caused_by))
#define b_error_caused_by_b_status(err, status) \
(z__b_error_caused_by_b_status(err, status))
#define b_error_replace(err, caused_by) \
(z__b_error_propagate(err, __FILE__, __LINE__, __FUNCTION__))
/* Error throw macros */
#define z__b_throw(err) (z__b_error_throw(err, NULL, 0, NULL))
#define b_throw(err) (z__b_error_throw(err, __FILE__, __LINE__, __FUNCTION__))
#define b_throw_status(status) \
(z__b_error_throw( \
z__b_error_create( \
b_error_vendor_get_builtin(), status, NULL, NULL, 0, \
NULL, NULL), \
__FILE__, __LINE__, __FUNCTION__))
#define b_throw_status_string(status, ...) \
(z__b_error_throw( \
z__b_error_create( \
b_error_vendor_get_builtin(), status, NULL, NULL, 0, \
NULL, __VA_ARGS__), \
__FILE__, __LINE__, __FUNCTION__))
#define b_throw_error_code(vendor, code) \
z__b_throw(b_error_with_code(vendor, code))
#define b_throw_error_caused_by_error(vendor, code, cause) \
z__b_throw(b_error_caused_by_error(vendor, code, cause))
#define b_throw_error_caused_by_status(vendor, code, cause) \
z__b_throw(b_error_caused_by_status(vendor, code, cause))
#define b_throw_error_with_string(vendor, code, ...) \
z__b_throw(b_error_with_string(vendor, code, __VA_ARGS__))
#define b_throw_error_with_string_caused_by_error(vendor, code, cause, ...) \
z__b_throw(b_error_with_string_caused_by_error( \
vendor, code, cause, __VA_ARGS__))
#define b_throw_error_with_string_caused_by_status(vendor, code, cause, ...) \
z__b_throw(b_error_with_string_caused_by_status( \
vendor, code, cause, __VA_ARGS__))
#define b_throw_error_with_msg(vendor, code, msg_id) \
z__b_throw(b_error_with_msg(vendor, code, msg_id))
#define b_throw_error_with_msg_caused_by_error(vendor, code, cause, msg_id) \
z__b_throw(b_error_with_msg_caused_by_error(vendor, code, cause, msg_id))
#define b_throw_error_with_msg_caused_by_status(vendor, code, cause, msg_id) \
z__b_throw(b_error_with_msg_caused_by_status(vendor, code, cause, msg_id))
#define b_throw_error_with_msg_template(vendor, code, msg_id, ...) \
z__b_throw(b_error_with_msg_template(vendor, code, msg_id, __VA_ARGS__))
#define b_throw_error_with_msg_template_caused_by_error( \
vendor, code, cause, msg_id, ...) \
z__b_throw(b_error_with_msg_template_caused_by_error( \
vendor, code, cause, msg_id, __VA_ARGS__))
#define b_throw_error_with_msg_template_caused_by_status( \
vendor, code, cause, msg_id, ...) \
z__b_throw(b_error_with_msg_template_caused_by_status( \
vendor, code, cause, msg_id, __VA_ARGS__))
#define b_throw_error_with_template(vendor, code, ...) \
z__b_throw(b_error_with_template(vendor, code, __VA_ARGS__))
#define b_throw_error_with_template_caused_by_error(vendor, code, cause, ...) \
z__b_throw(b_error_with_template_caused_by_error( \
vendor, code, cause, __VA_ARGS__))
#define b_throw_error_with_template_caused_by_status(vendor, code, cause, ...) \
z__b_throw(b_error_with_template_caused_by_status( \
vendor, code, cause, __VA_ARGS__))
#define B_ERR_MSG(s) \
{ \
.msg_type = B_ERROR_MESSAGE_ERROR, \
.msg_content = (s), \
}
#define B_ERR_MSG_WARN(s) \
{ \
.msg_type = B_ERROR_MESSAGE_WARN, \
.msg_content = (s), \
}
#define B_ERR_MSG_INFO(s) \
{ \
.msg_type = B_ERROR_MESSAGE_INFO, \
.msg_content = (s), \
}
#define B_ERR_MSG_END(s) \
{ \
.msg_type = B_ERROR_MESSAGE_NONE, \
.msg_content = NULL, \
}
typedef enum b_error_submsg_type {
B_ERROR_SUBMSG_NONE = 0,
B_ERROR_SUBMSG_ERROR,
B_ERROR_SUBMSG_WARNING,
B_ERROR_SUBMSG_INFO,
} b_error_submsg_type;
typedef enum b_error_report_flags {
B_ERROR_REPORT_NONE = 0,
B_ERROR_REPORT_STATUS = 0x01u,
B_ERROR_REPORT_DESCRIPTION = 0x02u,
B_ERROR_REPORT_SUBMSG = 0x04u,
B_ERROR_REPORT_STACK_TRACE = 0x08u,
B_ERROR_REPORT_CAUSE = 0x10u,
B_ERROR_REPORT_MINIMAL = B_ERROR_REPORT_STATUS | B_ERROR_REPORT_DESCRIPTION,
B_ERROR_REPORT_DEFAULT = B_ERROR_REPORT_MINIMAL | B_ERROR_REPORT_SUBMSG
| B_ERROR_REPORT_CAUSE,
B_ERROR_REPORT_ALL = B_ERROR_REPORT_DEFAULT | B_ERROR_REPORT_STACK_TRACE,
} b_error_report_flags;
typedef enum b_error_template_parameter_type {
B_ERROR_TEMPLATE_PARAM_NONE = 0,
B_ERROR_TEMPLATE_PARAM_STRING,
B_ERROR_TEMPLATE_PARAM_CHAR,
B_ERROR_TEMPLATE_PARAM_INT,
B_ERROR_TEMPLATE_PARAM_UINT,
B_ERROR_TEMPLATE_PARAM_LONG,
B_ERROR_TEMPLATE_PARAM_ULONG,
B_ERROR_TEMPLATE_PARAM_LONGLONG,
B_ERROR_TEMPLATE_PARAM_ULONGLONG,
B_ERROR_TEMPLATE_PARAM_SIZE_T,
B_ERROR_TEMPLATE_PARAM_INTPTR,
B_ERROR_TEMPLATE_PARAM_UINTPTR,
B_ERROR_TEMPLATE_PARAM_PTR,
} b_error_template_parameter_type;
typedef struct b_error_template_parameter_definition {
const char *param_name;
b_error_template_parameter_type param_type;
const char *param_format;
} b_error_template_parameter_definition;
typedef struct b_error_template_parameter {
const char *param_name;
uintptr_t param_value;
const struct b_error_template_parameter_definition *__param_def;
} b_error_template_parameter;
struct b_error_vendor;
typedef struct b_error b_error;
typedef struct b_error *b_result;
typedef struct b_error_submsg b_error_submsg;
typedef struct b_error_stack_frame b_error_stack_frame;
typedef long b_error_status_code;
typedef unsigned long b_error_msg_id;
typedef struct b_error_definition {
const char *err_name;
const char *err_message;
const b_error_template_parameter_definition err_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
} b_error_definition;
typedef struct b_error_msg {
const char *msg_message;
const b_error_template_parameter_definition msg_params[B_ERROR_TEMPLATE_PARAMETER_MAX];
} b_error_msg;
typedef const b_error_definition *(*b_error_status_code_get_definition)(
const struct b_error_vendor *, b_error_status_code);
typedef const b_error_msg *(*b_error_msg_get_definition)(
const struct b_error_vendor *, b_error_msg_id);
typedef void (*b_error_report_function)(
const struct b_error *, b_error_report_flags);
typedef struct b_error_vendor {
const char *v_name;
b_error_status_code_get_definition v_status_get_definition;
b_error_msg_get_definition v_msg_get_definition;
const b_error_definition *v_error_definitions;
size_t v_error_definitions_length;
const b_error_msg *v_msg;
size_t v_msg_length;
} b_error_vendor;
BLUE_API b_error *z__b_error_create_template(
const b_error_vendor *, b_error_status_code, b_error *, const char *,
unsigned int, const char *, const b_error_template_parameter[]);
BLUE_API b_error *z__b_error_create_string(
const b_error_vendor *, b_error_status_code, b_error *, const char *,
unsigned int, const char *, const char *, va_list);
BLUE_API b_error *z__b_error_create_msg(
const b_error_vendor *, b_error_status_code, b_error *, const char *,
unsigned int, const char *, b_error_msg_id,
const b_error_template_parameter[]);
BLUE_API b_error *z__b_error_propagate(
b_error *, const char *, unsigned int, const char *);
BLUE_API b_error *z__b_error_caused_by(b_error *, b_error *);
BLUE_API b_error *z__b_error_caused_by_b_status(b_error *, b_status);
BLUE_API void z__b_error_throw(b_error *, const char *, unsigned int, const char *);
BLUE_API bool b_result_is(
b_result result, const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const b_error_vendor *b_error_vendor_get_builtin(void);
BLUE_API const b_error_vendor *b_error_vendor_get_errno(void);
BLUE_API const b_error_definition *b_error_vendor_get_error_definition(
const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const char *b_error_vendor_get_status_code_name(
const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const char *b_error_vendor_get_status_code_description(
const b_error_vendor *vendor, b_error_status_code code);
BLUE_API const b_error_msg *b_error_vendor_get_msg(
const b_error_vendor *vendor, b_error_msg_id msg_id);
static inline b_error *z__b_error_create(
const b_error_vendor *v, b_error_status_code c, b_error *c2,
const char *f0, unsigned int l, const char *f1, const char *d, ...)
{
va_list arg;
va_start(arg, d);
b_error *err = z__b_error_create_string(v, c, c2, f0, l, f1, d, arg);
va_end(arg);
return err;
}
BLUE_API enum b_status b_error_add_submsg_string(
b_error *error, b_error_submsg_type type, const char *msg, ...);
BLUE_API enum b_status z__b_error_add_submsg_template(
b_error *error, b_error_submsg_type type, b_error_msg_id msg_id,
b_error_template_parameter param[]);
#define b_error_add_submsg(error, type, msg_id) \
(z__b_error_add_submsg_template( \
error, type, msg_id, (b_error_template_parameter[]) {{}}))
#define b_error_add_submsg_template(error, type, msg_id, ...) \
(z__b_error_add_submsg_template( \
error, type, msg_id, \
(b_error_template_parameter[]) {__VA_ARGS__, {}}))
BLUE_API void b_error_discard(b_error *error);
BLUE_API b_error_status_code b_error_get_status_code(const b_error *error);
BLUE_API const b_error_vendor *b_error_get_vendor(const b_error *error);
BLUE_API const b_error_definition *b_error_get_definition(const b_error *error);
BLUE_API const b_error_template_parameter *b_error_get_template_parameter(
const b_error *error, const char *param_name);
BLUE_API const b_error_template_parameter *b_error_get_template_parameters(
const b_error *error);
BLUE_API const char *b_error_get_description(const b_error *error);
BLUE_API const b_error_msg *b_error_get_msg(const b_error *error);
BLUE_API const b_error_submsg *b_error_get_first_submsg(const b_error *error);
BLUE_API const b_error_submsg *b_error_get_next_submsg(
const b_error *error, const b_error_submsg *msg);
BLUE_API const b_error_stack_frame *b_error_get_first_stack_frame(
const b_error *error);
BLUE_API const b_error_stack_frame *b_error_get_next_stack_frame(
const b_error *error, const b_error_stack_frame *frame);
BLUE_API const b_error *b_error_get_caused_by(const b_error *error);
BLUE_API b_error_submsg_type b_error_submsg_get_type(const b_error_submsg *msg);
BLUE_API const char *b_error_submsg_get_content(const b_error_submsg *msg);
BLUE_API const b_error_msg *b_error_submsg_get_msg(const b_error_submsg *msg);
BLUE_API const b_error_template_parameter *b_error_submsg_get_template_parameters(
const b_error_submsg *msg);
BLUE_API const char *b_error_stack_frame_get_filepath(
const b_error_stack_frame *frame);
BLUE_API unsigned int b_error_stack_frame_get_line_number(
const b_error_stack_frame *frame);
BLUE_API const char *b_error_stack_frame_get_function_name(
const b_error_stack_frame *frame);
BLUE_API const b_error_template_parameter_definition *b_error_definition_get_template_parameter(
const b_error_definition *error_def, const char *param_name);
BLUE_API const char *b_error_msg_get_content(const b_error_msg *msg);
BLUE_API const b_error_template_parameter_definition *b_error_msg_get_template_parameter(
const b_error_msg *msg, const char *param_name);
BLUE_API void b_set_error_report_function(
b_error_report_function func, b_error_report_flags flags);
#endif

View File

@@ -0,0 +1,111 @@
#ifndef BLUELIB_CORE_HASH_H_
#define BLUELIB_CORE_HASH_H_
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stddef.h>
#include <stdint.h>
#define B_DIGEST_LENGTH_128 16
#define B_DIGEST_LENGTH_160 20
#define B_DIGEST_LENGTH_192 24
#define B_DIGEST_LENGTH_224 28
#define B_DIGEST_LENGTH_256 32
#define B_DIGEST_LENGTH_384 48
#define B_DIGEST_LENGTH_512 64
#define B_DIGEST_LENGTH_MD4 B_DIGEST_LENGTH_128
#define B_DIGEST_LENGTH_MD5 B_DIGEST_LENGTH_128
#define B_DIGEST_LENGTH_SHA1 B_DIGEST_LENGTH_160
#define B_DIGEST_LENGTH_SHA2_224 B_DIGEST_LENGTH_224
#define B_DIGEST_LENGTH_SHA2_256 B_DIGEST_LENGTH_256
#define B_DIGEST_LENGTH_SHA2_384 B_DIGEST_LENGTH_384
#define B_DIGEST_LENGTH_SHA2_512 B_DIGEST_LENGTH_512
#define B_DIGEST_LENGTH_SHA3_224 B_DIGEST_LENGTH_224
#define B_DIGEST_LENGTH_SHA3_256 B_DIGEST_LENGTH_256
#define B_DIGEST_LENGTH_SHA3_384 B_DIGEST_LENGTH_384
#define B_DIGEST_LENGTH_SHA3_512 B_DIGEST_LENGTH_512
#define B_DIGEST_LENGTH_SHAKE128 B_DIGEST_LENGTH_128
#define B_DIGEST_LENGTH_SHAKE256 B_DIGEST_LENGTH_256
struct b_hash_function_ops;
struct b_rope;
typedef enum b_hash_function {
B_HASH_NONE = 0,
B_HASH_MD4,
B_HASH_MD5,
B_HASH_SHA1,
B_HASH_SHA2_224,
B_HASH_SHA2_256,
B_HASH_SHA2_384,
B_HASH_SHA2_512,
B_HASH_SHA3_224,
B_HASH_SHA3_256,
B_HASH_SHA3_384,
B_HASH_SHA3_512,
B_HASH_SHAKE128,
B_HASH_SHAKE256,
} b_hash_function;
typedef struct b_hash_ctx {
b_hash_function ctx_func;
const struct b_hash_function_ops *ctx_ops;
union {
struct {
uint32_t lo, hi;
uint32_t a, b, c, d;
uint32_t block[16];
unsigned char buffer[64];
} md4;
struct {
unsigned int count[2];
unsigned int a, b, c, d;
unsigned int block[16];
unsigned char input[64];
} md5;
struct {
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} sha1;
struct {
uint64_t curlen;
uint64_t length;
unsigned char buf[128];
uint32_t state[8];
} sha2_256;
struct {
uint64_t curlen;
uint64_t length;
unsigned char block[256];
uint64_t state[8];
} sha2_512;
struct {
union {
uint8_t b[200];
uint64_t q[25];
} st;
int pt, rsiz, mdlen;
} sha3;
} ctx_state;
} b_hash_ctx;
BLUE_API uint64_t b_hash_cstr(const char *s);
BLUE_API uint64_t b_hash_cstr_ex(const char *s, size_t *len);
BLUE_API b_status b_hash_ctx_init(b_hash_ctx *ctx, b_hash_function func);
BLUE_API b_status b_hash_ctx_reset(b_hash_ctx *ctx);
BLUE_API b_status b_hash_ctx_update(b_hash_ctx *ctx, const void *p, size_t len);
BLUE_API b_status b_hash_ctx_update_rope(b_hash_ctx *ctx, const struct b_rope *rope);
BLUE_API b_status b_hash_ctx_finish(
b_hash_ctx *ctx, void *out_digest, size_t out_max);
#endif

View File

@@ -1,8 +1,8 @@
#ifndef FX_INIT_H_ #ifndef BLUELIB_INIT_H_
#define FX_INIT_H_ #define BLUELIB_INIT_H_
#ifdef __cplusplus #ifdef __cplusplus
#define FX_INIT(f) \ #define B_INIT(f) \
static void f(void); \ static void f(void); \
struct f##_t_ { \ struct f##_t_ { \
f##_t_(void) \ f##_t_(void) \
@@ -14,17 +14,17 @@
static void f(void) static void f(void)
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#pragma section(".CRT$XCU", read) #pragma section(".CRT$XCU", read)
#define FX_INIT2_(f, p) \ #define B_INIT2_(f, p) \
static void f(void); \ static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \ __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker, "/include:" p #f "_")) static void f(void) __pragma(comment(linker, "/include:" p #f "_")) static void f(void)
#ifdef _WIN64 #ifdef _WIN64
#define FX_INIT(f) FX_INIT2_(f, "") #define B_INIT(f) B_INIT2_(f, "")
#else #else
#define FX_INIT(f) FX_INIT2_(f, "_") #define B_INIT(f) B_INIT2_(f, "_")
#endif #endif
#else #else
#define FX_INIT(f) \ #define B_INIT(f) \
static void f(void) __attribute__((constructor)); \ static void f(void) __attribute__((constructor)); \
static void f(void) static void f(void)
#endif #endif

View File

@@ -0,0 +1,93 @@
#ifndef BLUE_CORE_ITERATOR_H_
#define BLUE_CORE_ITERATOR_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdbool.h>
B_DECLS_BEGIN;
#define b_foreach(type, var, iterator) \
for (type var = (type)b_iterator_get_value(iterator).v_int; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (type)b_iterator_get_value(iterator).v_int)
#define b_foreach_ptr(type, var, iterator) \
for (type *var = (type *)b_iterator_get_value(iterator).v_ptr; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (type *)b_iterator_get_value(iterator).v_ptr)
#define b_foreach_c(type, var, iterator) \
for (type var = (type)b_iterator_get_cvalue(iterator).v_int; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (type)b_iterator_get_cvalue(iterator).v_int)
#define b_foreach_cptr(type, var, iterator) \
for (const type *var \
= (const type *)b_iterator_get_cvalue(iterator).v_cptr; \
B_OK(b_iterator_get_status(iterator)); \
b_iterator_move_next(iterator), \
var = (const type *)b_iterator_get_cvalue(iterator).v_cptr)
#define B_ITERATOR_VALUE_INT(v) ((b_iterator_value) {.v_int = (v)})
#define B_ITERATOR_VALUE_PTR(v) ((b_iterator_value) {.v_ptr = (v)})
#define B_ITERATOR_VALUE_CPTR(v) ((const b_iterator_value) {.v_cptr = (v)})
#define B_ITERATOR_VALUE_NULL ((b_iterator_value) {})
#define B_ITERATOR_VALUE_IS_NULL(v) ((v)->v_ptr == NULL)
#define B_TYPE_ITERATOR (b_iterator_get_type())
#define B_TYPE_ITERABLE (b_iterable_get_type())
typedef union b_iterator_value {
uintptr_t v_int;
void *v_ptr;
const void *v_cptr;
} b_iterator_value;
__B_DECLARE_TYPE(b_iterator);
B_DECLARE_TYPE(b_iterable);
B_TYPE_CLASS_DECLARATION_BEGIN(b_iterator)
b_status (*it_move_next)(const b_iterator *);
b_status (*it_erase)(b_iterator *);
b_iterator_value (*it_get_value)(b_iterator *);
const b_iterator_value (*it_get_cvalue)(const b_iterator *);
B_TYPE_CLASS_DECLARATION_END(b_iterator)
B_TYPE_CLASS_DECLARATION_BEGIN(b_iterable)
b_iterator *(*it_begin)(b_iterable *);
const b_iterator *(*it_cbegin)(const b_iterable *);
B_TYPE_CLASS_DECLARATION_END(b_iterable)
BLUE_API b_type b_iterator_get_type(void);
BLUE_API b_type b_iterable_get_type(void);
static inline const b_iterator *b_iterator_ref(const b_iterator *p)
{
return b_object_ref((b_object *)p);
}
static inline void b_iterator_unref(const b_iterator *p)
{
b_object_unref((b_object *)p);
}
BLUE_API b_iterator *b_iterator_begin(b_iterable *it);
BLUE_API const b_iterator *b_iterator_cbegin(const b_iterable *it);
BLUE_API b_status b_iterator_get_status(const b_iterator *it);
BLUE_API b_status b_iterator_set_status(const b_iterator *it, b_status status);
BLUE_API b_status b_iterator_move_next(const b_iterator *it);
BLUE_API b_iterator_value b_iterator_get_value(b_iterator *it);
BLUE_API const b_iterator_value b_iterator_get_cvalue(const b_iterator *it);
BLUE_API b_status b_iterator_erase(b_iterator *it);
static inline bool b_iterator_is_valid(const b_iterator *it)
{
return B_OK(b_iterator_get_status(it));
}
B_DECLS_END;
#endif

View File

@@ -0,0 +1,192 @@
#ifndef BLUE_CORE_MACROS_H_
#define BLUE_CORE_MACROS_H_
#include <blue/core/class.h>
#include <blue/core/misc.h>
#include <blue/core/object.h>
#include <blue/core/thread.h>
#include <blue/core/type.h>
#include <stdlib.h>
#define __B_IFACE_I0(p, x) p##x
#define __B_IFACE_I1(p, x) __B_IFACE_I0(p, x)
#define B_STRUCT_EMPTY char _x
/* Type definitions macros (for use in .c source file) */
#define B_TYPE_CLASS_DEFINITION_BEGIN(type_name) \
static void type_name##_class_init(b_class *p, void *d) \
{
#define B_TYPE_CLASS_DEFINITION_END(type_name) }
#define B_TYPE_CLASS_INTERFACE_BEGIN(interface_name, interface_id) \
interface_name##_class *__B_IFACE_I1(iface, __LINE__) \
= b_class_get_interface(p, interface_id); \
if (!__B_IFACE_I1(iface, __LINE__)) { \
b_throw_error_with_msg_template( \
B_ERRORS_BUILTIN, B_ERR_CLASS_INIT_FAILURE, \
B_MSG_CLASS_SPECIFIES_UNKNOWN_INTERFACE, \
B_ERROR_PARAM("class_name", b_class_get_name(p)), \
B_ERROR_PARAM("interface_name", #interface_name)); \
exit(-1); \
} else { \
interface_name##_class *iface = __B_IFACE_I1(iface, __LINE__);
#define B_TYPE_CLASS_INTERFACE_END(interface_name, interface_id) }
#define B_INTERFACE_ENTRY(slot) iface->slot
#define B_TYPE_DEFINITION_BEGIN(name) \
static b_type_info name##_type_info = {0}; \
static void name##_class_init(b_class *, void *); \
static void name##_type_init(void) \
{ \
b_type_info *type_info = &name##_type_info; \
unsigned int nr_vtables = 0; \
type_info->t_name = #name; \
type_info->t_class_init = name##_class_init;
#define B_TYPE_DEFINITION_END(name) \
b_result result = b_type_register(type_info); \
if (b_result_is_error(result)) { \
b_throw_error_caused_by_error( \
B_ERRORS_BUILTIN, B_ERR_TYPE_REGISTRATION_FAILURE, \
result); \
abort(); \
} \
} \
b_type name##_get_type(void) \
{ \
static b_once static_type_init = B_ONCE_INIT; \
\
if (b_init_once(&static_type_init)) { \
name##_type_init(); \
} \
\
return &name##_type_info.t_id; \
}
#define B_TYPE_ID(a, b, c, d, e) b_type_id_init(&type_info->t_id, a, b, c, d, e)
#define B_TYPE_EXTENDS(parent_id) \
b_type_id_copy(parent_id, &type_info->t_parent_id)
#define B_TYPE_IMPLEMENTS(interface_id) \
b_type_id_copy( \
interface_id, \
&type_info->t_interfaces[type_info->t_nr_interfaces++])
#define B_TYPE_CLASS(class_struct) \
type_info->t_class_size = sizeof(class_struct)
#define B_TYPE_FLAGS(flags) type_info->t_flags = (flags)
#define B_TYPE_INSTANCE_INIT(func) type_info->t_instance_init = (func)
#define B_TYPE_INSTANCE_FINI(func) type_info->t_instance_fini = (func)
#if 0
#define B_TYPE_VTABLE_BEGIN(vtable_struct, interface_id) \
vtable_struct __B_IFACE_I1(iface, __LINE__) = {0}; \
{ \
vtable_struct *iface = &__B_IFACE_I1(iface, __LINE__); \
type_info->t_vtables[nr_vtables].v_vtable = iface; \
type_info->t_vtables[nr_vtables].v_interface_id = interface_id; \
nr_vtables++;
#define B_TYPE_VTABLE_END(vtable_struct, interface_id) }
#endif
#define B_TYPE_INSTANCE_PRIVATE(instance_struct) \
type_info->t_instance_private_size = sizeof(instance_struct)
#define B_TYPE_INSTANCE_PROTECTED(instance_struct) \
type_info->t_instance_protected_size = sizeof(instance_struct)
/* Type declaration macros (for use in .h header file) */
#define __B_DECLARE_TYPE(name) \
typedef B_TYPE_FWDREF(name) name; \
typedef struct _##name##_class name##_class;
#define B_DECLARE_TYPE(name) \
__B_DECLARE_TYPE(name); \
static inline name *name##_ref(name *p) \
{ \
return b_object_ref(p); \
} \
static inline void name##_unref(name *p) \
{ \
b_object_unref(p); \
}
#define B_TYPE_CLASS_DECLARATION_BEGIN(name) struct _##name##_class {
#define B_TYPE_CLASS_DECLARATION_END(name) \
} \
;
#define B_TYPE_VIRTUAL_METHOD(return_type, method_name) \
return_type(*method_name)
#define B_TYPE_DEFAULT_CONSTRUCTOR(type_name, type_id) \
static inline type_name *type_name##_create(void) \
{ \
return b_object_create(type_id); \
}
/* Other macros */
#define B_CLASS_DISPATCH_VIRTUAL( \
type_name, type_id, default_value, func, object, ...) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
return iface->func(object, __VA_ARGS__); \
} else { \
return default_value; \
} \
} while (0)
#define B_CLASS_DISPATCH_VIRTUAL_0(type_name, type_id, default_value, func, object) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
return iface->func(object); \
} else { \
return default_value; \
} \
} while (0)
#define B_CLASS_DISPATCH_VIRTUAL_V(type_name, type_id, func, object, ...) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
iface->func(object, __VA_ARGS__); \
return; \
} \
} while (0)
#define B_CLASS_DISPATCH_VIRTUAL_V0(type_name, type_id, func, object) \
do { \
type_name##_class *iface \
= b_object_get_interface(object, type_id); \
if (iface && iface->func) { \
iface->func(object); \
return; \
} \
} while (0)
#define B_CLASS_DISPATCH_STATIC(type_id, func_name, obj, ...) \
do { \
void *priv = b_object_get_private(obj, type_id); \
return func_name(priv, __VA_ARGS__); \
} while (0)
#define B_CLASS_DISPATCH_STATIC_V(type_id, func_name, obj, ...) \
do { \
void *priv = b_object_get_private(obj, type_id); \
func_name(priv, __VA_ARGS__); \
} while (0)
#define B_CLASS_DISPATCH_STATIC_0(type_id, func_name, obj) \
do { \
void *priv = b_object_get_private(obj, type_id); \
return func_name(priv); \
} while (0)
#define B_CLASS_DISPATCH_STATIC_V0(type_id, func_name, obj) \
do { \
void *priv = b_object_get_private(obj, type_id); \
func_name(priv); \
} while (0)
#endif

View File

@@ -0,0 +1,126 @@
#ifndef BLUE_CORE_MISC_H_
#define BLUE_CORE_MISC_H_
#include <stddef.h>
#include <stdint.h>
#ifndef _Nonnull
#define _Nonnull
#endif
#ifdef __cplusplus
#define B_DECLS_BEGIN extern "C" {
#define B_DECLS_END }
#else
#define B_DECLS_BEGIN
#define B_DECLS_END
#endif
#define B_NPOS ((size_t)-1)
#define b_min(type, x, y) (z__b_min_##type(x, y))
#define b_max(type, x, y) (z__b_max_##type(x, y))
#define b_unbox(type, box, member) \
((type *_Nonnull)((box) ? (uintptr_t)(box) - (offsetof(type, member)) : 0))
#define z__b_merge_(a, b) a##b
#define z__b_label_(a) z__b_merge_(__unique_name_, a)
#define z__b_unique_name() z__b_label_(__LINE__)
#define z__b_numargs(arg_type, ...) \
(sizeof((arg_type[]) {__VA_ARGS__}) / sizeof(arg_type))
#ifdef _MSC_VER
#ifdef BLUELIB_STATIC
#define BLUE_API extern
#else
#ifdef BLUELIB_EXPORT
#define BLUE_API extern __declspec(dllexport)
#else
#define BLUE_API extern __declspec(dllimport)
#endif
#endif
#else
#define BLUE_API extern
#endif
static inline char z__b_min_char(char x, char y)
{
return x < y ? x : y;
}
static inline unsigned char z__b_min_uchar(unsigned char x, unsigned char y)
{
return x < y ? x : y;
}
static inline int z__b_min_int(int x, int y)
{
return x < y ? x : y;
}
static inline unsigned int z__b_min_uint(unsigned int x, unsigned int y)
{
return x < y ? x : y;
}
static inline long z__b_min_long(long x, long y)
{
return x < y ? x : y;
}
static inline unsigned int z__b_min_ulong(unsigned long x, unsigned long y)
{
return x < y ? x : y;
}
static inline long long z__b_min_longlong(long long x, long long y)
{
return x < y ? x : y;
}
static inline unsigned long long z__b_min_ulonglong(
unsigned long long x, unsigned long long y)
{
return x < y ? x : y;
}
static inline size_t z__b_min_size_t(size_t x, size_t y)
{
return x < y ? x : y;
}
static inline char z__b_max_char(char x, char y)
{
return x > y ? x : y;
}
static inline unsigned char z__b_max_uchar(unsigned char x, unsigned char y)
{
return x > y ? x : y;
}
static inline int z__b_max_int(int x, int y)
{
return x > y ? x : y;
}
static inline unsigned int z__b_max_uint(unsigned int x, unsigned int y)
{
return x > y ? x : y;
}
static inline long z__b_max_long(long x, long y)
{
return x > y ? x : y;
}
static inline unsigned int z__b_max_ulong(unsigned long x, unsigned long y)
{
return x > y ? x : y;
}
static inline long long z__b_max_longlong(long long x, long long y)
{
return x > y ? x : y;
}
static inline unsigned long long z__b_max_ulonglong(
unsigned long long x, unsigned long long y)
{
return x > y ? x : y;
}
static inline size_t z__b_max_size_t(size_t x, size_t y)
{
return x > y ? x : y;
}
BLUE_API size_t b_int_length(intptr_t v);
BLUE_API size_t b_uint_length(uintptr_t v);
#endif // BLUE_CORE_MISC_H_

View File

@@ -0,0 +1,43 @@
#ifndef BLUE_CORE_OBJECT_H_
#define BLUE_CORE_OBJECT_H_
#include <blue/core/misc.h>
#include <blue/core/type.h>
B_DECLS_BEGIN;
#define B_OBJECT_MAGIC 0xDECAFC0C0ABEEF13ULL
#define B_OBJECT(p) ((b_object *)(p))
#define B_TYPE_OBJECT (b_object_get_type())
#define B_TYPE_FWDREF(name) struct _b_object
#define B_RV(p) (b_object_make_rvalue(p))
typedef B_TYPE_FWDREF(b_object) b_object;
typedef struct _b_object_class {
void (*to_string)(const b_object *, B_TYPE_FWDREF(b_stream) *);
} b_object_class;
BLUE_API b_type b_object_get_type(void);
BLUE_API void *b_object_get_private(const b_object *object, b_type type);
BLUE_API void *b_object_get_protected(const b_object *object, b_type type);
BLUE_API void *b_object_get_interface(const b_object *object, b_type type);
BLUE_API b_status b_object_get_data(
const b_object *object, b_type type, void **priv, void **prot,
void **iface);
BLUE_API b_object *b_object_ref(b_object *p);
BLUE_API void b_object_unref(b_object *p);
BLUE_API b_object *b_object_make_rvalue(b_object *p);
BLUE_API b_object *b_object_create(b_type type);
BLUE_API void b_object_to_string(const b_object *p, B_TYPE_FWDREF(b_stream) * out);
BLUE_API bool b_object_is_type(const b_object *p, b_type type);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,82 @@
#ifndef BLUE_CORE_QUEUE_H_
#define BLUE_CORE_QUEUE_H_
#include <blue/core/iterator.h>
#include <blue/core/macros.h>
#include <blue/core/status.h>
#include <stdbool.h>
#include <string.h>
B_DECLS_BEGIN;
#define B_TYPE_QUEUE_ITERATOR (b_queue_iterator_get_type())
B_DECLARE_TYPE(b_queue_iterator);
B_TYPE_CLASS_DECLARATION_BEGIN(b_queue_iterator)
B_TYPE_CLASS_DECLARATION_END(b_queue_iterator)
#define B_QUEUE_INIT ((b_queue) {.q_first = NULL, .q_last = NULL})
#define B_QUEUE_ENTRY_INIT ((b_queue_entry) {.qe_next = NULL, .qe_prev = NULL})
typedef struct b_queue_entry {
struct b_queue_entry *qe_next;
struct b_queue_entry *qe_prev;
} b_queue_entry;
typedef struct b_queue {
b_queue_entry *q_first;
b_queue_entry *q_last;
} b_queue;
static inline void b_queue_init(b_queue *q)
{
memset(q, 0x00, sizeof *q);
}
static inline bool b_queue_empty(const b_queue *q)
{
return q ? (q->q_first == NULL) : true;
}
static inline b_queue_entry *b_queue_first(const b_queue *q)
{
return q ? q->q_first : NULL;
}
static inline b_queue_entry *b_queue_last(const b_queue *q)
{
return q ? q->q_last : NULL;
}
static inline b_queue_entry *b_queue_next(const b_queue_entry *entry)
{
return entry ? entry->qe_next : NULL;
}
static inline b_queue_entry *b_queue_prev(const b_queue_entry *entry)
{
return entry ? entry->qe_prev : NULL;
}
BLUE_API b_type b_queue_iterator_get_type(void);
BLUE_API size_t b_queue_length(const b_queue *q);
BLUE_API void b_queue_insert_before(
b_queue *q, b_queue_entry *entry, b_queue_entry *before);
BLUE_API void b_queue_insert_after(
b_queue *q, b_queue_entry *entry, b_queue_entry *after);
BLUE_API void b_queue_push_front(b_queue *q, b_queue_entry *entry);
BLUE_API void b_queue_push_back(b_queue *q, b_queue_entry *entry);
BLUE_API b_queue_entry *b_queue_pop_front(b_queue *q);
BLUE_API b_queue_entry *b_queue_pop_back(b_queue *q);
BLUE_API void b_queue_move(b_queue *q, b_queue_entry *dest, b_queue_entry *src);
BLUE_API void b_queue_delete(b_queue *q, b_queue_entry *entry);
BLUE_API void b_queue_delete_all(b_queue *q);
BLUE_API b_iterator *b_queue_begin(b_queue *q);
BLUE_API b_iterator *b_queue_cbegin(const b_queue *q);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,37 @@
#ifndef BLUELIB_RANDOM_H_
#define BLUELIB_RANDOM_H_
#include <blue/core/status.h>
#include <stddef.h>
struct b_random_algorithm;
typedef enum b_random_flags {
/* algorithm selection */
B_RANDOM_MT19937 = 0x01u,
/* generation flags */
B_RANDOM_SECURE = 0x100u,
} b_random_flags;
typedef struct b_random_ctx {
b_random_flags __f;
struct b_random_algorithm *__a;
union {
struct {
unsigned long long mt[312];
size_t mti;
} __mt19937;
};
} b_random_ctx;
BLUE_API b_random_ctx *b_random_global_ctx(void);
BLUE_API b_status b_random_init(b_random_ctx *ctx, b_random_flags flags);
BLUE_API unsigned long long b_random_next_int64(b_random_ctx *ctx);
BLUE_API double b_random_next_double(b_random_ctx *ctx);
BLUE_API void b_random_next_bytes(
b_random_ctx *ctx, unsigned char *out, size_t nbytes);
#endif

View File

@@ -0,0 +1,47 @@
#ifndef BLUE_CORE_RINGBUFFER_H_
#define BLUE_CORE_RINGBUFFER_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
B_DECLS_BEGIN;
#define B_TYPE_RINGBUFFER (b_ringbuffer_get_type())
B_DECLARE_TYPE(b_ringbuffer);
B_TYPE_CLASS_DECLARATION_BEGIN(b_ringbuffer)
B_TYPE_CLASS_DECLARATION_END(b_ringbuffer)
BLUE_API b_type b_ringbuffer_get_type(void);
BLUE_API b_ringbuffer *b_ringbuffer_create(size_t capacity);
BLUE_API b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity);
BLUE_API b_status b_ringbuffer_clear(b_ringbuffer *buf);
BLUE_API b_status b_ringbuffer_read(
b_ringbuffer *buf, void *p, size_t count, size_t *nr_read);
BLUE_API b_status b_ringbuffer_write(
b_ringbuffer *buf, const void *p, size_t count, size_t *nr_written);
BLUE_API int b_ringbuffer_getc(b_ringbuffer *buf);
BLUE_API b_status b_ringbuffer_putc(b_ringbuffer *buf, int c);
BLUE_API size_t b_ringbuffer_write_capacity_remaining(const b_ringbuffer *buf);
BLUE_API size_t b_ringbuffer_available_data_remaining(const b_ringbuffer *buf);
BLUE_API b_status b_ringbuffer_open_read_buffer(
b_ringbuffer *buf, const void **ptr, size_t *length);
BLUE_API b_status b_ringbuffer_close_read_buffer(
b_ringbuffer *buf, const void **ptr, size_t nr_read);
BLUE_API b_status b_ringbuffer_open_write_buffer(
b_ringbuffer *buf, void **ptr, size_t *capacity);
BLUE_API b_status b_ringbuffer_close_write_buffer(
b_ringbuffer *buf, void **ptr, size_t nr_written);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,109 @@
#ifndef BLUE_CORE_ROPE_H_
#define BLUE_CORE_ROPE_H_
#include <blue/core/hash.h>
#include <blue/core/misc.h>
#include <blue/core/stream.h>
#include <stdint.h>
#include <string.h>
struct b_string;
struct b_bstr;
#define B_ROPE_TYPE(f) ((f) & 0xFF)
#define B_ROPE_CHAR(c) \
\
{ \
.r_flags = B_ROPE_F_CHAR, .r_len_total = 1, \
.r_v = {.v_char = (c) } \
}
#define B_ROPE_CSTR(str) \
{ \
.r_flags = B_ROPE_F_CSTR_BORROWED, \
.r_len_total = strlen(str), \
.r_v = { \
.v_cstr = { \
.s = (str), \
.hash = b_hash_cstr(str), \
}, \
}, \
}
#define B_ROPE_CSTR_STATIC(str) \
{ \
.r_flags = B_ROPE_F_CSTR_STATIC, \
.r_len_total = strlen(str), \
.r_v = { \
.v_cstr = { \
.s = (str), \
.hash = b_hash_cstr(str), \
}, \
}, \
}
#define B_ROPE_INT(v) \
\
{ \
.r_flags = B_ROPE_F_INT, .r_len_total = b_int_length(v), \
.r_v = {.v_int = (v) } \
}
#define B_ROPE_UINT(v) \
\
{ \
.r_flags = B_ROPE_F_UINT, .r_len_total = b_uint_length(v), \
.r_v = {.v_uint = (v) } \
}
typedef enum b_rope_flags {
B_ROPE_F_NONE = 0x0000u,
B_ROPE_F_CHAR = 0x0001u,
B_ROPE_F_CSTR = 0x0002u,
B_ROPE_F_CSTR_BORROWED = 0x0003u,
B_ROPE_F_CSTR_STATIC = 0x0004u,
B_ROPE_F_INT = 0x0005u,
B_ROPE_F_UINT = 0x0006u,
B_ROPE_F_COMPOSITE = 0x0007u,
B_ROPE_F_MALLOC = 0x0100u,
} b_rope_flags;
typedef struct b_rope {
b_rope_flags r_flags;
unsigned long r_len_left, r_len_total;
union {
char v_char;
intptr_t v_int;
uintptr_t v_uint;
struct {
const char *s;
uint64_t hash;
} v_cstr;
struct {
const struct b_rope *r_left, *r_right;
} v_composite;
} r_v;
} b_rope;
BLUE_API void b_rope_init_char(b_rope *rope, char c);
BLUE_API void b_rope_init_cstr(b_rope *rope, const char *s);
BLUE_API void b_rope_init_cstr_borrowed(b_rope *rope, const char *s);
BLUE_API void b_rope_init_cstr_static(b_rope *rope, const char *s);
BLUE_API void b_rope_init_int(b_rope *rope, intptr_t v);
BLUE_API void b_rope_init_uint(b_rope *rope, uintptr_t v);
BLUE_API void b_rope_destroy(b_rope *rope);
BLUE_API void b_rope_iterate(
const b_rope *rope, void (*func)(const b_rope *, void *), void *arg);
BLUE_API size_t b_rope_get_size(const b_rope *rope);
BLUE_API void b_rope_concat(b_rope *result, const b_rope *left, const b_rope *right);
BLUE_API void b_rope_join(b_rope *result, const b_rope **ropes, size_t nr_ropes);
BLUE_API b_status b_rope_to_cstr(const b_rope *rope, char *out, size_t max);
BLUE_API b_status b_rope_to_bstr(const b_rope *rope, struct b_bstr *str);
BLUE_API b_status b_rope_to_string(const b_rope *rope, b_stream *out);
#endif

View File

@@ -0,0 +1,48 @@
#ifndef BLUELIB_CORE_STATUS_H_
#define BLUELIB_CORE_STATUS_H_
#include <blue/core/misc.h>
#define B_OK(status) ((enum b_status)((uintptr_t)(status)) == B_SUCCESS)
#define B_ERR(status) ((status) != B_SUCCESS)
typedef enum b_status {
B_SUCCESS = 0x00u,
B_ERR_NO_MEMORY,
B_ERR_OUT_OF_BOUNDS,
B_ERR_INVALID_ARGUMENT,
B_ERR_NAME_EXISTS,
B_ERR_NOT_SUPPORTED,
B_ERR_BAD_STATE,
B_ERR_NO_ENTRY,
B_ERR_NO_DATA,
B_ERR_NO_SPACE,
B_ERR_UNKNOWN_FUNCTION,
B_ERR_BAD_FORMAT,
B_ERR_IO_FAILURE,
B_ERR_IS_DIRECTORY,
B_ERR_NOT_DIRECTORY,
B_ERR_PERMISSION_DENIED,
B_ERR_BUSY,
/* blue-compress specific code */
B_ERR_COMPRESSION_FAILURE,
/* blue-object specific code */
B_ERR_TYPE_REGISTRATION_FAILURE,
B_ERR_CLASS_INIT_FAILURE,
} b_status;
typedef enum b_status_msg {
B_MSG_SUCCESS = 0,
/* blue-object specific messages */
B_MSG_TYPE_REGISTRATION_FAILURE,
B_MSG_CLASS_INIT_FAILURE,
B_MSG_CLASS_SPECIFIES_UNKNOWN_INTERFACE,
} b_status_msg;
BLUE_API const char *b_status_to_string(b_status status);
BLUE_API const char *b_status_description(b_status status);
#endif

View File

@@ -0,0 +1,101 @@
#ifndef BLUE_CORE_STREAM_H_
#define BLUE_CORE_STREAM_H_
#include <blue/core/encoding.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <stdarg.h>
#include <stdio.h>
B_DECLS_BEGIN;
#define b_stdin (z__b_stream_get_stdin())
#define b_stdout (z__b_stream_get_stdout())
#define b_stderr (z__b_stream_get_stderr())
#define B_TYPE_STREAM (b_stream_get_type())
#define B_TYPE_STREAM_BUFFER (b_stream_buffer_get_type())
B_DECLARE_TYPE(b_stream);
B_DECLARE_TYPE(b_stream_buffer);
typedef enum b_stream_mode {
B_STREAM_READ = 0x01u,
B_STREAM_WRITE = 0x02u,
B_STREAM_BINARY = 0x10u,
Z__B_STREAM_STATIC = 0x80u,
} b_stream_mode;
typedef enum b_stream_seek_origin {
B_STREAM_SEEK_START = 0x01u,
B_STREAM_SEEK_CURRENT = 0x02u,
B_STREAM_SEEK_END = 0x03u,
} b_stream_seek_origin;
typedef struct b_stream_cfg {
b_stream_mode s_mode;
} b_stream_cfg;
B_TYPE_CLASS_DECLARATION_BEGIN(b_stream)
b_status (*s_close)(b_stream *);
b_status (*s_seek)(b_stream *, long long, b_stream_seek_origin);
b_status (*s_tell)(const b_stream *, size_t *);
b_status (*s_getc)(b_stream *, b_wchar *);
b_status (*s_read)(b_stream *, void *, size_t, size_t *);
b_status (*s_write)(b_stream *, const void *, size_t, size_t *);
b_status (*s_reserve)(b_stream *, size_t);
B_TYPE_CLASS_DECLARATION_END(b_stream)
B_TYPE_CLASS_DECLARATION_BEGIN(b_stream_buffer)
B_STRUCT_EMPTY;
B_TYPE_CLASS_DECLARATION_END(b_stream_buffer)
BLUE_API b_type b_stream_get_type();
BLUE_API b_type b_stream_buffer_get_type();
BLUE_API b_stream *z__b_stream_get_stdin(void);
BLUE_API b_stream *z__b_stream_get_stdout(void);
BLUE_API b_stream *z__b_stream_get_stderr(void);
BLUE_API b_stream_buffer *b_stream_buffer_create(void *p, size_t len);
BLUE_API b_stream_buffer *b_stream_buffer_create_dynamic(size_t buffer_size);
BLUE_API b_stream *b_stream_open_fp(FILE *fp);
BLUE_API b_status b_stream_reserve(b_stream *stream, size_t len);
BLUE_API b_status b_stream_seek(
b_stream *stream, long long offset, b_stream_seek_origin origin);
BLUE_API size_t b_stream_cursor(const b_stream *stream);
BLUE_API b_status b_stream_push_indent(b_stream *stream, int indent);
BLUE_API b_status b_stream_pop_indent(b_stream *stream);
BLUE_API b_status b_stream_read_char(b_stream *stream, b_wchar *c);
BLUE_API b_status b_stream_read_bytes(
b_stream *stream, void *buf, size_t count, size_t *nr_read);
BLUE_API b_status b_stream_read_line(b_stream *stream, char *s, size_t max);
BLUE_API b_status b_stream_read_line_s(b_stream *src, b_stream *dest);
BLUE_API b_status b_stream_read_all_bytes(
b_stream *stream, void *p, size_t max, size_t *nr_read);
BLUE_API b_status b_stream_read_all_bytes_s(
b_stream *src, b_stream *dest, b_stream_buffer *buffer, size_t *nr_read);
BLUE_API b_status b_stream_write_char(b_stream *stream, b_wchar c);
BLUE_API b_status b_stream_write_string(
b_stream *stream, const char *s, size_t *nr_written);
BLUE_API b_status b_stream_write_bytes(
b_stream *stream, const void *buf, size_t count, size_t *nr_written);
BLUE_API b_status b_stream_write_fmt(
b_stream *stream, size_t *nr_written, const char *format, ...);
BLUE_API b_status b_stream_write_vfmt(
b_stream *stream, size_t *nr_written, const char *format, va_list arg);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,36 @@
#ifndef BLUE_CORE_STRINGSTREAM_H_
#define BLUE_CORE_STRINGSTREAM_H_
#include <blue/core/macros.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <blue/core/stream.h>
#include <stddef.h>
B_DECLS_BEGIN;
#define B_TYPE_STRINGSTREAM (b_stringstream_get_type())
B_DECLARE_TYPE(b_stringstream);
B_TYPE_CLASS_DECLARATION_BEGIN(b_stringstream)
B_STRUCT_EMPTY;
B_TYPE_CLASS_DECLARATION_END(b_stringstream)
BLUE_API b_type b_stringstream_get_type(void);
BLUE_API b_stringstream *b_stringstream_create(void);
BLUE_API b_stringstream *b_stringstream_create_with_buffer(char *buf, size_t max);
BLUE_API b_status b_stringstream_reset(b_stringstream *strv);
BLUE_API b_status b_stringstream_reset_with_buffer(
b_stringstream *strv, char *buf, size_t max);
BLUE_API const char *b_stringstream_ptr(const b_stringstream *strv);
BLUE_API char *b_stringstream_steal(b_stringstream *strv);
BLUE_API size_t b_stringstream_get_length(const b_stringstream *strv);
B_DECLS_END;
#endif

View File

@@ -0,0 +1,36 @@
#ifndef BLUELIB_CORE_THREAD_H_
#define BLUELIB_CORE_THREAD_H_
#include <blue/core/bitop.h>
#include <blue/core/misc.h>
#include <stdbool.h>
#if defined(__APPLE__) || defined(__linux__)
#include <pthread.h>
#define B_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t b_mutex;
#else
#error Unsupported compiler/system
#endif
#define B_ONCE_INIT ((b_once)0)
typedef struct b_thread b_thread;
typedef int b_once;
static inline bool b_init_once(b_once *once)
{
int x = 0;
return b_cmpxchg(once, &x, 1);
}
BLUE_API b_thread *b_thread_self(void);
BLUE_API bool b_mutex_lock(b_mutex *mut);
BLUE_API bool b_mutex_trylock(b_mutex *mut);
BLUE_API bool b_mutex_unlock(b_mutex *mut);
#endif

View File

@@ -0,0 +1,70 @@
#ifndef BLUE_CORE_TYPE_H_
#define BLUE_CORE_TYPE_H_
#include <blue/core/error.h>
#include <blue/core/misc.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
B_DECLS_BEGIN;
#define B_TYPE_MAX_INTERFACES 64
struct _b_class;
struct _b_object;
typedef void (*b_class_init_function)(struct _b_class *, void *);
typedef void (*b_instance_init_function)(struct _b_object *, void *);
typedef void (*b_instance_fini_function)(struct _b_object *, void *);
typedef const union b_type_id {
struct {
uint64_t p00, p01;
} a;
unsigned char b[16];
} *b_type;
typedef enum b_type_flags {
B_TYPE_F_ABSTRACT = 0x01u,
} b_type_flags;
typedef struct b_type_info {
union b_type_id t_id;
union b_type_id t_parent_id;
const char *t_name;
b_type_flags t_flags;
union b_type_id t_interfaces[B_TYPE_MAX_INTERFACES];
size_t t_nr_interfaces;
size_t t_class_size;
b_class_init_function t_class_init;
size_t t_instance_private_size;
size_t t_instance_protected_size;
b_instance_init_function t_instance_init;
b_instance_fini_function t_instance_fini;
} b_type_info;
BLUE_API void b_type_id_init(
union b_type_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d,
uint64_t e);
static inline void b_type_id_copy(b_type src, union b_type_id *dest)
{
dest->a.p00 = src->a.p00;
dest->a.p01 = src->a.p01;
}
static inline int b_type_id_compare(b_type a, b_type b)
{
if (a == b) {
return 0;
}
return memcmp(a, b, sizeof(union b_type_id));
}
BLUE_API b_result b_type_register(b_type_info *info);
B_DECLS_END;
#endif

View File

@@ -1,359 +0,0 @@
#ifndef FX_CORE_BST_H_
#define FX_CORE_BST_H_
#include <fx/core/iterator.h>
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
FX_DECLS_BEGIN;
#define FX_BST_INIT {0}
#define FX_TYPE_BST_ITERATOR (fx_bst_iterator_get_type())
FX_DECLARE_TYPE(fx_bst_iterator);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_bst_iterator)
FX_TYPE_CLASS_DECLARATION_END(fx_bst_iterator)
/* defines a simple node insertion function.
this function assumes that your nodes have simple integer keys that can be
compared with the usual operators.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
int key;
fx_bst_node base;
}
You would use the following call to generate an insert function for a tree
with this node type:
BST_DEFINE_SIMPLE_INSERT(
struct my_tree_node,
base,
key,
my_tree_node_insert);
Which would emit a function defined like:
static void my_tree_node_insert(fx_bst *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that
contains a fx_bst_node member.
@param container_node_member the name of the fx_bst_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
*/
#define FX_BST_DEFINE_SIMPLE_INSERT( \
node_type, container_node_member, container_key_member, function_name) \
void function_name(fx_bst *tree, node_type *node) \
{ \
if (!tree->bst_root) { \
tree->bst_root = &node->container_node_member; \
fx_bst_insert_fixup(tree, &node->container_node_member); \
return; \
} \
\
fx_bst_node *cur = tree->bst_root; \
while (1) { \
node_type *cur_node = fx_unbox( \
node_type, cur, container_node_member); \
fx_bst_node *next = NULL; \
\
if (node->container_key_member \
>= cur_node->container_key_member) { \
next = fx_bst_right(cur); \
\
if (!next) { \
fx_bst_put_right( \
cur, \
&node->container_node_member); \
break; \
} \
} else if ( \
node->container_key_member \
< cur_node->container_key_member) { \
next = fx_bst_left(cur); \
\
if (!next) { \
fx_bst_put_left( \
cur, \
&node->container_node_member); \
break; \
} \
} \
\
cur = next; \
} \
\
fx_bst_insert_fixup(tree, &node->container_node_member); \
}
/* defines a node insertion function.
this function should be used for trees with complex node keys that cannot be
directly compared. a comparator for your keys must be supplied.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
complex_key_t key;
fx_bst_node base;
}
You would need to define a comparator function or macro with the following
signature:
int my_comparator(struct my_tree_node *a, struct my_tree_node *b);
Which implements the following:
return -1 if a < b
return 0 if a == b
return 1 if a > b
You would use the following call to generate an insert function for a tree
with this node type:
BST_DEFINE_INSERT(struct my_tree_node, base, key, my_tree_node_insert,
my_comparator);
Which would emit a function defined like:
static void my_tree_node_insert(fx_bst *tree, struct my_tree_node *node);
@param node_type your custom tree node type. usually a structure that
contains a fx_bst_node member.
@param container_node_member the name of the fx_bst_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
@param comparator the name of a comparator function or functional-macro that
conforms to the requirements listed above.
*/
#define FX_BST_DEFINE_INSERT( \
node_type, container_node_member, container_key_member, function_name, \
comparator) \
void function_name(fx_bst *tree, node_type *node) \
{ \
if (!tree->bst_root) { \
tree->bst_root = &node->container_node_member; \
fx_bst_insert_fixup(tree, &node->container_node_member); \
return; \
} \
\
fx_bst_node *cur = tree->bst_root; \
while (1) { \
node_type *cur_node = fx_unbox( \
node_type, cur, container_node_member); \
fx_bst_node *next = NULL; \
int cmp = comparator(node, cur_node); \
\
if (cmp >= 0) { \
next = fx_bst_right(cur); \
\
if (!next) { \
fx_bst_put_right( \
cur, \
&node->container_node_member); \
break; \
} \
} else if (cmp < 0) { \
next = fx_bst_left(cur); \
\
if (!next) { \
fx_bst_put_left( \
cur, \
&node->container_node_member); \
break; \
} \
} else { \
return; \
} \
\
cur = next; \
} \
\
fx_bst_insert_fixup(tree, &node->container_node_member); \
}
/* defines a simple tree search function.
this function assumes that your nodes have simple integer keys that can be
compared with the usual operators.
EXAMPLE:
if you have a tree node type like this:
struct my_tree_node {
int key;
fx_bst_node base;
}
You would use the following call to generate a search function for a tree
with this node type:
BST_DEFINE_SIMPLE_GET(struct my_tree_node, int, base, key,
my_tree_node_get);
Which would emit a function defined like:
static struct my_tree_node *my_tree_node_get(fx_bst *tree, int key);
@param node_type your custom tree node type. usually a structure that
contains a fx_bst_node member.
@param key_type the type name of the key embedded in your custom tree node
type. this type must be compatible with the builtin comparison operators.
@param container_node_member the name of the fx_bst_node member variable
within your custom type.
@param container_key_member the name of the key member variable within your
custom type.
@param function_name the name of the function to generate.
*/
#define FX_BST_DEFINE_SIMPLE_GET( \
node_type, key_type, container_node_member, container_key_member, \
function_name) \
node_type *function_name(const fx_bst *tree, key_type key) \
{ \
fx_bst_node *cur = tree->bst_root; \
while (cur) { \
node_type *cur_node = fx_unbox( \
node_type, cur, container_node_member); \
if (key > cur_node->container_key_member) { \
cur = fx_bst_right(cur); \
} else if (key < cur_node->container_key_member) { \
cur = fx_bst_left(cur); \
} else { \
return cur_node; \
} \
} \
\
return NULL; \
}
#define fx_bst_foreach(it, bst) \
for (int z__fx_unique_name() = fx_bst_iterator_begin(bst, it); \
(it)->node != NULL; fx_bst_iterator_next(it))
/* binary tree nodes. this *cannot* be used directly. you need to define a
custom node type that contains a member variable of type fx_bst_node.
you would then use the supplied macros to define functions to manipulate your
custom binary tree.
*/
typedef struct fx_bst_node {
struct fx_bst_node *n_parent, *n_left, *n_right;
unsigned short n_height;
} fx_bst_node;
/* binary tree. unlike fx_bst_node, you can define variables of type fx_bst.
*/
typedef struct fx_bst {
fx_bst_node *bst_root;
} fx_bst;
FX_API fx_type fx_bst_iterator_get_type(void);
/* re-balance a binary tree after an insertion operation.
NOTE that, if you define an insertion function using BST_DEFINE_INSERT or
similar, this function will automatically called for you.
@param tree the tree to re-balance.
@param node the node that was just inserted into the tree.
*/
FX_API void fx_bst_insert_fixup(fx_bst *tree, fx_bst_node *node);
/* delete a node from a binary tree and re-balance the tree afterwards.
@param tree the tree to delete from
@param node the node to delete.
*/
FX_API void fx_bst_delete(fx_bst *tree, fx_bst_node *node);
/* get the first node in a binary tree.
this will be the node with the smallest key (i.e. the node that is
furthest-left from the root)
*/
FX_API fx_bst_node *fx_bst_first(const fx_bst *tree);
/* get the last node in a binary tree.
this will be the node with the largest key (i.e. the node that is
furthest-right from the root)
*/
FX_API fx_bst_node *fx_bst_last(const fx_bst *tree);
/* for any binary tree node, this function returns the node with the
* next-largest key value */
FX_API fx_bst_node *fx_bst_next(const fx_bst_node *node);
/* for any binary tree node, this function returns the node with the
* next-smallest key value */
FX_API fx_bst_node *fx_bst_prev(const fx_bst_node *node);
/* return true if the bst is empty, false otherwise */
static inline bool fx_bst_empty(const fx_bst *tree)
{
return tree->bst_root == NULL;
}
/* sets `child` as the immediate left-child of `parent` */
static inline void fx_bst_put_left(fx_bst_node *parent, fx_bst_node *child)
{
parent->n_left = child;
child->n_parent = parent;
}
/* sets `child` as the immediate right-child of `parent` */
static inline void fx_bst_put_right(fx_bst_node *parent, fx_bst_node *child)
{
parent->n_right = child;
child->n_parent = parent;
}
/* get the immediate left-child of `node` */
static inline fx_bst_node *fx_bst_left(fx_bst_node *node)
{
return node->n_left;
}
/* get the immediate right-child of `node` */
static inline fx_bst_node *fx_bst_right(fx_bst_node *node)
{
return node->n_right;
}
/* get the immediate parent of `node` */
static inline fx_bst_node *fx_bst_parent(fx_bst_node *node)
{
return node->n_parent;
}
FX_API void fx_bst_move(fx_bst *tree, fx_bst_node *dest, fx_bst_node *src);
/* get the height of `node`.
the height of a node is defined as the length of the longest path
between the node and a leaf node.
this count includes the node itself, so the height of a leaf node will be 1.
*/
static inline unsigned short fx_bst_height(fx_bst_node *node)
{
return node->n_height;
}
FX_API fx_iterator *fx_bst_begin(fx_bst *tree);
FX_API const fx_iterator *fx_bst_cbegin(const fx_bst *tree);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,71 +0,0 @@
#ifndef FX_CORE_BSTR_H_
#define FX_CORE_BSTR_H_
#include <fx/core/misc.h>
#include <fx/core/status.h>
#include <stdarg.h>
#include <stddef.h>
#define FX_BSTR_MAGIC 0x5005500550055005ULL
struct fx_rope;
enum fx_bstr_flags {
FX_BSTR_F_NONE = 0x00u,
FX_BSTR_F_ALLOC = 0x01u,
};
typedef struct fx_bstr {
uint64_t bstr_magic;
enum fx_bstr_flags bstr_flags;
char *bstr_buf;
/* total number of characters in bstr_buf, not including null terminator */
size_t bstr_len;
/* number of bytes allocated for bstr_buf (includes space for the null
* terminator) */
size_t bstr_capacity;
int *bstr_istack;
int bstr_add_indent;
size_t bstr_istack_ptr, bstr_istack_size;
} fx_bstr;
FX_API void fx_bstr_begin(fx_bstr *strv, char *buf, size_t max);
FX_API void fx_bstr_begin_dynamic(fx_bstr *strv);
FX_API char *fx_bstr_end(fx_bstr *strv);
FX_API fx_status fx_bstr_reserve(fx_bstr *strv, size_t len);
static inline size_t fx_bstr_get_size(const fx_bstr *str)
{
return str->bstr_len;
}
static inline size_t fx_bstr_get_capacity(const fx_bstr *str)
{
return str->bstr_capacity;
}
FX_API fx_status fx_bstr_push_indent(fx_bstr *strv, int indent);
FX_API fx_status fx_bstr_pop_indent(fx_bstr *strv);
FX_API fx_status fx_bstr_write_char(fx_bstr *strv, char c);
FX_API fx_status fx_bstr_write_chars(
fx_bstr *strv, const char *cs, size_t len, size_t *nr_written);
FX_API fx_status fx_bstr_write_cstr(
fx_bstr *strv, const char *str, size_t *nr_written);
FX_API fx_status fx_bstr_write_cstr_list(
fx_bstr *strv, const char **strs, size_t *nr_written);
FX_API fx_status fx_bstr_write_cstr_array(
fx_bstr *strv, const char **strs, size_t count, size_t *nr_written);
FX_API fx_status fx_bstr_write_cstr_varg(fx_bstr *strv, size_t *nr_written, ...);
FX_API fx_status fx_bstr_write_rope(
fx_bstr *strv, const struct fx_rope *rope, size_t *nr_written);
FX_API fx_status fx_bstr_write_fmt(
fx_bstr *strv, size_t *nr_written, const char *format, ...);
FX_API fx_status fx_bstr_write_vfmt(
fx_bstr *strv, size_t *nr_written, const char *format, va_list arg);
FX_API char *fx_bstr_rope(const struct fx_rope *rope, size_t *nr_written);
FX_API char *fx_bstr_fmt(size_t *nr_written, const char *format, ...);
FX_API char *fx_bstr_vfmt(size_t *nr_written, const char *format, va_list arg);
#endif

View File

@@ -1,15 +0,0 @@
#ifndef FX_OBJECT_CLASS_H_
#define FX_OBJECT_CLASS_H_
#include <fx/core/type.h>
#define FX_CLASS_MAGIC 0xDEADFACEDCAFEBEDULL
#define FX_CLASS(p) ((fx_class *)(p))
typedef struct _fx_class fx_class;
FX_API void *fx_class_get(fx_type id);
FX_API const char *fx_class_get_name(const fx_class *c);
FX_API void *fx_class_get_interface(const fx_class *c, fx_type id);
#endif

View File

@@ -1,41 +0,0 @@
#ifndef FX_CORE_ENCODING_H_
#define FX_CORE_ENCODING_H_
#include <fx/core/misc.h>
#include <stdbool.h>
#include <stdint.h>
#define FX_WCHAR_INVALID ((fx_wchar) - 1)
typedef int32_t fx_wchar;
FX_API bool fx_wchar_is_alpha(fx_wchar c);
FX_API bool fx_wchar_is_number(fx_wchar c);
static inline bool fx_wchar_is_bin_digit(fx_wchar c)
{
return c >= '0' && c <= '1';
}
static inline bool fx_wchar_is_oct_digit(fx_wchar c)
{
return c >= '0' && c <= '7';
}
FX_API bool fx_wchar_is_hex_digit(fx_wchar c);
FX_API bool fx_wchar_is_space(fx_wchar c);
static inline bool fx_wchar_is_alnum(fx_wchar c)
{
return fx_wchar_is_alpha(c) || fx_wchar_is_number(c);
}
FX_API bool fx_wchar_is_punct(fx_wchar c);
FX_API bool fx_wchar_utf8_is_valid_scalar(fx_wchar c);
FX_API unsigned int fx_wchar_utf8_header_decode(char c);
FX_API unsigned int fx_wchar_utf8_codepoint_size(fx_wchar c);
FX_API fx_wchar fx_wchar_utf8_codepoint_decode(const char *s);
FX_API unsigned int fx_wchar_utf8_codepoint_encode(fx_wchar c, char s[4]);
FX_API unsigned int fx_wchar_utf8_codepoint_stride(const char *s);
FX_API size_t fx_wchar_utf8_codepoint_count(const char *s, size_t nr_bytes);
FX_API size_t fx_wchar_utf8_string_encoded_size(
const fx_wchar *s, size_t nr_codepoints);
#endif

View File

@@ -1,49 +0,0 @@
#ifndef FX_CORE_ENDIAN_H_
#define FX_CORE_ENDIAN_H_
#include <fx/core/misc.h>
#include <stdint.h>
typedef struct {
union {
unsigned char i_bytes[sizeof(uint16_t)];
int16_t i_val;
uint16_t i_uval;
};
} fx_i16;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint32_t)];
int32_t i_val;
uint32_t i_uval;
};
} fx_i32;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint64_t)];
int64_t i_val;
uint64_t i_uval;
};
} fx_i64;
FX_API fx_i16 fx_i16_htob(uint16_t v);
FX_API fx_i16 fx_i16_htos(uint16_t v);
FX_API uint16_t fx_i16_btoh(fx_i16 v);
FX_API uint16_t fx_i16_stoh(fx_i16 v);
FX_API fx_i32 fx_i32_htob(uint32_t v);
FX_API fx_i32 fx_i32_htos(uint32_t v);
FX_API uint32_t fx_i32_btoh(fx_i32 v);
FX_API uint32_t fx_i32_stoh(fx_i32 v);
FX_API fx_i64 fx_i64_htob(uint64_t v);
FX_API fx_i64 fx_i64_htos(uint64_t v);
FX_API uint64_t fx_i64_btoh(fx_i64 v);
FX_API uint64_t fx_i64_stoh(fx_i64 v);
#endif

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

View File

@@ -1,111 +0,0 @@
#ifndef FX_CORE_HASH_H_
#define FX_CORE_HASH_H_
#include <fx/core/misc.h>
#include <fx/core/status.h>
#include <stddef.h>
#include <stdint.h>
#define FX_DIGEST_LENGTH_128 16
#define FX_DIGEST_LENGTH_160 20
#define FX_DIGEST_LENGTH_192 24
#define FX_DIGEST_LENGTH_224 28
#define FX_DIGEST_LENGTH_256 32
#define FX_DIGEST_LENGTH_384 48
#define FX_DIGEST_LENGTH_512 64
#define FX_DIGEST_LENGTH_MD4 FX_DIGEST_LENGTH_128
#define FX_DIGEST_LENGTH_MD5 FX_DIGEST_LENGTH_128
#define FX_DIGEST_LENGTH_SHA1 FX_DIGEST_LENGTH_160
#define FX_DIGEST_LENGTH_SHA2_224 FX_DIGEST_LENGTH_224
#define FX_DIGEST_LENGTH_SHA2_256 FX_DIGEST_LENGTH_256
#define FX_DIGEST_LENGTH_SHA2_384 FX_DIGEST_LENGTH_384
#define FX_DIGEST_LENGTH_SHA2_512 FX_DIGEST_LENGTH_512
#define FX_DIGEST_LENGTH_SHA3_224 FX_DIGEST_LENGTH_224
#define FX_DIGEST_LENGTH_SHA3_256 FX_DIGEST_LENGTH_256
#define FX_DIGEST_LENGTH_SHA3_384 FX_DIGEST_LENGTH_384
#define FX_DIGEST_LENGTH_SHA3_512 FX_DIGEST_LENGTH_512
#define FX_DIGEST_LENGTH_SHAKE128 FX_DIGEST_LENGTH_128
#define FX_DIGEST_LENGTH_SHAKE256 FX_DIGEST_LENGTH_256
struct fx_hash_function_ops;
struct fx_rope;
typedef enum fx_hash_function {
FX_HASH_NONE = 0,
FX_HASH_MD4,
FX_HASH_MD5,
FX_HASH_SHA1,
FX_HASH_SHA2_224,
FX_HASH_SHA2_256,
FX_HASH_SHA2_384,
FX_HASH_SHA2_512,
FX_HASH_SHA3_224,
FX_HASH_SHA3_256,
FX_HASH_SHA3_384,
FX_HASH_SHA3_512,
FX_HASH_SHAKE128,
FX_HASH_SHAKE256,
} fx_hash_function;
typedef struct fx_hash_ctx {
fx_hash_function ctx_func;
const struct fx_hash_function_ops *ctx_ops;
union {
struct {
uint32_t lo, hi;
uint32_t a, b, c, d;
uint32_t block[16];
unsigned char buffer[64];
} md4;
struct {
unsigned int count[2];
unsigned int a, b, c, d;
unsigned int block[16];
unsigned char input[64];
} md5;
struct {
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} sha1;
struct {
uint64_t curlen;
uint64_t length;
unsigned char buf[128];
uint32_t state[8];
} sha2_256;
struct {
uint64_t curlen;
uint64_t length;
unsigned char block[256];
uint64_t state[8];
} sha2_512;
struct {
union {
uint8_t b[200];
uint64_t q[25];
} st;
int pt, rsiz, mdlen;
} sha3;
} ctx_state;
} fx_hash_ctx;
FX_API uint64_t fx_hash_cstr(const char *s);
FX_API uint64_t fx_hash_cstr_ex(const char *s, size_t *len);
FX_API fx_status fx_hash_ctx_init(fx_hash_ctx *ctx, fx_hash_function func);
FX_API fx_status fx_hash_ctx_reset(fx_hash_ctx *ctx);
FX_API fx_status fx_hash_ctx_update(fx_hash_ctx *ctx, const void *p, size_t len);
FX_API fx_status fx_hash_ctx_update_rope(fx_hash_ctx *ctx, const struct fx_rope *rope);
FX_API fx_status fx_hash_ctx_finish(
fx_hash_ctx *ctx, void *out_digest, size_t out_max);
#endif

View File

@@ -1,93 +0,0 @@
#ifndef FX_CORE_ITERATOR_H_
#define FX_CORE_ITERATOR_H_
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <fx/core/status.h>
#include <stdbool.h>
FX_DECLS_BEGIN;
#define fx_foreach(type, var, iterator) \
for (type var = (type)fx_iterator_get_value(iterator).v_int; \
FX_OK(fx_iterator_get_status(iterator)); \
fx_iterator_move_next(iterator), \
var = (type)fx_iterator_get_value(iterator).v_int)
#define fx_foreach_ptr(type, var, iterator) \
for (type *var = (type *)fx_iterator_get_value(iterator).v_ptr; \
FX_OK(fx_iterator_get_status(iterator)); \
fx_iterator_move_next(iterator), \
var = (type *)fx_iterator_get_value(iterator).v_ptr)
#define fx_foreach_c(type, var, iterator) \
for (type var = (type)fx_iterator_get_cvalue(iterator).v_int; \
FX_OK(fx_iterator_get_status(iterator)); \
fx_iterator_move_next(iterator), \
var = (type)fx_iterator_get_cvalue(iterator).v_int)
#define fx_foreach_cptr(type, var, iterator) \
for (const type *var \
= (const type *)fx_iterator_get_cvalue(iterator).v_cptr; \
FX_OK(fx_iterator_get_status(iterator)); \
fx_iterator_move_next(iterator), \
var = (const type *)fx_iterator_get_cvalue(iterator).v_cptr)
#define FX_ITERATOR_VALUE_INT(v) ((fx_iterator_value) {.v_int = (v)})
#define FX_ITERATOR_VALUE_PTR(v) ((fx_iterator_value) {.v_ptr = (v)})
#define FX_ITERATOR_VALUE_CPTR(v) ((const fx_iterator_value) {.v_cptr = (v)})
#define FX_ITERATOR_VALUE_NULL ((fx_iterator_value) {})
#define FX_ITERATOR_VALUE_IS_NULL(v) ((v)->v_ptr == NULL)
#define FX_TYPE_ITERATOR (fx_iterator_get_type())
#define FX_TYPE_ITERABLE (fx_iterable_get_type())
typedef union fx_iterator_value {
uintptr_t v_int;
void *v_ptr;
const void *v_cptr;
} fx_iterator_value;
__FX_DECLARE_TYPE(fx_iterator);
FX_DECLARE_TYPE(fx_iterable);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_iterator)
fx_status (*it_move_next)(const fx_iterator *);
fx_status (*it_erase)(fx_iterator *);
fx_iterator_value (*it_get_value)(fx_iterator *);
const fx_iterator_value (*it_get_cvalue)(const fx_iterator *);
FX_TYPE_CLASS_DECLARATION_END(fx_iterator)
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_iterable)
fx_iterator *(*it_begin)(fx_iterable *);
const fx_iterator *(*it_cbegin)(const fx_iterable *);
FX_TYPE_CLASS_DECLARATION_END(fx_iterable)
FX_API fx_type fx_iterator_get_type(void);
FX_API fx_type fx_iterable_get_type(void);
static inline const fx_iterator *fx_iterator_ref(const fx_iterator *p)
{
return fx_object_ref((fx_object *)p);
}
static inline void fx_iterator_unref(const fx_iterator *p)
{
fx_object_unref((fx_object *)p);
}
FX_API fx_iterator *fx_iterator_begin(fx_iterable *it);
FX_API const fx_iterator *fx_iterator_cbegin(const fx_iterable *it);
FX_API fx_status fx_iterator_get_status(const fx_iterator *it);
FX_API fx_status fx_iterator_set_status(const fx_iterator *it, fx_status status);
FX_API fx_status fx_iterator_move_next(const fx_iterator *it);
FX_API fx_iterator_value fx_iterator_get_value(fx_iterator *it);
FX_API const fx_iterator_value fx_iterator_get_cvalue(const fx_iterator *it);
FX_API fx_status fx_iterator_erase(fx_iterator *it);
static inline bool fx_iterator_is_valid(const fx_iterator *it)
{
return FX_OK(fx_iterator_get_status(it));
}
FX_DECLS_END;
#endif

View File

@@ -1,197 +0,0 @@
#ifndef FX_CORE_MACROS_H_
#define FX_CORE_MACROS_H_
#include <fx/core/class.h>
#include <fx/core/object.h>
#include <fx/core/thread.h>
#include <fx/core/type.h>
#include <stdlib.h>
#define __FX_IFACE_I0(p, x) p##x
#define __FX_IFACE_I1(p, x) __FX_IFACE_I0(p, x)
/* Type definitions macros (for use in .c source file) */
#define FX_TYPE_CLASS_DEFINITION_BEGIN(type_name) \
static void type_name##_class_init(fx_class *p, void *d) \
{
#define FX_TYPE_CLASS_DEFINITION_END(type_name) }
#define FX_TYPE_CLASS_INTERFACE_BEGIN(interface_name, interface_id) \
interface_name##_class *__FX_IFACE_I1(iface, __LINE__) \
= fx_class_get_interface(p, interface_id); \
if (!__FX_IFACE_I1(iface, __LINE__)) { \
fx_throw_error_with_msg_template( \
FX_ERRORS_BUILTIN, FX_ERR_CLASS_INIT_FAILURE, \
FX_MSG_CLASS_SPECIFIES_UNKNOWN_INTERFACE, \
FX_ERROR_PARAM("class_name", fx_class_get_name(p)), \
FX_ERROR_PARAM("interface_name", #interface_name)); \
exit(-1); \
} else { \
interface_name##_class *iface = __FX_IFACE_I1(iface, __LINE__);
#define FX_TYPE_CLASS_INTERFACE_END(interface_name, interface_id) }
#define FX_INTERFACE_ENTRY(slot) iface->slot
#define FX_TYPE_DEFINITION_BEGIN(name) \
static fx_type_info name##_type_info = {0}; \
static void name##_class_init(fx_class *, void *); \
static void name##_type_init(void) \
{ \
fx_type_info *type_info = &name##_type_info; \
unsigned int nr_vtables = 0; \
type_info->t_name = #name; \
type_info->t_class_init = name##_class_init;
#define FX_TYPE_DEFINITION_END(name) \
fx_result result = fx_type_register(type_info); \
if (fx_result_is_error(result)) { \
fx_throw_error_caused_by_error( \
FX_ERRORS_BUILTIN, FX_ERR_TYPE_REGISTRATION_FAILURE, \
result); \
abort(); \
} \
} \
fx_type name##_get_type(void) \
{ \
static fx_once static_type_init = FX_ONCE_INIT; \
\
if (fx_init_once(&static_type_init)) { \
name##_type_init(); \
} \
\
return &name##_type_info.t_id; \
}
#define FX_TYPE_ID(a, b, c, d, e) fx_type_id_init(&type_info->t_id, a, b, c, d, e)
#define FX_TYPE_EXTENDS(parent_id) \
fx_type_id_copy(parent_id, &type_info->t_parent_id)
#define FX_TYPE_IMPLEMENTS(interface_id) \
fx_type_id_copy( \
interface_id, \
&type_info->t_interfaces[type_info->t_nr_interfaces++])
#define FX_TYPE_CLASS(class_struct) \
type_info->t_class_size = sizeof(class_struct)
#define FX_TYPE_FLAGS(flags) type_info->t_flags = (flags)
#define FX_TYPE_INSTANCE_INIT(func) type_info->t_instance_init = (func)
#define FX_TYPE_INSTANCE_FINI(func) type_info->t_instance_fini = (func)
#if 0
#define FX_TYPE_VTABLE_BEGIN(vtable_struct, interface_id) \
vtable_struct __FX_IFACE_I1(iface, __LINE__) = {0}; \
{ \
vtable_struct *iface = &__FX_IFACE_I1(iface, __LINE__); \
type_info->t_vtables[nr_vtables].v_vtable = iface; \
type_info->t_vtables[nr_vtables].v_interface_id = interface_id; \
nr_vtables++;
#define FX_TYPE_VTABLE_END(vtable_struct, interface_id) }
#endif
#define FX_TYPE_INSTANCE_PRIVATE(instance_struct) \
type_info->t_instance_private_size = sizeof(instance_struct)
#define FX_TYPE_INSTANCE_PROTECTED(instance_struct) \
type_info->t_instance_protected_size = sizeof(instance_struct)
/* Type declaration macros (for use in .h header file) */
#define __FX_DECLARE_TYPE(name) \
typedef FX_TYPE_FWDREF(name) name; \
typedef struct _##name##_class name##_class;
#define FX_DECLARE_TYPE(name) \
__FX_DECLARE_TYPE(name); \
static inline name *name##_ref(name *p) \
{ \
return fx_object_ref(p); \
} \
static inline void name##_unref(name *p) \
{ \
fx_object_unref(p); \
}
#define FX_TYPE_CLASS_DECLARATION_BEGIN(name) struct _##name##_class {
#define FX_TYPE_CLASS_DECLARATION_END(name) \
} \
;
#define FX_TYPE_VIRTUAL_METHOD(return_type, method_name) \
return_type(*method_name)
#define FX_TYPE_DEFAULT_CONSTRUCTOR(type_name, type_id) \
static inline type_name *type_name##_create(void) \
{ \
return fx_object_create(type_id); \
}
/* Other macros */
#define FX_CLASS_DISPATCH_VIRTUAL( \
type_name, type_id, default_value, func, object, ...) \
do { \
type_name##_class *iface \
= fx_object_get_interface(object, type_id); \
if (iface && iface->func) { \
return iface->func(object, __VA_ARGS__); \
} else { \
return default_value; \
} \
} while (0)
#define FX_CLASS_DISPATCH_VIRTUAL_0(type_name, type_id, default_value, func, object) \
do { \
type_name##_class *iface \
= fx_object_get_interface(object, type_id); \
if (iface && iface->func) { \
return iface->func(object); \
} else { \
return default_value; \
} \
} while (0)
#define FX_CLASS_DISPATCH_VIRTUAL_V(type_name, type_id, func, object, ...) \
do { \
type_name##_class *iface \
= fx_object_get_interface(object, type_id); \
if (iface && iface->func) { \
iface->func(object, __VA_ARGS__); \
return; \
} \
} while (0)
#define FX_CLASS_DISPATCH_VIRTUAL_V0(type_name, type_id, func, object) \
do { \
type_name##_class *iface \
= fx_object_get_interface(object, type_id); \
if (iface && iface->func) { \
iface->func(object); \
return; \
} \
} while (0)
#define FX_CLASS_DISPATCH_STATIC(type_id, func_name, obj, ...) \
do { \
void *priv = fx_object_get_private(obj, type_id); \
return func_name(priv, __VA_ARGS__); \
} while (0)
#define FX_CLASS_DISPATCH_STATIC_V(type_id, func_name, obj, ...) \
do { \
void *priv = fx_object_get_private(obj, type_id); \
func_name(priv, __VA_ARGS__); \
} while (0)
#define FX_CLASS_DISPATCH_STATIC_0(type_id, func_name, obj) \
do { \
void *priv = fx_object_get_private(obj, type_id); \
return func_name(priv); \
} while (0)
#define FX_CLASS_DISPATCH_STATIC_V0(type_id, func_name, obj) \
do { \
void *priv = fx_object_get_private(obj, type_id); \
func_name(priv); \
} while (0)
#ifdef __cplusplus
#define FX_DECLS_BEGIN extern "C" {
#define FX_DECLS_END }
#else
#define FX_DECLS_BEGIN
#define FX_DECLS_END
#endif
#endif

View File

@@ -1,118 +0,0 @@
#ifndef FX_CORE_MISC_H_
#define FX_CORE_MISC_H_
#include <stddef.h>
#include <stdint.h>
#ifndef _Nonnull
#define _Nonnull
#endif
#define FX_NPOS ((size_t)-1)
#define fx_min(type, x, y) (z__fx_min_##type(x, y))
#define fx_max(type, x, y) (z__fx_max_##type(x, y))
#define fx_unbox(type, box, member) \
((type *_Nonnull)((box) ? (uintptr_t)(box) - (offsetof(type, member)) : 0))
#define z__fx_merge_(a, b) a##b
#define z__fx_label_(a) z__fx_merge_(__unique_name_, a)
#define z__fx_unique_name() z__fx_label_(__LINE__)
#define z__fx_numargs(arg_type, ...) \
(sizeof((arg_type[]) {__VA_ARGS__}) / sizeof(arg_type))
#ifdef _MSC_VER
#ifdef FX_STATIC
#define FX_API extern
#else
#ifdef FX_EXPORT
#define FX_API extern __declspec(dllexport)
#else
#define FX_API extern __declspec(dllimport)
#endif
#endif
#else
#define FX_API extern
#endif
static inline char z__fx_min_char(char x, char y)
{
return x < y ? x : y;
}
static inline unsigned char z__fx_min_uchar(unsigned char x, unsigned char y)
{
return x < y ? x : y;
}
static inline int z__fx_min_int(int x, int y)
{
return x < y ? x : y;
}
static inline unsigned int z__fx_min_uint(unsigned int x, unsigned int y)
{
return x < y ? x : y;
}
static inline long z__fx_min_long(long x, long y)
{
return x < y ? x : y;
}
static inline unsigned int z__fx_min_ulong(unsigned long x, unsigned long y)
{
return x < y ? x : y;
}
static inline long long z__fx_min_longlong(long long x, long long y)
{
return x < y ? x : y;
}
static inline unsigned long long z__fx_min_ulonglong(
unsigned long long x, unsigned long long y)
{
return x < y ? x : y;
}
static inline size_t z__fx_min_size_t(size_t x, size_t y)
{
return x < y ? x : y;
}
static inline char z__fx_max_char(char x, char y)
{
return x > y ? x : y;
}
static inline unsigned char z__fx_max_uchar(unsigned char x, unsigned char y)
{
return x > y ? x : y;
}
static inline int z__fx_max_int(int x, int y)
{
return x > y ? x : y;
}
static inline unsigned int z__fx_max_uint(unsigned int x, unsigned int y)
{
return x > y ? x : y;
}
static inline long z__fx_max_long(long x, long y)
{
return x > y ? x : y;
}
static inline unsigned int z__fx_max_ulong(unsigned long x, unsigned long y)
{
return x > y ? x : y;
}
static inline long long z__fx_max_longlong(long long x, long long y)
{
return x > y ? x : y;
}
static inline unsigned long long z__fx_max_ulonglong(
unsigned long long x, unsigned long long y)
{
return x > y ? x : y;
}
static inline size_t z__fx_max_size_t(size_t x, size_t y)
{
return x > y ? x : y;
}
FX_API size_t fx_int_length(intptr_t v);
FX_API size_t fx_uint_length(uintptr_t v);
#endif // FX_CORE_MISC_H_

View File

@@ -1,39 +0,0 @@
#ifndef FX_CORE_OBJECT_H_
#define FX_CORE_OBJECT_H_
#include <fx/core/misc.h>
#include <fx/core/type.h>
#define FX_OBJECT_MAGIC 0xDECAFC0C0ABEEF13ULL
#define FX_OBJECT(p) ((fx_object *)(p))
#define FX_TYPE_OBJECT (fx_object_get_type())
#define FX_TYPE_FWDREF(name) struct _fx_object
#define FX_RV(p) (fx_object_make_rvalue(p))
typedef FX_TYPE_FWDREF(fx_object) fx_object;
typedef struct _fx_object_class {
void (*to_string)(const fx_object *, FX_TYPE_FWDREF(fx_stream) *);
} fx_object_class;
FX_API fx_type fx_object_get_type(void);
FX_API void *fx_object_get_private(const fx_object *object, fx_type type);
FX_API void *fx_object_get_protected(const fx_object *object, fx_type type);
FX_API void *fx_object_get_interface(const fx_object *object, fx_type type);
FX_API fx_status fx_object_get_data(
const fx_object *object, fx_type type, void **priv, void **prot,
void **iface);
FX_API fx_object *fx_object_ref(fx_object *p);
FX_API void fx_object_unref(fx_object *p);
FX_API fx_object *fx_object_make_rvalue(fx_object *p);
FX_API fx_object *fx_object_create(fx_type type);
FX_API void fx_object_to_string(const fx_object *p, FX_TYPE_FWDREF(fx_stream) * out);
FX_API bool fx_object_is_type(const fx_object *p, fx_type type);
#endif

View File

@@ -1,82 +0,0 @@
#ifndef FX_CORE_QUEUE_H_
#define FX_CORE_QUEUE_H_
#include <fx/core/iterator.h>
#include <fx/core/macros.h>
#include <fx/core/status.h>
#include <stdbool.h>
#include <string.h>
FX_DECLS_BEGIN;
#define FX_TYPE_QUEUE_ITERATOR (fx_queue_iterator_get_type())
FX_DECLARE_TYPE(fx_queue_iterator);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_queue_iterator)
FX_TYPE_CLASS_DECLARATION_END(fx_queue_iterator)
#define FX_QUEUE_INIT ((fx_queue) {.q_first = NULL, .q_last = NULL})
#define FX_QUEUE_ENTRY_INIT ((fx_queue_entry) {.qe_next = NULL, .qe_prev = NULL})
typedef struct fx_queue_entry {
struct fx_queue_entry *qe_next;
struct fx_queue_entry *qe_prev;
} fx_queue_entry;
typedef struct fx_queue {
fx_queue_entry *q_first;
fx_queue_entry *q_last;
} fx_queue;
static inline void fx_queue_init(fx_queue *q)
{
memset(q, 0x00, sizeof *q);
}
static inline bool fx_queue_empty(const fx_queue *q)
{
return q ? (q->q_first == NULL) : true;
}
static inline fx_queue_entry *fx_queue_first(const fx_queue *q)
{
return q ? q->q_first : NULL;
}
static inline fx_queue_entry *fx_queue_last(const fx_queue *q)
{
return q ? q->q_last : NULL;
}
static inline fx_queue_entry *fx_queue_next(const fx_queue_entry *entry)
{
return entry ? entry->qe_next : NULL;
}
static inline fx_queue_entry *fx_queue_prev(const fx_queue_entry *entry)
{
return entry ? entry->qe_prev : NULL;
}
FX_API fx_type fx_queue_iterator_get_type(void);
FX_API size_t fx_queue_length(const fx_queue *q);
FX_API void fx_queue_insert_before(
fx_queue *q, fx_queue_entry *entry, fx_queue_entry *before);
FX_API void fx_queue_insert_after(
fx_queue *q, fx_queue_entry *entry, fx_queue_entry *after);
FX_API void fx_queue_push_front(fx_queue *q, fx_queue_entry *entry);
FX_API void fx_queue_push_back(fx_queue *q, fx_queue_entry *entry);
FX_API fx_queue_entry *fx_queue_pop_front(fx_queue *q);
FX_API fx_queue_entry *fx_queue_pop_back(fx_queue *q);
FX_API void fx_queue_move(fx_queue *q, fx_queue_entry *dest, fx_queue_entry *src);
FX_API void fx_queue_delete(fx_queue *q, fx_queue_entry *entry);
FX_API void fx_queue_delete_all(fx_queue *q);
FX_API fx_iterator *fx_queue_begin(fx_queue *q);
FX_API fx_iterator *fx_queue_cbegin(const fx_queue *q);
FX_DECLS_END;
#endif

View File

@@ -1,37 +0,0 @@
#ifndef FX_RANDOM_H_
#define FX_RANDOM_H_
#include <fx/core/status.h>
#include <stddef.h>
struct fx_random_algorithm;
typedef enum fx_random_flags {
/* algorithm selection */
FX_RANDOM_MT19937 = 0x01u,
/* generation flags */
FX_RANDOM_SECURE = 0x100u,
} fx_random_flags;
typedef struct fx_random_ctx {
fx_random_flags __f;
struct fx_random_algorithm *__a;
union {
struct {
unsigned long long mt[312];
size_t mti;
} __mt19937;
};
} fx_random_ctx;
FX_API fx_random_ctx *fx_random_global_ctx(void);
FX_API fx_status fx_random_init(fx_random_ctx *ctx, fx_random_flags flags);
FX_API unsigned long long fx_random_next_int64(fx_random_ctx *ctx);
FX_API double fx_random_next_double(fx_random_ctx *ctx);
FX_API void fx_random_next_bytes(
fx_random_ctx *ctx, unsigned char *out, size_t nbytes);
#endif

View File

@@ -1,47 +0,0 @@
#ifndef FX_CORE_RINGBUFFER_H_
#define FX_CORE_RINGBUFFER_H_
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <fx/core/status.h>
FX_DECLS_BEGIN;
#define FX_TYPE_RINGBUFFER (fx_ringbuffer_get_type())
FX_DECLARE_TYPE(fx_ringbuffer);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_ringbuffer)
FX_TYPE_CLASS_DECLARATION_END(fx_ringbuffer)
FX_API fx_type fx_ringbuffer_get_type(void);
FX_API fx_ringbuffer *fx_ringbuffer_create(size_t capacity);
FX_API fx_ringbuffer *fx_ringbuffer_create_with_buffer(void *ptr, size_t capacity);
FX_API fx_status fx_ringbuffer_clear(fx_ringbuffer *buf);
FX_API fx_status fx_ringbuffer_read(
fx_ringbuffer *buf, void *p, size_t count, size_t *nr_read);
FX_API fx_status fx_ringbuffer_write(
fx_ringbuffer *buf, const void *p, size_t count, size_t *nr_written);
FX_API int fx_ringbuffer_getc(fx_ringbuffer *buf);
FX_API fx_status fx_ringbuffer_putc(fx_ringbuffer *buf, int c);
FX_API size_t fx_ringbuffer_write_capacity_remaining(const fx_ringbuffer *buf);
FX_API size_t fx_ringbuffer_available_data_remaining(const fx_ringbuffer *buf);
FX_API fx_status fx_ringbuffer_open_read_buffer(
fx_ringbuffer *buf, const void **ptr, size_t *length);
FX_API fx_status fx_ringbuffer_close_read_buffer(
fx_ringbuffer *buf, const void **ptr, size_t nr_read);
FX_API fx_status fx_ringbuffer_open_write_buffer(
fx_ringbuffer *buf, void **ptr, size_t *capacity);
FX_API fx_status fx_ringbuffer_close_write_buffer(
fx_ringbuffer *buf, void **ptr, size_t nr_written);
FX_DECLS_END;
#endif

View File

@@ -1,109 +0,0 @@
#ifndef FX_CORE_ROPE_H_
#define FX_CORE_ROPE_H_
#include <fx/core/hash.h>
#include <fx/core/misc.h>
#include <fx/core/stream.h>
#include <stdint.h>
#include <string.h>
struct fx_string;
struct fx_bstr;
#define FX_ROPE_TYPE(f) ((f) & 0xFF)
#define FX_ROPE_CHAR(c) \
\
{ \
.r_flags = FX_ROPE_F_CHAR, .r_len_total = 1, \
.r_v = {.v_char = (c) } \
}
#define FX_ROPE_CSTR(str) \
{ \
.r_flags = FX_ROPE_F_CSTR_BORROWED, \
.r_len_total = strlen(str), \
.r_v = { \
.v_cstr = { \
.s = (str), \
.hash = fx_hash_cstr(str), \
}, \
}, \
}
#define FX_ROPE_CSTR_STATIC(str) \
{ \
.r_flags = FX_ROPE_F_CSTR_STATIC, \
.r_len_total = strlen(str), \
.r_v = { \
.v_cstr = { \
.s = (str), \
.hash = fx_hash_cstr(str), \
}, \
}, \
}
#define FX_ROPE_INT(v) \
\
{ \
.r_flags = FX_ROPE_F_INT, .r_len_total = fx_int_length(v), \
.r_v = {.v_int = (v) } \
}
#define FX_ROPE_UINT(v) \
\
{ \
.r_flags = FX_ROPE_F_UINT, .r_len_total = fx_uint_length(v), \
.r_v = {.v_uint = (v) } \
}
typedef enum fx_rope_flags {
FX_ROPE_F_NONE = 0x0000u,
FX_ROPE_F_CHAR = 0x0001u,
FX_ROPE_F_CSTR = 0x0002u,
FX_ROPE_F_CSTR_BORROWED = 0x0003u,
FX_ROPE_F_CSTR_STATIC = 0x0004u,
FX_ROPE_F_INT = 0x0005u,
FX_ROPE_F_UINT = 0x0006u,
FX_ROPE_F_COMPOSITE = 0x0007u,
FX_ROPE_F_MALLOC = 0x0100u,
} fx_rope_flags;
typedef struct fx_rope {
fx_rope_flags r_flags;
unsigned long r_len_left, r_len_total;
union {
char v_char;
intptr_t v_int;
uintptr_t v_uint;
struct {
const char *s;
uint64_t hash;
} v_cstr;
struct {
const struct fx_rope *r_left, *r_right;
} v_composite;
} r_v;
} fx_rope;
FX_API void fx_rope_init_char(fx_rope *rope, char c);
FX_API void fx_rope_init_cstr(fx_rope *rope, const char *s);
FX_API void fx_rope_init_cstr_borrowed(fx_rope *rope, const char *s);
FX_API void fx_rope_init_cstr_static(fx_rope *rope, const char *s);
FX_API void fx_rope_init_int(fx_rope *rope, intptr_t v);
FX_API void fx_rope_init_uint(fx_rope *rope, uintptr_t v);
FX_API void fx_rope_destroy(fx_rope *rope);
FX_API void fx_rope_iterate(
const fx_rope *rope, void (*func)(const fx_rope *, void *), void *arg);
FX_API size_t fx_rope_get_size(const fx_rope *rope);
FX_API void fx_rope_concat(fx_rope *result, const fx_rope *left, const fx_rope *right);
FX_API void fx_rope_join(fx_rope *result, const fx_rope **ropes, size_t nr_ropes);
FX_API fx_status fx_rope_to_cstr(const fx_rope *rope, char *out, size_t max);
FX_API fx_status fx_rope_to_bstr(const fx_rope *rope, struct fx_bstr *str);
FX_API fx_status fx_rope_to_string(const fx_rope *rope, fx_stream *out);
#endif

View File

@@ -1,48 +0,0 @@
#ifndef FX_CORE_STATUS_H_
#define FX_CORE_STATUS_H_
#include <fx/core/misc.h>
#define FX_OK(status) ((enum fx_status)((uintptr_t)(status)) == FX_SUCCESS)
#define FX_ERR(status) ((status) != FX_SUCCESS)
typedef enum fx_status {
FX_SUCCESS = 0x00u,
FX_ERR_NO_MEMORY,
FX_ERR_OUT_OF_BOUNDS,
FX_ERR_INVALID_ARGUMENT,
FX_ERR_NAME_EXISTS,
FX_ERR_NOT_SUPPORTED,
FX_ERR_BAD_STATE,
FX_ERR_NO_ENTRY,
FX_ERR_NO_DATA,
FX_ERR_NO_SPACE,
FX_ERR_UNKNOWN_FUNCTION,
FX_ERR_BAD_FORMAT,
FX_ERR_IO_FAILURE,
FX_ERR_IS_DIRECTORY,
FX_ERR_NOT_DIRECTORY,
FX_ERR_PERMISSION_DENIED,
FX_ERR_BUSY,
/* fx-compress specific code */
FX_ERR_COMPRESSION_FAILURE,
/* fx-object specific code */
FX_ERR_TYPE_REGISTRATION_FAILURE,
FX_ERR_CLASS_INIT_FAILURE,
} fx_status;
typedef enum fx_status_msg {
FX_MSG_SUCCESS = 0,
/* fx-object specific messages */
FX_MSG_TYPE_REGISTRATION_FAILURE,
FX_MSG_CLASS_INIT_FAILURE,
FX_MSG_CLASS_SPECIFIES_UNKNOWN_INTERFACE,
} fx_status_msg;
FX_API const char *fx_status_to_string(fx_status status);
FX_API const char *fx_status_description(fx_status status);
#endif

View File

@@ -1,100 +0,0 @@
#ifndef FX_CORE_STREAM_H_
#define FX_CORE_STREAM_H_
#include <fx/core/encoding.h>
#include <fx/core/macros.h>
#include <fx/core/misc.h>
#include <fx/core/status.h>
#include <stdarg.h>
#include <stdio.h>
FX_DECLS_BEGIN;
#define fx_stdin (z__fx_stream_get_stdin())
#define fx_stdout (z__fx_stream_get_stdout())
#define fx_stderr (z__fx_stream_get_stderr())
#define FX_TYPE_STREAM (fx_stream_get_type())
#define FX_TYPE_STREAM_BUFFER (fx_stream_buffer_get_type())
FX_DECLARE_TYPE(fx_stream);
FX_DECLARE_TYPE(fx_stream_buffer);
typedef enum fx_stream_mode {
FX_STREAM_READ = 0x01u,
FX_STREAM_WRITE = 0x02u,
FX_STREAM_BINARY = 0x10u,
Z__FX_STREAM_STATIC = 0x80u,
} fx_stream_mode;
typedef enum fx_stream_seek_origin {
FX_STREAM_SEEK_START = 0x01u,
FX_STREAM_SEEK_CURRENT = 0x02u,
FX_STREAM_SEEK_END = 0x03u,
} fx_stream_seek_origin;
typedef struct fx_stream_cfg {
fx_stream_mode s_mode;
} fx_stream_cfg;
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_stream)
fx_status (*s_close)(fx_stream *);
fx_status (*s_seek)(fx_stream *, long long, fx_stream_seek_origin);
fx_status (*s_tell)(const fx_stream *, size_t *);
fx_status (*s_getc)(fx_stream *, fx_wchar *);
fx_status (*s_read)(fx_stream *, void *, size_t, size_t *);
fx_status (*s_write)(fx_stream *, const void *, size_t, size_t *);
fx_status (*s_reserve)(fx_stream *, size_t);
FX_TYPE_CLASS_DECLARATION_END(fx_stream)
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_stream_buffer)
FX_TYPE_CLASS_DECLARATION_END(fx_stream_buffer)
FX_API fx_type fx_stream_get_type();
FX_API fx_type fx_stream_buffer_get_type();
FX_API fx_stream *z__fx_stream_get_stdin(void);
FX_API fx_stream *z__fx_stream_get_stdout(void);
FX_API fx_stream *z__fx_stream_get_stderr(void);
FX_API fx_stream_buffer *fx_stream_buffer_create(void *p, size_t len);
FX_API fx_stream_buffer *fx_stream_buffer_create_dynamic(size_t buffer_size);
FX_API fx_stream *fx_stream_open_fp(FILE *fp);
FX_API fx_status fx_stream_reserve(fx_stream *stream, size_t len);
FX_API fx_status fx_stream_seek(
fx_stream *stream, long long offset, fx_stream_seek_origin origin);
FX_API size_t fx_stream_cursor(const fx_stream *stream);
FX_API fx_status fx_stream_push_indent(fx_stream *stream, int indent);
FX_API fx_status fx_stream_pop_indent(fx_stream *stream);
FX_API fx_status fx_stream_read_char(fx_stream *stream, fx_wchar *c);
FX_API fx_status fx_stream_read_bytes(
fx_stream *stream, void *buf, size_t count, size_t *nr_read);
FX_API fx_status fx_stream_read_line(fx_stream *stream, char *s, size_t max);
FX_API fx_status fx_stream_read_line_s(fx_stream *src, fx_stream *dest);
FX_API fx_status fx_stream_read_all_bytes(
fx_stream *stream, void *p, size_t max, size_t *nr_read);
FX_API fx_status fx_stream_read_all_bytes_s(
fx_stream *src, fx_stream *dest, fx_stream_buffer *buffer, size_t *nr_read);
FX_API fx_status fx_stream_write_char(fx_stream *stream, fx_wchar c);
FX_API fx_status fx_stream_write_string(
fx_stream *stream, const char *s, size_t *nr_written);
FX_API fx_status fx_stream_write_bytes(
fx_stream *stream, const void *buf, size_t count, size_t *nr_written);
FX_API fx_status fx_stream_write_fmt(
fx_stream *stream, size_t *nr_written, const char *format, ...);
FX_API fx_status fx_stream_write_vfmt(
fx_stream *stream, size_t *nr_written, const char *format, va_list arg);
FX_DECLS_END;
#endif

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